JavaRush /בלוג Java /Random-HE /מבוא ל-Java FX

מבוא ל-Java FX

פורסם בקבוצה
יום אחד עלה לי רעיון לכתוב יישום שולחן עבודה קטן לצרכים שלי - משהו כמו מילון קטן ללימוד מילים לועזיות - והתחלתי לעצבן את המוח שלי, איך אני יכול לעשות את זה? באופן טבעי, הדבר הראשון שעלה לי בראש היה סווינג. כולם בטח שמעו על סווינג . זוהי ספרייה ליצירת ממשקים גרפיים למשתמש. בשל העובדה שאורקל האהובה שלנו עדיין לא נטשה לחלוטין את Swing, היא לא נחשבת למיושנת, ואפליקציות עדיין רצות עליה. עם זאת, זה כבר לא עובר מודרניזציה על ידי Swing, ואנשי Oracle נתנו לנו טעימה מה העתיד של JavaFX. ולמעשה, JavaFX משתמש ברכיבי Swing כספק שירות)

מה זה JavaFX?

JavaFX הוא בעצם ערכת כלים GUI עבור Java. תהיה כאן סטייה קטנה, ונזכור מה זה GUI : ממשק משתמש גרפי - ממשק משתמש גרפי הוא סוג של ממשק משתמש בו כל האלמנטים (כפתורים, תפריטים, אייקונים, רשימות) מוצגים למשתמש ב- התצוגה נעשית בצורה של תמונות, גרפיקה. שלא כמו ממשק שורת פקודה, ב-GUI למשתמש יש גישה אקראית לאובייקטים גלויים באמצעות התקני קלט. לעתים קרובות, רכיבי ממשק מיושמים בצורה של מטפורות ומציגים את תכונותיהם ומטרתם כדי להקל על הבנת המשתמש. JavaFX מכוון ליצירת משחקים ויישומי שולחן עבודה ב-Java. למעשה, הוא יחליף את Swing בשל כלי ה-GUI החדש המוצע עבור Java. זה גם מאפשר לנו לעצב קבצי פריסת GUI (XML) ולהפוך אותם לאלגנטיים יותר באמצעות CSS, בדומה למה שהורגלנו אליו ביישומי אינטרנט. JavaFX מטפל בנוסף בגרפיקה תלת-ממדית משולבת וכן ביישומי אודיו, וידאו ויישומי רשת משובצים בערכת כלים יחידה של ממשק משתמש משתמש... קל ללמוד ומותאם היטב. הוא תומך במערכות הפעלה רבות, כמו גם במערכות Windows, UNIX ו-Mac OS. מבוא ל-Java FX - 3

תכונות JavaFX:

  • JavaFX מגיע בהתחלה עם סט גדול של חלקי ממשק גרפי, כמו כל מיני כפתורים, שדות טקסט, טבלאות, עצים, תפריטים, תרשימים וכו', שבתורם יחסכו לנו הרבה זמן.
  • JavaFX משתמש לעתים קרובות בסגנונות CSS, ונוכל להשתמש בפורמט FXML מיוחד כדי ליצור את ה-GUI, במקום לעשות זאת בקוד Java. זה מקל על פריסה מהירה של ממשק משתמש (GUI) או לשנות את המראה או ההרכב מבלי שתצטרך לשחק עם קוד Java.
  • ל-JavaFX יש חלקי דיאגרמה מוכנים לשימוש כך שלא נצטרך לכתוב אותם מאפס בכל פעם שאתה צריך דיאגרמה בסיסית.
  • JavaFX מגיע בנוסף עם תמיכה בגרפיקה תלת מימדית, שלעתים קרובות שימושית אם אנו מפתחים סוג של משחק או יישומים דומים.
בואו נסתכל קצת על המרכיבים העיקריים של החלון שלנו:
  • הבמה היא בעצם חלון שמסביב שפועל כקנבס התחלתי ומכיל את שאר הרכיבים. אפליקציה יכולה לכלול כמה שלבים, אבל בכל מקרה חייב להיות רכיב אחד כזה. בעיקרו של דבר, Stage הוא המיכל ונקודת הכניסה הראשית.
  • סצנה - מציגה את תוכן הבמה (כמו בובת קינון). כל שלב יכול להכיל מספר מרכיבים - סצנה, שניתן להחליף בינם לבין עצמם. באופן פנימי, זה מיושם על ידי גרף אובייקטים הנקרא Scene Graph (כאשר כל אלמנט הוא צומת, הנקרא גם Node ).
  • צמתים הם פקדים, כגון לחצני תוויות, או אפילו פריסות, שיכולים לכלול בתוכם מספר רכיבים מקוננים. לכל סצנה יכול להיות צומת מקונן אחד, אבל זה יכול להיות פריסה עם מספר רכיבים. קינון יכול להיות רב רמות, כאשר פריסות מכילות פריסות אחרות ורכיבים רגילים. לכל צומת כזה יש מזהה, סגנון, אפקטים, מצב ומטפלים משלו.
מבוא ל-Java FX - 4 אז בואו נתקדם קצת לכיוון הקוד. מכיוון שאני משתמש ב-Java 8, אני לא צריך להעלות תלות כלשהי, מכיוון ש-JavaFx נמצא ב-JDK כברירת מחדל (כמו ב-Java 9.10), אבל אם יש לנו Java 11+, אז אנחנו צריכים ללכת למאגר של maven. למשוך את זה משם תלות.

JavaFX: דוגמאות לשימוש

אנו יוצרים מחלקה רגילה עם שיטה main(נקודת כניסה):
public class AppFX extends Application {

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

