如何在JavaFX中正确地将对话框放入动画计时器中

如何在JavaFX中正确地将对话框放入动画计时器中,java,javafx,java-8,gluon,gluon-mobile,Java,Javafx,Java 8,Gluon,Gluon Mobile,我有一个动画计时器,当我处理结束时,如果某个条件为真,我想向用户显示一个对话框。当我尝试在stop()方法之后调用对话框时,出现了以下异常(仅在移动设备上): java.lang.IllegalStateException:在动画或布局处理期间无法进入嵌套循环 因此,对于这种情况,我解决了将对话框包装到Platform.runLater()方法中的问题 这是处理这个案子的正确方法吗 如果不是,哪一个是正确的 我使用的对话框是胶子对话框: 在这个简单的节目中不存在,只有show和wait。我在A

我有一个动画计时器,当我处理结束时,如果某个条件为真,我想向用户显示一个对话框。当我尝试在stop()方法之后调用对话框时,出现了以下异常(仅在移动设备上):

java.lang.IllegalStateException:在动画或布局处理期间无法进入嵌套循环

因此,对于这种情况,我解决了将对话框包装到Platform.runLater()方法中的问题

这是处理这个案子的正确方法吗

如果不是,哪一个是正确的

我使用的对话框是胶子对话框:


在这个简单的节目中不存在,只有show和wait。

我在
AnimationTimer
中添加了一个
警报来重现这个问题:

private long count = 0;

public BasicView(String name) {
    super(name);

    AnimationTimer timer = new AnimationTimer() {
        private long time;

        @Override
        public void handle(long now) {
            if (now - time > 1_000_000_000) {
                count++;
                if (count == 5) {
                    Alert alert = new Alert(Alert.AlertType.INFORMATION, "Hi there");
                    alert.showAndWait();
                }
                time = now;
            }

        }
    };

    setCenter(new StackPane(new Label("Hello JavaFX World!")));

    setOnShown(e -> timer.start());
    setOnHidden(e -> timer.stop());
}
无论您选择
javafx.scene.control.Alert
,此操作都会失败:

Exception in thread "JavaFX Application Thread" java.lang.IllegalStateException: showAndWait is not allowed during animation or layout processing
at javafx.scene.control.Dialog.showAndWait(Dialog.java:328)
Exception in thread "JavaFX Application Thread" java.lang.IllegalStateException: Cannot enter nested loop during animation or layout processing
at com.sun.javafx.tk.quantum.QuantumToolkit.enterNestedEventLoop(QuantumToolkit.java:570)
at com.gluonhq.charm.glisten.control.Dialog.a(SourceFile:613)
com.glionhq.charm.glisten.control.Alert

Exception in thread "JavaFX Application Thread" java.lang.IllegalStateException: showAndWait is not allowed during animation or layout processing
at javafx.scene.control.Dialog.showAndWait(Dialog.java:328)
Exception in thread "JavaFX Application Thread" java.lang.IllegalStateException: Cannot enter nested loop during animation or layout processing
at com.sun.javafx.tk.quantum.QuantumToolkit.enterNestedEventLoop(QuantumToolkit.java:570)
at com.gluonhq.charm.glisten.control.Dialog.a(SourceFile:613)
无论您是在桌面上还是在Android上运行:

04-05 17:50:48.289  9592  9627 E AndroidRuntime: java.lang.IllegalStateException: Cannot enter nested loop during animation or layout processing
04-05 17:50:48.289  9592  9627 E AndroidRuntime:    at com.sun.javafx.tk.quantum.QuantumToolkit.enterNestedEventLoop(QuantumToolkit.java:585)
04-05 17:50:48.289  9592  9627 E AndroidRuntime:    at com.gluonhq.charm.glisten.control.Dialog.a(SourceFile:613)
对话框实现(JavaFX/glion)使用
Toolkit.getToolkit().enterNestedEventLoop()
,如果您检查量程:

如果在动画中尝试此操作:

@Override
public void handle(long now) {
    System.out.println("In pulse: " + !Toolkit.getToolkit().canStartNestedEventLoop()); 
}
您将看到在动画中您的脉冲是真实的:根据animationTimer的定义,
handle
在每个脉冲上都被精确地调用

所以你不能进入嵌套的事件循环,除非你在那一瞬间避免调用
Platform.runLater()
这只是一种稍后再做的方法

因此,这将很好地工作:

@Override
public void handle(long now) {
        if (now - time > 1_000_000_000) {
            count++;
            if (count == 5) {
                Alert alert = new Alert(AlertType.INFORMATION, "Hi there");
                Platform.runLater(alert::showAndWait);
            }
            time = now;
        }
}

我假定您正在调用
showAndWait()
。根据(请参阅
@throws
部分),这应该只在事件处理程序中调用。似乎您可以在
平台上调用它。runLater(…)
,但这并没有明确的AFAIK文档记录。您可以调用
show()
吗?glion对话框中不存在show()。还有其他建议吗?哦,这是Gluon对话框,不是标准的JavaFX对话框?不知道,我根本没用过。是的,对不起,我错了。下次我会说得更具体一些