JavaFX – Come utilizzare un metodo in un controller da un altro controller?

Lavorare con SceneBuilder. Ho 2 fasi, ognuna con un controller: 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"); } } 

Ecco come vengono caricati entrambi i file fxml nella class Main.java utilizzando 2 metodi (chiamati nel metodo 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(); } } 
  • Il metodo handleTranslate (eventEvent event) viene utilizzato come metodo OnAction per il MenuItem translate nel primo stage, traduce la visualizzazione in entrambe le fasi.

Come posso inserire setLabel nel metodo handleTranslate? Grazie

Il modo “veloce e sporco” è di dare allo Stage1Controller un riferimento a 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 ... } 

Ora nella tua app principale:

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

Un approccio più robusto a questo, tuttavia, consiste nel consentire a entrambi i controller di accedere a una class di modello condivisa, memorizzando i dati. Se si rappresentano i dati utilizzando le proprietà osservabili di JavaFX, i controllori possono ascoltare le modifiche sulle proprietà a cui tengono. Per esempio:

 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... } 

Ora i tuoi controller avranno questo aspetto:

 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! } // ... } 

e

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

E in questo caso la tua app principale ha il seguente aspetto:

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