O
O
Orkhan Hasanli2019-11-11 21:09:00
Java
Orkhan Hasanli, 2019-11-11 21:09:00

How to troubleshoot issue in Spring Boot + JavaFX?

Good day!
I will try to describe the problem as briefly as possible.
I am using Spring Boot + JavaFX to create a small desktop application.
An example of JavaFX + Spring + Spring Security integration was taken from here -
https://github.com/emorgado/javafx-springboot-spri...
So, the problem itself:
1) By clicking on a menu item, a new window opens.

@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();
        }

    }

If you click on the "Cancel" button, the following code is triggered and the window is closed.
@FXML
    public void cancelPatientButtonAction(ActionEvent event) {
        Stage stage = (Stage) cancelPatientButton.getScene().getWindow();
        stage.close();
    }

When trying to re-open - Exception:
IllegalArgumentException: AnchorPane is already set as root of another scene
And accordingly, the above window does not open when re-accessed. I googled and looked at stackoverflow, there is a solution to the problem, but for some reason, together with Spring Security, it is not possible to "make friends" with the whole thing.
How to fix this problem? If necessary, I can provide access to the project itself on GitHub (or better on BitBucket).
Thanks in advance!
PS Here is a nuance ...
The error itself occurs for the following reason:
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...
But in this case, it gets Parent root from the following controller, as indicated in the project on github (link above)
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;
    }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
C
Cheypnow, 2019-11-12
@azerphoenix

On first call

Scene newPatientScene = new Scene(patientController.getView());
is created root, which will be reused on the next call.
Therefore the error
AnchorPane is already set as root of another scene
- the same root is used for two scenes.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question