mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			266 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			266 lines
		
	
	
		
			8.3 KiB
		
	
	
	
		
			Java
		
	
	
	
/* StateEdit.java -- UndoableEdit for StateEditable implementations.
 | 
						|
   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
 | 
						|
 | 
						|
This file is part of GNU Classpath.
 | 
						|
 | 
						|
GNU Classpath is free software; you can redistribute it and/or modify
 | 
						|
it under the terms of the GNU General Public License as published by
 | 
						|
the Free Software Foundation; either version 2, or (at your option)
 | 
						|
any later version.
 | 
						|
 | 
						|
GNU Classpath is distributed in the hope that it will be useful, but
 | 
						|
WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
General Public License for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License
 | 
						|
along with GNU Classpath; see the file COPYING.  If not, write to the
 | 
						|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
						|
02110-1301 USA.
 | 
						|
 | 
						|
Linking this library statically or dynamically with other modules is
 | 
						|
making a combined work based on this library.  Thus, the terms and
 | 
						|
conditions of the GNU General Public License cover the whole
 | 
						|
combination.
 | 
						|
 | 
						|
As a special exception, the copyright holders of this library give you
 | 
						|
permission to link this library with independent modules to produce an
 | 
						|
executable, regardless of the license terms of these independent
 | 
						|
modules, and to copy and distribute the resulting executable under
 | 
						|
terms of your choice, provided that you also meet, for each linked
 | 
						|
independent module, the terms and conditions of the license of that
 | 
						|
module.  An independent module is a module which is not derived from
 | 
						|
or based on this library.  If you modify this library, you may extend
 | 
						|
this exception to your version of the library, but you are not
 | 
						|
obligated to do so.  If you do not wish to do so, delete this
 | 
						|
exception statement from your version. */
 | 
						|
 | 
						|
 | 
						|
package javax.swing.undo;
 | 
						|
 | 
						|
import java.util.Hashtable;
 | 
						|
import java.util.Iterator;
 | 
						|
 | 
						|
/**
 | 
						|
 * A helper class, making it easy to support undo and redo.
 | 
						|
 *
 | 
						|
 * <p>The following example shows how to use this class.</p>
 | 
						|
 *
 | 
						|
 * <pre>
 | 
						|
 * Foo foo; // class Foo implements {@link StateEditable}
 | 
						|
 * StateEdit edit;
 | 
						|
 *
 | 
						|
 * edit = new StateEdit(foo, "Name Change");
 | 
						|
 * foo.setName("Jane Doe");
 | 
						|
 * edit.end();
 | 
						|
 * undoManager.addEdit(edit);
 | 
						|
 * </pre>
 | 
						|
 *
 | 
						|
 * <p>If <code>Foo</code>’s implementation of {@link
 | 
						|
 * StateEditable} considers the name as part of the editable state,
 | 
						|
 * the user can now choose “Undo Name Change” or
 | 
						|
 * “Redo Name Change” from the respective menu. No
 | 
						|
 * further undo support is needed from the application.</p>
 | 
						|
 *
 | 
						|
 * <p>The following explains what happens in the example.</p>
 | 
						|
 *
 | 
						|
 * <ol>
 | 
						|
 * <li>When a <code>StateEdit</code> is created, the associated
 | 
						|
 *     {@link StateEditable} gets asked to store its state into a hash
 | 
						|
 *     table, {@link #preState}.</li>
 | 
						|
 * <li>The application will now perform some changes to the edited
 | 
						|
 *     object. This typically happens by invoking methods on the edited
 | 
						|
 *     object.</li>
 | 
						|
 * <li>The editing phase is terminated by invoking the {@link #end()}
 | 
						|
 *     method of the <code>StateEdit</code>. The <code>end()</code> method
 | 
						|
 *     does two things.
 | 
						|
 *
 | 
						|
 *     <ul>
 | 
						|
 *     <li>The edited object receives a second request for storing
 | 
						|
 *         its state.  This time, it will use a different hash table, {@link
 | 
						|
 *         #postState}.</li>
 | 
						|
 *     <li>To increase efficiency, the <code>StateEdit</code> now removes
 | 
						|
 *         any entries from {@link #preState} and {@link #postState} that have
 | 
						|
 *         the same key, and whose values are equal. Equality is determined
 | 
						|
 *         by invoking the <code>equals</code> method inherited from
 | 
						|
 *         {@link java.lang.Object}.</li>
 | 
						|
 *     </ul></li>
 | 
						|
 * <li>When the user later chooses to undo the <code>StateEdit</code>,
 | 
						|
 * the edited object is asked to {@linkplain StateEditable#restoreState
 | 
						|
 * restore its state} from the {@link #preState} table.  Similarly,
 | 
						|
 * when the user chooses to <i>redo</i> the <code>StateEdit</code>,
 | 
						|
 * the edited object gets asked to restore its state from the {@link
 | 
						|
 * #postState}.</li>
 | 
						|
 * </ol>
 | 
						|
 *
 | 
						|
 * @author Andrew Selkirk (aselkirk@sympatico.ca)
 | 
						|
 * @author Sascha Brawer (brawer@dandelis.ch)
 | 
						|
 */
 | 
						|
