Yusuf
Yusuf

Reputation: 108

Communicating with an FXML Controller that's already open

I have searched again and again on this to no avail. I have a JavaFX FXML window which is connected to a Controller; this window is open. Clicking a button on the window triggers the opening of another FXML file, linked to its respective controller.

The second window (optionsUI.fxml and optionsController) has a few radio buttons. When one is clicked, I want the location of an image/button to change in the mainUI window. How do I go about doing that?

mainController:

public void assetPressed(MouseEvent event) {
        //Get the source of Handler
        HUDButton button = (HUDButton) event.getSource();

        //Check if an asset is already selected
        //----do a thing
            //Open stage
            openStage(currentAsset);

        } else {
            //if the current asset selected and the new asset clicked are the same
            //----do something
                closeStage();
            }
            //if the current asset selected and the new asset clicked are different
            else {
                //----do something else
                assetIsSelected = true;
                openStage(currentAsset);
            }
        }
    }
//opening optionsUI.fxml
public void openStage(Asset asset) {

        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("optionsUI.fxml"));

        Parent root = null;
        try {
            root = fxmlLoader.load();
        } catch (IOException e) {
            e.printStackTrace();
        }
        optionsController controller = fxmlLoader.getController();

        Scene scene = new Scene(root, 300, 450);
        stage.setScene(scene);
        if (alreadyExecuted == false) {
            stage.initStyle(StageStyle.UNDECORATED);
            stage.initOwner(stageControls); //Making the mainUI the owner of the optionsUI
            stage.setTitle("HUDEdit Version 3.0.0");
            alreadyExecuted = true;
        }

The main issue I am having is adding an event handler on the radio buttons which will change a property of the Button that was pressed (currentButton). I searched on this issue, but what I got was what I have already done: to open a new stage with the new values present in the other FXML file.

Upvotes: 1

Views: 393

Answers (1)

James_D
James_D

Reputation: 209330

You can do something like this in your OptionsController (I am going to rename things to conform to standard naming conventions, btw.)

The basic idea here is just to expose a property representing what the user has selected via the radio buttons.

public class OptionsController {

    @FXML
    private RadioButton radioButton1 ;

    @FXML
    private RadioButton radioButton2 ;

    private SomeType someValue1 = new SomeType();
    private SomeType someValue2 = new SomeType();

    private final ReadOnlyObjectWrapper<SomeType> selectedThing = new ReadOnlyObjectWrapper<>();

    public ReadOnlyObjectProperty<SomeType> selectedThingProperty() {
        return selectedThing.getReadOnlyProperty() ;
    }

    public final SomeType getSelectedThing() {
        return selectedThingProperty().get();
    }

    public void initialize() {
        radioButton1.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
            if (isNowSelected) {
                selectedThing.set(someValue1);
            }
        });
        radioButton2.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
            if (isNowSelected) {
                selectedThing.set(someValue2);
            }
        });
    }

    // ...
}

And now when you load Options.fxml you can just observe that property and do whatever you need when it's value changes:

public void openStage(Asset asset) {

    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("optionsUI.fxml"));

    Parent root = null;
    try {
        root = fxmlLoader.load();
    } catch (IOException e) {
        e.printStackTrace();
    }
    OptionsController controller = fxmlLoader.getController();
    controller.selectedThingProperty().addListener((obs, oldSelection, newSelection) -> {
        // do whatever you need with newSelection....
    });

    // etc...
}

Upvotes: 2

Related Questions