| /* |
| * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. |
| * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
| * |
| * This code is free software; you can redistribute it and/or modify it |
| * under the terms of the GNU General Public License version 2 only, as |
| * published by the Free Software Foundation. Oracle designates this |
| * particular file as subject to the "Classpath" exception as provided |
| * by Oracle in the LICENSE file that accompanied this code. |
| * |
| * This code 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 |
| * version 2 for more details (a copy is included in the LICENSE file that |
| * accompanied this code). |
| * |
| * You should have received a copy of the GNU General Public License version |
| * 2 along with this work; if not, write to the Free Software Foundation, |
| * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
| * |
| * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
| * or visit www.oracle.com if you need additional information or have any |
| * questions. |
| */ |
| |
| package javax.swing.undo; |
| |
| import javax.swing.event.*; |
| import java.util.*; |
| |
| /** |
| * A support class used for managing <code>UndoableEdit</code> listeners. |
| * |
| * @author Ray Ryan |
| */ |
| public class UndoableEditSupport { |
| protected int updateLevel; |
| protected CompoundEdit compoundEdit; |
| protected Vector<UndoableEditListener> listeners; |
| protected Object realSource; |
| |
| /** |
| * Constructs an <code>UndoableEditSupport</code> object. |
| */ |
| public UndoableEditSupport() { |
| this(null); |
| } |
| |
| /** |
| * Constructs an <code>UndoableEditSupport</code> object. |
| * |
| * @param r an <code>Object</code> |
| */ |
| public UndoableEditSupport(Object r) { |
| realSource = r == null ? this : r; |
| updateLevel = 0; |
| compoundEdit = null; |
| listeners = new Vector<UndoableEditListener>(); |
| } |
| |
| /** |
| * Registers an <code>UndoableEditListener</code>. |
| * The listener is notified whenever an edit occurs which can be undone. |
| * |
| * @param l an <code>UndoableEditListener</code> object |
| * @see #removeUndoableEditListener |
| */ |
| public synchronized void addUndoableEditListener(UndoableEditListener l) { |
| listeners.addElement(l); |
| } |
| |
| /** |
| * Removes an <code>UndoableEditListener</code>. |
| * |
| * @param l the <code>UndoableEditListener</code> object to be removed |
| * @see #addUndoableEditListener |
| */ |
| public synchronized void removeUndoableEditListener(UndoableEditListener l) |
| { |
| listeners.removeElement(l); |
| } |
| |
| /** |
| * Returns an array of all the <code>UndoableEditListener</code>s added |
| * to this UndoableEditSupport with addUndoableEditListener(). |
| * |
| * @return all of the <code>UndoableEditListener</code>s added or an empty |
| * array if no listeners have been added |
| * @since 1.4 |
| */ |
| public synchronized UndoableEditListener[] getUndoableEditListeners() { |
| return listeners.toArray(new UndoableEditListener[0]); |
| } |
| |
| /** |
| * Called only from <code>postEdit</code> and <code>endUpdate</code>. Calls |
| * <code>undoableEditHappened</code> in all listeners. No synchronization |
| * is performed here, since the two calling methods are synchronized. |
| */ |
| protected void _postEdit(UndoableEdit e) { |
| UndoableEditEvent ev = new UndoableEditEvent(realSource, e); |
| Enumeration cursor = ((Vector)listeners.clone()).elements(); |
| while (cursor.hasMoreElements()) { |
| ((UndoableEditListener)cursor.nextElement()). |
| undoableEditHappened(ev); |
| } |
| } |
| |
| /** |
| * DEADLOCK WARNING: Calling this method may call |
| * <code>undoableEditHappened</code> in all listeners. |
| * It is unwise to call this method from one of its listeners. |
| */ |
| public synchronized void postEdit(UndoableEdit e) { |
| if (updateLevel == 0) { |
| _postEdit(e); |
| } else { |
| // PENDING(rjrjr) Throw an exception if this fails? |
| compoundEdit.addEdit(e); |
| } |
| } |
| |
| /** |
| * Returns the update level value. |
| * |
| * @return an integer representing the update level |
| */ |
| public int getUpdateLevel() { |
| return updateLevel; |
| } |
| |
| /** |
| * |
| */ |
| public synchronized void beginUpdate() { |
| if (updateLevel == 0) { |
| compoundEdit = createCompoundEdit(); |
| } |
| updateLevel++; |
| } |
| |
| /** |
| * Called only from <code>beginUpdate</code>. |
| * Exposed here for subclasses' use. |
| */ |
| protected CompoundEdit createCompoundEdit() { |
| return new CompoundEdit(); |
| } |
| |
| /** |
| * DEADLOCK WARNING: Calling this method may call |
| * <code>undoableEditHappened</code> in all listeners. |
| * It is unwise to call this method from one of its listeners. |
| */ |
| public synchronized void endUpdate() { |
| updateLevel--; |
| if (updateLevel == 0) { |
| compoundEdit.end(); |
| _postEdit(compoundEdit); |
| compoundEdit = null; |
| } |
| } |
| |
| /** |
| * Returns a string that displays and identifies this |
| * object's properties. |
| * |
| * @return a <code>String</code> representation of this object |
| */ |
| public String toString() { |
| return super.toString() + |
| " updateLevel: " + updateLevel + |
| " listeners: " + listeners + |
| " compoundEdit: " + compoundEdit; |
| } |
| } |