Desarrollo de Aplicaciones en Java INF 473 Desarrollo de Interfaces Gráficas Componentes Swing II Prof. José Miguel Rubio jose.rubio.l@ucv.cl jrubio@inf.ucv.cl PUCV Marzo 2008 0 Generación de código Diferencia (en Swing y AWT) entre: » Código generado automáticamente – En una IDE (como Netbeans) Se deben conservar los ficheros: » *.java » *.form » Código no generado automáticamente 1 Ejemplo 2 Ejemplo, autom. (I) public class MiVentana extends javax.swing.JFrame { private int clicks; public MiVentana() { this.clicks=0; initComponents(); } private void initComponents() { jPanel1 = new javax.swing.JPanel(); jButton1 = new javax.swing.JButton(); jButton2 = new javax.swing.JButton(); jPanel2 = new javax.swing.JPanel(); jLabel1 = new javax.swing.JLabel(); setTitle("Un ejemplo"); addWindowListener (new java.awt.event.WindowAdapter() { public void windowClosing (java.awt.event.WindowEvent evt) { exitForm(evt); } }); …… 3 Ejemplo, autom. (II) …… jPanel1.setBorder // Definido en JComponent (new javax.swing.border.LineBorder (new java.awt.Color(0, 0, 0))); jButton1.setText("Numero de clicks"); jButton1.addActionListener (new java.awt.event.ActionListener() { public void actionPerformed (java.awt.event.ActionEvent evt) { jButton1ActionPerformed(evt); } }); jPanel1.add(jButton1); jButton2.setText("No hacer click"); jButton2.addActionListener (new java.awt.event.ActionListener() { public void actionPerformed (java.awt.event.ActionEvent evt) { jButton2ActionPerformed(evt); } }); jPanel1.add(jButton2); ,,,,,, 4 Ejemplo, autom. (III) ,,,,,, getContentPane(). add(jPanel1, java.awt.BorderLayout.SOUTH); jLabel1.setText("Numero de clicks: 0"); jLabel1.setBorder (new javax.swing.border.LineBorder (new java.awt.Color(0, 0, 0))); jPanel2.add(jLabel1); getContentPane().add(jPanel2, java.awt.BorderLayout.CENTER); pack(); } private void jButton2ActionPerformed (java.awt.event.ActionEvent evt) { // Add your handling code here: this.clicks=(this.clicks%2)/(this.clicks%2); // EXCEPCIONES RUNTIME this.jLabel1.setText("Número de clicks: " + this.clicks); } …… 5 Ejemplo, autom. (IV) …… private void jButton1ActionPerformed (java.awt.event.ActionEvent evt) { // Add your handling code here: this.clicks++; this.jLabel1.setText("Número de clicks: " + this.clicks); } private void exitForm(java.awt.event.WindowEvent evt) { System.exit(0); } public static void main(String args[]) { new MiVentana().show(); } private javax.swing.JButton jButton2; private javax.swing.JLabel jLabel1; private javax.swing.JButton jButton1; private javax.swing.JPanel jPanel2; private javax.swing.JPanel jPanel1; } 6 Mensajes de error java.lang.ArithmeticException: / by zero at MiVentana.jButton2ActionPerformed(MiVentana.java:71) at MiVentana.access$200(MiVentana.java:11) at MiVentana$3.actionPerformed(MiVentana.java:52) ... ... ... ... at java.awt.EventDispatchThread.pumpEvents (EventDispatchThread.java:130) at java.awt.EventDispatchThread.run (EventDispatchThread.java:98) El programa sigue funcionando. Funcionamiento de un programa Swing: » El hilo de tratamiento de eventos es un bucle que recoge los eventos generados y ejecuta los métodos de los listeners » En pseudocódigo: while (“hay-eventos-por-procesar”) { try { “procesa-el-siguiente-evento” } catch (Exception exc) { exc.printStackTrace(); } } 7 Ejemplo, no autom. (I) import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.border.*; public class MiVentana extends JFrame implements ActionListener { private JButton jButton2; private JLabel jLabel1; private JButton jButton1; private JPanel jPanel2; private JPanel jPanel1; private int clicks; public MiVentana() { this.clicks=0; jPanel1 = new JPanel(); jButton1 = new JButton(); jButton2 = new JButton(); jPanel2 = new JPanel(); jLabel1 = new JLabel(); setTitle("Un ejemplo"); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); 8 Ejemplo, no autom. (II) jPanel1.setBorder (new LineBorder(new Color(0, 0, 0))); jButton1.setText("Numero de clicks"); jButton1.addActionListener(this); jPanel1.add(jButton1); jButton2.setText("No hacer click"); jButton2.addActionListener(this); jPanel1.add(jButton2); getContentPane(). add(jPanel1, BorderLayout.SOUTH); jLabel1.setText("N\u00famero de clicks: 0"); jLabel1.setBorder (new LineBorder(new Color(0, 0, 0))); jPanel2.add(jLabel1); getContentPane(). add(jPanel2, BorderLayout.CENTER); pack(); } 9 Ejemplo, no autom. (III) public void actionPerformed (ActionEvent evt) { if (evt.getSource()==this.jButton1) { this.clicks++; this.jLabel1. setText("Número de clicks: " + this.clicks); } else if (evt.getSource()==this.jButton2) { this.clicks=(this.clicks%2)/(this.clicks%2); this.jLabel1. setText("Número de clicks: " + this.clicks); } } public static void main(String args[]) { new MiVentana().show(); } } 10 Ejemplo, no autom. (IV) Los oyentes pueden ser: » La ventana (el JFrame) » Clases anónimas (como las generadas por Netbeans) » Clases anidadas – Ejemplo “Clases-anidadas-oyentes” » Otras clases – Deberían tener acceso a los parámetros de la ventana (como tienen las clases anónimas y las internas) 11 Jerarquía de eventos javax.swing.event.ListSelectionEvent Object java.util.EventObject java.awt.AWTEvent ItemEvent KeyEvent ActionEvent MouseEvent FocusEvent Paquete por defecto java.awt.event.*; Línea discontinua otras clases intermedias Clase EventObject public Object getSource() 12 Clases JButton y JCheckBox (I) JButton » Constructor: – public JButton(String text) » Eventos: – ActionEvent (haciendo click) JCheckBox » Constructor: – public JCheckBox (String text, boolean selected) » Eventos: – ActionEvent y ItemEvent (haciendo click) Evento ActionEvent – public ActionEvent(Object source, int id, String command) 13 Clases JButton y JCheckBox (II) Interface ActionListener: » public void actionPerformed (ActionEvent evt) Evento ItemEvent – public ItemEvent(ItemSelectable source, int id, Object item, int stateChange) Valores de stateChange: » ItemEvent.SELECTED » ItemEvent.DESELECTED Interface ItemListener: » public void itemStateChanged (ItemEvent evt) Ejemplo: » “JButton-JCheckBox” 14 Ejemplo 15 Clases JLabel y JComboBox JLabel » Constructor: public JLabel(String text, Icon icon, int horizontalAlignment) JComboBox » Editable o no editable » Constructor: – public JComboBox(ComboBoxModel aModel) DefaultComboBoxModel (descendiente de ComboBoxModel) » Se permite modificar los elementos del modelo en tiempo de ejecución. » Eventos: – ItemEvent (al seleccionar) – ActionEvent (al seleccionar o apretar “enter) Ejemplo: » “JLabel-JComboBox” 16 Ejemplo 17 Clases JTextField y JTextArea JTextField » Constructor: public JTextField(String text, int columns) » Eventos: – ActionEvent (pulsando “enter”) » Métodos: – (set|get)Text JTextArea » Constructor: public JTextArea(String text, int rows, int columns) » Métodos: public void append(String str) (set|get)Text 18 Clase JScrollPane JScrollPane » Métodos: – public void setHorizontalScrollBarPolicy(int policy) » JScrollPane.HORIZONTAL_SCROLLBA R_AS_NEEDED » JScrollPane.HORIZONTAL_SCROLLBA R_NEVER » JScrollPane.HORIZONTAL_SCROLLBA R_ALWAYS – public void setViewportView(Component view) Incluir una componente » Constructor: – public JScrollPane(Component view) Equivalente a haber hecho “setViewPort” y política AS_NEEDED horizontal y vertical Ejemplo: » “JTextField-JTextArea-JScrollPane” 19 Ejemplo 20 Clases JList y JDialog (I) JList » Selección simple o múltiple » Constructor: – public JList(ListModel dataModel) » Eventos: – javax.swing.event.ListSelectionEvent Interface ListModel. Descendientes: » AbstractListModel (clase abstracta) – DefaultListModel Permite modificar los elementos en tiempo de ejecución. 21 Clases JList y JDialog (II) JDialog » Análogo a un JFrame, aunque: – Modal (única ventana activable) El thread principal de eventos queda bloqueado al hacer “setVisible(true)” en el diálogo. Se desbloquea al hacer “setVisible(false)” en el diálogo. » Se genera otro thread para los eventos de la ventana de diálogo. – No modal » Constructor: public JDialog(Dialog owner, boolean modal) Ventanas de diálogo predefinidas: » javax.swing.JOptionPane – Es “extends JComponent” » Dos posibles usos: – Primer uso: public static int showConfirmDialog(Component parentComponent, Object message). Valores de retorno: » JOptionPane.YES_OPTION » JOptionPane.NO_OPTION » JOptionPane.CANCEL_OPTION 22 Clases JList y JDialog (III) – Segundo uso: public JOptionPane(Object message, int messageType, int optionType) » messageType: JOptionPane.QUESTION_MESSAGE, etc » optionType: JOptionPane.YES_NO_CANCEL_OPTI ON, etc Luego utilizar: » public JDialog createDialog(Component parentComponent, String title) Valor de retorno: » Método “getValue()” en clase JOptionPane En cualquier ventana de diálogo, por defecto: » Al hacer click en esquina superior derecha, la ventana desaparece. Ejemplo: » “JList-JDialog” 23 Ejemplo 24 Menus/Ventanas (I) Una Interfaz de Usuario maneja datos realizando: » Introducción de datos » Procesamiento de datos » Visualización de resultados Posibles interfaces de usuario: » Menús » Ventanas Ejemplo » “Menus-Ventanas” 25 Menus/Ventanas (II) 26