如何在另一个类中访问已实例化ButtonData对象的存储数据?
你遇到的是JavaFX里很常见的跨Controller共享数据问题,新建对象肯定拿不到之前存的数据,因为每次new出来的都是全新的实例。下面给你几个靠谱的实现方式,都是实际开发里常用的:
方案1:通过FXMLLoader直接传递实例
这是最直接的方式——当你加载目标Controller对应的FXML时,把InfoController里已经赋值好的ButtonData实例直接传过去。
假设你要跳转的目标Controller叫AnotherController,在InfoController的onSaveClick方法里这么写:
@FXML void onSaveClick(ActionEvent event) { if(parseInputs()) { ButtonData buttonData = new ButtonData(); // 给buttonData设置你需要存储的数据 buttonData.setButtonText("提交"); buttonData.setIsEnabled(true); // 加载目标页面的FXML文件 try { FXMLLoader loader = new FXMLLoader(getClass().getResource("another-page.fxml")); Parent targetRoot = loader.load(); // 获取目标Controller的实例 AnotherController anotherController = loader.getController(); // 直接把准备好的buttonData传递过去 anotherController.setButtonData(buttonData); // 切换场景显示目标页面 Scene targetScene = new Scene(targetRoot); Stage currentStage = (Stage) ((Node) event.getSource()).getScene().getWindow(); currentStage.setScene(targetScene); currentStage.show(); } catch (IOException e) { e.printStackTrace(); } } }
然后在AnotherController里添加接收数据的方法:
public class AnotherController { private ButtonData buttonData; // 提供setter方法接收外部传递的buttonData public void setButtonData(ButtonData buttonData) { this.buttonData = buttonData; } // 比如在初始化方法里就可以使用数据了 @FXML public void initialize() { if(buttonData != null) { String btnText = buttonData.getButtonText(); boolean isEnabled = buttonData.getIsEnabled(); // 用这些数据做你需要的操作,比如设置按钮状态 } } }
方案2:给ButtonData实现单例模式
如果你的ButtonData是全局唯一的(不需要多个不同实例),可以把它改成单例类,这样无论哪个Controller获取的都是同一个实例,自然能拿到之前存储的数据。
修改你的ButtonData类:
public class ButtonData { // 全局唯一的实例 private static final ButtonData INSTANCE = new ButtonData(); // 私有构造方法,禁止外部直接new private ButtonData() {} // 提供全局访问入口 public static ButtonData getInstance() { return INSTANCE; } // 你的getter和setter方法 private String buttonText; private boolean isEnabled; public String getButtonText() { return buttonText; } public void setButtonText(String buttonText) { this.buttonText = buttonText; } public boolean getIsEnabled() { return isEnabled; } public void setIsEnabled(boolean isEnabled) { this.isEnabled = isEnabled; } }
在InfoController里设置数据:
@FXML void onSaveClick(ActionEvent event) { if(parseInputs()) { ButtonData buttonData = ButtonData.getInstance(); buttonData.setButtonText("提交"); buttonData.setIsEnabled(true); } }
在另一个Controller里获取数据:
public class AnotherController { @FXML public void initialize() { ButtonData buttonData = ButtonData.getInstance(); String btnText = buttonData.getButtonText(); boolean isEnabled = buttonData.getIsEnabled(); // 使用数据 } }
注意:单例模式只适合全局共享的数据场景,如果你的应用需要多个不同的ButtonData实例,这个方法就不适用了,还要注意JavaFX的UI线程安全问题。
方案3:通过父Controller中转传递
如果两个Controller都属于同一个父容器(比如TabPane的不同Tab、BorderPane的不同区域),可以通过父Controller来中转数据。
比如父Controller叫MainController,它已经通过FXML绑定了两个子Controller的实例:
public class MainController { @FXML private InfoController infoController; @FXML private AnotherController anotherController; // 提供方法让InfoController把数据传给AnotherController public void passButtonData(ButtonData buttonData) { anotherController.setButtonData(buttonData); } }
然后在InfoController里获取父Controller并传递数据:
@FXML void onSaveClick(ActionEvent event) { if(parseInputs()) { ButtonData buttonData = new ButtonData(); buttonData.setButtonText("提交"); // 获取父Controller实例 Node sourceNode = (Node) event.getSource(); Scene currentScene = sourceNode.getScene(); MainController mainController = (MainController) currentScene.getUserData(); // 调用父Controller的方法传递数据 mainController.passButtonData(buttonData); } }
这种方式适合有明确父容器的场景,需要提前在父Controller的FXML里通过
fx:id关联子Controller。
内容的提问来源于stack exchange,提问作者Boxify

