JavaFX多个FXML对应的Controller类之间的通讯

Preface

Q:为什么有此文?
A:其他人写的文章不是很具体,没有一针见血的感觉,故有此文


原理

  • 通过一个属性,然后用MainController类来传递Controller类,以达到传输与定位的目的(具体请看源码

  • 还有一个非常大!!!大的坑!!,请看MainController类源码中的注释(如果名字不正确就一定会NPE

实际效果

JavaFX多个FXML对应的Controller类之间的通讯_第1张图片

源码

项目结构

.
├── 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 {
    //一定要初始化这两个
    //并且,这个变量名一定是这样的模式:`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






<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






<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






<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

你可能感兴趣的:(javafx,FXML,Controller,类间通讯,fx:include,JavaFX)