SlideShare una empresa de Scribd logo
1 de 68
Java UI – Manejo de eventos    En Java los eventos son representados por objetos    Ejemplos:     clic en un botón    arrastrar el mouse    pulsar Enter    Los componentes AWT y Swing generan ( fire ) eventos    java.awt.AWTEvent
Los XXXEvent nos informan...    Quién lo dispara?    De qué tipo es?    Cuándo ocurrió?     Información propia del evento Los detalles del evento pueden ser obtenidos  usando métodos de acceso: Ej.: getActionCommand() getModifiers()
Eventos AWT    De bajo nivel     Componentes – ComponentEvent, FocusEvent, KeyEvent, MouseEvent PaintEvent    Contenedores – ContainerEvent    Ventanas – WindowEvent    Semánticos – mayor nivel de abstracción    ActionEvent, ItemEvent, TextEvent, AdjustmentEvent
Eventos AWT
Eventos semánticos    No son disparados por todos los componentes    Ejemplo 1: ItemEvent indica que un ítem fue seleccionado o deseleccionado     Disparado por JComboBox    No disparado por JButton    Ejemplo 2: ActionEvent    Disparado por JComboBox    Disparado por JButton
Eventos Swing    Swing tiene además su propio paquete de manejo de eventos: javax.swing.event    Casi todos estos nuevos eventos están relacionados con la arquitectura MVC    Ejemplo:     TreeModelEvent    ListDataEvent
Manejo de eventos    Modelo de Delegación de Eventos    Interfaces “listeners”    Registro para recibir eventos de una fuente    Patrón Observer
Manejo de eventos Button Event Event Listeners Event Sources addActionListener(ActionListener l)
Listeners    Interfaces que manejan los eventos (java.util.EventListener). Basadas en Observer    Cada clase Event tiene su correspondiente  interface Listener    Varios Listeners para el mismo tipo de eventos ActionEvent ActionListener MouseEvent MouseListener MouseMotionListener
Listeners Ejemplos de Listeners:
public interface WindowListener extends EventListerner { void windowActivated(WindowEvent e); void windowClosed(WindowEvent e); void windowClosing(WindowEvent e); void windowDeactivated(WindowEvent e); void windowDeiconified(WindowEvent e); void windowIconified(WindowEvent e); void windowOpened(WindowEvent e);} public interface MouseListener extends EventListener { public void mouseClicked(MouseEvent e); public void mousePressed(MouseEvent e); public void mouseReleased(MouseEvent e); public void mouseEntered(MouseEvent e); public void mouseExited(MouseEvent e);}
Registro de Listeners    Un Listener debe en primer lugar registrarse con la(s) fuente(s) que pueda(n) generar los eventos  de su interés:    public void addXXXListener(XXXListener e)    addActionListener, addItemListener, etc.      Para el mismo evento en un componente, puede haber registrado varios Listeners     Un evento puede provocar numerosas respuestas    Los eventos son “difundidos” a todos sus Listeners
Múltiples Listeners Component EventListener addEventListener Event Ocurre evento EventListener Event Ocurre evento addEventListener
Conectar un Listener con una fuente de eventos    Defina una clase que implemente la interface Listener(o que extienda una clase que la implemente)    Añada la implementación de la interface    Registre el Listener con la fuente
Tips    Debe implementar todos los métodos de la interface Si el código usado para implementar el manejo de  eventos tiene unas pocas líneas se suele usar una  clase interna anónima.     No hay garantía de cuál Listener es notificado primero. No escribir código contando con un orden específico.    Trate eventos semánticos antes que de bajo nivel    cambios en look and feel    componentes compuestos    Utilice métodos descriptivos de los eventos    ActionEvent – getActionCommand()    Threads
Clases Adapter    Son clases que implementan una interface Listener  con métodos vacíos (“dummy”), uso herencia.  Desventaja: Java no permite herencia múltiple Solución: usar clases internas anónimas    Utiles sólo para interfaces Listeners con más de un método    Principalmente por razones de conveniencia    Ejemplos:    MouseAdapter    WindowAdapter
Clases internas    En Java una clase puede ser definida en cualquier lugar    Anidada dentro de otras clases    En la invocación de un método    Tienen acceso a los miembros y métodos de todas  las clases externas a ellas    Pueden tener nombres o ser anónimas    Pueden extender de otra clase o implementar interfaces    Muy útiles para el manejo de eventos
Clases internas con nombre    Se definen como las clases normales    No pueden ser  public
Clases internas con nombre public class MyClass extends JPanel { … anObject.addMouseListener(new MyAdapter()); … class myAdapter extends MouseAdapter { public void mouseClicked(MouseEvent e) { // blah } // end mouseClicked } // end inner class } // end MyClass
Clases internas anónimas    Definida dentro de addXXXListener (new  classNam e(  ) {  classBody  }); (new  interfaceNam e() {  classBody  }); Dentro del cuerpo no puedo definir constructores.
Ejemplo
Código // importa los símbolos de AWT and Swing  import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SimpleEvents extends JFrame { static final int WIDTH=350; //ancho y alto del frame static final int HEIGHT=180; // Declara JTextField para entrar texto JTextField textField; // Declara JTextArea p/recibir líneas de textField JTextArea textList; // Declara JScrollPane para JTextArea JScrollPane pane; // Constructor:aquí se hace casi todo el trabajo  public SimpleEvents(String lab) { // llama el constructor de Jframe:pone etiqueta super(lab);
Código /******* Crea un contedor para textField ****/ // Instancia un JPanel JPanel textPanel = new JPanel(); // le pone un borde (por defecto no tiene) textPanel.setBorder(BorderFactory.createEtchedBorder()); // Set el layout del textPanel a BorderLayout textPanel.setLayout(new BorderLayout()); // Crea una etiqueta y la añade al panel JLabel textTitle =new JLabel(&quot;Type and hit <ENTER>&quot;); textPanel.add(textTitle, BorderLayout.NORTH); // Instancia un JTextField y añade a textPanel textField = new JTextField(); textPanel.add(textField, BorderLayout.SOUTH); // Añade un strut al textPanel como margen inferior textPanel.add(Box.createVerticalStrut(6));   // Crea un contenedor p/ textArea  // Instancia un JPanel JPanel listPanel = new JPanel();
Código // añade borde listPanel.setBorder (BorderFactory.createEtchedBorder()); // Set el layout del textPanel  listPanel.setLayout(new BoxLayout(listPanel,BoxLayout.Y_AXIS)); // Crea una etiqueta y añade al panel JLabel title = new JLabel(&quot;Text List&quot;); listPanel.add(title); // Añade un strut al BoxLayout listPanel.add(Box.createVerticalStrut(10)); // Instancia una JTextArea sin texto inicial // 6 filas, 10 columnas, y vertical scrollbars textList=new JTextArea(&quot;&quot;, 6, 10); // la hace read-only textList.setEditable(false); // Añade textList a listPanel pane = new JScrollPane (textList); listPanel.add(pane);
Código // Añade un strut a listPanel como margen inferior listPanel.add(Box.createVerticalStrut(6)); /* Añade un listener a textField cuando se pulse ENTER copia el texto de textField al area de texto. Los componentes están interrelacionados*/ textField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // Añade el texto de textField a textList textList.append(textField.getText()); textList.append(&quot;&quot;); // Reset el textField textField.setText(&quot;&quot;); }}); // Añade los 2 paneles al frame, separados por strut Container c = getContentPane(); c.setLayout (new FlowLayout()); c.add(textPanel); c.add(Box.createHorizontalStrut(30)); c.add(listPanel);}
Código public static void main(String args[]) { SimpleEvents frame = new SimpleEvents(&quot;Simple Events Example&quot;); // standard adapter usado en casi todas las  // aplicaciones para cerrar la ventana frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); // set el tamaño de frame y lo muestra frame.setSize(WIDTH, HEIGHT); frame.setVisible(true); } }
Command Pattern    Command encapsula un requerimiento en un objeto, permitiendo parametrizar clientes con diferentes  requerimientos, hacer una cola o registro de ellos y  permitir por lo tanto hacer undo/redo.
Command Pattern
Swing Action    Command permite desacoplar el objeto invocante (Invoker) del receptor (Receiver, el que conoce  cómo atender el requerimiento).     Swing implementa el patrón Command con objectos de clases que implementen Action, por ej., subclases de AbstractAction. Siempre que selecciona un ítem de un menú o pulsa un botón, estos objetos action emiten un requerimiento de una acción específica de la  aplicación.
 
Swing Action    Puede configurar un objeto JBbutton mediante una implementación concreta de Action que delega el requerimiento al Receiver.    JButton actúa como Invoker llamando al método actionPerformed de un objeto concreto Action y no le importa qué objeto ejecuta realmente el comando requerido.    El objeto Action delega el llamado al objeto Receiver que sabe cómo procesar el requerimiento, pero no quién lo hizo.    El Receiver puede ser modificado o ser otro objeto y   no afectar el código en JButton y del mismo modo se puede añadir el pedido de nuevos objetos, sin afectar al Receiver.
Ejemplo Swing Action
Código import java.awt.*; import java.awt.event.*; import javax.swing.*; class ColorAction extends AbstractAction{  private Component target; public ColorAction(String name, Icon icon,Color c, Component comp) {putValue(Action.NAME, name); putValue(Action.SMALL_ICON, icon); putValue(&quot;Color&quot;, c); target = comp;}
Código public void actionPerformed(ActionEvent evt) { Color c = (Color)getValue(&quot;Color&quot;); target.setBackground(c); target.repaint();}} class ActionButton extends JButton{  public ActionButton(Action a){  setText((String)a.getValue(Action.NAME)); Icon icon = (Icon)a.getValue(Action.SMALL_ICON); if (icon != null)  setIcon(icon); addActionListener(a);}}
Código class SeparateGUIFrame extends JFrame{  public SeparateGUIFrame(){  setTitle(&quot;SeparateGUITest&quot;); setSize(300, 200); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0);}}); JPanel panel = new JPanel(); Action blueAction = new ColorAction(&quot;Blue&quot;,new ImageIcon( &quot;blue-ball.gif&quot;),Color.blue, panel);
Código Action yellowAction = new ColorAction(&quot;Yellow&quot;, new ImageIcon(&quot;yellow-ball.gif&quot;),Color.yellow, panel); Action redAction = new ColorAction(&quot;Red&quot;, new ImageIcon(&quot;red-ball.gif&quot;),Color.red, panel); panel.add(new ActionButton(yellowAction)); panel.add(new ActionButton(blueAction)); panel.add(new ActionButton(redAction)); panel.registerKeyboardAction(yellowAction, KeyStroke.getKeyStroke(KeyEvent.VK_Y, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
Código panel.registerKeyboardAction(blueAction, KeyStroke.getKeyStroke(KeyEvent.VK_B, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); panel.registerKeyboardAction(redAction, KeyStroke.getKeyStroke(KeyEvent.VK_R, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); Container contentPane = getContentPane(); contentPane.add(panel); JMenu m = new JMenu(&quot;Color&quot;); m.add(yellowAction);
Código m.add(blueAction); m.add(redAction); JMenuBar mbar = new JMenuBar(); mbar.add(m); setJMenuBar(mbar);}} public class SeparateGUITest{  public static void main(String[] args){  JFrame frame = new SeparateGUIFrame(); frame.show();}}
Threads y Swing    Si su programa crea y se refiere a la GUI en forma correcta, probablemente no tenga que preocuparse  de este tema.    Si su programa crea threads para realizar tareas que afecten la GUI, o si manipula la GUI ya visible en respuesta a algo que no sea un evento standard, sea cuidadoso!
Regla     Regla del thread único: “ Una vez que un componente se “realizó”, todo código que   pueda afectarlo o dependa del estado del mismo, debería ejecutarse en el “ event-dispatching thread  ”.”    Hay unas pocas excepciones: http://java.sun.com/docs/books/tutorial/uiswing/overview/threads.html
La historia real Usualmente se piensa en un programa como un único  conjunto lineal de pasos a ejecutar, aunque ocurre algo  especial cuando se crean objetos gráficos.  import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println  (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println  (“Finished making GUI”); }// main }// class HelloGUI
Event-dispatching thread import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println  (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println  (“Finished making GUI”); }// main }// class HelloGUI
Las dos áreas de un programa con GUI Su código Graphics 1 El código que  escribe en main() Y otros métodos 2 El código que Java provee para manejar la parte gráfica de la aplicación.  import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println  (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println  (“Finished making GUI”); }// main }// class HelloGUI
Event-dispatching thread Mouse Click El código para manejar este evento import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println  (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println  (“Finished making GUI”); }// main }// class HelloGUI callback
Event-dispatching thread Registro de eventos antes que ocurren
Event-dispatching thread public void actionPerformed (ActionEvent e)  { // code doing something  } Este método  DEBE estar aquí, tal que Java lo  sabe y puede “callback”  al mismo. import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println  (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println  (“Finished making GUI”); }// main }// class HelloGUI callback ActionListener
Cuando conviene usar threads?    Para mover, fuera del thread principal, una tarea de inicialización que   requiera mucho tiempo y para que la  GUI sea más rápida (ej.: cálculos intensivos, I/O en disco tal como carga de imágenes).    Para mover fuera del event-dispatching thread, tareas que requieran mucho tiempo, de forma tal que la GUI  permanezca  sensible . ( Ejecutar el código de manejo de eventos en un único thread garantiza que el manejo de cada uno de ellos terminará de ejecutarse antes del manejo del siguiente)      Para ejecutar una operación repetidamente, usualmente a iguales intervalos de tiempo.     Para esperar mensajes de otros programas.
Programas Multi-threads    Debería analizar el código de su programa y  documentar desde cuál thread se invoca cada método.    Si no está seguro si su código se está ejecutando en el  thread de eventos use  SwingUtilities.isEventDispatchThread()  que retorna true si se est á ejecutando en el EDT.    Invoque SwingUtilities.invokeLater (preferido, retorna  inmediatamente sin esperar que el EDT ejecute el código) o SwingUtilities.invokeAndWait desde cualquier thread  para requerir que el EDT ejecute cierto código que  involucre un acceso a la GUI.
Programas Multi-threads Ejemplo: un thread que necesita acceder a un par de text fields: void printTextField() throws Exception {  final String[] myStrings = new String[2];  Runnable getTextFieldText = new Runnable() {  public void run() {  myStrings[0] = textField0.getText();  myStrings[1] = textField1.getText(); } }; SwingUtilities.invokeAndWait(getTextFieldText); System.out.println(myStrings[0] + &quot; &quot; + myStrings[1]); }
Programas Multi-threads    SwingWorker    Crea un thread para ejecutar operaciones que  requieran mucho tiempo. Después que las  mismas finalizan, da la opción de ejecutar código  adicional en el EDT.    no está en Swing release.    métodos  construct()  and  finish()    javax.swing.Timer    Se suele usar si se necesita actualizar un  componente después de un delay o a intervalos regulares.
Ejemplo animación
Código import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Components extends JPanel { int position = 10; public void paintComponent(Graphics g) { super.paintComponent(g); g.drawLine(position,10,position + 20,90); position ++; if(position > 300) position = 10;}}
Código import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MovingLine extends JFrame implements ActionListener {Timer timer; boolean frozen = false; Component moving; MovingLine(int fps, String windowTitle) { super(windowTitle); int delay = (fps > 0) ? (1000 / fps) : 100; timer = new Timer(delay, this);
Código timer.setInitialDelay(0); timer.setCoalesce(true); addWindowListener(new WindowAdapter() { public void windowIconified(WindowEvent e) {   stopAnimation();} public void windowDeiconified(WindowEvent e) {   startAnimation();} public void windowClosing(WindowEvent e) {   System.exit(0);} }); Component contents = new Components();
Código contents.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { if (frozen) { frozen = false; startAnimation(); }  else { frozen = true; stopAnimation(); }} }); getContentPane().add(contents, BorderLayout.CENTER);} //Can be invoked by any thread (since timer is thread-safe).
Código public void startAnimation() { if (frozen) { //Do nothing.  The user has requested that we //stop changing the image. } else {//Start animating! if (!timer.isRunning()) { timer.start();  } } } //Can be invoked by any thread (since timer is thread-safe). public void stopAnimation() { //Stop the animating thread. if (timer.isRunning()) { timer.stop();} }
Código public void actionPerformed(ActionEvent e) { //Advance the animation frame. repaint(); } public static void main(String args[]) { int fps = 10; //Get frames per second from the command line argument. if (args.length > 0) {try { fps = Integer.parseInt(args[0]); } catch (Exception e) {} } MovingLine moving = new MovingLine(fps, &quot;Moving line with Timer --&quot; + &quot;Click to pause or continue&quot;);
Código moving.pack(); moving.setSize(600,200); moving.setVisible(true); //It's OK to start the animation here because  //startAnimation can be invoked by any thread. moving.startAnimation();  }}
Applet, Timer y SwingWorker
Código import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.net.*; public class TumbleItem extends JApplet implements ActionListener { int loopslot = -1;  //nro.de frame actual String dir;  //direct.relativo desde el cual cargo las 17 imágenes Timer timer;  int pause;  //long. de pausas int offset;  //offset entre loops int off;  //offset actual
Código int speed;  //veloc.de animación int nimgs;  //nro.de imágenes a animar int width;  //ancho del content pane del applet JComponent contentPane;  ImageIcon imgs[];  //imágenes int maxWidth;  //ancho máx.de las imágenes boolean finishedLoading = false; JLabel statusLabel; static Color[] labelColor = { Color.black, Color.black, Color.black, Color.black, Color.black, Color.white, Color.white, Color.white,Color.white, Color.white };
Código public void init() { //parámetros del applet..... //Anima de derecha a izquierda si offset es negativo. width = getSize().width; if (offset < 0) {off = width - maxWidth;} //dibuja la imagen actual a un particular offset. contentPane = new JPanel() {  public void paintComponent(Graphics g) {super.paintComponent(g); if (finishedLoading &&(loopslot > -1) && (loopslot < nimgs)) { imgs[loopslot].paintIcon(this, g, off, 0);}}}; contentPane.setBackground(Color.white);
Código setContentPane(contentPane); //&quot;Loading Images...&quot; label  statusLabel = new JLabel(&quot;Loading Images...&quot;, JLabel.CENTER); statusLabel.setForeground(labelColor[0]); contentPane.setLayout(new BorderLayout()); contentPane.add(statusLabel, BorderLayout.CENTER); //Set up timer, no comience h/cargar todas las imágenes  timer = new Timer(speed, this); timer.setInitialDelay(pause); imgs = new ImageIcon[nimgs]; timer.start(); //comienza la animación
Código //Carga de imágenes puede tomar mucho tiempo, las carga en un SwingWorker thread final SwingWorker worker = new SwingWorker() { public Object construct() { //Imágenes numeradas de 1 a nimgs, for (int i = 0; i < nimgs; i++) {imgs[i] = createFrame(i+1);} finishedLoading = true; return imgs;} public void finished() {//saca la etiqueta &quot;Loading images&quot; contentPane.removeAll(); contentPane.repaint(); loopslot = -1;}};
Código worker.start();} protected ImageIcon createFrame(int imageNum) { String path = dir + &quot;/T&quot; + imageNum + &quot;.gif&quot;; URL imgURL = this.getClass().getResource(path); if (imgURL != null) { return new ImageIcon(imgURL);}  else {System.err.println(&quot;Couldn't find file: &quot; + path); return null;}} public void start() { if (finishedLoading && (nimgs > 1)) { timer.restart();}} public void stop() {timer.stop();}
Código //actualiza nro.de frame y offset. //si es el último frame, hacer una pausa larga entre loops public void actionPerformed(ActionEvent e) { loopslot++; if (!finishedLoading) { int colorIndex = loopslot % labelColor.length; statusLabel.setForeground(labelColor[colorIndex]); return;}
Código if (loopslot >= nimgs) { loopslot = 0; off += offset; if (off < 0) { off = width - maxWidth; } else if (off + maxWidth > width) { off = 0;}} contentPane.repaint(); if (loopslot == nimgs - 1) { timer.restart();}}
Código

Más contenido relacionado

La actualidad más candente

Formularios y contenedores
Formularios y contenedoresFormularios y contenedores
Formularios y contenedoreszeta2015
 
Clase n°2 3-4 java
Clase n°2 3-4 javaClase n°2 3-4 java
Clase n°2 3-4 javajbersosa
 
Manuales seminario java-manualdejava-sem 3 - 4
Manuales seminario java-manualdejava-sem 3 - 4Manuales seminario java-manualdejava-sem 3 - 4
Manuales seminario java-manualdejava-sem 3 - 4Robert Wolf
 
Clase n°1 java
Clase n°1 javaClase n°1 java
Clase n°1 javajbersosa
 
Programación Orientada a Eventos Java
Programación Orientada a Eventos JavaProgramación Orientada a Eventos Java
Programación Orientada a Eventos JavaJosé Mendoza
 
Java Listeners
Java ListenersJava Listeners
Java ListenersMagikJames
 
Java GUI La librería Swing
Java GUI La librería Swing Java GUI La librería Swing
Java GUI La librería Swing Laura
 
Sesion 07 nivel_acceso_miembros_clases
Sesion 07 nivel_acceso_miembros_clasesSesion 07 nivel_acceso_miembros_clases
Sesion 07 nivel_acceso_miembros_clasesecodereck
 
Jyoc java-cap23 j unit
Jyoc java-cap23 j unitJyoc java-cap23 j unit
Jyoc java-cap23 j unitJyoc X
 
AWT- JAVA
AWT- JAVAAWT- JAVA
AWT- JAVAale8819
 
ActionScript 3 - Iniciación
ActionScript 3 - IniciaciónActionScript 3 - Iniciación
ActionScript 3 - IniciaciónFrancisco Ortiz
 
Jyoc java-cap05 metodos (funciones)
Jyoc java-cap05 metodos (funciones)Jyoc java-cap05 metodos (funciones)
Jyoc java-cap05 metodos (funciones)Jyoc X
 
INFOSAN Objetos del navegador
INFOSAN Objetos del navegador INFOSAN Objetos del navegador
INFOSAN Objetos del navegador FRANCIACOCO
 
Librería swing java
Librería swing javaLibrería swing java
Librería swing javapgpg2006
 
Constructores en java(grupo 8)
Constructores en java(grupo 8)Constructores en java(grupo 8)
Constructores en java(grupo 8)Manuel Ch.
 

La actualidad más candente (20)

Formularios y contenedores
Formularios y contenedoresFormularios y contenedores
Formularios y contenedores
 
Clase n°2 3-4 java
Clase n°2 3-4 javaClase n°2 3-4 java
Clase n°2 3-4 java
 
Manuales seminario java-manualdejava-sem 3 - 4
Manuales seminario java-manualdejava-sem 3 - 4Manuales seminario java-manualdejava-sem 3 - 4
Manuales seminario java-manualdejava-sem 3 - 4
 
Clase n°1 java
Clase n°1 javaClase n°1 java
Clase n°1 java
 
Programación Orientada a Eventos Java
Programación Orientada a Eventos JavaProgramación Orientada a Eventos Java
Programación Orientada a Eventos Java
 
Java Listeners
Java ListenersJava Listeners
Java Listeners
 
Java GUI La librería Swing
Java GUI La librería Swing Java GUI La librería Swing
Java GUI La librería Swing
 
Sesion 07 nivel_acceso_miembros_clases
Sesion 07 nivel_acceso_miembros_clasesSesion 07 nivel_acceso_miembros_clases
Sesion 07 nivel_acceso_miembros_clases
 
Jyoc java-cap23 j unit
Jyoc java-cap23 j unitJyoc java-cap23 j unit
Jyoc java-cap23 j unit
 
AWT- JAVA
AWT- JAVAAWT- JAVA
AWT- JAVA
 
ActionScript 3 - Iniciación
ActionScript 3 - IniciaciónActionScript 3 - Iniciación
ActionScript 3 - Iniciación
 
Jyoc java-cap05 metodos (funciones)
Jyoc java-cap05 metodos (funciones)Jyoc java-cap05 metodos (funciones)
Jyoc java-cap05 metodos (funciones)
 
Sesion12-componentes Visuales java
Sesion12-componentes Visuales javaSesion12-componentes Visuales java
Sesion12-componentes Visuales java
 
INFOSAN Objetos del navegador
INFOSAN Objetos del navegador INFOSAN Objetos del navegador
INFOSAN Objetos del navegador
 
Unidad 5: Excepciones Ejercicio 3
Unidad 5: Excepciones Ejercicio 3Unidad 5: Excepciones Ejercicio 3
Unidad 5: Excepciones Ejercicio 3
 
Librería swing java
Librería swing javaLibrería swing java
Librería swing java
 
Javaintroduccion 2010
Javaintroduccion 2010Javaintroduccion 2010
Javaintroduccion 2010
 
Constructores en java(grupo 8)
Constructores en java(grupo 8)Constructores en java(grupo 8)
Constructores en java(grupo 8)
 
Swin01
Swin01Swin01
Swin01
 
Semana 2 Clases y Objetos en Java
Semana 2   Clases y Objetos en JavaSemana 2   Clases y Objetos en Java
Semana 2 Clases y Objetos en Java
 

Destacado

Meu Amigo
Meu AmigoMeu Amigo
Meu AmigoJNR
 
Lista De Desejos!!
Lista De Desejos!!Lista De Desejos!!
Lista De Desejos!!JNR
 
FatlaBloqueCierre
FatlaBloqueCierreFatlaBloqueCierre
FatlaBloqueCierredannyman8
 
Entrevista a José de la Mata
Entrevista a José de la MataEntrevista a José de la Mata
Entrevista a José de la MataOficinaJudicial
 
É Natal
É NatalÉ Natal
É NatalJNR
 
Presentacion Proxima Parada OtoñO
Presentacion Proxima Parada OtoñOPresentacion Proxima Parada OtoñO
Presentacion Proxima Parada OtoñOarosaymartaa
 
Emprego doméstico no mercado de trabalho da região metropolitana de porto alegre
Emprego doméstico no mercado de trabalho da região metropolitana de porto alegreEmprego doméstico no mercado de trabalho da região metropolitana de porto alegre
Emprego doméstico no mercado de trabalho da região metropolitana de porto alegreFundação de Economia e Estatística
 
Portfolio
PortfolioPortfolio
Portfoliodidja2
 
Obrigado Senhor Oracao De Sao Francisco
Obrigado Senhor   Oracao De Sao FranciscoObrigado Senhor   Oracao De Sao Francisco
Obrigado Senhor Oracao De Sao FranciscoJNR
 
Destruccion de mi mundo
Destruccion de mi mundoDestruccion de mi mundo
Destruccion de mi mundoJocelyn4
 
Analisis de riesgos cds
Analisis de riesgos cdsAnalisis de riesgos cds
Analisis de riesgos cdsfrancisco
 
Apresentação fotos isabel
Apresentação fotos isabelApresentação fotos isabel
Apresentação fotos isabelCarlos Abrunhosa
 
Vila Arboreto - Tecnisa - Lafer Fernandes 8319.5675
 Vila Arboreto - Tecnisa - Lafer Fernandes 8319.5675 Vila Arboreto - Tecnisa - Lafer Fernandes 8319.5675
Vila Arboreto - Tecnisa - Lafer Fernandes 8319.5675LCLafer
 
Meus alunos do dinah2010 matutino 7ª a e b;8ª a e b
Meus alunos do dinah2010 matutino 7ª a e b;8ª a e bMeus alunos do dinah2010 matutino 7ª a e b;8ª a e b
Meus alunos do dinah2010 matutino 7ª a e b;8ª a e bAntonio Carneiro
 

Destacado (20)

Meu Amigo
Meu AmigoMeu Amigo
Meu Amigo
 
Lista De Desejos!!
Lista De Desejos!!Lista De Desejos!!
Lista De Desejos!!
 
FatlaBloqueCierre
FatlaBloqueCierreFatlaBloqueCierre
FatlaBloqueCierre
 
Basquetebol
BasquetebolBasquetebol
Basquetebol
 
Viajando. .
Viajando. .Viajando. .
Viajando. .
 
Entrevista a José de la Mata
Entrevista a José de la MataEntrevista a José de la Mata
Entrevista a José de la Mata
 
É Natal
É NatalÉ Natal
É Natal
 
Eu Por Eu Mesmo
Eu Por Eu MesmoEu Por Eu Mesmo
Eu Por Eu Mesmo
 
Presentacion Proxima Parada OtoñO
Presentacion Proxima Parada OtoñOPresentacion Proxima Parada OtoñO
Presentacion Proxima Parada OtoñO
 
Emprego doméstico no mercado de trabalho da região metropolitana de porto alegre
Emprego doméstico no mercado de trabalho da região metropolitana de porto alegreEmprego doméstico no mercado de trabalho da região metropolitana de porto alegre
Emprego doméstico no mercado de trabalho da região metropolitana de porto alegre
 
Portfolio
PortfolioPortfolio
Portfolio
 
Obrigado Senhor Oracao De Sao Francisco
Obrigado Senhor   Oracao De Sao FranciscoObrigado Senhor   Oracao De Sao Francisco
Obrigado Senhor Oracao De Sao Francisco
 
Labellezaazul
LabellezaazulLabellezaazul
Labellezaazul
 
Destruccion de mi mundo
Destruccion de mi mundoDestruccion de mi mundo
Destruccion de mi mundo
 
Analisis de riesgos cds
Analisis de riesgos cdsAnalisis de riesgos cds
Analisis de riesgos cds
 
Apresentação fotos isabel
Apresentação fotos isabelApresentação fotos isabel
Apresentação fotos isabel
 
Vila Arboreto - Tecnisa - Lafer Fernandes 8319.5675
 Vila Arboreto - Tecnisa - Lafer Fernandes 8319.5675 Vila Arboreto - Tecnisa - Lafer Fernandes 8319.5675
Vila Arboreto - Tecnisa - Lafer Fernandes 8319.5675
 
Meus alunos do dinah2010 matutino 7ª a e b;8ª a e b
Meus alunos do dinah2010 matutino 7ª a e b;8ª a e bMeus alunos do dinah2010 matutino 7ª a e b;8ª a e b
Meus alunos do dinah2010 matutino 7ª a e b;8ª a e b
 
slide aluno
slide alunoslide aluno
slide aluno
 
Catalogo argos
Catalogo argosCatalogo argos
Catalogo argos
 

Similar a Java UI event handling

Similar a Java UI event handling (20)

6.eventos y swing
6.eventos y swing6.eventos y swing
6.eventos y swing
 
Flow layout
Flow layoutFlow layout
Flow layout
 
Miswing 110511215936-phpapp01
Miswing 110511215936-phpapp01Miswing 110511215936-phpapp01
Miswing 110511215936-phpapp01
 
Interfaces Usuario 3
Interfaces Usuario 3Interfaces Usuario 3
Interfaces Usuario 3
 
Clase event
Clase eventClase event
Clase event
 
2 desarrollo interfaz_grafico-capitulo1-02otroseventos
2 desarrollo interfaz_grafico-capitulo1-02otroseventos2 desarrollo interfaz_grafico-capitulo1-02otroseventos
2 desarrollo interfaz_grafico-capitulo1-02otroseventos
 
Clase 5 JAVA 2012
Clase 5 JAVA 2012Clase 5 JAVA 2012
Clase 5 JAVA 2012
 
Event Programing & Driven Mediator Pattern
Event Programing & Driven Mediator PatternEvent Programing & Driven Mediator Pattern
Event Programing & Driven Mediator Pattern
 
Awt
AwtAwt
Awt
 
Programación i
Programación iProgramación i
Programación i
 
03 interfaces gráficas awt
03   interfaces gráficas awt03   interfaces gráficas awt
03 interfaces gráficas awt
 
Java construye las interfaces gráficas del usuario mediante awt
Java construye las interfaces gráficas del usuario mediante awtJava construye las interfaces gráficas del usuario mediante awt
Java construye las interfaces gráficas del usuario mediante awt
 
Java 120706083911-phpapp01
Java 120706083911-phpapp01Java 120706083911-phpapp01
Java 120706083911-phpapp01
 
Guia4 java
Guia4 javaGuia4 java
Guia4 java
 
Programacion en JAVA 2
Programacion en JAVA 2Programacion en JAVA 2
Programacion en JAVA 2
 
Menejo de eventos en java introduccion
Menejo de eventos en java introduccionMenejo de eventos en java introduccion
Menejo de eventos en java introduccion
 
Interfaces graficas(1)
Interfaces graficas(1)Interfaces graficas(1)
Interfaces graficas(1)
 
Java
JavaJava
Java
 
Proyecto sencillo con gui
Proyecto sencillo con guiProyecto sencillo con gui
Proyecto sencillo con gui
 
Eventos en Java
Eventos en JavaEventos en Java
Eventos en Java
 

Java UI event handling

  • 1. Java UI – Manejo de eventos  En Java los eventos son representados por objetos  Ejemplos:  clic en un botón  arrastrar el mouse  pulsar Enter  Los componentes AWT y Swing generan ( fire ) eventos  java.awt.AWTEvent
  • 2. Los XXXEvent nos informan...  Quién lo dispara?  De qué tipo es?  Cuándo ocurrió?  Información propia del evento Los detalles del evento pueden ser obtenidos usando métodos de acceso: Ej.: getActionCommand() getModifiers()
  • 3. Eventos AWT  De bajo nivel  Componentes – ComponentEvent, FocusEvent, KeyEvent, MouseEvent PaintEvent  Contenedores – ContainerEvent  Ventanas – WindowEvent  Semánticos – mayor nivel de abstracción  ActionEvent, ItemEvent, TextEvent, AdjustmentEvent
  • 5. Eventos semánticos  No son disparados por todos los componentes  Ejemplo 1: ItemEvent indica que un ítem fue seleccionado o deseleccionado  Disparado por JComboBox  No disparado por JButton  Ejemplo 2: ActionEvent  Disparado por JComboBox  Disparado por JButton
  • 6. Eventos Swing  Swing tiene además su propio paquete de manejo de eventos: javax.swing.event  Casi todos estos nuevos eventos están relacionados con la arquitectura MVC  Ejemplo:  TreeModelEvent  ListDataEvent
  • 7. Manejo de eventos  Modelo de Delegación de Eventos  Interfaces “listeners”  Registro para recibir eventos de una fuente  Patrón Observer
  • 8. Manejo de eventos Button Event Event Listeners Event Sources addActionListener(ActionListener l)
  • 9. Listeners  Interfaces que manejan los eventos (java.util.EventListener). Basadas en Observer  Cada clase Event tiene su correspondiente interface Listener  Varios Listeners para el mismo tipo de eventos ActionEvent ActionListener MouseEvent MouseListener MouseMotionListener
  • 10. Listeners Ejemplos de Listeners:
  • 11. public interface WindowListener extends EventListerner { void windowActivated(WindowEvent e); void windowClosed(WindowEvent e); void windowClosing(WindowEvent e); void windowDeactivated(WindowEvent e); void windowDeiconified(WindowEvent e); void windowIconified(WindowEvent e); void windowOpened(WindowEvent e);} public interface MouseListener extends EventListener { public void mouseClicked(MouseEvent e); public void mousePressed(MouseEvent e); public void mouseReleased(MouseEvent e); public void mouseEntered(MouseEvent e); public void mouseExited(MouseEvent e);}
  • 12. Registro de Listeners  Un Listener debe en primer lugar registrarse con la(s) fuente(s) que pueda(n) generar los eventos de su interés:  public void addXXXListener(XXXListener e)  addActionListener, addItemListener, etc.  Para el mismo evento en un componente, puede haber registrado varios Listeners  Un evento puede provocar numerosas respuestas  Los eventos son “difundidos” a todos sus Listeners
  • 13. Múltiples Listeners Component EventListener addEventListener Event Ocurre evento EventListener Event Ocurre evento addEventListener
  • 14. Conectar un Listener con una fuente de eventos  Defina una clase que implemente la interface Listener(o que extienda una clase que la implemente)  Añada la implementación de la interface  Registre el Listener con la fuente
  • 15. Tips  Debe implementar todos los métodos de la interface Si el código usado para implementar el manejo de eventos tiene unas pocas líneas se suele usar una clase interna anónima.  No hay garantía de cuál Listener es notificado primero. No escribir código contando con un orden específico.  Trate eventos semánticos antes que de bajo nivel  cambios en look and feel  componentes compuestos  Utilice métodos descriptivos de los eventos  ActionEvent – getActionCommand()  Threads
  • 16. Clases Adapter  Son clases que implementan una interface Listener con métodos vacíos (“dummy”), uso herencia. Desventaja: Java no permite herencia múltiple Solución: usar clases internas anónimas  Utiles sólo para interfaces Listeners con más de un método  Principalmente por razones de conveniencia  Ejemplos:  MouseAdapter  WindowAdapter
  • 17. Clases internas  En Java una clase puede ser definida en cualquier lugar  Anidada dentro de otras clases  En la invocación de un método  Tienen acceso a los miembros y métodos de todas las clases externas a ellas  Pueden tener nombres o ser anónimas  Pueden extender de otra clase o implementar interfaces  Muy útiles para el manejo de eventos
  • 18. Clases internas con nombre  Se definen como las clases normales  No pueden ser public
  • 19. Clases internas con nombre public class MyClass extends JPanel { … anObject.addMouseListener(new MyAdapter()); … class myAdapter extends MouseAdapter { public void mouseClicked(MouseEvent e) { // blah } // end mouseClicked } // end inner class } // end MyClass
  • 20. Clases internas anónimas  Definida dentro de addXXXListener (new classNam e( ) { classBody }); (new interfaceNam e() { classBody }); Dentro del cuerpo no puedo definir constructores.
  • 22. Código // importa los símbolos de AWT and Swing import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SimpleEvents extends JFrame { static final int WIDTH=350; //ancho y alto del frame static final int HEIGHT=180; // Declara JTextField para entrar texto JTextField textField; // Declara JTextArea p/recibir líneas de textField JTextArea textList; // Declara JScrollPane para JTextArea JScrollPane pane; // Constructor:aquí se hace casi todo el trabajo public SimpleEvents(String lab) { // llama el constructor de Jframe:pone etiqueta super(lab);
  • 23. Código /******* Crea un contedor para textField ****/ // Instancia un JPanel JPanel textPanel = new JPanel(); // le pone un borde (por defecto no tiene) textPanel.setBorder(BorderFactory.createEtchedBorder()); // Set el layout del textPanel a BorderLayout textPanel.setLayout(new BorderLayout()); // Crea una etiqueta y la añade al panel JLabel textTitle =new JLabel(&quot;Type and hit <ENTER>&quot;); textPanel.add(textTitle, BorderLayout.NORTH); // Instancia un JTextField y añade a textPanel textField = new JTextField(); textPanel.add(textField, BorderLayout.SOUTH); // Añade un strut al textPanel como margen inferior textPanel.add(Box.createVerticalStrut(6)); // Crea un contenedor p/ textArea // Instancia un JPanel JPanel listPanel = new JPanel();
  • 24. Código // añade borde listPanel.setBorder (BorderFactory.createEtchedBorder()); // Set el layout del textPanel listPanel.setLayout(new BoxLayout(listPanel,BoxLayout.Y_AXIS)); // Crea una etiqueta y añade al panel JLabel title = new JLabel(&quot;Text List&quot;); listPanel.add(title); // Añade un strut al BoxLayout listPanel.add(Box.createVerticalStrut(10)); // Instancia una JTextArea sin texto inicial // 6 filas, 10 columnas, y vertical scrollbars textList=new JTextArea(&quot;&quot;, 6, 10); // la hace read-only textList.setEditable(false); // Añade textList a listPanel pane = new JScrollPane (textList); listPanel.add(pane);
  • 25. Código // Añade un strut a listPanel como margen inferior listPanel.add(Box.createVerticalStrut(6)); /* Añade un listener a textField cuando se pulse ENTER copia el texto de textField al area de texto. Los componentes están interrelacionados*/ textField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // Añade el texto de textField a textList textList.append(textField.getText()); textList.append(&quot;&quot;); // Reset el textField textField.setText(&quot;&quot;); }}); // Añade los 2 paneles al frame, separados por strut Container c = getContentPane(); c.setLayout (new FlowLayout()); c.add(textPanel); c.add(Box.createHorizontalStrut(30)); c.add(listPanel);}
  • 26. Código public static void main(String args[]) { SimpleEvents frame = new SimpleEvents(&quot;Simple Events Example&quot;); // standard adapter usado en casi todas las // aplicaciones para cerrar la ventana frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); // set el tamaño de frame y lo muestra frame.setSize(WIDTH, HEIGHT); frame.setVisible(true); } }
  • 27. Command Pattern  Command encapsula un requerimiento en un objeto, permitiendo parametrizar clientes con diferentes requerimientos, hacer una cola o registro de ellos y permitir por lo tanto hacer undo/redo.
  • 29. Swing Action  Command permite desacoplar el objeto invocante (Invoker) del receptor (Receiver, el que conoce cómo atender el requerimiento).  Swing implementa el patrón Command con objectos de clases que implementen Action, por ej., subclases de AbstractAction. Siempre que selecciona un ítem de un menú o pulsa un botón, estos objetos action emiten un requerimiento de una acción específica de la aplicación.
  • 30.  
  • 31. Swing Action  Puede configurar un objeto JBbutton mediante una implementación concreta de Action que delega el requerimiento al Receiver.  JButton actúa como Invoker llamando al método actionPerformed de un objeto concreto Action y no le importa qué objeto ejecuta realmente el comando requerido.  El objeto Action delega el llamado al objeto Receiver que sabe cómo procesar el requerimiento, pero no quién lo hizo.  El Receiver puede ser modificado o ser otro objeto y no afectar el código en JButton y del mismo modo se puede añadir el pedido de nuevos objetos, sin afectar al Receiver.
  • 33. Código import java.awt.*; import java.awt.event.*; import javax.swing.*; class ColorAction extends AbstractAction{ private Component target; public ColorAction(String name, Icon icon,Color c, Component comp) {putValue(Action.NAME, name); putValue(Action.SMALL_ICON, icon); putValue(&quot;Color&quot;, c); target = comp;}
  • 34. Código public void actionPerformed(ActionEvent evt) { Color c = (Color)getValue(&quot;Color&quot;); target.setBackground(c); target.repaint();}} class ActionButton extends JButton{ public ActionButton(Action a){ setText((String)a.getValue(Action.NAME)); Icon icon = (Icon)a.getValue(Action.SMALL_ICON); if (icon != null) setIcon(icon); addActionListener(a);}}
  • 35. Código class SeparateGUIFrame extends JFrame{ public SeparateGUIFrame(){ setTitle(&quot;SeparateGUITest&quot;); setSize(300, 200); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0);}}); JPanel panel = new JPanel(); Action blueAction = new ColorAction(&quot;Blue&quot;,new ImageIcon( &quot;blue-ball.gif&quot;),Color.blue, panel);
  • 36. Código Action yellowAction = new ColorAction(&quot;Yellow&quot;, new ImageIcon(&quot;yellow-ball.gif&quot;),Color.yellow, panel); Action redAction = new ColorAction(&quot;Red&quot;, new ImageIcon(&quot;red-ball.gif&quot;),Color.red, panel); panel.add(new ActionButton(yellowAction)); panel.add(new ActionButton(blueAction)); panel.add(new ActionButton(redAction)); panel.registerKeyboardAction(yellowAction, KeyStroke.getKeyStroke(KeyEvent.VK_Y, 0), JComponent.WHEN_IN_FOCUSED_WINDOW);
  • 37. Código panel.registerKeyboardAction(blueAction, KeyStroke.getKeyStroke(KeyEvent.VK_B, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); panel.registerKeyboardAction(redAction, KeyStroke.getKeyStroke(KeyEvent.VK_R, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); Container contentPane = getContentPane(); contentPane.add(panel); JMenu m = new JMenu(&quot;Color&quot;); m.add(yellowAction);
  • 38. Código m.add(blueAction); m.add(redAction); JMenuBar mbar = new JMenuBar(); mbar.add(m); setJMenuBar(mbar);}} public class SeparateGUITest{ public static void main(String[] args){ JFrame frame = new SeparateGUIFrame(); frame.show();}}
  • 39. Threads y Swing  Si su programa crea y se refiere a la GUI en forma correcta, probablemente no tenga que preocuparse de este tema.  Si su programa crea threads para realizar tareas que afecten la GUI, o si manipula la GUI ya visible en respuesta a algo que no sea un evento standard, sea cuidadoso!
  • 40. Regla  Regla del thread único: “ Una vez que un componente se “realizó”, todo código que pueda afectarlo o dependa del estado del mismo, debería ejecutarse en el “ event-dispatching thread ”.”  Hay unas pocas excepciones: http://java.sun.com/docs/books/tutorial/uiswing/overview/threads.html
  • 41. La historia real Usualmente se piensa en un programa como un único conjunto lineal de pasos a ejecutar, aunque ocurre algo especial cuando se crean objetos gráficos. import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println (“Finished making GUI”); }// main }// class HelloGUI
  • 42. Event-dispatching thread import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println (“Finished making GUI”); }// main }// class HelloGUI
  • 43. Las dos áreas de un programa con GUI Su código Graphics 1 El código que escribe en main() Y otros métodos 2 El código que Java provee para manejar la parte gráfica de la aplicación. import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println (“Finished making GUI”); }// main }// class HelloGUI
  • 44. Event-dispatching thread Mouse Click El código para manejar este evento import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println (“Finished making GUI”); }// main }// class HelloGUI callback
  • 45. Event-dispatching thread Registro de eventos antes que ocurren
  • 46. Event-dispatching thread public void actionPerformed (ActionEvent e) { // code doing something } Este método DEBE estar aquí, tal que Java lo sabe y puede “callback” al mismo. import java.awt.*; public class HelloGUI { public static void main (String[ ] arg) { System.out.println (“About to make GUI”); Frame f = new Frame (“Hello GUIs”); f.setSize( 200, 200 ); f.show(); System.out.println (“Finished making GUI”); }// main }// class HelloGUI callback ActionListener
  • 47. Cuando conviene usar threads?  Para mover, fuera del thread principal, una tarea de inicialización que requiera mucho tiempo y para que la GUI sea más rápida (ej.: cálculos intensivos, I/O en disco tal como carga de imágenes).  Para mover fuera del event-dispatching thread, tareas que requieran mucho tiempo, de forma tal que la GUI permanezca sensible . ( Ejecutar el código de manejo de eventos en un único thread garantiza que el manejo de cada uno de ellos terminará de ejecutarse antes del manejo del siguiente)  Para ejecutar una operación repetidamente, usualmente a iguales intervalos de tiempo.  Para esperar mensajes de otros programas.
  • 48. Programas Multi-threads  Debería analizar el código de su programa y documentar desde cuál thread se invoca cada método.  Si no está seguro si su código se está ejecutando en el thread de eventos use SwingUtilities.isEventDispatchThread() que retorna true si se est á ejecutando en el EDT.  Invoque SwingUtilities.invokeLater (preferido, retorna inmediatamente sin esperar que el EDT ejecute el código) o SwingUtilities.invokeAndWait desde cualquier thread para requerir que el EDT ejecute cierto código que involucre un acceso a la GUI.
  • 49. Programas Multi-threads Ejemplo: un thread que necesita acceder a un par de text fields: void printTextField() throws Exception { final String[] myStrings = new String[2]; Runnable getTextFieldText = new Runnable() { public void run() { myStrings[0] = textField0.getText(); myStrings[1] = textField1.getText(); } }; SwingUtilities.invokeAndWait(getTextFieldText); System.out.println(myStrings[0] + &quot; &quot; + myStrings[1]); }
  • 50. Programas Multi-threads  SwingWorker  Crea un thread para ejecutar operaciones que requieran mucho tiempo. Después que las mismas finalizan, da la opción de ejecutar código adicional en el EDT.  no está en Swing release.  métodos construct() and finish()  javax.swing.Timer  Se suele usar si se necesita actualizar un componente después de un delay o a intervalos regulares.
  • 52. Código import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Components extends JPanel { int position = 10; public void paintComponent(Graphics g) { super.paintComponent(g); g.drawLine(position,10,position + 20,90); position ++; if(position > 300) position = 10;}}
  • 53. Código import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MovingLine extends JFrame implements ActionListener {Timer timer; boolean frozen = false; Component moving; MovingLine(int fps, String windowTitle) { super(windowTitle); int delay = (fps > 0) ? (1000 / fps) : 100; timer = new Timer(delay, this);
  • 54. Código timer.setInitialDelay(0); timer.setCoalesce(true); addWindowListener(new WindowAdapter() { public void windowIconified(WindowEvent e) { stopAnimation();} public void windowDeiconified(WindowEvent e) { startAnimation();} public void windowClosing(WindowEvent e) { System.exit(0);} }); Component contents = new Components();
  • 55. Código contents.addMouseListener(new MouseAdapter() { public void mousePressed(MouseEvent e) { if (frozen) { frozen = false; startAnimation(); } else { frozen = true; stopAnimation(); }} }); getContentPane().add(contents, BorderLayout.CENTER);} //Can be invoked by any thread (since timer is thread-safe).
  • 56. Código public void startAnimation() { if (frozen) { //Do nothing. The user has requested that we //stop changing the image. } else {//Start animating! if (!timer.isRunning()) { timer.start(); } } } //Can be invoked by any thread (since timer is thread-safe). public void stopAnimation() { //Stop the animating thread. if (timer.isRunning()) { timer.stop();} }
  • 57. Código public void actionPerformed(ActionEvent e) { //Advance the animation frame. repaint(); } public static void main(String args[]) { int fps = 10; //Get frames per second from the command line argument. if (args.length > 0) {try { fps = Integer.parseInt(args[0]); } catch (Exception e) {} } MovingLine moving = new MovingLine(fps, &quot;Moving line with Timer --&quot; + &quot;Click to pause or continue&quot;);
  • 58. Código moving.pack(); moving.setSize(600,200); moving.setVisible(true); //It's OK to start the animation here because //startAnimation can be invoked by any thread. moving.startAnimation(); }}
  • 59. Applet, Timer y SwingWorker
  • 60. Código import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.net.*; public class TumbleItem extends JApplet implements ActionListener { int loopslot = -1; //nro.de frame actual String dir; //direct.relativo desde el cual cargo las 17 imágenes Timer timer; int pause; //long. de pausas int offset; //offset entre loops int off; //offset actual
  • 61. Código int speed; //veloc.de animación int nimgs; //nro.de imágenes a animar int width; //ancho del content pane del applet JComponent contentPane; ImageIcon imgs[]; //imágenes int maxWidth; //ancho máx.de las imágenes boolean finishedLoading = false; JLabel statusLabel; static Color[] labelColor = { Color.black, Color.black, Color.black, Color.black, Color.black, Color.white, Color.white, Color.white,Color.white, Color.white };
  • 62. Código public void init() { //parámetros del applet..... //Anima de derecha a izquierda si offset es negativo. width = getSize().width; if (offset < 0) {off = width - maxWidth;} //dibuja la imagen actual a un particular offset. contentPane = new JPanel() { public void paintComponent(Graphics g) {super.paintComponent(g); if (finishedLoading &&(loopslot > -1) && (loopslot < nimgs)) { imgs[loopslot].paintIcon(this, g, off, 0);}}}; contentPane.setBackground(Color.white);
  • 63. Código setContentPane(contentPane); //&quot;Loading Images...&quot; label statusLabel = new JLabel(&quot;Loading Images...&quot;, JLabel.CENTER); statusLabel.setForeground(labelColor[0]); contentPane.setLayout(new BorderLayout()); contentPane.add(statusLabel, BorderLayout.CENTER); //Set up timer, no comience h/cargar todas las imágenes timer = new Timer(speed, this); timer.setInitialDelay(pause); imgs = new ImageIcon[nimgs]; timer.start(); //comienza la animación
  • 64. Código //Carga de imágenes puede tomar mucho tiempo, las carga en un SwingWorker thread final SwingWorker worker = new SwingWorker() { public Object construct() { //Imágenes numeradas de 1 a nimgs, for (int i = 0; i < nimgs; i++) {imgs[i] = createFrame(i+1);} finishedLoading = true; return imgs;} public void finished() {//saca la etiqueta &quot;Loading images&quot; contentPane.removeAll(); contentPane.repaint(); loopslot = -1;}};
  • 65. Código worker.start();} protected ImageIcon createFrame(int imageNum) { String path = dir + &quot;/T&quot; + imageNum + &quot;.gif&quot;; URL imgURL = this.getClass().getResource(path); if (imgURL != null) { return new ImageIcon(imgURL);} else {System.err.println(&quot;Couldn't find file: &quot; + path); return null;}} public void start() { if (finishedLoading && (nimgs > 1)) { timer.restart();}} public void stop() {timer.stop();}
  • 66. Código //actualiza nro.de frame y offset. //si es el último frame, hacer una pausa larga entre loops public void actionPerformed(ActionEvent e) { loopslot++; if (!finishedLoading) { int colorIndex = loopslot % labelColor.length; statusLabel.setForeground(labelColor[colorIndex]); return;}
  • 67. Código if (loopslot >= nimgs) { loopslot = 0; off += offset; if (off < 0) { off = width - maxWidth; } else if (off + maxWidth > width) { off = 0;}} contentPane.repaint(); if (loopslot == nimgs - 1) { timer.restart();}}