Tabla de Contenidos
Anexo: IntelliJ IDEA
En este apartado se explican diferentes cuestiones y formas de trabajo con el IDE IntelliJ:
Versión del JDK
- File → Project Structure → Project
En IntelliJ, como en cualquier otro IDE, podemos indicar qué JDK vamos a utilizar para desarrollar nuestra aplicación. Para ello debo añadir la ruta del directorio del JDK instalado en mi sistema.
Además IntelliJ me permite indicar la versión en la que quiero compilar el código de mi aplicación. Por ejemplo, si tengo el JDK 17 y quiero que mi aplicación sea compatible con Java8, debo reducir en valor de “Language Level” a Java 8. Siempre deberé indicar una versión igual o inferior al JDK que esté utilizando.
Diseñador de GUIs: UI Designer
Es la herramienta para diseñar interfaces gráficas de usuario (GUI's). Utiliza las librerías gráficas de Swing, que son unas librerías nativas existentes en la API de Java.
Vista del diseñador Swing UI Designer de IntelliJ
Crear GUI Form
Para crear utilizar el Diseñador de IntelliJ para crear una interfaz gráfica:
- Click derecho sobre el package donde quiera crear la GUI
- Selecciono New → Swing UI Designer → GUI Form
- Dar nombre a la clase y seleccionar un Layout
Se crean dos elementos, un archivo form que contiene el aspecto de la ventana y una clase de java, que contiene los atributos de la clase.
UI Designer nos permite diseñar el contenido de un elemento JPanel
principal. Para poder visualizarlo en una ventana necesito añadirlo a un objeto JFrame
. El primer requisito es asegurarme que el elemento JPanel
principal de mi GUI es un atributo de la clase. Basta con asegurarse de que el JPanel principal tiene nombre, como se ve en la siguiente imagen:
De este modo en la clase vinculada a ese form aparecerá el objeto JPanel como un atributo.
import javax.swing.*; public class Vista { private JPanel panel1; //Atributo JPanel que he diseñado private JTextField txtTiempo; private JButton btnIniciar;
IntelliJ nos permite crear un método main para iniciar nuestra interfaz gráfica de forma sencilla. Basta con hacer:
- click derecho en la clase vinculada a mi form
- Generate → Form main()
IntelliJ nos genera un método main()
en el que se crea un JFrame que contiene al panel que hemos diseñado:
public class Vista { private JPanel panel1; private JTextField txtTiempo; private JButton btnIniciar; public static void main(String[] args) { JFrame frame = new JFrame("Vista"); frame.setContentPane(new Vista().panel1); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } }
Ahora puede ejecutar esta clase y nos desplegará la ventana.
Como consejo, siempre será más fácil crear un constructor para la clase que corresponde a la ventana. El código anterior quedaría así:
public class Vista { private JPanel panel1; private JTextField txtTiempo; private JButton btnIniciar; public Vista(){ JFrame frame = new JFrame("Vista"); //En la siguiente linea me aseguro de no llamar al constructor new Vista(). frame.setContentPane(panel1); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } public static void main(String[] args) { new Vista(); } }
Listeners
Para añadir manejadores de eventos a los componentes de mi interfaz gráfica:
- click derecho sobre el componente → Create Listener
- indico el tipo de listener que deseo crear (Action listener si es un botón)
- selecciono los métodos del listener y acepto
Y acto seguido se creará un clase anónima para implementar el listener:
. . . btnIniciar.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //Tareas a realizar } }); . . .
Separación de GUI y Listener
Es útil separar las clases que contienen componentes gráficos de las clases que gestionan los eventos sobre esos componentes. Cuando consigo que las clases tengan funcionalidades independientes, estoy desacoplando las clases de mi programa, basándome en el principio de responsabilidad única, el cual forma parte de los tan importantes principios SOLID para el diseño de programas orientados a objetos.
Para ello, en lugar de crear los listeners en la clase vinculada al GUI Form, lo voy a hacer en una clase distinta.
1: En la clase Java vinculada a mi GUI, añado un constructor para crear la ventana. Puedo aprovechar el código generado por mi método main (Generate → Form main() ).
public class Vista { private JPanel panel1; JTextField txtTiempo; JButton btnIniciar; public Vista() { JFrame frame = new JFrame("Vista"); //Eliminar la llamada recursiva al contructor "new Vista().panel1" frame.setContentPane(panel1); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setVisible(true); } }
Debo recordar dos cosas importantes:
- Me facilita el acceso a los componentes de la GUI, eliminar el modificador de visibilidad
private
de los atributos con los que quiera interactuar cuando capture eventos. - En la linea frame.setContentPane(new Vista().panel1) generada por el Form main(), debo eliminar la llamada recursiva al constructor de la clase ( Vista() ).
2: Crear una clase que ejerza de listener. Una clase puede implementar todas las interfaces
que queramos por lo que una sola clase puede ser un listener de diferentes tipos. En el siguiente caso la clase es un listener de tipo ActionListener
:
public class Controlador implements ActionListener { private Vista vista; public Controlador(Vista vista){ this.vista = vista; /* Al crear un objeto de la clase Controlador, vincularé esta propia clase con los componentes de la GUI sobre los que quiero capturar eventos de este tipo */ vincularManejadoresAComponentes(this); } private void vincularManejadoresAComponentes(Controlador listener) { vista.btnIniciar.addActionListener(listener); } @Override public void actionPerformed(ActionEvent e) { // Tareas a realizar cuando se capture el evento . . . } }
Si en el método actionPerformed()
necesito capturar eventos originados en diferentes componentes (p.e. tengo varios botones) puedo usar los métodos e.getSource()
ó e.getActionCommand()
del objeto ActionEvent
que recibe el método como parámetro para saber dónde se produjeron.
Por último creo un método main()
en alguna clase para iniciar mi aplicación en una tercera clase:
public class Principal { public static void main(String[] args) { Vista vista = new Vista(); Controlador controlador = new Controlador(vista); } }
Archivos JAR
Los ficheros Jar (Java Archive) son archivos comprimidos en los que podemos empaquetar clases (.class) y otros recursos. En IntelliJ los JAR se denominan artifacts.
Utilizar librerías externas
Para utilizar librerías en formato JAR en mis proyectos de IntelliJ, es útil almacenarlas primero en un directorio dentro de mi proyecto. Para ello creo un directorio en la estructura de mi proyecto:
- Click derecho sobre el proyecto → new → directory
- Copiar y pegar los archivos JAR que necesite en el directorio creado
A continuación:
- File → Project Structure → Libraries → boton (+) → Java Library
- Busco en el explorador de archivos que se abre, la ruta del directorio que he creado en mi proyecto. Lo selecciono, y aceptar todo.
Ahora puedo utilizar las clases contenidas en esos paquetes JAR.
Crear libreria de clases
Desde la sección Project Structure
dentro del menu File
, nos situamos sobre Artifacts
.
Ahí pulsamos sobre el boton (+) para crear un nuevo artifact Jar vacio.
En el siguiente cuadro de dialogo, podemos indicar un nombre para el fichero , indicar si queremos que se cree cuando hagamos un Build del proyecto, y en la sección inferior, si queremos que nuestras librería de clases esté organizada en directorios (del mismo modo que los packages), podemos pulsar sobre el botón crear directorio:
y después pulsando sobre el símbolo (+) debemos seleccionar los archivos .class que queremos que incluya:
Ahí en el selector de ficheros, buscamos los archivo .class que queramos incluir en nuestro Jar. Una vez indicamos pulsamos sobre aceptar finalizando la creación del artifact.
Para generarlo el fichero Jar iremos al menú Build de IntelliJ, y pulsaremos sobre build project
en caso de que a la hora de configurar el artifact marcaramos el checkbox que indicamos en esta sección. En caso contrario, pulsamos sobre build artifacts
.
Crear JAR ejecutable
Una vez que tengo mi aplicación con GUI diseñada, puedo exportarla en un fichero ejecutable, que se podrá arrancar en cualquier equipo que tenga la versión de Java con la que se diseño, o una posterior.
Para exportar mi aplicación como JAR ejecutable haré lo siguiente:
- Menú File → Project Structure
- Artifacts → Add Jar → From modules with dependencies
- Seleccionar la clase que contiene el método
main()
y aceptar - En la última ventana se indica donde se creará el JAR. Aceptar
Una vez que tengo la configuración de JAR Artifact, tan solo me queda crearlo:
- Menú Build → Build Artifacts…
GUI Dinámica
Se conoce como GUI dinámica a una interfaz gráfica que permite crear o eliminar componentes gráficos en una misma ventana en tiempo de ejecución, en lugar de tenerlos en la ventana desde el inicio.
La idea es diferente a construir nuevas ventanas (JFrame o JDialog) en tiempo de ejecución. Se busca añadir o eliminar componentes a una misma ventana. Podemos añadir componentes existentes en la API de Swing, pero en ciertas ocasiones puede que nos interese diseñar componentes personalizados que cumplan una finalidad concreta.
Crear componentes
Para crear componentes personalizados que podamos añadir a otras ventanas, podemos hacerlos de dos formas:
- Diseñando el componente directamente mediante código Java
- Diseñando el componente con el UI Designer de IntelliJ
Para diseñarlo con el UI Designer, debemos tener en cuenta que la clase que vinculada al GUI Form que crea IntellJ, no es un componentes gráfico de Java en sí, es decir, no es una clase que extienda de JComponent, u otro componente gráfico.
Pero como hemos visto, el diseñador basa el diseño de las GUI en un objeto JPanel
principal al que sí puedo acceder, y sí es un componente gráfico de Java. Si quiero utilizar mi clase para añadirla a algún otro panel de otra ventana, puedo crear un método getter()
que me permita acceder al JPanel
que he diseñado:
public class Vista { private JPanel panel1; private JTextField txtTiempo; private JButton btnIniciar; public void JPanel getPanel1(){ return panel1; } . . . }
Añadir componentes de forma dinámica
Crear contenedor
Para emplazar de forma dinámica estos nuevos componentes debo tener otro GUI Form que contenga un panel donde desee añadir dinámicamente, los nuevos componentes diseñados anteriormente.
Para ello el JPanel
que escoja para alojar dinámicamente otros “paneles” debe tener un Layout que me permita que se ordenen correctamente al añadirlos (p.e. verticalmente). BoxLayout
y WrapLayout son layouts que se adaptan a este propósito.
IntelliJ me permite personalizar la creación de los objetos de mi GUI. Para ello tan solo debo marcar el checkbox que dice “Custom Create” en las propiedades de los componentes que aparece a la izquierda en el UI Designer. Al pulsar sobre ese checkbox me aparece un método en la clase vinculada, donde indicaré el código de creación de los objetos:
private void createUIComponents() { // TODO: place custom component creation code here panelDinamico = new JPanel(); BoxLayout layout = new BoxLayout(panel, BoxLayout.Y_AXIS) panelDinamico.setLayout(layout); }
Añadir y eliminar componentes
Una vez que tengo el panel contenedor, ahora tan solo debo crear componentes y añadirlos, por ejemplo al pulsar un botón.
. . . @Override public void actionPerformed(ActionEvent e) { JPanel panelComponente = new MiClase().getPanel1() panelDinamico.add(panelComponente); panelDinamico.revalidate(); //Y para eliminarlo panelDinamico.remove(panelComponente); panelDinamico.repaint(); panelDinamico.revalidate(); } . . .
Creación de GUI dinámica
GUI dinámica: Manejar componentes
© 2024 Fernando Valdeón