我有一个JavaFX应用程序,我在画布上绘制。图纸跟随鼠标。这种移动有点滞后,因为渲染需要一些时间。到目前为止还不错。但是当我停止鼠标时,它的坐标有时仍处于旧位置。
以下代码重现了该问题:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.SceneBuilder;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Ellipse;
import javafx.scene.shape.EllipseBuilder;
import javafx.stage.Stage;
public class TestApp extends Application
{
public static void main(String[] args)
{
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception
{
Pane p = new Pane();
final Ellipse ellipse = EllipseBuilder.create().radiusX(10).radiusY(10).fill(Color.RED).build();
p.getChildren().add(ellipse);
p.setOnMouseMoved(event ->
{
ellipse.setCenterX(event.getX());
ellipse.setCenterY(event.getY());
Platform.runLater(() -> doSomeWork());
});
Scene scene = SceneBuilder.create().root(p).width(1024d).height(768d).build();
primaryStage.setScene(scene);
primaryStage.show();
}
void doSomeWork()
{
try
{
Thread.sleep(100);
}
catch (Exception ignore) { }
}
}
当你快速移动鼠标并突然停止时,圆圈有时不在鼠标下面。
我使用过或不使用Platform.runLater()或通话订单。没有成功。
修改 我无法在Windows下重现此行为。
答案 0 :(得分:1)
我的假设是在UI-Thread和onMouseMoved
上调用Platform.runLater
。这会阻止UI-Thread,因此,最后onMouseMoved
次调用将被丢弃(这使得该圈位于onMouseMoved
的最后一次调用的位置)。正如Platform.runLater-Doc:
此外,长时间运行的操作应尽可能在后台线程上完成,从而释放JavaFX应用程序线程以进行GUI操作。
因此,尝试在额外线程上完成工作,并在计算完成后通过runLater
将其发布到用户界面:
public class TestApp extends Application
{
public static void main(String[] args)
{
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception
{
Pane p = new Pane();
final Ellipse ellipse = EllipseBuilder.create().radiusX(10).radiusY(10).fill(Color.RED).build();
p.getChildren().add(ellipse);
p.setOnMouseMoved(event ->
{
ellipse.setCenterX(event.getX());
ellipse.setCenterY(event.getY());
doSomeWork();
});
Scene scene = SceneBuilder.create().root(p).width(1024d).height(768d).build();
primaryStage.setScene(scene);
primaryStage.show();
}
void doSomeWork()
{
new Thread(){
public void run(){
try
{
Thread.sleep(100);
Platform.runLater(() -> {
// ui updates
});
}
catch (Exception ignore) { }
}
}.start();
}
}