JavaRush /وبلاگ جاوا /Random-FA /مقدمه ای بر Java FX

مقدمه ای بر Java FX

در گروه منتشر شد
یک روز به این فکر افتادم که برای نیازهایم یک برنامه دسکتاپ کوچک بنویسم - چیزی شبیه یک دیکشنری کوچک برای یادگیری لغات خارجی - و شروع به تکان دادن مغزم کردم، چگونه می توانم این کار را انجام دهم؟ طبیعتا اولین چیزی که به ذهنم رسید Swing بود. احتمالا همه نام Swing را شنیده اند . این یک کتابخانه برای ایجاد رابط های کاربری و گرافیکی است. با توجه به اینکه اوراکل محبوب ما هنوز Swing را به طور کامل رها نکرده است، منسوخ تلقی نمی شود و برنامه ها همچنان روی آن اجرا می شوند. با این حال، دیگر توسط Swing مدرن نمی‌شود و افراد Oracle به ما طعم آینده JavaFX را داده‌اند. و در واقع، JavaFX از اجزای Swing به عنوان ارائه دهنده خدمات استفاده می کند.

JavaFX چیست؟

JavaFX در اصل یک جعبه ابزار رابط کاربری گرافیکی برای جاوا است. یک انحراف کوچک در اینجا وجود خواهد داشت و ما به یاد خواهیم آورد که رابط کاربری گرافیکی چیست : رابط کاربری گرافیکی - رابط کاربری گرافیکی نوعی از رابط کاربری است که در آن همه عناصر (دکمه ها، منوها، نمادها، لیست ها) به کاربر ارائه می شود. نمایش در قالب تصاویر، گرافیک ساخته شده است. برخلاف رابط خط فرمان، در رابط کاربری گرافیکی کاربر با استفاده از دستگاه های ورودی به اشیاء قابل مشاهده دسترسی تصادفی دارد. اغلب، عناصر رابط در قالب استعاره پیاده سازی می شوند و ویژگی ها و هدف خود را برای تسهیل درک کاربر نشان می دهند. JavaFX با هدف ایجاد بازی ها و برنامه های دسکتاپ در جاوا است. در واقع، به دلیل ابزار جدید رابط کاربری گرافیکی پیشنهادی برای جاوا، جایگزین Swing خواهد شد. همچنین، به ما اجازه می‌دهد تا به فایل‌های طرح‌بندی رابط کاربری گرافیکی (XML) استایل دهیم و با استفاده از CSS، شبیه به آنچه در برنامه‌های کاربردی وب به آن عادت داریم، آن‌ها را زیباتر کنیم. JavaFX علاوه بر این، گرافیک های سه بعدی یکپارچه و همچنین صدا، تصویر و برنامه های شبکه جاسازی شده را در یک جعبه ابزار رابط کاربری گرافیکی مدیریت می کند... یادگیری آن آسان است و به خوبی بهینه شده است. این برنامه از بسیاری از سیستم عامل ها و همچنین سیستم های ویندوز، یونیکس و سیستم عامل مک پشتیبانی می کند. مقدمه ای بر Java FX - 3

ویژگی های JavaFX:

  • JavaFX در ابتدا با مجموعه بزرگی از بخش های رابط گرافیکی مانند انواع دکمه ها، فیلدهای متنی، جداول، درختان، منوها، نمودارها و غیره عرضه می شود که به نوبه خود باعث صرفه جویی در وقت ما می شود.
  • JavaFX اغلب از سبک های CSS استفاده می کند، و ما قادر خواهیم بود از یک فرمت FXML ویژه برای ایجاد رابط کاربری گرافیکی استفاده کنیم، نه اینکه آن را در کد جاوا انجام دهیم. این باعث می شود بدون نیاز به بازی با کد جاوا، به سرعت یک رابط کاربری گرافیکی یا ظاهر یا ترکیب را تغییر دهید.
  • JavaFX دارای قطعات نمودار آماده برای استفاده است، بنابراین لازم نیست هر زمان که به یک نمودار اولیه نیاز داشتید آنها را از ابتدا بنویسیم.
  • JavaFX علاوه بر این، با پشتیبانی از گرافیک سه بعدی همراه است، که اگر در حال توسعه نوعی بازی یا برنامه های مشابه هستیم، اغلب مفید است.
