JavaFX之多個FXML載入和通訊
- 2020 年 3 月 14 日
- 筆記
前言
在使用了FXML設計布局後,新的問題隨之而來,當一個程式需要多個介面時,我們不可能在一個FXML中寫出全部布局,這樣太過於臃腫不易查看和維護(當然非要這麼做也是可以的),這裡就涉及到如何在一個FXML中添加另一個FXML以及多個FXML對應Controller類之間的通訊。經過查閱發現方法還不止一個,這裡分別例舉一下吧。
本文目錄
方式1
這個方法也是我一開始使用的,原理上就是利用FXMLLoader
載入FXML然後通過程式碼添加,假設現有JavaFx項目結構如下:
project │ └───java │ │ │ └───main.java │ │ │ └───controller │ ├──mainController.java │ ├──partController.java │ └───resources ├── main.FXML ├── part.FXML
首先以正常情況載入main.FXML
,那麼對於part.FXML,可以在mainController
的initializable
方法中使用FXMLLoader
方法從FXML中獲取布局,再以程式碼方式添加到main布局中,有如下偽程式碼:
/** * mainController.java * 偽程式碼僅用作示例,無法運行 */ public class mainController implements Initializable { @FXML private GridPane root; private GridPane part; @Override public void initialize(URL location, ResourceBundle resources) { try { part=new FXMLLoader(getClass().getClassLoader().getResource("resources/part.fxml")).load(); root.add(part); } catch (IOException e) { e.printStackTrace(); } } }
那麼Controller之間的通訊,同樣以上方項目結構為例,假定需要在partController中和mainController實現通訊,可以利用HashMap
作為Controller容器來實現傳遞。我們有如下程式碼:
mian.java
public class main extends Application { //創建一個Controller容器 public static Map<String, Object> controllers = new HashMap<String, Object>(); @Override public void start(Stage primaryStage) throws Exception { Parent root = new FXMLLoader(getClass().getClassLoader().getResource("resources/main.fxml")).load(); primaryStage.setScene(new Scene(root)); primaryStage.show(); } public static void main(String[] args) { launch(); } }
如此,在partController.java
定義如下屬性:
private mainControl controller= (mainControl) main.controllers.get(mainControl.class.getSimpleName());
那麼在partController
中,我們就可以使用controller.xxx
調用partController
中的公有屬性和方法了。
(此例與上例沒有直接關係)
方式2
在使用過程中,我們可以發現,方法1雖然可以實現通訊,但是並不好用,這裡就要介紹方法2了。同樣的,還是先從FXML中添加FXML說起。查了資料發現通過
同樣的以上面項目結構為例,在main.fxml
中添加part.fxml
有如下偽程式碼:
mian.fxml
<AnchorPane fx:id="root" fx:controller="java.controller.mainController" prefHeight="400.0" prefWidth="600.0"> <children> <fx:include fx:id="part" source="TitlesBar.fxml"/> </children> </AnchorPane>
這樣就行了,接下來接著看通訊,注意這裡前後是連著的,不像上一個方法,前後沒有直接關係。
在mainController.java
中,設置如下屬性:
@FXML private partController controller;
那麼在mainController
中,我們就可以使用controller.xxx
調用partController
中的公有屬性和方法了。
完事,結論很明確,方式2更好
參考文章:[https://blog.csdn.net/qq_20336817/article/details/80055701)
(本文最後更新於2020.3.14,原創文章,轉載請註明)