Java-无法在矢量内收集2D数组



正如我在上一个(未回答)问题中提到的,我正在制作一个可以嵌入到我的程序中的图像编辑器。所以我决定图像编辑器必须撤消和重做。所以我写了这个代码:

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();
    }
}

问题是,不知何故,我无法从具有所有色度修正的向量中写入数组。正如您所看到的,我尝试了所有的方法,但"色度"变量似乎并没有改变。Em我做错了什么?

只是忘了提一下:撤销和重做是使用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的副本。然后通过一些用户操作分配给色度,不应该改变保存的状态:副本必须是不可变的=不可更改的,其内部状态不取决于可更改的东西。

所以,副本ie需要因为:

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.setBlue(23)的东西并不存在。

我建议您查看Java Collections教程并重新构建代码。例如,Java Vector类被认为是过时和不推荐使用的(而且Vector是线程安全的,因为您可能在EDT上调用它,从JButton的使用来看,没有必要这样做)。如果您有一些真正特定的(性能)要求,那么使用低级别多维数组也会很有用,但我认为在您的场景中不是这样。

使用高级Java集合构造,有更简单、可读性更强的方法可以实现您想要的功能。

最新更新