0

I have a main controller which handles my main.fxml and a second controller which handles my popup.fxml

When a button is pressed from the main controller, the popup windows appears. In the popup window you add players. The players are added by textfield to an array and must be sent back to main controller. I have a button called "btnApply" in my popup controller, when that is pressed I want to close the popup window and handle the array from my main controller class. I only want my main controller class to be aware of the popup.

This is how I am creating a popup from main controller:

button.setOnAction(e -> newWindow());

     public void newWindow(){
     try{
                FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("popup.fxml"));
                Parent popupRoot = fxmlLoader.load();
                Stage playerStage = new Stage();
                playerStage.setTitle("Player");
                playerStage.setScene(new Scene(popupRoot, 720, 600));
                playerStage.show();
            }catch(Exception e) {
                e.printStackTrace();
            }
     }

Now the question is how to I get the event or the object. When I created the popup window without using FXML (created the GUI manually), it was easy because I just made an object of the Class Popup and had a getButton() and getArray(). In my main controller class I had a Popup popup = new Popup(); then I had a method where I handle the button from my popup class popup.getButton().setOnAction(e -> addPlayers());

But this is not possible using fxml. I cant seem to get the object that is running. If I were to create a Popup popup I will just get a new event not the one that is being ran.

CookieMonster
  • 241
  • 1
  • 9
  • 26

1 Answers1

0

The way to do this most similar to your previous approach would be adding the getButton() method to to your controller class and get the controller class from the FXMLLoader:

Parent popupRoot = fxmlLoader.load();
MyController controller = fxmlLoader.<MyController>getController();
controller.getButton()...

Alternatives

However I recommend a different approach to passing the data, since this way you limit yourself to a single button in the popup as the only way to submit the players. I'd rather do this by "notifying" the class creating the popup, i.e:

Implement this interface in the calling class

public interface PlayerContainer {
    void addPlayers(Player[] players);
}

and add this to the controller:

private PlayerContainer playerContainer;

public void setPlayerContainer(PlayerContainer playerContainer) {
    this.playerContainer = playerContainer;
}

And pass the calling class to the controller directly after loading the popup content:

Parent popupRoot = fxmlLoader.load();
MyController controller = fxmlLoader.<MyController>getController();
controller.setPlayerContainer(this);

and when the user submits the player data, simply call

this.playerContainer.addPlayers(playerData);

in addition to closing the window. Passing a ObservableList<Player> to the controller class instead and adding all players to this list would work too, if you handle changes to the list appropriately in the calling class.

Take a look at jewelsea's answer to "Passing Parameters JavaFX FXML". This lists some alternative ways to can pass objects to the controller of the fxml. The Setting a Controller on the FXMLLoader approach could be easy to implement, e.g. if you use a inner class of the calling class as the controller class. This way it's harder to reuse the popup than with the approach described above however...

Community
  • 1
  • 1
fabian
  • 80,457
  • 12
  • 86
  • 114