Ejemplo sencillo con JFrame

De ChuWiki


Veamos en este ejemplo los pasos para crear la ventana principal de nuestra aplicación en Java y todos los trucos para esta ventana. Puedes ver el ejemplo completo en github

Crear y visualizar un JFrame[editar]

La ventana principal de la aplicación debe ser JFrame por una serie de motivos que iremos explicando. El código mínimo para crear y visualizar esta ventana es el siguiente

package com.chuidiang.examples;

import javax.swing.*;

/**
 * JFrame example
 * @author Chuidiang
 */
public class JFrameExample 
{
    public static void main( String[] args )
    {
        JFrame frame = new JFrame("Main Window");
        frame.setVisible(true);
    }
}

Esto crea un JFrame y lo visualiza. El título de la ventana será "Main Window", que es el String que hemos pasado en el constructor. ¿Pega de esto? Varias de momento.

  • La ventana sale en pequeñito, en el lado superior izquierdo de nuestra pantalla. El título no se ve porque la ventana es pequeña.
  • Si cerramos la ventana con la "x", la ventana se cierra, pero la aplicación no termina.

Vamos a ir añadiendo código para ir solucionando problemas.

Terminar la aplicación al cerrar el JFrame[editar]

Podemos llamar al método setDefaultCloseOperation de JFrame para indicar cual queremos que sea el comportamiento de la ventana cuando se cierre. Hay varias opciones que están definidas como constantes en JFrame: EXIT_ON_CLOSE, DISPOSE_ON_CLOSE, DO_NOTHING_ON_CLOSE, HIDE_ON_CLOSE. Por orden:

  • Exit on close hace que nuestra aplicación termine del todo. Es lo que vamos a poner en el código
  • Dispose on close oculta la ventana y libera toda la memoria que ocupa, pero la aplicación sigue arrancada.
  • Do nothing on close hace que se ignore totalmente la pulsación de la "x" en la ventana.
  • Hide on close oculta la ventana sin liberar la memoria, haciendo que podamos volver a visualizarla más adelante. La aplicación sigue corriendo.
        JFrame frame = new JFrame("Main Window");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

Centrar el JFrame en pantalla[editar]

Si queremos que la ventana aparezca en otra posición, tenemos los métodos setLocation() y setLocationRelativeTo para dar posición a la ventana. El primero nos permite colocarla en cualquier posición de la pantalla sin más que dar las coordenadas en pixels. El origen (0,0) es la esquina superior izquierda de la pantalla y las y positivas son hacia abajo.

Más útil suele ser setLocationRelativeTo(). Este método hace que la ventana aparezca centrada sobre otro componente java (un botón, otra ventana, un panel, etc). Si pasamos null como parámetro, centra la ventana en la pantalla. Esto es lo que vamos a usar.

        JFrame frame = new JFrame("Main Window");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

Si ejecutamos ahora, la ventana seguirá siendo chiquita, pero aparecerá centrada en la pantalla.

Dar tamaño al JFrame[editar]

Podemos dar tamaño a la ventana con el método setSize de JFrame, pasando las dimensiones en pixels. Pero salvo casos muy especiales no suele ser buena idea dar tamaños fijos a las ventanas. Lo ideal es que las ventanas sean capaces de coger automáticamente el tamaño adecuado a su contenido. Para ello está el método pack(). Nuestra ventana no tiene contenido, no le hemos metido nada. Vamos a meterle un botón JButton para que tenga algo, grandecito para que se note que la ventana se redimensiona.

    public static void main( String[] args )
    {
        JFrame frame = new JFrame("Main Window");

        // Boton con margenes grandes para que tenga un tamaño importante y 
        // lo metemos en la ventana principal.
        JButton button = new JButton("Click me!");
        button.setMargin(new Insets(20,200,20,200));
        frame.getContentPane().add(button);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.pack();

        frame.setVisible(true);
    }

Si ejecutas ahora, verás que ventana sale en el centro y que tiene el tamaño justo para que el botón se vea completo.

Cambiar icono al JFrame[editar]

Si te fijas, tanto el icono de la ventana cuando la arrancas como el icono que sale para la aplicación en la barra de tareas de windows es un icono de java por defecto. Para nuestras aplicaciones puede ser interesante cambiar dicho icono por algo más nuestro que represente nuestra aplicación. Para ello, llamamos al método setIconImage() pasándole una Image. La forma más fácil de obtenerla, a partir de un fichero de imagen, es el código que se muestra abajo.

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setIconImage(new ImageIcon("C:/Users/fjabe/Pictures/ing.png").getImage());
        frame.pack();

NOTA: Es windows, pero java es listo e interpreta las / de directorio correctamente, aunque no sean las de windows \

Este es el motivo por el que nuestra ventana principal debe ser un JFrame. La otra posible ventana de java, JDialog no tiene este método para cambiar el icono ni dicha ventana sale en la barra de tareas de windows. JDialog hereda el icono de su ventana padre, que suele ser el JFrame u otro JDialog

Un detalle importante[editar]

Aunque aquí lo hemos hecho de forma correcta, no está de más resaltar algunos puntos que al no mencionar explícitamente igual se pasan por alto

  1. Hay que añadir todos los componentes que queramos a la ventana antes de llamar al método pack(). Si no lo hacemos así, la ventana cogerá el tamaño de los componentes que hayamos añadido hasta ese momento, pero no se redimensionará automáticamente si añadimos componentes después.
  2. Conviene hacer todo antes de mostrar la ventana, es decir, setVisible(true) debería ser la última llamada, cuando todo esté ya preparado, por dos motivos
    1. Evitar efectos feos si hacemos la ventana visible al principio y luego le vamos haciendo cosas
    2. Hay cosas que no se reflejan si la ventana es visible, por ejemplo, añadir más componentes. Si se hace, hay que forzar "refrescos" duros, como llamar al método SwingUtilities.updateComponentTreeUI() o updateUI si está accesible.