1

私の問題は単純です。私は 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");
           }                       
        }
     }
 }

誰かが興味を持っている場合に備えて: updateAreafunction (言及された を表す拡張された JPanel クラスのメンバーdrawingField):

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)

どんな助けでも大歓迎

4

1 に答える 1

3

示したコードでは、参照を画像にコピーしていますが、両方の参照は同じ画像オブジェクトを指しています。参照を再割り当てしないアクション()を実行すると、両方の参照=に反映されます。古いバージョンの画像を保存するには、参照だけでなく実際のオブジェクトをコピーする必要があります。

Javaの確立された元に戻る管理アプローチを使用することをお勧めしますが、独自のアプローチを継続したい場合は、次の方法を検討する必要があります。

//BufferedImage image;
Raster raster = image.getData(); // save
image.setData(raster); // restore
于 2012-07-16T14:00:29.330 に答える