Diseño Y Aplicaciones de Sistemas Distribuidos Interfaces gráficas en Java GUIs Graphical User Interface Joan Vila DISCA / UPV Departament d’Informàtica de Sistemes i Computadors Universitat Politècnica de València Java - GUI Indice – Componentes del AWT – – – – Componentes básicos Containers Layout managers Un ejemplo Utilización de Frames Manejo de eventos Proceso de dibujo en AWT Procesamiento distribuido en Java © Joan Vila 73 Java - GUI Componetes del AWT (Abstract Window Toolkit) – Componentes “básicos” Button Checkbox Choice List Label MenuItem TextField TextArea Canvas Procesamiento distribuido en Java – Containers Frame Dialog FileDialog – Layout Managers Border Card Flow Grid GridBagLayout © Joan Vila 74 Java AWT: componentes Procesamiento distribuido en Java © Joan Vila 75 Java AWT: componentes básicos Procesamiento distribuido en Java © Joan Vila 76 Java AWT: componentes básicos Uso de Button b1 = new Button(); b1.disable(); Uso de Choice choice = new Choice(); choice.addItem("ichi"); choice.addItem("ni"); choice.addItem("san"); choice.addItem("yon"); int i = choice.getSelectedIndex() String S = choice.getSelectedItem()); Procesamiento distribuido en Java Uso de textField y textArea // En la inicialización TextField textField; TextArea textArea; textField = new TextField(20); textArea = new TextArea(5, 20); textArea.setEditable(false); ... // En los manejadores de eventos String text = textField.getText(); textArea.appendText(text + "\n"); textField.selectAll(); © Joan Vila 77 Java AWT: componentes básicos Uso de CheckBox Checkbox cb1, cb2, cb3; //These are independent checkboxes. Checkbox cb4, cb5, cb6; //These checkboxes are part of a group. CheckboxGroup cbg; cb1 = new Checkbox(); //Default state is "off" (false). cb1.setLabel("Checkbox 1"); cb2 = new Checkbox("Checkbox 2"); cb3 = new Checkbox("Checkbox 3"); cb3.setState(true); //Set state to "on" (true). ... cbg = new CheckboxGroup(); cb4 = new Checkbox("Checkbox 4", cbg, false); //initial state: off (false) cb5 = new Checkbox("Checkbox 5", cbg, false); //initial state: off cb6 = new Checkbox("Checkbox 6", cbg, false); //initial state: off Procesamiento distribuido en Java © Joan Vila 78 Java AWT: containers Containers – Frame: proporciona ventanas para aplicaciones. – Dialog: Ventanas dependientes de frame que se iconizan cuando el correspondiente Frame se iconiza. Se utilizan para formular preguntas – FileDialog: Dialog para seleccionar un fichero. No puede visualizarse en un applet. – Panel: sirven para agrupar componentes básicos Applet es subclase de Panel Procesamiento distribuido en Java © Joan Vila 79 Java AWT: layout managers • También es posible trabajar con posicionamiento absoluto Procesamiento distribuido en Java © Joan Vila 80 Un ejemplo Procesamiento distribuido en Java © Joan Vila 81 Utilización de Frames public class UnFrame extends Frame implements WindowListener { // Declarar layout GridBagLayout gridBagLayout1 = new GridBagLayout(); // Declarar componentes Button botonEnviar = new Button(); Label label1 = new Label(); TextField textoHost = new TextField(); public UnFrame() { // Inicializar componentes botonEnviar.setLabel("SEND"); ... // Establecer un Layout this.setLayout(gridBagLayout1); // Añadir componentes al Frame¡ this.add(botonEnviar, ...); this.add(label1, ...); this.add(textoHost, ...); } Procesamiento distribuido en Java © Joan Vila 82 Utilización de Frames public class UnFrame extends Frame implements WindowListener { ... public static void main(String[] args) { // Declarar un objeto de tipo Frame y visualizarlo UnFrame UnFrame1 = new UnFrame(); UnFrame1.addWindowListener(echoFrame1); UnFrame1.show(); } // Define window listeners. public void windowClosing( WindowEvent event ) {dispose(); System.exit(1);} public void windowOpened( WindowEvent event ) {} ... } Procesamiento distribuido en Java © Joan Vila 83 Manejo de eventos Eventos – La pulsación de un botón, retorno de carro en un campo de texto, etc..., produce eventos asíncronos a los que se les puede declarar funciones para manejarlos. – Estas funciones están definidas en una serie de interfaces y clases del paquete java.awt.event Procesamiento distribuido en Java © Joan Vila 84 Manejo de eventos Eventos Un componente, como p.e. un Button puede generar dos tipos de eventos – Bajo nivel: eventos no específicos del componente, como p.e., MouseEvent al ser visitado, abandonado o presionado por el ratón, etc... – Alto nivel: evento con acciones específicas del componente como p.e., ActionEvent al ser presionado, que evita procesar eventos poco “relevantes” (semánticamente) como movimientos o clicks del ratón El evento ActionEvent se propaga a cada objeto que implemente la interfaz ActionListener y que se haya registrado para recibir dicho evento, utilizando para ello el método AButton.addActionListener(ActionListener l) del correspondiente componente. La interfaz ActionListener obliga a implementar un actionPerformed(ActionEvent e) que sirve para manejar el evento. Procesamiento distribuido en Java método © Joan Vila 85 Manejo de eventos Eventos: un ejemplo – La pulsación de un botón. Button boton1 = new Button(); boton1.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(ActionEvent e) { boton_manejador(e); } }); Procesamiento distribuido en Java © Joan Vila 86 Un ejemplo de GUI Un applet de echo Procesamiento distribuido en Java © Joan Vila 87 Un ejemplo de GUI Diseño visual de GUIs con Eclipse Procesamiento distribuido en Java © Joan Vila 88 Un ejemplo de GUI Código generado por Eclipse public class EchoApplet extends JApplet { private JPanel jContentPane = null; private JButton botonEnviar = null; private JLabel jLabel = null; private JLabel jLabel1 = null; private JLabel jLabel2 = null; private JTextField textoHost = null; private JTextField textoEnviar = null; private JTextPane textoRecibido = null; private JLabel barraEstado = null; Procesamiento distribuido en Java © Joan Vila 89 Un ejemplo de GUI Código generado por Eclipse /** * This method initializes jButton * * @return javax.swing.JButton */ private JButton getBotonEnviar() { if (jButton == null) { botonEnviar = new JButton(); botonEnviar.setBounds(new java.awt.Rectangle(16,16,75,26)); botonEnviar.setName("botonEnviar"); botonEnviar.setText("SEND"); botonEnviar.addActionListener( new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent e) { System.out.println("actionPerformed()"); Manejador // TODO Auto-generated Event stub actionPerformed() evento } }); } return botonEnviar; } Procesamiento distribuido en Java © Joan Vila 90 Un ejemplo de GUI Código generado por Eclipse private JTextField getTextoHost() {…} private JTextField getTextoEnviar() {…} private JTextPane getTextoRecibido() {…} public static void main(String[] args) { // TODO Auto-generated method stub } /** * This is the default constructor */ public EchoApplet() { super(); } public void init() { this.setSize(400, 200); this.setContentPane(getJContentPane()); } Procesamiento distribuido en Java © Joan Vila 91 Un ejemplo de GUI Código generado por Eclipse /** * This method initializes jContentPane * @return javax.swing.JPanel */ private JPanel getJContentPane() { if (jContentPane == null) { barraEstado = new JLabel(); barraEstado.setBounds(new java.awt.Rectangle(3,166,389,30)); barraEstado.setBackground(java.awt.Color.darkGray); jLabel2 = new JLabel(); jLabel2.setBounds(new java.awt.Rectangle(14,93,102,27)); jLabel2.setText(" String received:"); … Procesamiento distribuido en Java © Joan Vila 92 Un ejemplo de GUI Código generado por Eclipse /** * This method initializes jContentPane * @return javax.swing.JPanel */ private JPanel getJContentPane() { if (jContentPane == null) { … … jContentPane = new JPanel(); jContentPane.setLayout(null); jContentPane.setPreferredSize(new java.awt.Dimension(1,1)); jContentPane.add(getJButton(), null); jContentPane.add(jLabel, null); jContentPane.add(jLabel1, null); jContentPane.add(jLabel2, null); jContentPane.add(getTextoHost(), null); jContentPane.add(getTextoEnviar(), null); jContentPane.add(getTextoRecibido(), null); jContentPane.add(barraEstado, null); } return jContentPane; } Procesamiento distribuido en Java © Joan Vila 93 Proceso de dibujo en AWT ¿Cómo dibuja el AWT? Los programas dibujan sólo cuando el AWT se lo permite. La razón es hacerlo de manera ininterrumpida. El AWT realiza los dibujos desde un único thread. La secuencia es: – repaint(): método invocado por un componente para planificar una orden de dibujo – update(): método de un componente que el AWT invoca cuando le llega el turno de dibujar. Por defecto, lo que hace es: Limpiar el hueco del componente Invocar el método paint() del componente. El método paint() no hace nada por defecto. Procesamiento distribuido en Java © Joan Vila 94 Proceso de dibujo en AWT El objeto Graphics El único argumento de los métodos paint() y update() es un objeto Graphics que representa el contexto en el que un componente puede dibujarse. La clase Graphics proporciona métodos para: – Dibujar y rellenar rectángulos, arcos, líneas, óvalos, polígonos, texto e imágenes. – Obtener o fijar el color o fuente actual – Fijar el modo de dibujo. ¿Cómo dibujar? La manera más fácil de dibujar es poner código (sobrecargar) el método paint(): public publicvoid voidpaint(Graphics paint(Graphicsg) g){{ Dimension Dimensiondd==size(); size(); g.drawRect(0,0, g.drawRect(0,0,d.width d.width--1, 1,d.height d.height--1); 1); }} Procesamiento distribuido en Java © Joan Vila 95 Realización de un componente gráfico public class RobotGrafico extends Component{ public RobotGrafico(...) { super(); this.setBackground(new Color(124, 178, 193)); this.setForeground(Color.gray); ...} public Dimension getMinimumSize(){ return new Dimension(...); } public Dimension getPreferredSize(){ ... } public void paint(Graphics g) { g.setColor(Color.blue); g.fillOval(...); g.drawLine(...); ...} } Procesamiento distribuido en Java © Joan Vila 96 Realización de un componente gráfico public class Consola extends JApplet implements Runnable, WindowListener{ BevelPanel pnlEscenario = new BevelPanel(); rbtg= new RobotGrafico(...); public Consola() { jbInit(); ...} private void jbInit() throws Exception { ... pnlEscenario.add(rbtg, ...); pnlEscenario.validate(); this.getContentPane().add(pnlEscenario, ...); ...} public void run(){ pnlEscenario.repaint(); try{Thread.sleep(400);} catch(Exception e){} ...} ...} Procesamiento distribuido en Java © Joan Vila 97