JavaRush /Blog Java /Random-ES /Introducción a Java FX

Introducción a Java FX

Publicado en el grupo Random-ES
Un día tuve la idea de escribir una pequeña aplicación de escritorio para mis necesidades, algo así como un pequeño diccionario para aprender palabras extranjeras, y comencé a devanarme los sesos: ¿cómo podría hacer esto? Naturalmente, lo primero que me vino a la mente fue Swing. Probablemente todo el mundo haya oído hablar del Swing . Esta es una biblioteca para crear interfaces gráficas de usuario. Debido a que nuestro querido Oracle aún no ha abandonado por completo Swing, no se considera obsoleto y las aplicaciones aún se ejecutan en él. Sin embargo, Swing ya no lo moderniza y la gente de Oracle nos ha dado una idea de cuál es el futuro de JavaFX. Y, de hecho, JavaFX utiliza componentes Swing como proveedor de servicios)

¿Qué es JavaFX?

JavaFX es esencialmente un conjunto de herramientas GUI para Java. Aquí haremos una pequeña digresión y recordaremos qué es una GUI : Interfaz gráfica de usuario : una interfaz gráfica de usuario es un tipo de interfaz de usuario en la que todos los elementos (botones, menús, iconos, listas) presentados al usuario en el La visualización se realiza en forma de imágenes, gráficos. A diferencia de una interfaz de línea de comandos, en una GUI el usuario tiene acceso aleatorio a objetos visibles mediante dispositivos de entrada. A menudo, los elementos de la interfaz se implementan en forma de metáforas y muestran sus propiedades y propósito para facilitar la comprensión del usuario. JavaFX tiene como objetivo la creación de juegos y aplicaciones de escritorio en Java. De hecho, reemplazará a Swing debido a la nueva herramienta GUI propuesta para Java. También nos permite diseñar archivos de diseño GUI (XML) y hacerlos más elegantes usando CSS, similar a lo que estamos acostumbrados en las aplicaciones web. JavaFX además maneja gráficos 3D integrados, así como aplicaciones de audio, video y redes integradas en un único conjunto de herramientas GUI... Es fácil de aprender y está bien optimizado. Es compatible con muchos sistemas operativos, así como con Windows, sistemas UNIX y Mac OS. Introducción a Java FX - 3

Características de JavaFX:

  • JavaFX inicialmente viene con un gran conjunto de partes de la interfaz gráfica, como todo tipo de botones, campos de texto, tablas, árboles, menús, gráficos, etc., lo que a su vez nos ahorrará mucho tiempo.
  • JavaFX a menudo usa estilos CSS y podremos usar un formato FXML especial para crear la GUI, en lugar de hacerlo en código Java. Esto facilita diseñar rápidamente una GUI o cambiar la apariencia o composición sin tener que jugar con el código Java durante mucho tiempo.
  • JavaFX tiene partes de diagramas listas para usar, por lo que no tenemos que escribirlas desde cero cada vez que necesitemos un diagrama básico.
  • JavaFX viene además con soporte para gráficos 3D, lo que suele resultar útil si estamos desarrollando algún tipo de juego o aplicación similar.
Echemos un pequeño vistazo a los componentes principales de nuestra ventana:
  • El escenario es esencialmente una ventana circundante que actúa como un lienzo inicial y contiene el resto de los componentes. Una aplicación puede tener varias etapas, pero en cualquier caso debe existir uno de esos componentes. Básicamente, Stage es el contenedor principal y el punto de entrada.
  • Escena : muestra el contenido del escenario (como una muñeca nido). Cada etapa puede contener varios componentes: escenas, que se pueden alternar entre sí. Internamente, esto se implementa mediante un gráfico de objetos llamado Scene Graph (donde cada elemento es un nodo, también llamado Nodo ).
  • Los nodos son controles, como botones de etiquetas o incluso diseños, que pueden tener varios componentes anidados en su interior. Cada escena puede tener un nodo anidado, pero puede ser un diseño con múltiples componentes. El anidamiento puede ser de varios niveles, con diseños que contienen otros diseños y componentes regulares. Cada uno de estos nodos tiene su propio identificador, estilo, efectos, estado y controladores de eventos.
Introducción a Java FX - 4 Así que avancemos un poco hacia el código. Como uso Java 8, no necesito generar ninguna dependencia, ya que JavaFx está en el JDK de forma predeterminada (como en Java 9.10), pero si tenemos Java 11+, entonces debemos ir al repositorio de Maven y sáquelo de allí dependencias.

JavaFX: ejemplos de uso

Creamos una clase regular con un método main(punto de entrada):
public class AppFX extends Application {

    public static void main(String[] args) {
        Application.launch();
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
pimarySatge.show();
    }
}
Aquí nuestra clase hereda javafx.application.Application(que tenemos del cuadro Bugaga). En main llamamos al método de aplicación estática launch()para iniciar nuestra ventana. Además, nuestra idea se quejará de que no hemos implementado el método de Aplicación, startque es lo que finalmente hacemos. ¿Para qué sirve? Y para poder administrar las propiedades (la funcionalidad de nuestra ventana). Para hacer esto, usamos un argumento entrante primaryStageen el que llamamos a un método showpara que podamos ver la ventana que se abre en main. Completemos un poco nuestro método start:
public void start(Stage primaryStage) throws Exception {
    primaryStage.setTitle("Dogs application");
    primaryStage.setWidth(500);
    primaryStage.setHeight(400);

    InputStream iconStream =
    getClass().getResourceAsStream("/images/someImage.png");
    Image image = new Image(iconStream);
    primaryStage.getIcons().add(image);

    Button button = new Button("WOF WOF ???'");

    button.setOnAction(e -< {
      Alert alert = new Alert(Alert.AlertType.INFORMATION, "WOF WOF WOF!!!");
        alert.showAndWait();
    });
    Scene primaryScene = new Scene(button);
    primaryStage.setScene(primaryScene);

    primaryStage.show();
}
Entonces, ¿qué vemos aquí? Repasémoslo línea por línea: 2 - establezca el nombre de la ventana en sí (etapa) 3.4 - establezca sus dimensiones 6.7 - establezca la ruta de la secuencia de lectura al archivo (icono) Introducción a Java FX - 58 - cree el archivo como un objeto de Imagen, que está conectado al archivo real mediante la secuencia pasada en el constructor 9 - establecer un icono en el panel superior de la ventana 11 - crear un objeto de botón 13-16 - establecer la reacción cuando se presiona el botón 17 - crear una escena donde colocamos nuestro botón 18 - colocamos la escena en nuestra ventana común 20 - configuramos la bandera de visibilidad para la ventana Y como resultado obtenemos una pequeña ventana para dar la bienvenida a nuestros pesels favoritos: Introducción a Java FX - 6Todo parece mucho más simple que Swing, ¿no? Pero esto aún no ha terminado. No es bueno escribir todo el código para mostrar una aplicación; es necesario dividirlo de alguna manera para hacerlo más comprensible (componentes gráficos en una cesta, lógica en otra). Y aquí xml entra en escena... Dios mío, ¿xml? Exactamente. En concreto, utilizamos su implementación específica para JavaFX - FXML, en la que definimos los componentes gráficos de la aplicación y sus propiedades (todo tipo de tamaños, etc.), para luego conectarla a un controlador, que ayuda a gestionar la lógica. Veamos un ejemplo de este xml:
<?xml version="1.0" encoding="UTF-8"?>
<?language javascript?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.VBox?>

<VBox xmlns="http://javafx.com/javafx"  xmlns:fx="http://javafx.com/fxml"
   id="Dogs application" prefHeight="200" prefWidth="300" alignment="center">

  <Label text="Wow wow?"/>

  <Button fx:id="mainButton" text="Greeting" onAction="buttonClicked()"/>

    <fx:script>
       function buttonClicked() {
            mainButton.setText("Wow wow wow!!!")
       }
    </fx:script>
</VBox>
2 - el lenguaje de programación que utilizamos 4-6 - datos importados 8-9 Vbox - un contenedor que coloca subcomponentes en una línea. 11 - mostrar algo de texto 13 - un botón, al hacer clic, usamos el método descrito en el script en las líneas 15 a 18. Debería haber un código para llamar a este archivo xml en el método start, pero ahora esto no es tan importante y lo omitirá (a continuación habrá un ejemplo de cómo extraer este archivo). Entonces, xml es, por supuesto, bueno (pero no muy bueno), escribirlos manualmente es muy confuso, ¿no es este el siglo pasado? Introducción a Java FX - 7

Presentamos JavaFX SceneBuilder

Es en este punto que entra en juego (redoble de tambores) - SceneBuilder En JavaFX Scene Builder es una herramienta con la que podemos diseñar nuestras ventanas en forma de interfaz gráfica y luego guardarlas, y este programa, en función del resultado, construiremos archivos xml que los mejoraremos en nuestra aplicación. La interfaz de este constructor fmxl se parece a esto: Introducción a Java FX - 8

Una pequeña digresión. Lecciones de JavaFX

