En este tutorial realizaremos una introducción al diseño de interfaces gráficas en JavaFX y Scene Builder, así también veremos como podemos implementar el patrón MVC (Modelo, Vista y Controlador) en nuestros proyectos.
¿Qué necesitamos?
Herramientas:
Conocimientos mínimos necesarios:
Tiempo: 40 minutos
Nivel: Básico
PROYECTO
Paso 1: Crea un nuevo proyecto en Netbeans menú Archivo → Proyecto nuevo… seleccionar categoría javaFX → JavaFX FXML Application, presionar botón «Siguiente«.
En la ventana que aparece, escribir el nombre del proyecto «Sample-Login«, la opción «Create Application class«, debe estar desactivada. Presiona «Terminar» para crear el proyecto.
Paso 2: Estructura del proyecto
El proyecto creado en el paso 1 se encuentra vacío, para crear los diferentes paquetes y archivos, debemos hacer lo siguiente:
Clic derecho sobre «Paquete de fuentes» → Nuevo → Package, en Package Name escribe «app» y luego presiona «terminar«.
Clic derecho sobre el paquete «app» → Nuevo → Otro → seleccionamos la categoría JavaFX → JavaFX Main Class , a continuación escribimos un nombre para el archivo «FXMain» y presionamos terminar.
Este archivo Main es el que se debe ejecutar primero ya que contiene el método start() el principal punto de entrada para las aplicaciones JavaFX, para realizar esto, clic derecho sobre el proyecto → Propiedades, a continuación seleccionamos la categoría RUN, buscamos la opción «Application class» y presionamos el botón browse, en la ventana que aparece seleccionamos «app.FXMain» y presionamos el boton «select class» y aceptar para terminar.
Hasta el momento tenemos los siguiente [ver imagen de abajo]. Si ejecutamos en este punto el proyecto solo veremos una ventana con el clásico «Hello World«, pero ese no es nuestro objetivo así que continuemos.
Paso 3: Paquetes
Continuamos creando los paquetes necesarios para el proyecto.
Clic derecho sobre «app» → Nuevo → Java Package, en Package Name escribe «resources» y luego presiona «terminar«. En el paquete que acabas de crear, clic derecho → Nuevo → Otro … selecciona categoria Otros → Hoja de estilos en Cascada CSS y presionas siguiente, en nombre de archivos escribe «MyStyle» y luego terminar. En este archivo escribiremos los estilos CSS para la interfaz.
Clic derecho sobre «app.resources» → Nuevo → Java Package, en Package Name escribe «images» y luego presiona «terminar«. En este nuevo paquete colocaremos las imágenes que utilizaremos.
Necesitamos otro paquete para colocar nuestras vistas y controladores, dependiendo de la complejidad de la aplicación pueden utilizarse 1 o más paquetes, en este ejemplo solo utilizaremos un paquete, Clic derecho sobre «app» → Nuevo → Java Package, en Package Name escribe «login» y luego presiona «terminar«.
Finalmente, necesitamos un paquete más para el modelo. Clic derecho sobre «app» → Nuevo → Java Package, en Package Name escribe «model» y luego presiona «terminar«.
Paso 4: Vistas, controladores y modelo
Primeramente crearemos las clases para el modelo, no usaremos base de datos así que emularemos la autenticación de usuarios con datos de un arrayList.
Clic derecho sobre «model» → Nuevo → Java Class, en Class Name escribimos «User» y luego presiona «terminar«. Pega el siguiente código en la clase.
package app.model; /** * @web https://www.jc-mouse.net/ * @author jc mouse */ public class User { private String nick; private String pass; private String fullName; /** Constructor de clase */ public User(){} /** Constructor de clase * @param nick apodo * @param pass palabra secreta * @param fullName nombre completo */ public User(String nick, String pass, String fullName){ this.nick = nick; this.pass = pass; this.fullName = fullName; } public String getNick() { return nick; } public void setNick(String nick) { this.nick = nick; } public String getPass() { return pass; } public void setPass(String pass) { this.pass = pass; } public String getFullName() { return fullName; } public void setFullName(String fullName) { this.fullName = fullName; } }
Continuamos con la clase que nos permitirá emular la autenticación de usuarios. Clic derecho sobre «model» → Nuevo → Java Class, en Class Name escribimos «Authentication» y luego presiona «terminar«.
Esta clase contara con un método userExists que retorna TRUE si el usuario existe y FALSE en caso contrario, el metodo getUser retorna una Usuario. El código es el siguiente:
package app.model; import java.util.ArrayList; import java.util.Optional; /** * @web https://www.jc-mouse.net/ * @author jc mouse */ public class Authentication { private final ArrayList<User> userList; /** * Constructor de clase */ public Authentication(){ this.userList = new ArrayList<>(); userList.add(new User("demo","demo","Pierre Nodoyuna")); userList.add(new User("zacarias","123456","Zacarias Flores de la Plaza")); userList.add(new User("jc mouse","123456","JC Mouse Bolivia")); } /** * Autenticacion de usuario * @param user usuario * @param pass palabra secreta de usuario * @return boolean */ public boolean userExists(String user, String pass){ return userList.stream().filter((p) -> (user.equals(p.getNick()))).anyMatch((p) -> (pass.equals(p.getPass()))); } /** * Obtiene un Usuario segun parametros de entrada * @param user usuario * @param pass palabra secreta de usuario * @return User */ public Optional<User> getUser(String user, String pass){ return userList.stream().filter(u -> u.getNick().equals(user) ).filter(u -> u.getPass().equals(pass)).findFirst(); } }
Continuamos con las vistas y controladores, Clic derecho sobre el paquete «app.login» → Nuevo → Otro… seleccionamos categoría JavaFX → Empty FXML, y presionamos siguiente, en FXML Name escribimos «LoginView«, en la siguiente ventana activamos la opción «Use Java Controller«, con la opción «create new» seleccionada en Control Name escribimos «LoginController» y luego presiona «terminar«.
Haremos uso de una segunda vista más, Clic derecho sobre «app.login» → Nuevo → Otro… seleccionamos categoría JavaFX → Empty FXML, y presionamos siguiente, en FXML Name escribimos «DetailsView«, en la siguiente ventana activamos la opción «Use Java Controller«, con la opción «create new» seleccionada en Control Name escribimos «DetailsController» y luego presiona «terminar«.
Nuestro proyecto debe tener la siguiente forma:
Paso 5: Interfaz de usuario
Nuestro proyecto cuenta con dos interfaces, la primera corresponde al formulario de «Login de usuario«, el segundo mucho más sencillo, se reducirá a una ventana de confirmación donde se muestran los datos del usuario logueado.
Antes de crear interfaces de usuario con Scene Builder o en cualquier otro IDE, es buena practica antes diseñar un borrador de la idea que tenemos en mente ya sea con lápiz y papel o un software de diseño. Esto nos permitirá estudiar el diseño de la interfaz y también comprobar su funcionalidad en el programa.
Con ayuda de nuestro sencillo mockup podemos identificar que necesitamos los siguientes estilos CSS y archivos:
Comenzaremos ahora a escribir los estilos CSS, en Netbeans abre el archivo «MyStyle.css«.
JavaFX CSS esta basado en las Hojas de Estilo CSS pero no es 100% igual. Etiquetas más etiquetas menos, javaFX CSS esta pensado para que el que sepa trabajar con CSS y HTML pueda usar esos conocimientos para desarrollar interfaces en JavaFX CSS de una manera natural.
Otra dato importante acerca de JavaFX CSS es que se debe usar antes de cada propiedad el prefijo «-fx-«, es decir si tenemos «background-color: #fff;» en javafx css sera «-fx-background-color: #fff;«. Eso todo lo que necesitamos saber por el momento, continuemos.
Los estilos que usaremos en el proyecto, son los siguientes:
/*color de fondo*/ .background_app{ -fx-background-color: #00aff0; } /* cajas de texto */ .text_app{ -fx-background-color: #cceffc; -fx-text-fill: #000; -fx-prompt-text-fill: #5aaff0; -fx-text-box-border: transparent; -fx-background-radius: 0; -fx-padding: 8; -fx-font-size:14px; } .text_app:focused { -fx-text-fill: #000; -fx-background-color: #fff; } /*boton de inicio de sesion*/ .button_app{ -fx-background-color: #0c7daf; -fx-border-radius: 46; -fx-background-radius: 46; -fx-text-fill: #fff; -fx-alignment: CENTER; } /**etiqueta de inicio de sesion*/ .textb_app{ -fx-text-fill: #fff; -fx-font-size:16px; -fx-font-weight: bold; -fx-effect: dropshadow( gaussian , rgba(0,0,0,0.5) , 0,0,0,1 ); } /**etiqueta ¿no puede...*/ .textnp_app{ -fx-text-fill: #fff; -fx-font-size:12px; -fx-font-weight: normal; } /*etiqueta de error*/ .texterr_app{ -fx-text-fill: #a53b3f; -fx-font-size:12px; -fx-font-style:italic; }
Las Vistas
Ahora que tenemos listo nuestra hoja de estilos, en netbeans clic derecho en «LoginView.fxml» → Open. Se nos abrirá el Scene Builder y por el momento nos mostrara un contenedor (AnchorPane) vacio.
Agregar Hojas de Estilo al archivo FXML
Selecciona el contenedor → en el apartado de «propiedades» busca «StylesSheets» y presiona el signo [+] que esta debajo, entonces busca el archivo CSS que para este ejemplo, esta en «app.resources.MyStyle.css». No olvides guardar los cambios File → Save después de cada modificación.
Agregar imagen
En este proyecto hacemos uso de una imagen para mostrar el logo de nuestra aplicación, la imagen es un archivo *.PNG de 123×60 pixeles. Debes colocarlo en el paquete «app.resources.images«.
En Scene Builder en la sección de Library → Controls, busca el control ImageView y arrastra hacia el contenedor. Con el control aún seleccionado, en Propiedades busca Image y presiona el boton […] para buscar la imagen en el proyecto. No notaras nada por el momento porque la imagen es de color blanco y el contenedor también, despliega el contenedor «Layout» y busca fit width y fit height, coloca los valores 123 y 60 respectivamente.
Agregar CSS a un control
Selecciona el contenedor y en sus Propiedades busca Style Class, despliega y selecciona el estilo «background_app«, ahora nuestro contenedor toma un color azul y ya podemos ver la imagen que añadimos en el paso anterior.
Tamaño del contenedor
Es importe especificar el tamaño que tendrá el contenedor, para esto, selecciona el contenedor «AnchorPane» y en el panel de «Layout«, busca Pref Width y Pref Height, escribe 480 y 320 respectivamente.
Agregar el resto de los controles
Desde la librería de controles Library → Controls, arrastra y suelta en el contenedor los siguientes controles:
Para agregar texto a un control se utiliza la propiedad Text, ademas los controles TextField y PasswordField cuentan con la propiedad Promp Text, esta propiedad muestra un texto cuando el control esta vació, como el placeholder en HTML5
Completa los textos para cada control según la plantilla de nuestra vista:
Debemos añadir los estilos CSS para cada control tal como hicimos para el contenedor, la imagen siguiente muestra los CSS para cada uno de ellos.
Después de agrear los estilos y con unos ajustes de tamaño, colocamos cada control en su lugar y tenemos:
Guarda los cambios y cierra el Scene Builder
Si abres el «LoginView.fxml» en modo edición, veras como Scene Builder a escrito todo el código FXML necesario para la interfaz. Este código puede editarse manualmente, pero eso lo veremos en otra ocasión.
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.image.*?> <?import java.lang.*?> <?import java.util.*?> <?import javafx.scene.*?> <?import javafx.scene.control.*?> <?import javafx.scene.layout.*?> <AnchorPane id="AnchorPane" prefHeight="320.0" prefWidth="480.0" styleClass="background_app" stylesheets="@../resources/MyStyle.css" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8" fx:controller="app.login.LoginController"> <children> <ImageView fitHeight="60.0" fitWidth="123.0" layoutX="182.0" layoutY="33.0" pickOnBounds="true" preserveRatio="true"> <image> <Image url="@../resources/images/logo_app.png" /> </image> </ImageView> <Label layoutX="191.0" layoutY="101.0" styleClass="textb_app" text="Iniciar Sesión" /> <TextField layoutX="114.0" layoutY="133.0" prefHeight="36.0" prefWidth="260.0" promptText="Nombre de usuario" styleClass="text_app" /> <PasswordField layoutX="114.0" layoutY="176.0" prefHeight="36.0" prefWidth="260.0" promptText="Palabra secreta" styleClass="text_app" /> <Button layoutX="168.0" layoutY="222.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="153.0" styleClass="button_app" text="Iniciar sesión" /> <Label layoutX="179.0" layoutY="258.0" styleClass="texterr_app" text="Los datos son incorrectos" /> <Label layoutX="304.0" layoutY="297.0" styleClass="textnp_app" text="¿No puede acceder a su cuenta?" /> </children> </AnchorPane>
Paso 6:
Ya para terminar esta primera parte, abre la clase FXMain.java y reemplaza el método «start» por:
@Override public void start(Stage stage) throws Exception { Parent root = FXMLLoader.load(getClass().getResource("login/LoginView.fxml")); Scene scene = new Scene(root); stage.setTitle("Sample Login - [https://www.jc-mouse.net/]"); stage.setScene(scene); stage.show(); }
Lo que hacemos con este código es indicarle al programa que inicie con la vista «LoginView.fxml«. Finalmente ejecuta el proyecto (F6) y si no tenemos ningún error podremos ver algo similar a esto en pantalla.
Nuestra vista para autenticar usuarios esta lista, aunque carece de funcionalidad, eso lo veremos en la segunda parte 🙂
Enjoy!!!
En este oportunidad comparto una pequeña aplicación hecha en java para recortar partes de una imagen seleccionado con el[...]
En esta oportunidad dejo para estudio y critica de los programadores android un ejemplo sencillo de una aplicación que h[...]
Una Vista (View) es una Tabla Virtual cuyo contenido está definido por una consulta (SELECT), al igual que una tabla rea[...]
Si necesitamos mostrar gráficos estadísticos en nuestras aplicaciones android, contamos con muchas librerías disponibles[...]
Antes de la aparición de los celulares inteligentes y de las grandes mejoras tecnológicas que trajeron con ellas, las ap[...]
Gson es una biblioteca de código abierto para Java desarrollado por Google Inc que permite la serialización y deserializ[...]