azerphoenix
@azerphoenix
Java Software Engineer

Как устранить проблему в Spring Boot + JavaFX?

Доброго времени суток!
Постараюсь максимально кратко описать проблему.
Использую связку Spring Boot + JavaFX для создания небольшого десктопного приложения.
Пример интеграции JavaFX + Spring + Spring Security взял отсюда -
https://github.com/emorgado/javafx-springboot-spri...

Итак, собственно сама проблема:
1) По клику на пункте меню открывается новое окно.
@FXML
public void addNewPatientMenu(ActionEvent event) {

        try {

            Stage newPatientStage = new Stage();
            newPatientStage.setTitle("Добавить нового пациента");
            PatientController patientController = applicationContext.getBean(PatientController.class);
            Scene newPatientScene = new Scene(patientController.getView());
            newPatientStage.setScene(newPatientScene);
            newPatientStage.setMaximized(true);
            newPatientStage.showAndWait();

        } catch (IOException e) {
            e.printStackTrace();
        }

    }

Если нажать на кнопку "Отмена", то срабатывает следующий код и окно закрывается.
@FXML
    public void cancelPatientButtonAction(ActionEvent event) {
        Stage stage = (Stage) cancelPatientButton.getScene().getWindow();
        stage.close();
    }


При попытке повторного открытия - Исключение:
IllegalArgumentException: AnchorPane is already set as root of another scene

И соответственно, указанное выше окно при повторном обращении не открывается. Прогуглил и глянул на stackoverflow, там есть решение проблемы, но почему-то вместе с Spring Security не удается все это дело "подружить".

Как устранить данную проблему? При надобности могу предоставить доступ к самому проекту на GitHub (а лучше на BitBucket).

Заранее благодарен!

P.S. Тут какой нюанс...
Сама ошибка возникает по следующей причине:
The exception is pretty self-explanatory: the anchor pane cannot be the root of two different scenes. Instead of creating a new scene every time, just replace the root of the existing scene:

https://stackoverflow.com/questions/46328192/javaf...

Но в данном случае Parent root он получает из следующего контроллера, как и указано в проекте на github (по ссылке выше)

public class FXMLController {

    Logger log = LoggerFactory.getLogger(FXMLController.class);

    private static String prefix = "Controller";

    private Parent root;

    public Parent load() throws IOException {
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource(getFxmlName()));
        loader.setControllerFactory(clz -> this);
        return loader.load();
    }

    private String getFxmlName(){
        String name = this.getClass().getSimpleName();
        name = name.replaceAll("\\.", "/");
        if(name.endsWith(prefix)){
            name = name.substring(0, name.lastIndexOf(prefix));
        }
        return String.format("/fxml/%s.fxml", name).toLowerCase();
    }

    public Parent getView() throws IOException{
        if(root == null){
            root = load();
        }
        return root;
    }
}
  • Вопрос задан
  • 104 просмотра
Решения вопроса 1
@Cheypnow
При первом вызове
Scene newPatientScene = new Scene(patientController.getView());
создается root, который при следующем вызове будет использован повторно.
Поэтому и ошибка
AnchorPane is already set as root of another scene
- один и тот же root используется для двух сцен.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Bell Integrator Ульяновск
До 400 000 ₽
Bell Integrator Хабаровск
До 400 000 ₽
Bell Integrator Ижевск
До 400 000 ₽
19 апр. 2024, в 20:43
20000 руб./за проект
19 апр. 2024, в 20:11
500 руб./за проект