2014-03-14 3 views
1

Я выполнил шаги из многих статей, но система отмены не ведет себя так, как ожидалось. во-первых, кнопка отмены возвращается правильно до первого редактирования, но не может выйти за пределы первого редактирования. также, когда я нажимаю кнопку «Отменить», а затем повторно редактирую его, круги возвращаются к последнему правлению. Лучше, если вы выполните код и посмотрите сами.Невозможно заставить систему отменить/отменить работу для простой программы рисования.

Другой вопрос, в то время как я пытаюсь найти решение, я читал, что сохранение изображений в массиве является интенсивным с использованием памяти, верно ли это даже для этого простого класса краски и что является альтернативой? сохранение графического изображения?

import java.awt.*;import java.awt.image.BufferedImage;import java.awt.event.*;import java.util.ArrayList;import javax.swing.*;import javax.swing.event.*;import javax.swing.undo.*; 
public class Painter extends JFrame{  
//attributes// 
Painter.Canvas canvas; 
JPanel controlPanel; 
JButton undoButton; 
JButton redoButton; 
PainterHandler handler; 
Container container; 
//undo system elements// 
UndoManager undoManager;   // history list 
UndoableEditSupport undoSupport; // event support 

//constructor// 
public Painter() 
{ 
    super("Painter-test"); 
    controlPanel = new JPanel(); 
    undoButton = new JButton("undo"); 
    redoButton = new JButton("redo"); 
    handler = new Painter.PainterHandler(); 
    container = getContentPane(); 
    canvas = new Painter.Canvas(); 

    this.organizer(); 
}// end constructor 

public void organizer() 
{ 
    controlPanel.setLayout(null); 
    controlPanel.setPreferredSize(new Dimension(120,350)); 
    controlPanel.setBackground(null); 

    //add undo listeners to undo/redo buttons. 
    undoButton.addActionListener(new AbstractAction() 
       { 
        public void actionPerformed(ActionEvent evt) 
        { undoManager.undo(); refreshCanvas(); refreshUndoRedo();} 
       }); 
    redoButton.addActionListener(new AbstractAction() 
       { 
        public void actionPerformed(ActionEvent evt) 
        { undoManager.redo(); refreshCanvas(); refreshUndoRedo(); } 
       }); 

    // initilize the undo/redo system. 
    undoManager= new UndoManager();//history list 
    // event support, instance. 
    undoSupport = new UndoableEditSupport(); 
    //add undoable edit listener to the support instance. 
    undoSupport.addUndoableEditListener(new UndoableEditListener() 
       { 
        public void undoableEditHappened (UndoableEditEvent event) 
        { 
         UndoableEdit edit = event.getEdit(); 
         undoManager.addEdit(edit); 
         refreshUndoRedo(); 
        } 
       }); 
    refreshUndoRedo(); 

    canvas.setPreferredSize(new Dimension(600,400)); 
    //place buttons on panel. 
    undoButton.setBounds(10, 160, 80, 20); 
    redoButton.setBounds(10, 181, 80, 20); 

    //add components to panel. 
    controlPanel.add(undoButton); 
    controlPanel.add(redoButton); 

    //add panels to window. 
    container.add(canvas,BorderLayout.WEST); 
    container.add(controlPanel, BorderLayout.EAST); 
}//end organizerTab3() 

public void refreshCanvas() { canvas.repaint(); } 

//refresh undo, redo buttons. 
public void refreshUndoRedo() 
{ 
    // refresh undo 
    undoButton.setEnabled(undoManager.canUndo()); 
    // refresh redo 
    redoButton.setEnabled(undoManager.canRedo()); 
} 


//INNER CLASSES 
ArrayList<BufferedImage> imagesArray = new ArrayList<BufferedImage>(); 
BufferedImage imageCopy; 
Graphics graphics; 
BufferedImage image; 
int index; 
private class Canvas extends JPanel 
{ 
    public Canvas() 
    { 
     //Panel properties 
     setSize(600,400); 
     setBackground(new Color(84,84,118)); 

     image = new BufferedImage(getWidth(), getHeight(),BufferedImage.TYPE_INT_ARGB); 
     //add Listeners. 
     addMouseMotionListener(handler); 
     addMouseListener(handler); 
    }//end constructor 

