I am writing a program with JavaFX and Scene Builder

There is a main class Main which starts the program and opens the main window of the controller (Controller).

public class Main extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage primaryStage) throws Exception { try { Parent root = FXMLLoader.load(getClass().getResource("/card/card.fxml")); Scene scene = new Scene(root, 1600, 600); primaryStage.setScene(scene); scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm()); primaryStage.initStyle(StageStyle.UNDECORATED); primaryStage.setMaximized(true); primaryStage.setResizable(true); primaryStage.getIcons().add(new Image("card/resources/logo-icon.png")); primaryStage.show(); //adding resize and drag primary stage ResizeHelper.addResizeListener(primaryStage); //assign ALT+ENTER to maximize window final KeyCombination kb = new KeyCodeCombination(KeyCode.ENTER, KeyCombination.CONTROL_DOWN); scene.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent event) { if (kb.match(event)) { primaryStage.setMaximized(!primaryStage.isMaximized()); primaryStage.setResizable(true); } } }); } catch (Exception e) { e.printStackTrace(); } } } 

In the main window there is a label and also a button, when clicked, a window with another controller appears (FontController)

 @FXML private Button btnFont; @FXML private Label category1 @FXML void changeFont(ActionEvent event) { try { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("font.fxml")); Parent rootFont = (Parent) fxmlLoader.load(); Stage stage = new Stage(); stage.setTitle("Select Font"); stage.setScene(new Scene(rootFont)); stage.show(); } catch (Exception e) { System.out.println("can't load new window"); } } 

FontController has a label and an OK button.

 @FXML private Label fontLabel; @FXML private Button btnFontOk; 

Please tell me how to make it so that when you click on the OK button, the text from the label of this controller is sent to the Controller and displayed in the label?

Controller

FontController

EDITORIAL:

@boneferz I pasted this code, but setController is not recognized

setController

  • do you have a controller of type FontController? check it for null before accessing its methods - boneferz

3 answers 3

SOLUTION FOUND:

True, I have to create many getters and setters for each component in my program with which I want to manipulate from other windows.

In the folder with the project, I created the Context class, it is needed so that the controllers communicate with each other through it. You can place as many controllers as you want in this class.

 package card; public class Context { private final static Context instance = new Context(); public static Context getInstance() { return instance; } private Controller controller; public void setController(Controller controller) { this.controller=controller; } public Controller getController() { return controller; } private FontController fontController; public void setFontController(FontController fontController) { this.fontController=fontController; } public FontController getFontController() { return fontController; } } 

Controller class :

Here I created getters and setters for the label, which will change from another controller (ALT + INSERT to IDEA)

 public Label getCategory1() { return category1; } public void setCategory1(Label category1) { this.category1 = category1; } 

To get the methods and variables of FontController through the Context class, I applied the code:

 //getting FontController through Context Class FontController fontCont = Context.getInstance().getFontController(); 

I register the Controller in the Context class in the initialize () method;

 @FXML public void initialize(URL location, ResourceBundle resources) { //register Controller in Context Class Context.getInstance().setController(this); } 

FontController class :

to get the Controller methods and variables through the Context class, I use the following code:

 //getting Controller variables and methods through Context class Controller cont = Context.getInstance().getController(); 

I also register the FontController controller in the initialize () method; in the Context class:

 @Override public void initialize(URL location, ResourceBundle resources) { //register FontController in Context Class Context.getInstance().setFontController(this); } 

When I click on the "OK" button, a method is called that sends text and text color from the FontController label to the Controller

 @FXML void applyFont(ActionEvent event) { cont.getCategory1().setText(fontLabel.getText()); cont.getCategory1().setTextFill(fontLabel.getTextFill()); } 

MINUSES: creating getters and field setters that need to be manipulated from other controllers for each controller. Many lines of code for getters and setters are obtained (in my case)

PLUSES: all controllers are initialized in the same class

  • You can ask where they found such a solution? - boneferz
  • I can not remember on which forum I saw this solution, but after I implemented it, I found one more similar: youtube.com/watch?v=5GsdaZWDcdY&t=507s - kentforth
  • what I ask, I did the same in my project, literally recently. but doubted if that was right. Here, I even asked a question about this implementation - ru.stackoverflow.com/q/926037/296437 in general, I have no doubt now) - boneferz
  • @boneferz I understand that there are several options for how to organize interaction between controllers, the only question is how this model will work if for example there are not 2 controllers, but much more, whether it will be an optimized solution, or it will slow everything down ) - kentforth
  • The main thing is working, and there are no problems. I just do not see any other way of implementation besides this method. It seems to me the most faithful for today - boneferz
 label.getText() // получить значение содержащегося текста в label label.setText(String text) // установить текст в label 

How to transfer to another controller? You have a false link to it, and access to its label

How to make a link to it and access to the label?

 public class Main { public void start(Stage primaryStage) throws Exception{ FXMLLoader UIview = new FXMLLoader(getClass().getResource("sample.fxml")); Parent root = UIview.load(); MainController view = UIview.getController(); // можно юзать эту ссылку на класс главного контроллера если нужно } } class MainController { @FXML public Button btnFont; @FXML public Label category1; Controller controller; @FXML void changeFont(ActionEvent event) { FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("font.fxml")); Parent rootFont = fxmlLoader.load(); controller = fxmlLoader.getController(); controller.setMainController(this); // тут передать ссылку на главный контроллер (this) } } class FontController { @FXML private Label fontLabel; @FXML private Button btnFontOk; MainController mainController; // тут сохранить ссылку на главный контроллер void setMainController(MainController _mainController) { // тут принять ссылку this.mainController = _mainController; mainController.category1.setText("text"); // обращаться к елементам главного контроллера } } 
  • and how to make a link to it and access to the label? - kentforth
  • added how to add a link, try it, it should work! - boneferz

You can also use data binding .

Unidirectional binding (if label1 changes text, label2 will change text):

 Label label1 = new Label(); Label label2 = new Label(); label2.textProperty().bind(label1.textProperty()); // текст label2 зависит от текста label1 

Either bidirectional binding (if you change the text of label1, the text of label2 will change and vice versa: if you change the text of label2, the text of label1 will change):

 label2.textProperty().bindBidirectional(label1.textProperty()); 

For this example I will add the FontController class:

 class FontController { @FXML private Label fontLabel; @FXML private Button btnFontOk; MainController mainController; // тут сохранить ссылку на главный контроллер void setMainController(MainController _mainController) { // тут принять ссылку this.mainController = _mainController; mainController.category1.textProperty().bind(fontLabel.textProperty()); // связать текст } } 
  • The question was about linking CONTROLLER labels, not labels inside one controller - kentforth