/* * 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 UndoableEdit listeners. * * @author Ray Ryan */ public class UndoableEditSupport { protected int updateLevel; protected CompoundEdit compoundEdit; protected Vector listeners; protected Object realSource; /** * Constructs an UndoableEditSupport object. */ public UndoableEditSupport() { this(null); } /** * Constructs an UndoableEditSupport object. * * @param r an Object */ public UndoableEditSupport(Object r) { realSource = r == null ? this : r; updateLevel = 0; compoundEdit = null; listeners = new Vector(); } /** * Registers an UndoableEditListener. * The listener is notified whenever an edit occurs which can be undone. * * @param l an UndoableEditListener object * @see #removeUndoableEditListener */ public synchronized void addUndoableEditListener(UndoableEditListener l) { listeners.addElement(l); } /** * Removes an UndoableEditListener. * * @param l the UndoableEditListener object to be removed * @see #addUndoableEditListener */ public synchronized void removeUndoableEditListener(UndoableEditListener l) { listeners.removeElement(l); } /** * Returns an array of all the UndoableEditListeners added * to this UndoableEditSupport with addUndoableEditListener(). * * @return all of the UndoableEditListeners 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 postEdit and endUpdate. Calls * undoableEditHappened in all listeners. No synchronization * is performed here, since the two calling methods are synchronized. * * @param e edit to be verified */ protected void _postEdit(UndoableEdit e) { UndoableEditEvent ev = new UndoableEditEvent(realSource, e); @SuppressWarnings("unchecked") Enumeration cursor = ((Vector)listeners.clone()).elements(); while (cursor.hasMoreElements()) { cursor.nextElement().undoableEditHappened(ev); } } /** * DEADLOCK WARNING: Calling this method may call * undoableEditHappened in all listeners. * It is unwise to call this method from one of its listeners. * * @param e edit to be posted */ 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 beginUpdate. * Exposed here for subclasses' use. * * @return new created {@code CompoundEdit} object */ protected CompoundEdit createCompoundEdit() { return new CompoundEdit(); } /** * DEADLOCK WARNING: Calling this method may call * undoableEditHappened 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 String representation of this object */ public String toString() { return super.toString() + " updateLevel: " + updateLevel + " listeners: " + listeners + " compoundEdit: " + compoundEdit; } }