1. /*
  2. * @(#)StateEdit.java 1.9 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing.undo;
  8. import java.util.Enumeration;
  9. import java.util.Hashtable;
  10. import java.util.Vector;
  11. /**
  12. * <P>StateEdit is a general edit for objects that change state.
  13. * Objects being edited must conform to the StateEditable interface.</P>
  14. *
  15. * <P>This edit class works by asking an object to store it's state in
  16. * Hashtables before and after editing occurs. Upon undo or redo the
  17. * object is told to restore it's state from these Hashtables.</P>
  18. *
  19. * A state edit is used as follows:
  20. * <PRE>
  21. * // Create the edit during the "before" state of the object
  22. * StateEdit newEdit = new StateEdit(myObject);
  23. * // Modify the object
  24. * myObject.someStateModifyingMethod();
  25. * // "end" the edit when you are done modifying the object
  26. * newEdit.end();
  27. * </PRE>
  28. *
  29. * <P><EM>Note that when a StateEdit ends, it removes redundant state from
  30. * the Hashtables - A state Hashtable is not guaranteed to contain all
  31. * keys/values placed into it when the state is stored!</EM></P>
  32. *
  33. * @see StateEditable
  34. *
  35. * @version 1.9 11/29/01
  36. * @author Ray Ryan
  37. */
  38. public class StateEdit
  39. extends AbstractUndoableEdit {
  40. protected static final String RCSID = "$Id: StateEdit.java,v 1.6 1997/10/01 20:05:51 sandipc Exp $";
  41. //
  42. // Attributes
  43. //
  44. /**
  45. * The object being edited
  46. */
  47. protected StateEditable object;
  48. /**
  49. * The state information prior to the edit
  50. */
  51. protected Hashtable preState;
  52. /**
  53. * The state information after the edit
  54. */
  55. protected Hashtable postState;
  56. /**
  57. * The undo/redo presentation name
  58. */
  59. protected String undoRedoName;
  60. //
  61. // Constructors
  62. //
  63. /**
  64. * Create and return a new StateEdit.
  65. *
  66. * @param anObject The object to watch for changing state
  67. *
  68. * @see StateEdit
  69. */
  70. public StateEdit(StateEditable anObject) {
  71. super();
  72. init (anObject,null);
  73. }
  74. /**
  75. * Create and return a new StateEdit with a presentation name.
  76. *
  77. * @param anObject The object to watch for changing state
  78. * @param name The presentation name to be used for this edit
  79. *
  80. * @see StateEdit
  81. */
  82. public StateEdit(StateEditable anObject, String name) {
  83. super();
  84. init (anObject,name);
  85. }
  86. protected void init (StateEditable anObject, String name) {
  87. this.object = anObject;
  88. this.preState = new Hashtable(11);
  89. this.object.storeState(this.preState);
  90. this.postState = null;
  91. this.undoRedoName = name;
  92. }
  93. //
  94. // Operation
  95. //
  96. /**
  97. * Gets the post-edit state of the StateEditable object and
  98. * ends the edit.
  99. */
  100. public void end() {
  101. this.postState = new Hashtable(11);
  102. this.object.storeState(this.postState);
  103. this.removeRedundantState();
  104. }
  105. /**
  106. * Tells the edited object to apply the state prior to the edit
  107. */
  108. public void undo() {
  109. super.undo();
  110. this.object.restoreState(preState);
  111. }
  112. /**
  113. * Tells the edited object to apply the state after the edit
  114. */
  115. public void redo() {
  116. super.redo();
  117. this.object.restoreState(postState);
  118. }
  119. /**
  120. * Gets the presentation name for this edit
  121. */
  122. public String getPresentationName() {
  123. return this.undoRedoName;
  124. }
  125. //
  126. // Internal support
  127. //
  128. /**
  129. * Remove redundant key/values in state hashtables.
  130. */
  131. protected void removeRedundantState() {
  132. Vector uselessKeys = new Vector();
  133. Enumeration myKeys = preState.keys();
  134. // Locate redundant state
  135. while (myKeys.hasMoreElements()) {
  136. Object myKey = myKeys.nextElement();
  137. if (postState.containsKey(myKey) &&
  138. postState.get(myKey).equals(preState.get(myKey))) {
  139. uselessKeys.addElement(myKey);
  140. }
  141. }
  142. // Remove redundant state
  143. for (int i = uselessKeys.size()-1; i >= 0; i--) {
  144. Object myKey = uselessKeys.elementAt(i);
  145. preState.remove(myKey);
  146. postState.remove(myKey);
  147. }
  148. }
  149. } // End of class StateEdit