尝试从另一个类填充TableView时获取NullPointerException

时间:2017-08-01 02:15:00

标签: java nullpointerexception javafx-2

每当我尝试从另一个类的Executor重新填充TableView中的元素时,我会收到以下错误:

MainController Init prints main.getCurrentTime = 2017-07-31T22:31:37.969
*** MainController Initialized ***
**** createAndStartScheduler **** 
repeat every 2
Platform.isFxApplicationThread() = true
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
    at testpackage.MainController.populateTable(MainController.java:107)
    at testpackage.Refresh.lambda$null$0(Refresh.java:41)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(PlatformImpl.java:294)
    at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
    at java.lang.Thread.run(Thread.java:745)
  

MainController.java

107处的错误:nameCol.setCellValueFactory(new PropertyValueFactory<>(“name”));

  @FXML // fx:id="tableView"
  private TableView<Item> tableView; // Value injected by FXMLLoader

  @FXML // fx:id="statusCol"
  private TableColumn<Item, Boolean> statusCol; // Value injected by FXMLLoader

  @FXML // fx:id="dateCol"
  // USing string to display it because SimpleDateFormat.format returns a string
  private TableColumn<Item, String> dateCol; // Value injected by FXMLLoader

  @FXML // fx:id="nameCol"
  private TableColumn<Item, String> nameCol; // Value injected by FXMLLoader

  @FXML // fx:id="urlCol"
  private TableColumn<Item, Hyperlink> urlCol; // Value injected by FXMLLoader

  public void initialize() {
    GimmeTheFreeStuff gimmeTheFreeStuff = new GimmeTheFreeStuff();
    GetSetProps getSetProps = new GetSetProps();
    System.out.println(
        "MainController Init prints main.getCurrentTime = " + Main.getCurrentTime().toString());
    // testLink is called twice in the try
    try {
      Main.getStage()
          .setTitle("GimmeTheFreeStuff for " + gimmeTheFreeStuff.getTitle(getSetProps.getLink()));
      populateTable("");
    } catch (IOException e) {
      System.err.println("Unable to set the title OR Unable to populate table");
      e.printStackTrace();
    }
    System.out.println("*** MainController Initialized ***");
  }

public void populateTable(String temp) throws IOException {
    nameCol.setCellValueFactory(new PropertyValueFactory<>("name"));
    dateCol.setCellValueFactory(new PropertyValueFactory<>("date"));
    urlCol.setCellValueFactory(new PropertyValueFactory<>("urlLink"));
    statusCol.setCellValueFactory(new PropertyValueFactory<>("status"));
    ObservableList<Item> oList =     
    FXCollections.observableArrayList(parseItemList(temp));
    tableView.getItems().setAll(oList);
    success();
}
  

Refresh.java

41处的错误:mainController.populateTable(“”);

static void createAndStartScheduler() throws IOException {
    scheduler = Executors.newSingleThreadScheduledExecutor();
    System.out.println("**** createAndStartScheduler **** ");

    long delay = 2;

    scheduler.scheduleAtFixedRate(() -> Platform.runLater(() -> {
      MainController mainController = new MainController();
      System.out.println("repeat every " + delay);
      System.out.println("Platform.isFxApplicationThread() = " + Platform
          .isFxApplicationThread()); // returns True
      try {
        mainController.populateTable("");
      } catch (IOException e) {
        e.printStackTrace();
      }
    }), delay, delay, TimeUnit.SECONDS);
  }

由于它的NullPointerException意味着在错误118处,PropertyValueFactory“name”为null或nameCol出错。我读过的大部分答案都涉及使用Platform.runLater。我认为最接近我的问题是:JavaFX: Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException

我会假设我必须以某种方式重新初始化nameCol,dateCol等?

编辑#2(找到解决方案)

感谢Scary Wombat简单的调试建议,我添加了if(namCol == null){System.out.print(“nameCol is null”);返回;} nameCol确实是null b / c FXMLLoader初始化MainController.fxml的UI元素,并且创建MainController.java的新实例不会做任何事情。所以我只需要从Main.java获取控制器的FXMLLoader实例并使用它来更新我的TableView。

  

Main.java

FXMLLoader loader = new FXMLLoader(getClass().getResource("MainUserInterface.fxml"));
Parent root = loader.load();

MainController controller = loader.getController();
Refresh refresh = new Refresh();
refresh.setObj(controller);
  

Refresh.java

private static MainController obj;

public static MainController getObj() { return obj;}
public static void setObj(MainController obj) { Refresh.obj = obj;}
// used getObj() to update tableview instead of creating new instance of MainController

希望这有助于其他人!

0 个答案:

没有答案