Vous êtes sur la page 1sur 26

Programación Orientada a Objetos

Junio, 2005

Programación con Swing


Noelia Méndez Fernández
Jose Luis García Valiente

Departamento de Informática y Automática


Universidad de Salamanca
Jose Luis García y Noelia Méndez

RESUMEN

Este documento pretende hacer una descripción de Swing, una de las APIs de Java, que se
incluye en las JFC 1.1.
En primer lugar se hace una introducción a Swing, describiendo el entorno en el que se
encuentra, tratando por ello algunos aspectos relacionados con AWT, JFC 1.1 y JDK 1.2.
Además, se realiza una breve descripción de las interfaces de usuario.
Posteriormente, se describe Swing con más profundidad, analizando su arquitectura y sus
componentes principales.
A continuación, se hace una pequeña introducción al manejo de eventos en Swing y a los
Applets.
Finalmente, se analiza por qué es útil convertir una aplicación a Swing y se dan unas
indicaciones para facilitar la conversión.
Y por último, se explican varios ejemplos de aplicaciones con Swing.

ABSTRACT

This document tries to make a description of Swing, one of the APIs of Java, which is included
in JFC 1.1.
First of all, this document makes an introduction to Swing, describing the IDE where it is,
dealing with some aspects related to AWT, JFC 1.1 and JDK 1.2. Besides, a short description
about the interfaces of user is made.
Afterwards, Swing is described more deeply, analysing its architecture and main
components.
Later, a small introduction about the management of events in Swing and the Applets is
made.
Eventually, why is useful to convert an application into Swing is analysed and some
indications are given to make easy the conversion.
Finally, some examples about applications with Swing are explained.

2
Programación con Swing

LISTA DE CONTENIDOS

- Introducción al trabajo ................................................................................................. Pág. 6


- Introducción a Swing .................................................................................................. Pág. 6
- Introducción a las interfaces de usuario y el AWT ...................................................... Pág. 6
- Swing, el AWT y las JFC............................................................................................. Pág. 7
- La jerarquía de componentes Swing ............................................................................ Pág. 8
- Panorámica del paquete Swing .................................................................................... Pág. 8
- Construcción de GUI en Swing .................................................................................. Pág. 10
- Manejo de eventos en Swing ...................................................................................... Pág. 12
- Applets en Swing ........................................................................................................ Pág. 13
- Conversión a Swing .................................................................................................... Pág. 13
- Ejemplos ..................................................................................................................... Pág. 14
- Conclusiones ............................................................................................................... Pág. 24
- Bibliografía ................................................................................................................. Pág. 26

3
Jose Luis García y Noelia Méndez

LISTA DE FIGURAS

- Figura 1: Swing, IFC, JFC y AWT .............................................................................. Pág. 7


- Figura 2: Jerarquía de componentes Swing ................................................................. Pág. 9
- Figura 3: Ejemplos de eventos .................................................................................... Pág. 12
- Figura 4: Relación entre eventos y oyentes................................................................. Pág. 13
- Figura 5: Ejemplo de ventana con pestañas ................................................................ Pág. 15
- Figura 6: Componentes de menús............................................................................... Pág. 17
- Figura 7: Árbol de herencia de las clases relacionadas con menús............................. Pág. 17
- Figura 8: Detección de eventos................................................................................... Pág. 19
- Figura 9: Menú personalizado..................................................................................... Pág. 22
- Figura 10: Otra distribución de un menú .................................................................... Pág. 22

4
Programación con Swing

LISTA DE TABLAS

- Tabla 1: Crear y configurar un TabbedPane ............................................................... Pág. 15


- Tabla 2: Insertar, Eliminar, Encontrar y Seleccionar Pestañas ................................... Pág. 16
- Tabla 3: Cambiar la Apariencia de las Pestañas ......................................................... Pág. 16
- Tabla 4: Crear y configurar barras de menús .............................................................. Pág. 22
- Tabla 5: Crear y Rellenar Menús ................................................................................ Pág. 22
- Tabla 6: Crear y Rellenar Menús Desplegables.......................................................... Pág. 23
- Tabla 7: Implementar Ítems de Menú ......................................................................... Pág. 23

5
Jose Luis García y Noelia Méndez

1. INTRODUCCIÓN AL TRABAJO
Este trabajo pretende ser una pequeña introducción a Swing, con la que se intenta mostrar al
lector una visión general sobre el mundo de las interfaces gráficas de usuario, y más
concretamente, sobre el desarrollo de éstas con Java y sus APIs. Puesto que tan sólo se trata de
una breve introducción al tema, lo que se pretende es captar la atención del lector y mostrar las
ventajas que ofrece éste tipo de programación.
En primer lugar, se realiza una introducción a Swing, el AWT y las interfaces de usuario,
tratando de ésta forma de centrar al lector en el tema a tratar.
Una vez realizada dicha introducción, se describirá brevemente el paquete Swing, para dar
una idea de la jerarquía de componentes que se puede utilizar con Swing y de sus utilidades.
También se mencionará el manejo de eventos en Swing, así como los Applets, aunque de
una forma muy superficial, ya que debido a la gran amplitud de variaciones que pueden darse,
sería muy extenso hacer una descripción detallada.
A continuación, se exponen los motivos por los que resulta interesante convertir las
aplicaciones a Swing.
Para terminar, se examinarán más concretamente dos de las clases que ofrece Swing: la
clase Tabbed Pane y la clase Menu.
Para aquellas personas que después de leer este documento se sientan atraídas por la
construcción de interfaces gráficas de usuario con Swing, al final del documento se incluyen las
referencias, para facilitar la búsqueda de información a todo el que desee profundizar en el
tema.

