Soporte Java para el desarrollo de GUIs ... - fdi.ucm.es · de JDK 1.1) es mediante un mecanismo...
Transcript of Soporte Java para el desarrollo de GUIs ... - fdi.ucm.es · de JDK 1.1) es mediante un mecanismo...
Interfaces gráficas de usuario (2): Swing
Programación Orientada a ObjetosFacultad de Informática
Juan Pavón MestrasDep. Sistemas Informáticos y Programación
Universidad Complutense Madrid
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 2
Soporte Java para el desarrollo de GUIs
Swing
AWT
Soporte nativo para GUIs
Swing utiliza el modelo de eventos basado en delegación de AWT (definido a partir de Java 1.1)
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 3
Una aplicación Swing sencilla
! El comportamiento deseado para esta aplicación es:! Cuando el usuario pulsa en el botón Dí Hola, en el campo de
texto la aplicación ha de poner 'Hola'! Cuando el usuario pulsa en el botón Dí Adios, en el campo de
texto la aplicación ha de poner 'Adios'! Cuando el usuario cierra la ventana, la aplicación ha de
terminar
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 4
Una aplicación Swing sencilla
! El diseño de toda interfaz conlleva, a grandes rasgos, los siguientes pasos:! Decidir la estructura de la interfaz
• Qué componentes gráficos se van a utilizar, y cómo se van a relacionar estos componentes)
! Decidir la disposición (layout) de los componentes• Existen dos tipos de componentes: contenedores y componentes
atómicos• Los contenedores sirven para organizar los componentes
contenidos en los mismos. Esta organización se denomina disposición (o layout)
! Decidir el comportamiento de la interfaz: gestión de eventos• Algunos componentes son controles: permiten reaccionar ante
eventos del usuario. El comportamiento se especifica programando las respuestas a dichos eventos. Normalmente, dichas respuestas supondrán invocar funcionalidades de la lógica de la aplicación
• Conviene mantener la interfaz y la lógica lo más independientes posibles (veremos patrones que permiten lograr esto)
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 5
Una aplicación Swing sencilla: estructura
Loro (JFrame)
Panel Principal (JSplitPane)
Botonera (JPanel)
Hola (JButon) Adios (JButon)
Eco (JTextField)
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 6
Una aplicación Swing sencilla: estructura
import javax.swing.*;
public class Loro extends JFrame {private JTextField eco;
public Loro() {setTitle("Loro");
JComponent botonera = creaBotonera();JComponent eco = creaEco();// Crea panel con botonera y ecoJSplitPane panelPrincipal =
new JSplitPane(JSplitPane.VERTICAL_SPLIT,botonera,eco);// Añade el panel a la ventana principalgetContentPane().add(panelPrincipal);// Se 'redimensiona' toda la interfaz gráfica en la ventanapack();// Y hace visible la ventana, con sus componentessetVisible(true);
} // ...
import javax.swing.*;
public class Loro extends JFrame {private JTextField eco;
public Loro() {setTitle("Loro");
JComponent botonera = creaBotonera();JComponent eco = creaEco();// Crea panel con botonera y ecoJSplitPane panelPrincipal =
new JSplitPane(JSplitPane.VERTICAL_SPLIT,botonera,eco);// Añade el panel a la ventana principalgetContentPane().add(panelPrincipal);// Se 'redimensiona' toda la interfaz gráfica en la ventanapack();// Y hace visible la ventana, con sus componentessetVisible(true);
} // ...
Ordena la redimensión y la disposición de toda la jerarquía de componentes en la ventana
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 7
Una aplicación Swing sencilla: estructura
private JComponent creaBotonera() {JPanel botonera = new JPanel(); // Se crean los botones ...JButton hola = new JButton("Dí Hola");JButton adios = new JButton("Dí Adios");// .. y se añaden al panelbotonera.add(hola);botonera.add(adios); return botonera;
}
private JComponent creaEco() {// Se crea el campo de texto donde poner el eco
eco = new JTextField("Pulsa un botón");return eco;
} // ...
private JComponent creaBotonera() {JPanel botonera = new JPanel(); // Se crean los botones ...JButton hola = new JButton("Dí Hola");JButton adios = new JButton("Dí Adios");// .. y se añaden al panelbotonera.add(hola);botonera.add(adios); return botonera;
}
private JComponent creaEco() {// Se crea el campo de texto donde poner el eco
eco = new JTextField("Pulsa un botón");return eco;
} // ...
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 8
Una aplicación Swing sencilla: estructura
public static void main(String[] args) {Loro loro = new Loro();//... aquí termina la ejecución del 'hilo principal', // ... pero queda pendiente la ejecución del hilo de // ... tratamiento de eventos... A partir de ahora toda la // ... ejecución es gobernada por la interacción con el usuario.
}}
public static void main(String[] args) {Loro loro = new Loro();//... aquí termina la ejecución del 'hilo principal', // ... pero queda pendiente la ejecución del hilo de // ... tratamiento de eventos... A partir de ahora toda la // ... ejecución es gobernada por la interacción con el usuario.
}}
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 9
Una aplicación Swing sencilla: comportamiento
! Los controles señalizan eventos! Diferentes tipos de eventos, dependiendo de los controles! La forma de tratar eventos en Swing (y en AWT, a partir
de JDK 1.1) es mediante un mecanismo denominado delegación:! Por cada tipo de evento notificado por un control, el control
acepta un oyente de dicho evento (métodos addXXXListener)! Dicho oyente ha de implementar una interfaz adecuada
(XXXListener)! Cuando se produce un evento, el control invoca un método
apropiado del oyente. Es en este método donde se trata el evento
! Estas clases están declaradas en el paquete java.awt.event
import java.awt.event.*;
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 10
Una aplicación Swing sencilla: comportamiento
OyenteHolaactionPerformed
(ActionEvent ev)
OyenteAdiosactionPerformed
(ActionEvent ev)
OyenteVentanawindowClosing
(WindowEvent ev)
Escribir hola en el campo de texto
Escribir adios en el campo de texto
Terminar laejecución
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 11
Una aplicación Swing sencilla: comportamiento asociado a los botones
private JComponent creaBotonera() {JPanel botonera = new JPanel(); // Panel para contener los botones// Se crean los botones ...JButton hola = new JButton("Dí Hola");hola.addActionListener(
new ActionListener() {public void actionPerformed(ActionEvent ev) {
eco.setText("Hola!");}});
JButton adios = new JButton("Dí Adios");adios.addActionListener(
new ActionListener() {public void actionPerformed(ActionEvent ev) {
eco.setText("Adios!");}});
// .. y se añaden al panelbotonera.add(hola);botonera.add(adios); return botonera;
}
private JComponent creaBotonera() {JPanel botonera = new JPanel(); // Panel para contener los botones// Se crean los botones ...JButton hola = new JButton("Dí Hola");hola.addActionListener(
new ActionListener() {public void actionPerformed(ActionEvent ev) {
eco.setText("Hola!");}});
JButton adios = new JButton("Dí Adios");adios.addActionListener(
new ActionListener() {public void actionPerformed(ActionEvent ev) {
eco.setText("Adios!");}});
// .. y se añaden al panelbotonera.add(hola);botonera.add(adios); return botonera;
} Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 12
Una aplicación Swing sencilla: comportamiento asociado a la ventana principal
public Loro() {setTitle("Loro");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent ev) {// Se termina la ejecución de la aplicación
System.exit(0);}
});// ...
public Loro() {setTitle("Loro");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent ev) {// Se termina la ejecución de la aplicación
System.exit(0);}
});// ...
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 13
Funcionamiento de las aplicaciones con GUI en Java
! Java es, por diseño, un lenguaje multiproceso: en un programa Java pueden existir (y de hecho existen) simultáneamente múltiples hilos de ejecución (threads) concurrentes
! Uno de estos hilos es el hilo de tratamiento de eventos! En las aplicaciones con GUI, el hilo principal se limita a construir
la estructura de la GUI, a asociar los oyentes adecuados con loscontroles y, hecho esto, termina …
! … pero la aplicación en sí no termina, puesto que todavía queda, al menos, un hilo con vida: el de tratamiento de eventos! Este hilo se encarga de tratar automáticamente eventos rutinarios
(p.ej. redibujar una ventana cuando ésta pasa a primer plano, o cuando se quita una ventana que la ocultaba parcialmente, actualizar la presentación como resultado de cambios ordenados por la aplicación, etc.)
! … y también se encarga de tratar los eventos de usuario, invocando a los oyentes previamente registrados
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 14
Funcionamiento de las aplicaciones con GUI en Java
! Consecuencias del funcionamiento:! La aplicación avanza guiada por los eventos del usuario! Cuando, desde el código de la aplicación, se realizan cambios sobre
la interfaz (p.ej. cambiar el texto de una etiqueta, dibujar algo, limpiar un cuadro de texto, etc.) tales cambios no son inmediatos, sino que se encolan (en estructuras internas del frameworkAWT/Swing) para ser procesados por el hilo de tratamiento de eventos una vez que termine la ejecución del código del oyente que ha provocado los cambios
• La ejecución de métodos que cambian la presentación de componentes no debe interpretarse como ejecuciones, sino como promesas de ejecuciones (que se realizarán cuando sea posible)
! El tratamiento de los eventos debe ser rápido • La ejecución de los oyentes se lleva a cabo en el hilo de tratamiento de
eventos: si tal ejecución tarda mucho, o se bloquea, bloquea a dicho hilo, que no puede tratar el resto de eventos rutinarios, por lo que la aplicación en sí se bloquea, y no responderá
• Si un tratamiento de un evento necesita mucho tiempo para ser realizado, una solución puede ser crear otro hilo que lo lleve a cabo (no es sencillo porque aparecen los problemas de sincronización de hilos)
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 15
JFrame
! Toda aplicación Swing tiene, al menos, un contenedor raíz (una ventana)
! La clase JFrame proporciona ventanas al uso (aunque puede haber otro tipo de ventanas)
! A su vez, JFrame incluye una serie de elementos:• Los contenidos se
añaden en el panel de contenidos (contentpane) accesible a través del método getContentPane (por defecto, un objeto de tipo Jpane, aunque puede cambiarse con setContentPane).
• La barra de menúpuede fijarse con setJMenuBar
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 16
JFrame
import java.awt.Color;import java.awt.Dimension;import java.awt.BorderLayout;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JMenuBar;
public class TopLevelDemo {public static void main(String s[]) {
JFrame frame = new JFrame("TopLevelDemo");
frame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {
System.exit(0);}
});
//...
import java.awt.Color;import java.awt.Dimension;import java.awt.BorderLayout;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JMenuBar;
public class TopLevelDemo {public static void main(String s[]) {
JFrame frame = new JFrame("TopLevelDemo");
frame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {
System.exit(0);}
});
//...
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 17
JFrame
JLabel yellowLabel = new JLabel("");yellowLabel.setOpaque(true);yellowLabel.setBackground(Color.yellow);yellowLabel.setPreferredSize(new Dimension(200, 180));
JMenuBar cyanMenuBar = new JMenuBar();cyanMenuBar.setOpaque(true);cyanMenuBar.setBackground(Color.cyan);cyanMenuBar.setPreferredSize(new Dimension(200, 20));
frame.setJMenuBar(cyanMenuBar);frame.getContentPane().add(yellowLabel, BorderLayout.CENTER);
frame.pack();frame.setVisible(true);
}
JLabel yellowLabel = new JLabel("");yellowLabel.setOpaque(true);yellowLabel.setBackground(Color.yellow);yellowLabel.setPreferredSize(new Dimension(200, 180));
JMenuBar cyanMenuBar = new JMenuBar();cyanMenuBar.setOpaque(true);cyanMenuBar.setBackground(Color.cyan);cyanMenuBar.setPreferredSize(new Dimension(200, 20));
frame.setJMenuBar(cyanMenuBar);frame.getContentPane().add(yellowLabel, BorderLayout.CENTER);
frame.pack();frame.setVisible(true);
}Para añadir componentes a un JFrame se añaden componentes a su panel de contenidos
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 18
JSplitPane y Box: Haciendo layout fácil en Swing
! El control de la disposición en Swing (y en AWT) se delega en objetos especiales, denominados gestores de disposición (layout managers)! En AWT vimos diversos tipos de gestores de disposición, que ofrecen
mecanismos más o menos sofisticados para organizar los contenidos en un contenedor
! Swing ofrece además dos componentes que facilitan la realización del layout: ! JSplitPane permite dividir una región en dos subregiones, y asignar
a cada una de ellas un peso determinado (que dictará la forma en cómo se repartirá el espacio extra en cada subregión cuando el contenedor crezca)
! Box permite organizar vertical u horizontalmente componentes, asícomo especificar espaciado fijo entre ellos, y componentes de glue(componentes invisibles que crecen cuando la caja crece, dejando el resto de los componentes adecuadamente situados)
• Combinando JSplitPane y Box es posible especificar layouts complicados, sin necesidad de vérselas con las complejidades de más bajo nivel de los layout managers
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 19
JSplitPane y Box: Haciendo layout fácil en Swing
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 20
JSplitPane y Box: Haciendo layout fácil en Swing
peso=1
peso=0
0 1
1 0
glue glue
JSplitPane
JSplitPane
JSplitPane
Box
Box
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 21
JSplitPane y Box: Haciendo layout fácil en Swing
public class LayoutDemo {public static void main(String s[]) {
JButton b1 = new JButton("Botón 1");JButton b2 = new JButton("Botón 2");JButton b3 = new JButton("Botón 3");
Box cajaBotones = Box.createVerticalBox();cajaBotones.add(b1);cajaBotones.add(b2);cajaBotones.add(b3);cajaBotones.add(Box.createVerticalGlue());
public class LayoutDemo {public static void main(String s[]) {
JButton b1 = new JButton("Botón 1");JButton b2 = new JButton("Botón 2");JButton b3 = new JButton("Botón 3");
Box cajaBotones = Box.createVerticalBox();cajaBotones.add(b1);cajaBotones.add(b2);cajaBotones.add(b3);cajaBotones.add(Box.createVerticalGlue());
Las cajas se crean con los métodos estáticos createHorizontalBox y createVerticalBox de Box.
El glue se crea con los métodos estáticos de Box createVerticalBox y createHorizontalBox. Con createHorizontalStrut y createVerticalStrut puede introducirse espacios fijos entre los componentes
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 22
JSplitPane y Box: Haciendo layout fácil en Swing
JLabel e1 = new JLabel("Etiqueta 1");JLabel e2 = new JLabel("Etiqueta 2"); Box cajaEtiquetas = Box.createVerticalBox();cajaEtiquetas.add(e1);cajaEtiquetas.add(e2);cajaEtiquetas.add(Box.createVerticalGlue());
JSplitPane panelSecundario1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
new JPanel(),cajaEtiquetas);
panelSecundario1.setDividerSize(1); panelSecundario1.setResizeWeight(1);
JSplitPane panelSecundario2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
cajaBotones,panelSecundario1);
panelSecundario2.setDividerSize(1);
JLabel e1 = new JLabel("Etiqueta 1");JLabel e2 = new JLabel("Etiqueta 2"); Box cajaEtiquetas = Box.createVerticalBox();cajaEtiquetas.add(e1);cajaEtiquetas.add(e2);cajaEtiquetas.add(Box.createVerticalGlue());
JSplitPane panelSecundario1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
new JPanel(),cajaEtiquetas);
panelSecundario1.setDividerSize(1); panelSecundario1.setResizeWeight(1);
JSplitPane panelSecundario2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
cajaBotones,panelSecundario1);
panelSecundario2.setDividerSize(1);
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 23
JSplitPane y Box: Haciendo layout fácil en Swing
JSplitPane panelPrincipal = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
panelSecundario2,new JPanel());
panelPrincipal.setDividerSize(1); panelPrincipal.setResizeWeight(1);
JFrame frame = new JFrame("LayoutDemo");
frame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {
System.exit(0);}
});
frame.setContentPane(panelPrincipal);frame.pack();frame.setVisible(true);
}
}
JSplitPane panelPrincipal = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
panelSecundario2,new JPanel());
panelPrincipal.setDividerSize(1); panelPrincipal.setResizeWeight(1);
JFrame frame = new JFrame("LayoutDemo");
frame.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {
System.exit(0);}
});
frame.setContentPane(panelPrincipal);frame.pack();frame.setVisible(true);
}
}
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 24
Botones
! Los botones, junto con los menús, son los controles más típicos en una GUI
! Existen diferentes tipos (especializaciones de AbstractButton)! JButton: Botón aislado. Puede pulsarse, pero su estado no cambia! JToggleButton : Botón seleccionable. Cuando se pulsa el botón, su
estado pasa a seleccionado, hasta que se pulsa de nuevo (entonces se deselecciona)
• isSelected() permite chequear su estado
! JCheckBox : Especialización de JToggleButton que implementa una casilla de verificación. Botón con estado interno, que cambia de apariencia de forma adecuada según si está o no está seleccionado
! JRadioButton: Especialización de JToggleButton que tiene sentido dentro de un mismo grupo de botones (ButtonGroup) que controla que sólamente uno de ellos está seleccionado
• Nota: ButtonGroup es únicamente un controlador, no un componente)
! El evento semántico más común anunciado por los botones es ActionEvent
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 25
Botones
Box caja = Box.createHorizontalBox();caja.add(new JButton("Un botón normal"));caja.add(new JToggleButton("Un botón seleccionable"));caja.add(new JToggleButton("Otro botón seleccionable",true));caja.add(new JCheckBox("Cine"));caja.add(new JCheckBox("Teatro"));caja.add(new JCheckBox("Música"));ButtonGroup grupo = new ButtonGroup();JRadioButton r1 = new JRadioButton("Hombre");JRadioButton r2 = new JRadioButton("Mujer");JRadioButton r3 = new JRadioButton("Asexuado");
Box caja = Box.createHorizontalBox();caja.add(new JButton("Un botón normal"));caja.add(new JToggleButton("Un botón seleccionable"));caja.add(new JToggleButton("Otro botón seleccionable",true));caja.add(new JCheckBox("Cine"));caja.add(new JCheckBox("Teatro"));caja.add(new JCheckBox("Música"));ButtonGroup grupo = new ButtonGroup();JRadioButton r1 = new JRadioButton("Hombre");JRadioButton r2 = new JRadioButton("Mujer");JRadioButton r3 = new JRadioButton("Asexuado");
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 26
Botones
grupo.add(r1);grupo.add(r2);grupo.add(r3);caja.add(r1);caja.add(r2);caja.add(r3);
grupo.add(r1);grupo.add(r2);grupo.add(r3);caja.add(r1);caja.add(r2);caja.add(r3);
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 27
Menús
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 28
Menús
• La creación de una barra de menús básica supone:• Crear un objeto de tipo JMenuBar.• Para cada entrada, crear un objeto de tipo JMenu.• Incluir objetos de tipo JMenuItem en el menú. Esto puede incluir
menús anidados.• Asociar a los items acciones apropiadas (notifican eventos
semánticos de tipo ActionEvent, ya que, en realidad, especializan a AbstractButton).
• Con setJMenuBar es posible añadir una barra de menús a una ventana (JFrame).
• Importante: En una GUI, muchas veces existen controles ligados a la misma acción (eg. un botón que hace lo mismo que un itemde un menú). En este caso ambos controles pueden compartir el mismo oyente (y es aconsejable hacerlo así).
• Más importante aún: El diseño de una barra de menús debe ser consistente (poner opciones semánticamente relacionadas juntas).
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 29
Menús
public class PruebaMenu extends JFrame {public void ejecuta() {
JMenuBar barra = new JMenuBar();JMenu menu1 = new JMenu("Menú 1");menu1.add(new JMenuItem("Una opción de texto"));menu1.add(new JSeparator());ButtonGroup grupo = new ButtonGroup();JRadioButtonMenuItem r1 = new JRadioButtonMenuItem("Opción 1");JRadioButtonMenuItem r2 = new JRadioButtonMenuItem("Opción 2");grupo.add(r1);grupo.add(r2);menu1.add(r1);menu1.add(r2);menu1.add(new JSeparator());menu1.add(new JCheckBoxMenuItem("Selección 1",true));menu1.add(new JCheckBoxMenuItem("Selección 2"));
public class PruebaMenu extends JFrame {public void ejecuta() {
JMenuBar barra = new JMenuBar();JMenu menu1 = new JMenu("Menú 1");menu1.add(new JMenuItem("Una opción de texto"));menu1.add(new JSeparator());ButtonGroup grupo = new ButtonGroup();JRadioButtonMenuItem r1 = new JRadioButtonMenuItem("Opción 1");JRadioButtonMenuItem r2 = new JRadioButtonMenuItem("Opción 2");grupo.add(r1);grupo.add(r2);menu1.add(r1);menu1.add(r2);menu1.add(new JSeparator());menu1.add(new JCheckBoxMenuItem("Selección 1",true));menu1.add(new JCheckBoxMenuItem("Selección 2"));
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 30
Menús
JMenu menu11 = new JMenu("Submenú");menu11.add(new JMenuItem("Opción 1"));menu11.add(new JMenuItem("Opción 2")); menu1.add(menu11);barra.add(menu1);barra.add(new JMenu("Menú 2"));setJMenuBar(barra);pack();setVisible(true);
}public static void main(String[] args) {
new PruebaMenu().ejecuta();}}
JMenu menu11 = new JMenu("Submenú");menu11.add(new JMenuItem("Opción 1"));menu11.add(new JMenuItem("Opción 2")); menu1.add(menu11);barra.add(menu1);barra.add(new JMenu("Menú 2"));setJMenuBar(barra);pack();setVisible(true);
}public static void main(String[] args) {
new PruebaMenu().ejecuta();}}
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 31
Interacción modal
! Muchas veces surge la necesidad de lanzar, esporádicamente, ventanas secundarias para indicar algún hecho, o pedir algún dato al usuario: cuadros de diálogo
! La mayor parte de estas interacciones suelen ser modales (es decir, la ejecución del programa se interrumpe hasta que el usuario cierra el cuadro de diálogo)
! Swing ofrece la posibilidad de crear diálogos a medida…! …pero (afortunadamente), también ofrece la posibilidad de
crear/configurar diálogos prefabricados que son útiles en muchas situaciones
! ¿Cómo funciona la interacción modal?: Swing lanza un hilo adicional para manejar dichas interacciones (y el resto de los eventos rutinarios). El hilo de tratamiento de eventos se sincroniza (espera) la finalización de dicho hilo de interacción modal
! Importante: Un abuso de la interacción modal conduce a interfaces poco usables (en el límite, a interacciones tipo consola)
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 32
Interacción modal
! La clase JOptionPane ofrece un conjunto de métodos estáticos que lanzan diferentes tipos de diálogos (estos métodos están sobrecargados para poder crear diálogos con diferentes grados de fineza):! showMessageDialog : Muestra un diálogo de mensaje! showConfirmDialog : Muestra un diálogo de confirmación.
Permite determinar la opción elegida por el usuario de forma modal (yes, no, cancel)
! showInputDialog: Muestra un diálogo en el que se solicita, de forma modal, una entrada al usuario. Dependiendo de la versión de método utilizada, el usuario puede teclear la entrada, o bien seleccionarla de una lista de entradas disponibles
! showOptionDialog: Muestra un diálogo que puede personalizarse con botones (en general, con componentes) a medida
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 33
Interacción modal
JOptionPane.showMessageDialog(this, // La ventana padre."Error deconocido!: Lo llevas muy mal!", //El mensaje."Error", // El título de la ventana de diálogo.JOptionPane.ERROR_MESSAGE // El tipo de mensaje
);
JOptionPane.showMessageDialog(this, // La ventana padre."Error deconocido!: Lo llevas muy mal!", //El mensaje."Error", // El título de la ventana de diálogo.JOptionPane.ERROR_MESSAGE // El tipo de mensaje
);
JOptionPane.showMessageDialog(this,"Te informo de que lo llevas fatal", "Info",JOptionPane.INFORMATION_MESSAGE);JOptionPane.showMessageDialog(this,"Te informo de que lo llevas fatal", "Info",JOptionPane.INFORMATION_MESSAGE);
JOptionPane.showMessageDialog(this,"Te aviso de que lo llevas fatal", "Aviso",JOptionPane.WARNING_MESSAGE);
JOptionPane.showMessageDialog(this,"Te aviso de que lo llevas fatal", "Aviso",JOptionPane.WARNING_MESSAGE);
JOptionPane.showMessageDialog(this, Este mensaje es para tí, majete!", "Mensaje",
JOptionPane.PLAIN_MESSAGE);JOptionPane.showMessageDialog(this,
Este mensaje es para tí, majete!", "Mensaje", JOptionPane.PLAIN_MESSAGE);
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 34
Interacción modal
int seleccionada = JOptionPane.showConfirmDialog(this, "Lo aceptas?", "Aviso",JOptionPane.YES_NO_OPTION, // Configuración del mensajeJOptionPane.INFORMATION_MESSAGE);
switch(seleccionada) {case JOptionPane.YES_OPTION: ... // tratar SIcase JOptionPane.NO_OPTION: .. // tratar NOcase JOptionPane.CLOSED_OPTION: .. // tratar ventana cerradadefault: ... // esta opción nunca debería alcanzarse
}
int seleccionada = JOptionPane.showConfirmDialog(this, "Lo aceptas?", "Aviso",JOptionPane.YES_NO_OPTION, // Configuración del mensajeJOptionPane.INFORMATION_MESSAGE);
switch(seleccionada) {case JOptionPane.YES_OPTION: ... // tratar SIcase JOptionPane.NO_OPTION: .. // tratar NOcase JOptionPane.CLOSED_OPTION: .. // tratar ventana cerradadefault: ... // esta opción nunca debería alcanzarse
}
int seleccionada = JOptionPane.showConfirmDialog(this,
"Lo aceptas?","Aviso",JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
... // los posibles valores devueltos son los anteriores y
... // JOptionPane.CANCEL_OPTION
int seleccionada = JOptionPane.showConfirmDialog(this,
"Lo aceptas?","Aviso",JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
... // los posibles valores devueltos son los anteriores y
... // JOptionPane.CANCEL_OPTION
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 35
Interacción modal
String[] colores = {"rojo","negro","amarillo","azul","majenta"};
Object opcion = JOptionPane.showInputDialog(this,"Selecciona un color, resalao!", "Petición",JOptionPane.QUESTION_MESSAGE, null, //icono. no hay.colores, // opciones. Se le podría pasar un array de
// objetos arbitrarioscolores[0] //opción inicial
);// ...procesar opción...
String[] colores = {"rojo","negro","amarillo","azul","majenta"};
Object opcion = JOptionPane.showInputDialog(this,"Selecciona un color, resalao!", "Petición",JOptionPane.QUESTION_MESSAGE, null, //icono. no hay.colores, // opciones. Se le podría pasar un array de
// objetos arbitrarioscolores[0] //opción inicial
);// ...procesar opción...
String nombre = JOptionPane.showInputDialog(this,"Cómo te llamas, majete?","Petición", JOptionPane.QUESTION_MESSAGE
);// ... procesar entrada
String nombre = JOptionPane.showInputDialog(this,"Cómo te llamas, majete?","Petición", JOptionPane.QUESTION_MESSAGE
);// ... procesar entrada
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 36
Interacción modal
String[] sexo = {"hetero","homo","bi","auto"};int opcion =
JOptionPane.showOptionDialog(this, "Y tú qué eres?", "Petición", -1, // opciones->quedan fijadas por el array de opcionesJOptionPane.QUESTION_MESSAGE, null,//icono. no hay.sexo, // array de opcionessexo[0] // opcion inicial
);... // procesamiento de la opcion ...
String[] sexo = {"hetero","homo","bi","auto"};int opcion =
JOptionPane.showOptionDialog(this, "Y tú qué eres?", "Petición", -1, // opciones->quedan fijadas por el array de opcionesJOptionPane.QUESTION_MESSAGE, null,//icono. no hay.sexo, // array de opcionessexo[0] // opcion inicial
);... // procesamiento de la opcion ...
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 37
Interacción modal: selección de archivos
! Los diálogos de tipo JFileChooser facilitan esta tarea! La forma habitual de trabajar con JFileChooser es:
! Crear una instancia de JFileChooser.! Configurar dicha instancia de forma adecuada. Dicha configuración,
normalmente, se limita a poner filtros sobre lo que puede seleccionarse con el selector de ficheros, así como a fijar la carpeta actual (con setCurrentDirectory):
• Con setFileSelectionMode.• Con setFileFilter : Aquí debe añadirse una instancia de una subclase
adecuada de FileFilter.
! Mostrar un selector de ficheros utilizando alguno de los siguientes métodos:
• showDialog : Selector a medida.• showOpenDialog : Selector para abrir un fichero.• showSaveDialog : Selector para salvar un fichero.
! La interacción es modal: los métodos show devuelven el estado de la operación. Si todo ha ido bien, el método getSelectedFile devuelve un objeto de tipo File, que debe ser tratado de forma adecuada
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 38
Interacción modal: selección de archivos
! Creación y configuración de un selectorselector = new JFileChooser(); selector.setFileFilter(new FiltroTexto()); selector.setFileSelectionMode(JFileChooser.FILES_ONLY);selector.setCurrentDirectory(new File(System.getProperty("user.dir")));
! Un filtro de ficheros
class FiltroTexto extends FileFilter {public boolean accept(File f) {
String nombre = f.getName(); return nombre.substring(Math.max(nombre.length()-4,0)).equals(".txt");
}public String getDescription() {
return "Ficheros de tipo texto";}
}
class FiltroTexto extends FileFilter {public boolean accept(File f) {
String nombre = f.getName(); return nombre.substring(Math.max(nombre.length()-4,0)).equals(".txt");
}public String getDescription() {
return "Ficheros de tipo texto";}
}
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 39
Interacción modal: selección de archivos
! El mismo selector permite crear diferentes diálogos de selección
selector.showOpenDialog(this)
selector.showSaveDialog(this)
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 40
Interacción modal: selección de archivos
if ( selector.showOpenDialog(this) == JFileChooser.APPROVE_OPTION ) {
File f = selector.getSelectedFile();// Hacer lo que sea pertinente con el fichero ...
}
Uso habitual de un diálogo creado a través de un FileChooser
Juan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 41
Otros contenedores Swing
! JPanel. Un contenedor intermedio genérico! Se utiliza para poner otros componentes ! FlowLayout por defecto (los componentes se colocan uno
detrás de otro)
! JScrollPane. Un panel con barras de scroll! JTabbedPane. Un panel con diferentes vistas
! JToolBar. Una barra de herramientas! Puede cambiarse de situación por los bordes de su
contenedor e incluso llevarse fuera! Las herramientas suelen ser (aunque no obligatoriamente)
botonesJuan Pavón MestrasFacultad de Informática UCM, 2004 Java Swing 42
Otros componentes atómicos Swing
! JLabel. Etiquetas! JTextField. Entrada de una línea de texto! JTextArea. Entradas de varias líneas de texto! JSlider. Una barra de selección en una escala! JList. Una lista de elementos seleccionables! JComboBox. Una lista de elementos desplegable! JPopupMenu. Un menú desplegable