正如我在之前的问题中提到的那样,我正在制作一个可以嵌入到程序中的图像编辑器。因此,我想到了一个点,在此我决定图像编辑器必须具有撤消和重做功能。所以我写了这段代码:
public Vector<Color[][]> undo = new Vector<Color[][]>();
size = 16;
public Color[][] chroma = new Color[size][size];
//These are variables
public void saveRevision(){
System.out.println("Saving: " + current);
undo.insertElementAt(chroma.clone(), current);
current++;
/*for (int i = 0; i < (undo.size()-1); i++) {
if(i > current){
undo.remove(i);
}
}*/
}
public void undo(){
if(current > 0){
System.out.println("Gathering: " + (current-1));
current--;
/*Color[][] c = undo.get(current);
for (int i = 0; i < c.length; i++) {
for (int j = 0; j < c[i].length; j++) {
System.out.print(c[i][j]);
}
System.out.println();
}*/
/*for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
chroma[i][j] = null;
}
}*/
chroma = undo.get(current);
repaint();
}
}
public void redo(){
if((undo.size()-1) > current){
System.out.println("Gathering: " + (current+1));
current++;
for(int i = 0; i < size; i++){
for(int j = 0; j < size; j++){
chroma[i][j] = null;
}
}
chroma = undo.get(current);
repaint();
}
}
问题是我不知怎么不能从具有所有色度修订版的向量中写入数组。
如您所见,我尝试了所有操作,但“色度”变量似乎并未更改。我做错什么了吗?
只是忘了提一下:撤消和重做是使用JButton触发的,每次释放鼠标按钮都会进行修订。
最佳答案
问题可能在于,要使撤消重做工作,撤消队列必须包含不可变的数据。
这意味着对chroma
的每次更改(更改的原子组)都将需要一个新的2D数组副本。昂贵。
解决方案是仅将更改操作保留在撤消/重做队列中。
在Java中,有一个AbstractAction,它实现了Action接口,并以编辑为例:UndoManager。也许对此做一些研究。
(也对Vector表示弃权,ArrayList不会给出注释。)
更好的解释:chroma[][]
是当前状态。对于撤消/重做工具,需要将此状态更改为较早的状态。现在,每个时间点都可以存储,并且可以撤消到以前的整个状态,即chroma
的副本。
更好的方法可能是存储两个状态之间的更改。因此,如果chroma[47][11]
从A
更改为B
,则仅存储操作对:
undo: chroma[47][11] = A;
redo: chroma[47][11] = B;
这种(需要更多的精力)替代方法通常更实用。
原始选择可能更直接:保存
chroma
的副本。然后,通过某些用户操作将其分配给色度,切勿更改保存状态:副本必须是不可变的=不可更改,其内部状态不取决于可更改的内容。因此,由于以下原因需要复制:
Color[][] chroma = ...;
Color[][] falseCopied = chroma;
chroma[3][4] = c;
// Now also `falseCopied[3][4].equals(c)`.
可以完成一个真实的副本:
public static Color copy(Color[][] grid) {
Color[][] copied = new Color[grid.length][];
for (int i = 0; i < grid.length; ++i) {
copied[i] = Arrays,copyOf(grid[i], grid[i].length);
}
return copied;
}
这里不需要复制每个Color本身,因为Color是“不可变的”,即您不能更改其内部状态。
color.setBlue(23)
之类的东西不存在。