JavaRush /مدونة جافا /Random-AR /مقدمة إلى جافا FX

مقدمة إلى جافا FX

نشرت في المجموعة
في أحد الأيام خطرت ببالي فكرة كتابة تطبيق مكتبي صغير لتلبية احتياجاتي - مثل قاموس صغير لتعلم الكلمات الأجنبية - وبدأت في إثارة ذهني، كيف يمكنني أن أفعل هذا؟ وبطبيعة الحال، أول ما يتبادر إلى ذهني هو التأرجح. ربما سمع الجميع عن سوينغ . هذه مكتبة لإنشاء واجهات المستخدم الرسومية. نظرًا لحقيقة أن Oracle المفضلة لدينا لم تتخل تمامًا عن Swing، فهي لا تعتبر قديمة، ولا تزال التطبيقات تعمل عليها. ومع ذلك، لم يعد يتم تحديثها بواسطة Swing، وقد أعطانا العاملون في Oracle لمحة عن مستقبل JavaFX. وفي الواقع، تستخدم JavaFX مكونات Swing كمزود خدمة)

ما هو جافا اف اكس؟

JavaFX هي في الأساس مجموعة أدوات واجهة المستخدم الرسومية لـ Java. سيكون هناك استطراد صغير هنا، وسوف نتذكر ما هي واجهة المستخدم الرسومية : واجهة المستخدم الرسومية - واجهة المستخدم الرسومية هي نوع من واجهة المستخدم التي يتم فيها تقديم جميع العناصر (الأزرار، القوائم، الرموز، القوائم) للمستخدم على يتم العرض على شكل صور ورسومات. على عكس واجهة سطر الأوامر، في واجهة المستخدم الرسومية، يتمتع المستخدم بوصول عشوائي إلى الكائنات المرئية باستخدام أجهزة الإدخال. في كثير من الأحيان، يتم تنفيذ عناصر الواجهة في شكل استعارات وعرض خصائصها والغرض منها لتسهيل فهم المستخدم. يهدف JavaFX إلى إنشاء ألعاب وتطبيقات سطح المكتب في Java. في الواقع، سيحل محل Swing بسبب أداة واجهة المستخدم الرسومية الجديدة المقترحة لـ Java. كما أنه يسمح لنا بتصميم ملفات تخطيط واجهة المستخدم الرسومية (XML) وجعلها أكثر أناقة باستخدام CSS، على غرار ما اعتدنا عليه في تطبيقات الويب. يتعامل JavaFX بالإضافة إلى ذلك مع الرسومات ثلاثية الأبعاد المدمجة بالإضافة إلى تطبيقات الصوت والفيديو والشبكات المدمجة في مجموعة أدوات واحدة لواجهة المستخدم الرسومية... إنه سهل التعلم ومُحسّن بشكل جيد. وهو يدعم العديد من أنظمة التشغيل، بالإضافة إلى أنظمة Windows وأنظمة UNIX وMac OS. مقدمة إلى Java FX - 3

مميزات جافا اف اكس:

  • يأتي JavaFX في البداية مع مجموعة كبيرة من أجزاء الواجهة الرسومية، مثل جميع أنواع الأزرار، وحقول النص، والجداول، والأشجار، والقوائم، والمخططات، وما إلى ذلك، والتي بدورها ستوفر لنا الكثير من الوقت.
  • يستخدم JavaFX في كثير من الأحيان أنماط CSS، وسنكون قادرين على استخدام تنسيق FXML خاص لإنشاء واجهة المستخدم الرسومية، بدلاً من القيام بذلك في كود Java. وهذا يجعل من السهل تصميم واجهة المستخدم الرسومية بسرعة أو تغيير المظهر أو التكوين دون الحاجة إلى التلاعب بكود Java.
  • تحتوي JavaFX على أجزاء رسم تخطيطي جاهزة للاستخدام، لذا لا يتعين علينا كتابتها من الصفر في أي وقت تحتاج فيه إلى رسم تخطيطي أساسي.
  • بالإضافة إلى ذلك، يأتي JavaFX مزودًا بدعم الرسومات ثلاثية الأبعاد، وهو ما يكون مفيدًا غالبًا إذا كنا نقوم بتطوير نوع ما من الألعاب أو التطبيقات المشابهة.
دعونا نلقي نظرة سريعة على المكونات الرئيسية لنافذتنا:
  • المسرح هو في الأساس نافذة محيطة تعمل بمثابة لوحة بداية وتحتوي على بقية المكونات. يمكن أن يتكون التطبيق من عدة مراحل، ولكن على أية حال يجب أن يكون هناك مكون واحد من هذا القبيل. في الأساس، المرحلة هي الحاوية الرئيسية ونقطة الدخول.
  • المشهد - يعرض محتويات المسرح (مثل دمية التعشيش). يمكن أن تحتوي كل مرحلة على عدة مكونات - المشهد، والتي يمكن تبديلها فيما بينها. داخليًا، يتم تنفيذ ذلك من خلال رسم بياني للكائن يسمى الرسم البياني للمشهد (حيث يكون كل عنصر عبارة عن عقدة، وتسمى أيضًا العقدة ).
  • العقد هي عناصر تحكم، مثل أزرار التسمية، أو حتى التخطيطات، والتي يمكن أن تحتوي على مكونات متداخلة متعددة بداخلها. يمكن أن يحتوي كل مشهد على عقدة متداخلة واحدة، ولكن يمكن أن يكون تخطيطًا يحتوي على مكونات متعددة. يمكن أن يكون التداخل متعدد المستويات، حيث تحتوي التخطيطات على تخطيطات أخرى ومكونات عادية. كل عقدة لها معرفها ونمطها وتأثيراتها وحالتها ومعالجات الأحداث الخاصة بها.