Me saltaré los detalles de instalación y también un estudio detallado de esta herramienta. Estos son temas que vale la pena explorar más a fondo. Por lo tanto, todavía dejaré un par de enlaces interesantes a lecciones de JavaFX: uno (tutorial en línea sobre JavaFX) y dos (otro buen tutorial). Repasemos un pequeño ejemplo que esbocé. Al final obtuve algo como: Introducción a Java FX - 9
(algo así como una ventana para registrar perros)
Cuando selecciona un perro y presiona el botón Eliminar, el perro se elimina de nuestra lista. Cuando seleccionas un amigo de cuatro patas y cambias sus campos, y después de presionar el botón Editar, la información del perro se actualiza. Cuando presionamos el botón Nuevo, aparece una ventana para crear un registro para un nuevo perro (para comenzar con su nombre): Introducción a Java FX - 10Luego haga clic en Guardar y complete el resto de sus campos en la primera ventana, y luego haga clic en el botón Editar para ahorrar. Suena fácil, ¿verdad? Veamos cómo se verá esto en nuestra aplicación Java. Para empezar, dejaré aquí los diseños xml para estas dos ventanas generadas en SceneBuilder: Primero (básico):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<AnchorPane prefHeight="300.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.tutorial.controller.BaseController">
   <children>
      <SplitPane dividerPositions="0.29797979797979796" prefHeight="300.0" prefWidth="600.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
        <items>
          <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
               <children>
                  <TableView fx:id="dogs" layoutX="-2.0" layoutY="-4.0" prefHeight="307.0" prefWidth="190.0" AnchorPane.bottomAnchor="-5.0" AnchorPane.leftAnchor="-2.0" AnchorPane.rightAnchor="-13.0" AnchorPane.topAnchor="-4.0">
                    <columns>
                      <TableColumn fx:id="nameList" prefWidth="100.33334350585938" text="Nickname" />
                    </columns>
                     <columnResizePolicy>
                        <TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
                     </columnResizePolicy>
                  </TableView>
               </children>
            </AnchorPane>
          <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
               <children>
                  <Label layoutX="49.0" layoutY="25.0" text="Person Details" AnchorPane.leftAnchor="5.0" AnchorPane.topAnchor="5.0" />
                  <GridPane accessibleText="erreererer" gridLinesVisible="true" layoutX="5.0" layoutY="31.0" AnchorPane.leftAnchor="5.0" AnchorPane.rightAnchor="5.0" AnchorPane.topAnchor="31.0">
                    <columnConstraints>
                      <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                      <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
                    </columnConstraints>
                    <rowConstraints>
                      <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                      <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                        <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                      <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
                    </rowConstraints>
                     <children>
                        <Label prefHeight="17.0" prefWidth="70.0" text="Nickname" />
                        <Label text="Breed" GridPane.rowIndex="1" />
                        <Label text="Age" GridPane.rowIndex="2" />
                        <Label text="City" GridPane.rowIndex="3" />
                        <Label text="Level of training" GridPane.rowIndex="4" />
                        <TextField fx:id="breed" GridPane.columnIndex="1" GridPane.rowIndex="1" />
                        <TextField fx:id="age" GridPane.columnIndex="1" GridPane.rowIndex="2" />
                        <TextField fx:id="city" GridPane.columnIndex="1" GridPane.rowIndex="3" />
                        <TextField fx:id="levelOfTraining" GridPane.columnIndex="1" GridPane.rowIndex="4" />
                        <TextField fx:id="name" GridPane.columnIndex="1" />
                     </children>
                  </GridPane>
                  <Button layoutX="251.0" layoutY="259.0" mnemonicParsing="false" onAction="#create" text="New" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="230.0" AnchorPane.rightAnchor="130.0" AnchorPane.topAnchor="260.0" />
                  <Button layoutX="316.0" layoutY="262.0" mnemonicParsing="false" onAction="#edit" text="Edit" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="290.0" AnchorPane.rightAnchor="70.0" AnchorPane.topAnchor="260.0" />
                  <Button layoutX="360.0" layoutY="262.0" mnemonicParsing="false" onAction="#delete" text="Delete" AnchorPane.bottomAnchor="10.0" AnchorPane.leftAnchor="350.0" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="260.0" />
               </children>
            </AnchorPane>
        </items>
      </SplitPane>
   </children>
