JavaFX canvas 重绘不执行任何操作

JavaFX canvas redraw doesn't do anything

我有一个Canvas,我在上面画了一架飞机,在一个特定的位置(第一张画的很好)。当我的程序运行时,我需要从另一个服务器采样飞机位置并相应地更新我的飞机位置。

一切正常(参数明智),除了没有重绘..

编辑:更正 - 在原来的飞机顶部画了一点污迹,然后没有其他事情发生

我的代码:

public class AirplaneDrawer extends Canvas{
    double x,y,rotate;

    public void setCords(double x,double y,double rotate) {
        if(x != this.x || y != this.y || rotate != this.rotate) {
            this.x = x;
            this.y = y;
            this.rotate = rotate;
            redraw();
        }
    }

    public void redraw() {
        GraphicsContext gc = getGraphicsContext2D();
        String path = new String("M 323.193 226.645 c 39.244 24.41 75.644 47.053 115.706 71.978 c 7.687 -5.443 20.518 -14.485 33.308 -23.596 c 16.733 -11.923 36.27 -11.452 49.046 3.779 c 3.513 4.191 2.568 15.766 -0.705 21.426 c -23.705 40.994 -48.427 81.404 -73.095 121.833 c -4.729 7.745 -9.06 19.278 -21.177 13.509 c -12.203 -5.8 -28.746 -9.521 -27.842 -28.026 c 0.891 -18.185 3.495 -36.292 4.924 -50.249 c -40.704 -19.793 -79.74 -38.778 -119.825 -58.269 c -16.168 17.561 -22.275 40.532 -27.606 64.119 c -8.975 39.719 -18.474 79.324 -28.171 118.881 c -5.593 22.809 -12.452 26.109 -34.167 17.908 c -28.122 -10.606 -31.047 -14.689 -31.318 -45.384 c -0.605 -68.198 -1.514 -136.4 -1.325 -204.593 c 0.045 -15.865 -4.177 -25.531 -19.237 -32.95 c -30.238 -14.884 -60.119 -30.866 -88.548 -48.915 c -13.988 -8.884 -26.951 -21.77 -35.867 -35.727 C 3.526 110.834 15.381 90.43 40.637 91.746 c 17.786 0.931 36.644 4.67 52.618 12.229 c 32.58 15.413 63.735 33.905 95.022 51.921 c 8.735 5.028 15.083 4.992 23.944 0.068 c 64.671 -35.921 129.717 -71.172 194.611 -106.705 c 25.712 -14.075 46.608 -10.335 65.331 12.008 c 10.309 12.302 2.247 20.797 -6.506 28.579 c -35.89 31.91 -72.438 63.093 -107.682 95.687 C 344.877 197.641 334.677 212.878 323.193 226.645 Z");
        double wid = getWidth()/247;
        double hei = getHeight()/152;
        gc.translate(wid*x,hei*y);
        gc.scale(0.02,0.02);    
        gc.rotate(rotate);
        gc.appendSVGPath(path);
        gc.setFill(Color.BLACK);
        gc.fill();
        gc.stroke();
    }

}

我想也许 GraphicContext 记得最后一个 scale/translate/rotatation ,所以我尝试在 setCords 方法中 if 的开头添加第二个 if ,如果这不是第一幅画,向后撤消这些步骤,但它没有改变任何东西。

编辑:如果我使用这个条件,那么我之前在第一次编辑中提到的污迹不会出现,也不会重绘任何东西

        if(this.x!=0 || this.y!= 0 || this.rotate != 0) {
            GraphicsContext gc = getGraphicsContext2D();
            double wid = getWidth()/247;
            double hei = getHeight()/152;
            gc.rotate(-this.rotate);
            gc.scale(50, 50);
            gc.translate(-wid*this.x,-hei*this.y);
        }

我做错了什么? (我已经调试并看到 setCords 正在根据需要使用正确的参数调用)

注意:我不知道这是否重要,但是对 setCords 的调用是在单独的线程中进行的,因此我的程序将照常继续。

谢谢!

你提到:

Note: I dont know if it matter, but the call to setCords is being made in a separete Thread, so my program will continue as usual .

这很重要。来自 GraphicsContext 的文档:

A Canvas only contains one GraphicsContext, and only one buffer. If it is not attached to any scene, then it can be modified by any thread, as long as it is only used from one thread at a time. Once a Canvas node is attached to a scene, it must be modified on the JavaFX Application Thread.

Calling any method on the GraphicsContext is considered modifying its corresponding Canvas and is subject to the same threading rules.

如果您在后台线程上,您可以使用 Platform.runLater(Runnable). Take care not to flood the FX thread with too many actions, however. You may want to consider using an AnimationTimer 代替或可能与(使用适当的同步)单独的线程一起将操作发布到 FX 线程。

此外,请注意,在 Canvas 上绘图不会清除之前绘制的任何内容。要模拟运动,您需要清除适当的区域(或在其上绘制,例如使用背景),然后在不同的位置重新绘制。这可以具体到仅 clearing/drawing 改变了什么,也可以像每次重绘整个 canvas 一样笼统。