2. INTRODUCCIÓN A SWING
Swing es una de las mejoras principales que ha experimentado el JDK en su versión 1.2 con
respecto a la versión 1.1, y representa la nueva generación de AWT. También es una de las API
de las Clases de Fundamentos de Java (JFC), lo cual es el resultado de un esfuerzo de
colaboración muy grande entre Sun, Netscape, IBM y otras empresas. Lo que da a Swing su
importancia es el poder que ofrece para desarrollar interfaces gráficas de usuario (GUI) para
applets y aplicaciones. La cantidad y calidad de los controles GUI que ofrece Swing no tiene
rival en ningún otro juego de herramientas GUI.
El origen de los controles GUI que presenta Swing lo encontramos en las Clases de
Fundamentos de Internet de Netscape (IFC). Los componentes Swing van más allá de las IFC,
hasta el punto de que no hay un parecido apreciable entre los componentes Swing y los de las
IFC. Swing ofrece también la posibilidad de cambiar fácil y rápidamente el aspecto y sensación
(L&F) de un único componente o grupo de componente. Esta posibilidad, que se conoce como
aspecto y sensación conectables (PL&F), es un sello distintivo de Swing.

3. INTRODUCCIÓN A LAS INTERFACES DE USUARIO Y EL AWT


Para poder apreciar la importancia de Swing, haremos primero una introducción a las interfaces
de usuario y al AWT.
El interfaz de usuario es la parte del programa que permite a éste interactuar con el usuario.
Las interfaces de usuario pueden adoptar muchas formas, que van desde la simple línea de
comandos hasta las interfaces gráficas que proporcionan las aplicaciones más modernas. El
interfaz de usuario es el aspecto más importante de cualquier aplicación. Una aplicación sin un
interfaz fácil, impide que los usuarios saquen el máximo rendimiento del programa. Java
proporciona los elementos básicos para construir interfaces de usuario a través del AWT, y
opciones para mejorarlas mediante Swing, que sí permite la creación de interfaces de usuario de
gran impacto y sin demasiados quebraderos de cabeza por parte del programador.

6
Programación con Swing

Al nivel más bajo, el sistema operativo transmite información desde el ratón y el teclado
como dispositivos de entrada al programa. El AWT fue diseñado pensando en que el
programador no tuviese que preocuparse de detalles como controlar el movimiento del ratón o
leer el teclado, ni tampoco atender a detalles como la escritura en pantalla. El AWT constituye
una librería de clases orientada a objeto para cubrir estos recursos y servicios de bajo nivel.
Debido a que el lenguaje de programación Java es independiente de la plataforma en que se
ejecuten sus aplicaciones, el AWT también es independiente de la plataforma en que se ejecute.
El AWT proporciona un conjunto de herramientas para la construcción de interfaces gráficas
que tienen una apariencia y se comportan de forma semejante en todas las plataformas en que se
ejecute. Los elementos de interfaz proporcionados por el AWT están implementados utilizando
toolkits nativos de las plataformas, preservando una apariencia semejante a todas las
aplicaciones que se creen para esa plataforma. Este es un punto fuerte del AWT, pero también
tiene la desventaja de que un interfaz gráfico diseñado para una plataforma, puede no
visualizarse correctamente en otra diferente. Estas carencias del AWT son subsanadas en parte
por Swing, y en general por las JFC.

4. SWING, EL AWT Y LAS JFC

JFC

AWT
IFC Swing

Figura 1 Swing, IFC, JFC y AWT

La Figura 1 muestra la relación existente entre Swing, el AWT y las JFC. Las JFC subsumen y
amplían el AWT original, y constan de las siguientes API principales:
- AWT.
- Swing.
- Java 2D.
- Drag-and-Drop.
- Accessibility.
Aunque Swing esté separado del AWT, se implementa en términos de clases AWT básicas.
El AWT proporciona la interfaz entre el sistema de ventanas nativo subyacente y los
componentes GUI de Java. Swing utiliza esta interfaz, pero no se apoya en componentes del
AWT para hacer uso de objetos nativos. En lugar de ello, los componentes Swing están escritos
en Java puro. Esto ofrece ventajas significativas. Permite a los componentes Swing ser
independientes del sistema de ventanas nativo, lo cual implica que pueden ejecutarse en
cualquier sistema de ventanas que admita el AWT. También permite a los componentes Swing
ser independientes de cualquier limitación de los sistemas de ventanas nativos. Esta
independencia permite a Swing controlar y adaptar su aspecto y sensación (de ahí la aparición
de PL&F).
Entre los componentes nuevos que incluye Swing hay desde paneles tabulados y bordes
estilizados hasta barras deslizadoras y efectos giratorios. Estos componentes nuevos, en sí
mismos, hacen que Swing constituya un agregado de primera magnitud a la API Java. La galería
de componentes Swing, que se encuentra en http://java.sun.com/products/jfc/swingdoc-

7
Jose Luis García y Noelia Méndez

current/comp_gal.html, muestra algunos de ellos. Swing también incorpora un programa de


demostración llamado SwingSet.
Swing también ofrece una implementación de Java puro de muchos de los componentes
tradicionales del AWT. Estos componentes tienen la misma funcionalidad que los componentes
del AWT y todas las ventajas de Swing. Swing es compatible con el AWT, y los componentes
Swing se pueden utilizar con los componentes del AWT. Sin embargo, los compenentes Swing
sólo se pueden usar con el modelo de eventos del JDK 1.1. No admiten el modelo de eventos
del JDK 1.0.
La arquitectura PL&F de Swing facilita la personalización de tanto del aspecto como del
comportamiento de cualquier control Swing o de cualquier grupo de estos controles. Swing
también incorpora varios L&F predefinidos, entre los que reincluye el Metal L&F
predeterminado, el Motif L&F y el Windows L&F. Los L&F para Macintosh y otras
plataformas también se están desarrollando.

5. LA JERARQUÍA DE COMPONENTES SWING


