Herramientas de usuario

Herramientas del sitio


bloque4:organizargui

Organizar una ventana y acoplarla a un programa

WindowBuilder genera el código referente a los componentes gráficos de Swing con los que trabaja.

Para que podamos usar las clases generadas por nuestro diseñador de Swing poder acoplarlo fácilmente a nuestros proyectos anteriores, vamos a seguir unos sencillos pasos.

Organizar código generado por WindowBuilder

WindowBuilder genera el código de la ventana en una clase de la siguiente forma:

  • Crea un método main en la propia clase, desde el cual se inicia la ejecución de la ventana.
  • Además, incluye todo el código de nuestra ventana dentro del constructor de la clase.

Para organizar las clases que creemos con WindowBuilder, debemos hacer 2 cosas:

  1. organizar el código generado en el constructor en un par de métodos
  2. eliminar el método main de esta clase

1 - Organizar el constructor

Todo el código que genera WindowBuilder se añade al constructor de la clase. Nosotros vamos a dividirlo en dos métodos:

  • Método iniciarComponentes(), dentro del cual movemos el código que se haya generado al crear los distintos componentes (todo el código del constructor). Posteriormente el código que WindowBuilder vaya generando se incluirá automáticamente (más o menos) dentro de este método.
  • Método iniciarManejadoresEventos(), dentro del cual incluiremos todo el código que se genera al crear los manejadores de eventos de los distintos botones o elementos. Estos se usan para decirle a un botón que va a ejecutar código cuando sea pulsado con el ratón, p.e.

La finalidad de estos dos métodos es simplemente organizativa, y pueden nombrarse con cualquier otro identificador que creamos oportuno (initComponents, initHandlers, etc).

Estos dos métodos serán llamados por el constructor de la clase.

2 - Eliminar el método main

El método main generado por WindowBuilder usa hilos de ejecución y no queremos usarlo; por lo tanto los borraremos. La ventana será creada desde un método main en otra clase, como por ejemplo:

public class EjecutarAplicacion{
   public static void main(String[] args) {
      Ventana1 ventana = new Ventana1();
      ventana.setVisible(true);
   }
}

Y con esto tendremos funcionando nuestra aplicación.

Asignar manejadores de eventos a un componente

Ahora solo nos falta hacer que nuestra aplicación responda a los eventos del usuario. Los eventos normalmente serán eventos del ratón o del teclado. Por ejemplo, pulsar los botones del ratón, pasar el cursor del ratón encima de un componente, pulsar teclas del teclado, etc.

En la siguiente imagen hemos incluido un JButton (botón) y un JTextField (campo de texto). Si en el editor de WindowBuilder pulsamos con el botón derecho sobre el botón se nos desplegará el menu que vemos en la imagen.

La mayor parte de las acciones que realizaremos sobre un elemento gráfico pueden responder al evento ActionPerformed, así que con pulsar sobre dicho evento nos bastará.

En ese momento WindowBuilder nos habrá generado algo más de código en el método iniciarComponentes():

El código relativo a nuestros componentes se crea ahora dentro del método iniciarComponentes(). Los manejadores de eventos se crean justo debajo del elemento (botón en este caso) que los necesita, también dentro de ese método.

Si queremos organizar nuestro código de forma más clara debemos mover este código dentro del método que hemos creado para tal fin:

Además hemos incluido el código referente para mostrar un saludo en el campo de texto (variable textField).

Si nos fijamos, la variable btnSaludar, está subrayada en rojo, debido a que el compilador detecta un error.

Esto se debe a que la variable btnSaludar, no está creada (no existe) dentro del método iniciarManejadoresEventos().

Dicha variable se ha creado en el método iniciarComponentes(), por lo que es una variable local a ese método, y solo puede ser accedida (existe) desde dicho método.

En el siguiente punto vamos a tratar el ámbito de las variables de una ventana.

Ámbito de las variables de componentes

Debido a la organización de nuestro código en métodos, debemos tener en cuenta que muchas variables que crea WindowBuilder son locales (su ámbito es el método en el que se crean) y no serán visibles desde ningún otro método a no ser que cambiemos su ámbito.

