Java 撤销&;重做,不存储图形文件

Java 撤销&;重做,不存储图形文件,java,swing,graphics,graphics2d,Java,Swing,Graphics,Graphics2d,我目前正在开发一个绘图程序,并实现了撤消和重做方法,但由于用户绘图时我的程序速度变慢,我决定不将co-ords存储在ArrayList中,而是直接将它们应用于BuffereImage。这个方法的问题是我不能像以前那样撤销或重做。 我在互联网上搜索过,找到了一个名为的类的引用。但我不知道如何将其应用于图形对象(考虑到我的条件) 我仍然可以存储这些单词,但当我直接绘制它们时,这对我来说是无用的,除非有人能想出一种方法来覆盖一条黑色的线和一条透明的线来替换它(目前,为此,我使用BuffereImage

我目前正在开发一个绘图程序,并实现了撤消和重做方法,但由于用户绘图时我的程序速度变慢,我决定不将co-ords存储在ArrayList中,而是直接将它们应用于BuffereImage。这个方法的问题是我不能像以前那样撤销或重做。 我在互联网上搜索过,找到了一个名为的类的引用。但我不知道如何将其应用于图形对象(考虑到我的条件)

我仍然可以存储这些单词,但当我直接绘制它们时,这对我来说是无用的,除非有人能想出一种方法来覆盖一条黑色的线和一条透明的线来替换它(目前,为此,我使用BuffereImage.setRGB(x,y,color),但这只在我要替换的形状是圆(x^2+y^2=r^2)时才有用或矩形)


有什么想法吗?

您可以保留上次操作中修改内容的增量,并且在撤消操作时应用该增量的倒数

这就是我的意思:假设你有一个图像A,在它上面画一条线,那么现在你有了图像B。如果你计算
C=A xor B
,那么C是你刚才做的增量的倒数。因此,您只需存储C就可以进行撤销。撤消过程将是:
A=B xor C

当然,A、B和C不需要是完整的图像,它们可以只是带有起点信息的变化区域

如果你想重做,它是:
B=A xor C

这背后的逻辑如下,请记住,将一个值与自身异或得到0,将任何值与0异或得到相同的数字。我将使用
^
作为
xor
的缩写,就像您使用Java一样

如果一行中有3个像素的图像,且具有RGB值:

A=[(255255),(255255),(255255)]

用红色墨水在中间像素的顶部绘制,您将得到:

B=[(255255),(255,0,0),(255255)]

现在,通过对两个图像执行异或运算来计算增量:

C=[(0,0,0),(0255255),(0,0,0)]

如果您想从B和C中获得A,您可以执行
B xor C
,即:

[(255^0,255^0,255^0),(255^0,0^255,0^255),(255^0,255^0,255^0)]

这是原始图像:

`[ (255,255,255) , (255,255,255), (255,255,255) ]`
在这里,我使用255和0,因为这些数字具有易于计算的xor,但它适用于任何值。尝试A=127,B=83并将C计算为
127^83
,然后检查
A=B^C


希望能有所帮助。

很抱歉,我以前没有使用过二进制逻辑,所以请您向我解释一下,并(如果可以的话)包括代码?谢谢。我修改了我的答案,添加了一个更详细的解释。考虑到OP在ArrayList中存储点导致程序变慢这一事实,我只能想象在每个图像之间存储字节增量只会产生同样的问题……但我确实喜欢这个想法;)说得好。这并不明确,但是:这个想法是将每个delta保存为ArrayList的一个元素,而不是将delta的每个点保存为一个元素。那么,还有其他想法吗@MadProgrammer如何创建ArrayList?你试过使用LinkedList吗?@MadProgrammer我以前使用AL,但当我实现橡胶工具时(由于画布是透明的,所以必须使用BuffImg.setPixel而不是G2D.drawLine),性能急剧下降,因为每次单击或拖动都必须设置像素rrpi时间,其中r是可变的,包括所有其他笔划,我刚刚读了这篇文章,发现LinkedList的笔划比AL的慢。你问这个问题的原因是什么?
LinkedList
如果你不想进行顺序访问,速度会慢一些,它的容量增长更快,因为它不需要不断地重新分配备份缓冲区,所以它不会创建大量需要垃圾收集的对象。在我看来,您只需按下并弹出列表并运行线性访问(从列表的开始到结束运行)和
LinkedList
实际上可能会给您带来更好的性能。您还可以减少撤消操作的概念,因此如果用户按下鼠标按钮并执行拖动操作,我认为,直到鼠标释放,这将构成一个单一的行动。我可能更容易把你需要画的东西从被认为是“可撤销的”行动中分离出来,作为一个想法