java 如何等待转换在 javafx 2.1 中结束?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11188018/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to wait for a transition to end in javafx 2.1?
提问by dadox
My scene consists only of an ImageView, displaying an image. I would like to fade the image to black (assigned color of the scene), then after some time, fade from black to the image again. I found the FadeTransitionvery fitting for this purpose. This is a piece of my code:
我的场景只包含一个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();
My problem is that ft1.play()
is asynchronous, so the code below will start being executed before ft1.play()
is exited. As the result I see only the second transition. How can I wait for the first transition to end and then to launch the second transition? I cannot put the thread to sleep in between because it's the main javafx thread (tried and didn't work).
我的问题是这ft1.play()
是异步的,所以下面的代码将在ft1.play()
退出之前开始执行。结果我只看到第二个过渡。如何等待第一个转换结束,然后启动第二个转换?我不能让线程在两者之间休眠,因为它是主要的 javafx 线程(尝试过但没有工作)。
I tried using the onFinishedProperty() method with the combination of a busy-waiting on a flag, but I get stuck in the while loop forever. Here is my code for that:
我尝试将 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();
How is waiting done properly? Thank you
等待是如何正确完成的?谢谢
采纳答案by jewelsea
Busy waiting (or even Thread.sleep) on the JavaFX application thread is always a bad idea - you tie up the thread which handles the UI processing so your transitions, as well as the rest of your UI, is never updated - effectively freezing your app UI for the duration of the busy wait. For a responsive UI, you need to run your logic on the FX application thread as quickly as possible, then let the thread go so the rest of the JavaFX system can get on with it's processing. This is why the transitions have async callbacks - which, once you get used to them, are a very natural way of developing.
在 JavaFX 应用程序线程上忙于等待(甚至 Thread.sleep)总是一个坏主意——你占用了处理 UI 处理的线程,因此你的转换以及你的 UI 的其余部分永远不会更新——有效地冻结你的忙等待期间的应用程序 UI。对于响应式 UI,您需要尽快在 FX 应用程序线程上运行您的逻辑,然后让线程运行,以便 JavaFX 系统的其余部分可以继续处理。这就是转换具有异步回调的原因——一旦你习惯了它们,这是一种非常自然的开发方式。
In addition to Uluk's solutions (which are great), you could also look at the SequentialTransitionclass for handling assistance in performing transitions in sequence. Note that if you want to take an action after the SequentialTransition has completed, you will still want to add an onFinished handler to the SequentialTransition to take action at that time.
除了 Uluk 的解决方案(非常棒)之外,您还可以查看SequentialTransition类来帮助处理按顺序执行转换。请注意,如果您想在 SequentialTransition 完成后采取行动,您仍然需要向 SequentialTransition 添加一个 onFinished 处理程序以在那时采取行动。
回答by Uluk Biy
Ok if your ft2
is the reflective animation of ft1
then do
好的,如果你ft2
是反射动画ft1
然后做
ft1.setAutoReverse(true);
ft1.setCycleCount(1);
// Or
// ft1.setCycleCount(Timeline.INDEFINITE);
// to loop infinitely (blinking effect) until stop()
and you don't ft2
. If you still need ft2
to play after ft1
then
而你没有ft2
。如果您还需要ft2
后打ft1
那么
ft1.setOnFinished(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
ft2.play();
}
});
回答by user3727126
I had problem where other code was doing some calculations and I wanted to run Animations in JavaFX app, but needed to make other code to wait for animation to finish. I wasn't able to tell this other code when animation has finished, so I have created method for playing Animation and then waiting for it to finish:
我在其他代码进行一些计算时遇到问题,我想在 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
}
}
}
It is required that this method is not invoked in main JavaFX thread, otherwise, it works for me.
要求此方法不在主 JavaFX 线程中调用,否则,它对我有用。