Swing consta de nueve paquetes y cientos de clases e interfaces. No obstante, la clase
JComponent de java.awt.swing es la clase superior de la jerarquía de componentes
Swing. La clase JComponent es una subclase de la clase java.awt.container y, por
tanto, es a la vez un componente y un contenedor en el sentido del AWT. Dado que
JComponent es la superclase de todos los componentes Swing, todos ellos descienden de
java.awt.Container y java.awt.Component.
La Figura 2 muestra la jerarquía de componentes Swing. La primera cosa que se debe tener
en cuenta es que todos los componentes empiezan por la letra J, seguida por el tipo de
componente que admite la clase. Jcomponent consta de las subclases directas que se
muestran en la Figura 2.

6. PANORÁMICA DEL PAQUETE SWING


Swing es una API grande que consta de nueve paquetes y de numerosas clases e interfaces. La
mayor parte de componentes Swing se incluyen en el paquete java.awt.swing, el cual
ofrece asimismo clases e interfaces que admiten y manejan los componentes GUI. El paquete
java.awt.swing.border ofrece una serie de interesantes bordes que se pueden usar con
los componentes Swing. Estos bordes le ayudan a adaptar el aspecto y sensación de los
conjuntos de componentes.
El paquete java.awt.swing.event define los eventos y auditores de eventos que
utilizan los componentes Swing. Es sin duda una buena idea examinar la lista de eventos y de
auditores de eventos para tener una idea de las interacciones de usuario que admite Swing.
El paquete java.awt.swing.table ofrece clases e interfaces que admiten el objeto
JTable enriquecido y flexible. Estas clases e interfaces se usan para adaptar las características
de muestra de una tabla.
Los paquetes java.awt.swing.text ofrecen varias clases e interfaces que admiten
componentes de texto. Estas clases e interfaces controlan el signo de intercalación, resaltado,
formato y demás aspectos del texto que se introduce y se modifica en los componentes del texto.
El paquete java.awt.swing.text.html contiene la clase única
HTMLEditorKit. Esta clase admite la implementación de un editor HTML sencillo pero
potente. El paquete java.awt.swing.text.rtf es parecido al paquete
java.awt.swing.text.html. Contiene la clase única RTFEditorKit, la cual ofrece
la posibilidad de modificar Texto con Formato Enriquecido (RTF).

8
Programación con Swing

El paquete java.awt.swing.tree ofrece clases e interfaces que admiten el uso del


componente JTree.
El paquete java.awt.swing.undo admite operaciones hacer y rehacer.

JComponent
• AbstractButton
• JButton
• JMenuItem
• JCheckBoxMenuItem
• JMenu
• JRadioButtonMenuItem
• JToggleButton
• JCheckBox
• JRadioButton
• JComboBox
• JInternalFrame
• JLabel
• DefaultTableCellRenderer(java.awt.swing.table)
• JLayeredPane
• JDesktopPane
• JList
• JMenuBar
• JOptionPane
• JPanel
• ColorChooserPanel
• JPopupMenu
• JProgressBar
• JRootPane
• JScrollBar
• JScrollPane
• JSeparator
• JSlider
• JSplitPane
• JTabbedPane
• JTable
• JTableHeader(java.awt.swingn.table)
• JTextComponent(java.awt.swing.text)
• JEditorPane
• JTextPane
• JTextArea
• JTextField
• JPasswordField
• JToolBar
• JToolTip
• JTree
• JViewport

Figura 2. La jerarquía de componentes Swing

9
Jose Luis García y Noelia Méndez

7. CONSTRUCCIÓN DE GUI EN SWING


La construcción de una GUI en Swing es muy similar a la construcción de GUI en el AWT,
exceptuando que la primera tendrá muchas más clases de componentes con las que trabajar. A
continuación se describen las clases que se usan para la construcción de GUI y se señalan las
mejoras que Swing proporciona, comparando éstas clases con las de AWT.
- Ventanas
Swing, al igual que AWT, proporciona una jerarquía de clases Window. Las clases de la
ventana de Swing constituyen extensiones de la jerarquía de clases Window del AWT. La
clase JWindow amplía la clase Window. La clase JFrame amplía la clase JFrame del
AWT y la clase JDialog amplía la clase Dialog del AWT.
Las clases JWindow, JFrame y JDialog difieren de sus homólogos del AWT en
que utilizan un panel de contenido separado para agregar y diseñar componentes GUI. Este
panel es un objeto Container al que se accede a través del método
getContentPane(). El panel de contenido es una parte de un objeto JRootPane que
contiene otros paneles que se usan para sobreponerse a componentes e interceptar eventos
del ratón y del teclado.
- Menús
Los menús de Swing, al igual que las ventanas de Swing, son análogos a sus homólogos del
AWT. Las clases JMenuBar, JMenu, JMenuItem, JCheckBoxMenuItem y
JRadioButtonMenuItem se utilizan de la misma forma que las clases MenuBar,
Menu, MenuItem y CheckboxMenuItem del AWT, sólo que con una diferencia
fundamental. Las clases de menús de Swing son todas ellas subclases de la clase
JComponent y, por tanto, de la clase Component. Esto implica que los menús de Swing,
al contrario que sus homólogos del AWT, constituyen componentes de primera clase y se
pueden usar con cualquiera de las clases Container. La clase JPopupMenu es
equivalente a la clase PopupMenu del AWT. Otra atractiva característica de los menús de
Swing es la posibilidad de utilizar imágenes de iconos en los menús. Se puede añadir una
imagen a un elemento de menú por medio de su constructor.
- Paneles
La clase JPanel es el equivalente de Swing a la clase Panel del AWT. Esta clase, al
igual que sucede en otras clases de JComponent, ofrece la posibilidad de agregar un
borde.
- Diseños
Los contenedores de Swing admiten todos los diseños posibles del AWT, entre los que se
incluye el diseño null, además de admitir otros diseños nuevos.
- Iconos
Una de las características más útiles que Swing ofrece es la posibilidad de agregar iconos a
los componentes, como etiquetas, botones, elementos de menú, etc. La interfaz Icon define
los métodos que las clases de iconos deben implementar. La clase ImageIcon
proporciona una implementación predeterminada de esta interfaz. Los objetos ImageIcon
se pueden construir a partir de archivos de imagen, URL que apuntan a archivos de imagen
u objetos Image del AWT.
- Bordes
El paquete java.awt.swing.border proporciona la interfaz Border, la cual define
los métodos que necesitan ser implementados por todas las clases de bordes. La clase

10
Programación con Swing

AbstractBorder implementa la interfaz Border y es la superclase de las clases de


bordes de Swing.
- Información sobre herramientas
La clase JToolTip ofrece la posibilidad de agregar cuadros de texto emergentes que
aparecen cuando se posa el ratón sobre un componente. Estos componentes, que admiten
información sobre herramientas, permiten que éstas vengan especificadas en sus respectivos
constructores. El método setToolTipText() de la clase JComponent se puede usar
también para especificar la información sobre herramientas de un componente.
- Barras de herramientas
La clase JToolBar ofrece la posibilidad de utilizar barras de herramientas movibles y
acoplables con Swing. Los objetos de esta clase son contenedores de otros componentes
Swing o del AWT. Los objetos JToolBar típicos contienen objetos JButton que se
construyen por medio de iconos de imagen.
- Etiquetas y botones
Las clases JLabel y JButton proporcionan los equivalentes de Swing a las clases
Label y Button del AWT. La implementación de Swing ofrece la ventaja de poder usar
iconos a la vez que texto. Los constructores JLabel() y JButton() permiten que se
especifique un icono. Además, ambas clases admiten el método setIcon() para
establecer un icono una vez que se ha construido el objeto.
- Componentes de texto
Las clases JTextComponent, JTextField y JTextArea son los equivalentes de
Swing de las clases TextCompoenent, TextField y TextArea del AWT. Además,
Swing proporciona la clase TextPane para trabajar con documentos de texto, que se
pueden marcar con estilos de texto diferentes.
- Listas y cuadros combinados
Las clases JComboBox y JList ofrecen la posibilidad de presentarle al usuario una lista
de selecciones gráficas de texto. La clase JComboBox implementa una lista desplegable,
parecida a una lista de opciones Motif. La clase JList es una lista de selecciones
individuales o múltiples en las que se pueden ver muchos elementos.
- Deslizadores y barras de progreso
Las clases JSlider y JProgressBar carecen de equivalentes en el AWT. Ambas
clases admiten orientaciones horizontales y verticales. La clase JProgressBar se utiliza
típicamente para mostrar el progreso de una tarea, como la carga de una imagen. La clase
JSlider se usa para ajustar o controlar el valor de una variable dentro del intervalo
admisible.
- Barras de desplazamiento
El JScrollPane simplifica en gran medida el uso de las barras de desplazamiento. El
método getViewport() devuelve un objeto JViewport en el que se pueden ir
añadiendo componentes. En la mayoría de los casos, sólo necesita agregar componentes al
objeto JViewport para que uno se pueda desplazar automáticamente por ellos.
- Tablas
La clase JTable es otro componente de Swing que carece de equivalente en AWT.
JTable ofrece una posibilidad muy flexible para crear y mostrar tablas. Permite construir
tablas a partir de arrays o vectores de objetos, o bien a partir de objetos que implementan la
interfaz TableModel.

11
Jose Luis García y Noelia Méndez

La interfaz JTableModel define métodos para los objetos que especifican el


contenido de una tabla. La clase AbstractTableModel ofrece una implementación
predeterminada de la interfaz JTableModel. Esta clase se amplía típicamente para
proporcionar una implementación personalizada de modelo de tabla.
La clase JTable ofrece la posibilidad de editar tablas. El método
setCellEditor() permite que un objeto de la interfaz TableCellEditor sea
identificado como el editor de celdas de una tabla.
- Árboles
Una de las clases nuevas más interesantes que ofrece Swing es la clase JTree. Esta clase
implementa una estructura en forma de árbol que se puede usar para mostrar datos
jerárquicos. La interfaz TreeNode define métodos que tienen que implementar los nodos
de un objeto JTree. La clase DefaulMutableTreeNode proporciona una
implementación predeterminada de la interfaz TreeNode. Los árboles se crean
construyendo objetos de la interfaz TreeNode para luego añadirlos todos juntos (a través
del método add()). Cuando todos los objetos TreeNode se hayan juntado, el objeto
TreeNode resultante se pasa al constructor JTree.
La presentación predeterminada de un objeto JTree utiliza un icono de carpeta con el
fin de identificar los nodos de árbol que tienen nodos inferiores y un icono de archivo para
identificar las ramificaciones del árbol. El método setCellRenderer() de la clase
JTree se usa para identificar una prestación de árbol alternativa.

8. MANEJO DE EVENTOS EN SWING


Cada vez que el usuario teclea un carácter o pulsa un botón del ratón, ocurre un evento.
Cualquier componente puede ser notificado del evento. Todo lo que tiene que hacer es
implementar el interface apropiado y ser registrado como un oyente de evento del evento fuente
apropiado. Los componentes Swing pueden generar muchas clases de evento.
El paquete java.awt.swing.event define una serie de interfaces auditoras de
eventos y clases de eventos que se usan con los componentes Swing. Además, muchos de los
componentes Swing también utilizan eventos del AWT.
En la figura 3 mostramos unos pocos ejemplos:

Figura 3 Ejemplos de eventos

Cada evento está representado por un objeto que ofrece información sobre el evento e
identifica la fuente. Las fuentes de los eventos normalmente son componentes, pero otros tipos
de objetos también pueden ser fuente de eventos. Como muestra la siguiente figura, cada fuente

12
Programación con Swing

de evento puede tener varios oyentes registrados. Inversamente, un sólo oyente puede registrarse
con varias fuentes de eventos.

Figura 4 Relación entre eventos y oyentes

9. APPLETS DE SWING
La clase JApplet es el equivalente de Swing de la clase Applet. JApllet se parece a
JFrame en que admite un panel de contenido separado. A este contenedor se accede a través
del método getContentPane(). La barra de menús debe ser un objeto de la clase
JMenuBar.

