Перерисовка холста JavaFX ничего не делает - PullRequest
0 голосов
/ 19 июня 2019

У меня есть холст, на котором я рисую самолет, в специальной локации (первый рисунок работает хорошо).Во время работы моей программы мне нужно сэмплировать местоположение самолета с другого сервера и соответствующим образом обновить местоположение моего самолета.

Все работает нормально (с учетом параметров), за исключением того, что ничего не перерисовывается ..

РЕДАКТИРОВАТЬ: Исправление - на исходном самолете рисуется небольшое пятно, а затем ничего не происходит

Мой код:

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 запоминает последнюю шкалу / перевод / вращение, поэтому я попытался добавить второй if в начале метода if in setCords, чтобы, если это не первый рисунок, отменитьэти шаги в обратном направлении, но это ничего не изменило.

РЕДАКТИРОВАТЬ: Если я использую это условие, то пятно, которое я упоминал ранее в первом редактировании, не появляется, и ничего неперерисовывается

        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сделано в отдельной теме, поэтому моя программа будет продолжаться как обычно.

Спасибо!

1 Ответ

2 голосов
/ 19 июня 2019

Вы упоминаете:

Примечание: Я не знаю, имеет ли это значение, но вызов setCords выполняется в отдельной ветке, поэтому моя программа будет продолжаться как обычно.

Это имеет значение. Из документации GraphicsContext:

A Canvas содержит только один GraphicsContext и только один буфер. Если он не прикреплен к какой-либо сцене, он может быть изменен любым потоком, если он используется только из одного потока за раз. Когда узел Canvas присоединен к сцене, он должен быть изменен в потоке приложений JavaFX.

Вызов любого метода в GraphicsContext считается изменением его соответствующего Canvas и подчиняется тем же правилам потоков.

Если вы работаете в фоновом потоке, вы можете опубликовать действие в потоке FX, используя Platform.runLater(Runnable). Однако будьте осторожны, чтобы не затопить поток FX слишком большим количеством действий. Вы можете рассмотреть возможность использования AnimationTimer вместо или, возможно, в сочетании с (используя правильную синхронизацию) отдельным потоком.

Также имейте в виду, что рисунок на Canvas не очищает ничего ранее нарисованного. Для имитации движения вам необходимо очистить соответствующую область (или нарисовать над ней, например, с фоном), а затем перерисовать ее в другом положении. Это может быть так же специфично, как только очистка / отрисовка того, что изменилось, или так же общего, как перерисовка всего холста каждый раз.

...