Java - 无法收集 vector 内的二维数组

标签 java multidimensional-array vector undo-redo image-editor

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

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

问题是我无法在具有所有色度修订的 vector 的数组内写入。 正如你所看到的,我尝试了一切,但“色度”变量似乎没有改变。我做错了什么吗?

只是忘了提及:撤消和重做是使用 JButton 触发的,每次释放鼠标按钮都会进行修改。

最佳答案

问题可能是,为了使撤消重做工作,撤消队列必须包含不可变数据。

这意味着对色度的每次更改(更改的原子组)都需要一个新的 2D 数组副本;价格昂贵。

解决方案是仅将更改操作保留在撤消/重做队列中。

在 Java 中,有一个 AbstractAction 实现了 Action 接口(interface),作为编辑示例:UndoManager 。也许对此做一些研究。

(同时放弃 Vector,ArrayList 不会给出注释。)

<小时/>

更好的解释:

chroma[][] 是当前状态。对于撤消/重做功能,需要将此状态更改为较早的状态。现在,人们可以通过撤消前一时刻的每个时间点来存储整个状态,即色度的副本。 更好的方法可能是存储两个状态之间的变化。因此,如果 chroma[47][11]A 更改为 B 仅存储操作对:

undo: chroma[47][11] = A;
redo: chroma[47][11] = B;

这种(需要更多努力)替代方案通常更实用。

最初的选择可能更直接:保存色度的副本。然后通过某些用户操作分配给色度,永远不应该更改已保存的状态:副本必须是不可变的=不可更改的,其内部状态不依赖于可更改的内容。

因此,需要副本,因为:

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) 这样的东西不存在。

关于Java - 无法收集 vector 内的二维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28644236/

相关文章:

c++ - 在 C++ 中使用多维数组跟踪索引

java - 递归地替换二维数组中的内部数组

c++ - 在 C++ 中循环 vector<string> 的结构

multithreading - 如何从结构向量中生成线程以从向量中的每个结构运行 impl fn?

java - EJB 和 JPA 设计问题

java - RestEasy GET 方法接受 HEAD 请求

java.sql.SQLIntegrityConstraintViolationException : Column 'library_idlibrary' cannot be null

java - Java 中的用户输入和 .equals() 问题

c - 在 C 中打印 3d 数组中的 2d 部分(段错误)

java - 如何输出存储在java vector 中的对象的属性?