miércoles, 23 de julio de 2008

Aplicaciones Java (III): Swing: botones, menús y eventos

Seguimos con los artículos sobre Swing. Pasamos a comentar algunos controles relacionados con la interactividad de nuestro programa: botones y menús, y eventos asociados.

Botones (JButton)

Por medio de la clase JButton crearemos botones a los que asociaremos determinadas acciones.

JButton botonsinusar = new JButton("boton sin usar");
root.add(botonsinusar, BorderLayout.EAST);

Es posible añadir imágenes a los botones. Para ello, utilizaremos el constructor de JButton que permite pasar una imagen como parámetro. Para la imagen del botón, podemos proporcionar un fichero gráfico propio que almacenaremos dentro de nuestro fichero jar, o gracias al método UIManager.getIcon, utilizar una imagen proporcionada por los componentes estándar de Java. En esta página podremos encontrar un listado con algunos de los gráficos incluidos en componentes estándar. Alguien conoce algún listado más exahustivo?

JButton boton = new JButton("texto boton", UIManager.getIcon("FileView.hardDriveIcon"));
root.add(boton, BorderLayout.SOUTH)

Menús (JMenuBar, JMenu, JMenuItem)

Por medio de las clases JMenuBar, JMenu, y JMenuItem/JRadioButtonMenuItem/JCheckBoxMenuItem, podremos fácilmente generar menús para nuestro programa con todas las características que podemos imaginar:

  • Atajos de teclado
  • Iconos
  • Submenús (menú que se abre cuando pones el ratón encima de una opción de otro menú)
  • Botones de radio, para seleccionar una entre múltiples opciones
  • Checkbox, para activar o desactivar una opción

En primer lugar crearemos un objeto del tipo JMenuBar, que es la barra de menú que colocaremos en el panel como un componente más (utilizando el layout correspondiente).

JMenuBar menubar = new JMenuBar();
root.add(menubar, BorderLayout.NORTH);

A este JMenuBar le añadiremos un JMenu, que es cada uno de los menús de una barra de menú (Archivo, Herramientas, Ayuda...).

JMenu toolsmenu = new JMenu("Tools");
menubar.add(toolsmenu);

Cada uno de estos menús puede tener una serie de elementos (JMenuItem, JRadioButtonMenuItem, JCheckBoxMenuItem) o contener menús anidados (un JMenu dentro de un JMenu).

JMenu languagemenu  = new JMenu("Language");
toolsmenu.add(languagemenu);

JMenuItem languageitemEN = new JRadioButtonMenuItem("English");
languagemenu.add(languageitemEN);

JMenuItem languageitemES = new JRadioButtonMenuItem("Español");
languagemenu.add(languageitemES);

JMenuItem aboutitem = new JMenuItem("Exit");
toolsmenu.add(aboutitem);

En el caso de los botones de radio, podremos definir un grupo de botones entre los que sólo será posible seleccionar una opción, utilizando la clase ButtonGroup.

ButtonGroup languagegroup = new ButtonGroup();
languagegroup.add(languageitemEN);
languagegroup.add(languageitemES);
languageitemES.setSelected(true);

Eventos (ActionListener)

Para escuchar los eventos, como los generados por los botones y menús, tendremos que crear una clase que implemente el interfaz ActionListener, creando el método actionPerformed, definido como abstracto. Este método será invocado cada vez que se produzca un evento de los que hemos seleccionado que queremos escuchar. En nuestro caso, la pulsación de botones y menús.

Para añadir la capacidad de escuchar eventos a nuestra clase deberemos añadir lo siguiente:

Para cada componente cuyos eventos queramos escuchar le diremos que será el objeto de la clase actual (this) quien escuchará ese evento. También se puede crear una clase independiente para escuchar estos eventos.

boton.addActionListener(this);
languageitemEN.addActionListener(this);
languageitemES.addActionListener(this);
aboutitem.addActionListener(this);

Utilizando el evento (de la clase clase ActionEvent) pasado como parámetro, podremos distinguir de qué tipo de evento se trata (source.getClass().getName()), identificar el componente concreto que generó el evento event.getSource(), y otra información (getActionCommand()).

Para cada clase que queramos que escuche eventos (en nuestro caso sólo en SwingSampleBase):

public class SwingSampleBase implements ActionListener
{    
    // constructor y otros métodos
    // [...]

    public void actionPerformed(ActionEvent event)
    {
        Object source = event.getSource();
        if (source.getClass().getName().equals("javax.swing.JMenuItem") ||
            source.getClass().getName().equals("javax.swing.JRadioButtonMenuItem"))
        {
            if (source == aboutitem)
            {
                lCenter.setText("selected About item");
            }
            else if (source == languageitemES)
            {
                lCenter.setText("selected Spanish language");
            }
            else if (source == languageitemEN)
            {
                lCenter.setText("selected English language");
            }
        }
        else // JButton
        {
            if (source == boton)
            {
                lCenter.setText("botón pulsado");
            }
        }
    }
}

Material

El código fuente mostrando el uso de estos componentes se puede descargar bajo licencia GPLv3:
Download

Ejecutar ejemplo, como applet o como Java Web Start (recomendado):
Start Applet Launch via Java Web Start

2 comentarios:

Anónimo dijo...

Buenos días,

Alguien sabría decirme si existe algún entorno de Java que permita crear aplicaciones Web tipo formulario donde puedas ir arrastrando los componentes al formulario (textbox, label, login, tables, etc.)?? Swing permite hacer aplicaciones Web o solo escritorio?

Muchas gracias

Jose dijo...

Hola Anónimo. Échale un vistazo a NetBeans.

Tiene un interfaz con el que puedes arrastrar componentes y él te genera el código Swing o JavaFX.

Respecto a tu segunda pregunta, Swing puede utilizarse tanto para aplicaciones de escritorio como web.