1. /*
  2. * @(#)List.java 1.72 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 java.awt;
  8. import java.util.Vector;
  9. import java.awt.peer.ListPeer;
  10. import java.awt.event.*;
  11. import java.io.ObjectOutputStream;
  12. import java.io.ObjectInputStream;
  13. import java.io.IOException;
  14. /**
  15. * The <code>List</code> component presents the user with a
  16. * scrolling list of text items. The list can be set up so that
  17. * the user can choose either one item or multiple items.
  18. * <p>
  19. * For example, the code . . .
  20. * <p>
  21. * <hr><blockquote><pre>
  22. * List lst = new List(4, false);
  23. * lst.add("Mercury");
  24. * lst.add("Venus");
  25. * lst.add("Earth");
  26. * lst.add("JavaSoft");
  27. * lst.add("Mars");
  28. * lst.add("Jupiter");
  29. * lst.add("Saturn");
  30. * lst.add("Uranus");
  31. * lst.add("Neptune");
  32. * lst.add("Pluto");
  33. * cnt.add(lst);
  34. * </pre></blockquote><hr>
  35. * <p>
  36. * where <code>cnt</code> is a container, produces the following
  37. * scrolling list:
  38. * <p>
  39. * <img src="doc-files/List-1.gif"
  40. * ALIGN=center HSPACE=10 VSPACE=7>
  41. * <p>
  42. * Clicking on an item that isn't selected selects it. Clicking on
  43. * an item that is already selected deselects it. In the preceding
  44. * example, only one item from the scrolling list can be selected
  45. * at a time, since the second argument when creating the new scrolling
  46. * list is <code>false</code>. Selecting an item causes any other
  47. * selected item to be automatically deselected.
  48. * <p>
  49. * Beginning with Java 1.1, the Abstract Window Toolkit
  50. * sends the <code>List</code> object all mouse, keyboard, and focus events
  51. * that occur over it. (The old AWT event model is being maintained
  52. * only for backwards compatibility, and its use is discouraged.)
  53. * <p>
  54. * When an item is selected or deselected, AWT sends an instance
  55. * of <code>ItemEvent</code> to the list.
  56. * When the user double-clicks on an item in a scrolling list,
  57. * AWT sends an instance of <code>ActionEvent</code> to the
  58. * list following the item event. AWT also generates an action event
  59. * when the user presses the return key while an item in the
  60. * list is selected.
  61. * <p>
  62. * If an application wants to perform some action based on an item
  63. * in this list being selected or activated, it should implement
  64. * <code>ItemListener</code> or <code>ActionListener</code>
  65. * as appropriate and register the new listener to receive
  66. * events from this list.
  67. * <p>
  68. * For multiple-selection scrolling lists, it is considered a better
  69. * user interface to use an external gesture (such as clicking on a
  70. * button) to trigger the action.
  71. * @version 1.72, 11/29/01
  72. * @author Sami Shaio
  73. * @see java.awt.event.ItemEvent
  74. * @see java.awt.event.ItemListener
  75. * @see java.awt.event.ActionEvent
  76. * @see java.awt.event.ActionListener
  77. * @since JDK1.0
  78. */
  79. public class List extends Component implements ItemSelectable {
  80. /**
  81. * A vector created to contain items which will become
  82. * part of the List Component.
  83. *
  84. * @serial
  85. * @see addItem()
  86. * @see getItem()
  87. */
  88. Vector items = new Vector();
  89. /**
  90. * This field will represent the number of rows in the
  91. * List Component. It is specified only once, and
  92. * that is when the list component is actually
  93. * created. It will never change.
  94. *
  95. * @serial
  96. * @see getRows()
  97. */
  98. int rows = 0;
  99. /**
  100. * <code>multipleMode</code> is a variable that will
  101. * be set to <code>true</code> if a list component is to be set to
  102. * multiple selection mode, that is where the user can
  103. * select more than one item in a list at one time.
  104. * <code>multipleMode</code> will be set to false if the
  105. * list component is set to single selection, that is where
  106. * the user can only select one item on the list at any
  107. * one time.
  108. *
  109. * @serial
  110. * @see isMultipleMode()
  111. * @see setMultipleMode()
  112. */
  113. boolean multipleMode = false;
  114. /**
  115. * <code>selected</code> is an array that will contain
  116. * the indices of items that have been selected.
  117. *
  118. * @serial
  119. * @see getSelectedIndexes()
  120. * @see getSelectedIndex()
  121. */
  122. int selected[] = new int[0];
  123. /**
  124. * This variable contains the value that will be used
  125. * when trying to make a particular list item visible.
  126. *
  127. * @serial
  128. * @see makeVisible()
  129. */
  130. int visibleIndex = -1;
  131. transient ActionListener actionListener;
  132. transient ItemListener itemListener;
  133. private static final String base = "list";
  134. private static int nameCounter = 0;
  135. /*
  136. * JDK 1.1 serialVersionUID
  137. */
  138. private static final long serialVersionUID = -3304312411574666869L;
  139. /**
  140. * Creates a new scrolling list.
  141. * By default, there are four visible lines and multiple selections are
  142. * not allowed.
  143. */
  144. public List() {
  145. this(0, false);
  146. }
  147. /**
  148. * Creates a new scrolling list initialized with the specified
  149. * number of visible lines. By default, multiple selections are
  150. * not allowed.
  151. * @param rows the number of items to show.
  152. * @since JDK1.1
  153. */
  154. public List(int rows) {
  155. this(rows, false);
  156. }
  157. /**
  158. * The default number of visible rows is 4. A list with
  159. * zero rows is unusable and unsightly.
  160. */
  161. final static int DEFAULT_VISIBLE_ROWS = 4;
  162. /**
  163. * Creates a new scrolling list initialized to display the specified
  164. * number of rows. If the value of <code>multipleMode</code> is
  165. * <code>true</code>, then the user can select multiple items from
  166. * the list. If it is <code>false</code>, only one item at a time
  167. * can be selected.
  168. * @param rows the number of items to show.
  169. * @param multipleMode if <code>true</code>,
  170. * then multiple selections are allowed;
  171. * otherwise, only one item can be selected at a time.
  172. */
  173. public List(int rows, boolean multipleMode) {
  174. this.rows = (rows != 0) ? rows : DEFAULT_VISIBLE_ROWS;
  175. this.multipleMode = multipleMode;
  176. }
  177. /**
  178. * Construct a name for this component. Called by getName() when the
  179. * name is null.
  180. */
  181. String constructComponentName() {
  182. synchronized (getClass()) {
  183. return base + nameCounter++;
  184. }
  185. }
  186. /**
  187. * Creates the peer for the list. The peer allows us to modify the
  188. * list's appearance without changing its functionality.
  189. */
  190. public void addNotify() {
  191. synchronized (getTreeLock()) {
  192. if (peer == null)
  193. peer = getToolkit().createList(this);
  194. super.addNotify();
  195. visibleIndex = -1;
  196. }
  197. }
  198. /**
  199. * Removes the peer for this list. The peer allows us to modify the
  200. * list's appearance without changing its functionality.
  201. */
  202. public void removeNotify() {
  203. synchronized (getTreeLock()) {
  204. ListPeer peer = (ListPeer)this.peer;
  205. if (peer != null) {
  206. selected = peer.getSelectedIndexes();
  207. }
  208. super.removeNotify();
  209. }
  210. }
  211. /**
  212. * Gets the number of items in the list.
  213. * @return the number of items in the list.
  214. * @see java.awt.List#getItem
  215. * @since JDK1.1
  216. */
  217. public int getItemCount() {
  218. return countItems();
  219. }
  220. /**
  221. * @deprecated As of JDK version 1.1,
  222. * replaced by <code>getItemCount()</code>.
  223. */
  224. public int countItems() {
  225. return items.size();
  226. }
  227. /**
  228. * Gets the item associated with the specified index.
  229. * @return an item that is associated with
  230. * the specified index.
  231. * @param index the position of the item.
  232. * @see java.awt.List#getItemCount
  233. */
  234. public String getItem(int index) {
  235. return getItemImpl(index);
  236. }
  237. // NOTE: This method may be called by privileged threads.
  238. // We implement this functionality in a package-private method
  239. // to insure that it cannot be overridden by client subclasses.
  240. // DO NOT INVOKE CLIENT CODE ON THIS THREAD!
  241. final String getItemImpl(int index) {
  242. return (String)items.elementAt(index);
  243. }
  244. /**
  245. * Gets the items in the list.
  246. * @return a string array containing items of the list.
  247. * @see java.awt.List#select
  248. * @see java.awt.List#deselect
  249. * @see java.awt.List#isIndexSelected
  250. * @since JDK1.1
  251. */
  252. public synchronized String[] getItems() {
  253. String itemCopies[] = new String[items.size()];
  254. items.copyInto(itemCopies);
  255. return itemCopies;
  256. }
  257. /**
  258. * Adds the specified item to the end of scrolling list.
  259. * @param item the item to be added.
  260. * @since JDK1.1
  261. */
  262. public void add(String item) {
  263. addItem(item);
  264. }
  265. /**
  266. * @deprecated replaced by <code>add(String)</code>.
  267. */
  268. public void addItem(String item) {
  269. addItem(item, -1);
  270. }
  271. /**
  272. * Adds the specified item to the the scrolling list
  273. * at the position indicated by the index. The index is
  274. * zero-based. If the value of the index is less than zero,
  275. * or if the value of the index is greater than or equal to
  276. * the number of items in the list, then the item is added
  277. * to the end of the list.
  278. * @param item the item to be added.
  279. * If this parameter is null then the item is
  280. * treated as an empty string, <code>""</code>.
  281. * @param index the position at which to add the item.
  282. * @since JDK1.1
  283. */
  284. public void add(String item, int index) {
  285. addItem(item, index);
  286. }
  287. /**
  288. * @deprecated replaced by <code>add(String, int)</code>.
  289. */
  290. public synchronized void addItem(String item, int index) {
  291. if (index < -1 || index >= items.size()) {
  292. index = -1;
  293. }
  294. if (item == null) {
  295. item = "";
  296. }
  297. if (index == -1) {
  298. items.addElement(item);
  299. } else {
  300. items.insertElementAt(item, index);
  301. }
  302. ListPeer peer = (ListPeer)this.peer;
  303. if (peer != null) {
  304. peer.addItem(item, index);
  305. }
  306. }
  307. /**
  308. * Replaces the item at the specified index in the scrolling list
  309. * with the new string.
  310. * @param newValue a new string to replace an existing item.
  311. * @param index the position of the item to replace.
  312. */
  313. public synchronized void replaceItem(String newValue, int index) {
  314. remove(index);
  315. add(newValue, index);
  316. }
  317. /**
  318. * Removes all items from this list.
  319. * @see #remove
  320. * @see #delItems
  321. * @since JDK1.1
  322. */
  323. public void removeAll() {
  324. clear();
  325. }
  326. /**
  327. * @deprecated As of JDK version 1.1,
  328. * replaced by <code>removeAll()</code>.
  329. */
  330. public synchronized void clear() {
  331. ListPeer peer = (ListPeer)this.peer;
  332. if (peer != null) {
  333. peer.clear();
  334. }
  335. items = new Vector();
  336. selected = new int[0];
  337. }
  338. /**
  339. * Removes the first occurrence of an item from the list.
  340. * @param item the item to remove from the list.
  341. * @exception IllegalArgumentException
  342. * if the item doesn't exist in the list.
  343. * @since JDK1.1
  344. */
  345. public synchronized void remove(String item) {
  346. int index = items.indexOf(item);
  347. if (index < 0) {
  348. throw new IllegalArgumentException("item " + item +
  349. " not found in list");
  350. } else {
  351. remove(index);
  352. }
  353. }
  354. /**
  355. * Remove the item at the specified position
  356. * from this scrolling list.
  357. * @param position the index of the item to delete.
  358. * @see java.awt.List#add(String, int)
  359. * @since JDK1.1
  360. * @exception ArrayIndexOutOfBoundsException
  361. * if the <code>position</code> is less than 0 or
  362. * greater than <code>getItemCount()-1</code>
  363. */
  364. public void remove(int position) {
  365. delItem(position);
  366. }
  367. /**
  368. * @deprecated replaced by <code>remove(String)</code>
  369. * and <code>remove(int)</code>.
  370. */
  371. public void delItem(int position) {
  372. delItems(position, position);
  373. }
  374. /**
  375. * Gets the index of the selected item on the list,
  376. * @return the index of the selected item, or
  377. * <code>-1</code> if no item is selected,
  378. * or if more that one item is selected.
  379. * @see java.awt.List#select
  380. * @see java.awt.List#deselect
  381. * @see java.awt.List#isIndexSelected
  382. */
  383. public synchronized int getSelectedIndex() {
  384. int sel[] = getSelectedIndexes();
  385. return (sel.length == 1) ? sel[0] : -1;
  386. }
  387. /**
  388. * Gets the selected indexes on the list.
  389. * @return an array of the selected indexes
  390. * of this scrolling list.
  391. * @see java.awt.List#select
  392. * @see java.awt.List#deselect
  393. * @see java.awt.List#isIndexSelected
  394. */
  395. public synchronized int[] getSelectedIndexes() {
  396. ListPeer peer = (ListPeer)this.peer;
  397. if (peer != null) {
  398. selected = ((ListPeer)peer).getSelectedIndexes();
  399. }
  400. return selected;
  401. }
  402. /**
  403. * Get the selected item on this scrolling list.
  404. * @return the selected item on the list,
  405. * or null if no item is selected.
  406. * @see java.awt.List#select
  407. * @see java.awt.List#deselect
  408. * @see java.awt.List#isIndexSelected
  409. */
  410. public synchronized String getSelectedItem() {
  411. int index = getSelectedIndex();
  412. return (index < 0) ? null : getItem(index);
  413. }
  414. /**
  415. * Get the selected items on this scrolling list.
  416. * @return an array of the selected items
  417. * on this scrolling list.
  418. * @see java.awt.List#select
  419. * @see java.awt.List#deselect
  420. * @see java.awt.List#isIndexSelected
  421. */
  422. public synchronized String[] getSelectedItems() {
  423. int sel[] = getSelectedIndexes();
  424. String str[] = new String[sel.length];
  425. for (int i = 0 ; i < sel.length ; i++) {
  426. str[i] = getItem(sel[i]);
  427. }
  428. return str;
  429. }
  430. /**
  431. * Returns the selected items on the list in an array of Objects.
  432. * @see ItemSelectable
  433. */
  434. public Object[] getSelectedObjects() {
  435. return getSelectedItems();
  436. }
  437. /**
  438. * Selects the item at the specified index in the scrolling list.
  439. * @param index the position of the item to select.
  440. * @see java.awt.List#getSelectedItem
  441. * @see java.awt.List#deselect
  442. * @see java.awt.List#isIndexSelected
  443. */
  444. public void select(int index) {
  445. // Bug #4059614: select can't be synchronized while calling the peer,
  446. // because it is called from the Window Thread. It is sufficient to
  447. // synchronize the code that manipulates 'selected' except for the
  448. // case where the peer changes. To handle this case, we simply
  449. // repeat the selection process.
  450. ListPeer peer;
  451. do {
  452. peer = (ListPeer)this.peer;
  453. if (peer != null) {
  454. peer.select(index);
  455. return;
  456. }
  457. synchronized(this)
  458. {
  459. boolean alreadySelected = false;
  460. for (int i = 0 ; i < selected.length ; i++) {
  461. if (selected[i] == index) {
  462. alreadySelected = true;
  463. break;
  464. }
  465. }
  466. if (!alreadySelected) {
  467. if (!multipleMode) {
  468. selected = new int[1];
  469. selected[0] = index;
  470. } else {
  471. int newsel[] = new int[selected.length + 1];
  472. System.arraycopy(selected, 0, newsel, 0,
  473. selected.length);
  474. newsel[selected.length] = index;
  475. selected = newsel;
  476. }
  477. }
  478. }
  479. } while (peer != this.peer);
  480. }
  481. /**
  482. * Deselects the item at the specified index.
  483. * <p>
  484. * If the item at the specified index is not selected, or if the
  485. * index is out of range, then the operation is ignored.
  486. * @param index the position of the item to deselect.
  487. * @see java.awt.List#select
  488. * @see java.awt.List#getSelectedItem
  489. * @see java.awt.List#isIndexSelected
  490. */
  491. public synchronized void deselect(int index) {
  492. ListPeer peer = (ListPeer)this.peer;
  493. if (peer != null) {
  494. peer.deselect(index);
  495. }
  496. for (int i = 0 ; i < selected.length ; i++) {
  497. if (selected[i] == index) {
  498. int newsel[] = new int[selected.length - 1];
  499. System.arraycopy(selected, 0, newsel, 0, i);
  500. System.arraycopy(selected, i+1, newsel, i, selected.length - (i+1));
  501. selected = newsel;
  502. return;
  503. }
  504. }
  505. }
  506. /**
  507. * Determines if the specified item in this scrolling list is
  508. * selected.
  509. * @param index the item to be checked.
  510. * @return <code>true</code> if the specified item has been
  511. * selected; <code>false</code> otherwise.
  512. * @see java.awt.List#select
  513. * @see java.awt.List#deselect
  514. * @since JDK1.1
  515. */
  516. public boolean isIndexSelected(int index) {
  517. return isSelected(index);
  518. }
  519. /**
  520. * @deprecated As of JDK version 1.1,
  521. * replaced by <code>isIndexSelected(int)</code>.
  522. */
  523. public boolean isSelected(int index) {
  524. int sel[] = getSelectedIndexes();
  525. for (int i = 0 ; i < sel.length ; i++) {
  526. if (sel[i] == index) {
  527. return true;
  528. }
  529. }
  530. return false;
  531. }
  532. /**
  533. * Get the number of visible lines in this list.
  534. * @return the number of visible lines in this scrolling list.
  535. */
  536. public int getRows() {
  537. return rows;
  538. }
  539. /**
  540. * Determines whether this list allows multiple selections.
  541. * @return <code>true</code> if this list allows multiple
  542. * selections; otherwise, <code>false</code>.
  543. * @see java.awt.List#setMultipleMode
  544. * @since JDK1.1
  545. */
  546. public boolean isMultipleMode() {
  547. return allowsMultipleSelections();
  548. }
  549. /**
  550. * @deprecated As of JDK version 1.1,
  551. * replaced by <code>isMultipleMode()</code>.
  552. */
  553. public boolean allowsMultipleSelections() {
  554. return multipleMode;
  555. }
  556. /**
  557. * Sets the flag that determines whether this list
  558. * allows multiple selections.
  559. * @param b if <code>true</code> then multiple selections
  560. * are allowed; otherwise, only one item from
  561. * the list can be selected at once.
  562. * @see java.awt.List#isMultipleMode
  563. * @since JDK1.1
  564. */
  565. public void setMultipleMode(boolean b) {
  566. setMultipleSelections(b);
  567. }
  568. /**
  569. * @deprecated As of JDK version 1.1,
  570. * replaced by <code>setMultipleMode(boolean)</code>.
  571. */
  572. public synchronized void setMultipleSelections(boolean b) {
  573. if (b != multipleMode) {
  574. multipleMode = b;
  575. ListPeer peer = (ListPeer)this.peer;
  576. if (peer != null) {
  577. peer.setMultipleSelections(b);
  578. }
  579. }
  580. }
  581. /**
  582. * Gets the index of the item that was last made visible by
  583. * the method <code>makeVisible</code>.
  584. * @return the index of the item that was last made visible.
  585. * @see java.awt.List#makeVisible
  586. */
  587. public int getVisibleIndex() {
  588. return visibleIndex;
  589. }
  590. /**
  591. * Makes the item at the specified index visible.
  592. * @param index the position of the item.
  593. * @see java.awt.List#getVisibleIndex
  594. */
  595. public synchronized void makeVisible(int index) {
  596. visibleIndex = index;
  597. ListPeer peer = (ListPeer)this.peer;
  598. if (peer != null) {
  599. peer.makeVisible(index);
  600. }
  601. }
  602. /**
  603. * Gets the preferred dimensions for a list with the specified
  604. * number of rows.
  605. * @param rows number of rows in the list.
  606. * @return the preferred dimensions for displaying this scrolling list
  607. * given that the specified number of rows must be visible.
  608. * @see java.awt.Component#getPreferredSize
  609. * @since JDK1.1
  610. */
  611. public Dimension getPreferredSize(int rows) {
  612. return preferredSize(rows);
  613. }
  614. /**
  615. * @deprecated As of JDK version 1.1,
  616. * replaced by <code>getPreferredSize(int)</code>.
  617. */
  618. public Dimension preferredSize(int rows) {
  619. synchronized (getTreeLock()) {
  620. ListPeer peer = (ListPeer)this.peer;
  621. return (peer != null) ?
  622. peer.preferredSize(rows) :
  623. super.preferredSize();
  624. }
  625. }
  626. /**
  627. * Gets the preferred size of this scrolling list.
  628. * @return the preferred dimensions for displaying this scrolling list.
  629. * @see java.awt.Component#getPreferredSize
  630. * @since JDK1.1
  631. */
  632. public Dimension getPreferredSize() {
  633. return preferredSize();
  634. }
  635. /**
  636. * @deprecated As of JDK version 1.1,
  637. * replaced by <code>getPreferredSize()</code>.
  638. */
  639. public Dimension preferredSize() {
  640. synchronized (getTreeLock()) {
  641. return (rows > 0) ?
  642. preferredSize(rows) :
  643. super.preferredSize();
  644. }
  645. }
  646. /**
  647. * Gets the minumum dimensions for a list with the specified
  648. * number of rows.
  649. * @param rows number of rows in the list.
  650. * @return the minimum dimensions for displaying this scrolling list
  651. * given that the specified number of rows must be visible.
  652. * @see java.awt.Component#getMinimumSize
  653. * @since JDK1.1
  654. */
  655. public Dimension getMinimumSize(int rows) {
  656. return minimumSize(rows);
  657. }
  658. /**
  659. * @deprecated As of JDK version 1.1,
  660. * replaced by <code>getMinimumSize(int)</code>.
  661. */
  662. public Dimension minimumSize(int rows) {
  663. synchronized (getTreeLock()) {
  664. ListPeer peer = (ListPeer)this.peer;
  665. return (peer != null) ?
  666. peer.minimumSize(rows) :
  667. super.minimumSize();
  668. }
  669. }
  670. /**
  671. * Determines the minimum size of this scrolling list.
  672. * @return the minimum dimensions needed
  673. * to display this scrolling list.
  674. * @see java.awt.Component#getMinimumSize()
  675. * @since JDK1.1
  676. */
  677. public Dimension getMinimumSize() {
  678. return minimumSize();
  679. }
  680. /**
  681. * @deprecated As of JDK version 1.1,
  682. * replaced by <code>getMinimumSize()</code>.
  683. */
  684. public Dimension minimumSize() {
  685. synchronized (getTreeLock()) {
  686. return (rows > 0) ? minimumSize(rows) : super.minimumSize();
  687. }
  688. }
  689. /**
  690. * Adds the specified item listener to receive item events from
  691. * this list.
  692. * If l is null, no exception is thrown and no action is performed.
  693. *
  694. * @param l the item listener.
  695. * @see java.awt.event.ItemEvent
  696. * @see java.awt.event.ItemListener
  697. * @see java.awt.List#removeItemListener
  698. * @since JDK1.1
  699. */
  700. public synchronized void addItemListener(ItemListener l) {
  701. if (l == null) {
  702. return;
  703. }
  704. itemListener = AWTEventMulticaster.add(itemListener, l);
  705. newEventsOnly = true;
  706. }
  707. /**
  708. * Removes the specified item listener so that it no longer
  709. * receives item events from this list.
  710. * If l is null, no exception is thrown and no action is performed.
  711. *
  712. * @param l the item listener.
  713. * @see java.awt.event.ItemEvent
  714. * @see java.awt.event.ItemListener
  715. * @see java.awt.List#addItemListener
  716. * @since JDK1.1
  717. */
  718. public synchronized void removeItemListener(ItemListener l) {
  719. if (l == null) {
  720. return;
  721. }
  722. itemListener = AWTEventMulticaster.remove(itemListener, l);
  723. }
  724. /**
  725. * Adds the specified action listener to receive action events from
  726. * this list. Action events occur when a user double-clicks
  727. * on a list item.
  728. * If l is null, no exception is thrown and no action is performed.
  729. *
  730. * @param l the action listener.
  731. * @see java.awt.event.ActionEvent
  732. * @see java.awt.event.ActionListener
  733. * @see java.awt.List#removeActionListener
  734. * @since JDK1.1
  735. */
  736. public synchronized void addActionListener(ActionListener l) {
  737. if (l == null) {
  738. return;
  739. }
  740. actionListener = AWTEventMulticaster.add(actionListener, l);
  741. newEventsOnly = true;
  742. }
  743. /**
  744. * Removes the specified action listener so that it no longer
  745. * receives action events from this list. Action events
  746. * occur when a user double-clicks on a list item.
  747. * If l is null, no exception is thrown and no action is performed.
  748. *
  749. * @param l the action listener.
  750. * @see java.awt.event.ActionEvent
  751. * @see java.awt.event.ActionListener
  752. * @see java.awt.List#addActionListener
  753. * @since JDK1.1
  754. */
  755. public synchronized void removeActionListener(ActionListener l) {
  756. if (l == null) {
  757. return;
  758. }
  759. actionListener = AWTEventMulticaster.remove(actionListener, l);
  760. }
  761. // REMIND: remove when filtering is done at lower level
  762. boolean eventEnabled(AWTEvent e) {
  763. switch(e.id) {
  764. case ActionEvent.ACTION_PERFORMED:
  765. if ((eventMask & AWTEvent.ACTION_EVENT_MASK) != 0 ||
  766. actionListener != null) {
  767. return true;
  768. }
  769. return false;
  770. case ItemEvent.ITEM_STATE_CHANGED:
  771. if ((eventMask & AWTEvent.ITEM_EVENT_MASK) != 0 ||
  772. itemListener != null) {
  773. return true;
  774. }
  775. return false;
  776. default:
  777. break;
  778. }
  779. return super.eventEnabled(e);
  780. }
  781. /**
  782. * Processes events on this scrolling list. If an event is
  783. * an instance of <code>ItemEvent</code>, it invokes the
  784. * <code>processItemEvent</code> method. Else, if the
  785. * event is an instance of <code>ActionEvent</code>,
  786. * it invokes <code>processActionEvent</code>.
  787. * If the event is not an item event or an action event,
  788. * it invokes <code>processEvent</code> on the superclass.
  789. * @param e the event.
  790. * @see java.awt.event.ActionEvent
  791. * @see java.awt.event.ItemEvent
  792. * @see java.awt.List#processActionEvent
  793. * @see java.awt.List#processItemEvent
  794. * @since JDK1.1
  795. */
  796. protected void processEvent(AWTEvent e) {
  797. if (e instanceof ItemEvent) {
  798. processItemEvent((ItemEvent)e);
  799. return;
  800. } else if (e instanceof ActionEvent) {
  801. processActionEvent((ActionEvent)e);
  802. return;
  803. }
  804. super.processEvent(e);
  805. }
  806. /**
  807. * Processes item events occurring on this list by
  808. * dispatching them to any registered
  809. * <code>ItemListener</code> objects.
  810. * <p>
  811. * This method is not called unless item events are
  812. * enabled for this component. Item events are enabled
  813. * when one of the following occurs:
  814. * <p><ul>
  815. * <li>An <code>ItemListener</code> object is registered
  816. * via <code>addItemListener</code>.
  817. * <li>Item events are enabled via <code>enableEvents</code>.
  818. * </ul>
  819. * @param e the item event.
  820. * @see java.awt.event.ItemEvent
  821. * @see java.awt.event.ItemListener
  822. * @see java.awt.List#addItemListener
  823. * @see java.awt.Component#enableEvents
  824. * @since JDK1.1
  825. */
  826. protected void processItemEvent(ItemEvent e) {
  827. if (itemListener != null) {
  828. itemListener.itemStateChanged(e);
  829. }
  830. }
  831. /**
  832. * Processes action events occurring on this component
  833. * by dispatching them to any registered
  834. * <code>ActionListener</code> objects.
  835. * <p>
  836. * This method is not called unless action events are
  837. * enabled for this component. Action events are enabled
  838. * when one of the following occurs:
  839. * <p><ul>
  840. * <li>An <code>ActionListener</code> object is registered
  841. * via <code>addActionListener</code>.
  842. * <li>Action events are enabled via <code>enableEvents</code>.
  843. * </ul>
  844. * @param e the action event.
  845. * @see java.awt.event.ActionEvent
  846. * @see java.awt.event.ActionListener
  847. * @see java.awt.List#addActionListener
  848. * @see java.awt.Component#enableEvents
  849. * @since JDK1.1
  850. */
  851. protected void processActionEvent(ActionEvent e) {
  852. if (actionListener != null) {
  853. actionListener.actionPerformed(e);
  854. }
  855. }
  856. /**
  857. * Returns the parameter string representing the state of this
  858. * scrolling list. This string is useful for debugging.
  859. * @return the parameter string of this scrolling list.
  860. */
  861. protected String paramString() {
  862. return super.paramString() + ",selected=" + getSelectedItem();
  863. }
  864. /**
  865. * @deprecated As of JDK version 1.1,
  866. * Not for public use in the future.
  867. * This method is expected to be retained only as a package
  868. * private method.
  869. */
  870. public synchronized void delItems(int start, int end) {
  871. for (int i = end; i >= start; i--) {
  872. items.removeElementAt(i);
  873. }
  874. ListPeer peer = (ListPeer)this.peer;
  875. if (peer != null) {
  876. peer.delItems(start, end);
  877. }
  878. }
  879. /*
  880. * Serialization support. Since the value of the selected
  881. * field isn't neccessarily up to date we sync it up with the
  882. * peer before serializing.
  883. */
  884. /**
  885. * The List Components Serialized Data Version.
  886. *
  887. * @serial
  888. */
  889. private int listSerializedDataVersion = 1;
  890. /**
  891. * Writes default serializable fields to stream. Writes
  892. * a list of serializable ItemListener(s) as optional data.
  893. * The non-serializable ItemListner(s) are detected and
  894. * no attempt is made to serialize them.
  895. *
  896. * @serialData Null terminated sequence of 0 or more pairs.
  897. * The pair consists of a String and Object.
  898. * The String indicates the type of object and
  899. * is one of the following :
  900. * itemListenerK indicating and ItemListener object.
  901. *
  902. * @see AWTEventMulticaster.save(ObjectOutputStream, String, EventListener)
  903. * @see java.awt.Component.itemListenerK
  904. */
  905. private void writeObject(ObjectOutputStream s)
  906. throws IOException
  907. {
  908. synchronized (this) {
  909. ListPeer peer = (ListPeer)this.peer;
  910. if (peer != null) {
  911. selected = peer.getSelectedIndexes();
  912. }
  913. }
  914. s.defaultWriteObject();
  915. AWTEventMulticaster.save(s, itemListenerK, itemListener);
  916. AWTEventMulticaster.save(s, actionListenerK, actionListener);
  917. s.writeObject(null);
  918. }
  919. /**
  920. * Read the ObjectInputStream and if it isnt null
  921. * add a listener to receive item events fired
  922. * by the List.
  923. * Unrecognised keys or values will be Ignored.
  924. * @see removeActionListener()
  925. * @see addActionListener()
  926. */
  927. private void readObject(ObjectInputStream s)
  928. throws ClassNotFoundException, IOException
  929. {
  930. s.defaultReadObject();
  931. Object keyOrNull;
  932. while(null != (keyOrNull = s.readObject())) {
  933. String key = ((String)keyOrNull).intern();
  934. if (itemListenerK == key)
  935. addItemListener((ItemListener)(s.readObject()));
  936. else if (actionListenerK == key)
  937. addActionListener((ActionListener)(s.readObject()));
  938. else // skip value for unrecognized key
  939. s.readObject();
  940. }
  941. }
  942. }