views:

377

answers:

3

hi there, I need to write these 3 functions, but i got stuck at redo and delete. Redo is showing error when there is nothing to redo and i don't know how to write delete function. Thank you

undo

public class Undo extends AbstractAction {

private MyCanvas myCanvas;

public Undo(MyCanvas myCanvas) {
    this.myCanvas = myCanvas;
    this.putValue(NAME, "Undo");
    this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl Z"));
    this.putValue(SMALL_ICON, new ImageIcon(Main.class.getResource("/icons/Undo24.gif")));
}

public void actionPerformed(ActionEvent e) {
    if (!myCanvas.commands.isEmpty()) {

        Command cmd = myCanvas.commands.pop();
        cmd.undo();
        myCanvas.undoneCommands.add(cmd);
        myCanvas.repaint();
    }
            else
                System.out.println();
}
}

redo

public class Redo extends AbstractAction {

private MyCanvas myCanvas;

public Redo(MyCanvas myCanvas) {
    this.myCanvas = myCanvas;
    this.putValue(NAME, "Redo");
    this.putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl Y"));
    this.putValue(SMALL_ICON, new ImageIcon(Main.class.getResource("/icons/Redo16.gif")));
}

public void actionPerformed(ActionEvent e) {
    //if (!myCanvas.commands.isEmpty()) {
        Command cmd = myCanvas.undoneCommands.pop();
        cmd.execute();
        myCanvas.commands.add(cmd);
        myCanvas.repaint();
    //}
        //   else
               System.out.println();
}
}
+1  A: 

I believe you'll want to have a look at the command pattern.

There's a good write-up on this in the book Head First Design Patterns as well.

leeand00
I suppose I can not get more specific answer :)
ivan
@ivan Yes you can. Go to the library, or your local Barns and Noble and read about the Command Pattern. Wait; do you understand UML?(cause to read about that it would help if you knew a little UML, mainly, how to read class diagrams)Believe me, you'll be glad you made the effort to learn it!
leeand00
+1  A: 

It's a difficult problem to solve generically--if it were easy it would be in a library.

One way is to have every "Action" be a class. For instance, an "Add text" class might add a number of characters to the screen at a given position. This object is created as you type and pushed onto the stack when it's complete (could be that you want one object for each character.

The trick is that each "Action" also has an undo method that can undo itself. So repeated undos become just a chain of actionStack.pop().undo();

In this way, a delete function would know that it was supposed to delete the currently selected text. It would record the position and the text that was deleted in itself and sit in the stack. If you were to call it's undo, it would simply place the text back into the document.

It looks like you are trying to do something along these lines but without creating a different object for each type of action that can effect the document (AddCharacter, Delete, EraseDocument, ...). This is doable--it's the way you'd do it in a non-OO language, but it's not easy or clean--For instance, you'd have to store arbitrary metadata like the text deleted, the position you deleted it from, etc.. into some part of your stack.

When you break it up into small actions, it becomes extremely fun and easy...

Bill K
@Bill Your explanation is better than what I told him, but you're basically referring to the command pattern correct? (well at least in reference to the OOP stuff)(said standing in humble reverence to Bill's 12k (all I have is 2k))
leeand00
Yes, I just tried to tailor it to his problem and give him an idea why it's useful.
Bill K
A: 

Swing has UndoManager. Take a loot at its documentation.

Bozho