Sie sind auf Seite 1von 12

Universidad Catlica Los ngeles de Chimbote Programacin Visual II

OBJETOS JDIALOG, JTREE Y JFORMATTEDTEXTFIELD

Objeto JDialog En una aplicacin java con ventanas debera haber un nico JFrame, correspondiente a la ventana principal de la aplicacin. El resto de ventanas secundarias deberan ser JDialog. Por supuesto, podemos usar JInternalFrame, si lo deseamos sin ningn problema, pero en sta sesin nos referimos slo a ventanas "reales", a las que el sistema operativo trata como tales.
Ing. Martn Salcedo Quiones Pgina 1

Universidad Catlica Los ngeles de Chimbote Programacin Visual II


Un JFrame en una ventana que en Windows crea, en la barra de herramientas, donde est el men de "inicio" y las aplicaciones que tenemos abiertas, un nuevo botn de aplicacin abierta. En una aplicacin lo normal es que slo haya un botn ah. Si creamos varios JFrame en nuestra aplicacin, aparecern varios botones, uno por cada JFrame. El JDialog no muestra este botn. Por ello, el resto de las ventanas de nuestra aplicacin deberas ser JDialog. Hay otro motivo ms. Un JFrame no admite a ninguna otra ventana como padre. El JDialog s admite como padres un JFrame u otros JDialog. Esto es importante porque una ventana hija siempre quedar por encima de su ventana padre. Si al crear los JDialog les pasamos el JFrame como padre, los JDialog siempre estarn visibles por encima del JFrame. No se podrn ir "detrs" de l. Si adems, en el constructor del JDialog ponemos a true el flag que indica que es modal, adems de pasarle una ventana padre, entonces el JDialog impedir el acceso a las otras ventanas hasta que se cierre. Otra ventaja de admitir un padre es que heredan el icono de l. Si hemos cambiado el icono del JFrame con el mtodo setIconImage(), entonces todos los JDialog que hagamos como hijos de este JFrame heredarn el icono. Todas las ventanas de nuestra aplicacin tendrn el mismo icono en lugar de la taza de caf por defecto. Un JDialog puede ser modal, pasndole un true en el constructor en el sitio adecuado o hacindolo modal con el mtodo setModal(). Si hacemos un JDialog modal, todas las dems ventanas se deshabilitarn hasta que el usuario de nuestro programa cierre el JDialog. Esto est estupendo para pedir un dato al usuario y evitar que toque otras cosas hasta que haya introducido el dato. Sin embargo, tiene un peligro. Supongamos un JDialog que lo hacemos modal para pedir unos datos al usuario. Este JDialog tiene un botn de "Aceptar" para que el usuario lo pulse cuando haya terminado de introducir los datos. Supongamos que en el cdigo de ese botn "Aceptar" comprobamos los datos que ha metido el usuario y vemos que son incorrectos. Le sacamos un segundo JDialog modal para indicarle el error y no cerramos el primero.
Ing. Martn Salcedo Quiones Pgina 2

Universidad Catlica Los ngeles de Chimbote Programacin Visual II


Quin debe ser el padre de ese segundo JDialog modal?. Si hacemos que el padre sea el JFrame tendremos dos JDialog modales hijos del JFrame, es decir, dos JDialog modales hermanos. Esto nos dar problemas, como que ambas ventanas queden deshabilitadas, que al cerrar una de ellas se nos oculten todas, que parte de la ventana quede deshabilitada mientras que otra parte no, etc. Entonces, cmo hacemos?. Para que java no haga cosas raras, el padre del segundo JDialog modal debe ser el primer JDialog modal. De esta forma, el segundo tiene "prioridad" sobre el primero. Todo queda deshabilitado excepto este segundo JDialog. Cuando lo cerremos, ser el primero el que mande. Resumiendo, si queremos varias ventanas modales simultneamente en pantalla, cada ventana que se muestre debe ser padre de la siguiente, de forma que la cadena de ventanas modales sean padre, hijo, nieto, etc. Tener dos ventanas modales simultaneas que sean hermanas o primas o cualquier otra relacin que no sea directa, nos dar problemas Veamos a continuacin un ejemplo sencillo usando JDialog
import java.awt.event.*; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.WindowConstants; public class DosVentanas { private JFrame ventanaPrincipal; private JDialog ventanaSecundaria; public static void main(String[] args) { new DosVentanas(); } public DosVentanas() { // Construccin de ventana principal ventanaPrincipal = new JFrame("Ventana principal"); JButton boton = new JButton("Abre secundaria"); ventanaPrincipal.getContentPane().add(boton); Ing. Martn Salcedo Quiones Pgina 3

Universidad Catlica Los ngeles de Chimbote Programacin Visual II


ventanaPrincipal.pack(); // Construccin de ventana secundaria ventanaSecundaria = new JDialog(ventanaPrincipal,"Ventana secundaria"); JLabel etiqueta = new JLabel("Hola"); ventanaSecundaria.getContentPane().add(etiqueta); ventanaSecundaria.pack(); // Hacer que el botn abra la ventana secundaria y cierre la principal boton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ventanaPrincipal.setVisible(false); ventanaSecundaria.setVisible(true); } }); // Hacer que al cerrarse la secundaria con la x de arriba a la // derecha, se muestre la primaria ventanaSecundaria.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { ventanaPrincipal.setVisible(true); ventanaSecundaria.setVisible(false); } public void windowClosed(WindowEvent e) { ventanaPrincipal.setVisible(true); ventanaSecundaria.setVisible(false); }

});

