Este applet swing tiene carcaterísticas que pueden hacerlo de interés:
A continuación se muestra el applet, que maneja los siguientes eventos:
A continuación explicaremos con algo de detenimiento el código fuente.
Tal y como hemos comentado, en Swing los componentes, paneles y administradores de diseño se asignan al panel raíz. A diferencia de AWT, donde se asignan al Applet directamente. Lo principal es obtener el panel raíz, aquí lo nombramos cont_global y le asignamos un administrador de diseño del tipo GridLayout( filas, cols, hgap, vgap):
Container cont_global = this.getContentPane();
cont_global.setLayout( new GridLayout(2,1,5,5) );
El administrador elegido hace que el contenedor raíz se divida en dos filas y una columna. Visualmente el anidamiento de paneles hace que el applet se divida en dos zonas:
panel_sup.add( panel_botones, BorderLayout.NORTH );
panel_sup.add( scroll_lista, BorderLayout.CENTER );
panel_sup.add( text, BorderLayout.SOUTH );
Desde un punto de vista lógico vamos desde dentro hacia afuera, es decir, primero los paneles de dentro y luego los de fuera. En nuestro caso hacemos panel_bot, panel_sup y terminamos con cont_global:
cont_global.add( panel_sup );
cont_global.add( scroll_text );
El orden en el que añadimos (add) los elementos al contenedor raíz (cont_global) es significativo. Puesto que hemos escogido un administrador "grid" para el contenedor raíz, el primer add() asigna panel_sup a la fila de arriba (mitad superior) y el segundo add() asigna el editor a la mitad inferior (segunda fila del grid).
En Swing los scroll generalmente se añaden a los componentes. Siguiendo este estilo, en nuestro caso se añaden a la lista (JList) y al panel de edición de texto (JEditorPane)
JScrollPane scroll_lista = new JScrollPane( lista ); // Asignamos scroll a lista
JScrollPane scroll_text = new JScrollPane( panel_text ); // Asignamos scroll al panel de texto
A partir de este momento la lista y el editor estan "enganchados" a sus respectivos scrolls. Por ello, para asignar estos controles (lista y editor) a sus paneles debemos usar los scrolls:
panel_sup.add( scroll_lista, BorderLayout.CENTER );
cont_global.add( scroll_text );
Este es un ejemplo del patrón "Decorador":
La lista (clase JList) utiliza el patrón "modelo-vista", con la finalidad de desacoplar la presentación (vista) del tratamiento de los datos (modelo). Nos vamos a servir de nuestro ejemplo de applet para ver como se puede hacer esto de forma sencilla. En un problema que contenga cierta complejidad una aplicación estricta de este patrón implicaría crear una clase específica para el modelo. Pero para la mayor parte de los casos la problematica es muy sencilla, por lo que los diseñadores del JDK nos proveen con un "modelo por defecto" (clase DefaultListModel). Para empezar veamos como se pueden cargar los datos:
int cargar_datos_lista( ) {
DefaultListModel modelo = new DefaultListModel();
modelo.addElement( "Buenos dias" );
modelo.addElement( "Buenas noches" );
modelo.addElement( "¿Me sigue?" );
modelo.addElement( "Pues va a ser que no" );
modelo.addElement( "Me llamo Pablo" );
modelo.addElement( "¿Qué tal está?" );
lista.setModel(modelo);
return modelo.getSize();
}
Se puede observar que cargamos los datos en el modelo (addElement()) y después asignamos (setModel()) el modelo a la vista (lista). A partir de este momento cualquier cambio en el modelo se refleja en la vista (al cambiar, el propio modelo manda un "update" a la vista). El método termina devolviendo el número de items añadidos (getSize()).
Al pulsar el botón "Añadir" se añaden items al modelo:
String t = text.getText(); // Obtener texto de JTextField
DefaultListModel model = (DefaultListModel) lista.getModel();
model.addElement( t );
Al pulsar el botón "Eliminar" se borra el item de modelo:
model.remove(lista.getSelectedIndex());
Recordar que se cumple de forma estricta el patrón modelo-vista, así que cualquier cambio en el modelo se refleja de forma automática en la vista.
Hay una forma más rápida (y menos flexible) de añadir datos a una lista:
String datos = { "pedro", "ana", "juan" };
JList lis = new JList( datos );
Swing es compatible con el manejo de eventos de AWT. De hecho, lo que hace es ampliarlo. En nuestro ejemplo el problema es lo suficientemente sencillo como para gestionar los eventos tradicionales de AWT. Recordar lo que se dijo sobre la gestión de eventos en un applet AWT:
bot_añadir.addActionListener(new adaptador_bot_añadir(this));
bot_eliminar.addActionListener(new adaptador_bot_eliminar(this));
class adaptador_bot_añadir implements java.awt.event.ActionListener {
lista_texto adaptee; // El JApplet
adaptador_bot_añadir(lista_texto adaptee) {
this.adaptee = adaptee; // JApplet
}
public void actionPerformed(ActionEvent e) {
adaptee.bot_añadir_actionPerformed(e); // Método del applet que recibe el evento
}
}
void bot_añadir_actionPerformed(ActionEvent e) {
String t = text.getText(); // Obtener texto de JTextField
....
}