Juicymoo
Juicymoo

Reputation: 3

Spawning a child window in JavaFX

I need to create a popup window for a desktop application. I am communications from a client to a server via TCP and I want the window to cover the main interface while waiting for a response from the server. Basically a "Please wait for response" kind of item.

I have been able to spawn a window and have it end when the response is of a validated nature, but I am unable to show any items on the stage itself.

Label lblSecondWindow = new Label("This is the second window");
lblSecondWindow.setAlignment(Pos.TOP_LEFT);
lblSecondWindow.autosize();
lblSecondWindow.setVisible(true);
StackPane secondLayout = new StackPane();
secondLayout.getChildren().add(lblSecondWindow);
Scene secondScene = new Scene(secondLayout, 300, 200);
Stage secondStage = new Stage();
secondStage.setTitle("Please Wait");
secondStage.setScene(secondScene);
secondStage.show();

A window appears, but the label is nowhere to be found. I am willing to attack this from another way if possible as I have lost more hair on this issue than I am willing to admit.

Upvotes: 0

Views: 1314

Answers (1)

fabian
fabian

Reputation: 82461

The code you use doesn't contain the error. However I'm sure I know your error: You block the UI thread by making the server communication on the UI thread. You have to move it to a different thread to make it work.


I could reproduce your error with this code:

Label lblSecondWindow = new Label("This is the second window");
lblSecondWindow.setAlignment(Pos.TOP_LEFT);
lblSecondWindow.autosize();
lblSecondWindow.setVisible(true);
StackPane secondLayout = new StackPane();
secondLayout.getChildren().add(lblSecondWindow);
Scene secondScene = new Scene(secondLayout, 300, 200);
Stage secondStage = new Stage();
secondStage.setTitle("Please Wait");
secondStage.setScene(secondScene);
secondStage.show();
try {
    Thread.sleep(1000);
} catch (InterruptedException ex) {
} // Stands for expensive operation (the whole try catch)
secondStage.close();

but not if I comment out the try-catch block, that stands for your server communication, and secondStage.close();.

The code can be rewritten like this to make it work:

Label lblSecondWindow = new Label("This is the second window");
lblSecondWindow.setAlignment(Pos.TOP_LEFT);
lblSecondWindow.autosize();
lblSecondWindow.setVisible(true);
StackPane secondLayout = new StackPane();
secondLayout.getChildren().add(lblSecondWindow);
Scene secondScene = new Scene(secondLayout, 300, 200);
final Stage secondStage = new Stage();
secondStage.setTitle("Please Wait");
secondStage.setScene(secondScene);
secondStage.show();
new Thread() {
    @Override
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
        } // Stands for expensive operation (the whole try catch)
        Platform.runLater(new Runnable() {

            @Override
            public void run() {
                // UI changes have to be done from the UI thread
                secondStage.close();
            }
        });
    }
}.start();

Upvotes: 2

Related Questions