001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Evgeniya G. Maenkova
019: * @version $Revision$
020: */package javax.swing.undo;
021:
022: import java.util.Vector;
023:
024: import javax.swing.event.UndoableEditEvent;
025: import javax.swing.event.UndoableEditListener;
026:
027: public class UndoableEditSupport {
028:
029: /**
030: * This is a counter. BeginUpdate call increases this variable, endUpdate
031: * call decreases this variable.
032: */
033: protected int updateLevel;
034:
035: protected CompoundEdit compoundEdit;
036:
037: protected Vector<UndoableEditListener> listeners;
038:
039: /**
040: * Source for UndoableEditEvent
041: */
042: protected Object realSource;
043:
044: /**
045: * Calls UndoableEditSupport(null)
046: */
047: public UndoableEditSupport() {
048: this (null);
049: }
050:
051: /**
052: * If source equals null, realSource will be this
053: * object(UndoableEditSupport).
054: */
055: public UndoableEditSupport(final Object source) {
056: realSource = (source == null) ? this : source;
057: listeners = new Vector<UndoableEditListener>();
058: updateLevel = 0;
059: }
060:
061: /**
062: * Creates a clone of listeners vector. Then calls undoableEditHappened on
063: * all registered listeners with new UndoableEditEvent(realSource, ue).
064: */
065: protected void _postEdit(final UndoableEdit ue) {
066: if (listeners.isEmpty()) {
067: return;
068: }
069: Vector duplicateVector = (Vector) listeners.clone();
070: UndoableEditEvent event = new UndoableEditEvent(realSource, ue);
071: for (int i = 0; i < duplicateVector.size(); i++) {
072: ((UndoableEditListener) duplicateVector.elementAt(i))
073: .undoableEditHappened(event);
074: }
075: }
076:
077: /**
078: * If updateLevel equals 0, sets compoundEdit by createCompoundEdit call.
079: * Increments updateLevel. This method updates updateLevel variable, because
080: * of this it is thread - safe
081: */
082: public synchronized void beginUpdate() {
083: if (updateLevel == 0) {
084: compoundEdit = createCompoundEdit();
085: }
086: updateLevel++;
087: }
088:
089: protected CompoundEdit createCompoundEdit() {
090: return new CompoundEdit();
091: }
092:
093: /**
094: * This method is a thread-safe method.
095: */
096: public synchronized void endUpdate() {
097: updateLevel--;
098: if (updateLevel == 0) {
099: _postEdit(compoundEdit);
100: compoundEdit.end();
101: compoundEdit = null;
102: }
103: }
104:
105: public int getUpdateLevel() {
106: return updateLevel;
107: }
108:
109: /**
110: * Thread-safe method. If updateLevel equals 0, then calls _postEdit;
111: * otherwise, calls compoundEdit(ue).
112: *
113: */
114: public synchronized void postEdit(final UndoableEdit ue) {
115: if (updateLevel == 0) {
116: _postEdit(ue);
117: } else {
118: compoundEdit.addEdit(ue);
119: }
120:
121: }
122:
123: /*
124: * The format of the string is based on 1.5 release behavior
125: * which can be revealed using the following code:
126: *
127: * Object obj = new UndoableEditSupport();
128: * System.out.println(obj.toString());
129: */
130: public String toString() {
131: return super .toString() + " " + "updateLevel: " + updateLevel
132: + " " + "listeners: " + listeners + " "
133: + "compoundEdit: " + compoundEdit;
134: }
135:
136: public synchronized void addUndoableEditListener(
137: final UndoableEditListener listener) {
138: listeners.add(listener);
139: }
140:
141: public synchronized void removeUndoableEditListener(
142: final UndoableEditListener listener) {
143: listeners.remove(listener);
144: }
145:
146: public synchronized UndoableEditListener[] getUndoableEditListeners() {
147: return listeners.toArray(new UndoableEditListener[listeners
148: .size()]);
149: }
150:
151: }
|