Desarrollo de Aplicaciones en Java INF 473 Desarrollo de Interfaces Gráficas Componentes Swing Prof. José Miguel Rubio jose.rubio.l@ucv.cl jrubio@inf.ucv.cl PUCV Marzo 2008 0
Interfaces de usuario en java El concepto de interfaz de usuario (IU) se refiere a modos de interacción entre un programa y el usuario. El entorno de Java contiene clases para funcionalidades de IU como:» Componentes gráficas» Sonido» Información de configuración (argumentos de línea de comandos en aplicaciones)» Lectura y escritura por teclado: System.in, System.out» Ficheros Interfaces gráficas de usuario:» Swing contiene las clases para generar una IU gráfica. Package javax.swing» Contiene botones, listas, menús, zonas de texto,... 1
Jerarquía de componentes JLabel Object java.awt.container JComponent JDialog JApplet JFrame JPanel JComboBox JAbstractButton JList JButton JMenuItem JCheckBox JTextArea JTextComponent JTextField Contenedores terminales: JFrame, JDialog, JApplet Línea discontinua: otras clases intermedias 2
Interfaces gráficas Referencia:» A Visual Index to the Swing Components The Java Tutorial (java.sun.com) Tamaños, formas, colores, tipos de letra, etc (java.awt.*):» Point, Rectangle, Polygon» Color (Color.black, Color.red,...)» Image» Font, FontMetrics» Graphics es un contexto gráfico (un pincel virtual): color actual, font actual,... En clase JComponent: colores de background y foreground; font (tipo de letra). Color getbackground() void setbackground(color) Foreground: {set/getforeground Font: {set/getfont 3
Ejemplo 4
Ejemplo public class MiVentana extends javax.swing.jframe { private javax.swing.jbutton jbutton2; private javax.swing.jbutton jbutton1; public MiVentana() { jbutton1 = new javax.swing.jbutton(); jbutton2 = new javax.swing.jbutton(); getcontentpane().setlayout(null); settitle("un ejemplo"); jbutton1.setbackground(java.awt.color.red); jbutton1.settext("boton 1"); getcontentpane().add(jbutton1); jbutton1.setbounds(121, 146, 120, 50); jbutton2.settext("boton 2"); getcontentpane().add(jbutton2); jbutton2.setbounds(130, 70, 77, 26); pack(); // COLOCA SEGÚN tamaños preferidos public static void main(string args[]) { new MiVentana().setVisible(true); // o bien.show(); que es deprecated 5
Disposición geométrica de componentes Acomodadores o gestores de disposición geométrica (layout managers)» Objetos que controlan la disposición (posición y tamaño) de componentes incluidas dentro de un contenedor Objetos contenedores:» getcontentpane() aplicado a objetos de: JFrame, JDialog, JApplet» objetos de la clase JPanel Cada objeto contenedor un tipo de layout manager por defecto:» BorderLayout (si provienen de ejecutar getcontentpane() )» FlowLayout (en objetos de la clase JPanel) Creación de una jerarquía a partir de un contenedor C con elementos E1, E2,.., EN y un layout manager A:» C.setLayout(A)» C.add(E1); C.add(E2);... C.add(EN); El layout manager puede ser null :» Posiciones absolutas 6
Ejemplo, I 7
Ejemplo, II public class MiVentana extends javax.swing.jframe { private javax.swing.jbutton jbutton2; private javax.swing.jbutton jbutton1; private javax.swing.jpanel jpanel2; private javax.swing.jpanel jpanel1; public MiVentana() { jpanel1 = new javax.swing.jpanel(); jpanel2 = new javax.swing.jpanel(); jbutton1 = new javax.swing.jbutton(); jbutton2 = new javax.swing.jbutton(); getcontentpane().setlayout(null); settitle("un ejemplo de layout null"); jpanel1.setbackground(java.awt.color.orange); getcontentpane().add(jpanel1); jpanel1.setbounds(30, 10, 270, 130); jpanel2.setlayout(null); 8
Ejemplo, III jpanel2.setbackground(java.awt.color.red); jbutton1.settext("jbutton1"); jpanel2.add(jbutton1); jbutton1.setbounds(20, 20, 81, 26); jbutton2.settext("jbutton2"); jpanel2.add(jbutton2); jbutton2.setbounds(120, 30, 81, 26); getcontentpane().add(jpanel2); jpanel2.setbounds(30, 180, 230, 80); pack(); public static void main(string args[]) { new MiVentana().setVisible(true); 9
Tipos de layout managers Tipos (java.awt.*): Null (posiciones absolutas) BorderLayout. Uso de norte, sur, este, oeste, centro. FlowLayout: De izquierda a derecha, empezando una nueva fila si es necesario GridLayout: Filas y Columnas de igual tamaño CardLayout. Dos o más componentes comparten la misma zona visual. Para un contenedor con un layout manager asociado se tiene: (TP) tamaño preferido Es una suma de los tamaños preferidos de las componentes hijas Observación: Tamaño preferido es 0 cuando el layout manager es null. (MC) modo de colocación de componentes hijas para un tamaño dado del contenedor 10
BorderLayout, I Basado en DIRECCIONES CARDINALES (MC): Las componentes se extienden en la dirección cardinal especificada (cuando no hay extensión, se considera el tamaño preferido). (TP): según pack(). public class MiVentana extends javax.swing.jframe { private javax.swing.jbutton jbutton2; private javax.swing.jbutton jbutton1; private javax.swing.jbutton jbutton3; private javax.swing.jbutton jbutton5; private javax.swing.jbutton jbutton4; public MiVentana() { jbutton1 = new javax.swing.jbutton(); jbutton2 = new javax.swing.jbutton(); jbutton3 = new javax.swing.jbutton(); jbutton4 = new javax.swing.jbutton(); jbutton5 = new javax.swing.jbutton(); 11
BorderLayout, II settitle("un ejemplo de BorderLayout"); jbutton1.settext("oeste"); getcontentpane(). add(jbutton1, java.awt.borderlayout.west); jbutton2.settext("norte"); getcontentpane(). add(jbutton2, java.awt.borderlayout.north); jbutton3.settext("centro"); getcontentpane(). add(jbutton3, java.awt.borderlayout.center); jbutton4.settext("sur"); getcontentpane(). add(jbutton4, java.awt.borderlayout.south); jbutton5.settext("este"); getcontentpane(). add(jbutton5, java.awt.borderlayout.east); pack(); public static void main(string args[]) { new MiVentana().setVisible(true); 12
Ejemplo 13
FlowLayout, I (MC): colocación de sus hijos en una fila (o varias) con tamaño preferido y centrado (TP): según colocación en una fila. public class MiVentana extends javax.swing.jframe { private javax.swing.jbutton jbutton2; private javax.swing.jbutton jbutton1; private javax.swing.jbutton jbutton3; private javax.swing.jbutton jbutton5; private javax.swing.jbutton jbutton4; public MiVentana() { jbutton1 = new javax.swing.jbutton(); jbutton2 = new javax.swing.jbutton(); jbutton3 = new javax.swing.jbutton(); jbutton4 = new javax.swing.jbutton(); jbutton5 = new javax.swing.jbutton(); getcontentpane(). setlayout(new java.awt.flowlayout()); settitle("un ejemplo de FlowLayout"); 14
FlowLayout, II settitle("un ejemplo de FlowLayout"); jbutton1.settext("oeste"); getcontentpane().add(jbutton1); jbutton2.settext("norte"); getcontentpane().add(jbutton2); jbutton3.settext("centro"); getcontentpane().add(jbutton3); jbutton4.settext("sur"); getcontentpane().add(jbutton4); jbutton5.settext("este"); getcontentpane().add(jbutton5); pack(); public static void main(string args[]) { new MiVentana().setVisible(true); 15
Ejemplo 16
GridLayout, I (MC): componentes en un enrejado de celdas con el mismo tamaño y ocupando todo el contenedor (TP): según pack() public class MiVentana extends javax.swing.jframe { private javax.swing.jbutton jbutton2; private javax.swing.jbutton jbutton1; private javax.swing.jbutton jbutton3; private javax.swing.jbutton jbutton5; private javax.swing.jbutton jbutton4; public MiVentana() { jbutton1 = new javax.swing.jbutton(); jbutton2 = new javax.swing.jbutton(); jbutton3 = new javax.swing.jbutton(); jbutton4 = new javax.swing.jbutton(); jbutton5 = new javax.swing.jbutton(); 17
GridLayout, II getcontentpane(). setlayout(new java.awt.gridlayout(2, 3)); settitle("un ejemplo de GridLayout"); jbutton1.settext("oeste"); getcontentpane().add(jbutton1); jbutton2.settext("norte"); getcontentpane().add(jbutton2); jbutton3.settext("centro"); getcontentpane().add(jbutton3); jbutton4.settext("sur"); getcontentpane().add(jbutton4); jbutton5.settext("este"); getcontentpane().add(jbutton5); pack(); public static void main(string args[]) { new MiVentana().setVisible(true); 18
Ejemplo 19
Cardlayout, I Dos o más componentes (normalmente paneles) que comparten espacio (una baraja de cartas donde sólo una es visible) Cada vez que aparece una componente, ocupa totalmente la componente contenedora Se puede mostrar una componente añadida (identificada con un nombre) mediante el método de CardLayout: public void show(container parent, String name) TP: tamaño preferido máximo de las componentes (anchura y altura) 20
Cardlayout, II public class MiVentana extends javax.swing.jframe { private javax.swing.jbutton jbutton2; private javax.swing.jbutton jbutton1; private javax.swing.jpanel jpanel2; private javax.swing.jpanel jpanel1; public MiVentana() { jpanel1 = new javax.swing.jpanel(); jbutton1 = new javax.swing.jbutton(); jpanel2 = new javax.swing.jpanel(); jbutton2 = new javax.swing.jbutton(); getcontentpane(). setlayout(new java.awt.cardlayout()); settitle("un ejemplo de CardLayout"); 21
Cardlayout, III jbutton1.settext("un boton"); jpanel1.add(jbutton1); getcontentpane().add(jpanel1, "carta1"); jpanel2.setlayout(new java.awt.borderlayout()); jbutton2.settext("boton 2"); jpanel2. add(jbutton2, java.awt.borderlayout.center); getcontentpane().add(jpanel2, "carta2"); pack(); java.awt.container c = this.getcontentpane(); java.awt.layoutmanager lm = c.getlayout(); ((java.awt.cardlayout)lm).show(c, "carta2"); public static void main(string args[]) { javax.swing.jframe v = new MiVentana(); v.setvisible(true); 22
Ejemplo 23
Tratamiento de eventos, I Generación de eventos:» Una componente gráfica (java.awt.container) genera objetos de tipo evento al interaccionar con ella (ratón, teclado). Se pueden programar respuestas ante la generación de eventos (event handling) mediante:» Entrega de objetos de tipo evento a objetos registrados como oyentes: Fuente del evento (una componente gráfica) Un oyente (listener): Un objeto de alguna clase. Este objeto actúa de oyente de esos eventos, ejecutando una respuesta al recibir un evento. En una aplicación se pueden establecer varias relaciones fuente-oyente entre un conjunto de fuentes y otro de oyentes 24
Tratamiento de eventos, II Pasos:» Declaración de clases listeners: <clase-oyente> implements <tipo-oyente>» Registrar un objeto oyente para un objeto fuente: <una-componente-fuente>.add<tipo-oyente> (<un-objeto-de-clase-oyente>) 25
Algunos eventos, I Se genera un java.awt.event.actionevent en acciones como:» Click en un JButton» Presionar enter en un JTextField Código:» public class Oyente implements ActionListener {... public void actionperformed(actionevent e) { // codigo a ejecutar ante el evento, // es decir la respuesta...» <un-boton>.addactionlistener (<una-instancia-de-oyente>) 26
Algunos eventos, II Oyentes:» Interface java.awt.event.actionlistener: public void actionperformed (ActionEvent e) En clases JButton, JTextField: public void addactionlistener(actionlistener l) Se genera un java.awt.event.mouseevent al interaccionar con el ratón en un java.awt.container:» Interface java.awt.event.mouselistener: public void mouse{clicked Pressed Released Enter Exited (MouseEvent e)» En java.awt.container: public void addmouselistener(mouselistener l) 27
Ejemplo, I import java.awt.*; import java.awt.event.*; public class MiVentana extends javax.swing.jframe implements ActionListener, MouseListener { private StringBuffer texto; private javax.swing.jbutton jbutton2; private javax.swing.jlabel jlabel1; private javax.swing.jbutton jbutton1; private javax.swing.jpanel jpanel1; public void actionperformed (ActionEvent e) { this.texto.append("click en botón 1."); this.jlabel1.settext(this.texto.tostring()); public void mouseclicked (MouseEvent e) { public void mousepressed (MouseEvent e) { public void mousereleased (MouseEvent e) { public void mouseentered (MouseEvent e) { this.texto.append("entrar en botón 2."); this.jlabel1.settext(this.texto.tostring()); 28
Ejemplo, II public void mouseexited (MouseEvent e) { this.texto.append("salir de botón 2."); this.jlabel1.settext(this.texto.tostring()); public MiVentana() { jlabel1 = new javax.swing.jlabel(); jpanel1 = new javax.swing.jpanel(); jbutton1 = new javax.swing.jbutton(); jbutton2 = new javax.swing.jbutton(); settitle("un ejemplo de eventos"); jlabel1.sethorizontalalignment( javax.swing.swingconstants.center); getcontentpane(). add(jlabel1, java.awt.borderlayout.center); jbutton1.settext("boton 1"); jpanel1.add(jbutton1); jbutton2.settext("boton 2"); jpanel1.add(jbutton2); getcontentpane(). add(jpanel1, java.awt.borderlayout.south); pack(); 29
Ejemplo, III this.texto=new StringBuffer(); this.jbutton1.addactionlistener(this); this.jbutton2.addmouselistener(this); public static void main(string args[]) { javax.swing.jframe v = new MiVentana(); v.setvisible(true); 30
Ejemplo, IV 31
Más eventos Otros eventos:» Generados por java.awt.container: addfocuslistener (java.awt.event.focusevent) addkeylistener (java.awt.event.keyevent) addmouselistener (java.awt.event.mouseevent) addmousemotionlistener (java.awt.event.mouseevent)» Generados por JFrame y por JDialog addwindowlistener(java.awt.event.windowevent) Otros eventos más sencillos:» java.awt.event.actionevent. Generado por: JButton JCheckBox JTextField JComboBox» java.awt.event.itemevent. Generado por: JCheckBox JComboBox» javax.swing.event.listselectionevent. Generado por: JList Referencia: Listeners Supported by Swing Components The Java Tutorial (java.sun.com) 32
Adaptadores Algunas interfaces oyentes tienen adaptadores para simplificar el código (java.awt.event.*):» Ejemplo: public abstract class MouseAdapter extends Object implements MouseListener» Código vacío en métodos de la interface Ejemplo:»El mismo que antes pero con uso de adaptadores 33
Adaptadores 34
Ejemplo, I import java.awt.*; import java.awt.event.*; import javax.swing.*; public class MiVentana extends javax.swing.jframe implements ActionListener { StringBuffer texto; private JButton jbutton2; private JLabel jlabel1; private JButton jbutton1; private JPanel jpanel1; public void actionperformed (ActionEvent e) { this.texto.append("click en botón 1."); this.jlabel1.settext(this.texto.tostring()); public MiVentana() { jlabel1 = new javax.swing.jlabel(); jpanel1 = new javax.swing.jpanel(); jbutton1 = new javax.swing.jbutton(); jbutton2 = new javax.swing.jbutton(); settitle("un ejemplo de eventos"); addwindowlistener( new WindowAdapter() { public void windowclosing (WindowEvent evt) { System.exit(0); ); 35
Ejemplo, II jlabel1.sethorizontalalignment( javax.swing.swingconstants.center); getcontentpane(). add(jlabel1, java.awt.borderlayout.center); jbutton1.settext("boton 1"); jpanel1.add(jbutton1); jbutton2.settext("boton 2"); jpanel1.add(jbutton2); getcontentpane(). add(jpanel1, java.awt.borderlayout.south); pack(); 36
Ejemplo, III this.texto=new StringBuffer(); this.jbutton1.addactionlistener(this); this.jbutton2.addmouselistener( new MouseAdapter() { public void mouseentered(mouseevent e) { // Aquí no sería válido this.texto texto.append("entrar en botón 2."); jlabel1.settext(texto.tostring()); public void mouseexited(mouseevent e) { texto.append("salir de botón 2."); jlabel1.settext(texto.tostring()); ); public static void main(string args[]) { javax.swing.jframe v = new MiVentana(); v.setvisible(true); 37