    @Override
    public void start(Stage primaryStage) throws Exception {
pimarySatge.show();
    }
}
כאן הכיתה שלנו יורשת ממנה javafx.application.Application(שיש לנו מקופסת הבוגגה). בעיקרון אנו קוראים לשיטת היישום הסטטית launch()כדי להפעיל את החלון שלנו. כמו כן, הרעיון שלנו יתלונן שלא יישמנו את שיטת היישום, startוזה מה שאנחנו עושים בסופו של דבר. לשם מה זה? ועל מנת להיות מסוגל לנהל את המאפיינים (הפונקציונליות של החלון שלנו). לשם כך, אנו משתמשים בארגומנט נכנס primaryStageשבו אנו קוראים שיטה showכדי שנוכל לראות את החלון מופעל ב main. בואו נמלא מעט את השיטה שלנו 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();
}
אז מה אנחנו רואים כאן? נעבור על זה שורה אחר שורה: 2 - קבע את שם החלון עצמו (שלב) 3.4 - קבע את מידותיו 6.7 - קבע את הנתיב של זרם הקריאה לקובץ (אייקון) מבוא ל-Java FX - 58 - צור את הקובץ כאובייקט Image, שמחובר לקובץ האמיתי על ידי הזרם שעבר בקונסטרוקטור 9 - קבע אייקון בפאנל העליון של חלון 11 - צור אובייקט כפתור 13-16 - קבע את התגובה כאשר הכפתור נלחץ 17 - צור סצנה שבה אנחנו מניחים את הכפתור 18 שלנו - מניחים את הסצנה על החלון המשותף שלנו 20 - מגדירים את דגל הנראות של החלון וכתוצאה מכך אנחנו מקבלים חלון קטן כדי לקבל את פני הפזלות האהובות עלינו: מבוא ל-Java FX - 6הכל נראה הרבה יותר פשוט מ-Swing, לא? אבל זה עוד לא נגמר. זה לא טוב לכתוב את כל הקוד כדי להציג אפליקציה, צריך לחלק אותו איכשהו כדי שיהיה מובן יותר (רכיבים גרפיים בסל אחד, היגיון באחר). והנה ה-xml נכנס לתמונה... אלוהים אדירים, xml? בְּדִיוּק. באופן ספציפי, אנו משתמשים ביישום הספציפי שלו עבור JavaFX - FXML, בו אנו מגדירים את הרכיבים הגרפיים של האפליקציה והמאפיינים שלהם (כל מיני גדלים וכו'), ולאחר מכן מחברים אותם לבקר, שעוזר בניהול ההיגיון. בואו נסתכל על דוגמה ל-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 - שפת הסקריפט בה אנו משתמשים 4-6 - נתונים מיובאים 8-9 Vbox - קונטיינר שמציב רכיבי משנה בשורה אחת. 11 - הצג קצת טקסט 13 - כפתור, בלחיצה, אנו משתמשים בשיטה המתוארת בסקריפט בשורות 15-18. צריך להיות קוד לקריאה לקובץ xml זה בשיטה start, אבל עכשיו זה לא כל כך חשוב, ואנחנו ישמיט אותו (למטה תהיה דוגמה למשיכת קובץ זה). אז, xml זה, כמובן, טוב (אך לא טוב מאוד), כתיבה ידנית מאוד מבלבלת, האם זו לא המאה האחרונה? מבוא ל-Java FX - 7

היכרות עם JavaFX SceneBuilder

בנקודה זו נכנס לפעולה (דrum roll) - SceneBuilder ב-JavaFX Scene Builder הוא כלי שבעזרתו נוכל לעצב את החלונות שלנו בצורה של ממשק גרפי ואז לשמור אותם, והתוכנה הזו, על סמך התוצאה, לבנות קבצי xml שאנו נשפר אותם באפליקציה שלנו. הממשק של בונה fmxl זה נראה בערך כך: מבוא ל-Java FX - 8

סטייה קטנה. שיעורי JavaFX

אדלג על פרטי ההתקנה, וגם על מחקר מפורט של הכלי הזה. אלו נושאים שכדאי לחקור עוד יותר. לכן, אני עדיין אשאיר כמה קישורים מעניינים לשיעורי JavaFX: אחד (מדריך מקוון על JavaFX) ושניים ( עוד מדריך טוב). בוא נעבור על דוגמה קטנה ששרטטתי. בסוף קיבלתי משהו כמו: מבוא ל-Java FX - 9
(בערך כמו חלון לרישום כלבים)
כאשר אתה בוחר כלב ולחץ על כפתור Delete, הכלב מוסר מהרשימה שלנו. כאשר אתה בוחר חבר בעל ארבע רגליים ומשנה את השדות שלו, ולאחר לחיצה על כפתור העריכה, המידע של הכלב מתעדכן. כאשר אנו לוחצים על כפתור חדש, קופץ חלון ליצירת רשומה עבור כלב חדש (כדי להתחיל בשמו): מבוא ל-Java FX - 10לאחר מכן לחץ על שמור ומלא את שאר השדות שלו בחלון הראשון, ולאחר מכן לחץ על כפתור ערוך כדי להציל. נשמע קל, נכון? בוא נראה איך זה ייראה באפליקציית Java שלנו. מלכתחילה, אני רק אשאיר כאן את פריסות ה-xml עבור שני החלונות הללו שנוצרו ב SceneBuilder: ראשית (בסיסי):
<?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>
שנית (כדי ליצור כלבלבים חדשים):
<?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>
איך נראה מבנה התיקיות: מבוא ל-Java FX - 11כפי שאתה יכול לראות, אין שום דבר מיוחד, יש בקרים שמייצגים חלונות מסוימים, יש מודלים שמייצגים את הנתונים שלנו. בואו נסתכל על המחלקה שמפעילה את האפליקציה (יישום יישום): @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));
    }