10. CONVERSIÓN A SWING


9.1 ¿Por qué convertir a Swing?
Ante la pregunta, ¿por qué debo convertir a Swing?, la razón más fuerte es que Swing ofrece
muchos beneficios a los programadores y usuarios finales. Entre ellos:
- El rico conjunto de componentes listo-para-usar significa que podemos añadir
características divertidas a nuestros programas -- botones con imágenes, barras de
herramientas, paneles con pestañas, display HTML, imágenes en ítems de menú, un
selector de color, etc.
- También significa que podríamos reemplazar algunos componentes personalizados con
componentes Swing más extensibles y eficaces.
- Tener modelos separados de datos y estados hace que los componentes Swing sean
altamente personalizables y permite compartir datos entres componentes.
- La arquitectura conectable del aspecto y comportamiento swing ofrece una amplia
selección de aspectos y comportamientos. Junto al aspecto y comportamiento de la
plataforma usual, podemos usar el aspecto y comportamiento Java e incluso aspectos y
comportamientos de terceras partes.
- Los componentes Swing tienen soporte interno para accesibilidad, lo que hace que
nuestros programas pueden usarse automáticamente con tecnologías asistivas.
- Los componentes Swing continuarán ampliándose en el futuro.
- Por lo que la pregunta sería ahora "¿Por qué no debo convertir a Swing?" Es razonable
posponer la conversión si pensamos que nuestros usuarios no podrán ejecutar los
programas Swing de forma conveniente. Por ejemplo, su nuestro programa es un applet
y queremos que todo el mundo pueda usarlo en internet, deberíamos considerar cuantos
navegantes del Web tienen navegadores que puedan ejecutar programas Swing. En el
momento de escribir esto, la mayoría de los navegadores no tienen soporte Swing
interno; los usuarios deben añadirlo descargando e instalando Java Plug-in.

9.2 ¿Cómo convertir a Swing?

13
Jose Luis García y Noelia Méndez

Dado que Swing ofrece componentes GUI que son equivalentes a los componentes del AWT,
resulta fácil convertir las aplicaciones y applets a Swing. Las aplicaciones se convierten a
Swing reemplazando la clase Frame por la clase JFrame y utilizando getContentPane()
para acceder al contenedor del marco. Los componentes GUI que se hubieran añadido al Frame
se añaden al contenedor del marco. Los applets se convierten deforma parecida con la clase
JApplet reemplazando a la clase Applet. La mayor parte de los componentes GUI del
AWT pueden convertirse a Swing anteponiendo al nombre de la clase de AWT la letra ‘J’.

11. EJEMPLOS
Puesto que Swing tiene una gran cantidad de componentes y sería demasiado extenso detallar
cada uno de éstos, a continuación se analizan de forma detallada sólo dos de ellos. Para conocer
el funcionamiento del resto de los componentes, en la bibliografía se muestran algunas
referencias para encontrar la información necesaria.
10.1 Cómo utilizar la Clase Tabbed Pane
10.1.1 ¿Qué es la clase Tabbed Pane?
Con la clase JTabbedPane, podemos tener varios componentes (normalmente objetos
JPanel) compartiendo el mismo espacio. El usuario puede elegir qué componente ver
seleccionando la pestaña del componente deseado.
10.1.2 Construir una aplicación con un Tabbed Pane
Para crear un TabbedPane, simplemente se ejemplariza un JTabbedPane, se crean los
componentes que deseemos mostrar, y luego los añadimos al TabbedPane utilizando el
método addTab.
Compilando y ejecutando el siguiente código, se obtiene como resultado la ventana que
aparece representada en la Figura 5.

ImageIcon icon = new ImageIcon("images/middle.gif");


JTabbedPane tabbedPane = new JTabbedPane();
Component panel1 = makeTextPanel("Blah");
tabbedPane.addTab("One", icon, panel1, "Does nothing");
tabbedPane.setSelectedIndex(0);
Component panel2 = makeTextPanel("Blah blah");
tabbedPane.addTab("Two", icon, panel2, "Does twice as much nothing");
Component panel3 = makeTextPanel("Blah blah blah");
tabbedPane.addTab("Three", icon, panel3, "Still does nothing");
Component panel4 = makeTextPanel("Blah blah blah blah");
tabbedPane.addTab("Four", icon, panel4, "Does nothing at all");

14
Programación con Swing

Figura 5 Ejemplo de ventana con pestañas


Esta imagen representa una aplicación que utiliza cuatro TabbedPane. Como podemos
apreciar, la ventana está constituida por cuatro pestañas. Una pestaña puede tener un tooltip, y
puede mostrar tanto texto como una imagen. El ejemplo muestra las pestañas en sus posiciones
por defecto, en la parte superior del TabbedPane. Podemos cambiar las posiciones de las
pestañas a la izquierda, derecha, o abajo.
Poniendo el cursor sobre una pestaña, después de un corto tiempo, se verá una ayuda
(tooltip) asociada con la pestaña. Como conveniencia se debe añadir el texto de la ayuda
(tooltip) cuando se añade el componente al TabbedPane.
10.1.3 El API TabbedPane
Las siguientes tablas listan los métodos y constructores más utilizados de TabbedPane. El
API para utilizar TabbedPane se divide en estas categorías:
- Crear y configurar un TabbedPane.
- Insertar, Eliminar, Encontrar y Seleccionar Pestañas.
- Cambiar la apariencia de las pestañas.

Tabla 1 Crear y configurar un TabbedPane


Método Propósito
JTabbedPane() Crea un TabbedPane. El argumento
JTabbedPane(int) opcional indica dónde deberían aparecer las
pestañas.
Por defecto, las pestañas aparecen en la
parte superior. Se pueden especificar estas
posiciones (definidas en el interface
SwingConstants, que implementa
TabbedPane):
TOP, BOTTOM, LEFT, LEFT.

