Acceder a la clase de controlador FXML

Me gustaría comunicarme con una clase de controlador FXML en cualquier momento, para actualizar la información en la pantalla desde la aplicación principal u otras etapas.

es posible? No he encontrado ninguna forma de hacerlo.

Las funciones estáticas podrían ser una forma, pero no tienen acceso a los controles del formulario.

¿Algunas ideas?

Puedes obtener el controlador desde el FXMLLoader

 FXMLLoader fxmlLoader = new FXMLLoader(); Pane p = fxmlLoader.load(getClass().getResource("foo.fxml").openStream()); FooController fooController = (FooController) fxmlLoader.getController(); 

guárdelo en su escenario principal y proporcione el método GetFooController () getter.
Desde otras clases o etapas, cada vez que necesite actualizar la página cargada “foo.fxml”, solicítelo a su controlador:

 getFooController().updatePage(strData); 

updatePage () puede ser algo así como:

 // ... @FXML private Label lblData; // ... public void updatePage(String data){ lblData.setText(data); } // ... 

en la clase FooController.
De esta forma, los usuarios de otras páginas no se preocupan por la estructura interna de la página, como qué y dónde está Label lblData .

También mire el https://stackoverflow.com/a/10718683/682495 . En JavaFX 2.2 FXMLLoader se ha mejorado.

Solo para ayudar a aclarar la respuesta aceptada y quizás ahorrar algo de tiempo para otras que son nuevas en JavaFX:

Para una aplicación JavaFX FXML, NetBeans generará automáticamente su método de inicio en la clase principal de la siguiente manera:

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

Ahora, todo lo que tenemos que hacer para tener acceso a la clase de controlador es cambiar el método load() FXMLLoader de la implementación estática a una implementación instanciada y luego podemos usar el método de la instancia para obtener el controlador, así:

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

Otra solución es configurar el controlador desde la clase de su controlador, así que …

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

Esta es la solución que prefiero usar, ya que el código es un poco desordenado para crear una instancia de FXMLLoader totalmente funcional que maneje adecuadamente los recursos locales, etc.

 @Override public void start(Stage stage) throws Exception { Parent root = FXMLLoader.load(getClass().getResource("/sample.fxml")); } 

versus

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

En la carga del objeto desde la pantalla principal, una forma de pasar los datos que he encontrado y funciona es usar la búsqueda y luego establecer los datos dentro de una etiqueta invisible que puedo recuperar más adelante desde la clase del controlador. Me gusta esto:

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

Esto funciona, pero debe haber una mejor manera.