将JPanel保存为图像(不是作为文件,而是作为变量)

时间:2012-07-16 11:40:17

标签: java image swing save jpanel

好吧我的问题很简单:我制作Paint应用程序,我想提供某种“撤消”功能。我读过撤消管理器等等,但这种方法对我来说似乎很难理解,所以我决定自己设计。我的想法很简单:因为我在JPanel上绘图,我将在任何绘图操作之前保存其当前内容。撤消按钮只会恢复之前的按钮。

问题是:我无法“恢复”保存的图像并将其放在JPanel上。因为我已经实现了“保存”硬盘驱动器上的当前图像以及从硬盘驱动器“打开”任意图像,因此我被缓冲了。这两个都完美无缺。

不幸的是,为我的“撤销”系统尝试完全相同的方法是行不通的。

查看代码:(为了简化,我手动'保存'当前图片 - >用于测试目的)

public class PictureEdit { //class for saving the current JPanel drawing for undo
    public BufferedImage saveBI;
    public Graphics2D saveG2D;
}

public void actionPerformed(ActionEvent e) { //action for "UNDO" button, not working
    //drawingField - instance of JPanel
    //pe - instance of PictureEdit class
    drawingField.setBufferedImg(drawingField.pe.saveBI);
    drawingField.updateArea(drawingField.getBufferedImg());            
}

public void actionPerformed(ActionEvent e) { //action for manual "save" (for undo)
    drawingField.pe.saveBI=drawingField.getBufferedImg();
    drawingField.pe.saveG2D=(Graphics2D)drawingField.getBufferedImg().getGraphics();

}

现在我的工作解决方案的例子,但与在HDD上唤醒witk文件有关:

public void actionPerformed(ActionEvent e){ //Opening file from harddrive - works fine
    JFileChooser jfc = new JFileChooser();
    int selection = jfc.showOpenDialog(PaintUndo.this);
    if (selection == JFileChooser.APPROVE_OPTION){                
        try {
           drawingField.setBufferedImg(ImageIO.read(jfc.getSelectedFile()));
           drawingField.updateArea(drawingField.getBufferedImg());

        } catch (IOException ex) {
           Logger.getLogger(PaintUndo.class.getName()).log(Level.SEVERE, null, ex);
           JOptionPane.showMessageDialog(PaintUndo.this, "Could not open file");
        }
    }                 
}


public void actionPerformed(ActionEvent e) { //Saving to harddrive - works fine
     int n = JOptionPane.showConfirmDialog(PaintUndo.this, "Are you sure you want to save?", "Saving image...", JOptionPane.OK_CANCEL_OPTION);
     if (n == JOptionPane.YES_OPTION){
        JFileChooser jfc = new JFileChooser();
        int nn = jfc.showSaveDialog(PaintUndo.this);
        if (nn == JFileChooser.APPROVE_OPTION){                       
           File saveFile = new File(jfc.getSelectedFile()+".bmp");
           try {
              ImageIO.write(drawingField.getBufferedImg(), "bmp", saveFile);
           } catch (IOException ex) {
              Logger.getLogger(PaintUndo.class.getName()).log(Level.SEVERE, null, ex);
              JOptionPane.showMessageDialog(PaintUndo.this, "Error while saving file");
           }                       
        }
     }
 }

以防有人好奇:updateArea函数(代表提到的drawingField的扩展JPanel类的成员):

public void updateArea(BufferedImage img){ //it is just resizing the current picture (if necessary) and then assigns the new Graphics.
    area.height=img.getHeight();
    area.width=img.getWidth();
    this.setPreferredSize(area);
    g2d = (Graphics2D)this.getGraphics();
}

基本上程序是完全一样的,使用文件是可以的,而我操作变量时无法保存和恢复图像......有什么可能是错的?有任何想法吗?当我使用Undo / UndoSave按钮时,我的JPanel(drawingField

绝对没有任何变化

任何帮助表示赞赏

1 个答案:

答案 0 :(得分:3)

在您显示的代码中,您正在复制对图像的引用,但两个引用仍然指向同一图像对象 - 如果您执行任何不重新分配引用的操作(=)它将反映在两个引用中!为了保存旧版本的图像,您需要复制实际对象,而不仅仅是参考。

我建议使用Java已建立的撤消管理方法,但是如果你想继续使用自己的方法,那么这些是你应该看到的方法:

//BufferedImage image;
Raster raster = image.getData(); // save
image.setData(raster); // restore