addTab(String, Icon, Component, Añade una nueva pestaña al TabbedPane.


String) El primer argumento especifica el texto de la
addTab(String, Icon, Component) pestaña.

addTab(String, Component) El argumento Icon es opcional e indica


el icono de la pestaña. El argumento
Component especifica el componente que el
TabbedPane debería mostrar cuando se
selecciona la pestaña. El cuarto argumento, si
existe, especifica el texto del tooltip para la
pestaña.

15
Jose Luis García y Noelia Méndez

Tabla 2 Insertar, Eliminar, Encontrar y Seleccionar Pestañas


Método Propósito
insertTab(String, Icon, Inserta una pestaña en el índice especificado,
Component, String, int) donde la primera pestaña tiene índice 0. Los
argumentos son los mismos que para
addTab.
remove(Component) Elimina la pestaña correspondiente al índice o
removeTabAt(int) componente especificado.

removeAll() Elimina todas las pestañas.


int indexOfComponent(Component) Devuelve el índice de la pestaña que tiene el
int indexOfTab(String) componente, título o icono especificados.

int indexOfTab(Icon)
void setSelectedIndex(int) Selecciona la pestaña que tiene el índice o
void componente especificado.
setSelectedComponent(Component) Seleccionar una pestaña tiene el efecto de
mostrar su componente asociado.

int getSelectedIndex() Devuelve el índice o componente de la


Component getSelectedComponent() pestaña seleccionada.

Tabla 3 Cambiar la Apariencia de las Pestañas


Método Propósito
void setComponentAt(int, Selecciona u obtiene qué componente está
Component) asociado con la pestaña del índice
Component getComponentA(int) especificado. La primera pestaña tiene índice
0.
void setTitleAt(int, String) Selecciona u obtiene el título de la pestaña del
String getTitleAt(int) índice especificado.

void setIconAt(int, Icon) Selecciona u obtiene iconos mostrados


Icon getIconAt(int) pestaña del índice especificado.

void setDisabledIconAt(int, Icon)


Icon getDisabledIconAt(int)
void setBackgroundAt(int, Color) Selecciona u obtiene el color de fondo o de
Color getBackgroundAt(int) primer plano usado por la pestaña del índice
especificado. Por defecto, una pestaña utiliza
void setForegroundAt(int, Color) los colores del TabbedPane.
Color getForegroundAt(int) Por ejemplo, si el color de primer plano del
TabbedPane es negro, entonces todos los
títulos de las pestañas serán en negro, excepto
para aquellas en que especifiquemos otro
color usando setForegroundAt.

16
Programación con Swing

void setEnabledAt(int, boolean) Selecciona u obtiene el estado activado de la


boolean isEnabledAt(int) pestaña del índice especificado.

10.2 Cómo Utilizar Menús


10.2.1 Qué es un Menú
Un menú proporciona una forma de ahorrar espacio y permitir al usuario elegir una entre varias
opciones. Otros componentes con los que el usuario puede hacer una elección incluyen combo
boxes, lists, radio buttons, y tool bars.
Los menús son únicos en que, por convención, no se sitúan con los otros componentes en el
UI. En su lugar, aparecen en una barra de menú o en un menú desplegable. Una barra de menú
contiene uno o más menús, y tiene una posición dependiente de la plataforma, normalmente
debajo de la parte superior de la ventana. Un menú desplegable es un menú que es invisible
hasta que el usuario hace una acción del ratón específica de la plataforma, como pulsar el botón
derecho del ratón sobre un componente. Entonces el menú desplegable aparece bajo el cursor.
La figura 6 muestra los componentes Swing que implementan cada parte de un sistema de
menús.

Figura 6 Componentes de un menú

10.2.2 La herencia de componentes de menú

Figura 7 Árbol de herencia de las clases relacionadas con menús.

17
Jose Luis García y Noelia Méndez

Como se ve en la figura 7, los ítems de menús (incluidos los propios menús) son simples
botones. Un menú, a pesar de ser un botón, muestra sus ítems ya que cuando se activa,
automáticamente trae un menú desplegable que muestra sus ítems.
10.2.3 Construir una aplicación con un Menú
A continuación tenemos el fragmento de código que crea los menús mostrados en la figura 4.
Como este código no tiene manejo de eventos, los menús no hacen nada útil, excepto verse
como serían. Si se ejecuta el ejemplo, observaremos que a pesar de no tener un manejo de
eventos, los menús y submenús aparecen cuando deben, y los checkbox y los botones de radio
responden apropiadamente cuando el usuario los elige.

menu.add(cbMenuItem);
cbMenuItem = new JCheckBoxMenuItem("Another one");
menu.add(cbMenuItem);
//a submenu
menu.addSeparator();
submenu = new JMenu("A submenu");
menuItem = new JMenuItem("An item in the submenu");
submenu.add(menuItem);
menuItem = new JMenuItem("Another item");
submenu.add(menuItem);
menu.add(submenu);
//Build second menu in the menu bar.
menu = new JMenu("Another Menu");
menuBar.add(menu);

Como se ve en el código, para configurar una barra de menú para un JFrame, se utiliza el
método setJMenuBar. Para añadir un JMenu a un JMenuBar, se utiliza el método
add(JMenu). Para añadir ítems de menú y submenús a un JMenu, se utiliza el método
add(JMenuItem). Estos métodos y otros más se listan en El API de JMenu.
10.2.4 Manejar Eventos desde Ítems de Menús
Para detectar cuando el usuario selecciona un JMenuItem, se puede escuchar por eventos
action (igual que se haría para un JButton). Para detectar cuando el usuario selecciona un
JRadioButtonMenuItem, se puede escuchar tanto por eventos action, como por eventos
item. Para JCheckBoxMenuItems, generalmente se escuchan eventos de item.
La figura 8 muestra un programa que añade detección de eventos al ejemplo anterior.

18
Programación con Swing

