0

I'm writing an music player and I can't link my Observable Array with TableView defined in controller. When project runned, I get NullPointerException on line under comment. I don't know what is making it happen and how find way around this problem.

Main.java

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.SplitPane;
import javafx.stage.Stage;


public class Main extends Application {
    ObservableList<CModel> modelData = FXCollections.observableArrayList();


    @Override
    public void start(Stage primaryStage) {
        try {
            FXMLLoader loader = new FXMLLoader();

            SplitPane root = FXMLLoader.load(getClass().getResource("Player.fxml"));

            Scene scene = new Scene(root);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());

            primaryStage.setScene(scene);

            PlayerController controller = loader.getController();

            //this line gives exception
            controller.setData(this);

            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public ObservableList<CModel> getPersonData() {
        return modelData;
    }

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

PlayerController.java

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Menu;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;

public class PlayerController {

    @FXML
    private TableView<CModel> cTable;

    @FXML
    private TableColumn<CModel, String> artCol;

    @FXML
    private TableColumn<CModel, String> albCol;

    @FXML
    private TableColumn<CModel, String> trNameCol;

    @FXML
    private TableColumn<CModel, String> trNoCol;

    @FXML
    private TableColumn<CModel, String> durCol;

    @FXML
    private Menu addFile;

    @FXML
    private Menu addFolder;

    @FXML
    private Menu savePlayL;

    @FXML
    private Menu loadPlayL;


    private Files files;



    private Main main;

    public PlayerController() {

    }

    @FXML
    private void initialize() {
        artCol.setCellValueFactory(
                new PropertyValueFactory<CModel,String>("artistName")
            );

        albCol.setCellValueFactory(
                new PropertyValueFactory<CModel,String>("albumName")
            );

        trNameCol.setCellValueFactory(
                new PropertyValueFactory<CModel,String>("trackName")
            );

        trNoCol.setCellValueFactory(
                new PropertyValueFactory<CModel,String>("trackDurationName")
            );

        durCol.setCellValueFactory(
                new PropertyValueFactory<CModel,String>("trackNumberName")
            );



    }


    @FXML 
    protected void handleAddFile(ActionEvent event) {
        files = new Files();
        files.openFile();
    }

   public void setData(Main mainApp) {
        this.main = mainApp;

        cTable.setItems(main.getPersonData());
   }

}
ItachiUchiha
  • 36,135
  • 10
  • 122
  • 176

2 Answers2

2

You need to call loader.load() method of instantiated object, instead of using static method, before getting controller, take a look here for details.

Community
  • 1
  • 1
nikis
  • 11,166
  • 2
  • 35
  • 45
0

There are few things to be considered here. In order to get the controller, you need to remember the following things :

  • Use the FXMLoader reference to load the FXML
  • Call the non-static load method. Inorder to do that pass a InputStream as a parameter.

Inside your Main.Java, you should have :

FXMLLoader loader = new FXMLLoader();
SplitPane root = (SplitPane)loader.load(getClass().getResource("Player.fxml").openStream());

If you don't want to use InputStream, you can also pass the resource in the constructor and call the non-staic load() method

FXMLLoader loader = new FXMLLoader(getClass().getResource("Player.fxml"));
SplitPane root = (SplitPane)loader.load();
ItachiUchiha
  • 36,135
  • 10
  • 122
  • 176