java javafx controller javafx-8 scenebuilder

JavaFX-¿Cómo usar un método en un controlador desde otro controlador?



controller javafx-8 (1)

La forma "rápida y sucia" es darle al Stage1Controller una referencia al Stage2Controller :

public class Stage1Controller { private final Stage2Controller stage2Controller ; public void setStage2Controller(Stage2Controller stage2Controller) { this.stage2Controller = stage2Controller ; } // ... @FXML private void handleTranslate (ActionEvent event){ translateFirstStage(); stage2Controller.setLabel(...); } // other code as before ... }

Ahora en tu aplicación principal:

public class MainApp extends Application { private Stage1Controller stage1Controller ; private Stage2Controller stage2Controller ; @Override public void start(Stage primaryStage) { firstStage(); secondStage(); stage1Controller.setStage2Controller(stage2Controller); // ... } public void firstStage() { try { // Load root layout from fxml file. FXMLLoader loader = new FXMLLoader(); loader.setLocation(Main.class.getResource("view/stage1.fxml")); rootLayout = (BorderPane) loader.load(); stage1Controller = loader.getController(); // Show the scene containing the root layout. Scene scene = new Scene(rootLayout); primaryStage.setScene(scene); primaryStage.show(); } catch (IOException e) { e.printStackTrace(); } } public void secondStage() { try { // Load root layout from fxml file. FXMLLoader loader = new FXMLLoader(); loader.setLocation(Main.class.getResource("view/stage2.fxml")); XD = (AnchorPane) loader.load(); stage2Controller = loader.getController(); // Show the scene containing the root layout. Scene scene = new Scene(XD); Stage stage = new Stage(); stage.setScene(scene); stage.show(); } catch (IOException e) { e.printStackTrace(); } } // ... }

Sin embargo, un enfoque más sólido para esto es permitir que ambos controladores accedan a una clase de modelo compartida, almacenando los datos. Si representa los datos utilizando propiedades observables JavaFX, los controladores pueden escuchar los cambios en las propiedades que les interesan. Por ejemplo:

public class Model { private final StringProperty text = new SimpleStringProperty("Initial text..."); public StringProperty textProperty() { return text ; } public final void setText(String text) { textProperty().set(text); } public final String getText() { return textProperty().get(); } // other properties as needed... }

Ahora sus controladores se verán así:

public class Stage1Controller { private Model model ; public void setModel(Model model) { this.model = model ; } @FXML private void handleTranslate (ActionEvent event){ translateFirstStage(); model.setText(...); // value will appear in stage2 controller''s label! } // ... }

y

public class Stage2Controller { @FXML private Label lb ; private Model model ; public void setModel(Model model) { lb.textProperty().unbind(); this.model = model ; lb.textProperty().bind(model.textProperty()); } // ... }

Y en este caso su aplicación principal se ve así:

public class MainApp extends Application { private final Model = new Model(); @Override public void start(Stage primaryStage) { // ... } public void firstStage() { try { // Load root layout from fxml file. FXMLLoader loader = new FXMLLoader(); loader.setLocation(Main.class.getResource("view/stage1.fxml")); rootLayout = (BorderPane) loader.load(); Stage1Controller controller = loader.getController(); controller.setModel(model); // Show the scene containing the root layout. Scene scene = new Scene(rootLayout); primaryStage.setScene(scene); primaryStage.show(); } catch (IOException e) { e.printStackTrace(); } } public void secondStage() { try { // Load root layout from fxml file. FXMLLoader loader = new FXMLLoader(); loader.setLocation(Main.class.getResource("view/stage2.fxml")); XD = (AnchorPane) loader.load(); Stage2Controller controller = loader.getController(); controller.setModel(model); // Show the scene containing the root layout. Scene scene = new Scene(XD); Stage stage = new Stage(); stage.setScene(scene); stage.show(); } catch (IOException e) { e.printStackTrace(); } } }

Trabajando con SceneBuilder. Tengo 2 etapas, cada una con un controlador:
stage1Controller ,
stage2Controller .
Stage1Controller:

public class Stage1Controller { @FXML private MenuItem translate; @FXML private Menu file; @FXML private Menu edit; @FXML private Menu help; @FXML private void handleTranslate (ActionEvent event){ translateFirstStage(); //HOW TO ACCESS THE stage2Controller setLabel()?? } private void translateFirstStage(){ file.setText("Fichier"); edit.setText("Modifier"); help.setText("Aide"); } }

Stage2Controller:

public class Stage2Controller { @FXML private Label lb; private void setLabel(String string){ lb.setText("string"); } }

Así es como se cargan ambos archivos fxml en la clase Main.java usando 2 métodos
(llamado en el método Start(Stage primaryStage) ):

public void firstStage() { try { // Load root layout from fxml file. FXMLLoader loader = new FXMLLoader(); loader.setLocation(Main.class.getResource("view/stage1.fxml")); rootLayout = (BorderPane) loader.load(); // Show the scene containing the root layout. Scene scene = new Scene(rootLayout); primaryStage.setScene(scene); primaryStage.show(); } catch (IOException e) { e.printStackTrace(); } } public void secondStage() { try { // Load root layout from fxml file. FXMLLoader loader = new FXMLLoader(); loader.setLocation(Main.class.getResource("view/stage2.fxml")); XD = (AnchorPane) loader.load(); // Show the scene containing the root layout. Scene scene = new Scene(XD); Stage stage = new Stage(); stage.setScene(scene); stage.show(); } catch (IOException e) { e.printStackTrace(); } }

  • El handleTranslate(ActionEvent event) se utiliza como un método OnAction para la MenuItem translate en la primera etapa, traduce la vista en ambas etapas.

¿Cómo puedo poner setLabel en el método handleTranslate ? Gracias