بیایید کمی به اجزای اصلی پنجره خود نگاه کنیم:
  • استیج در اصل یک پنجره اطراف است که به عنوان یک بوم شروع عمل می کند و بقیه اجزا را در بر می گیرد. یک برنامه می تواند چندین مرحله داشته باشد، اما در هر صورت باید یکی از این اجزا وجود داشته باشد. اساساً Stage محفظه اصلی و نقطه ورود است.
  • صحنه - محتویات صحنه را نمایش می دهد (مانند یک عروسک تودرتو). هر مرحله می تواند شامل چندین مؤلفه باشد - صحنه، که می توانند بین خودشان تغییر کنند. در داخل، این توسط یک گراف شی به نام Scene Graph (که در آن هر عنصر یک گره است، که Node نیز نامیده می شود ) پیاده سازی می شود.
  • گره‌ها کنترل‌هایی مانند دکمه‌های برچسب یا حتی طرح‌بندی هستند که می‌توانند چندین مؤلفه تودرتو در داخل خود داشته باشند. هر صحنه می تواند یک گره تودرتو داشته باشد، اما می تواند یک طرح با اجزای متعدد باشد. تودرتو می‌تواند چند سطحی باشد، با طرح‌بندی‌هایی که شامل طرح‌بندی‌های دیگر و اجزای معمولی باشد. هر یک از این گره ها دارای شناسه، سبک، افکت ها، وضعیت ها و کنترل کننده های رویداد خود هستند.
مقدمه ای بر Java FX - 4 پس بیایید کمی به سمت کد حرکت کنیم. از آنجایی که من از جاوا 8 استفاده می کنم، نیازی به ایجاد وابستگی ندارم، زیرا JavaFx به طور پیش فرض در JDK است (مانند جاوا 9.10)، اما اگر جاوا 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(که ما از جعبه Bugaga داریم) ارث می برد. در اصل ما متد Static Application را فراخوانی می کنیم launch()تا پنجره ما راه اندازی شود. همچنین، ایده ما شکایت خواهد کرد که ما متد Application را پیاده‌سازی نکرده‌ایم، 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 معمولی خود قرار می دهیم - پرچم دید را برای پنجره تنظیم می کنیم و در نتیجه یک پنجره کوچک برای استقبال از pesels مورد علاقه خود دریافت می کنیم: مقدمه ای بر 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

در این مرحله است که (درام رول) وارد بازی می شود - SceneBuilder در JavaFX Scene Builder ابزاری است که با آن می توانیم ویندوز خود را در قالب یک رابط گرافیکی طراحی کرده و سپس آنها را ذخیره کنیم و این برنامه بر اساس نتیجه، فایل های xml را بسازیم که ما آن را در برنامه خود بهبود خواهیم داد. رابط کاربری این سازنده fmxl چیزی شبیه به این است: مقدمه ای بر Java FX - 8

یک انحراف کوچک. دروس JavaFX

من از جزئیات نصب و مطالعه دقیق این ابزار صرف نظر می کنم. اینها موضوعاتی هستند که ارزش بررسی بیشتر را دارند. بنابراین، من هنوز چند پیوند جالب به درس های JavaFX می گذارم: یکی (آموزش آنلاین JavaFX) و دو (یک آموزش خوب دیگر). بیایید مثال کوچکی را که ترسیم کردم مرور کنیم. در پایان من چیزی شبیه به: مقدمه ای بر Java FX - 9
(مثل پنجره ای برای ثبت نام سگ ها)
وقتی سگی را انتخاب می کنید و دکمه Delete را فشار می دهید، سگ از لیست ما حذف می شود. وقتی دوست چهارپا را انتخاب می کنید و فیلدهای آن را تغییر می دهید و پس از فشار دادن دکمه Edit اطلاعات سگ به روز می شود. وقتی دکمه New را فشار می دهیم، پنجره ای برای ایجاد یک رکورد برای یک سگ جدید ظاهر می شود (برای شروع با نام آن): مقدمه ای بر Java FX - 10سپس روی Save کلیک کنید و بقیه قسمت های آن را در پنجره اول پر کنید و سپس دکمه Edit را بزنید تا صرفه جویی. آسان به نظر می رسد، درست است؟ بیایید ببینیم این در برنامه جاوا ما چگونه به نظر می رسد. برای شروع، من فقط طرح بندی های 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 یک حاشیه نویسی است که برای پیوند دادن کد جاوا و شی متناظر طرح ما (دکمه، فیلد یا چیز دیگری) طراحی شده است.
@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 - یک سگ جدید ایجاد می کنیم و روش فراخوانی پنجره ایجاد را فراخوانی می کنیم و یک شی جدید را ارسال می کنیم و بعد از بسته شدن آن اگر نام null نیست، حیوان خانگی جدید را ذخیره می کنیم.
در حال حرکت، کنترل کننده پنجره برای ایجاد سگ: @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();
    }
}
در اینجا ما ارتباط با فیلد متن را در پنجره مشاهده می کنیم که دکمه های Save و Cancel را پردازش می کند که به نوعی پنجره را می بندد. همانطور که می بینید، برای راحتی بیشتر در برنامه کوچک خود، از Lombok استفاده کردم، در غیر این صورت کد بسیار رشد می کرد و من آن را در بررسی خود قرار نمی دادم. این احتمالاً تمام چیزی است که برای امروز دارم. امروز به طور خلاصه با مفاهیم اولیه و نمونه ای از استفاده از JavaFX آشنا شدیم و می توانیم اپلیکیشن های دسکتاپ کوچک (با استفاده از اطلاعات اضافی که خوشبختانه در اینترنت فراوان است) بسازیم. و شما به نوبه خود دوست دارید))
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION