1. /*
  2. * @(#)AbstractListModel.java 1.34 04/05/05
  3. *
  4. * Copyright 2004 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.34 05/05/04
  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. * <code>index0</code> and <code>index1</code> are the end points
  123. * of the interval that's been removed. Note that <code>index0</code>
  124. * need not be less than or equal to <code>index1</code>.
  125. *
  126. * @param source the <code>ListModel</code> that changed, typically "this"
  127. * @param index0 one end of the removed interval,
  128. * including <code>index0</code>
  129. * @param index1 the other end of the removed interval,
  130. * including <code>index1</code>
  131. * @see EventListenerList
  132. * @see DefaultListModel
  133. */
  134. protected void fireIntervalRemoved(Object source, int index0, int index1)
  135. {
  136. Object[] listeners = listenerList.getListenerList();
  137. ListDataEvent e = null;
  138. for (int i = listeners.length - 2; i >= 0; i -= 2) {
  139. if (listeners[i] == ListDataListener.class) {
  140. if (e == null) {
  141. e = new ListDataEvent(source, ListDataEvent.INTERVAL_REMOVED, index0, index1);
  142. }
  143. ((ListDataListener)listeners[i+1]).intervalRemoved(e);
  144. }
  145. }
  146. }
  147. /**
  148. * Returns an array of all the objects currently registered as
  149. * <code><em>Foo</em>Listener</code>s
  150. * upon this model.
  151. * <code><em>Foo</em>Listener</code>s
  152. * are registered using the <code>add<em>Foo</em>Listener</code> method.
  153. * <p>
  154. * You can specify the <code>listenerType</code> argument
  155. * with a class literal, such as <code><em>Foo</em>Listener.class</code>.
  156. * For example, you can query a list model
  157. * <code>m</code>
  158. * for its list data listeners
  159. * with the following code:
  160. *
  161. * <pre>ListDataListener[] ldls = (ListDataListener[])(m.getListeners(ListDataListener.class));</pre>
  162. *
  163. * If no such listeners exist,
  164. * this method returns an empty array.
  165. *
  166. * @param listenerType the type of listeners requested;
  167. * this parameter should specify an interface
  168. * that descends from <code>java.util.EventListener</code>
  169. * @return an array of all objects registered as
  170. * <code><em>Foo</em>Listener</code>s
  171. * on this model,
  172. * or an empty array if no such
  173. * listeners have been added
  174. * @exception ClassCastException if <code>listenerType</code> doesn't
  175. * specify a class or interface that implements
  176. * <code>java.util.EventListener</code>
  177. *
  178. * @see #getListDataListeners
  179. *
  180. * @since 1.3
  181. */
  182. public <T extends EventListener> T[] getListeners(Class<T> listenerType) {
  183. return listenerList.getListeners(listenerType);
  184. }
  185. }