Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Stage.close()不';不工作javafx_Java_Javafx - Fatal编程技术网

Stage.close()不';不工作javafx

Stage.close()不';不工作javafx,java,javafx,Java,Javafx,我有一个主窗口,当我按下按钮时,另一个窗口会打开。 经过一定时间后,此窗口应关闭。因为它扩展了stage,所以我使用了super.close,但它不起作用。我能做什么?这可能是因为我在服务任务中关闭了它吗 public Game(int width, int height, int time) { this.width = width - 15; this.height = height - 15; this.time = time; this.layout =

我有一个主窗口,当我按下按钮时,另一个窗口会打开。 经过一定时间后,此窗口应关闭。因为它扩展了
stage
,所以我使用了
super.close
,但它不起作用。我能做什么?这可能是因为我在服务任务中关闭了它吗

public Game(int width, int height, int time) {
    this.width = width - 15;
    this.height = height - 15;
    this.time = time;

    this.layout = generateLayout();
    this.scene = new Scene(this.layout, this.width, this.height);

    super.initModality(Modality.APPLICATION_MODAL);
    super.setScene(scene);
    super.setResizable(false);
    super.setTitle(TITLE);

    this.cicle.reset();
    this.cicle.start();

    super.showAndWait();
}
cicle
中,我调用
close()

有点困惑,但这是
cicle
服务任务:

Service<Void> cicle = new Service<Void>() {
    @Override
    protected Task<Void> createTask() {
        return new Task<Void>() {
            volatile boolean waiting = false;

            @Override
            protected Void call() throws Exception {
                Timer.start();
                while (Timer.update() / 1000 < time) {
                    System.out.println(Timer.update())
                }
                close();
                return null;
            }
        };
    }
};
Service cicle=新服务(){
@凌驾
受保护的任务createTask(){
返回新任务(){
易失性布尔等待=假;
@凌驾
受保护的Void调用()引发异常{
Timer.start();
while(Timer.update()/1000
问题是您试图从JavaFX应用程序线程以外的线程关闭。查看
Stage
的文档,您将看到:

必须在JavaFX上构造和修改阶段对象 应用程序线程

JavaFX应用程序线程是作为启动的一部分创建的 JavaFX运行时的进程。请参阅应用程序类和 有关详细信息,请参阅Platform.startup(Runnable)方法

然而,
服务
在启动时将在后台线程上执行其
任务
。具体地说,
任务的
call()
方法在所述后台线程上执行。我刚刚测试了在后台线程上关闭一个
Stage
,看看会发生什么(是否会抛出异常)。结果是
java.lang.IllegalStateException:不在FX应用程序线程上;currentThread=Thread-3

您没有看到这一点的原因是您没有观察到
服务的故障。你可以看看,看看如何观察失败。答案特别提到了
任务
,但在
服务
中也存在同样的行为

要使代码正常工作,您需要做的是确保在JavaFX应用程序线程上调用
close()
。最简单的方法是在调用中包装
close()

还有其他方法:监听
state
属性,使用
setOnSucceeded(EventHandler)

Service<Void> cicle = new Service<Void>() {
    @Override
    protected Task<Void> createTask() {
        return new Task<Void>() {
            volatile boolean waiting = false;

            @Override
            protected Void call() throws Exception {
                Timer.start();
                while (Timer.update() / 1000 < time) {
                    System.out.println(Timer.update())
                }
                Platform.runLater(() -> close()); // wrapped in Platform#runLater
                return null;
            }
        };
    }
};
Service<Void> cicle = new Service<Void>() {
    @Override
    protected Task<Void> createTask() {
        return new Task<Void>() {
            volatile boolean waiting = false;

            @Override
            protected Void call() throws Exception {
                Timer.start();
                while (Timer.update() / 1000 < time) {
                    System.out.println(Timer.update())
                }
                return null;
            }
        };
    }
    @Override
    protected void succeeded() {
        close();
    }

};