Saltar al contenido

Ventanas en java. Uso de JFrame y JPanel.

Las ventanas en java o JFrame, forman la parte principal de las interfaces de usuario en java y son muy utilizadas para realizar diferentes aplicaciones. Además, estos JFrame suelen contener laminas o JPanel.

En este artículo, aprenderás a crear interfaces gráficas con ventanas en java y a utilizar estos dos controles utilizando el patrón modelo – vista – controlador o MVC. Este patrón de diseño de interfaces, es muy utilizado cuando se crean aplicaciones empresariales.

Índice de contenidos

    Como crear ventanas en java a través del modelo vista controlador.

    Para crear las interfaces gráficas en java a través patrón, se deben crear cuatro paquetes:

    • Modelo. En este paquete se crearán los objetos de datos si los hubiere.
    • Vista. En este paquete, crearemos las vistas de la aplicacion, es decir los JFrame y jPanel.
    • Controlador. Lo utilizaremos para conectar el paquete modelo y el paquete vista.
    • Arranque. Aquí implementaremos el método main para poder arrancar el programa.

    Ten en cuenta, que en este post te vamos a ayudar a crear aplicaciones gráficas sencillas con dos ejemplos básicos en las que aprenderás lo siguiente:

    • Crear ventanas en java (JFrame). Esto equivale a los típicos formularios como si fuese una aplicación de Windows.
    • Agregar láminas o layouts (JPanel). Estas láminas se insertarán dentro del JFrame. Aunque los JPanel no son obligatorios, a veces suelen agregarse depende del diseño de nuestras ventanas de java.
    • Agregar controles. Estos controles se agregarán dentro la lámina. Esto nos van a permitir distribuir los controles dentro de las ventanas de java de una manera concreta.

    Debido a estas tres razones y ya que no vamos a trabajar con bases de datos, no vamos a crear el paquete referente al modelo.

    Teniendo en cuenta esto, vamos a crear dos ejemplos:

    • Ejemplo 1: Crearemos una interfaz que pintará un formulario en tres colores: Azul, en rojo o verde, dependiendo de la opción que el usuario seleccione.
    • Ejemplo 2: Crearemos una ventana con 9 botones colocados en forma de rejilla. Cada botón se desactivará cuando el usuario haga clic en un botón.

    Dentro de nuestro proyecto, crearemos tres paquetes: vista, controlador y arranque. Una vez hecho esto, comenzaremos a trabajar con el paquete vista y a ver el código necesario para cada uno de los ejemplos.

    Como implementar el paquete vista para crear ventanas en java.

    Dentro del paquete vista, vamos a ver el código necesario para implementar la interfaz para cada uno de los ejemplos.

    Componentes de la interfaz gráfica para pintar las ventanas de java.

    Para este ejemplo agregaremos lo siguiente:

    • Un JFrame. Lo que es la ventana en java propiamente dicha.
    • Un JPanel. Una lámina que será la que se pinte de un color dependiendo de lo que el usuario seleccione.
    • Tres RadioButton. Al pulsar en cada uno, la lámina o JPanel se pintará de un color concreto.

    Ejemplo de código en java para el ejemplo de como pintar ventanas en java.

    package vista;
     
    // Importamos el paquete swing para trabajar con interfaces gráficas
    import javax.swing.*;
     
    /**
     * ESTA CLASE DEBE HEREDAR DE JFRAME PARA PODER
     * CREAR LA VENTANA DE NUESTRA INTERFAZ
     */
    public class PintarVentana extends JFrame{
         
        /* Esta variable no es necesaria, pero si
         * muy recomendable, ya que nos evitará problemas
         * si hay futuras actualizaciones de la aplicacion*/
        private static final long serialVersionUID = 1L;
        
        // Creamos una lámina para colocar encima del JFrame
        private JPanel lamina = new JPanel(); 
         
        // Creamos los controles que tendrá nuestra lámina
        public JRadioButton rdbAzul = new JRadioButton("Azul");
        public JRadioButton rdbRojo = new JRadioButton("Rojo");
        public JRadioButton rdbVerde = new JRadioButton("Verde");
        public JTextField txtColor = new JTextField(10);
        private ButtonGroup grupoBotones = new ButtonGroup();
         
        /**
         * EL CONSTRUCTOR CREA LA VENTANA, LE DA UNAS PROPIEDADES
         * Y ADEMÁS EN EL, SE INDICA QUE SE LE AGREGUE UN JPANEL
         * O LO QUE ES LO MISMO, UNA LAMINA PARA PODER AGREGAR
         * LOS CONTROLES NECESARIOS
         */
        public PintarVentana() {
              
            // Le damos un tamaño a la ventana
            this.setSize(450, 300);
             
            // Agregamos un tículo
            this.setTitle("Colorear ventanas");
              
            // Lo centramos en pantalla
            this.setLocationRelativeTo(null);
              
            /* Le decimos que no se puede redimensionar*/
            this.setResizable(false);
              
            // Le decimos que al cerrar la ventana, acabe el programa
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              
            // Agregamos una lámina a la ventana
            this.getContentPane().add(lamina);
             
            // llamamos al método que configura la lamina y agrega los controles
            configurarLaminaYagregarControles();
        }
         
        /**
         * ESTE MÉTODO CONFIGURA NUESTRA LÁMINA (JPANEL) Y AGREGA LOS CONTROLES
         * AL JPANEL DE NUESTRA VENTANA
         */
        private void configurarLaminaYagregarControles() {
             
            // Lo primero que debemos hacer, es darle una
            // distribución (un layout) a nuestra lámina.
            // En este caso, no utilizaremos ningún tipo de distribución
            // por lo que estableceremos el layout de la lamina (Jpanel) en null
            lamina.setLayout(null);
             
            // Agregamos cada RadioButton al ButtonGroup. Esto nos permite
            // que cuando seleccionemos una opción, se desactive la que
            // este seleccionada
            grupoBotones.add(rdbAzul);
            grupoBotones.add(rdbRojo);
            grupoBotones.add(rdbVerde);
             
            /* Damos una posicion y un tamaño (x,y, ancho, alto)
             * a cada uno de los RadioButton y al cuadro de texto*/
            rdbAzul.setBounds(10, 10, 60, 30);
            rdbRojo.setBounds(10, 40, 60, 30);
            rdbVerde.setBounds(10,70, 60, 30);
            txtColor.setBounds(10, 100, 60, 20);
             
            /* Desactivamos el txtColor para que no se pueda escribir*/
            txtColor.setEnabled(false);
              
            /* Añadimos los controles a la lamina*/
            lamina.add(rdbAzul);
            lamina.add(rdbRojo);
            lamina.add(rdbVerde);
            lamina.add(txtColor);
        }
    }
    

    Componentes del ejemplo de la interfaz en la que se desactivan los botones.

    En este segundo ejemplo, los componentes que vamos a utilizar son los siguientes:

    • Una lámina o JPanel llamada laminaFondo. Este JPanel, tendrá una distribución de tipo BorderLayout. Dentro de esta lamina tendremos los siguientes controles:
      • Un JLabel a modo de título en la parte superior (parte NORTH).
      • Otro JLabel en la parte de abajo que indicará el número del botón que se ha pulsado.
      • En la parte central, se colocará otra lámina o JPanel con una distribución tipo GridLayout (distribución tipo rejilla), que contendrá los botones del 1 al 9.
    package vista;
     
    import java.awt.BorderLayout;
    import java.awt.GridLayout;
     
    // Importamos el paquete swing para trabajar con interfaces gráficas
    import javax.swing.*;
     
    /**
     * ESTA CLASE DEBE HEREDAR DE JFRAME PARA PODER
     * CREAR LA VENTANA DE NUESTRA INTERFAZ
     */
    public class VentanaDesactivarBotones extends JFrame{
         
        /* Esta variable no es necesaria, pero si
         * muy recomendable, ya que nos evitará problemas
         * si hay futuras actualizaciones de la aplicacion*/
        private static final long serialVersionUID = 1L;
        
        // Creamos una lámina para colocar encima del JFrame
        public JPanel laminaFondo = new JPanel(); 
        public JPanel laminaBotones = new JPanel();
         
        // Creamos los controles que tendrá nuestra lámina
         private JLabel lblTitulo = new JLabel();
         public JLabel lblNumero = new JLabel(); 
         public JButton [] botones =new JButton[9];
         
        /**
         * EL CONSTRUCTOR CREA LA VENTANA, LE DA UNAS PROPIEDADES
         * Y ADEMÁS EN EL, SE INDICA QUE SE LE AGREGUE UN JPANEL
         * O LO QUE ES LO MISMO, UNA LAMINA PARA PODER AGREGAR
         * LOS CONTROLES NECESARIOS
         */
        public VentanaDesactivarBotones() {
              
            // Le damos un tamaño a la ventana
            this.setSize(640, 480);
             
            // Agregamos un tículo
            this.setTitle("Desactivar botones");
              
            // Lo centramos en pantalla
            this.setLocationRelativeTo(null);
              
            /* Le decimos que no se puede redimensionar*/
            this.setResizable(false);
              
            // Le decimos que al cerrar la ventana, acabe el programa
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              
            // Agregamos una lámina a la ventana
            this.getContentPane().add(laminaFondo);
             
            // llamamos al método que configura la lamina fondo
            // y la lamina de los botones
            configurarLaminaFondo();
            configurarLaminaBotones();   
        }
         
        /**
         * ESTE MÉTODO CONFIGURA NUESTRA LÁMINA (JPANEL) Y AGREGA LOS CONTROLES
         * AL JPANEL DE NUESTRA VENTANA
         */
        private void configurarLaminaFondo() {
             
            // Le damos a la lamina una distribución de tipo BorderLayout.
            laminaFondo.setLayout(new BorderLayout());
             
            // Colocamos un texto a las etiquetas
            lblTitulo.setText("Pulsa cada botón para desactivarlo");
            lblNumero.setText("Número");
             
            // Agregamos las etiquetas al norte y al sur de la lamina
            laminaFondo.add(lblNumero,BorderLayout.SOUTH);
            laminaFondo.add(lblTitulo,BorderLayout.NORTH);
             
            // Alineamos el texto de las etiquetas
            lblNumero.setHorizontalAlignment(SwingConstants.CENTER);
            lblTitulo.setHorizontalAlignment(SwingConstants.CENTER);
               
        }
         
        private void configurarLaminaBotones() {
             
            // Le damos a la lamina botones una distribucion del tipo GridLayout
            laminaBotones.setLayout(new GridLayout(3,3));
             
            /* Con un bucle, agrego los botones del 1 al 9
             * al panel en forma de rejilla*/
            for(int x=0;x<botones.length;x++) {
                          
                botones[x]=new JButton("Botón " + (x+1));
                laminaBotones.add(botones[x]);
            }     
          
            // Agregamos la laminaBotones en el
            // centro de la laminaFondo
            laminaFondo.add(laminaBotones,BorderLayout.CENTER);
        }
    }
    

    Implementar la capa controlador.

    Una vez configurada la capa vista, en los dos ejemplos, crearemos la interacción del usuario con los formularios en el paquete controlador. Para esto dentro de este paquete, crearemos una clase llamada ControlClics. e importaremos el paquete vista, ya que necesitaremos acceder tanto al formulario como a los diferentes controles.

    Interacción del usuario en la aplicación que pinta ventanas en java.

    El código que programaremos para este primer ejemplo será el siguiente.

    package controlador;
    
    import java.awt.Color;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import vista.*;
    
    /**
     * ESTA CLASE DEBE IMPLEMENTAR LA INTERFAZ DE JAVA ACTIONLISTENER
     * Y DEBE SOBREESCRIBIR TODOS LOS MÉTODOS QUE CONTENGA ESTA INTERFAZ
     */
    
    public class ControlClics implements ActionListener {
    
    	// Creamos una variable de tipo PintarVentana
    	PintarVentana vistaPintarVentana;
    	
    	/**
    	 * EL MÉTODO CONSTRUCTOR RECIBIRÁ POR PARÁMETRO UN
    	 * OBJETO DE TIPO PINTAR VENTANA Y A ESTE OBJETO
    	 */
    	
    	public ControlClics(PintarVentana vPintar) {
    		// A La variable vistaPintarVentana se le asignara
    		// un objeto de la clase PintarVentana llamado vPintar
    		// y el cual se le esta pasando por parámetro
    		// en el constructor de esta clase
    		vistaPintarVentana=vPintar;
    	}
    	
    	/**
    	 * ESTE MÉTODO PONE A LA ESCUCHA DE LOS EVENTOS
    	 * DE CLIC DE RATON A CADA UNO DE LOS RADIOBUTTON
    	 * DE LA VENTANA CREADA EN EL PAQUETE VISTA
    	 */
    	public void escucharEventos() {
    		vistaPintarVentana.rdbAzul.addActionListener(this);
    		vistaPintarVentana.rdbRojo.addActionListener(this);
    		vistaPintarVentana.rdbVerde.addActionListener(this);
    	}
    	
    	/**
    	 * ESTE MÉTODO SE ENCARGA DE EJECUTAR LAS ACCIONES
    	 * 
    	 */
    	@Override
    	public void actionPerformed(ActionEvent e) {
    		
    		// Si el RadioButton azul está seleccionado
    		if(vistaPintarVentana.rdbAzul.isSelected()) {
    			
    			// Pintamos de azul la ventana
    			vistaPintarVentana.lamina.setBackground(Color.BLUE);
    			
    			// Colocamos en el cuadro de texto "Azul"
    			vistaPintarVentana.txtColor.setText("Azul");
    			
    		}
    		
    		// Sino, si el RadioButton rojo está seleccionado
    		else if(vistaPintarVentana.rdbRojo.isSelected()) {
    			
    			// Pintamos de rojo la ventana
    			vistaPintarVentana.lamina.setBackground(Color.RED);
    			
    			// Colocamos en el cuadro de texto "Rojo"
    			vistaPintarVentana.txtColor.setText("Rojo");
    		}
    		
    		// Sino, si el RadioButton verde esta seleccionado...
    		else if(vistaPintarVentana.rdbVerde.isSelected()) {
    			
    			// Pintamos de rojo la ventana
    			vistaPintarVentana.lamina.setBackground(Color.GREEN);
    			
    			// Colocamos en el cuadro de texto "Verde"
    			vistaPintarVentana.txtColor.setText("Verde");
    		}
    	}
    }
    

    Interacción de la aplicación de desactivar ventanas en java.

    Para esta aplicación de nuestro segundo ejemplo, la clase que crearemos en la capa controlador, tendrá el siguiente código.

    package controlador;
     
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
     
    import vista.*;
     
    /**
     * ESTA CLASE DEBE IMPLEMENTAR LA INTERFAZ DE JAVA ACTIONLISTENER
     * Y DEBE SOBREESCRIBIR TODOS LOS MÉTODOS QUE CONTENGA ESTA INTERFAZ
     */
     
    public class ControlClics implements ActionListener {
     
        // Creamos una variable de tipo PintarVentana
        VentanaDesactivarBotones vistaDesactivarVentana;
         
        /**
         * EL MÉTODO CONSTRUCTOR RECIBIRÁ POR PARÁMETRO UN
         * OBJETO DE TIPO PINTAR VENTANA Y A ESTE OBJETO
         */
         
        public ControlClics(VentanaDesactivarBotones vDesactivar) {
            // A La variable vistaDesactivarBotones se le asignara
            // un objeto de la clase DesactivarBotones llamado vDesactivar
            // y el cual se le esta pasando por parámetro
            // en el constructor de esta clase
            this.vistaDesactivarVentana=vDesactivar;
        }
         
        /**
         * ESTE MÉTODO PONE A LA ESCUCHA DE LOS EVENTOS
         * DE CLIC DE RATON A CADA UNO DE LOS BOTONES
         * DE LA VENTANA CREADA EN EL PAQUETE VISTA
         */
        public void escucharEventos() {
             
            for(int x=0;x<vistaDesactivarVentana.botones.length;x++) {
                vistaDesactivarVentana.botones[x].addActionListener(this);
            }
        }
         
        /**
         * ESTE MÉTODO SE ENCARGA DE EJECUTAR LAS ACCIONES
         * 
         */
        @Override
        public void actionPerformed(ActionEvent e) {
             
              
            if(e.getSource().equals(vistaDesactivarVentana.botones[0])) {
                vistaDesactivarVentana.botones[0].setEnabled(false);
                vistaDesactivarVentana.lblNumero.setText("Botón 1 desactivado");
            }
              
            else if(e.getSource().equals(vistaDesactivarVentana.botones[1])) {
                vistaDesactivarVentana.botones[1].setEnabled(false);
                vistaDesactivarVentana.lblNumero.setText("Botón 2 desactivado");
            }
              
            else if(e.getSource().equals(vistaDesactivarVentana.botones[2])) {
                vistaDesactivarVentana.botones[2].setEnabled(false);
                vistaDesactivarVentana.lblNumero.setText("Botón 3 desactivado");
            }
            else if(e.getSource().equals(vistaDesactivarVentana.botones[3])) {
                vistaDesactivarVentana.botones[3].setEnabled(false);
                vistaDesactivarVentana.lblNumero.setText("Botón 4 desactivado");
            }
              
            else if(e.getSource().equals(vistaDesactivarVentana.botones[4])) {
                vistaDesactivarVentana.botones[4].setEnabled(false);
                vistaDesactivarVentana.lblNumero.setText("Botón 5 desactivado");
            }
              
            else if(e.getSource().equals(vistaDesactivarVentana.botones[5])) {
                vistaDesactivarVentana.botones[5].setEnabled(false);
                vistaDesactivarVentana.lblNumero.setText("Botón 6 desactivado");
            }
             
            else if(e.getSource().equals(vistaDesactivarVentana.botones[6])) {
                vistaDesactivarVentana.botones[6].setEnabled(false);
                vistaDesactivarVentana.lblNumero.setText("Botón 7 desactivado");
            }
             
            else if(e.getSource().equals(vistaDesactivarVentana.botones[7])) {
                vistaDesactivarVentana.botones[7].setEnabled(false);
                vistaDesactivarVentana.lblNumero.setText("Botón 8 desactivado");
            }
            else if(e.getSource().equals(vistaDesactivarVentana.botones[8])) {
                vistaDesactivarVentana.botones[8].setEnabled(false);
                vistaDesactivarVentana.lblNumero.setText("Botón 9 desactivado");
            }
        }
    }
    

    Por el momento si ejecutásemos cualquiera de las dos aplicaciones, no hará absolutamente nada, bien es cierto que ya hemos programado nuestras interfaces gráficas y que también les dimos las instrucciones para que el usuario puede utilizarlas. Sin embargo, para que podamos utilizar la aplicación y que funcione, debemos conectar los paquetes vista y controlador. ¡Vamos a ver como conseguirlo!

    Conectando las capas vista y controlador para poder ejecutar las acciones.

    Para poder conectar ambas capas, debemos acceder a nuestro paquete vista y crear en ella una instancia de nuestro controlador. Para ello dentro de la clase donde se construyen nuestras ventanas en java, crearemos una instancia de la clase ControlClics y acto seguido, los métodos necesarios para cada ejemplo.

    Conectando la aplicación para pintar ventanas en java.

    package vista;
     
    // Importamos el paquete swing para trabajar con interfaces gráficas
    import javax.swing.*;
    
    // Importamos el paquete controlador
    import controlador.*;
    
    public class PintarVentana extends JFrame{
    
        // Declaramos una variable de tipo ControlClics
        private ControlClics ejecutarEventosClic;
    
    	/**
    	 * METODO QUE CONECTA EL CONTROLADOR CON LA INTERFAZ GRÁFICA
    	 */
    	
    	private void ejecutarAcciones() {
    		
    		// Creamos una instancia de la clase controladorClics
    		// Esta instancia recibe por parámetro un objeto de tipo
    		// PintarVentana. Ese objeto, será esta misma clase.
    		ejecutarEventosClic = new ControlClics(this);
    		
    		// Ahora la clase ControlClics, tiene un metodo que pone
    		// a la escucha a los diferentes controles, así que,
    		// llamaremos a ese método.
    		ejecutarEventosClic.escucharEventos();
    	}
    }
    

    El constructor de la clase para poder interactuar con la aplicación, quedaría de la siguiente manera:

    public PintarVentana() {
             
            // Le damos un tamaño a la ventana
            this.setSize(450, 300);
            
            // Agregamos un tículo
            this.setTitle("Colorear ventanas");
             
            // Lo centramos en pantalla
            this.setLocationRelativeTo(null);
             
            /* Le decimos que no se puede redimensionar*/
            this.setResizable(false);
             
            // Le decimos que al cerrar la ventana, acabe el programa
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             
            // Agregamos una lámina a la ventana
            this.getContentPane().add(lamina);
            
            // llamamos al método que configura la lamina y agrega los controles
            configurarLaminaYagregarControles();
            
            // Llamamos al mentodo que pone los controles a la escucha
            ejecutarAcciones();
        }
    

    Conectando la aplicación para desactivar los botones de las ventanas en java.

    package vista;
     
    // Importamos el paquete swing para trabajar con interfaces gráficas
    import javax.swing.*;
    
    // Importamos el paquete controlador
    import controlador.*;
    
    // Creamos una instancia de nuestra clase controlador
    private ControlClics ejecutarAcciones;
     
    /**
    * ESTE MÉTODO EJECUTA LAS ACCIONES DEL CONTROLADOR UNA VEZ
    * QUE ES LLAMADO DESDE EL CONSTRUCTOR DE ESTA CLASE
    */
    private void ejecutar() {
        ejecutarAcciones = new ControlClics(this);
        ejecutarAcciones.escucharEventos();
    }
     
    /**
    * EL CONSTRUCTOR QUEDARÍA DE LA SIGUIENTE MANERA:
    */
    public VentanaDesactivarBotones() {
              
            // Le damos un tamaño a la ventana
            this.setSize(640, 480);
             
            // Agregamos un tículo
            this.setTitle("Desactivar botones");
              
            // Lo centramos en pantalla
            this.setLocationRelativeTo(null);
              
            /* Le decimos que no se puede redimensionar*/
            this.setResizable(false);
              
            // Le decimos que al cerrar la ventana, acabe el programa
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              
            // Agregamos una lámina a la ventana
            this.getContentPane().add(laminaFondo);
             
            // llamamos al método que configura la lamina fondo
            // y la lamina de los botones
            configurarLaminaFondo();
            configurarLaminaBotones();
            ejecutar();
        }    
    

    Como lanzar nuestras ventanas en java. Ejecutar las aplicaciones.

    Para que nuestra aplicación se ejecute, solo debemos implementar el método main de la clase que hemos llamado Principal que se encuentra en el paquete llamado arranque de la siguiente manera:

    Para el ejemplo en el que se pintan las ventanas en java, el método sería el siguiete:

    package arranque;
    
    // Importamos el paquete vista
    import vista.*;
    
    public class Principal {
    
    	public static void main(String[] args) {
    		
    		// Creamos una instancia de la clase PintarVentana
    		PintarVentana ventanaPintada=new PintarVentana();
    		
    		// Hacemos visible la ventana
    		ventanaPintada.setVisible(true);
    	}
    }
    

    DESCARGAR PROYECTO PINTAR VENTANAS

    Si queremos utilizar la aplicación para desactivar botones usaremos el siguiente método.

    package arranque;
     
    // Importamos el paquete vista
    import vista.*;
     
    public class Principal {
     
        public static void main(String[] args) {
             
            // Creamos una instancia de la clase PintarVentana
            VentanaDesactivarBotones ventanaPintada=new VentanaDesactivarBotones();
             
            // Hacemos visible la ventana
            ventanaPintada.setVisible(true);
        }
    }
    

    DESCARGAR PROYECTO DESACTIVAR VENTANAS

    Configuración