Как я могу использовать FXMLLoader внутри EventHandler?

Я создаю ListView с возможностью двойного щелчка по каждому элементу, и у меня есть всплывающее окно с входами, структурированными в файле FXML. Файл FXS 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 ответ

Решение

Ваш ItemStep Класс не имеет конструктора без аргументов.

Новый экземпляр ItemStep воссоздается после каждого двойного [щелчка]?

Да, это то, для чего вы написали свой код.

Если вы не хотите этого делать, вам следует вызвать метод load в FXMLLoader вне вашего обработчика событий, сохранить ссылку на загруженную панель в конечной переменной и использовать эту ссылку в обработчике событий, а не загружать время новой панели каждый раз, когда вызывается обработчик события.

когда я вызываю загрузочный FXMLLoader и конечный AnchorPane вне обработчика событий, я получаю: AnchorPane@ed39805[styleClass=root] уже установлен как корень другой сцены

Вы не можете добавить узел в более чем одну сцену или в одну сцену более одного раза, вы должны либо удалить его из исходной сцены, либо просто повторно использовать исходную сцену с одним экземпляром узла. Я не знаю, какое поведение вы хотите, но, возможно, вы хотите просто открыть одно окно и сделать его модальным, а не создавать новое окно каждый раз, когда кто-то нажимает на что-то.

По сути, вы делаете что-то вроде этого (хотя это всего лишь набросок, который я никогда не компилировал и не выполнял, так как я не полностью знаю ваши полные требования, а также то, каковы ваши 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());
        }
    }
});
Другие вопросы по тегам