JavaFX的Controller之间进行通信

javafx的Controller实例是由javafx框架代码自动创建并管理的,我尝试去获取javafx托管的Controller实例,但使用网上的方法,都是获取到了一个新的Controller实例,这显然是不符合要求的,那么我们可以自己创建保存管理一份Controller的引用,在使用时就能很方便获取了。

一、创建一个可以全局访问的存放Controller实例引用的容器

package com.yqsh.kit.context;

import java.util.HashMap;
import java.util.Map;

public class Context {
    public static StageManager stageController = new StageManager();

    public static Factory factory = new Factory();
    //Controller容器
    public static Map<String, Object> controllers = new HashMap<String, Object>();
}

二、创建一个根控制器,作为所有的Controller的父类,在RootController的构造器中将当前实例的引用保存起来,这样每个Controller实例在创建时就会自动把自己的引用存放在我们建立的容器中,每个Controller类型的实例是唯一的

package com.yqsh.kit.controller;

import com.yqsh.kit.context.Context;

public class RootController {
    public RootController(){
        //初始化时保存当前Controller实例
        Context.controllers.put(this.getClass().getSimpleName(), this);
    }
}

三、在使用时直接从容器中获取我们自己保存的Controller引用就可以实现对某个Controller函数调用和数据传递,因为Context是全局的,所以在程序任何位置都可以方便地获取想要的Controller实例

package com.yqsh.kit.controller;

import com.yqsh.kit.context.Constant;
import com.yqsh.kit.context.Context;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;

public class LoginController extends RootController{
    @FXML private TextField userName;
    @FXML private PasswordField password;
    private Logger logger = LogManager.getLogger(this.getClass());

    @FXML public void login(ActionEvent event) throws IOException {
        Context.factory.createStage(Constant.WINDOW_TITLE, Constant.FUNCTION_WINDOW_WIDTH, Constant.FUNCTION_WINDOW_HEIGHT, "function.fxml");;
        Context.stageController.jump("login", "function");

        //从容器中获取FunctionController实例
        FunctionController controller = (FunctionController) Context.controllers.get(FunctionController.class.getSimpleName());
        //调用FunctionController的函数
        controller.printlf("i was login.");
    }
}
  • 6
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,我可以给您提供一个简单的示例代码,帮助您理解使用单例模式来创建全局控制器对象,并实现不同FXML文件中的控制器之间通信。 在这个示例中,我们将创建两个FXML文件,分别为Main.fxml和Sub.fxml,每个文件都有自己的控制器类,分别为MainController和SubController。这两个控制器类之间需要进行通信。 1. Main.fxml的控制器类MainController ```java public class MainController implements Initializable { @FXML private Label label; @Override public void initialize(URL location, ResourceBundle resources) { // 在MainController中获取SubController对象,并调用其方法 SubController subController = ControllerManager.getInstance().getSubController(); subController.setText("Hello from MainController!"); } // 将label的文本设置为指定的内容 public void setText(String text) { label.setText(text); } } ``` 2. Sub.fxml的控制器类SubController ```java public class SubController implements Initializable { @FXML private Label label; @Override public void initialize(URL location, ResourceBundle resources) { } // 将label的文本设置为指定的内容 public void setText(String text) { label.setText(text); } } ``` 3. 创建ControllerManager类,用于管理全局控制器对象 ```java public class ControllerManager { private static ControllerManager instance = new ControllerManager(); private MainController mainController = new MainController(); private SubController subController = new SubController(); private ControllerManager() { } public static ControllerManager getInstance() { return instance; } public MainController getMainController() { return mainController; } public SubController getSubController() { return subController; } } ``` 4. 在Main.fxml中,使用fx:include标签引入Sub.fxml,并设置Sub.fxml的控制器为SubController ```xml <Pane xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.MainController"> <Label fx:id="label" text="Hello World!" /> <fx:include source="Sub.fxml" fx:id="sub" fx:controller="com.example.SubController" /> </Pane> ``` 5. 在MainController的initialize()方法中,获取SubController对象,并调用其方法setText()设置label的文本 ```java public void initialize(URL location, ResourceBundle resources) { // 在MainController中获取SubController对象,并调用其方法 SubController subController = ControllerManager.getInstance().getSubController(); subController.setText("Hello from MainController!"); } ``` 6. 在SubController的setText()方法中,设置label的文本 ```java public void setText(String text) { label.setText(text); } ``` 这样,我们就完成了不同FXML文件中控制器之间的相互调用。在MainController的initialize()方法中,我们获取了ControllerManager中的SubController对象,并调用了其方法setText()设置了label的文本。在SubController的setText()方法中,我们直接设置了label的文本。这样,在运行时,Main.fxml中的label的文本就会被设置为"Hello from MainController!",而Sub.fxml中的label的文本就会被设置为"Hello from MainController!"。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值