// Mostrar la ventana principal ventanaPrincipal.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); ventanaPrincipal.setVisible(true); } }

Al momento de ejecutar el cdigo antes indicado, se visualiza:

Al dar clic en el botn de comando Abre secundaria se muestra:


Ing. Martn Salcedo Quiones Pgina 4

Universidad Catlica Los ngeles de Chimbote Programacin Visual II

Objeto JTree El JTree es el componente java visual (como los botoncitos, listas, mens, etc) que nos permite visualizar un rbol. En l podemos ver el tpico rbol de datos en el que podemos abrir cada uno de los nodos para ver qu tiene dentro, cerrarlos, etc. Similar al rbol de directorios que nos muestran algunas aplicaciones para elegir un fichero. Como en casi todos los componentes visuales de java, hay dos clases importantes implicadas. Por un lado tenemos "la vista", que es la clase java que se ve. Esta clase es el JTree y es lo que se ve en la pantalla, en nuestra ventana. Por otro lado tenemos el "modelo de datos". Esta clase de java puede ser cualquier clase que implemente la interface TreeModel, pero java nos ofrece ya implementada la clase DefaultTreeModel. Esta clase es la que contiene los datos que queremos visualizar en "la vista". Contiene los datos que visualizaremos en el JTree. Puesto que vamos a hacer un rbol, admite datos que se puedan asociar entre s como padres e hijos. No valen datos cualesquiera. Esos datos deben implementar la interface TreeNode. Cualquier clase que implemente esta interface, tendr mtodos para interrogarle sobre quin es su padre, si tiene hijos, etc. Estos mtodos ser los que acabe usando JTree para saber qu debe pintar, quin es hijo de quin y quin es padre de quin. Existe otro tipo de dato tambin importante, el MutableTreeNode. Este es igual que el anterior, pero adems tiene mtodos para modificar las asociaciones entre padres e hijos. Permite aadir nuevos hiijos a los padres, cambiar el padre de los hijos y cualquier otro tipo de indecencia que se nos ocurra. Si nuestro rbol va a cambiar sobre la marcha, nos interesa usar datos (nodos) que implementen esta interface. Java nuevamente nos ofrece una clase que ya implementa MutableTreeNode y por tanto tiene todos los
Ing. Martn Salcedo Quiones Pgina 5

Universidad Catlica Los ngeles de Chimbote Programacin Visual II


mtodos necesarios para saber quin es hijo de quin y los mtodos necesarios para cambiar estas asociaciones. Esta clase es DefaultMutableTreeNode. Tiene adems un mtodo intereseante, que es setUserObject(). Este mtodo nos permite guardar dentro la informacin que queramos. Esta informacin ser nuestro dato real, lo que realmente nos interesa. DefaultMutableTreeNode nicamente nos ahorrar escribir el cdigo necesario para mantener asociaciones entre padres e hijos, adems de hacer de almacn de nuestro dato. Vamos a proceder a construir un rbol que tenga la siguiente apariencia:

Primero instanciamos nuestro modelo de datos, el DefaultTreeModel y la parte visual, el JTree. Metemos el primero dentro del segundo. La clase DefaultTreeModel necesita en su constructor el nodo raz del rbol, es decir, el dato que hace de padre de todos los dems, el de ms alto nivel. Por ello, debemos instanciar este primer dato para poder construir el DefaultTreeModel. Ese primer dato ser un DefaultMutableTreeNode. A este DefaultMutableTreeNode podemos pasarle el dato que queramos bien a travs del mtodo que comentamos setUserObject(), bien a travs del constructor. Nuestro dato ser un simple String que diga "abuelo" y lo meteremos en el constructor. El cdigo quedara as
DefaultMutableTreeNode abuelo = new DefaultMutableTreeNode("abuelo"); modelo = new DefaultTreeModel(abuelo); JTree tree = new JTree(modelo);

