如何等待JavaFX2.1中的转换结束?

如何等待JavaFX2.1中的转换结束?,java,concurrency,javafx,Java,Concurrency,Javafx,我的场景只包含一个,显示一个图像。我想将图像淡入黑色(指定的场景颜色),然后在一段时间后,再次从黑色淡入图像。我觉得这个方法非常适合这个目的。这是我的一段代码: // fade to black transition FadeTransition ft1 = new FadeTransition(Duration.millis(2000), myImageView); ft1.setFromValue(1.0); ft1.setToValue(0.0);

我的场景只包含一个,显示一个图像。我想将图像淡入黑色(指定的场景颜色),然后在一段时间后,再次从黑色淡入图像。我觉得这个方法非常适合这个目的。这是我的一段代码:

    // fade to black transition
    FadeTransition ft1 = new FadeTransition(Duration.millis(2000), myImageView);
    ft1.setFromValue(1.0);
    ft1.setToValue(0.0);
    ft1.play();

    // fade from black transition
    FadeTransition ft2 = new FadeTransition(Duration.millis(2000), myImageView);
    ft2.setFromValue(0.0);
    ft2.setToValue(1.0);
    ft2.play();
我的问题是
ft1.play()
是异步的,因此在退出
ft1.play()
之前将开始执行下面的代码。因此,我只看到第二个过渡。如何等待第一次转换结束,然后启动第二次转换?我不能让线程在两者之间休眠,因为它是主javafx线程(尝试过但不起作用)

我尝试将onFinishedProperty()方法与忙等待标志结合使用,但我永远陷入while循环。以下是我的代码:

    boolean isTransitionPlaying;
    FadeTransition ft = new FadeTransition(Duration.millis(2000), iv);
    ft.setFromValue(1.0);
    ft.setToValue(0.0);
    ft.onFinishedProperty().set(new EventHandler<ActionEvent>() {
        @Override 
        public void handle(ActionEvent actionEvent) {
            transitionPlaying = false;
        }
    });
    transitionPlaying = true;
    ft.play();

    while (transitionPlaying == true)
    {
        // busy wait
        System.out.println("still waiting...");
    }

    FadeTransition ft2 = new FadeTransition(Duration.millis(2000), iv);
    ft2.setFromValue(0.0);
    ft2.setToValue(1.0);
    ft2.play();
boolean-isTransitionPlaying;
FadeTransition ft=新的FadeTransition(持续时间.毫秒(2000年),iv);
ft.setFromValue(1.0);
ft.setToValue(0.0);
ft.onFinishedProperty().set(新的EventHandler()){
@凌驾
公共无效句柄(ActionEvent ActionEvent){
转换播放=错误;
}
});
转换播放=真;
ft.play();
while(transitionPlaying==true)
{
//忙等
System.out.println(“仍在等待…”);
}
FADETRANSION ft2=新的FADETRANSION(持续时间.毫秒(2000),iv);
ft2.setFromValue(0.0);
ft2.设定值(1.0);
ft2.play();

如何正确地进行等待?谢谢

好的,如果您的
ft2
ft1
的反射动画,请执行

ft1.setAutoReverse(true);
ft1.setCycleCount(1);
// Or
// ft1.setCycleCount(Timeline.INDEFINITE);
// to loop infinitely (blinking effect) until stop()
而且你不需要ft2。如果在
ft1
之后仍需要
ft2
播放,则

ft1.setOnFinished(new EventHandler<ActionEvent>() {

    @Override
    public void handle(ActionEvent event) {
        ft2.play();
    }
});
ft1.setOnFinished(新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent事件){
ft2.play();
}
});
在JavaFX应用程序线程上忙着等待(甚至是Thread.sleep)总是一个坏主意-你把处理UI处理的线程绑起来,这样你的转换以及UI的其余部分就永远不会更新-在忙着等待的过程中有效地冻结了你的应用程序UI。对于响应性UI,您需要尽快在FX应用程序线程上运行您的逻辑,然后放开线程,以便JavaFX系统的其余部分可以继续处理它。这就是为什么转换有异步回调的原因——一旦习惯了异步回调,这是一种非常自然的开发方式


除了Uluk的解决方案(非常好)之外,您还可以查看该类在按顺序执行转换时的处理帮助。请注意,如果您想在SequentialTransition完成后执行操作,您仍然需要将未完成的处理程序添加到SequentialTransition以在该时间执行操作。

我遇到问题,其他代码正在执行一些计算,我想在JavaFX应用程序中运行动画,但需要制作其他代码以等待动画完成。当动画完成时,我无法告诉其他代码,所以我创建了播放动画并等待其完成的方法:

    private synchronized void playAnimationAndWaitForFinish(final Animation animation) {
    if (Platform.isFxApplicationThread()) {
        throw new IllegalThreadStateException("Cannot be executed on main JavaFX thread");
    }
    final Thread currentThread = Thread.currentThread();
    final EventHandler<ActionEvent> originalOnFinished = animation.getOnFinished();
    animation.setOnFinished(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent event) {
            if (originalOnFinished != null) {
                originalOnFinished.handle(event);
            }
            synchronized (currentThread) {
                currentThread.notify();
            }
        }
    });
    Platform.runLater(new Runnable() {

        @Override
        public void run() {
            animation.play();
        }
    });
    synchronized (currentThread) {
        try {
            currentThread.wait();
        } catch (InterruptedException ex) {
            //somebody interrupted me, OK
        }
    }
}
private synchronized void play Animation和waitforfinish(最终动画){
if(Platform.isFxApplicationThread()){
抛出新的IllegalThreadStateException(“无法在主JavaFX线程上执行”);
}
最终线程currentThread=Thread.currentThread();
final EventHandler originalonfished=animation.getOnFinished();
animation.setOnFinished(新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent事件){
如果(originalOnFinished!=null){
originalOnFinished.handle(事件);
}
已同步(当前线程){
currentThread.notify();
}
}
});
Platform.runLater(新的Runnable(){
@凌驾
公开募捐{
动画。播放();
}
});
已同步(当前线程){
试一试{
currentThread.wait();
}捕获(中断异常例外){
//有人打断了我,好吗
}
}
}

要求在主JavaFX线程中不调用此方法,否则,它对我有效。

好的,您知道在play()结束后执行给定代码段的另一种方法,而不是setonfixed()?我希望能够通过我的代码组织转换,而不是围绕转换组织逻辑……不幸的是,正如您所提到的,将主线程置于睡眠/等待模式是不容易的。显示模式(确认)对话框窗口时也会遇到同样的困难。但是showAndWait(v2.2)方法将提供解决方案,它只适用于模态阶段。我想我是在想,既然转换play()是异步的,它们发生在另一个线程上,然后是JavaFX应用程序线程。这就是为什么我认为可以让主线程等待转换完成,然后再继续。现在我看到,如果应用程序线程处于睡眠状态,那么转换也无法处理,对吗?因此,我想顺序转换是我的案例中最清晰的解决方案。多亏了你和Ukuk。