JavaFX之多個FXML加載和通信



前言

在使用了FXML設計布局后,新的問題隨之而來,當一個程序需要多個界面時,我們不可能在一個FXML中寫出全部布局,這樣太過於臃腫不易查看和維護(當然非要這么做也是可以的),這里就涉及到如何在一個FXML中添加另一個FXML以及多個FXML對應Controller類之間的通訊。經過查閱發現方法還不止一個,這里分別例舉一下吧。

本文目錄

1. 方式1

2. 方式2(推薦)


方式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 partController;

那么在mainController中,我們就可以使用partController.xxx調用partController中的公有屬性和方法了。
 
注意,這里屬性名partController是根據上一步設置的<fx:include>中設置的fx:id來的,格式為id+Controller,如id為'text',則此處應為

    @FXML
    private partController textController;

格式不對會報錯無法使用的


完事,結論很明確,方式2更好

參考文章:[https://blog.csdn.net/qq_20336817/article/details/80055701)

(本文最后更新於2020.3.14,原創文章,轉載請注明)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM