-1

I am having trouble figuring out why I get this error:

*java.lang.NullPointerException: Cannot invoke "javafx.scene.control.TabPane.getTabs()" because "this.TabPane" is null*

When I call the method addTab() from the NewProjectController class it gives me the error, If I call the method within the WorkspaceController class, it will work fine.

Can anyone figure out how to fix this?

public class WorkspaceController {
    @FXML
    private Button LogoutButton;

    @FXML
    private Button editProfileButton;

    @FXML
    private Label usernameDisplayLabel;

    @FXML
    private ImageView ImageDisplay;
    
    @FXML
    private MenuItem newProjectMenui;
    
    @FXML
    private TabPane TabPane;

    private Stage stage;
    protected Stage parentStage;
    public UserModel model;
    public User user;
    
    public WorkspaceController(Stage parentStage, UserModel model, User user) {
        this.stage = new Stage();
        this.parentStage = parentStage;
        this.model = model;
        this.user= user;
    }
    
    public WorkspaceController() {
    }

    public void exitButtonOnAction(ActionEvent event) {
        stage.close();
        parentStage.show();
    }

    public void EditProfileOnAction(ActionEvent event) throws SQLException {
        try {
            FXMLLoader loader = new FXMLLoader(getClass().getResource("/resources/View/EditProfileView.fxml"));
        
            Callback<Class<?>, Object> controllerFactory = param -> {
                return new EditProfileController(stage, model);
            };
            loader.setControllerFactory(controllerFactory);
            
            Pane root = loader.load();

            EditProfileController editProfileController = loader.getController();
            editProfileController.displayUname(user.getUsername());
            editProfileController.showStage(root);
            InputStream imp = (user.getInputStream());
                
            editProfileController.displayProfileImage(imp);     
        } catch (IOException | RuntimeException e) {
            e.printStackTrace();
        } 
    }
    
    public void imgTest(InputStream imp) {
        Pane pane = new HBox(15);
        Image img = new Image(imp);
        pane.getChildren().add(new ImageView(img));
        Scene scene = new Scene(pane, 600, 300);
        stage.setScene(scene);
        stage.show();
    }
    
    public void showStage(Pane root) {
        Scene scene = new Scene(root, 1403, 894);
        stage.setScene(scene);
        stage.setResizable(false);
        stage.setTitle("Workspace");
        stage.show();
        
    }
    
    public void displayUser(String loggedInUser) {
        usernameDisplayLabel.setText(loggedInUser);
    }
    
    public void displayProfileImage(InputStream imageFile) throws SQLException {
        Image image = new Image(imageFile);
        ImageDisplay.setImage(image);
    }
    
    public void newProjectOnAction(ActionEvent event) throws IOException {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/resources/View/NewProjectView.fxml"));
        
        Callback<Class<?>, Object> controllerFactory = param -> {
            return new NewProjectController(stage, model);
        };
            
        loader.setControllerFactory(controllerFactory);
            
        Pane root = loader.load();
        NewProjectController newProjectController = loader.getController();
        newProjectController.showStage(root);
    }
    
    public void addTab()  {
        TabPane.getTabs().addAll(getTab());
    }
    
    public final ObservableList<Tab> getTab(){
        ObservableList<Tab> tabs = FXCollections.observableArrayList();
        tabs.add(new Tab("tab1"));
        return tabs;
    }

    
}

public class NewProjectController {
    @FXML
    private TextField NewProjectTextField;

    @FXML
    private Button okButton;

    @FXML
    private Button cancelButton;
    
    private Stage stage;
    private Stage parentStage;
    public UserModel model;
    public User user;
    
    public NewProjectController(Stage parentStage, UserModel model) {
        this.stage = new Stage();
        this.parentStage = parentStage;
        this.model = model;
    }

    public void showStage(Pane root) {
        Scene scene = new Scene(root, 454, 155);
        stage.setScene(scene);
        stage.setResizable(false);
        stage.setTitle("Create a new project");
        stage.show();
    }

    @FXML
    public void addNewProject(ActionEvent event){
        WorkspaceController workspaceController = new WorkspaceController();
        workspaceController.addTab();   
    }
}
Ash
  • 1
  • 1
  • 2
    You need to call the method on the actual controller (created for you when you load the relevant FXML file), not on some arbitrary object you create that just happens to be the same class. – James_D Oct 25 '21 at 00:31
  • 1
    I'd recommend having a look at [Using FXML to Create a User Interface](https://docs.oracle.com/javafx/2/get_started/fxml_tutorial.htm) to see how you "should" load a view based on FXML – MadProgrammer Oct 25 '21 at 00:38
  • Java is case-sensitive; instead of `TabPane TabPane`, try `TabPane tabPane` to declare an instance of `TabPane` named `tabPane`. – trashgod Oct 25 '21 at 03:27

1 Answers1

1

This:

WorkspaceController workspaceController = new WorkspaceController();

Creates a WorkspaceController Object which has no connection at all with the stage that you are trying to control. It is a POJO if I can put it like that. If you want to use the functional Controller you have to get it like this the moment you load it:

....

FXMLLoader loader = new FXMLLoader();
loader.setLocation(....)); // Your .fxml File

Parent content = loader.load();

 WorkspaceController workspaceController = loader.getController(); // This object here is what you need and want
 // You could save this somewhere globaly so that each Controller can access it.

....
Renis1235
  • 4,116
  • 3
  • 15
  • 27