مقدمة إلى 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 - قم بإنشاء الملف ككائن صورة، المتصل بالملف الحقيقي عن طريق الدفق الذي تم تمريره في المنشئ 9 - تعيين رمز في اللوحة العلوية للنافذة 11 - إنشاء كائن زر 13-16 - ضبط التفاعل عند الضغط على الزر 17 - إنشاء مشهد حيث نضع زرنا 18 - نضع المشهد على نافذتنا المشتركة 20 - نضبط علامة الرؤية للنافذة ونتيجة لذلك نحصل على نافذة صغيرة للترحيب بأغانينا المفضلة: مقدمة إلى Java FX - 6كل شيء يبدو أبسط بكثير من Swing، أليس كذلك؟ لكن الأمر لم ينته بعد. ليس من الجيد كتابة كل التعليمات البرمجية لعرض تطبيق ما، فأنت بحاجة إلى تقسيمها بطريقة ما لجعلها أكثر قابلية للفهم (المكونات الرسومية في سلة واحدة، والمكونات المنطقية في سلة أخرى). وهنا يأتي ملف 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

عند هذه النقطة يأتي دور (قرع الطبل) - SceneBuilder في JavaFX Scene Builder هي أداة يمكننا من خلالها تصميم نوافذنا على شكل واجهة رسومية ثم حفظها، وهذا البرنامج، بناءً على النتيجة، سوف إنشاء ملفات xml التي سنقوم بتحسينها في تطبيقنا. تبدو واجهة منشئ fmxl كما يلي: مقدمة إلى Java FX - 8

انحراف صغير. دروس جافا اف اكس

سأتخطى تفاصيل التثبيت والدراسة التفصيلية لهذه الأداة أيضًا. هذه مواضيع تستحق الاستكشاف أكثر. لذلك، سأظل أترك رابطين مثيرين للاهتمام لدروس JavaFX: أحدهما (برنامج تعليمي عبر الإنترنت حول JavaFX) واثنان ( برنامج تعليمي جيد آخر). دعونا نستعرض مثالًا صغيرًا رسمته. في النهاية حصلت على شيء مثل: مقدمة إلى Java FX - 9
(نوعًا ما مثل نافذة لتسجيل الكلاب)
عند تحديد كلب والضغط على زر الحذف، تتم إزالة الكلب من قائمتنا. عند تحديد صديق ذو أربعة أرجل وتغيير حقوله، وبعد الضغط على زر تحرير، يتم تحديث معلومات الكلب. عندما نضغط على الزر جديد، تظهر نافذة لإنشاء سجل لكلب جديد (ليبدأ باسمه): مقدمة إلى 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("");
    }
}
في الطريقة الأولى نرى تعيين مرجع داخلي للفئة التي تنفذ التطبيق (حتى نتمكن من استدعاء طريقتها لاستدعاء النافذة الثانية)، وتعيين القائمة الأولية التي سيتم عرضها. والثاني يتحقق مما إذا كان الكلب الحالي لديه بيانات معينة، وبناء على ذلك يقوم بتعيين حقول النص:
@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
  • حذف - حذف الكلب المحدد (المحدد) حسب الفهرس؛
  • تحرير - إنشاء كلب جديد بالبيانات المنقولة، وتعيينه بدلاً من الذي كان من قبل؛
  • إنشاء - نقوم بإنشاء كلب جديد واستدعاء طريقة استدعاء نافذة الإنشاء، وتمرير كائن جديد، وبعد إغلاقه، إذا لم يكن الاسم فارغًا، فقم بحفظ الحيوان الأليف الجديد.
لننتقل إلى وحدة التحكم في النافذة لإنشاء الكلب: @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();
    }
}
هنا نرى الاتصال بحقل النص في النافذة، ومعالجة أزرار الحفظ والإلغاء، التي تغلق النافذة بطريقة ما. كما ترون، لمزيد من الراحة في تطبيقي الصغير، استخدمت Lombok، وإلا لكان الكود قد زاد كثيرًا، ولم أكن لأضعه في مراجعتي. ربما هذا هو كل ما لدي لهذا اليوم. تعرفنا اليوم لفترة وجيزة على المفاهيم الأساسية ومثال لاستخدام JavaFX، ويمكننا بناء تطبيقات سطح مكتب صغيرة (باستخدام معلومات إضافية، والتي، لحسن الحظ، وفيرة على الإنترنت). وأنت، بدوره، مثل))
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION