开发者

Undo and Redo Action events in Java

开发者 https://www.devze.com 2023-01-25 21:32 出处:网络
I have an application with a JPanel and buttons that users click on to draw shapes on the panel. You can color and resize开发者_StackOverflow the shapes as well as move them around in the panel. How w

I have an application with a JPanel and buttons that users click on to draw shapes on the panel. You can color and resize开发者_StackOverflow the shapes as well as move them around in the panel. How would I go about implementing undo and redo for such an application? I have an Actions class where all the actions are actually implemented. In this class each action is its own class that extends AbstractAction. My Actions class is basically a nested class.

e.g this is one of the classes in my Actions class:

private class RandomAction extends AbstractAction {
  private static final long serialVersionUID = 1L;
  public NewAction(String text, ImageIcon icon, String desc){
            super(text, icon);
            putValue(SHORT_DESCRIPTION, desc);
        }
        public void actionPerformed(ActionEvent e) {

        }
    }

When I then create a button all I do is:

 randButton = new JButton(Actions.RandomAction);


Usually undo/redo functionality is done by implementing a stack. You can implement your own action stack that keeps track of the previous X actions, which you can then just pop off each time the user undos an action. You will probably also need to keep a similar type of structure for the redo functionality. So when an action is popped off the undo stack, it first needs to go unto the redo stack.

If you are using Java and NetBeans (although strictly speaking you do not need to use the NetBeans IDE), you can have a look at the NetBeans Platform (can be downloaded separately). I have not worked with the undo/redo much, but it does provide the functionality.

Personally I would just write a class that wraps any "action" that the user can do, which I see you already have done. Now it is simply a matter of implementing a stack to keep track of those actions, and when one is popped off the undo stack, you need to do the "opposite" of the action. Place the item on a redo stack, so when the user clicks redo, you can simply pop the action off the redo stack and let your application handle it as it normally would have.


I agree with Nico's post and I'll add that it's possible to use one stack for both undo/redo.

A couple of years back in university, I was writing a dataflow diagram editor which required full undo/redo functionality. I created an abstract Action class representing any possible user action (with Undo and Do methods), and an ActionStack which wraps a List of all performed actions and maintains a pointer to the last performed Action. Undoing actions moves the pointer down the stack, and redoing them moves it up. So if the user performs 10 actions, the stack will contain actions 1-10 and the pointer points to action #10. If the user then performs 5 undos, there will still be 10 actions on the stack, but the pointer moves back to Action #5. If the user then performs a new action, all actions above the pointer (actions 6-10) will be deleted, the new action will be added to the top of the stack, and the pointer adjusted accordingly.

The user actions you describe don't sound too complicated, but for more complex actions, you might want to allow them to be composed of child actions.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号