Javafx在使用计时器时不在fx应用程序线程上 - java

我正在用这个

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)

而且我真的不明白怎么了

参考方案

可能是因为您误解了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();
}

JavaFX FXML无效类型 - java

我正在Linux中用Eclipse编写JavaFX应用程序,并使用SceneBuilder编写了某些FXML代码。当我移至Windows时,如果我尝试执行代码,它将运行良好,但是,如果我尝试修改fxml文件,它将开始给我一个错误(与修改无关)。我也尝试使用NetBeans,但没有任何改变。错误是:javafx.fxml.LoadException: Ligh…

JavaFX DatePicker设置日期值的对齐方式 - java

当我使用JavaFX的Datepicker并使用节点的整个宽度时,日期选择器的文本不会居中。我尝试使用setStyle("-fx-alignment: center;"),但这不起作用。我想要这样的东西(用油漆做):如何将文字居中?这是示例代码:import java.time.LocalDate; import javafx.appli…

JavaFX WebView URL.createObjectURL未定义 - java

我正在使用JavaFX 8嵌入式WebView。我想从Blob图片构建Blob URL。但是,URL.createObjectURL给了我未定义的信息。在JavaFX 8 WebView环境中,是否有任何方法(匀场等)从Blob对象创建Blob URL? 参考方案 看来目前尚不支持它,但是Java 9将于9月发布。https://bugs.openjdk.j…

JavaFX FXMLLoader:从jar文件加载时未设置位置 - java

我有一个问题,当我将项目导出到jar文件时,会出现错误:java.lang.IllegalStateException: Location is not set. 这是由于我试图做出如下所示的视图而引起的:public View(Stage stage) throws IOException { loader = new FXMLLoader(getClas…

Java FX 2 CSS伪类 - java

如何在Java FX 2中创建自己的CSS伪类?这样在CSS文件中我可以使用这种样式.MyButton : online{ } 在FX 1中,可以使用诸如 public long impl_getPseudoClassState() {} 但现在不推荐使用它们:-(有没有新的方法? 参考方案 目前您无法做到。这是JavaFX CSS Reference Gu…