Figura 8 Detección de eventos


A continuación se muestra un fragmento de código que implementa el manejo de eventos:

public class MenuDemo ... implements ActionListener,


ItemListener {
...
public MenuDemo() {
...//for each JMenuItem instance:
menuItem.addActionListener(this);
...//for each JRadioButtonMenuItem:
rbMenuItem.addActionListener(this);
...//for each JCheckBoxMenuItem:
cbMenuItem.addItemListener(this);
...
}
public void actionPerformed(ActionEvent e) {
...//Get information from the action event...
...//Display it in the text area...
}
public void itemStateChanged(ItemEvent e) {
...//Get information from the item event...
...//Display it in the text area...
}

Para traer un menú desplegable (JPopupMenu), debemos registrar un oyente de ratón


para cada componente al que debería estar asociado el menú desplegable. El oyente de mouse
debe detectar las peticiones del usuario para que aparezca el menú desplegable.

19
Jose Luis García y Noelia Méndez

Para las plataformas Windows y Motif, el usuario trae un menú desplegable pulsando el
botón derecho del ratón mientras el cursor está sobre el componente adecuado. El oyente de
mouse trae un menú desplegable llamando a setVisible(true) sobre el ejemplar
apropiado de JPopupMenu.
El siguiente fragmento de código, muestra cómo crear y mostrar menús desplegables:
...//where instance variables are declared:
JPopupMenu popup;
...//where the GUI is constructed:
//Create the popup menu.
popup = new JPopupMenu();
menuItem = new JMenuItem("A popup menu item");
menuItem.addActionListener(this);
popup.add(menuItem);
menuItem = new JMenuItem("Another popup menu item");
menuItem.addActionListener(this);
popup.add(menuItem);
//Add listener to components that can bring up popup menus.
MouseListener popupListener = new PopupListener();
output.addMouseListener(popupListener);
menuBar.addMouseListener(popupListener);
...
class PopupListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
private void maybeShowPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
popup.show(e.getComponent(),
e.getX(), e.getY());
}
}
}

20
Programación con Swing

Los menús desplegables tienen unos pocos detalles interesantes de implementación. Uno es que
cada menú tiene un menú desplegable apropiado. Cuando el menú se activa, utiliza su menú
desplegable para mostrar sus ítems de menú.
Otro detalle es que un propio menú desplegable utiliza otro componente para implementar
la ventana que contiene los ítems del menú. Dependiendo de las circunstancias bajo las que se
muestre el menú desplegable, podría implementar su "ventana" utilizando un componente de
peso ligero (como un JPanel), un componente de peso medio (como un Panel), o una
ventana de peso pesado (Window).
Las ventanas desplegables de peso ligero son más eficientes que las ventanas de peso
pesado, pero no funcionan bien si tenemos componentes pesados dentro de nuestro GUI.
Específicamente, cuando un área de una ventana desplegable de peso ligero se intersecciona con
un componente de peso pesado, el componente de peso pesado se dibuja encima. Esta es una de
las razones por la que se recomienda no mezclar componentes de peso ligero y de peso pesado.
Si realmente se necesita utilizar un componente de peso pesado en el GUI, se puede utilizar el
método setLightWeightPopupEnabled de JPopupMenu para desactivar las ventanas
desplegables de peso ligero.
10.2.5 Personalizar la Distribución de un Menú
Como los menús se hacen con componentes ordinarios Swing, se pueden personalizar
fácilmente. Por ejemplo, se puede añadir cualquier componente de peso ligero a un JMenu o
JMenuBar. Y como JMenuBar utiliza BoxLayout, se puede personalizar la distribución de
la barra de menú añadiéndole componentes invisibles. Aquí mostramos un ejemplo que añade
un componente glue a una barra de menú, para que el último elemento del menú se sitúe en el
lado derecho de la barra de menú:
...//create and add some menus...
menuBar.add(Box.createHorizontalGlue());
...//create the LEFTmost menu...
menuBar.add(LEFTMenu);

En la figura 9 podemos ver una imagen del resultado.

Figura 9 Menú personalizado


Otra forma de cambiar el aspecto de un menú es cambiar el controlador de distribución que
lo controla. Por ejemplo, se puede cambiar el controlador de distribución de la barra de menú
del valor por defecto BoxLayout de izquierda-derecha, a algo como un GridLayout.
También podemos cambiar como un menú activado u otro menú desplegable distribuye sus
ítems. En la figura 10 se muestra una imagen de una aplicación en la que se ha modificado la
distribución del menú.

Figura 10 Otra distribución de un menú

21
Jose Luis García y Noelia Méndez

10.2.6 El API de JMenu


Las siguientes tablas listan los métodos y constructores más utilizados de Jmenu. El API
se divide en estas categorías:
- Crear y Configurar Barras de Menú.
- Crear y Rellenar Menús.
- Crear, Rellenar y Controlar Menús Desplegables.
- Implementar Ítems de Menú.

Tabla 4 Crear y configurar barras de menús


Método Propósito
JMenuBar() Crea una barra de menú.
void setJMenuBar(JMenuBar) Selecciona u obtiene la barra de menú de un
JMenuBar getJMenuBar() applet, dialog, frame, o root
pane.
(en JApplet, JDialog, JFrame,
JRootPane) En las siguientes versiones de Swing y
del JDK 1.2, los frames internos también
soportarán estos métodos.
void setMenuBar(JMenuBar) Selecciona u obtiene la barra de menú de un
JMenuBar getMenuBar() Frame interno. En las siguientes versiones de
Swing y del JDK 1.2, este método será
(en JInternalFrame) anulado y deberíamos utilizar
setJMenuBar/getJMenuBar.

Tabla 5 Crear y Rellenar Menús


