KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > snow > texteditor > UndoableDocument


1 package snow.texteditor;
2
3 import snow.texteditor.*;
4 import snow.Basics;
5 import javax.swing.text.*;
6 import javax.swing.undo.*;
7 import javax.swing.event.*;
8 import java.awt.*;
9 import java.util.*;
10
11
12 /** A document with an undo capability
13 */

14 public class UndoableDocument extends SimpleDocument implements UndoableEditListener
15 {
16   /** UndoManager that we add edits to. */
17   private UndoManager undoManager_ = new UndoManager();
18
19   private boolean doNotUndoThis = false;
20
21   public UndoableDocument()
22   {
23     addUndoableEditListener(this);
24   } // Constructor
25

26
27   /** Allow to retrieve the undo manager. Can be later readded
28       after the text has been repasted. Useful when simulating multiple documents in the same doc.
29   */

30   public final UndoManager getAndRemoveUndoManager()
31   {
32      this.removeUndoableEditListener(this);
33      UndoManager um = undoManager_;
34      undoManager_ = null;
35      return um;
36   }
37
38   public final void reinstallUndoManager(UndoManager um)
39   {
40      if(undoManager_!=null)
41      {
42         System.out.println("PROBLEM: undomanager not null");
43         this.removeUndoableEditListener(this);
44      }
45      this.undoManager_ = um;
46      this.addUndoableEditListener(this);
47   }
48
49   //
50
// UNDO Manager interface
51
// he is not accessible from outside...
52
//
53

54   public void _setUndoEnabled(boolean state)
55   {
56      doNotUndoThis = state;
57   }
58
59   // important: the styler really polls a lot of style calls that are not of interrest
60
// with this flag set to true, all style changes are ignored
61
public boolean ignoreStyleUndos = true;
62
63   /**
64    * Messaged when the Document has created an edit, the edit is
65    * added to <code>undo</code>, an instance of UndoManager.
66    */

67   public void undoableEditHappened(UndoableEditEvent e)
68   {
69     if(doNotUndoThis==false)
70     {
71        if(ignoreStyleUndos)
72        {
73           if(e.getEdit() instanceof AbstractDocument.DefaultDocumentEvent)
74           {
75              AbstractDocument.DefaultDocumentEvent de = (AbstractDocument.DefaultDocumentEvent) e.getEdit();
76              // this selects the style events, the others are INSERT or REMOVE
77
if(de.getType()==DocumentEvent.EventType.CHANGE)
78              {
79                 e.getEdit().die();
80                 return;
81              }
82           }
83
84        }
85        if(undoManager_!=null)
86        {
87          undoManager_.addEdit(e.getEdit());
88          alertListenersThatUndoManagerStateChanged();
89        }
90     }
91   }
92
93
94   public void undo()
95   {
96      try
97      {
98         if(undoManager_.canUndo())
99         {
100           undoManager_.undo();
101           alertListenersThatUndoManagerStateChanged();
102         }
103      }
104      catch(Exception JavaDoc cue)
105      {
106         // not only UndoExceptions....
107
cue.printStackTrace();
108      }
109   }
110
111
112   public void redo()
113   {
114       try
115       {
116         if(undoManager_.canRedo())
117         {
118           undoManager_.redo();
119           alertListenersThatUndoManagerStateChanged();
120         }
121       }
122       catch(Exception JavaDoc cue)
123       {
124         cue.printStackTrace();
125         // not only UndoExceptions....
126
}
127   }
128
129
130   public boolean canUndo() { return undoManager_.canUndo();}
131   public boolean canRedo() { return undoManager_.canRedo();}
132   public String JavaDoc getNextUndoName() { return undoManager_.getUndoPresentationName(); }
133   public String JavaDoc getNextRedoName() { return undoManager_.getRedoPresentationName(); }
134
135   public void deleteUndoBuffer()
136   {
137      undoManager_.discardAllEdits();
138      alertListenersThatUndoManagerStateChanged();
139   }
140
141
142   // Undo manager listener
143
//
144

145   private final Vector<ChangeListener> undoManagerlisteners = new Vector<ChangeListener>();
146
147   /**
148    * allow one to listen to the undoManager state change,
149    * used for the undo/redo button visibilities.
150    */

151   public void addUndoManagerListener(ChangeListener listener)
152   {
153      synchronized(undoManagerlisteners)
154      {
155        undoManagerlisteners.addElement(listener);
156      }
157   }
158
159   public void removeUndoManagerListener(ChangeListener listener)
160   {
161      synchronized(undoManagerlisteners)
162      {
163        undoManagerlisteners.removeElement(listener);
164      }
165   }
166
167   private void alertListenersThatUndoManagerStateChanged()
168   {
169      // make a copy to safely iterates. Avoid concurrent access problems
170
ChangeListener[] cls = null;
171      synchronized(undoManagerlisteners)
172      {
173        cls = undoManagerlisteners.toArray(new ChangeListener[undoManagerlisteners.size()]);
174      }
175
176      for(ChangeListener cl : cls)
177      {
178         cl.stateChanged(new ChangeEvent(this));
179      }
180   }
181
182
183   public void terminate()
184   {
185      this.removeUndoableEditListener(this);
186      // delete all references
187
undoManagerlisteners.removeAllElements();
188      undoManager_.discardAllEdits();
189   }
190
191 }
Popular Tags