如何在EventHandler中使用FXMLLoader?

时间:2015-11-25 00:04:42

标签: java javafx javafx-2 scenebuilder

我正在创建一个ListView,它能够双击每个项目,并有一个窗口弹出窗口,输入由FXML文件构成。 FXML文件itemStep包含fx:controller =" controller.ItemStep"

listViewVariable.setOnMouseClicked(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent mouseEvent) {

        if (mouseEvent.getButton().equals(MouseButton.PRIMARY)) {
            if (mouseEvent.getClickCount() == 2) {
                ItemStep item = listViewVariable.getSelectionModel()
                        .getSelectedItem();
                if (item != null) {
                    try {
                    FXMLLoader isLoader = new FXMLLoader(Main.class.getResource("/view/itemStep.fxml"));
                    AnchorPane pane = isLoader.load();
                    Scene scene = new Scene(pane);
                    Stage stage = new Stage();
                    stage.setScene(scene);
                    item.setUrl(item.urlField.getText());

                    stage.show();

                    stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
                        public void handle(WindowEvent we) {
                            item.setUrl(item.urlField.getText());
                        }
                    });
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }

            }
        }
    }
});

我使用上面的内容继续得到以下错误。我需要能够在这个阶段使用FXML文件。

Caused by: java.lang.InstantiationException: controller.ItemStep
    at java.lang.Class.newInstance(Unknown Source)
    at sun.reflect.misc.ReflectUtil.newInstance(Unknown Source)
    ... 44 more
Caused by: java.lang.NoSuchMethodException: controller.ItemStep.<init>()
    at java.lang.Class.getConstructor0(Unknown Source)
    ... 46 more

1 个答案:

答案 0 :(得分:1)

您的ItemStep班级没有no argument constructor

  

每次双击[click]后,是否会重新创建一个新的ItemStep实例?

是的,这就是你编写代码的原因。

如果你不希望这样做,你应该在事件处理程序之外的FXMLLoader上调用load方法,将加载窗格的引用存储在final变量中,并在事件处理程序中使用该引用,而不是而不是每次调用事件处理程序时加载新的窗格时间。

  

当我在事件处理程序外调用加载FXMLLoader和最终的AnchorPane时我得到:AnchorPane @ ed39805 [styleClass = root]已经设置为另一个场景的根

您不能将节点多次添加到多个场景或单个场景中,您必须将其从原始场景中删除,或者仅使用节点的单个实例重新使用原始场景。我不知道你想要什么样的行为,但是,你可能只想弹出一个窗口并将其设为modal,而不是每当有人点击某个东西时创建一个新窗口。

基本上,你做的是这样的事情(虽然这只是我从未编译或执行的大纲,因为我不完全了解你的完整要求,也不知道你的ItemStep和urlField是什么):

final FXMLLoader isLoader = new FXMLLoader(Main.class.getResource("/view/itemStep.fxml"));
final AnchorPane pane = isLoader.load();
final Scene scene = new Scene(pane);
final Stage stage = new Stage();
stage.initModality(Modality.APPLICATION_MODAL);
stage.setScene(scene);

listViewVariable.setOnMouseClicked(event -> {    
    if (mouseEvent.getButton().equals(MouseButton.PRIMARY) && (mouseEvent.getClickCount() == 2)) {
        ItemStep item = listViewVariable.getSelectionModel().getSelectedItem();
        if (item != null) {
            stage.showAndWait();
            item.setUrl(item.urlField.getText());
        }
    }
});