Desde la vista “Design” de WindowBuilder tenemos una sección para las propiedades de cualquier elemento gráfico:

Dentro de ella podemos cambiar el nombre de la variable (elemento gráfico) que queramos y modificar sus propiedades. Pero hay un botón muy importante que debemos saber manejar.

Al pulsar este botón hacemos que una variable pase de ser variable local (solo existe en el método en el que se crea) a ser atributo de la clase (los atributos de la clase se definen al comienzo de la clase y son accesibles por todos los métodos).

Cuando el botón tiene esta imagen, la variable es local, y al poner el ratón encima del botón, nos dira convertir de local a campo (campo de la clase = atributo de la clase). Si lo pulsamos convertiremos la variable local en atributo de la clase (accesible desde toda la clase).

Cuando una variable es local, solo existe en el método en el que se crea, por defecto en el método iniciarComponentes(): Si nos fijamos la variable está declarada e inicializada (construida) en la misma línea.

Cuando el botón tiene está forma, quiere decir que la variable es atributo de la clase. Por lo tanto podrá ser accedida por cualquier método de ella (por ejemplo desde el método iniciarManejadoresEventos(). Si pasamos el ratón por encima nos dirá lo contrario al caso anterior: “convertir de campo a local”.

Cuando una variable es atributo de la clase está declarada al comienzo de la clase, y en el método iniciarComponentes(), solo se construirá el objeto.

Si nos fijamos en el método iniciarManejadoresEventos(), ya no tenemos problema a la hora de añadir el ActionListener (manejador de evento del raton) al botón que tenemos en la aplicación, ya que la variable btnSaludar es un atributo de la clase y puede ser accedida desde cualquier método de la clase.

Se ha de tener en cuenta que, cualquier elemento con el que queramos interactuar (como añadir un manejador de eventos o acceder al texto que contiene), debe ser atributo de la clase (Field).

Asociar nuestra ventana con nuestra aplicación

Como hemos ido programando hasta ahora, hemos trabajado unicamente con la consola para la entrada/salida de datos usando dos flujos:

  1. Entrada estándar: System.in (usada por método println())
  2. Salida estándar: System.out (usada por constructor de Scanner())

Esos flujos ya no serán usados ya que ahora nos comunicaremos con el usuario a través de la interfaz gráfica GUI y sus componentes.

La forma más fácil de asociar mi ventana con mi programa es crear una instancia de mi programa en mi clase Ventana.

Ejemplo: Clase GestorEmpleados, con los métodos para dar de alta empleados, buscarlos, eliminarlos, etc. Es acoplada a la clase Ventana.

public class Ventana extends JFrame{
 
   //Atributos de la clase (componentes gráficos con los que interactuo de algún modo)
   private JTextField txtNombre;
   private JTextArea txtAClientes;
   private JButton btnAltaCliente;
   private JButton btnListarClientes;
 
   //Referencia a mi aplicacion
   private GestorEmpleados gestor;
 
   //Constructor de la clase Ventana
   public Ventana(){
      initComponents();
      initEventHandlers();
 
      //Instancio la referencia a mi aplicación 
      gestor = new GestorEmpleados();
   }
 
   /*
     Método que incluye cada manejador de eventos
   */
   private void initEventHandlers(){
      //Listener para el boton altaCliente
      btnAltaCliente.addActionListener(new ActionListener() {
	public void actionPerformed(ActionEvent arg0) {
 
           //Obtengo el nombre del cliente del campo de texto 
           //y llamo al método altaCliente
           String nombre = txtNombre.getText();
           gestor.altaCliente(nombre);
        }
      });
 
      //Listener para el botón listar clientes
      btnListarCliente.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
 
           //Obtengo los clientes de mi gestor 
           //y los listo en el area de texto
           for (Cliente cliente : gestor.getListaClientes()){
              txtAClientes.append(cliente.toString() + "\n");
           }
        }
      });
 
   }
 
   private void initComponents(){
      //codigo generado por Windowbuilder de los componentes gráficos
      ...
   }
}

© 2020 Fernando Valdeón

bloque4/organizargui.txt · Última modificación: 04/01/2019 13:13 (editor externo)