jairogarcíarincón
03/12/2018
Contenidos
- Introducción a JavaFX y Prerrequisitos
- LibretaDirecciones: Creación del proyecto y configuración
- LibretaDirecciones: Modelo y Lista de personas
- LibretaDirecciones: Interacción con el usuario
- LibretaDirecciones: Hojas de estilo CSS
- LibretaDirecciones: Persistencia de datos con XML
- LibretaDirecciones: Gráficos e Informes
- LibretaDirecciones: Despliegue
- LibretaDirecciones: Persistencia con base de datos con MySQL (local)
- LibretaDirecciones: Persistencia con base de datos con MySQL (remota)
Crea un nuevo proyecto de tipo JavaFX Application llamado LibretaDirecciones. Desmarca la casilla que indica que se cree una clase principal, ya que la crearemos más adelante mediante otra estructura.
Para este proyecto y posteriores, nos acostumbraremos a utilizar una arquitectura de tipo Modelo-Vista-Controlador (MVC), de modo que separaremos el código de nuestra aplicación en 3 partes diferenciadas:
Fuente: Wikipedia
- Modelo: Es la representación de la información con la cual el sistema opera, por lo tanto gestiona todos los accesos a dicha información, tanto consultas como actualizaciones, implementando también los privilegios de acceso que se hayan descrito en las especificaciones de la aplicación (lógica de negocio).
- Controlador: Responde a eventos (usualmente acciones del usuario) e invoca peticiones al 'modelo' cuando se hace alguna solicitud sobre la información (por ejemplo, editar un documento o un registro en una base de datos). También puede enviar comandos a su 'vista' asociada si se solicita un cambio en la forma en que se presenta el 'modelo' (por ejemplo, desplazamiento o scroll por un documento o por los diferentes registros de una base de datos), por tanto se podría decir que el 'controlador' hace de intermediario entre la 'vista' y el 'modelo'.
- Vista: Presenta el 'modelo' (información y lógica de negocio) en un formato adecuado para interactuar (usualmente la interfaz de usuario), por tanto requiere de dicho 'modelo' la información que debe representar como salida.
De este modo, en nuestro proyecto crearemos tres nuevos paquetes o packages: controller, model y view. Esto hará que se borre automáticamente el default package.
Hay dos formas de crear una interfaz de usuario JavaFX: mediante código Java o mediante XML. En este caso, la realizaremos en XML (con un archivo de extensión .fxml) y utilizando para el diseño la herramienta de edición Scene Builder instalada anteriormente:
Haz clic derecho en el paquete view y crea un Empty FXML (dentro de la categoría JavaFX) llamado VistaPersona .
Haz clic derecho sobre el archivo VistaPersona.fxml y pincha en Open para abrirlo con Scene Builder.
Una vez abierto Scene Builder, seleccionando el AnchorPane en la jerarquía de la izquierda, ajusta el tamaño en el apartado layout (a la derecha).
Añade un SplitPane (horizontal) arrastrándolo desde la librería (Library) al área principal de edición. Haz clic en el Split Pane y, desde el menú Modify, haz clic en Fit to Parent, para ajustarlo a la ventana (o pulsa Ctrl + K).
Añade una TableView (en Controls) y arrástralo al lado izquierdo del SplitPane. En el lado derecho, ajusta los cuatro AnchorPane Constraints de la TableView a 0 para que la TableView esté anclada a los bordes y "siga" el posible redimensionamiento de la ventana padre (Puedes hacer clic en el menú Preview -> Show Preview in window o pulsar Ctrl + P para comprobarlo).
Haciendo clic en cada TableColumn de la TableView, cambia los títulos C1 y C2 por Nombre y Apellidos, respectivamente.
Selecciona la TableView y en Properties (lado derecho) selecciona Column Resize Policy: constrained-resize para que las columnas utilicen todo el espacio derecho disponible. El resultado debería ser similar al siguiente:
Crea ahora un Label (Controls) en el lado derecho del SplitPane con el texto "Detalles". Ajusta sus Properties a tu gusto.
Añade un GridPane (Containers) debajo del Label y ajusta su apariencia usando anclajes (similares a los que usamos en la TableView, aunque en este caso con valores arriba, derecha, abajo, izquierda: 30, 10, 60, 10).
Modifica el GridPane para que tenga 6 filas (haciendo clic derecho en un número de fila se pueden añadir nuevas con Add Row Above o Add Row Before) con las etiquetas Nombre, Apellidos, Dirección, Ciudad, Código Postal, Fecha de nacimiento. El resultado debe ser similar al siguiente:
Añade 3 Button (Controls) en la parte inferior derecha con los textos "Nuevo", "Editar" y "Borrar". Para ajustarlos más cómodamente de forma global, selecciona los 3 y con el botón derecho haz clic en Wrap in -> HBox. Ahora puedes ajustar el Layout del HBox para que el Spacing entre botones sea de 10 y los AnchorPane derecho e inferior sean 10. El resultado final del interfaz debería ser similar al siguiente
Cierra ahora Scene Builder y, antes de continuar, tómate un tiempo para analizar la estructura del archivo XML creado.
Con esto ya tendríamos creada nuestra VistaPersona, pero para nuestra aplicación necesitamos ademas una vista principal, que crearemos en un nuevo FXML llamado VistaPrincipal, también dentro del package view.
Una vez abierto en Scene Builder, borrar el AnchorPane, ya que en este caso utilizaremos un BorderPane, que puedes añadir arrastrando desde Containers en la parte superior izquierda.
El tamaño preferido del BorderPane (En Layout) debe ser 600x400 y de momento solo le añadiremos una barra de menú superior (MenuBar en Controls) en la parte superior. El resultado debería ser similar a este:
Por último, vamos a cerrar Scene Builder y crear la clase principal de nuestra aplicación, pero primero tómate algo de tiempo para analizar la estructura del archivo FXML recién creado.
Vamos a crear nuestra clase principal con el nombre LibretaDirecciones haciendo clic derecho en package controller (Other -> JavaFX -> JavaFX Main Class).
La clase generada (LibretaDirecciones.java) extiende a la clase Application y contiene dos métodos. Esta es la estructura básica que necesitamos para ejecutar una aplicación JavaFX. La parte más importante para nosotros es el método start(Stage primaryStage). Este método es invocado automáticamente cuando la aplicación es lanzada desde el método main.
Como puedes ver, el método start(...) toma un Stage como parámetro. El gráfico siguiente muestra la estructura de cualquier aplicación JavaFX:
Fuente: Oracle
El funcionamiento es similar al de una obra de teatro: El Stage (escenario) es el contenedor principal, normalmente una ventana con borde y los típicos botones para maximizar, minimizar o cerrar la ventana. Dentro del Stage se puede añadir una Scene (escena), la cual puede cambiarse dinámicamente por otra Scene. Dentro de un Scene se añaden los nodos JavaFX, tales como AnchorPane, TextBox, MediaPlayer, ImageView, etc.
Para tener más información puedes consultar Working with the JavaFX Scene Graph.
Por defecto, la clase principal creada invoca una vista sencilla con un botón que permite decir "Hola" al hacer clic en él. Vamos a borrar todo el código de la clase y sustituirlo por el siguiente, que como puedes ver está comentado indicando a qué corresponde cada apartado para que puedas comprender en detalle su funcionamiento:
package controller;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class LibretaDirecciones extends Application {
private Stage escenarioPrincipal;
private BorderPane layoutPrincipal;
private AnchorPane vistaPersona;
@Override
public void start(Stage escenarioPrincipal) {
//Debo hacerlo para que luego me funcione en l carga de escenas
this.escenarioPrincipal = escenarioPrincipal;
//Establezco el título
this.escenarioPrincipal.setTitle("Libreta de direcciones");
//Inicializo el layout principal
initLayoutPrincipal();
//Muestro la vista persona
muestraVistaPersona();
}
public void initLayoutPrincipal(){
//Cargo el layout principal a partir de la vista VistaPrincipal.fxml
FXMLLoader loader = new FXMLLoader();
URL location = LibretaDirecciones.class.getResource("../view/VistaPrincipal.fxml");
loader.setLocation(location);
try {
layoutPrincipal = loader.load();
} catch (IOException ex) {
Logger.getLogger(LibretaDirecciones.class.getName()).log(Level.SEVERE, null, ex);
}
//Cargo y muestro la escena que contiene ese layout principal
Scene escena = new Scene(layoutPrincipal);
escenarioPrincipal.setScene(escena);
escenarioPrincipal.show();
}
public void muestraVistaPersona(){
//Cargo la vista persona a partir de VistaPersona.fxml
FXMLLoader loader = new FXMLLoader();
URL location = LibretaDirecciones.class.getResource("../view/VistaPersona.fxml");
loader.setLocation(location);
try {
vistaPersona = loader.load();
} catch (IOException ex) {
Logger.getLogger(LibretaDirecciones.class.getName()).log(Level.SEVERE, null, ex);
}
//Añado la vista al centro del layoutPrincipal
layoutPrincipal.setCenter(vistaPersona);
}
//Invoco el método getPrimaryStage para que devuelva mi escenario principal
public Stage getPrimaryStage() {
return escenarioPrincipal;
}
//Método main
public static void main(String[] args) {
launch(args);
}
}
Si ejecutas el código, deberías ver un interfaz similar a la de la imagen mostrada al inicio del capítulo.
IMPORTANTE: En el caso de JavaFX, si los resultados no son los esperados al ejecutar la aplicación, prueba a hacer un Clean and Build de tu proyecto antes de ejecutarlo.
Publicado el 30 de Enero de 2025
xmlinterfacesjavafx