Sigueme en Facebook Sigueme en Twitter Sigueme en Instagram Sigueme en Youtube
JC Mouse Bolivia
Index / JavaFX / Introducción a Scene Builder y MVC (Parte II)

Introducción a Scene Builder y MVC (Parte II)

Autor jc mouse miércoles, enero 20, 2016

Segunda parte del tutorial [Introducción a Scene Builder y MVC (Parte I)]. En esta segunda parte, completaremos el diseño de la vista DetailsView e implementaremos código java en los controladores.

Paso 7: Vista Detalle

Para terminar la segunda vista «Vista Detalle«, nos basaremos en la siguiente plantilla:

mockup details

Dimensión igual que la vista «LoginView«, de 480 de ancho y 320 de alto.

Clic derecho sobre «DetailsView.fxml» → Open para abrir la vista en el Scene Builder, añade la hoja de estilos a la vista, agrega también los controles y al TextField y Button agrega los estilos CSS «text_app» y «button_app» como ya vimos en el primer tutorial.

Si bien podemos hacer uso de hojas de estilo en los controles, también podemos agregar algunas propiedades directamente e incluso algunos efectos.

propiedades

Debemos tener algo como esto:

vista detalle

Guarda los cambios y cierra el Scene Builder.

Paso 8: Autenticación de Usuarios

Para que el controlador *.java identifique cada uno de los controles de la vista *.fxml, se ayuda del atributo «fx:id» donde se coloca un valor único para cada control, en el controlador en cambio para identificar esos controles, se emplea @FXML, por ejemplo:

En una vista cualquiera tenemos un control Label cuyo fx:id es «saludo»

<Label fx:id="saludo" text="Hola Mundo" />

Entonces para que ese control Label sea reconocido desde el controlador *.java, se emplea la siguiente sintaxis:

@FXML Label saludo;

Donde @FXML le indica que ese Label sea visible desde el controlador.

Para asignar un identificador a un control desde Scene Builder, se debe seleccionar el control y en el menu del lado derecho desplegamos el panel «Code» buscamos el atributo fx:id , escribimos el identificador y presionamos ENTER.

fx id

Dicho todo esto, continuemos con el proyecto.

Abre la vista «LoginView.fxml» en Scene Builder y coloca los identificadores para los siguientes controles:

id login

 

Cuando presionamos el botón de Iniciar sesión «btnOk«se producirá una acción el cual es verificar los datos del usuario, pero para que eso pase, debemos definir un nombre para ese método, entonces en el mismo panel donde escribimos el fx:id del botón, más abajo encontraremos On Action, en el campo de texto escribimos «verifyUserData» y presionamos enter.

user data

Guarde los cambios y cierre.

Ahora abre la vista «DetailsView.fxml» e igual que la anterior vista, agrega los fx:id como se muestra en la imagen de abajo.

ids detalle

Guarde los cambios y cierre.

Controladores

Comenzaremos a escribir el código en los controladores, pero antes, debemos modificar el archivo «FXMain.java«, ábrelo y reemplaza su contenido con el siguiente código:

package app;
import app.login.LoginController;
import java.io.InputStream;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
/**
 * @web https://www.jc-mouse.net/
 * @author jc mouse
 */
public class FXMain extends Application {
    
    private Stage stage;    
    
    @Override
    public void start(Stage stage) throws Exception {
         try {
            this.stage = stage;
            stage.setTitle("Sample Login - [https://www.jc-mouse.net/]");                     
            LoginController login = (LoginController) replaceSceneContent("login/LoginView.fxml");
            login.setStage(stage);            
            stage.show();
        } catch (Exception ex) {
            System.err.println(ex.getMessage());
        }     
    }

    private Initializable replaceSceneContent(String fxml) throws Exception {
        FXMLLoader loader = new FXMLLoader();
        InputStream in = FXMain.class.getResourceAsStream(fxml);
        loader.setBuilderFactory(new JavaFXBuilderFactory());
        loader.setLocation(FXMain.class.getResource(fxml));
        AnchorPane page;
        try {
            page = (AnchorPane) loader.load(in);
        } finally {
            in.close();
        } 
        Scene scene = new Scene(page, 480,320);
        stage.setScene(scene);
        stage.sizeToScene();
        return (Initializable) loader.getController();
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
    
}

El funcionamiento de este pequeño sistema sera el siguiente

Cuando se escriba el usuario y contraseña y se presione el botón «Iniciar Sesión«, el sistema validara que los datos sean correctos, si no lo son, mostrara un mensaje de error, si son correctos, mostrara una segunda pantalla donde se desplegara el nombre completo del usuario logueado, pero aquí lo importante, no abrirá otra ventana sino que reemplazara la existe por la vista DeatilsView y hará lo mismo cuando se presione el botón «Volver» reemplazara el contenido de la ventana actual por LoginView.

Esto que parece no ser tan importante, se vera su utilidad cuando implementemos este sistema para la web.

continuemos….

Abre el controlador «LoginController.java» y reemplaza por:

package app.login;
import app.model.Authentication;
import java.io.InputStream;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
/**
 * FXML Controller class
 * @web https://www.jc-mouse.net/
 * @author jc mouse
 */
public class LoginController implements Initializable {

    @FXML Button btnOk;
    @FXML TextField txtUser;
    @FXML TextField txtPass;
    @FXML Label txtMsgError;
    
    private Stage stage;
     
    /**
     * Initializes the controller class.
     * @param url
     * @param rb
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        
        //oculta mensaje de error
        txtMsgError.setVisible(false);
        
         //cuando cualquier de los  textfield gane foco 
         //si existe mensaje de error visible -> se oculta
        txtUser.focusedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
             if (newValue){
                txtMsgError.setVisible(false);
             }
        });
        txtPass.focusedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
             if (newValue){
                txtMsgError.setVisible(false);
             }
        });
    }     
    
    public void setStage (Stage stage){
        this.stage = stage;
    }
    
    /**
     * Acción que se produce al presionar el boton "Iniciar Sesión"
     * @param event
     */
    @FXML       
    private void verifyUserData(ActionEvent event) throws Exception{
        Authentication authentication = new Authentication();
        //verifica que datos introducidos sean correctos
        boolean response = authentication.userExists(txtUser.getText(), txtPass.getText());
        if( response ){ // los datos son correctos      
            //reemplaza el stage actual por el de la vista "DetailsView"
            FXMLLoader loader = new FXMLLoader();
            InputStream in = LoginController.class.getResourceAsStream("DetailsView.fxml");
            loader.setBuilderFactory(new JavaFXBuilderFactory());
            loader.setLocation(LoginController.class.getResource("DetailsView.fxml"));
            AnchorPane page;
            try {
                page = (AnchorPane) loader.load(in);
            } finally {
                in.close();
            } 
            Scene scene = new Scene(page, 480,320);
            stage.setScene(scene);
            stage.sizeToScene();
            DetailsController login = (DetailsController)loader.getController();
            login.setStage(stage);
            login.setUser( authentication.getUser( txtUser.getText(), txtPass.getText()).get() );
            stage.show();
        }            
        else{
            txtMsgError.setVisible(true);
        }   
    }
    
}//LoginController:end

En la clase LoginController, podemos ver el método declarado en Scene Builder verififyUserData().

Finalmente abre «DetailsController.java» y reemplaza por:

package app.login;
import app.model.User;
import java.io.InputStream;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
/**
 * @web https://www.jc-mouse.net/
 * @author jc mouse
 */
public class DetailsController implements Initializable {

    @FXML TextField txtUserName;
    @FXML Button btnReturn;
    
    private User user;
    private Stage stage;
    
    /**
     * Initializes the controller class.
     * @param url
     * @param rb
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {

        //evento cuando se presiona el boton "volver"
        btnReturn.setOnAction((ActionEvent t) -> {
         try{
            FXMLLoader loader = new FXMLLoader();
            InputStream in = LoginController.class.getResourceAsStream("LoginView.fxml");
            loader.setBuilderFactory(new JavaFXBuilderFactory());
            loader.setLocation(LoginController.class.getResource("LoginView.fxml"));
            AnchorPane page;
            try {
                page = (AnchorPane) loader.load(in);
            } finally {
                in.close();
            } 
            Scene scene = new Scene(page, 480,320);
            stage.setScene(scene);
            stage.sizeToScene();            
            LoginController login = (LoginController)  loader.getController();
            login.setStage(stage);            
            stage.show();
         }  catch(Exception ex) {
            System.err.println(ex.getMessage());
        }     
       });
    }    

    /**
     * @param stage
     */
    public void setStage (Stage stage){
        this.stage = stage;
    }
    
    /**
     * @param user
     */
    public void setUser(User user) {
        this.user = user;
        txtUserName.setText( user.getFullName() );        
    }
}

En el controlador DetailsView, también tenemos un botón «Volver» que realiza un evento, pero si recordamos el el Scene Builder no declaramos ningún método, pero existe otra manera de declarar un evento para un control, y es declarando el mismo en el initialize del controlador.

Si no tenemos marcado ningún error, ejecuta el proyecto y logueate con user: demo y pass: demo.

Hasta aquí hemos concluido con el tutorial, pero debemos resaltar que uno de los puntos fuertes de javaFX es Rich Internet Application, esto es aplicaciones web que cuentan con la mayorías de las características de una aplicación de escritorio tradicional. Pero dejamos a continuación un video que muestra claramente de lo que hablamos.

https://youtu.be/odIOW_3qFJQ

Descargar proyecto Sample-login

enjoy!!!

Tags

Si te ha gustado podrías compartirlo o dejar un comentario. ¡Muchas gracias!
Autor: JC Mouse

Yo soy yo :) JC Mouse, Soy orgullosamente boliviano soy fundador y CEO de la web jc-Mouse.net uno de las pocas web en emprendimiento y tecnología en Bolivia.

Toda la información que encuentres en este sitio es y sera completamente gratis siempre, puedes copiar, descargar y re-publicar si así lo deseas en otros blogs o sitios web, solo te pido a cambio que dejes una referencia a esta web. Esto nos ayuda a crecer y seguir aportando. Bye

Enjoy! :)

También Te Podría Interesar

Arreglos en Visual Basic

Arreglos en Visual Basic

Un array es un conjunto finito y ordenado de elementos homogeneos. Ordenado porque los elementos n-esimo de un array pue...

Rompecabezas con forma irregular

Rompecabezas con forma irregular

En este post vemos una manera de como crear un juego de rompecabezas en java sin el uso de java2d, ademas, las piezas de...

SharedPreferences: Preferencias de Usuario

SharedPreferences: Preferencias de Usuario

En este post construiremos paso a paso un SharedPreferences más conocido en español como «Preferencias de Usuario«, esta...

Reportes con imagenes en Java (Video)

Reportes con imagenes en Java (Video)

Video Tutorial que muestra una de las maneras de utilizar y mostrar imagenes en iReport, pasando estas como parametros d...

JSON Web Tokens: Teoría y práctica

JSON Web Tokens: Teoría y práctica

En este post aprenderemos lo que es un JSON Web Token, como crear nuestro propio token de acceso y como usarlo en un Ser...

Crear componentes en tiempo de ejecución con Netbeans

Crear componentes en tiempo de ejecución con Netbeans

🙂 Una de las preguntas más buscadas por programadores java es la de crear componentes swing en tiempo de ejecución, eso...

Comparte lo que sabes

Categorias

Últimas entradas

Crecen las startups en Bolivia: La mayoría está en Santa Cruz, Cochabamba y La Paz Según el «Mapeo del Ecosistema de Tec...

«Las palabras que elegimos dan forma a nuestra realidad. La Fuente Educada (Polite Type) es una fuente de código abierto...

En este post realizaremos un proyecto en VUE que se conectara a un REST API  y utilizara un servicio del mismo para obte...

En este post realizaremos una aplicación que pueda capturar nuestra voz y convertir en texto Pasar voz a texto con Andro...

Herramientas

Generador de Enlaces a Whatsapp