我正在使用这个
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
Group root = new Group();
Scene scene = new Scene(root, 600, 400);
primaryStage.setScene(scene);
Circle circle = new Circle(300,200,50, Color.BLACK);
primaryStage.setTitle("Circle");
primaryStage.setResizable(false);
root.getChildren().add(circle);
moveCircle(circle, scene);
primaryStage.show();
}
public int random(int min, int max) {
return new Random().nextInt((max - min) + min);
}
public int random(int max) {
return random(0, max);
}
public void moveCircle(Circle circle, Scene scene) {
Platform.runLater(() -> {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
circle.setCenterX(random((int) scene.getX()));
circle.setCenterY(random((int) scene.getY()));
}
}, 1000, 1000);
});
}
但是这个:
public void moveCircle(Circle circle, Scene scene) {
Platform.runLater(() -> {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
circle.setCenterX(random((int) scene.getX()));
circle.setCenterY(random((int) scene.getY()));
}
}, 1000, 1000);
});
}
给我这个错误:
Exception in thread "Timer-0" java.lang.IllegalStateException: Not on FX application thread; currentThread = Timer-0
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:204)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:364)
at javafx.scene.Scene.addToDirtyList(Scene.java:485)
at javafx.scene.Node.addToSceneDirtyList(Node.java:424)
at javafx.scene.Node.impl_markDirty(Node.java:415)
at javafx.scene.shape.Shape.impl_markDirty(Shape.java:942)
at javafx.scene.shape.Circle$1.invalidated(Circle.java:136)
at javafx.beans.property.DoublePropertyBase.markInvalid(DoublePropertyBase.java:112)
at javafx.beans.property.DoublePropertyBase.set(DoublePropertyBase.java:146)
at javafx.scene.shape.Circle.setCenterX(Circle.java:122)
at Main$2.run(Main.java:48)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
我真的没有看到什么是错的
答案 0 :(得分:32)
可能是因为你误解了Platform.runLater()
的工作原理..
正确的代码段是:
public void moveCircle(Circle circle, Scene scene) {
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
Platform.runLater(() -> {
circle.setCenterX(random((int) scene.getX()));
circle.setCenterY(random((int) scene.getY()));
});
}
}, 1000, 1000);
}
<强>可是:强>
我强烈建议您不要使用Timer
,而应使用TimeLine
!它是JavaFX API的一部分,您无需执行这些Platform.runLater()
调用。这很快被黑客攻击,但你明白了:
public void moveCircle(Circle circle, Scene scene) {
Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(1), ev -> {
circle.setCenterX(random((int) scene.getX()));
circle.setCenterY(random((int) scene.getY()));
}));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}