-1

JavaFX doesn't show a dialog box like it is supposed to when the window close is called from a thread.

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class Main extends Application
{

    public static void main(String[] args)
    {
        launch(args);
    }

    @Override
    public void start(Stage stage) throws Exception
    {

        Task<Void> task = new Task<Void>()
        {
            @Override
            public Void call() {
                VBox vBox = new VBox();
                vBox.getChildren().add(new Label("Label"));
                stage.setScene(new Scene(vBox));
                return null;
            }
        };
        new Thread(task).start();
        stage.show();
//      VBox vBox = new VBox();
//      vBox.getChildren().add(new Label("Label"));
//      stage.setScene(new Scene(vBox));
    }
}

When I run the code, I only see a black window. If I comment out the code, I see a window that says "Label".

In my actual application, I want the scene to change depending on user input to the other thread.

If I cannot call JavaFX functions from another thread, how should I do this?

discape
  • 337
  • 1
  • 15
  • @James_D what should I do then? – discape Jun 10 '20 at 19:32
  • "Depending on user input to the other thread": how are you getting user input in a background thread? Or do you just mean input that comes from a call to some external resource (network or database or some such) – James_D Jun 10 '20 at 19:37
  • Here are a couple of other questions/answers that may be useful: https://stackoverflow.com/questions/30249493/using-threads-to-make-database-requests/30250308#30250308 https://stackoverflow.com/questions/14941084/javafx2-can-i-pause-a-background-task-service – James_D Jun 10 '20 at 20:13

1 Answers1

3

Try call stage.fireEvent() on Javafx Thread using Platform.runLater(()->{}).

Example:

public Void call() {
    try {
        Thread.sleep(2000);
    }
    catch (InterruptedException e) {
    }
    System.out.println("Sending close request two:");
    Platform.runLater(() -> stage.fireEvent(new WindowEvent(stage, WindowEvent.WINDOW_CLOSE_REQUEST)));
    System.out.println("Sent close request two:");
    return null;
}
Tix
  • 610
  • 6
  • 16
  • Platform.runLater is not suitable for my application since I need to have a separate thread constantly running alongside the gui – discape Jun 10 '20 at 18:56
  • I'm only talking about the event code, now I will add an example. – Tix Jun 10 '20 at 18:58
  • don't fireEvent in application code - it has evil side-effects – kleopatra Jun 10 '20 at 21:05
  • @kleopatra could you elaborate? – discape Jun 11 '20 at 06:30
  • it's changing the sequence of event propagation by starting a whole new capturing/bubbling cycle from the top scene to the firing element .. might (and does) violate the contract of that sequence. – kleopatra Jun 11 '20 at 09:14