8

我的场景仅包含一个ImageView,显示图像。我想将图像淡化为黑色(场景的指定颜色),然后在一段时间后再次从黑色淡化为图像。我发现FadeTransition非常适合此目的。这是我的一段代码:

    // 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();

等待是如何正确完成的?谢谢

4

3 回答 3

21

好的,如果你ft2ft1那么做的反射动画

ft1.setAutoReverse(true);
ft1.setCycleCount(1);
// Or
// ft1.setCycleCount(Timeline.INDEFINITE);
// to loop infinitely (blinking effect) until stop()

而你没有ft2。如果之后还需要ft2ft1

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

    @Override
    public void handle(ActionEvent event) {
        ft2.play();
    }
});
于 2012-06-25T11:15:18.220 回答
4

在 JavaFX 应用程序线程上忙于等待(甚至是 Thread.sleep)总是一个坏主意——你占用了处理 UI 处理的线程,因此你的转换以及你的 UI 的其余部分永远不会更新——有效地冻结你的繁忙等待期间的应用程序 UI。对于响应式 UI,您需要尽快在 FX 应用程序线程上运行逻辑,然后让线程运行,以便 JavaFX 系统的其余部分可以继续处理它。这就是过渡具有异步回调的原因——一旦你习惯了它们,这就是一种非常自然的开发方式。

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

于 2012-06-25T17:25:47.000 回答
1

我在其他代码进行一些计算时遇到问题,我想在 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
        }
    }
}

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

于 2014-06-10T17:41:16.420 回答