</AnchorPane>
Segundo (para crear nuevos perritos):
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<?import javafx.scene.text.Font?>
<AnchorPane prefHeight="200.0" prefWidth="300.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.tutorial.controller.NewDogController">
   <children>
      <GridPane layoutX="31.0" layoutY="25.0" prefHeight="122.0" prefWidth="412.0">
        <columnConstraints>
          <ColumnConstraints hgrow="SOMETIMES" maxWidth="185.0" minWidth="10.0" prefWidth="149.0" />
          <ColumnConstraints hgrow="SOMETIMES" maxWidth="173.0" minWidth="10.0" prefWidth="146.0" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <children>
            <Label prefHeight="48.0" prefWidth="178.0" text="Please, write name:">
               <font>
                  <Font size="20.0" />
               </font>
            </Label>
            <TextField fx:id="nickName" prefHeight="36.0" prefWidth="173.0" GridPane.columnIndex="1" />
         </children>
      </GridPane>
      <Button layoutX="222.0" layoutY="149.0" mnemonicParsing="false" onAction="#ok" prefHeight="37.0" prefWidth="95.0" text="Save" />
      <Button layoutX="325.0" layoutY="149.0" mnemonicParsing="false" onAction="#cansel" prefHeight="37.0" prefWidth="95.0" text="Cansel" />
   </children>
</AnchorPane>
Cómo se ve la estructura de carpetas: Introducción a Java FX - 11Como puede ver, no hay nada especial, hay controladores que representan ciertas ventanas, hay modelos que representan nuestros datos. Echemos un vistazo a la clase que inicia la aplicación (implementación de la aplicación): @Data
public class AppFX extends Application {

    private Stage primaryStage;
    private AnchorPane rootLayout;
    private ObservableList listDog = FXCollections.observableArrayList();

    public AppFX() {
        listDog.add(new Dog("Fluffy", "Pug", 8, "Odessa", 2));
        listDog.add(new Dog("Archie", "Poodle", 3, "Lviv", 6));
        listDog.add(new Dog("Willie", "Bulldog", 5, "Kiev", 4));
        listDog.add(new Dog("Hector", "Shepherd", 9, "Minsk", 6));
        listDog.add(new Dog("Duncan", "Dachshund", 1, "Hogwarts", 9));
    }
Aquí vemos un constructor que completará nuestros datos iniciales (que almacenamos en una hoja especial: ObservableList).
public static void main(String[] args) {
        Application.launch();
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        this.primaryStage = primaryStage;
        this.primaryStage.setTitle("Dogs application");
        showBaseWindow();
}
Nada especial mainy la implementación start()que inicia la aplicación:
public void showBaseWindow() {
        try {
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(AppFX.class.getResource("/maket/rootWindow.fxml"));
            rootLayout = loader.load();
            Scene scene = new Scene(rootLayout);
            primaryStage.setScene(scene);
            InputStream iconStream = getClass().getResourceAsStream("/icons/someImage.png");
            Image image = new Image(iconStream);
            primaryStage.getIcons().add(image);
            BaseController controller = loader.getController();
            controller.setAppFX(this);
            primaryStage.show();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
Entonces, aquí vemos el método que realmente iniciamos start(), es decir, el que establece la configuración de nuestra ventana base. Como en el diseño xml en recursos: dándole un ícono, vinculándolo a un controlador específico y dándole al controlador un vínculo a thisla clase).
public void showCreateWindow(Dog dog) {
        try {
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(AppFX.class.getResource("/maket/new.fxml"));
            AnchorPane page = loader.load();
            Stage dialogStage = new Stage();
            dialogStage.setTitle("Wow Wow Wow");
            dialogStage.initModality(Modality.WINDOW_MODAL);
            dialogStage.initOwner(primaryStage);
            dialogStage.setScene(new Scene(page));
            CreateController controller = loader.getController();
            controller.setDialogStage(dialogStage);
            controller.setDog(dog);
            dialogStage.showAndWait();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
Aquí vemos el método responsable de la aparición de la segunda ventana: la ventana para crear un nuevo registro (el nombre de un nuevo perro). También configuramos el controlador, el diseño xml, el escenario, etc... La siguiente clase que consideraremos será un modelo que representa a nuestro perro (información al respecto): @Data
public class Dog {

    private StringProperty name;
    private StringProperty breed;
    private IntegerProperty age;
    private StringProperty city;
    private IntegerProperty levelOfTraining;

    public Dog(String name, String breed, int age, String city, int levelOfTraining) {
        this.name = new SimpleStringProperty(name);
        this.breed = new SimpleStringProperty(breed);
        this.age = new SimpleIntegerProperty(age);
        this.city = new SimpleStringProperty(city);
        this.levelOfTraining = new SimpleIntegerProperty(levelOfTraining);
    }

    public Dog() {
        name = new SimpleStringProperty();
        breed = null;
        age = null;
        city = null;
        levelOfTraining = null;
    }
}
Aquí vemos dos constructores: uno casi normal con todos los argumentos (casi, porque usamos envoltorios FX especiales de tipos simples) y un constructor sin argumentos: lo usamos al crear un nuevo perro, que al principio solo tiene un nombre. Controlador para ventana básica: @Data
public class BaseController {

    @FXML
    private TableView dogs;
    @FXML
    private TableColumn nameList;
    @FXML
    private TextField name;
    @FXML
    private TextField breed;
    @FXML
    private TextField age;
    @FXML
    private TextField city;
    @FXML
    private TextField levelOfTraining;
    private AppFX appFX;
Aquí vemos nuestros campos de objetos, pero en formato TextField. Este es un formato que representa un campo de entrada de texto. @FXML es una anotación diseñada para vincular el código Java y el objeto correspondiente de nuestro diseño (botón, campo u otra cosa).
@FXML
private void initialize() {
    nameList.setCellValueFactory(
            cellData -> cellData.getValue().getName());
    dogs.getSelectionModel().selectedItemProperty().addListener(
            (observable, oldValue, newValue) -> showDogsInformation(newValue));
}
Aquí vemos un método para mostrar nombres de perros, a la derecha de la lista (su anotación @FXML se vincula al componente de diseño JavaFX TableView).
public void setAppFX(AppFX appFX) {
    this.appFX = appFX;
    dogs.setItems(appFX.getListDog());
}

private void showDogsInformation(Dog dog) {
    if (dog != null) {
        name.setText(dog.getName() != null ? dog.getName().getValue() : null);
        breed.setText(dog.getBreed() != null ? dog.getBreed().getValue() : null);
        age.setText(dog.getAge() != null ? String.valueOf(dog.getAge().get()) : null);
        city.setText(dog.getCity() != null ? dog.getCity().getValue() : null);
        levelOfTraining.setText(dog.getLevelOfTraining() != null ? String.valueOf(dog.getLevelOfTraining().get()) : null);
    } else {
        name.setText("");
        breed.setText("");
        age.setText("");
        city.setText("");
        levelOfTraining.setText("");
    }
}
En el primer método vemos configurar una referencia interna a la clase que implementa la Aplicación (para que podamos llamar a su método para llamar a la segunda ventana) y configurar la lista inicial que se mostrará. El segundo comprueba si el perro actual tiene ciertos datos y, en base a esto, configura los campos de texto:
@FXML
    private void delete() {
        int selectedIndex = dogs.getSelectionModel().getSelectedIndex();
        dogs.getItems().remove(selectedIndex);
    }

    @FXML
    private void edit() {
        int selectedIndex = dogs.getSelectionModel().getSelectedIndex();
        dogs.getItems().set(selectedIndex, new Dog(name.getText(), breed.getText(), Integer.valueOf(age.getText()), city.getText(), Integer.valueOf(levelOfTraining.getText())));
    }

    @FXML
    private void create() {
        Dog someDog = new Dog();
        appFX.showCreateWindow(someDog);
        if (someDog.getName() != null && !someDog.getName().getValue().isEmpty()) {
            appFX.getListDog().add(someDog);
        }
    }
}
Aquí vemos tres métodos de la ventana base asociados a botones: Introducción a Java FX - 12
  • eliminar : eliminar el perro seleccionado (seleccionado) por índice;
  • editar : cree un nuevo perro con los datos transferidos y configúrelo en lugar del anterior;
  • crear : creamos un nuevo perro y llamamos al método de llamar a la ventana de creación, pasando un nuevo objeto y después de cerrarlo, si el nombre no es nulo, guardamos la nueva mascota.
Continuando, el controlador de ventana para crear el perro: @Data
public class CreateController {
    private Stage dialogStage;
    private Dog dog;

    @FXML
    private TextField nickName;

    @FXML
    private void ok() {
        if (nickName != null && !nickName.getText().isEmpty()) {
            dog.setName(new SimpleStringProperty(nickName.getText()));
            dialogStage.close();
        }
    }

    @FXML
    private void cansel() {
        dialogStage.close();
    }
}
Aquí vemos la conexión con el campo de texto en la ventana, procesando los botones Guardar y Cancelar, que de alguna manera cierran la ventana. Como puede ver, para mayor comodidad en mi pequeña aplicación, utilicé Lombok; de lo contrario, el código habría crecido mucho y no lo habría incluido en mi revisión. Probablemente eso sea todo lo que tengo por hoy. Hoy nos familiarizamos brevemente con los conceptos básicos y un ejemplo del uso de JavaFX, y podemos crear pequeñas aplicaciones de escritorio (utilizando información adicional, que, afortunadamente, abunda en Internet). Y a ti, a tu vez, te gusta))
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION