访问FXML控制器类

我想随时与FXML控制器类进行通信,从主应用程序或其他阶段更新屏幕上的信息。

这可能吗? 我没有find任何方法来做到这一点。

静态函数可能是一种方法,但他们无法访问窗体的控件。

有任何想法吗?

你可以从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.2中, FXMLLoader得到了改进。

另一个解决scheme是从您的控制器类设置控制器,就像这样…

 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); } } 

这是我喜欢使用的解决scheme,因为代码是有点混乱,以创build一个function齐全的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)); } 

只是为了帮助澄清已被接受的答案,也许为JavaFX的其他人节省了一些时间:

对于JavaFX FXML应用程序,NetBeans将在主类中自动生成启动方法,如下所示:

 @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(); } 

现在,我们需要做的就是访问控制器类,将FXMLLoader的load()方法从静态实现改为实例化的实现,然后我们可以使用实例的方法来获取控制器,如下所示:

 //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(); } 

在主屏幕上加载对象时,传递数据的一种方法是使用lookup,然后将数据设置在一个不可见的标签中,以便以后可以从控制器类中检索。 喜欢这个:

 Parent root = FXMLLoader.load(me.getClass().getResource("Form.fxml")); Label lblData = (Label) root.lookup("#lblData"); if (lblData!=null) lblData.setText(strData); 

这有效,但必须有更好的方法。