Лучше ли repaint() без аргументов, чем repaint() с аргументами?

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

private void moveSquare(int x, int y) {
  if ((squareX != x) || (squareY != y)) {
     squareX = x;
     squareY = y;
     repaint();
  }
}

обеспечивает для этого конкретного примера намного лучшую производительность рисования по сравнению с рекомендуемым.

private void moveSquare(int x, int y) {
  int OFFSET = 1;
  if ((squareX != x) || (squareY != y)) {
     repaint(squareX, squareY, squareW + OFFSET, squareH + OFFSET);
     squareX = x;
     squareY = y;
     repaint(squareX, squareY, squareW + OFFSET, squareH + OFFSET);
  }
}

Если я использую последний, квадрат во время процесса перетаскивания выглядит несколько «сплющенным».

Я знаю, что это очень простой пример, но он несколько пугает производительность Java Graphics в целом.


person DaJunkie    schedule 07.09.2020    source источник


Ответы (2)


Делать двойную перекраску неестественно.

А когда только перекрашивание союза старой и новой площади?

private void moveSquare(int x, int y) {
  if (squareX != x || squareY != y) {
     final int OFFSET = 1;
     int minx = Math.min(x, squareX);
     int miny = Math.min(y, squareY);
     int dx = Math.abs(x - squareX);
     int dy = Math.abs(y - squareY);

     squareX = x;
     squareY = y;
     repaint(minx, miny, squareW + dx + OFFSET, squareH + dy + OFFSET);
  }
}

Это должно быть более плавным, когда квадрат относительно мал или находится за пределами показанной области (отсечение).

person Joop Eggen    schedule 07.09.2020
comment
Похоже, это улучшает рендеринг при движении вправо или вниз. Перемещение влево или вверх по-прежнему сжимает прямоугольник. Я буду исследовать это позже. - person DaJunkie; 07.09.2020

Разница между paint() без аргументов и с аргументами заключается в том, что тот, у которого есть аргументы, установит область отсечения при последующем вызове paint(). Разница в производительности отрисовки, если таковая имеется, будет зависеть от того, действительно ли метод paint() учитывает область отсечения или просто закрашивает всю область рисования, оставляя платформе решать, нуждается ли область в обновлении или нет.

Многие компоненты Java AWT/Spring игнорируют область отсечения и просто закрашивают всю область. Иногда это сделать быстрее, чем точно определить, как перерисовать очень специфическую часть области отображения. Если компонент написан вами самостоятельно, и вы знаете, что не тестируете область отсечения в paint(), то вы знаете, что нет никакой разницы, вызываете ли вы repaint() с аргументами или нет.

С другой стороны, если вы сильно потрудились над реализацией paint(), чтобы выяснить, как именно перерисовать субрегион, тогда вы должны сделать все возможное для себя, чтобы попытаться решить, как лучше вызвать repaint().

Если вы не писали компонент, то там наверняка знаете, лучше ли указывать область перерисовки или нет, кроме как путем тестирования или тщательного изучения исходного кода, если он у вас есть.

Если использование repaint() с аргументами приводит к искаженному изображению, это, вероятно, указывает на дефектную реализацию paint().

person Kevin Boone    schedule 07.09.2020
comment
Я использую Swing и реализовал только paintComponent(). Насколько я понял, это предпочтительный «путь Swing». Я читал, что не рекомендуется использовать Paint под Swing. - person DaJunkie; 07.09.2020
comment
paintComponent() — это всего лишь Swing-эквивалент paint(). Независимо от того, используете ли вы AWT или Swing, объект Graphics, передаваемый методу, содержит прямоугольник отсечения. В любом случае вы можете использовать обтравочный прямоугольник или игнорировать его — это ваш выбор. - person Kevin Boone; 07.09.2020
comment
Спасибо за информацию о форме стрижки. Я совсем новичок в живописи и раньше этого не знал. К сожалению, это не имеет значения: использование repaint() без аргументов «выглядит лучше», чем просто обновление прямоугольника отсечения. Я постараюсь привести полный пример со всеми упомянутыми решениями. - person DaJunkie; 07.09.2020