1. /*
  2. * @(#)AbstractListModel.java 1.31 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.swing;
  8. import javax.swing.event.*;
  9. import java.io.Serializable;
  10. import java.util.EventListener;
  11. /**
  12. * The abstract definition for the data model that provides
  13. * a <code>List</code> with its contents.
  14. * <p>
  15. * <strong>Warning:</strong>
  16. * Serialized objects of this class will not be compatible with
  17. * future Swing releases. The current serialization support is
  18. * appropriate for short term storage or RMI between applications running
  19. * the same version of Swing. As of 1.4, support for long term storage
  20. * of all JavaBeans<sup><font size="-2">TM</font></sup>
  21. * has been added to the <code>java.beans</code> package.
  22. * Please see {@link java.beans.XMLEncoder}.
  23. *
  24. * @version 1.31 01/23/03
  25. * @author Hans Muller
  26. */
  27. public abstract class AbstractListModel implements ListModel, Serializable
  28. {
  29. protected EventListenerList listenerList = new EventListenerList();
  30. /**
  31. * Adds a listener to the list that's notified each time a change
  32. * to the data model occurs.
  33. *
  34. * @param l the <code>ListDataListener</code> to be added
  35. */
  36. public void addListDataListener(ListDataListener l) {
  37. listenerList.add(ListDataListener.class, l);
  38. }
  39. /**
  40. * Removes a listener from the list that's notified each time a
  41. * change to the data model occurs.
  42. *
  43. * @param l the <code>ListDataListener</code> to be removed
  44. */
  45. public void removeListDataListener(ListDataListener l) {
  46. listenerList.remove(ListDataListener.class, l);
  47. }
  48. /**
  49. * Returns an array of all the list data listeners
  50. * registered on this <code>AbstractListModel</code>.
  51. *
  52. * @return all of this model's <code>ListDataListener</code>s,
  53. * or an empty array if no list data listeners
  54. * are currently registered
  55. *
  56. * @see #addListDataListener
  57. * @see #removeListDataListener
  58. *
  59. * @since 1.4
  60. */
  61. public ListDataListener[] getListDataListeners() {
  62. return (ListDataListener[])listenerList.getListeners(
  63. ListDataListener.class);
  64. }
  65. /**
  66. * <code>AbstractListModel</code> subclasses must call this method
  67. * <b>after</b>
  68. * one or more elements of the list change. The changed elements
  69. * are specified by the closed interval index0, index1 -- the endpoints
  70. * are included. Note that
  71. * index0 need not be less than or equal to index1.
  72. *
  73. * @param source the <code>ListModel</code> that changed, typically "this"
  74. * @param index0 one end of the new interval
  75. * @param index1 the other end of the new interval
  76. * @see EventListenerList
  77. * @see DefaultListModel
  78. */
  79. protected void fireContentsChanged(Object source, int index0, int index1)
  80. {
  81. Object[] listeners = listenerList.getListenerList();
  82. ListDataEvent e = null;
  83. for (int i = listeners.length - 2; i >= 0; i -= 2) {
  84. if (listeners[i] == ListDataListener.class) {
  85. if (e == null) {
  86. e = new ListDataEvent(source, ListDataEvent.CONTENTS_CHANGED, index0, index1);
  87. }
  88. ((ListDataListener)listeners[i+1]).contentsChanged(e);
  89. }
  90. }
  91. }
  92. /**
  93. * <code>AbstractListModel</code> subclasses must call this method
  94. * <b>after</b>
  95. * one or more elements are added to the model. The new elements
  96. * are specified by a closed interval index0, index1 -- the enpoints
  97. * are included. Note that
  98. * index0 need not be less than or equal to index1.
  99. *
  100. * @param source the <code>ListModel</code> that changed, typically "this"
  101. * @param index0 one end of the new interval
  102. * @param index1 the other end of the new interval
  103. * @see EventListenerList
  104. * @see DefaultListModel
  105. */
  106. protected void fireIntervalAdded(Object source, int index0, int index1)
  107. {
  108. Object[] listeners = listenerList.getListenerList();
  109. ListDataEvent e = null;
  110. for (int i = listeners.length - 2; i >= 0; i -= 2) {
  111. if (listeners[i] == ListDataListener.class) {
  112. if (e == null) {
  113. e = new ListDataEvent(source, ListDataEvent.INTERVAL_ADDED, index0, index1);
  114. }
  115. ((ListDataListener)listeners[i+1]).intervalAdded(e);
  116. }
  117. }
  118. }
  119. /**
  120. * <code>AbstractListModel</code> subclasses must call this method
  121. * <b>after</b> one or more elements are removed from the model.
  122. * The new elements
  123. * are specified by a closed interval index0, index1, i.e. the
  124. * range that includes both index0 and index1. Note that
  125. * index0 need not be less than or equal to index1.
  126. *
  127. * @param source the ListModel that changed, typically "this"
  128. * @param index0 one end of the new interval
  129. * @param index1 the other end of the new interval
  130. * @see EventListenerList
  131. * @see DefaultListModel
  132. */
  133. protected void fireIntervalRemoved(Object source, int index0, int index1)
  134. {
  135. Object[] listeners = listenerList.getListenerList();
  136. ListDataEvent e = null;
  137. for (int i = listeners.length - 2; i >= 0; i -= 2) {
  138. if (listeners[i] == ListDataListener.class) {
  139. if (e == null) {
  140. e = new ListDataEvent(source, ListDataEvent.INTERVAL_REMOVED, index0, index1);
  141. }
  142. ((ListDataListener)listeners[i+1]).intervalRemoved(e);
  143. }
  144. }
  145. }
  146. /**
  147. * Returns an array of all the objects currently registered as
  148. * <code><em>Foo</em>Listener</code>s
  149. * upon this model.
  150. * <code><em>Foo</em>Listener</code>s
  151. * are registered using the <code>add<em>Foo</em>Listener</code> method.
  152. * <p>
  153. * You can specify the <code>listenerType</code> argument
  154. * with a class literal, such as <code><em>Foo</em>Listener.class</code>.
  155. * For example, you can query a list model
  156. * <code>m</code>
  157. * for its list data listeners
  158. * with the following code:
  159. *
  160. * <pre>ListDataListener[] ldls = (ListDataListener[])(m.getListeners(ListDataListener.class));</pre>
  161. *
  162. * If no such listeners exist,
  163. * this method returns an empty array.
  164. *
  165. * @param listenerType the type of listeners requested;
  166. * this parameter should specify an interface
  167. * that descends from <code>java.util.EventListener</code>
  168. * @return an array of all objects registered as
  169. * <code><em>Foo</em>Listener</code>s
  170. * on this model,
  171. * or an empty array if no such
  172. * listeners have been added
  173. * @exception ClassCastException if <code>listenerType</code> doesn't
  174. * specify a class or interface that implements
  175. * <code>java.util.EventListener</code>
  176. *
  177. * @see #getListDataListeners
  178. *
  179. * @since 1.3
  180. */
  181. public EventListener[] getListeners(Class listenerType) {
  182. return listenerList.getListeners(listenerType);
  183. }
  184. }