JavaRush /Blog Java /Random-PL /Wprowadzenie do Java FX

Wprowadzenie do Java FX

Opublikowano w grupie Random-PL
Któregoś dnia wpadłem na pomysł napisania małej aplikacji desktopowej na swoje potrzeby – coś w rodzaju małego słownika do nauki obcych słów – i zacząłem się głowić, jak mam to zrobić? Naturalnie, pierwszą rzeczą, która przyszła mi do głowy, był Swing. Zapewne każdy słyszał o Swingu . Jest to biblioteka służąca do tworzenia interfejsów graficznych użytkownika. Dzięki temu, że nasza ukochana Oracle nie porzuciła jeszcze całkowicie Swinga, nie uważa się go za przestarzały, a aplikacje nadal na nim działają. Jednak Swing nie jest już modernizowany, a ludzie z Oracle dali nam przedsmak przyszłości JavaFX. I tak naprawdę JavaFX wykorzystuje komponenty Swing jako dostawcę usług)

Co to jest JavaFX?

JavaFX to zasadniczo zestaw narzędzi GUI dla języka Java. Będzie tu mała dygresja i przypomnijmy sobie co to jest GUI : Graficzny interfejs użytkownika – graficzny interfejs użytkownika to rodzaj interfejsu użytkownika, w którym wszystkie elementy (przyciski, menu, ikony, listy) prezentowane użytkownikowi na stronie ekspozytory wykonane są w formie zdjęć, grafik. W przeciwieństwie do interfejsu wiersza poleceń, w GUI użytkownik ma losowy dostęp do widocznych obiektów za pomocą urządzeń wejściowych. Często elementy interfejsu są realizowane w formie metafor i prezentują swoje właściwości oraz cel, aby ułatwić zrozumienie użytkownika. JavaFX ma na celu tworzenie gier i aplikacji desktopowych w Javie. W rzeczywistości zastąpi Swing ze względu na proponowane nowe narzędzie GUI dla Java. Pozwala nam także stylizować pliki układu GUI (XML) i nadawać im bardziej elegancki wygląd za pomocą CSS, podobnie do tego, do czego jesteśmy przyzwyczajeni w aplikacjach internetowych. JavaFX dodatkowo obsługuje zintegrowaną grafikę 3D, a także audio, wideo i wbudowane aplikacje sieciowe w jednym zestawie narzędzi GUI... Jest łatwy do nauczenia i dobrze zoptymalizowany. Obsługuje wiele systemów operacyjnych, a także systemy Windows, UNIX i Mac OS. Wprowadzenie do Java FX - 3

Funkcje JavaFX:

  • JavaFX początkowo zawiera duży zestaw elementów interfejsu graficznego, takich jak wszelkiego rodzaju przyciski, pola tekstowe, tabele, drzewa, menu, wykresy itp., co z kolei pozwoli nam zaoszczędzić mnóstwo czasu.
  • JavaFX często korzysta ze stylów CSS i będziemy mogli użyć specjalnego formatu FXML do stworzenia GUI, zamiast robić to w kodzie Java. Ułatwia to szybkie rozplanowanie GUI lub zmianę wyglądu lub kompozycji bez konieczności długotrwałej zabawy z kodem Java.
  • JavaFX ma gotowe do użycia części diagramu, więc nie musimy pisać ich od zera za każdym razem, gdy potrzebujesz podstawowego diagramu.
  • JavaFX dodatkowo obsługuje grafikę 3D, co często jest przydatne, jeśli tworzymy jakąś grę lub podobne aplikacje.
Przyjrzyjmy się trochę głównym elementom naszego okna:
  • Scena to w zasadzie otaczające ją okno, które pełni rolę płótna początkowego i zawiera resztę komponentów. Aplikacja może mieć kilka etapów, ale w każdym przypadku musi istnieć jeden taki komponent. Zasadniczo Stage jest głównym kontenerem i punktem wejścia.
  • Scena - wyświetla zawartość sceny (jak lalka gniazdująca). Każdy etap może zawierać kilka komponentów - scenę, które można przełączać między sobą. Wewnętrznie jest to realizowane za pomocą wykresu obiektowego zwanego wykresem sceny (gdzie każdy element jest węzłem, zwanym także węzłem ).
  • Węzły to kontrolki, takie jak przyciski etykiet, a nawet układy, które mogą zawierać wiele zagnieżdżonych komponentów. Każda scena może mieć jeden zagnieżdżony węzeł, ale może to być układ z wieloma komponentami. Zagnieżdżanie może być wielopoziomowe, z układami zawierającymi inne układy i zwykłe komponenty. Każdy taki węzeł ma swój własny identyfikator, styl, efekty, stan i procedury obsługi zdarzeń.
