JavaFX多個FXML對應的Controller類之間的通訊

Preface

Q:爲什麼有此文?
A:其他人寫的文章不是很具體,沒有一針見血的感覺,故有此文


原理

  • 通過一個<fx:include>屬性,然後用MainController類來傳遞Controller類,以達到傳輸與定位的目的(具體請看源碼

  • 還有一個非常大!!!大的坑!!,請看MainController類源碼中的註釋(如果名字不正確就一定會NPE

實際效果

demo

源碼

項目結構

.
├── java
│   ├── controller
│   │   ├── MainController.java
│   │   ├── Part1Controller.java
│   │   └── Part2Controller.java
│   └── Main.java
└── resources
    ├── main.fxml
    ├── part1.fxml
    └── part2.fxml

PS:此項目中使用了JFeonix庫;如果有希望我替換成原生的庫的請留言。

具體源碼

java

Main.java

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("main.fxml"));
        primaryStage.setTitle("JFeonix Test Example");
        primaryStage.setScene(new Scene(root, 600, 400));
        primaryStage.show();
    }


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

Controller

MainController.java
package controller;

import com.jfoenix.controls.JFXTextArea;
import javafx.fxml.FXML;

public class MainController {
    //一定要初始化這兩個
    //並且,這個變量名一定是這樣的模式:`<fx:id>Controller`
    //Eg,你的example.fxml中的`fx:id="example"`,那麼你的變量名一定是`exampleController`
    //如果不信,歡迎嘗試`NPE` :D
    //PS:fxml或者java文件名無所謂,只看`MainController`變量名,肉測!
    @FXML
    private Part1Controller part1Controller;

    @FXML
    private Part2Controller part2Controller;


    @FXML
    private void initialize() {
        part1Controller.injectMainController(this);
    }

    JFXTextArea getOutputPane() {
       return part2Controller.textArea;
    }
}
Part1Controller.java
package controller;

import com.jfoenix.controls.JFXTextArea;
import javafx.fxml.FXML;
import javafx.scene.control.Button;

public class Part1Controller {

    @FXML
    private Button button;

    private MainController mainController;
    //注入MainController
    void injectMainController(MainController mainController) {
        this.mainController = mainController;
    }

    //得到想要的TextArea
    private JFXTextArea getTextArea () {
        return this.mainController.getOutputPane();
    }

    @FXML
    private void onButtonAction() {
        getTextArea().appendText("Fuck me\n");
    }

    @FXML
    private void initialize() {
    }
}
Part2Controller.java
package controller;

import com.jfoenix.controls.JFXTextArea;
import javafx.fxml.FXML;

public class Part2Controller {
    @FXML
    public JFXTextArea textArea;

    @FXML
    private void initialize() {

    }
}

resources

main.fxml

<?xml version="1.0" encoding="UTF-8"?>


<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/9" xmlns:fx="http://javafx.com/fxml/1"
            fx:controller="controller.MainController">
    <children>
        <HBox layoutX="163.0" layoutY="135.0" prefHeight="100.0" prefWidth="200.0">
            <children>
                <fx:include fx:id="part1" source="part1.fxml"/>
                <fx:include fx:id="part2" source="part2.fxml"/>
            </children>
        </HBox>
    </children>
</AnchorPane>

part1.fxml

<?xml version="1.0" encoding="UTF-8"?>


<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.StackPane?>
<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="174.0"
           prefWidth="191.0" xmlns="http://javafx.com/javafx/9" xmlns:fx="http://javafx.com/fxml/1"
           fx:controller="controller.Part1Controller">
    <children>
        <Button fx:id="button" mnemonicParsing="false" onAction="#onButtonAction" text="Button"/>
    </children>
</StackPane>

part2.fxml

<?xml version="1.0" encoding="UTF-8"?>


<?import com.jfoenix.controls.JFXTextArea?>
<?import javafx.scene.layout.StackPane?>
<StackPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity"
           minWidth="-Infinity" prefHeight="192.0" prefWidth="289.0" xmlns="http://javafx.com/javafx/9"
           xmlns:fx="http://javafx.com/fxml/1" fx:controller="controller.Part2Controller">
    <children>
        <JFXTextArea fx:id="textArea"/>
    </children>
</StackPane>

Reference

https://github.com/mvpjava/javaFX-multiple-controllers-tutorial

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章