JavaFX,标签空指针异常
我目前正在编写的一个程序有以下问题,我在互联网上搜索过,但我真的找不到任何东西来帮助我理解以下问题 因此,在另一个类中,我编写了一个方法,每当单击搜索按钮时执行该方法,该方法如下所示:JavaFX,标签空指针异常,javafx,nullpointerexception,label,Javafx,Nullpointerexception,Label,我目前正在编写的一个程序有以下问题,我在互联网上搜索过,但我真的找不到任何东西来帮助我理解以下问题 因此,在另一个类中,我编写了一个方法,每当单击搜索按钮时执行该方法,该方法如下所示: public void searchButton(){ try { new SearchController().display(); } catch (IOException e) { e.printStackTrace();
public void searchButton(){
try {
new SearchController().display();
} catch (IOException e) {
e.printStackTrace();
}
}
然后SearchController类看起来像这样(我在这里简化了它):
有人能告诉我为什么可以在initialize方法上写入文本(该方法在borderPane=loader.load();
line之后被调用…那么如果我尝试在该行之后的标签上写入,为什么不起作用?)
提前感谢FXML加载器创建FXML根元素的
fx:controller
属性中指定的类的实例。然后,当fx:id
属性与字段名匹配时,它将FXML文件中定义的元素注入到它创建的控制器实例中。然后对该实例调用initialize()
方法
使用newsearchcontroller()
“手动”创建控制器实例。这与fxmloader
创建的对象不同。因此,现在当您加载fxml文件时,您有两个不同的SearchController
实例。因此,如果从display()
方法调用what.setText(…)
,则不会在FXMLLoader
创建的控制器实例上调用它。因此,what
在您调用what.setText(…)
的实例中没有初始化,您会得到一个空指针异常
由于
initialize()
由fxmloader
对其创建的实例调用,因此当您从initialize()
方法调用what.setText(…)
时,您是在fxmloader
创建的实例上调用它,因此,该实例的FXML注入字段已经初始化。另外,请注意,如果您加载FXML文件两次(并且同时显示这两个字段),那么您的静态
字段将是一场灾难。你根本不需要这些,它们是等待发生的bug。您可以使用cancelButton.setOnAction(e->cancelButton.getScene().getWindow().hide())
关闭窗口(并去掉stage
字段。如果确实需要borderPane
字段,将其作为实例变量并从fxml文件中注入(即,删除static
,只需将fx:id=“borderPane”
放在fxml的根元素上)。谢谢你的解释,我刚刚启动了JavaFX,所以我还不太清楚。那么打开新窗口的好方法是什么?不仅仅是在这种情况下,一般来说?因为直到现在我认为我应该通过创建控制器类的新对象来实现这一点。使用默认设置,FXMLLoader
创建cont因此,在该设置中,您永远不应该自己创建控制器对象method正是创建新窗口并在其中显示fxml文件内容所需的代码,但在controller类中将其作为实例方法是没有意义的;您通常只需要在应用程序中需要创建窗口的位置使用此代码。哦,我明白了。再次感谢,它看起来像我误解了这个概念。只是另一个简单的问题:这个:SearchController a=loader.getController()
没有创建一个新的实例,对吗?我想我现在得到了这个概念,多亏了你:loader.getController()
给你加载程序创建的控制器(您需要在调用load()
之后调用它,如果您稍微考虑一下,就会发现其中的原因)
public class SearchController {
@FXML
private Button cancelButton;
@FXML
private Label what;
private static Stage stage;
private static BorderPane borderPane;
@FXML
public void initialize(){
what.setText("Testing"); // this woks
cancelButton.setOnAction(e -> stage.close());
}
public void display() throws IOException {
stage = new Stage();
stage.setResizable(false);
stage.setTitle("Product search");
stage.initModality(Modality.APPLICATION_MODAL);
FXMLLoader loader = new FXMLLoader();
loader.setLocation(SearchController.class.getResource("Search.fxml"));
borderPane = loader.load();
Scene scene = new Scene(borderPane);
stage.setScene(scene);
//what.setText("Testing") and this doesn't work
stage.showAndWait();
}
}