JavaFX - 无法将控制器与数据阵列链接

时间:2014-09-22 10:46:57

标签: java user-interface javafx

我正在编写音乐播放器而我无法将我的Observable Array与控制器中定义的TableView链接起来。当项目运行时,我在评论下在线上获得NullPointerException。我不知道是什么让它发生以及如何解决这个问题。

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());
   }

}

2 个答案:

答案 0 :(得分:2)

在获取控制器之前,您需要调用实例化对象的loader.load()方法,而不是使用静态方法,请查看here以获取详细信息。

答案 1 :(得分:0)

这里有几件事需要考虑。为了获得控制器,您需要记住以下事项:

  • 使用FXMLoader引用加载FXML
  • 调用非静态load方法。为此,请将InputStream作为参数传递。

Main.Java内,您应该:

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

如果您不想使用InputStream,您还可以在构造函数中传递资源并调用非staic load()方法

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