Ahora slo nos queda ir aadiendo el resto de los datos del rbol. Lo nico que tenemos que hacer es ir creando los nodos, como DefaultMutableTreeNode. A
Ing. Martn Salcedo Quiones Pgina 6

Universidad Catlica Los ngeles de Chimbote Programacin Visual II


cada uno de ellos meterle el dato que queramos, bien en el constructor, bien con el mtodo setUserObject(). En nuestro caso usaremos un simple String con el texto que queremos que se muestre. Finalmente, hay que ir asociando estos datos. El abuelo ya lo tenemos creado, as que el cdigo de creacin de los dems nodos puede ser este:
DefaultMutableTreeNode padre = new DefaultMutableTreeNode("padre"); DefaultMutableTreeNode tio = new DefaultMutableTreeNode("tio"); DefaultMutableTreeNode hijo=new DefaultMutableTreeNode("hijo"); DefaultMutableTreeNode hija=new DefaultMutableTreeNode("hija");

Para asociar estos datos tenemos dos opciones:


1. Usar los mtodos add(), insert() y setParent() de DefaultMutableTreeNode

para ir aadiendo unos nodos a otros.


2. Usar el mtodo insertNodeInto() de DefaultTreeModel. A este mtodo le

pasamos nodo padre e hijo que queremos asociar y el se encarga de hacer la asociacin. La diferencia de hacerlo de una manera u otra es que JTree se entera automticamente de cambios de DefaultTreeModel y los refleja automticamente en pantalla, pero no se entera de los cambios en los DefaultMutableTreeNode y por tanto no los refresca en pantalla. Puesto que estamos haciendo un ejemplo simple y es ms simple, usaremos el mtodo insertNodeInto() para hacer la asociacin. Este mtodo lleva tres parmetros: Nodo que queremos que sea hijo Nodo que queremos que sea padre

En qu posicin queremos que est el hijo respecto a otros hijos. Dicho de otra forma, cuando despleguemos un padre que tiene por ejemplo cuatro hijos, en qu posicin queremos que est este nuevo hijo: el primero, en medio, el ltimo.

El cdigo para estas asociaciones es sencillo:


Ing. Martn Salcedo Quiones Pgina 7

Universidad Catlica Los ngeles de Chimbote Programacin Visual II


modelo.insertNodeInto(padre,abuelo,0); modelo.insertNodeInto(tio, abuelo, 1); modelo.insertNodeInto(hijo, padre, 0); modelo.insertNodeInto(hija, padre, 1);

Por lo tanto, el cdigo quedara de la siguiente manera:


import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.WindowConstants; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; public class PruebaJTree { public static void main(String[] args) { // Construccion del arbol DefaultMutableTreeNode abuelo = new DefaultMutableTreeNode("abuelo"); DefaultTreeModel modelo = new DefaultTreeModel(abuelo); JTree tree = new JTree(modelo); // Construccion de los datos del arbol DefaultMutableTreeNode padre = new DefaultMutableTreeNode("padre"); DefaultMutableTreeNode tio = new DefaultMutableTreeNode("tio"); modelo.insertNodeInto(padre, abuelo, 0); modelo.insertNodeInto(tio, abuelo, 1); DefaultMutableTreeNode hijo = new DefaultMutableTreeNode("hijo"); DefaultMutableTreeNode hija = new DefaultMutableTreeNode("hija"); modelo.insertNodeInto(hijo, padre, 0); modelo.insertNodeInto(hija, padre, 1); // Construccion y visualizacion de la ventana JFrame v = new JFrame(); JScrollPane scroll = new JScrollPane(tree); v.getContentPane().add(scroll); v.pack(); v.setVisible(true); v.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); } }

Al momento de ejecutar el cdigo antes indicado, se visualiza:


Ing. Martn Salcedo Quiones Pgina 8

Universidad Catlica Los ngeles de Chimbote Programacin Visual II

Objeto JFormattedTextField El JFormattedTextField es un componente java un paso ms evolucionado que un JTextField normal. El JTextField permite al usuario ingresar texto. Cuando desde nuestro cdigo le pedimos el contenido, nos devuelve el texto introducido por el usuario como String. Cuando desde cdigo le decimos lo que queremos que muestre, debemos pasarle un String. El JTextField, adems, no hace ningn tipo de comprobacin sobre el texto. El JFormattedTextField da un paso ms all. Aunque el usuario mete un texto, el JFormattedTextField lo convierte a la clase que nosotros queramos (un Integer, Float, Date o incluso una clase nuestra propia). Cuando queramos pasarle algo, le podemos pasar directamente cualquiera de estas clases y l se encarga de la conversin a texto para mostrar. Para editar cualquier tipo bsico de java, estilo Integer, Float, Double, Date, etc, basta con llamar al mtodo setValue() del JFormattedTextField pasndole uno

Ing. Martn Salcedo Quiones

Pgina 9

Universidad Catlica Los ngeles de Chimbote Programacin Visual II


de estos tipos de datos, o bien pasrselo en el constructor. Por ejemplo, para Integer,
nos bastara con cualquiera de los dos casos siguientes: JFormattedTextField textField1 = new JFormattedTextField (new Integer(3)); // o bien .... JFormattedTextField textField2 = new JFormattedTextField (); textField2.setValue(new Integer(3));

Con esto ya tenemos un editor que nos permite recoger Integer directamente cuando el usuario lo edite:
Integer valor = textField1.getValue();

Supongamos que el usuario escribe algo en el JFormattedTextField y luego pincha con el ratn en otros sitio (se dice que el JFormattedTextField pierde el foco), por ejemplo, en un botn de "Aceptar" los cambios introducidos. En el momento que el JFormattedTextField pierde el foco, comprueba el texto escrito por el usuario. Si es correcto, lo guarda de forma que el mtodo getValue() nos devolver el nuevo valor. Si es incorrecto, pondr automticamente el ltimo valor bueno, deshaciendo el cambio hecho por el usuario. Este comportamiento puede cambiarse con el mtodo setFocusLostBehavior(), al que podemos pasar varios valores:

JFormattedTextField.COMMIT. Si el texto introducido es correcto, se guarda para devolverlo cuando se haga getValue(). Si es incorrecto, no se hace nada, el texto en pantalla queda como esta, o sea, mal. getValue() nos devolver el ltimo valor correcto, independientemente de lo que se muestre en pantalla.

JFormattedTextField.REVERT. Cuando hacemos click en otro sitio, el editor vuelve automticamete a su ltimo valor bueno, descartando todas nuestras ediciones, sean correctas o no. Para que esta opcin tenga sentido, debemos llamar desde cdigo al mtodo commitEdit() sin que el

Ing. Martn Salcedo Quiones

Pgina 10

Universidad Catlica Los ngeles de Chimbote Programacin Visual II


JFormattedTextField pierda el foco, por ejemplo, cuando se pulsa <intro> sobre el editor, validando as los cambios realizados.

JFormattedTextField.COMMIT_OR_REVERT. Esta es la opcin por defecto y la ms til. Si el texto introducido es incorrecto, se vuelve automticamente al ltimo valor bueno conocido. Si el texto no es vlido, se muestra el ltimo valor bueno conocido.<>

JFormattedTextField.PERSIST. Esta opcin no hace nada con el texto introducido, independientemente de que est bien o mal. getValue() siempre devolver el ltimo valor bueno conocido. Para que el editor recoga el nuevo valor, debemos llamar a commitEdit() previamente.

Existen varios JFormattedTextField.AbstractFormatter adems de los que podamos hacernos nosotros. Uno de los ms conocidos es el MaskFormatter. Este formateador restringe el texto vlido incluso mientras lo estamos tecleando. Al instanciar el MaskFormatter le damos un "patrn" sobre cmo queremos que sea el texto. Una vez configurado todo, el usuario no podr escribir en el FormattedTextField nada que se salga de ese "patrn". Veamos con un ejemplo qu quiero decir.

Supongamos que quiero un editor que me permita escribir un nmero con dos cifras enteras y dos decimales. No queremos que el usuario escriba algo que no sea un nmero y no queremos que escriba ni ms ni menos de las cifras de las indicadas. El editor debe admitir y devolvernos con setValue() y getValue() un Float. Para conseguir esto, basta instanciar un MaskFormatter y pasrselo al JFormattedTextField en el constructor. Para evitar problemas, le damos un valor vlido inicial vlido al editor. El new MaskFormatter lanza una excepcin, as que debemos capturarla.
try { /* El "patrn" para el editor. Las # representan cifras. En la API puedes ver ms. Ojo con el punto decimal, segn el idioma puede ser una coma.*/ MaskFormatter mascara = new MaskFormatter("##.##"); Ing. Martn Salcedo Quiones Pgina 11

Universidad Catlica Los ngeles de Chimbote Programacin Visual II


// Se construye el JFormattedTextField pasndole la mscara JFormattedTextField textField = new JFormattedTextField(mascara); // Se da un valor inicial vlido para evitar problemas textField.setValue(new Float("12.34")); } catch (...)

Ya est listo. Nuestro editor slo admite nmeros de dos cifras enteras y dos decimales y no nos deja escribir otra cosa. Los mtodos getValue() y setValue() devuelven y admiten Floats.

Ing. Martn Salcedo Quiones

Pgina 12

Das könnte Ihnen auch gefallen