Wprowadzenie do Java FX - 4 Przejdźmy więc trochę w stronę kodu. Ponieważ używam Java 8, nie muszę wyciągać żadnych zależności, ponieważ JavaFx jest domyślnie w JDK (jak w Javie 9.10), ale jeśli mamy Java 11+, to musimy przejść do repozytorium maven i wyciągnij go z zależności.

JavaFX: przykłady użycia

Tworzymy zwykłą klasę z metodą main(punktem wejścia):
public class AppFX extends Application {

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

    @Override
    public void start(Stage primaryStage) throws Exception {
pimarySatge.show();
    }
}
Tutaj nasza klasa dziedziczy po javafx.application.Application(którą mamy z pudełka Bugaga). W głównej mierze wywołujemy statyczną metodę Application, launch()aby uruchomić nasze okno. Ponadto nasz pomysł będzie narzekał, że nie zaimplementowaliśmy metody aplikacji, startco ostatecznie robimy. Po co to jest? Oraz po to, aby móc zarządzać właściwościami (funkcjonalnością naszego okna). Aby to zrobić, używamy przychodzącego argumentu, primaryStagena podstawie którego wywołujemy metodę show, abyśmy mogli zobaczyć uruchamiające się okno w main. Wypełnijmy trochę naszą metodę 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();
}
Co więc tutaj widzimy? Przeanalizujmy to linia po linii: 2 - ustaw nazwę samego okna (sceny) 3.4 - ustaw jego wymiary 6.7 - ustaw ścieżkę strumienia odczytu do pliku (ikona) Wprowadzenie do Java FX - 58 - utwórz plik jako obiekt Obraz, który jest połączony z rzeczywistym plikiem poprzez strumień przekazywany w konstruktorze 9 - ustaw ikonę w górnym panelu okna 11 - utwórz obiekt przycisku 13-16 - ustaw reakcję po naciśnięciu przycisku 17 - utwórz scenę, w której umieszczamy nasz przycisk 18 - umieszczamy scenę na naszym wspólnym oknie 20 - ustawiamy flagę widoczności dla okna I w efekcie otrzymujemy małe okienko, w którym witamy nasze ulubione pesele: Wprowadzenie do Java FX - 6Wszystko wygląda o wiele prościej niż Swing, prawda? Ale to jeszcze nie koniec. Nie jest dobrze pisać całego kodu wyświetlającego aplikację, trzeba to jakoś podzielić, żeby był bardziej zrozumiały (elementy graficzne w jednym koszyku, logika w drugim). I tutaj xml pojawia się na obrazku... O mój Boże, XML? Dokładnie. Konkretnie wykorzystujemy jego specyficzną implementację dla JavaFX - FXML, w której definiujemy elementy graficzne aplikacji i ich właściwości (wszelkiego rodzaju rozmiary itp.), a następnie podłączamy ją do kontrolera, który pomaga zarządzać logiką. Spójrzmy na przykład tego pliku 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 - język skryptowy, którego używamy 4-6 - importowane dane 8-9 Vbox - kontener umieszczający podkomponenty w jednej linii. 11 - wyświetl jakiś tekst 13 - przycisk, po kliknięciu korzystamy z metody opisanej w skrypcie w liniach 15-18. W metodzie powinien znajdować się kod wywołujący ten plik xml start, ale teraz nie jest to aż tak istotne i my pominie go (poniżej będzie przykład ściągnięcia tego pliku). Zatem XML jest oczywiście dobry (ale niezbyt dobry), pisanie go ręcznie jest bardzo mylące, czy to nie ostatnie stulecie? Wprowadzenie do Java FX - 7

Przedstawiamy kreatora scen JavaFX

Właśnie w tym momencie wchodzi w grę (bęben) - SceneBuilder w JavaFX Scene Builder jest narzędziem, za pomocą którego możemy zaprojektować nasze okna w postaci interfejsu graficznego, a następnie je zapisać, a ten program na podstawie wyniku skonstruuj pliki XML, które będziemy ulepszać w naszej aplikacji. Interfejs tego kreatora fmxl wygląda mniej więcej tak: Wprowadzenie do Java FX - 8

Mała dygresja. Lekcje JavaFX

