Preface
Q:爲什麼有此文?
A:其他人寫的文章不是很具體,沒有一針見血的感覺,故有此文
原理
通過一個
<fx:include>
屬性,然後用MainController
類來傳遞Controller類,以達到傳輸與定位的目的(具體請看源碼)還有一個非常大!!!大的坑!!,請看
MainController類
源碼中的註釋(如果名字不正確就一定會NPE
)
實際效果
源碼
項目結構
.
├── 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