    @Override 
    public void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 
     g.drawImage(image, 0, 0, null); 
    } 
}//end inner class PaintPanel 


private class PainterHandler extends MouseAdapter 
{ 
    @Override 
    public void mouseDragged(MouseEvent event) 
    { 
     if(event.getComponent().equals(canvas)) 
     { 
      if (image != null) 
      { 
      // Paint into the image 
      graphics = image.getGraphics(); 
      graphics.setColor(new Color(249,30,138)); 
      graphics.fillOval(event.getX(), event.getY(), 20, 20); 
      imageCopy = new BufferedImage(canvas.getWidth(),canvas.getHeight(),BufferedImage.TYPE_INT_ARGB); 
      imageCopy.getGraphics().drawImage(image, 0, 0, null); 
      canvas.repaint(); 
      } 
     } 
    }//end mouseDragged(MouseEvent event) 

    @Override 
    public void mouseReleased(MouseEvent event) 
    { 
     if(event.getComponent().equals(canvas)) 
     { 
      //UNDO SYSTEM START// 
      //add image to the array. 
      imagesArray.add(imageCopy); 
      // get image's index. 
      index = imagesArray.indexOf(imageCopy); 
      //create AddEdit instance of type UndoableEdit. 
      UndoableEdit edit = new Painter.AddEdit(imagesArray, imageCopy,index); 
      // notify the listeners 
      undoSupport.postEdit(edit); 
      //UNDO SYSTEM END// 
     } 
    } 
}//end MouseHandler class 

private class AddEdit extends AbstractUndoableEdit 
{ 
    private ArrayList<BufferedImage> undoableImagesArray; 
    private BufferedImage undoableImage; 
    int undoableIndex; 
    public AddEdit(ArrayList<BufferedImage> v, BufferedImage img, int i) 
    { 
     undoableImagesArray = v; 
     undoableImage = img; 
     undoableIndex = i; 
    } 
    public void undo() throws CannotUndoException 
    { 
     undoableImagesArray.remove(undoableImage); 
     if(!undoableImagesArray.isEmpty()) 
      image = (BufferedImage)undoableImagesArray.get(undoableImagesArray.size()-1); 
     canvas.repaint(); 
    } 

    public void redo() throws CannotRedoException 
    { 
     undoableImagesArray.add(undoableImage); 
     image = (BufferedImage)undoableImagesArray.get(undoableImagesArray.size()-1); 
     canvas.repaint(); 
    } 

    public boolean canUndo() { return true; } 
    public boolean canRedo() { return true; } 
}//end class AddEdit 

public static void main(String[] s) 
{ 
    Painter p = new Painter(); 
    p.setSize(800, 500); 
    p.setVisible(true); 
    p.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
} 
}//END CLASS Painter 
+0

* "в то время как я Я пытаюсь понять решение, которое я читал, что сохранение изображений в массиве интенсивно занимает память »* Это зависит от разрешения, глубины и количества бит. Но типичная JRE может содержать сотни (например) 640x480 изображений с полным цветом и прозрачностью. –

ответ

2

Вы не используете undoableIndex. На самом деле вам не следует удалять изображение из массива, а вместо этого перемещать указатель.

canUndo() должен возвращать истину, если список не пуст, а указатель> 0

canRedo() должен возвращать истину, если указатель! = Размер() из списка

+0

Спасибо, вы имеете в виду, что я должен использовать undoableIndex в качестве указателя? Я изменил undo и canUndo, но я все равно получаю тот же результат: 'public void undo() throws CannotUndoException { image = (BufferedImage) unoableImagesArray.get (undoableIndex-1); canvas.repaint(); } public boolean canUndo() {if (! UndoableImagesArray.isEmpty() && undoableIndex> 0) return true; return false;} ' –

Смежные вопросы