8

私のシーンは、画像を表示するIm​​ageViewのみで構成されています。画像を黒(シーンに割り当てられた色)にフェードさせてから、しばらくしてから再び黒から画像にフェードします。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()。その結果、2番目の遷移のみが表示されます。最初の遷移が終了するのを待ってから、2番目の遷移を開始するにはどうすればよいですか?スレッドがメインの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

ft2あなたがの反射アニメーションであるft1場合はOK

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

そして、あなたはしませんft2ft2それでもプレイする必要がある場合ft1

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 に答える