Método Propósito
JMenu() Crea un menú.
JMenuItem add(JMenuItem) Añade un ítem de menú al final del menú.
JMenuItem add(Action) Si el argumento es un string, el menú
void add(String) crea automáticamente un objeto JMenuItem
que muestra el texto especificado.
void addSeparator() Añade un separador la final del menú.
>JMenuItem insert(JMenuItem, int) Inserta un ítem de menú o un separador en un
JMenuItem insert(Action, int) menú, en la posición especificada. El primer
ítem de menú es la posición 0, el segundo la
void insert(String, int) posición 1, etc. Los argumentos JMenuItem,
void insertSeparator(int) Action, y String se tratan de la misma
forma que en los correspondientes métodos
add.
void remove(JMenuItem) Elimina el ítem o ítems especificados del
void remove(int) menú. Si el argumento es un entero, especifica
la posición del ítem a eliminar.
void removeAll()

22
Programación con Swing

Tabla 6 Crear y Rellenar Menús Desplegables


Método Propósito
JPopupMenu() Crea un menú desplegable. El argumento
JPopupMenu(String) string opcional especifica el título que el
aspecto y comportamiento podría mostrar
como parte de la ventana desplegable.
JMenuItem add(JMenuItem) Añade un ítem de menú al final del menú
JMenuItem add(Action) desplegable.

void addSeparator() Añade un separador al final del menú


desplegable.
void insert(Component, int) Inserta un ítem de menú en la posición
JMenuItem insert(Action, int) especificada. El primer ítem del menú está
en la posición 0, el segundo en la posición
1, etc. El argumento Component
específica el ítem de menú a añadir. El
argumento Action es tratado de la misma
forma que en el método add
correspondiente.
void remove(JMenuItem) Elimina el ítem o ítems especificados del
void remove(int) menú.

void removeAll() Si el argumento es un entero, especifica


la posición del elemento del menú a
eliminar.
static void Por defecto, Swing implementa una ventana
setDefaultLightWeightPopupEnabled de menú utilizando un componente de peso
(boolean) ligero.
Esto causa problemas su utilizamos
componentes de peso pesado en nuestro
programa Swing. Para evitar estos
problemas, se puede llamar a
JPopupMenu.setDefaultLightWei
ghtPopupEnabled(false).
void show(Component, int, int) Muestra el menú desplegable en la posición
X,Y (especificada en el orden de los
argumentos enteros) en el sistema de
coordenadas del componente especificado.

Tabla 7 Implementar Ítems de Menú


Método Propósito
JMenuItem() Crea un ítem de menú normal. El
JMenuItem(Icon) argumento icon, si existe, especifica el
icono que debería mostrar el ítem de menú.
JMenuItem(String) Igualmente el argumento String, especifica
JMenuItem(String, Icon) el texto que debería mostrar el ítem de
menú. El argumento entero especifica el
JMenuItem(String, int) mnemónico de teclado a utilizar.
Se puede especificar una de las

23
Jose Luis García y Noelia Méndez

constantes VK definidas en la clase


KeyEvent. Por ejemplo, para especificar
"a" como el mnemónico, podemos utilizar
KeyEvent.VK_A.
JCheckBoxMenuItem() Crea un ítem de menú que se parece y
JCheckBoxMenuItem(Icon) actúa como un checkbox. Si se
especifica un icono, el ítem de menú utiliza
JCheckBoxMenuItem(String) el icono en vez del icono por defecto de los
JCheckBoxMenuItem(String, Icon) checkboxes. El argumento string, si
existe, especifica el texto que debería
JCheckBoxMenuItem(String, mostrar el ítem de menú. Si se especifica
boolean) true para el argumento booleano, el
JCheckBoxMenuItem(String, Icon, ítem de menú estará inicialmente
boolean) seleccionado. De lo contrario el ítem de
menú está desactivado.
JRadioButtonMenuItem() Crea un ítem de menú que se parece y
JRadioButtonMenuItem(Icon) actúa como un radio buttom. Si se
especifica un icono, el ítem de menú utiliza
JRadioButtonMenuItem(String) el icono en vez del icono por defecto de los
JRadioButtonMenuItem(String, botones de radio. El argumento string,
Icon)< si existe, especifica el texto que debería
mostrar el ítem de menú. El ítem de menú
está inicialmente desactivado.
void setState(boolean) Selecciona u obtiene el estado de selección
boolean getState() de un ítem de menú.

void setEnabled(boolean) Si el argumento es true, activa el ítem de


menú, si es false lo desactiva.

void setMnemonic(char) Selecciona la tecla alternativa para


seleccionar el ítem de menú sin el ratón.
void setActionCommand(String) Selecciona el nombre de la acción
realizada por el ítem de menú.
void Añade un oyente de eventos al ítem de
addActionListener(ActionListener) menú.
void
addItemListener(ItemListener)
La mayoría de los métodos anteriores son heredados desde AbstractButton.

12. CONCLUSIONES
Swing es un API que ofrece JFC 1.1, y representa la nueva generación de AWT. Swing amplía
AWT proporcionando muchos más tipos de componentes GUI, ofreciendo implementaciones
cien por cien Java puro a estos componentes y permitiendo adaptar fácilmente el aspecto y
comportamiento de tales componentes, facilitando así el trabajo de los programadores.
El que los componentes de Swing sean cien por cien Java puro implica que no dependen de
ninguna implementación nativa de ventanas que les de soporte, y que además estén disponibles
y sean consecuentes en todo tipo de plataforma.

24
Programación con Swing

Transformar programas de AWT a Swing es muy sencillo, y gracias a todos los


componentes que ofrece, presenta gran cantidad de ventajas, por lo que es recomendable utilizar
éste API.

25
Jose Luis García y Noelia Méndez

13. BIBLIOGRAFÍA
- http://www.programacion.com/java/tutorial/swing/
- Manual - Programación - Java tutor Swing
- http://jungla.dit.upm.es/~santiago/docencia/apuntes/Swing/
- Java 1.2 Al descubierto. Jaime Jaworski
- Sun’s Java Swing Tutorial
- Java Swing Tutorial (2005)
- Lenguaje de programación Java

26