George
George

Reputation: 3

JavaFX: Adding a new tab from a tab controller

I am trying to make it such that I can create a new tab for my TabPane from within another tab but I am having some difficulty. Currently I have the TabPane set up in the "main-window.fxml" with the corresponding MainWindowController. I have a tab within this TabPane which, via fx:include, displays "mainTab.fxml" to the scene graph, controlled by MainTabController. Now from within the "mainTab" I want a button to be able to add an additional tab to the TabPane, but since this is requires a reference to the TabPane in "main-window", I have created a static method in "main-window". When the run the code below I get a NullPointerException on this line in the MainWindowController:

mainTabPane.getTabs().add(new Tab(team.getTeamName()));

Could someone please tell me as to why it is giving this exception and how I can begin to work around it?

main-window.fxml:

<TabPane fx:id="mainTabPane">
    <tabs>
        <Tab fx:id="mainTab" text="Main" closable="false">
            <fx:include source="mainTab.fxml" fx:id="mainWindowTab" alignment="CENTER"/>
        </Tab>                
    </tabs>
</TabPane>

mainTab.fxml (the event handler for the button):

@FXML
public void handleSubmit() {
    String teamName = teamNameTextField.getText();
    Roster roster = rosterComboBox.getValue();
    int startWeek = spinner.getValue();
    Team newTeam = new Team(teamName, startWeek, roster);
    TeamData.addTeam(newTeam);
    MainWindowController controller = new MainWindowController();
    controller.createTeamTab(newTeam);

}

MainWindowController:

public class MainWindowController {

    @FXML
    private TabPane mainTabPane;

    public void createTeamTab(Team team) {
        mainTabPane.getTabs().add(new Tab(team.getTeamName()));

    }
}

Upvotes: 0

Views: 1581

Answers (1)

James_D
James_D

Reputation: 209225

Your code doesn't work because you are not calling createTeamTab(...) on the controller: you are calling it on another instance of MainWindowController that you created. (The fields annotated @FXML are initialized in the controller instance by the FXMLLoader when the FXML is loaded: for fairly obvious reasons they will not be set to the same values in arbitrary other instances of the same class.) You need to get a reference to the controller you are using for the main tab, and pass it a reference to the main controller.

You didn't tell us the class name for the controller of mainTab.fxml: I will assume it is MainTabController (so just change it to whatever class name you actually use).

In MainWindowController, do:

public class MainWindowController {

    @FXML
    private TabPane mainTabPane;

    @FXML
    // fx:id of the fx:include with "Controller" appended
    private MainTabController mainWindowTabController ; 

    public void initialize() {
        mainWindowTabController.setMainWindowController(this);
    }

    public void createTeamTab(Team team) {
        mainTabPane.getTabs().add(new Tab(team.getTeamName()));

    }
}

and then in MainTabController do

public class MainWindowController {

    private MainWindowController mainWindowController ;

    public void setMainWindowController(MainWindowController mainWindowController) {
        this.mainWindowController = mainWindowController ;
    }

    @FXML
    public void handleSubmit() {
        String teamName = teamNameTextField.getText();
        Roster roster = rosterComboBox.getValue();
        int startWeek = spinner.getValue();
        Team newTeam = new Team(teamName, startWeek, roster);
        TeamData.addTeam(newTeam);
        mainWindowController.createTeamTab(newTeam);

    }

}

Upvotes: 1

Related Questions