1 /* 2 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.swing.undo; 27 28 import java.util.Enumeration; 29 import java.util.Hashtable; 30 import java.util.Vector; 31 32 /** 33 * <P>StateEdit is a general edit for objects that change state. 34 * Objects being edited must conform to the StateEditable interface.</P> 35 * 36 * <P>This edit class works by asking an object to store it's state in 37 * Hashtables before and after editing occurs. Upon undo or redo the 38 * object is told to restore it's state from these Hashtables.</P> 39 * 40 * A state edit is used as follows: 41 * <PRE> 42 * // Create the edit during the "before" state of the object 43 * StateEdit newEdit = new StateEdit(myObject); 44 * // Modify the object 45 * myObject.someStateModifyingMethod(); 46 * // "end" the edit when you are done modifying the object 47 * newEdit.end(); 48 * </PRE> 49 * 50 * <P><EM>Note that when a StateEdit ends, it removes redundant state from 51 * the Hashtables - A state Hashtable is not guaranteed to contain all 52 * keys/values placed into it when the state is stored!</EM></P> 53 * 54 * @see StateEditable 55 * 56 * @author Ray Ryan 57 */ 58 @SuppressWarnings("serial") // Same-version serialization only 59 public class StateEdit 60 extends AbstractUndoableEdit { 61 62 protected static final String RCSID = "$Id: StateEdit.java,v 1.6 1997/10/01 20:05:51 sandipc Exp $"; 63 64 // 65 // Attributes 66 // 67 68 /** 69 * The object being edited 70 */ 71 protected StateEditable object; 72 73 /** 74 * The state information prior to the edit 75 */ 76 protected Hashtable<Object,Object> preState; 77 78 /** 79 * The state information after the edit 80 */ 81 protected Hashtable<Object,Object> postState; 82 83 /** 84 * The undo/redo presentation name 85 */ 86 protected String undoRedoName; 87 88 // 89 // Constructors 90 // 91 92 /** 93 * Create and return a new StateEdit. 94 * 95 * @param anObject The object to watch for changing state 96 * 97 * @see StateEdit 98 */ 99 public StateEdit(StateEditable anObject) { 100 super(); 101 init (anObject,null); 102 } 103 104 /** 105 * Create and return a new StateEdit with a presentation name. 106 * 107 * @param anObject The object to watch for changing state 108 * @param name The presentation name to be used for this edit 109 * 110 * @see StateEdit 111 */ 112 public StateEdit(StateEditable anObject, String name) { 113 super(); 114 init (anObject,name); 115 } 116 117 protected void init (StateEditable anObject, String name) { 118 this.object = anObject; 119 this.preState = new Hashtable<Object, Object>(11); 120 this.object.storeState(this.preState); 121 this.postState = null; 122 this.undoRedoName = name; 123 } 124 125 126 // 127 // Operation 128 // 129 130 131 /** 132 * Gets the post-edit state of the StateEditable object and 133 * ends the edit. 134 */ 135 public void end() { 136 this.postState = new Hashtable<Object, Object>(11); 137 this.object.storeState(this.postState); 138 this.removeRedundantState(); 139 } 140 141 /** 142 * Tells the edited object to apply the state prior to the edit 143 */ 144 public void undo() { 145 super.undo(); 146 this.object.restoreState(preState); 147 } 148 149 /** 150 * Tells the edited object to apply the state after the edit 151 */ 152 public void redo() { 153 super.redo(); 154 this.object.restoreState(postState); 155 } 156 157 /** 158 * Gets the presentation name for this edit 159 */ 160 public String getPresentationName() { 161 return this.undoRedoName; 162 } 163 164 165 // 166 // Internal support 167 // 168 169 /** 170 * Remove redundant key/values in state hashtables. 171 */ 172 protected void removeRedundantState() { 173 Vector<Object> uselessKeys = new Vector<Object>(); 174 Enumeration myKeys = preState.keys(); 175 176 // Locate redundant state 177 while (myKeys.hasMoreElements()) { 178 Object myKey = myKeys.nextElement(); 179 if (postState.containsKey(myKey) && 180 postState.get(myKey).equals(preState.get(myKey))) { 181 uselessKeys.addElement(myKey); 182 } 183 } 184 185 // Remove redundant state 186 for (int i = uselessKeys.size()-1; i >= 0; i--) { 187 Object myKey = uselessKeys.elementAt(i); 188 preState.remove(myKey); 189 postState.remove(myKey); 190 } 191 } 192 193 } // End of class StateEdit