diff options
Diffstat (limited to 'libjava/javax/swing/undo/UndoManager.java')
-rw-r--r-- | libjava/javax/swing/undo/UndoManager.java | 625 |
1 files changed, 0 insertions, 625 deletions
diff --git a/libjava/javax/swing/undo/UndoManager.java b/libjava/javax/swing/undo/UndoManager.java deleted file mode 100644 index 97bd3d31c8f..00000000000 --- a/libjava/javax/swing/undo/UndoManager.java +++ /dev/null @@ -1,625 +0,0 @@ -/* AbstractTableModel.java -- - Copyright (C) 2002, 2004, 2005 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 javax.swing.UIManager; -import javax.swing.event.UndoableEditEvent; -import javax.swing.event.UndoableEditListener; - - -/** - * A manager for providing an application’s undo/redo - * functionality. - * - * <p>Tyipcally, an application will create only one single instance - * of UndoManager. When the user performs an undoable action, for - * instance changing the color of an object from green to blue, the - * application registers an {@link UndoableEdit} object with the - * <code>UndoManager</code>. To implement the “undo” and - * “redo” menu commands, the application invokes the - * UndoManager’s {@link #undo} and {@link #redo} methods. The - * human-readable text of these menu commands is provided by {@link - * #getUndoPresentationName} and {@link #getRedoPresentationName}, - * respectively. To determine whether the menu item should be - * selectable or greyed out, use {@link #canUndo} and {@link - * #canRedo}. - * - * <p>The UndoManager will only keep a specified number of editing - * actions, the <em>limit</em>. The value of this parameter can be - * retrieved by calling {@link #getLimit} and set with {@link - * #setLimit}. If more UndoableEdits are added to the UndoManager, - * the oldest actions will be discarded. - * - * <p>Some applications do not provide separate menu commands for - * “undo” and “redo.” Instead, they - * have just a single command whose text switches between the two. - * Such applications would use an UndoManager with a <code>limit</code> - * of 1. The text of this combined menu item is available via - * {@link #getUndoOrRedoPresentationName}, and it is implemented - * by calling {@link #undoOrRedo}. - * - * <p><b>Thread Safety:</b> In constrast to the other classes of the - * <code>javax.swing.undo</code> package, the public methods of an - * <code>UndoManager</code> are safe to call from concurrent threads. - * The caller does not need to perform external synchronization, and - * {@link javax.swing.event.UndoableEvent} sources do not need to - * broadcast their events from inside the Swing worker thread. - * - * @author Sascha Brawer (brawer@dandelis.ch) - */ -public class UndoManager - extends CompoundEdit - implements UndoableEditListener -{ - /** - * The unique ID for serializing instances of this class. Determined - * using the <code>serialver</code> tool of Sun JDK 1.4.1_01 on - * GNU/Linux. - */ - static final long serialVersionUID = -2077529998244066750L; - - - /** - * An index into the inherited {@link #edits} Vector that indicates - * at which position newly added editing actions would get inserted. - * - * <p>Normally, the value of <code>indexOfNextAdd</code> equals - * the number of UndoableEdits stored by this UndoManager, i.e. - * <code>edits.size()</code>. For each call to {@link #undo}, - * <code>indexOfNextAdd</code> is decremented by one. For each - * call to {@link #redo}, it is incremented again. - */ - int indexOfNextAdd; - - - /** - * The maximum number of UndoableEdits stored by this UndoManager. - */ - int limit; - - - /** - * Constructs an UndoManager. - * - * <p>The <code>limit</code> of the freshly constructed UndoManager - * is 100. - */ - public UndoManager() - { - limit = 100; - } - - - /** - * Returns a string representation for this UndoManager. This may be - * useful for debugging purposes. For the text of menu items, please - * refer to {@link #getUndoPresentationName}, {@link - * #getRedoPresentationName}, and {@link - * #getUndoOrRedoPresentationName}. - */ - public String toString() - { - return super.toString() - + " limit: " + limit - + " indexOfNextAdd: " + indexOfNextAdd; - } - - - /** - * Puts this UndoManager into a state where it acts as a normal - * {@link CompoundEdit}. It is unlikely that an application would - * want to do this. - */ - public synchronized void end() - { - super.end(); - trimEdits(indexOfNextAdd, edits.size() - 1); - } - - - /** - * Returns how many edits this UndoManager can maximally hold. - * - * @see #setLimit - */ - public synchronized int getLimit() - { - return limit; - } - - - /** - * Changes the maximal number of edits that this UndoManager can - * process. If there are currently more edits than the new limit - * allows, they will receive a {@link UndoableEdit#die() die} - * message in reverse order of addition. - * - * @param limit the new limit. - * - * @throws IllegalStateException if {@link #end()} has already been - * called on this UndoManager. - */ - public synchronized void setLimit(int limit) - { - if (!isInProgress()) - throw new IllegalStateException(); - - this.limit = limit; - trimForLimit(); - } - - - /** - * Discards all editing actions that are currently registered with - * this UndoManager. Each {@link UndoableEdit} will receive a {@link - * UndoableEdit#die() die message}. - */ - public synchronized void discardAllEdits() - { - int size; - - size = edits.size(); - for (int i = size - 1; i >= 0; i--) - ((UndoableEdit) edits.get(i)).die(); - indexOfNextAdd = 0; - edits.clear(); - } - - - /** - * Called by various internal methods in order to enforce - * the <code>limit</code> value. - */ - protected void trimForLimit() - { - int high, s; - - s = edits.size(); - - /* The Sun J2SE1.4.1_01 implementation can be observed to do - * nothing (instead of throwing an exception) with a negative or - * zero limit. It may be debatable whether this is the best - * behavior, but we replicate it for sake of compatibility. - */ - if (limit <= 0 || s <= limit) - return; - - high = Math.min(indexOfNextAdd + limit/2 - 1, s - 1); - trimEdits(high + 1, s - 1); - trimEdits(0, high - limit); - } - - - /** - * Discards a range of edits. All edits in the range <code>[from - * .. to]</code> will receive a {@linkplain UndoableEdit#die() die - * message} before being removed from the edits array. If - * <code>from</code> is greater than <code>to</code>, nothing - * happens. - * - * @param from the lower bound of the range of edits to be - * discarded. - * - * @param to the upper bound of the range of edits to be discarded. - */ - protected void trimEdits(int from, int to) - { - if (from > to) - return; - - for (int i = to; i >= from; i--) - ((UndoableEdit) edits.get(i)).die(); - - // Remove the range [from .. to] from edits. If from == to, which - // is likely to be a very common case, we can do better than - // creating a sub-list and clearing it. - if (to == from) - edits.remove(from); - else - edits.subList(from, to + 1).clear(); - - if (indexOfNextAdd > to) - indexOfNextAdd = indexOfNextAdd - to + from - 1; - else if (indexOfNextAdd >= from) - indexOfNextAdd = from; - } - - - /** - * Determines which significant edit would be undone if {@link - * #undo()} was called. - * - * @returns the significant edit that would be undone, or - * <code>null</code> if no significant edit would be affected by - * calling {@link #undo()}. - */ - protected UndoableEdit editToBeUndone() - { - UndoableEdit result; - - for (int i = indexOfNextAdd - 1; i >= 0; i--) - { - result = (UndoableEdit) edits.get(i); - if (result.isSignificant()) - return result; - } - - return null; - } - - - /** - * Determines which significant edit would be redone if {@link - * #redo()} was called. - * - * @returns the significant edit that would be redone, or - * <code>null</code> if no significant edit would be affected by - * calling {@link #redo()}. - */ - protected UndoableEdit editToBeRedone() - { - UndoableEdit result; - - for (int i = indexOfNextAdd; i < edits.size(); i++) - { - result = (UndoableEdit) edits.get(i); - if (result.isSignificant()) - return result; - } - - return null; - } - - - /** - * Undoes all editing actions in reverse order of addition, - * up to the specified action, - * - * @param edit the last editing action to be undone. - */ - protected void undoTo(UndoableEdit edit) - throws CannotUndoException - { - UndoableEdit cur; - - if (!edits.contains(edit)) - throw new CannotUndoException(); - - while (true) - { - indexOfNextAdd -= 1; - cur = (UndoableEdit) edits.get(indexOfNextAdd); - cur.undo(); - if (cur == edit) - return; - } - } - - - /** - * Redoes all editing actions in the same order as they were - * added to this UndoManager, up to the specified action. - * - * @param edit the last editing action to be redone. - */ - protected void redoTo(UndoableEdit edit) - throws CannotRedoException - { - UndoableEdit cur; - - if (!edits.contains(edit)) - throw new CannotRedoException(); - - while (true) - { - cur = (UndoableEdit) edits.get(indexOfNextAdd); - indexOfNextAdd += 1; - cur.redo(); - if (cur == edit) - return; - } - } - - - /** - * Undoes or redoes the last action. If the last action has already - * been undone, it will be re-done, and vice versa. - * - * <p>This is useful for applications that do not present a separate - * undo and redo facility, but just have a single menu item for - * undoing and redoing the very last action. Such applications will - * use an <code>UndoManager</code> whose <code>limit</code> is 1. - */ - public synchronized void undoOrRedo() - throws CannotRedoException, CannotUndoException - { - if (indexOfNextAdd == edits.size()) - undo(); - else - redo(); - } - - - /** - * Determines whether it would be possible to either undo or redo - * this editing action. - * - * <p>This is useful for applications that do not present a separate - * undo and redo facility, but just have a single menu item for - * undoing and redoing the very last action. Such applications will - * use an <code>UndoManager</code> whose <code>limit</code> is 1. - * - * @return <code>true</code> to indicate that this action can be - * undone or redone; <code>false</code> if neither is possible at - * the current time. - */ - public synchronized boolean canUndoOrRedo() - { - return indexOfNextAdd == edits.size() ? canUndo() : canRedo(); - } - - - /** - * Undoes one significant edit action. If insignificant actions have - * been posted after the last signficant action, the insignificant - * ones will be undone first. - * - * <p>However, if {@link #end()} has been called on this - * UndoManager, it will behave like a normal {@link - * CompoundEdit}. In this case, all actions will be undone in - * reverse order of addition. Typical applications will never call - * {@link #end()} on their <code>UndoManager</code>. - * - * @throws CannotUndoException if no action can be undone. - * - * @see #canUndo() - * @see #redo() - * @see #undoOrRedo() - */ - public synchronized void undo() - throws CannotUndoException - { - if (!isInProgress()) - { - super.undo(); - return; - } - - UndoableEdit edit = editToBeUndone(); - if (edit == null) - throw new CannotUndoException(); - - undoTo(edit); - } - - - /** - * Determines whether it would be possible to undo this editing - * action. - * - * @return <code>true</code> to indicate that this action can be - * undone; <code>false</code> otherwise. - * - * @see #undo() - * @see #canRedo() - * @see #canUndoOrRedo() - */ - public synchronized boolean canUndo() - { - UndoableEdit edit; - - if (!isInProgress()) - return super.canUndo(); - - edit = editToBeUndone(); - return edit != null && edit.canUndo(); - } - - - - /** - * Redoes one significant edit action. If insignificant actions have - * been posted in between, the insignificant ones will be redone - * first. - * - * <p>However, if {@link #end()} has been called on this - * UndoManager, it will behave like a normal {@link - * CompoundEdit}. In this case, <em>all</em> actions will be redone - * in order of addition. Typical applications will never call {@link - * #end()} on their <code>UndoManager</code>. - * - * @throws CannotRedoException if no action can be redone. - * - * @see #canRedo() - * @see #redo() - * @see #undoOrRedo() - */ - public synchronized void redo() - throws CannotRedoException - { - if (!isInProgress()) - { - super.redo(); - return; - } - - UndoableEdit edit = editToBeRedone(); - if (edit == null) - throw new CannotRedoException(); - - redoTo(edit); - } - - - /** - * Determines whether it would be possible to redo this editing - * action. - * - * @return <code>true</code> to indicate that this action can be - * redone; <code>false</code> otherwise. - * - * @see #redo() - * @see #canUndo() - * @see #canUndoOrRedo() - */ - public synchronized boolean canRedo() - { - UndoableEdit edit; - - if (!isInProgress()) - return super.canRedo(); - - edit = editToBeRedone(); - return edit != null && edit.canRedo(); - } - - - /** - * Registers an undoable editing action with this UndoManager. If - * the capacity <code>limit</code> is reached, the oldest action - * will be discarded (and receives a {@linkplain UndoableEdit#die() - * die message}. Equally, any actions that were undone (but not re-done) - * will be discarded, too. - * - * @param edit the editing action that is added to this UndoManager. - * - * @return <code>true</code> if <code>edit</code> could be - * incorporated; <code>false</code> if <code>edit</code> has not - * been incorporated because {@link #end()} has already been called - * on this <code>UndoManager</code>. - */ - public synchronized boolean addEdit(UndoableEdit edit) - { - boolean result; - - // Discard any edits starting at indexOfNextAdd. - trimEdits(indexOfNextAdd, edits.size() - 1); - - result = super.addEdit(edit); - indexOfNextAdd = edits.size(); - trimForLimit(); - return result; - } - - - /** - * Calculates a localized text for presenting the undo or redo - * action to the user, for example in the form of a menu command. - * - * <p>This is useful for applications that do not present a separate - * undo and redo facility, but just have a single menu item for - * undoing and redoing the very last action. Such applications will - * use an <code>UndoManager</code> whose <code>limit</code> is 1. - * - * @return the redo presentation name if the last action has already - * been undone, or the undo presentation name otherwise. - * - * @see #getUndoPresentationName() - * @see #getRedoPresentationName() - */ - public synchronized String getUndoOrRedoPresentationName() - { - if (indexOfNextAdd == edits.size()) - return getUndoPresentationName(); - else - return getRedoPresentationName(); - } - - - /** - * Calculates a localized text for presenting the undo action - * to the user, for example in the form of a menu command. - */ - public synchronized String getUndoPresentationName() - { - UndoableEdit edit; - - if (!isInProgress()) - return super.getUndoPresentationName(); - - edit = editToBeUndone(); - if (edit == null) - return UIManager.getString("AbstractUndoableEdit.undoText"); - else - return edit.getUndoPresentationName(); - } - - - /** - * Calculates a localized text for presenting the redo action - * to the user, for example in the form of a menu command. - */ - public synchronized String getRedoPresentationName() - { - UndoableEdit edit; - - if (!isInProgress()) - return super.getRedoPresentationName(); - - edit = editToBeRedone(); - if (edit == null) - return UIManager.getString("AbstractUndoableEdit.redoText"); - else - return edit.getRedoPresentationName(); - } - - - /** - * Registers the edit action of an {@link UndoableEditEvent} - * with this UndoManager. - * - * <p><b>Thread Safety:</b> This method may safely be invoked from - * concurrent threads. The caller does not need to perform external - * synchronization. This means that {@link - * javax.swing.event.UndoableEvent} sources do not need to broadcast - * their events from inside the Swing worker thread. - * - * @param event the event whose <code>edit</code> will be - * passed to {@link #addEdit}. - * - * @see UndoableEditEvent#getEdit() - * @see #addEdit - */ - public void undoableEditHappened(UndoableEditEvent event) - { - // Note that this method does not need to be synchronized, - // because addEdit will obtain and release the mutex. - addEdit(event.getEdit()); - } -} |