Hola a todos, hoy os explicare como crear un dialogo para nuestra aplicación gráfica en Java.
Un diálogo es una ventana secundaria, normalmente, que se usa para que el usuario indique algún tipo de información.
Para ello, lo que haremos es crear un nuevo fichero Java en el mismo proyecto pero en lugar de crear una clase grafica JFrame, crearemos una clase JDialog.
Por defecto, esto es el código que nos crea:
import java.awt.BorderLayout; import java.awt.FlowLayout; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; public class EjemploDialogo extends JDialog { private final JPanel contentPanel = new JPanel(); /** * Launch the application. */ public static void main(String[] args) { try { EjemploDialogo dialog = new EjemploDialogo(); dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); dialog.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } /** * Create the dialog. */ public EjemploDialogo() { setBounds(100, 100, 450, 300); getContentPane().setLayout(new BorderLayout()); contentPanel.setLayout(new FlowLayout()); contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); getContentPane().add(contentPanel, BorderLayout.CENTER); { JPanel buttonPane = new JPanel(); buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT)); getContentPane().add(buttonPane, BorderLayout.SOUTH); { JButton okButton = new JButton("OK"); okButton.setActionCommand("OK"); buttonPane.add(okButton); getRootPane().setDefaultButton(okButton); } { JButton cancelButton = new JButton("Cancel"); cancelButton.setActionCommand("Cancel"); buttonPane.add(cancelButton); } } } }
Recuerda que podemos modificar el código como queramos.
Esto es lo que se ve si ejecutamos:
Como vemos, tenemos dos botones que no realizan ninguna acción, podemos modificar las acciones con eventos, como ya vimos.
Ahora podemos añadir elementos como ya vimos anteriormente, en nuestro caso, haremos que nos poda algún dato que debamos mostrar en la ventana principal, como escribir un nombre y apellido que nos lo muestre juntos.
Ahora nos toca programar los eventos, en el caso de los componentes que hayamos insertado, programaremos los eventos que veamos necesarios, lo que si deberemos de hacer es hacer como atributo los componentes que debamos extraer información, en nuestro caso, los dos campos de texto (no las etiquetas).
Para los botones que por defecto nos crea el diálogo (OK y Cancel), crearemos un evento para cada uno que hará que la ventana desaparezca y un atributo booleano para el botón OK, con su método get.
IMPORTANTE: debemos borrar el método main, no te preocupes, podrás ejecutarlo, desde la ventana principal. Si no lo haces, no te funcionara correctamente.
Vamos a ver como queda de momento.
import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.event.*; import javax.swing.*; public class EjemploDialogo extends JDialog { private final JPanel contentPanel = new JPanel(); //Atributos creados para pasar a la ventana principal private JTextField textField; private JTextField textField_1; private boolean pulsoOK; //Indicamos un frame como parámetro public EjemploDialogo(JFrame frame) { /* * Invocamos elconstructor padre, el booleano nos permite * crear un dialogo modal, es decir, que hasta que no * quitemos la ventana no podremos acceder a otra. */ super(frame, true); //Codigo que genero al crear el dialogo setBounds(100, 100, 450, 300); getContentPane().setLayout(new BorderLayout()); contentPanel.setLayout(null); getContentPane().add(contentPanel, BorderLayout.CENTER); JPanel buttonPane = new JPanel(); buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT)); getContentPane().add(buttonPane, BorderLayout.SOUTH); JButton okButton = new JButton("OK"); okButton.setActionCommand("OK"); buttonPane.add(okButton); getRootPane().setDefaultButton(okButton); JButton cancelButton = new JButton("Cancel"); cancelButton.setActionCommand("Cancel"); buttonPane.add(cancelButton); //Componentes creados JLabel lblEscribeElNombre = new JLabel("Escribe el nombre"); lblEscribeElNombre.setBounds(24, 28, 133, 14); contentPanel.add(lblEscribeElNombre); textField = new JTextField(); textField.setBounds(23, 56, 153, 20); contentPanel.add(textField); JLabel lblEscribeElApellido = new JLabel("Escribe el apellido"); lblEscribeElApellido.setBounds(24, 105, 152, 14); contentPanel.add(lblEscribeElApellido); textField_1 = new JTextField(); textField_1.setBounds(24, 146, 152, 20); contentPanel.add(textField_1); //Eventos cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { setVisible(false); } }); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { //Indicara que hemos introducido correctamentelos datos pulsoOK=true; setVisible(false); } }); //Creamos un listener que es igual para dos componentes KeyListener kl=new KeyListener(){ public void keyTyped(KeyEvent e){ if(Character.isDigit(e.getKeyChar())){ e.consume(); } } public void keyPressed (KeyEvent e){ } public void keyReleased(KeyEvent e){ } }; //Añadimos el listener textField.addKeyListener(kl); textField_1.addKeyListener(kl); } //Modificamos los metodos get, para que devuelva un String directamente public String getNombre() { return textField.getText(); } public String getApellido() { return textField_1.getText(); } //Usaremos este metodo en la ventana principal public boolean isPulsoOK() { return pulsoOK; } }
La idea de todo esto que estamos haciendo es que en la ventana principal creemos un objeto Dialogo en el evento del componente para que abra el dialogo y en este mismo, controlar que cuando pulsemos OK, haga lo que tengamos que hacer.
IMPORTANTE: crearemos un atributo con un tipo que sera el mismo nombre de la clase. El nombre del atributo lo elegiremos nosotros, este atributo, se pasara al crear el diálogo.
Veamos el código de la ventana principal, haciendo lo que antes hemos comentado:
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class EjemploDialogoVentanaPrincipal extends JFrame { private JPanel contentPane; private JTextField textField; private EjemploDialogoVentanaPrincipal frame; //Atributo con el mismo tipo que la clase /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { EjemploDialogoVentanaPrincipal frame = new EjemploDialogoVentanaPrincipal(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public EjemploDialogoVentanaPrincipal() { //Tirulo de la ventana setTitle("Ejemplo"); //Operacion por defecto al cerrar la ventana setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Colocamos la ventana setBounds(100, 100, 450, 300); //Creamos el panel contentPane = new JPanel(); //Indicamos el diseño usado contentPane.setLayout(null); //Añadimos el panel al frame setContentPane(contentPane); //Componentes textField = new JTextField(); textField.setBounds(48, 110, 159, 20); textField.setEditable(false); contentPane.add(textField); textField.setColumns(10); JLabel lblNombreYApellido = new JLabel("Nombre y apellido fusionado"); lblNombreYApellido.setBounds(48, 71, 159, 14); contentPane.add(lblNombreYApellido); JButton btnAbrirDilogo = new JButton("Abrir di\u00E1logo"); btnAbrirDilogo.setBounds(251, 109, 141, 23); contentPane.add(btnAbrirDilogo); btnAbrirDilogo.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ //Creamos un objeto dialogo, le pasamos el atributo frame EjemploDialogo dialogo=new EjemploDialogo(frame); //Hacemos visible la ventana de dialogo dialogo.setVisible(true); //Cuando pulsemos OK, en el dialogo realizara esta accion. if(dialogo.isPulsoOK()){ String nombre=dialogo.getNombre(); String apellido=dialogo.getApellido(); textField.setText(nombre+" "+apellido); } } }); } }
Veamos como queda, gráficamente:
Se nos abre el diálogo. Escribimos el nombre y apellido:
Pinchamos en OK y vemos el resultado:
Os dejo las dos clases del ejemplo:
–Dialogo
import java.awt.BorderLayout; import java.awt.FlowLayout; import java.awt.event.*; import javax.swing.*; public class EjemploDialogo extends JDialog { private final JPanel contentPanel = new JPanel(); //Atributos creados para pasar a la ventana principal private JTextField textField; private JTextField textField_1; private boolean pulsoOK; //Indicamos un frame como parámetro public EjemploDialogo(JFrame frame) { /* * Invocamos elconstructor padre, el booleano nos permite * crear un dialogo modal, es decir, que hasta que no * quitemos la ventana no podremos acceder a otra. */ super(frame, true); //Codigo que genero al crear el dialogo setBounds(100, 100, 450, 300); getContentPane().setLayout(new BorderLayout()); contentPanel.setLayout(null); getContentPane().add(contentPanel, BorderLayout.CENTER); JPanel buttonPane = new JPanel(); buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT)); getContentPane().add(buttonPane, BorderLayout.SOUTH); JButton okButton = new JButton("OK"); okButton.setActionCommand("OK"); buttonPane.add(okButton); getRootPane().setDefaultButton(okButton); JButton cancelButton = new JButton("Cancel"); cancelButton.setActionCommand("Cancel"); buttonPane.add(cancelButton); //Componentes creados JLabel lblEscribeElNombre = new JLabel("Escribe el nombre"); lblEscribeElNombre.setBounds(24, 28, 133, 14); contentPanel.add(lblEscribeElNombre); textField = new JTextField(); textField.setBounds(23, 56, 153, 20); contentPanel.add(textField); JLabel lblEscribeElApellido = new JLabel("Escribe el apellido"); lblEscribeElApellido.setBounds(24, 105, 152, 14); contentPanel.add(lblEscribeElApellido); textField_1 = new JTextField(); textField_1.setBounds(24, 146, 152, 20); contentPanel.add(textField_1); //Eventos cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { setVisible(false); } }); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { //Indicara que hemos introducido correctamentelos datos pulsoOK=true; setVisible(false); } }); //Creamos un listener que es igual para dos componentes KeyListener kl=new KeyListener(){ public void keyTyped(KeyEvent e){ if(Character.isDigit(e.getKeyChar())){ e.consume(); } } public void keyPressed (KeyEvent e){ } public void keyReleased(KeyEvent e){ } }; //Añadimos el listener textField.addKeyListener(kl); textField_1.addKeyListener(kl); } //Modificamos los metodos get, para que devuelva un String directamente public String getNombre() { return textField.getText(); } public String getApellido() { return textField_1.getText(); } //Usaremos este metodo en la ventana principal public boolean isPulsoOK() { return pulsoOK; } }
–Ventana principal
import java.awt.*; import java.awt.event.*; import javax.swing.*; public class EjemploDialogoVentanaPrincipal extends JFrame { private JPanel contentPane; private JTextField textField; private EjemploDialogoVentanaPrincipal frame; //Atributo con el mismo tipo que la clase /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { EjemploDialogoVentanaPrincipal frame = new EjemploDialogoVentanaPrincipal(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public EjemploDialogoVentanaPrincipal() { //Tirulo de la ventana setTitle("Ejemplo"); //Operacion por defecto al cerrar la ventana setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Colocamos la ventana setBounds(100, 100, 450, 300); //Creamos el panel contentPane = new JPanel(); //Indicamos el diseño usado contentPane.setLayout(null); //Añadimos el panel al frame setContentPane(contentPane); //Componentes textField = new JTextField(); textField.setBounds(48, 110, 159, 20); textField.setEditable(false); contentPane.add(textField); textField.setColumns(10); JLabel lblNombreYApellido = new JLabel("Nombre y apellido fusionado"); lblNombreYApellido.setBounds(48, 71, 159, 14); contentPane.add(lblNombreYApellido); JButton btnAbrirDilogo = new JButton("Abrir di\u00E1logo"); btnAbrirDilogo.setBounds(251, 109, 141, 23); contentPane.add(btnAbrirDilogo); btnAbrirDilogo.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ //Creamos un objeto dialogo, le pasamos el atributo frame EjemploDialogo dialogo=new EjemploDialogo(frame); //Hacemos visible la ventana de dialogo dialogo.setVisible(true); //Cuando pulsemos OK, en el dialogo realizara esta accion. if(dialogo.isPulsoOK()){ String nombre=dialogo.getNombre(); String apellido=dialogo.getApellido(); textField.setText(nombre+" "+apellido); } } }); } }
En netbeans, se crea siguiendo la misma mecanica, tenemos que agregar un JDialog a nuestro proyecto y ya lo tendremos operativo, aunque debemos conectarlo con el JFrame principal de la misma manera vista antes.
Espero que os sea de ayuda. Si tenéis dudas, preguntad. Estamos para ayudarte.
Hola
Ante todo, gracias por todo el esfuerzo. Personalmente me ayuda mucho.
Una duda, anulando el eventqueue y quedándome solo con
EjemploDialogoVentanaPrincipal frame = new EjemploDialogoVentanaPrincipal();
frame.setVisible(true);
… me funciona igual. Se nota que estoy empezando preguntándolo, pero ¿Qué hace exactamente eventqueue? ¿Tiene que ver con multiples threads?
Gracias por todo el material que compartes. Un saludo