Click here to Skip to main content
15,898,735 members
Articles / Programming Languages / Java

Undo Algorithm for Java Swing

Rate me:
Please Sign up or sign in to vote.
4.33/5 (2 votes)
21 Aug 2014CPOL2 min read 13.5K   101   6  
I am going to show how to perform undo algorithm on your Java Swing application.

Introduction

I am going to show how to perform undo algorithm on your Java Swing application. I hope before you tried to understand undo algorithm, you know how to create a simple text application as I am going to perform undo algorithm on it.

undo1

Here’s the simple text application source code:

Java
  1: package UndoSwingTutorialPackage;
  2: 
  3: import java.awt.event.ActionEvent;
  4: import java.awt.event.InputEvent;
  5: import java.awt.event.KeyEvent;
  6: import javax.swing.*;
  7: 
  8: public class SimpleTextApplication extends JFrame{
  9:      
 10:      /**
 11:       * 
 12:       */
 13:      private static final long serialVersionUID = -4626161399740482146L;
 14: 
 15:      SimpleTextApplication(){
 16:           super();
 17:           JTextArea text = new initialTextField();
 18:           
 19:           setTitle("Simple Text Application");
 20:           
 21:           getContentPane().add(text);          
 22:           
 23:      }
 24:      
 25:      class initialTextField extends JTextArea{
 26:           /**
 27:            * 
 28:            */
 29:           private static final long serialVersionUID = 1L;
 30: 
 31:           initialTextField(){
 32:                super();
 33:                
 34:                initialShortcutKey(this);
 35:                
 36:                setColumns(40);
 37:                setLineWrap(true);
 38:                setRows(5);
 39:                setEditable(true);
 40:                
 41:                               
 42:           }
 43:           
 44:           void initialShortcutKey(JComponent component){
 45:                
 46:                /*
 47:                 * Never tried to use keyListener as it wouldn't work on component
 48:                 * For more detail on the reason of keyListener, please find the answer on your own
 49:                 * 
 50:                 * On swing, we have to specify which component is listen to key and which key
 51:                 * We have to use InputMap and ActionMap instead of KeyListener
 52:                 * 
 53:                 */
 54:                
 55:                InputMap im = component.getInputMap(JComponent.WHEN_FOCUSED);
 56:                ActionMap am = component.getActionMap();
 57:                
 58:                /*
 59:                 * When the JTextArea is focused(Precisely JTextArea is focused all the times),
 60:                 * Component JTextArea is listened to space key by getKeyStroke( KeyEvent.VK_SPACE ,0 )  
 61:                 */
 62:                im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,0), "listenSpacebarKey");
 63:                am.put("listenSpacebarKey", new AbstractAction(){
 64: 
 65:                     /**
 66:                      * 
 67:                      */
 68:                     private static final long serialVersionUID = 1L;
 69: 
 70:                     @Override
 71:                     public void actionPerformed(ActionEvent arg0) {
 72:                          
 73:                          
 74:                     }
 75:                });
 76:                
 77:                im.put(KeyStroke.getKeyStroke(KeyEvent.VK_Z,InputEvent.CTRL_MASK), 
                                                  "listenCtrlzKey");
 78:                am.put("listenCtrlzKey", new AbstractAction(){
 79: 
 80:                     /**
 81:                      * 
 82:                      */
 83:                     private static final long serialVersionUID = 1L;
 84: 
 85:                     @Override
 86:                     public void actionPerformed(ActionEvent arg0) {
 87:                          
 88:                          
 89:                     }
 90:                });
 91:           }
 92:      }
 93:           
 94:           
 95:      public static void main(String[] args){
 96:           JFrame frame = new SimpleTextApplication();
 97:           frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 98:           frame.pack();
 99:           frame.setLocation(250,250);
100:           frame.setVisible(true);
101:      }
102: 
103: }

I hope you wouldn’t get confused by this simple application. On JTextArea component, keyEvent indicates when spacebar is pressed. But you will find out that nothing happened when spacebar is pressed, I blank it for the purpose of performing some undo action later on.

The long introduction is over and I hope you won't get confused as it is just the beginning.

How to Use It?

As what SimpleTextApplication shows, spacebar key and Ctrl+Z key is indicated as it is pressed. Before explaining how to use it, I tried the complete work and understood how the complete work is done. The complete code is given below.

Create MyUndoWork Class

Java
 1: package UndoSwingTutorialPackage;
 2:
 3: import javax.swing.JTextArea;
 4:
 5: public class MyUndoWork {
 6:
 7:      protected String[] memory;
 8:      protected String tempMemory;
 9:      protected int currentNumber = 0;
10:      private int max = 100;
11:
12:      MyUndoWork(JTextArea textComponent){
13:           super();
14:           memory = new String[max];
15:
16:           /*
17:            *  initial the first layer memory value
18:            *  If textComponent is found, put the text that exists on it at initial
19:            *  Else initial the memory with blank text ""
20:            */
21:           if(textComponent != null){
22:                memory[0] = textComponent.getText();
23:                tempMemory = textComponent.getText();
24:           }else{
25:                memory[0] = "";
26:                tempMemory = "";
27:           }
28:
29:      }
30:
31:      public void updateUndoMemory(String temp){
32:
33:           /*
34:            * Prevent duplicate data is store into undo Memory
35:            */
36:           if(!tempMemory.equals(temp)){
37:
38:                //Store previous data that store in tempMemory into memory
39:                storingDataForUndo(tempMemory);
40:
41:                //update tempMemory into latest content
42:                tempMemory = temp;
43:           }
44:      }
45:
46:      protected void storingDataForUndo(String value1){
47:
48:           if(currentNumber < max ){
49:
50:                /*
51:                 * If there is no overflow of memory
52:                 * Store the tempData into memory and
53:                 */
54:                memory[currentNumber] = value1;
55:                currentNumber++;
56:           }else if(currentNumber >= max){
57:                /*
58:                 * If data stores into memory is overflow
59:                 * Dispose the most bottom level memory and level down one of every memory
60:                 * Put the new data into top level memory
61:                 */
62:                for(int i = 0;i < max-1 ;i++){
63:                     memory[i ]= memory[i + 1];
64:                }
65:                currentNumber = max-1;
66:                memory[currentNumber] = value1;
67:                currentNumber++;
68:           }
69:      }
70:
71:      public String releaseDataForUndo(){
72:
73:           if(currentNumber > 0){
74:                currentNumber--;
75:                System.out.println("currentNumber : "+currentNumber);
76:
77:                /*
78:                 * Once undo is pressed and memory is release
79:                 * previous content that stored into tempMemory must be released
80:                 * and update it to latest current content
81:                 *
82:                 */
83:
84:                tempMemory = memory[currentNumber];
85:                return memory[currentNumber];
86:
87:           }else{
88:                currentNumber = 0;
89:                tempMemory = memory[currentNumber];
90:                return memory[currentNumber];
91:           }
92:      }
93: }
94:

Update SimpleTextApplication Class Source Code as Follows

Java
  1: package UndoSwingTutorialPackage;
  2: 
  3: import java.awt.event.ActionEvent;
  4: import java.awt.event.InputEvent;
  5: import java.awt.event.KeyEvent;
  6: import javax.swing.*;
  7: 
  8: public class SimpleTextApplication extends JFrame{
  9:      
 10:      /**
 11:       * 
 12:       */
 13:      private static final long serialVersionUID = -4626161399740482146L;
 14: 
 15:      MyUndoWork myUndoWork;
 16: 
 17:      SimpleTextApplication(){
 18:           super();
 19:           JTextArea text = new initialTextField();
 20:           
 21:           setTitle("Simple Text Application");
 22:           
 23:           getContentPane().add(text);          
 24:           
 25:      }
 26:      
 27:      class initialTextField extends JTextArea{
 28:           /**
 29:            * 
 30:            */
 31:           private static final long serialVersionUID = 1L;
 32: 
 33:           initialTextField(){
 34:                super();
 35:                
 36:                initialShortcutKey(this);
 37:                
 38:                /*
 39:                 * Implement MyUndoWork class and initial it.
 40:                 */
 41:                myUndoWork = new MyUndoWork(this);
 42:                
 43:                setColumns(40);
 44:                setLineWrap(true);
 45:                setRows(5);
 46:                setEditable(true);
 47:                
 48:                               
 49:           }
 50:           
 51:           void initialShortcutKey(JComponent component){
 52:                
 53:                /*
 54:                 * Never tried to use keyListener as it wouldn't work on component
 55:                 * For more detail on the reason of keyListener, please find the answer on your own
 56:                 * 
 57:                 * On swing, we have to specify which component is listen to key and which key
 58:                 * We have to use InputMap and ActionMap instead of KeyListener
 59:                 * 
 60:                 */
 61:                
 62:                InputMap im = component.getInputMap(JComponent.WHEN_FOCUSED);
 63:                ActionMap am = component.getActionMap();
 64:                
 65:                /*
 66:                 * When the JTextArea is focused (Precisely JTextArea is focused all the times),
 67:                 * Component JTextArea is listened to space key by getKeyStroke( KeyEvent.VK_SPACE ,0 )  
 68:                 */
 69:                im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE,0), "listenSpacebarKey");
 70:                am.put("listenSpacebarKey", new AbstractAction(){
 71: 
 72:                     /**
 73:                      * 
 74:                      */
 75:                     private static final long serialVersionUID = 1L;
 76: 
 77:                     @Override
 78:                     public void actionPerformed(ActionEvent arg0) {
 79:                          
 80:                          /*
 81:                           * Undo memory is updated when user press space bar on JTextArea
 82:                           *   
 83:                           */
 84:                          
 85:                          myUndoWork.updateUndoMemory(getText());                         
 86:                          
 87:                     }                    
 88:                });
 89:                
 90:                im.put(KeyStroke.getKeyStroke(KeyEvent.VK_Z,InputEvent.CTRL_MASK), 
                                 "listenCtrlzKey");
 91:                am.put("listenCtrlzKey", new AbstractAction(){
 92: 
 93:                     /**
 94:                      * 
 95:                      */
 96:                     private static final long serialVersionUID = 1L;
 97: 
 98:                     @Override
 99:                     public void actionPerformed(ActionEvent arg0) {
100:                          /*
101:                           * update the undo content when user pressed Ctrl + Z key  * 
102:                           */
103:                          setText(myUndoWork.releaseDataForUndo());
104:                          
105:                          
106:                     }
107:                });
108:           }
109:      }
110:           
111:           
112:      public static void main(String[] args){
113:           JFrame frame = new SimpleTextApplication();
114:           frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
115:           frame.pack();
116:           frame.setLocation(250,250);
117:           frame.setVisible(true);
118:      }
119: 
120: }
121:

Tried out how undo works?

How To Make It Work?

  1. When the application is opened, MyUndoWork is implemented and initialized.
  2. Content is updated when user presses spacebar key by getText() method.
  3. Content updated is retrieved and store it undo memory by declaring updateUndoMemory() method.
  4. To update undo content when user presses Ctrl + Z by declaring releaseDataForUndo() method.

That’s all! You can perform undo work on your application by declaring only two methods if implemented MyUndoWork class.

How Undo Works?

Predict user input " B C D" into text area and "A" exists on initial.

undo2

From the image above, "A" letter is there when user opens the application After that, letter "B" is input and spacebar by user. Before content is changed, initial content "A" is stored into memory. Again, "C" is input and spacebar. The content before "C" is input, "A B " is stored into memory. Again, "D" is input and spacebar. The content before "D" is input, content "A B C" is retrieved and stored into memory.

When user presses shortcut key Ctrl + Z to perform undo three times, it returns to initial state "A". The following picture shows how it works.

undo3

Ctrl+Z is the shortcut key of undo. When shortcut key is pressed, the top layer of memory is released into content. For instance, current content "A B C D" is input and Ctrl+Z  is pressed, the previous top layer memory "A B C" is released into content. When the top layer memory"A B C" is released into content, current content "A B C D" is replaced by top layer memory. So, what user will see is only the content of top layer memory.

Again, Ctrl + Z is pressed and "A B" is released into content and the current content "A B C" is replaced by it.

This is how my undo works.

Thank you for reading my post.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Japan Japan
Hi! Thank you everyone who reading my article. My major is electronic and programming. Right now I am doing foreign study at Japan. I will like sharing to everyone with my works and if you do interesting with my works, please leave you comment on my blog. Any comments is welcoming.

Comments and Discussions

 
-- There are no messages in this forum --