我想随时与FXML控制器类进行通信,以从主应用程序或其他阶段更新屏幕上的信息。
这可能吗?我还没有找到任何办法。
静态函数可能是一种方法,但是它们无法访问表单的控件。
有任何想法吗?
Answers:
您可以从 FXMLLoader
FXMLLoader fxmlLoader = new FXMLLoader();
Pane p = fxmlLoader.load(getClass().getResource("foo.fxml").openStream());
FooController fooController = (FooController) fxmlLoader.getController();
将其存储在您的主要阶段,并提供getFooController()getter方法。
在其他类或阶段中,每当您需要刷新加载的“ foo.fxml”页面时,请从其控制器中进行询问:
getFooController().updatePage(strData);
updatePage()可能类似于:
// ...
@FXML private Label lblData;
// ...
public void updatePage(String data){
lblData.setText(data);
}
// ...
在FooController类中。
这样,其他页面用户就不必担心页面的内部结构(例如,内容和位置Label lblData
)。
还要查看https://stackoverflow.com/a/10718683/682495。在JavaFX 2.2FXMLLoader
中进行了改进。
只是为了帮助阐明可接受的答案,并可能为JavaFX的其他新用户节省一些时间:
对于JavaFX FXML应用程序,NetBeans将在主类中自动生成您的start方法,如下所示:
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
现在,要访问控制器类,我们要做的就是将FXMLLoaderload()
方法从静态实现更改为实例化实现,然后我们可以使用实例的方法来获取控制器,如下所示:
//Static global variable for the controller (where MyController is the name of your controller class
static MyController myControllerHandle;
@Override
public void start(Stage stage) throws Exception {
//Set up instance instead of using static load() method
FXMLLoader loader = new FXMLLoader(getClass().getResource("FXMLDocument.fxml"));
Parent root = loader.load();
//Now we have access to getController() through the instance... don't forget the type cast
myControllerHandle = (MyController)loader.getController();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
另一个解决方案是从您的控制器类设置控制器,就像这样...
public class Controller implements javafx.fxml.Initializable {
@Override
public void initialize(URL location, ResourceBundle resources) {
// Implementing the Initializable interface means that this method
// will be called when the controller instance is created
App.setController(this);
}
}
这是我更喜欢使用的解决方案,因为代码有些混乱,无法创建功能齐全的FXMLLoader实例,该实例可以正确处理本地资源等。
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("/sample.fxml"));
}
与
@Override
public void start(Stage stage) throws Exception {
URL location = getClass().getResource("/sample.fxml");
FXMLLoader loader = createFXMLLoader(location);
Parent root = loader.load(location.openStream());
}
public FXMLLoader createFXMLLoader(URL location) {
return new FXMLLoader(location, null, new JavaFXBuilderFactory(), null, Charset.forName(FXMLLoader.DEFAULT_CHARSET_NAME));
}
Application
类中有一个静态映射,即关键控制器->值加载器(注意,可以始终从加载程序中获取控制器)。其次,我们得到了一种getController()
方法,因此使用它很有意义。第三,static
当真正涉及实例操作时,应避免使用方法,并应避免将其作为一般的编码偏好。