Pominę szczegóły instalacji i szczegółowe omówienie tego narzędzia. Są to tematy warte głębszego zgłębienia. Dlatego nadal pozostawię kilka ciekawych linków do lekcji JavaFX: jeden (samouczek online dotyczący JavaFX) i dwa (kolejny dobry tutorial). Przeanalizujmy mały przykład, który naszkicowałem. Ostatecznie wyszło mi coś takiego: Wprowadzenie do Java FX - 9
(coś w rodzaju okna do rejestracji psów)
Kiedy wybierzesz psa i naciśniesz przycisk Usuń, pies zostanie usunięty z naszej listy. Po wybraniu czworonożnego przyjaciela i zmianie jego pól, a następnie naciśnięciu przycisku Edytuj, informacje o psie zostaną zaktualizowane. Po naciśnięciu przycisku Nowy wyskakuje okno umożliwiające utworzenie rekordu dla nowego psa (zaczynając od jego imienia): Wprowadzenie do Java FX - 10Następnie kliknij Zapisz i w pierwszym oknie uzupełnij pozostałe pola, a następnie kliknij przycisk Edytuj, aby ratować. Brzmi łatwo, prawda? Zobaczmy jak to będzie wyglądać w naszej aplikacji Java. Na początek zostawię tutaj układy XML dla tych dwóch okien wygenerowanych w SceneBuilder: Pierwszy (podstawowy):
<?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>
Po drugie (aby stworzyć nowe pieski):
<?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>
Jak wygląda struktura folderów: Wprowadzenie do Java FX - 11Jak widać nie ma w tym nic specjalnego, są kontrolery, które reprezentują określone okna, są modele, które reprezentują nasze dane. Przyjrzyjmy się klasie uruchamiającej aplikację (Implementacja aplikacji): @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));
    }
Widzimy tutaj konstruktora, który uzupełni nasze dane początkowe (które przechowujemy w specjalnym arkuszu - 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();
}
Nic specjalnego - maini implementacja start()uruchamiająca aplikację:
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();
        }
    }
Zatem tutaj widzimy metodę, którą faktycznie uruchamiamy start(), a mianowicie tę, która ustawia ustawienia naszego okna podstawowego. Tak jak w układzie xml w zasobach: nadanie mu ikony, połączenie go z konkretnym kontrolerem i nadanie kontrolerowi łącza do thisklasy)
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();
        }
    }
}
Widzimy tu metodę odpowiedzialną za pojawienie się drugiego okna - okna umożliwiającego utworzenie nowego rekordu (imię nowego psa). Ustawiamy także kontroler, układ XML, scenę itp. Następną klasą, którą rozważymy będzie model przedstawiający naszego psa (informacje na jego temat): @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;
    }
}
Widzimy tutaj dwa konstruktory: jeden prawie zwykły ze wszystkimi argumentami (prawie, bo używamy specjalnych opakowań FX prostych typów) i konstruktor bez argumentów: używamy go podczas tworzenia nowego psa, który na początku ma tylko nazwa. Kontroler dla okna podstawowego: @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;
Tutaj widzimy nasze pola obiektowe, ale w formacie TextField. Jest to format reprezentujący pole wprowadzania tekstu. @FXML to adnotacja zaprojektowana w celu połączenia kodu Java z odpowiednim obiektem naszego układu (przyciskiem, polem lub czymś innym).
@FXML
private void initialize() {
    nameList.setCellValueFactory(
            cellData -> cellData.getValue().getName());
    dogs.getSelectionModel().selectedItemProperty().addListener(
            (observable, oldValue, newValue) -> showDogsInformation(newValue));
}
Tutaj widzimy metodę wyświetlania imion psów po prawej stronie listy (adnotacja @FXML jest powiązana z komponentem układu 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("");
    }
}
W pierwszej metodzie widzimy ustawienie wewnętrznego odwołania do klasy implementującej Application (abyśmy mogli wywołać jej metodę w celu wywołania drugiego okna) oraz ustawienie początkowej listy do wyświetlenia. Drugi sprawdza, czy aktualny pies posiada określone dane i na tej podstawie ustawia pola tekstowe:
@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);
        }
    }
}
Tutaj widzimy trzy metody okna bazowego powiązane z przyciskami: Wprowadzenie do Java FX - 12
  • usuń — usuń wybranego (wybranego) psa według indeksu;
  • edit - utwórz nowego psa z przesłanych danych i ustaw go zamiast poprzedniego;
  • create - tworzymy nowego psa i wywołujemy metodę wywołując okno tworzenia, przekazując nowy obiekt i po zamknięciu którego, jeśli nazwa nie jest null, to zapisujemy nowego zwierzaka.
Idąc dalej, kontroler okna do tworzenia psa: @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();
    }
}
Tutaj widzimy połączenie z polem tekstowym w oknie, przetwarzając przyciski Zapisz i Anuluj, które w jakiś sposób zamykają okno. Jak widać dla większej wygody w mojej małej aplikacji użyłem Lomboka, inaczej kod by się bardzo rozrósł i nie zmieściłbym go w mojej recenzji. To chyba wszystko co mam na dzisiaj. Dzisiaj pokrótce zapoznaliśmy się z podstawowymi pojęciami i przykładem wykorzystania JavaFX, a także możemy budować małe aplikacje desktopowe (wykorzystując dodatkowe informacje, których na szczęście jest mnóstwo w Internecie). A ty z kolei lubisz))
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION