1. /*
  2. * @(#)UndoableEditSupport.java 1.11 00/02/02
  3. *
  4. * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package javax.swing.undo;
  11. import javax.swing.event.*;
  12. import java.util.*;
  13. /**
  14. * A support class used for managing UndoableEdit listeners.
  15. *
  16. * @author Ray Ryan
  17. * @version 1.11 02/02/00
  18. */
  19. public class UndoableEditSupport {
  20. protected int updateLevel;
  21. protected CompoundEdit compoundEdit;
  22. protected Vector listeners;
  23. protected Object realSource;
  24. /**
  25. * Constructs an UndoableEditSupport object.
  26. */
  27. public UndoableEditSupport() {
  28. this(null);
  29. }
  30. /**
  31. * Constructs an UndoableEditSupport object.
  32. *
  33. * @param r an Object
  34. */
  35. public UndoableEditSupport(Object r) {
  36. realSource = r == null ? this : r;
  37. updateLevel = 0;
  38. compoundEdit = null;
  39. listeners = new Vector();
  40. }
  41. /**
  42. * Registers an UndoableEditListener. The listener is notified whenever
  43. * an edit occurs which can be undone.
  44. *
  45. * @param l an UndoableEditListener object
  46. * @see #removeUndoableEditListener
  47. */
  48. public synchronized void addUndoableEditListener(UndoableEditListener l) {
  49. listeners.addElement(l);
  50. }
  51. /**
  52. * Removes an UndoableEditListener.
  53. *
  54. * @param l an UndoableEditListener object
  55. * @see #addUndoableEditListener
  56. */
  57. public synchronized void removeUndoableEditListener(UndoableEditListener l)
  58. {
  59. listeners.removeElement(l);
  60. }
  61. /**
  62. * Called only from postEdit and endUpdate. Calls
  63. * undoableEditHappened in all listeners. No synchronization
  64. * is performed here, since the two calling methods are
  65. * synchonized.
  66. */
  67. protected void _postEdit(UndoableEdit e) {
  68. UndoableEditEvent ev = new UndoableEditEvent(realSource, e);
  69. Enumeration cursor = listeners.elements();
  70. while (cursor.hasMoreElements()) {
  71. ((UndoableEditListener)cursor.nextElement()).
  72. undoableEditHappened(ev);
  73. }
  74. }
  75. /**
  76. * DEADLOCK WARNING: Calling this method may call undoableEditHappened
  77. * in all listeners. It is unwise to call this method from one
  78. * of its listeners.
  79. */
  80. public synchronized void postEdit(UndoableEdit e) {
  81. if (updateLevel == 0) {
  82. _postEdit(e);
  83. } else {
  84. // PENDING(rjrjr) Throw an exception if this fails?
  85. compoundEdit.addEdit(e);
  86. }
  87. }
  88. /**
  89. * Returns the update level value.
  90. *
  91. * @return an int representing the update level
  92. */
  93. public int getUpdateLevel() {
  94. return updateLevel;
  95. }
  96. /**
  97. *
  98. */
  99. public synchronized void beginUpdate() {
  100. if (updateLevel == 0) {
  101. compoundEdit = createCompoundEdit();
  102. }
  103. updateLevel++;
  104. }
  105. /**
  106. * Called only from beginUpdate. Exposed here for subclasses' use
  107. */
  108. protected CompoundEdit createCompoundEdit() {
  109. return new CompoundEdit();
  110. }
  111. /**
  112. * DEADLOCK WARNING: Calling this method may call undoableEditHappened
  113. * in all listeners. It is unwise to call this method from one
  114. * of its listeners.
  115. */
  116. public synchronized void endUpdate() {
  117. updateLevel--;
  118. if (updateLevel == 0) {
  119. compoundEdit.end();
  120. _postEdit(compoundEdit);
  121. compoundEdit = null;
  122. }
  123. }
  124. /**
  125. * Returns a string that displays and identifies this
  126. * object's properties.
  127. *
  128. * @return a String representation of this object
  129. */
  130. public String toString() {
  131. return super.toString() +
  132. " updateLevel: " + updateLevel +
  133. " listeners: " + listeners +
  134. " compoundEdit: " + compoundEdit;
  135. }
  136. }