Я создаю программу, которая позволяет пользователям рисовать на экране, подобно использованию инструмента карандаша в маске MS, а затем позволяет пользователю воспроизводить процесс создания чертежа, как если бы кто-то рисовал его перед вами.
То, как я это делал с помощью Path2D, а также с помощью методов moveTo и lineTo, нарисовал линию, используя этот путь.
Теперь я не могу понять, как оживить перерисовку объекта Path2D. Моя нынешняя стратегия заключается в создании нового Path2D и использовании PathIterator, итерационно добавляет сегменты линии от старого пути к новому пути.
Это то, о чем я сейчас думаю:
public void redrawPath() {
Path2D oldPath = path;
path = new Path2D.Double();
double[] coords = new double[100];
PathIterator pi = oldPath.getPathIterator(new AffineTransform());
while (!pi.isDone()) {
pi.next();
pi.currentSegment(coords);
//Add segment to new path
repaint();
}
}
Основная проблема заключается в том, что я не знаю размер сегментов линии, поэтому я не знаю, как определить размер массива коордов. Я также не совсем понял, как я собираюсь добавить сегменты к новому пути. Казалось бы, можно использовать метод append в Path2D, хотя он, кажется, добавит весь путь к самому себе.
Я понимаю, что Path2D - это Shape, но я не могу найти альтернативных способов сделать это.
Вы можете использовать FlatteningPathIterator, разбирая ваши фигуры и обрабатывающие сегменты.
См. Пример движущейся точки здесь http://java-sl.com/tip_flatteningpathiterator_moving_shape.html
Я просто нашел эту страницу, содержащую очень полезный пример.
Оказывается, я читал апи неправильно. Массив координат может быть максимальным размером 7.
Чтобы заставить это работать, мне также пришлось использовать SwingWorker для обновления Path в фоновом режиме. redrawPath() только начинает поток.
Это то, что код в doInBackGround SwingWorker выглядит так:
PathIterator pi = oldPath.getPathIterator(null);
while (!pi.isDone()) {
double[] coordinates = new double[6];
int type = pi.currentSegment(coordinates);
switch (type) { //Decide what do based on type of segment
case PathIterator.SEG_MOVETO:
tempPath.moveTo(coordinates[0], coordinates[1]);
break;
case PathIterator.SEG_LINETO:
tempPath.lineTo(coordinates[0], coordinates[1]);
break;
default:
break;
}
publish(tempPath.clone());
pi.next();
}
Метод процесса обновляет путь на холсте и вызывает repaint();