כאן אנו רואים קונסטרוקטור שימלא את הנתונים הראשוניים שלנו (שאנו מאחסנים בגיליון מיוחד - 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();
}
שום דבר מיוחד - mainוהיישום start()שמפעיל את האפליקציה:
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();
        }
    }
אז, כאן אנו רואים את השיטה שאנו משיקים למעשה ב- start(), כלומר, זו שקובעת את ההגדרות של חלון הבסיס שלנו. כמו בפריסת ה-xml במשאבים: מתן אייקון, קישור לבקר ספציפי ומתן לבקר קישור למחלקה this)
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();
        }
    }
}
כאן אנו רואים את השיטה שאחראית על הופעת החלון השני – החלון ליצירת רשומה חדשה (שם של כלב חדש). אנחנו גם מגדירים את הבקר, פריסת ה-xml, הבמה וכו'... השיעור הבא שנשקול יהיה דגם המייצג את הכלב שלנו (מידע עליו): @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;
    }
}
כאן אנו רואים שני בנאים, אחד הוא כמעט רגיל עם כל הארגומנטים (כמעט, כי אנחנו משתמשים בעטיפות FX מיוחדות מסוגים פשוטים) ובנאי ללא ארגומנטים: אנחנו משתמשים בו כשיוצרים כלב חדש, שבהתחלה יש לו רק שֵׁם. בקר לחלון בסיסי: @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;
כאן אנו רואים את שדות האובייקט שלנו, אבל בפורמט TextField. זהו פורמט המייצג שדה קלט טקסט. @FXML הוא הערה שנועדה לקשר את קוד Java והאובייקט המתאים של הפריסה שלנו (כפתור, שדה או משהו אחר).
@FXML
private void initialize() {
    nameList.setCellValueFactory(
            cellData -> cellData.getValue().getName());
    dogs.getSelectionModel().selectedItemProperty().addListener(
            (observable, oldValue, newValue) -> showDogsInformation(newValue));
}
כאן אנו רואים שיטה להצגת שמות כלבים, בצד ימין ברשימה (ביאור ה-@FXML שלו נקשר לרכיב פריסת 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("");
    }
}
בשיטה הראשונה אנו רואים הגדרת הפניה פנימית למחלקה המיישמת Application (כדי שנוכל לקרוא למתודה שלה לקרוא לחלון השני), והגדרת הרשימה הראשונית שתוצג. השני בודק אם לכלב הנוכחי יש נתונים מסוימים, ועל סמך זה מגדיר את שדות הטקסט:
@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);
        }
    }
}
כאן אנו רואים שלוש שיטות של חלון הבסיס המשויך ללחצנים: מבוא ל-Java FX - 12
  • מחק - מחק את הכלב הנבחר (הנבחר) לפי אינדקס;
  • ערוך - צור כלב חדש עם הנתונים המועברים, והגדר אותו במקום זה שהיה קודם;
  • create - אנו יוצרים כלב חדש וקוראים לשיטת הקריאה לחלון היצירה, העברת אובייקט חדש, ולאחר סגירה אשר, אם השם אינו ריק, אז שומרים את חיית המחמד החדשה.
ממשיכים הלאה, בקר החלון ליצירת הכלב: @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();
    }
}
כאן אנו רואים את הקשר עם שדה הטקסט בחלון, עיבוד לחצני שמור וביטול, שסוגרים איכשהו את החלון. כפי שאתה יכול לראות, לנוחות רבה יותר באפליקציה הקטנה שלי, השתמשתי בלומבוק, אחרת הקוד היה גדל מאוד, ולא הייתי מתאים אותו לסקירה שלי. זה כנראה כל מה שיש לי להיום. היום הכרנו בקצרה את המושגים הבסיסיים ודוגמה לשימוש ב-JavaFX, ונוכל לבנות אפליקציות שולחן עבודה קטנות (באמצעות מידע נוסף, שלמרבה המזל, יש בשפע באינטרנט). ואתה, בתורו, אוהב))
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION