JavaFx 8 Administrar ventanas

En este tutorial veremos como podemos administrar varias ventanas creadas con JavaFX API, crearemos las ventanas a partir de un archivo .fxml y veremos las diferentes propiedades que podemos modificar para manipular la apariencia y comportamiento de nuestra aplicación JavaFX 8, sin mas, manos a la obra.

Requisitos: Introducción a Java FX 8

Lo primero que debemos saber es como esta conformada la arquitectura de JavaFX para las ventanas, una ventana esta compuesta por un marco principal que contiene normalmente los botones de cerrar, maximizar, minimizar, titulo e icono de la aplicación, en JavaFX este marco esta representado por la clase Stage, este debe contener un objeto de la clase Scene el cual representa la vista de nuestra aplicación, es en donde el usuario vera o inducirá datos, para finalizar necesitamos controles como botones cajas de texto y demás, por lo que un Scene contendrá uno o mas objetos extendidos de la clase Node, la clase base para los controles y figuras como: rectángulos, círculos, etc.

Creación de una ventana JavaFX 8

Creamos un proyecto como lo hicimos anteriormente, nos ubicamos en el método start() pues este es el punto de inicio para la aplicación, veremos que este método tiene como parámetro un objeto Stage que representa la ventana principal.

A este Stage le asignamos un Scene en nuestro caso el mismo será cargado desde un archivo .fxml que indicaremos, podemos crear el Scene directamente desde código si lo deseamos, ahora ya será posible mostrar la ventana usando método show() de la clase Stage.

public void start(Stage stage) throws Exception {

        //Cargar el contenido del archivo /Ventana.fxml, procesarlo y crear el
        //contenido a partir del mismo.
        Parent root = FXMLLoader.load(getClass().getResource("Ventana.fxml"));

        //Asignar las UI creadas desde *.fxml a un Scene
        Scene scene = new Scene(root);

        //Asignar el Scene a la ventana principal o Stage y mostrarla.
        stage.setScene(scene);
        stage.show();
    }

Si ejecutamos el programa y todo esta correcto veremos lo siguiente:

ventana javafx

Configurar la ventana

Para establecer el titulo de la ventana tenemos disponible el método setTitle("title"), también disponemos de getIcons() el cual retorna la colección de iconos que utiliza la aplicación para por ejemplo mostrar como icono de la ventana, mostrar en la barra de tareas, etc., los mismos deben estar en los tamaños correspondientes, 16x16, 32x32, etc.

Además tenemos muchas otras funciones y propiedades que podemos configurar como por ejemplo para mostrar la ventana en modo maximizado, evitar que la ventana pueda cambiar de tamaño, entre otras, no podemos mencionarlas ni verlas todas, por lo que siempre es recomendable echarle un ojo a la documentación oficial.

//Asignar la scene a la ventana principal o stage.
stage.setScene(scene);
stage.setTitle("Tutor de programacion");

//Establecer los iconos de la aplicacion
stage.getIcons().add(new Image(getClass().getResource("iconos/icon-16.png").toExternalForm()));
stage.getIcons().add(new Image(getClass().getResource("iconos/icon-32.png").toExternalForm()));
stage.getIcons().add(new Image(getClass().getResource("iconos/icon-64.png").toExternalForm()));
stage.getIcons().add(new Image(getClass().getResource("iconos/icon-128.png").toExternalForm()));
stage.getIcons().add(new Image(getClass().getResource("iconos/icon-256.png").toExternalForm()));
stage.getIcons().add(new Image(getClass().getResource("iconos/icon-512.png").toExternalForm()));

//establece una ventana minimizada y la misma no puede cambiar de
//tamaño con la accion de arrastrar y soltar del raton
stage.setIconified(true);
stage.setResizable(false);

Con esta modificación la ventana aparecerá minimizada y además la misma no permitirá modificar su tamaño.

Creación de Ventanas Secundarias

Por lo general al crear una aplicación requerimos de crear ventanas que puedan servir para interactuar con el usuario o mostrarle algún mensaje o notificación, veremos como crear ventanas secundarias que nos servirán como cuadros de dialogo o de lo que necesitemos en su momento, ya que una aplicación por lo general se compone de varias ventanas aprenderemos a manipular las mismas.

En esta ocasión la ventana secundaria la crearemos directamente desde código, aunque podemos cargarla de .fxml como lo hicimos anteriormente, aprovechando el código que ya tenemos, iremos al código de la clase VentanaController, la misma contiene un método llamado handleButtonAction() el mismo se ejecuta cada vez que hacemos clic sobre el botón, aquí haremos la llamada al método nuevaVentana() que será el encargado de crear y mostrar la ventana.

private void nuevaVentana() {
        Stage stage = new Stage();
        BorderPane pane = new BorderPane();
        Scene scene = new Scene(pane);

        stage.setScene(scene);
        stage.setTitle("Nueva Ventana");
        stage.show();
    }

Con este código logramos crear una ventana cada vez que hagamos clic sobre el botón "Click Me!", la diferencia con el código anterior es que el contenido del Scene fue creado desde código, podemos ver como asignamos un BorderPane al objeto Scene.

El BorderPane es un contenedor que nos permite ubicar su contenido en la parte superior, inferior, derecha o central, como ejemplo agregaremos una etiqueta con un mensaje cualquiera y lo ubicaremos en el centro del BorderPane, podemos ubicar los controles con los correspondientes métodos set: center, top, bottom, left, right.

Label etiqueta = new Label("\tTUTOR DE PROGRAMACIÓN\r\nCreación y administración de de ventanas");
pane.setCenter(etiqueta);

Para cambiar el estilo de la ventana usamos el método initStyle() de la clase Stage, para crear por ejemplo una ventana sin el marco visible, tenemos varios estilos que podemos probar:

stage.initStyle(StageStyle.UTILITY);
stage.initStyle(StageStyle.DECORATED);
stage.initStyle(StageStyle.UNDECORATED);
stage.initStyle(StageStyle.UNIFIED);
stage.initStyle(StageStyle.TRANSPARENT);

En este punto las ventanas que hemos creado tienen un inconveniente, si cerramos la ventana principal las demás permanecerán abiertas y ejecutándose, para evitar esto debemos establecer la relación primario secundario entre las ventanas.

Para resolverlo crearemos un método setStage() en la clase VentanaController el mismo nos servirá para guardar una instancia del Stage principal, para establecer el Stage primario usamos stageSecundario.initOwner(stagePrimario), también haremos una modificación en el método start(), cuando creemos la ventana principal obtendremos su controlador "VentanaController" para establecer el Stage principal.

//Parent root = FXMLLoader.load(getClass().getResource("Ventana.fxml"));
FXMLLoader loader = new FXMLLoader(getClass().getResource("Ventana.fxml"));
Parent root = loader.load();
VentanaController ven = loader.getController();
ven.setStage(stage);

Hecho esto todas las ventanas creadas deberán cerrarse al terminar la ejecución de la ventana principal.

Por ultimo veamos como crear ventana modales, estas son ventana secundarias que bloquean la ventana principal mientras están abiertas, para crear una de estas ventanas solo debemos establecer el método initModality(Modality.WINDOW_MODAL).

Siguiente tutorial JavaFX: Controles y contenedores.

Comentarios

  1. Que grande !!! ni te imaginas lo útil que me ha resultado, entradas como esta dan gusto.
    Muchas gracias !!!

    ResponderEliminar
  2. Buenos dias, he creado un formulario con scene builder y su respectivo controlador. Tengo hecho un proyecto en java swing, y necesito abrir ése formulario fxml. Como seria el codigo para abrirlo desde un JButton en java swing, Gracias.

    ResponderEliminar
  3. Si a alguien le sirve esta es otra forma de hacerlo sin el setStage
    Solamente obtienen el Stage asi:
    @FXML AnchorPane pane;

    Stage stagePrimario= (Stage) pane.getScene().getWindow();

    ResponderEliminar

Publicar un comentario

Temas relacionados

Entradas populares de este blog

tkinter Grid

tkinter Canvas

Histogramas OpenCV Python

Python Binance API