-1

Update: In accordance with @kleopatra comment.

I want to set the text of a Button from the String in a TextField from another controller upon closing of the window that contains the TextField.

public class Controller {

    @FXML Button btn1;

    public void initialize(){
        renderBtns();
    }

    public void renderBtns(){

        btn1.addEventHandler(MouseEvent.MOUSE_CLICKED, new CustomButtonHandler(1));
    }
}

I am using a custom handler for the Button MOUSE_CLICKED event. (Keep in mind this is a simplified version of my code, I need to use this handler in the full code)

Here is the CustomButtonHandler:

   public class CustomButtonHandler implements EventHandler {

    int id;

    public CustomButtonHandler(int id){
        this.id = id;
    }

    @Override
    public void handle(Event event) {
        try {

            FXMLLoader fxmlLoader = new FXMLLoader();
            fxmlLoader.setLocation(getClass().getResource("smetka.fxml"));
            Parent root = fxmlLoader.load();
            SmetkaControl controller = fxmlLoader.getController();
            controller.setId(id);
            Scene scene = new Scene(root);
            Stage stage = new Stage();
            stage.setTitle("Сметка - Маса" + " " + id);
            stage.setScene(scene);
            stage.initModality(Modality.APPLICATION_MODAL);
            stage.setOnHiding(event1 -> {
                try {
                    controller.exitScene();
                } catch (IOException | ParseException e) {
                    e.printStackTrace();
                }
            });
            stage.show();


        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Here is my other - SmetkaControl :

public class SmetkaControl {

    int id;
    @FXML
    TextField txtField;

    public void setId(int id) {
        this.id = id;
    }

    public void initialize() {

    }

    public void exitScene() throws IOException, ParseException {

        FXMLLoader fxmlLoader = new FXMLLoader();
        fxmlLoader.setLocation(getClass().getResource("sample.fxml"));
        fxmlLoader.load();
        Controller controller = fxmlLoader.getController();
        txtField.setFocusTraversable(false);
        controller.btn1.setText(txtField.getText());
        System.out.println(controller.btn1.getText());

    }
}

sample.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.BorderPane?>


    <BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/15.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Controller">
       <center>
          <Button fx:id="btn1" mnemonicParsing="false" text="Button" BorderPane.alignment="CENTER" />
       </center>
    </BorderPane>

and smetka.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.HBox?>

<HBox alignment="CENTER" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="950.0" xmlns="http://javafx.com/javafx/15.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.SmetkaControl">
   <children>
      <TextField fx:id="txtField" />
   </children>
</HBox>

The Main.class is default:

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 600, 400));
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }
}

When I close the window I get the correct value in the console (from btn1.getText()) but the button remains unchanged.

Why does it give me the right value in the console, but the graphic is unchanged?

How should I do this right?

Zozinski
  • 73
  • 8
  • 1
    [mcve] please.. – kleopatra Apr 06 '21 at 06:54
  • 1
    good starter :) Still missing: the fxml files and the application – kleopatra Apr 06 '21 at 10:25
  • btw: you are aware that you create a new controller in exitScene (that has nothing to do with the one the button with the handler is on) and do not use it anywhere? – kleopatra Apr 06 '21 at 10:44
  • @kleopatra I was actually not aware that I create a new controller... How should I reference the existing one and not create a new one? I thought getController() gives me the existing one – Zozinski Apr 06 '21 at 16:37
  • 1
    _I thought getController() gives me the existing one_ your assumption is wrong ;) – kleopatra Apr 07 '21 at 10:06
  • forgot references to options for a solution: see f.i. https://stackoverflow.com/questions/14187963/passing-parameters-javafx-fxml or https://stackoverflow.com/questions/32342864/applying-mvc-with-javafx – kleopatra Apr 07 '21 at 10:46
  • @kleopatra You are right, when I ran stage.show() in exitScene() it showed the new controller and the new scene with the correct values. I will work it out and post it as an answer later – Zozinski Apr 07 '21 at 11:12

1 Answers1

0

Turns out my problem wasn't with refreshing the screen, but instead I was creating a new instance of the Controller, hence the changes didn't show when running. (When I ran stage.show() in exitScene() the new instance was shown)

If I create an instance of the controller in the Application class and then call it through that class it works as I want.

Like this:

Main:

public class Main extends Application {

    public static Controller controller;

    @Override
    public void start(Stage primaryStage) throws Exception{
        FXMLLoader fxmlLoader = new FXMLLoader();
        fxmlLoader.setLocation(getClass().getResource("sample.fxml"));
        Parent root = fxmlLoader.load();
        controller = fxmlLoader.getController();
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 600, 400));
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

CustomButtonHandler:

public class CustomButtonHandler implements EventHandler {

    int id;

    public CustomButtonHandler(int id){
        this.id = id;
    }

    @Override
    public void handle(Event event) {
        try {

            FXMLLoader fxmlLoader = new FXMLLoader();
            fxmlLoader.setLocation(getClass().getResource("smetka.fxml"));
            Parent root = fxmlLoader.load();
            SmetkaControl controller = fxmlLoader.getController();
            controller.setId(id);
            Scene scene = new Scene(root);
            Stage stage = new Stage();
            stage.setTitle("Сметка - Маса" + " " + id);
            stage.setScene(scene);
            stage.initModality(Modality.APPLICATION_MODAL);
            stage.setOnHiding(event1 -> {
                controller.exitScene();
            });
            stage.show();


        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

SmetkaControl:

public class SmetkaControl {

    int id;
    @FXML
    TextField txtField;

    public void setId(int id) {
        this.id = id;
    }

    public void initialize() {

    }

    public void exitScene() {

        Main.controller.btn1.setText(txtField.getText());

    }
}

Controller:

public class Controller {

    @FXML Button btn1;

    public void initialize(){
        renderBtns();
    }

    public void renderBtns(){

        btn1.addEventHandler(MouseEvent.MOUSE_CLICKED, new CustomButtonHandler(1));
    }

    public void clickBtn(){

    }
}
Zozinski
  • 73
  • 8