我正在尝试创建动画,但是没有使用诸如TranslateTransition之类的内置功能。在“锚定窗格”上,我创建了一个圆,我希望它沿着这样的直线不断移动:
public void initialize() {
MyThread task = new MyThread();
new Thread(task).start();
}
class MyThread extends Task<Integer>
{
@FXML
Circle myCircle;
@Override
protected Integer call() throws Exception
{
int i= 737; //starting position
while(true)
{
((Node) myCircle).setLayoutX(i);
i--;
if(i%109==0) //ending position
i=737;
}
}
}
但是它根本没有动。我是javaFX中线程的新手,所以我真的不知道自己在做什么错。但是当我像这样打印一些数字时,它就可以正常工作:
class MyThread extends Task<Integer>
{
@Override
protected Integer call() throws Exception
{
for(int i=0; i<10;i++)
{
count(i);
count10(i);
}
protected void count(int i)
{
System.out.println(i);
}
protected void count10(int i)
{
System.out.println(10*i);
}
}
答案 0 :(得分:1)
仅应从JavaFX应用程序线程修改JavaFX节点。您正在从后台线程修改layoutX
属性,从而产生不可靠的结果。
您可以更新value
属性,并使用Task.value
属性的侦听器来为您完成同步:
class MyThread extends Task<Integer> {
@Override
protected Integer call() throws Exception {
final int minX = (737 / 109) * 109; // use rounding of integer division to find greatest int <= 737 divisible by 109
while(true) {
for (int i = 737; i >= minX; i--) {
updateValue(i);
}
}
}
}
MyThread task = new MyThread();
task.valueProperty().addListener((o, oldValue, newValue) -> circle.setLayoutX(newValue.doubleValue()));
new Thread(task).start();
请注意,这段代码的结果可能无法预测:更新之间没有延迟,因此,绑定更新时的值可能是随机的...
否则,您必须使用Platform.runLater
来更新GUI,但这在代码中非常棘手,因为您进行更新的频率足够高,JavaFX无法处理所有{{ 1}}个提交。
我建议您改用AnimationTimer
之类的JavaFX类。这些类可供使用。自己尝试实现这样的事情可能会带来更多的麻烦,尤其是作为一个没有经验的程序员。