public class StateEdit
 | 
						|
  extends AbstractUndoableEdit
 | 
						|
{
 | 
						|
  /**
 | 
						|
   * The ID of the Java source file in Sun’s Revision Control
 | 
						|
   * System (RCS).  This certainly should not be part of the API
 | 
						|
   * specification. But in order to be API-compatible with
 | 
						|
   * Sun’s reference implementation, GNU Classpath also has to
 | 
						|
   * provide this field and match its value. The value used here has
 | 
						|
   * been in every JDK release at least from 1.2 to 1.5.
 | 
						|
   */
 | 
						|
  protected static final String RCSID = "$" +
 | 
						|
    "Id: StateEdit.java,v 1.6 1997/10/01 20:05:51 sandipc Exp $";
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * The object which is being edited by this <code>StateEdit</code>.
 | 
						|
   */
 | 
						|
  protected StateEditable object;
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * The state of <code>object</code> at the time of constructing
 | 
						|
   * this <code>StateEdit</code>.
 | 
						|
   */
 | 
						|
  protected Hashtable<Object, Object> preState;
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * The state of <code>object</code> at the time when {@link #end()}
 | 
						|
   * was called.
 | 
						|
   */
 | 
						|
  protected Hashtable<Object, Object> postState;
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * A human-readable name for this edit action.
 | 
						|
   */
 | 
						|
  protected String undoRedoName;
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Constructs a <code>StateEdit</code>, specifying the object whose
 | 
						|
   * state is being edited.
 | 
						|
   *
 | 
						|
   * @param obj the object whose state is being edited by this
 | 
						|
   * <code>StateEdit</code>.
 | 
						|
   */
 | 
						|
  public StateEdit(StateEditable obj)
 | 
						|
  {
 | 
						|
    init(obj, null);
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Constructs a <code>StateEdit</code>, specifying the object whose
 | 
						|
   * state is being edited.
 | 
						|
   *
 | 
						|
   * @param obj the object whose state is being edited by this
 | 
						|
   * <code>StateEdit</code>.
 | 
						|
   *
 | 
						|
   * @param name the human-readable name of the editing action.
 | 
						|
   */
 | 
						|
  public StateEdit(StateEditable obj, String name)
 | 
						|
  {
 | 
						|
    init(obj, name);
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Initializes this <code>StateEdit</code>. The edited object will
 | 
						|
   * be asked to store its current state into {@link #preState}.
 | 
						|
   *
 | 
						|
   * @param obj the object being edited.
 | 
						|
   *
 | 
						|
   * @param name the human-readable name of the editing action.
 | 
						|
   */
 | 
						|
  protected void init(StateEditable obj, String name)
 | 
						|
  {
 | 
						|
    object = obj;
 | 
						|
    undoRedoName = name;
 | 
						|
    preState = new Hashtable<Object,Object>();
 | 
						|
    postState = new Hashtable<Object,Object>();
 | 
						|
    obj.storeState(preState);
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Informs this <code>StateEdit</code> that all edits are finished.
 | 
						|
   * The edited object will be asked to store its state into {@link
 | 
						|
   * #postState}, and any redundant entries will get removed from
 | 
						|
   * {@link #preState} and {@link #postState}.
 | 
						|
   */
 | 
						|
  public void end()
 | 
						|
  {
 | 
						|
    object.storeState(postState);
 | 
						|
    removeRedundantState();
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Undoes this edit operation. The edited object will be asked to
 | 
						|
   * {@linkplain StateEditable#restoreState restore its state} from
 | 
						|
   * {@link #preState}.
 | 
						|
   *
 | 
						|
   * @throws CannotUndoException if {@link #canUndo()} returns
 | 
						|
   * <code>false</code>, for example because this action has already
 | 
						|
   * been undone.
 | 
						|
   */
 | 
						|
  public void undo()
 | 
						|
  {
 | 
						|
    super.undo();
 | 
						|
    object.restoreState(preState);
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Redoes this edit operation. The edited object will be asked to
 | 
						|
   * {@linkplain StateEditable#restoreState restore its state} from
 | 
						|
   * {@link #postState}.
 | 
						|
   *
 | 
						|
   * @throws CannotRedoException if {@link #canRedo()} returns
 | 
						|
   * <code>false</code>, for example because this action has not yet
 | 
						|
   * been undone.
 | 
						|
   */
 | 
						|
  public void redo()
 | 
						|
  {
 | 
						|
    super.redo();
 | 
						|
    object.restoreState(postState);
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Returns a human-readable, localized name that describes this
 | 
						|
   * editing action and can be displayed to the user.
 | 
						|
   *
 | 
						|
   * @return the name, or <code>null</code> if no presentation
 | 
						|
   * name is available.
 | 
						|
   */
 | 
						|
  public String getPresentationName()
 | 
						|
  {
 | 
						|
    return undoRedoName;
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  /**
 | 
						|
   * Removes all redundant entries from the pre- and post-edit state
 | 
						|
   * hash tables. An entry is considered redundant if it is present
 | 
						|
   * both before and after the edit, and if the two values are equal.
 | 
						|
   */
 | 
						|
  protected void removeRedundantState()
 | 
						|
  {
 | 
						|
    Iterator<Object> i = preState.keySet().iterator();
 | 
						|
    while (i.hasNext())
 | 
						|
      {
 | 
						|
        Object key = i.next();
 | 
						|
        if (postState.containsKey(key))
 | 
						|
          {
 | 
						|
            if (preState.get(key).equals(postState.get(key)))
 | 
						|
              {
 | 
						|
                i.remove();
 | 
						|
                postState.remove(key);
 | 
						|
              }
 | 
						|
          }
 | 
						|
      }
 | 
						|
  }
 | 
						|
}
 |