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