Все, что вам действительно нужно, - это один Canvas, но всякий раз, когда выполняется редактирование, вы должны сделать снимок холста или сделать копию пикселей на холсте , а затем выдвинуть этот массив пикселей или объект, содержащийпиксель в стеке.Это было бы плохой идеей, потому что создание копии холста будет очень дорогим как в вычислительном отношении, так и с точки зрения памяти.Хотя это возможно, я бы советовал против этого.
Для меня лучший и самый простой способ справиться с "операциями отмены" - это сначала нарисовать на BufferedImage
, а затем нарисовать это изображение на Canvas
, как объяснено здесь и здесь и второе, чтобы ввести концепцию Action
в ваше приложение.Например, «действие рисования» будет выглядеть примерно так:
interface Action
{
//Used to re-apply action after it was undone
public void apply();
//Undo the action
public void undo();
}
class PaintAction() implements Action
{
static class Pixel
{
final int x;
final int y;
final int oldColor;
final int newColor;
PixelPos(int x, int y, int oldColor, int newColor)
{
this.x = x;
this.y = y;
this.oldColor = oldColor;
this.newColor = newColor;
}
}
List<Pixel> affectedPixels;
PaintAction()
{
affectedPixels = new ArrayList<>();
}
@Override
public void apply(Canvas canvas)
{
for (Pixel pixel : pixel)
{
//draw new pixel's color on the canvas
}
}
@Override
public void undo(Canvas canvas)
{
for (Pixel pixel : pixel)
{
//draw old pixel's color on the canvas
}
}
public void addPixel(Pixel pixel)
{
affectedPixels.add(Pixel);
}
}
Поэтому, когда пользователь нажимает кнопку мыши, чтобы начать рисовать, вы создаете новый PaintAction
, тогда всякий раз, когда пользователь перемещает мышь, вы бысоздайте новый объект Pixel и добавьте его в список «затронутых пикселей с помощью PaintAction
», затем перейдите к изменению цвета пикселя в BufferedImage
.
Тогда все, что вам нужно, этооставьте стопку Action
и примените, отмените их, как считаете нужным.
Надеюсь, что это имеет смысл, ура.