Merge from mainline.
[official-gcc.git] / libjava / classpath / javax / swing / plaf / basic / BasicComboPopup.java
blobd4eabc602644019fe130c2380a51c9898b10d96a
1 /* BasicComboPopup.java --
2 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing.plaf.basic;
41 import gnu.classpath.NotImplementedException;
43 import java.awt.Color;
44 import java.awt.Component;
45 import java.awt.Dimension;
46 import java.awt.Insets;
47 import java.awt.Point;
48 import java.awt.Rectangle;
49 import java.awt.event.ItemEvent;
50 import java.awt.event.ItemListener;
51 import java.awt.event.KeyAdapter;
52 import java.awt.event.KeyEvent;
53 import java.awt.event.KeyListener;
54 import java.awt.event.MouseAdapter;
55 import java.awt.event.MouseEvent;
56 import java.awt.event.MouseListener;
57 import java.awt.event.MouseMotionAdapter;
58 import java.awt.event.MouseMotionListener;
59 import java.beans.PropertyChangeEvent;
60 import java.beans.PropertyChangeListener;
62 import javax.swing.BorderFactory;
63 import javax.swing.ComboBoxModel;
64 import javax.swing.JComboBox;
65 import javax.swing.JList;
66 import javax.swing.JPopupMenu;
67 import javax.swing.JScrollBar;
68 import javax.swing.JScrollPane;
69 import javax.swing.ListCellRenderer;
70 import javax.swing.ListSelectionModel;
71 import javax.swing.MenuSelectionManager;
72 import javax.swing.SwingConstants;
73 import javax.swing.SwingUtilities;
74 import javax.swing.Timer;
75 import javax.swing.UIManager;
76 import javax.swing.event.ListDataEvent;
77 import javax.swing.event.ListDataListener;
78 import javax.swing.event.ListSelectionEvent;
79 import javax.swing.event.ListSelectionListener;
80 import javax.swing.event.PopupMenuEvent;
81 import javax.swing.event.PopupMenuListener;
83 /**
84 * UI Delegate for ComboPopup
86 * @author Olga Rodimina
88 public class BasicComboPopup extends JPopupMenu implements ComboPopup
90 /* Timer for autoscrolling */
91 protected Timer autoscrollTimer;
93 /** ComboBox associated with this popup */
94 protected JComboBox comboBox;
96 /** FIXME: Need to document */
97 protected boolean hasEntered;
99 /**
100 * Indicates whether the scroll bar located in popup menu with comboBox's
101 * list of items is currently autoscrolling. This happens when mouse event
102 * originated in the combo box and is dragged outside of its bounds
104 protected boolean isAutoScrolling;
106 /** ItemListener listening to the selection changes in the combo box */
107 protected ItemListener itemListener;
109 /** This listener is not used */
110 protected KeyListener keyListener;
112 /** JList which is used to display item is the combo box */
113 protected JList list;
115 /** This listener is not used */
116 protected ListDataListener listDataListener;
119 * MouseListener listening to mouse events occuring in the combo box's
120 * list.
122 protected MouseListener listMouseListener;
125 * MouseMotionListener listening to mouse motion events occuring in the
126 * combo box's list
128 protected MouseMotionListener listMouseMotionListener;
130 /** This listener is not used */
131 protected ListSelectionListener listSelectionListener;
133 /** MouseListener listening to mouse events occuring in the combo box */
134 protected MouseListener mouseListener;
137 * MouseMotionListener listening to mouse motion events occuring in the
138 * combo box
140 protected MouseMotionListener mouseMotionListener;
143 * PropertyChangeListener listening to changes occuring in the bound
144 * properties of the combo box
146 protected PropertyChangeListener propertyChangeListener;
148 /** direction for scrolling down list of combo box's items */
149 protected static final int SCROLL_DOWN = 1;
151 /** direction for scrolling up list of combo box's items */
152 protected static final int SCROLL_UP = 0;
154 /** Indicates auto scrolling direction */
155 protected int scrollDirection;
157 /** JScrollPane that contains list portion of the combo box */
158 protected JScrollPane scroller;
160 /** This field is not used */
161 protected boolean valueIsAdjusting;
164 * Creates a new BasicComboPopup object.
166 * @param comboBox the combo box with which this popup should be associated
168 public BasicComboPopup(JComboBox comboBox)
170 this.comboBox = comboBox;
171 mouseListener = createMouseListener();
172 mouseMotionListener = createMouseMotionListener();
173 keyListener = createKeyListener();
175 list = createList();
176 configureList();
177 scroller = createScroller();
178 configureScroller();
179 configurePopup();
180 installComboBoxListeners();
181 installKeyboardActions();
185 * This method displays drow down list of combo box items on the screen.
187 public void show()
189 Dimension size = comboBox.getSize();
190 size.height = getPopupHeightForRowCount(comboBox.getMaximumRowCount());
191 Insets i = getInsets();
192 size.width -= i.left + i.right;
193 Rectangle bounds = computePopupBounds(0, comboBox.getBounds().height,
194 size.width, size.height);
196 scroller.setMaximumSize(bounds.getSize());
197 scroller.setPreferredSize(bounds.getSize());
198 scroller.setMinimumSize(bounds.getSize());
199 list.invalidate();
201 syncListSelection();
203 list.ensureIndexIsVisible(list.getSelectedIndex());
204 setLightWeightPopupEnabled(comboBox.isLightWeightPopupEnabled());
205 show(comboBox, bounds.x, bounds.y);
209 * This method hides drop down list of items
211 public void hide()
213 MenuSelectionManager menuSelectionManager =
214 MenuSelectionManager.defaultManager();
215 javax.swing.MenuElement[] menuElements =
216 menuSelectionManager.getSelectedPath();
217 for (int i = 0; i < menuElements.length; i++)
219 if (menuElements[i] == this)
221 menuSelectionManager.clearSelectedPath();
222 break;
225 comboBox.repaint();
229 * Return list cointaining JComboBox's items
231 * @return list cointaining JComboBox's items
233 public JList getList()
235 return list;
239 * Returns MouseListener that is listening to mouse events occuring in the
240 * combo box.
242 * @return MouseListener
244 public MouseListener getMouseListener()
246 return mouseListener;
250 * Returns MouseMotionListener that is listening to mouse motion events
251 * occuring in the combo box.
253 * @return MouseMotionListener
255 public MouseMotionListener getMouseMotionListener()
257 return mouseMotionListener;
261 * Returns KeyListener listening to key events occuring in the combo box.
262 * This method returns null because KeyHandler is not longer used.
264 * @return KeyListener
266 public KeyListener getKeyListener()
268 return keyListener;
272 * This method uninstalls the UI for the given JComponent.
274 public void uninstallingUI()
276 uninstallComboBoxModelListeners(comboBox.getModel());
277 uninstallListeners();
278 uninstallKeyboardActions();
282 * This method uninstalls listeners that were listening to changes occuring
283 * in the comb box's data model
285 * @param model data model for the combo box from which to uninstall
286 * listeners
288 protected void uninstallComboBoxModelListeners(ComboBoxModel model)
290 model.removeListDataListener(listDataListener);
294 * This method uninstalls keyboard actions installed by the UI.
296 protected void uninstallKeyboardActions()
297 throws NotImplementedException
299 // FIXME: Need to implement
303 * This method fires PopupMenuEvent indicating that combo box's popup list
304 * of items will become visible
306 protected void firePopupMenuWillBecomeVisible()
308 PopupMenuListener[] ll = comboBox.getPopupMenuListeners();
310 for (int i = 0; i < ll.length; i++)
311 ll[i].popupMenuWillBecomeVisible(new PopupMenuEvent(comboBox));
315 * This method fires PopupMenuEvent indicating that combo box's popup list
316 * of items will become invisible.
318 protected void firePopupMenuWillBecomeInvisible()
320 PopupMenuListener[] ll = comboBox.getPopupMenuListeners();
322 for (int i = 0; i < ll.length; i++)
323 ll[i].popupMenuWillBecomeInvisible(new PopupMenuEvent(comboBox));
327 * This method fires PopupMenuEvent indicating that combo box's popup list
328 * of items was closed without selection.
330 protected void firePopupMenuCanceled()
332 PopupMenuListener[] ll = comboBox.getPopupMenuListeners();
334 for (int i = 0; i < ll.length; i++)
335 ll[i].popupMenuCanceled(new PopupMenuEvent(comboBox));
339 * Creates MouseListener to listen to mouse events occuring in the combo
340 * box. Note that this listener doesn't listen to mouse events occuring in
341 * the popup portion of the combo box, it only listens to main combo box
342 * part.
344 * @return new MouseMotionListener that listens to mouse events occuring in
345 * the combo box
347 protected MouseListener createMouseListener()
349 return new InvocationMouseHandler();
353 * Create Mouse listener that listens to mouse dragging events occuring in
354 * the combo box. This listener is responsible for changing the selection
355 * in the combo box list to the component over which mouse is being
356 * currently dragged
358 * @return new MouseMotionListener that listens to mouse dragging events
359 * occuring in the combo box
361 protected MouseMotionListener createMouseMotionListener()
363 return new InvocationMouseMotionHandler();
367 * KeyListener created in this method is not used anymore.
369 * @return KeyListener that does nothing
371 protected KeyListener createKeyListener()
373 return new InvocationKeyHandler();
377 * ListSelectionListener created in this method is not used anymore
379 * @return ListSelectionListener that does nothing
381 protected ListSelectionListener createListSelectionListener()
383 return new ListSelectionHandler();
387 * Creates ListDataListener. This method returns null, because
388 * ListDataHandler class is obsolete and is no longer used.
390 * @return null
392 protected ListDataListener createListDataListener()
394 return null;
398 * This method creates ListMouseListener to listen to mouse events occuring
399 * in the combo box's item list.
401 * @return MouseListener to listen to mouse events occuring in the combo
402 * box's items list.
404 protected MouseListener createListMouseListener()
406 return new ListMouseHandler();
410 * Creates ListMouseMotionlistener to listen to mouse motion events occuring
411 * in the combo box's list. This listener is responsible for highlighting
412 * items in the list when mouse is moved over them.
414 * @return MouseMotionListener that handles mouse motion events occuring in
415 * the list of the combo box.
417 protected MouseMotionListener createListMouseMotionListener()
419 return new ListMouseMotionHandler();
423 * Creates PropertyChangeListener to handle changes in the JComboBox's bound
424 * properties.
426 * @return PropertyChangeListener to handle changes in the JComboBox's bound
427 * properties.
429 protected PropertyChangeListener createPropertyChangeListener()
431 return new PropertyChangeHandler();
435 * Creates new ItemListener that will listen to ItemEvents occuring in the
436 * combo box.
438 * @return ItemListener to listen to ItemEvents occuring in the combo box.
440 protected ItemListener createItemListener()
442 return new ItemHandler();
446 * Creates JList that will be used to display items in the combo box.
448 * @return JList that will be used to display items in the combo box.
450 protected JList createList()
452 JList l = new JList(comboBox.getModel());
453 return l;
457 * This method configures the list of comboBox's items by setting default
458 * properties and installing listeners.
460 protected void configureList()
462 list.setFont(comboBox.getFont());
463 list.setForeground(comboBox.getForeground());
464 list.setBackground(comboBox.getBackground());
465 Color sfg = UIManager.getColor("ComboBox.selectionForeground");
466 list.setSelectionForeground(sfg);
467 Color sbg = UIManager.getColor("ComboBox.selectionBackground");
468 list.setSelectionBackground(sbg);
469 list.setBorder(null);
470 list.setCellRenderer(comboBox.getRenderer());
471 list.setFocusable(false);
472 syncListSelection();
473 list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
474 installListListeners();
478 * This method installs list listeners.
480 protected void installListListeners()
482 // mouse listener listening to mouse events occuring in the
483 // combo box's list of items.
484 listMouseListener = createListMouseListener();
485 list.addMouseListener(listMouseListener);
487 // mouse listener listening to mouse motion events occuring in the
488 // combo box's list of items
489 listMouseMotionListener = createListMouseMotionListener();
490 list.addMouseMotionListener(listMouseMotionListener);
492 listSelectionListener = createListSelectionListener();
493 list.addListSelectionListener(listSelectionListener);
497 * This method creates scroll pane that will contain the list of comboBox's
498 * items inside of it.
500 * @return JScrollPane
502 protected JScrollPane createScroller()
504 return new JScrollPane(list, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
505 JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
509 * This method configures scroll pane to contain list of comboBox's items
511 protected void configureScroller()
513 scroller.setBorder(null);
514 scroller.setFocusable(false);
515 scroller.getVerticalScrollBar().setFocusable(false);
519 * This method configures popup menu that will be used to display Scrollpane
520 * with list of items inside of it.
522 protected void configurePopup()
524 setBorderPainted(true);
525 setBorder(BorderFactory.createLineBorder(Color.BLACK));
526 setOpaque(false);
527 add(scroller);
528 setFocusable(false);
532 * This method installs listeners that will listen to changes occuring
533 * in the combo box.
535 protected void installComboBoxListeners()
537 // item listener listenening to selection events in the combo box
538 itemListener = createItemListener();
539 comboBox.addItemListener(itemListener);
541 propertyChangeListener = createPropertyChangeListener();
542 comboBox.addPropertyChangeListener(propertyChangeListener);
544 installComboBoxModelListeners(comboBox.getModel());
548 * This method installs listeners that will listen to changes occuring in
549 * the comb box's data model
551 * @param model data model for the combo box for which to install listeners
553 protected void installComboBoxModelListeners(ComboBoxModel model)
555 // list data listener to listen for ListDataEvents in combo box.
556 // This listener is now obsolete and nothing is done here
557 listDataListener = createListDataListener();
558 comboBox.getModel().addListDataListener(listDataListener);
562 * DOCUMENT ME!
564 protected void installKeyboardActions()
565 throws NotImplementedException
567 // FIXME: Need to implement
571 * This method always returns false to indicate that items in the combo box
572 * list are not focus traversable.
574 * @return false
576 public boolean isFocusTraversable()
578 return false;
582 * This method start scrolling combo box's list of items either up or down
583 * depending on the specified 'direction'
585 * @param direction of the scrolling.
587 protected void startAutoScrolling(int direction)
589 // FIXME: add timer
590 isAutoScrolling = true;
592 if (direction == SCROLL_UP)
593 autoScrollUp();
594 else
595 autoScrollDown();
599 * This method stops scrolling the combo box's list of items
601 protected void stopAutoScrolling()
603 // FIXME: add timer
604 isAutoScrolling = false;
608 * This method scrolls up list of combo box's items up and highlights that
609 * just became visible.
611 protected void autoScrollUp()
613 // scroll up the scroll bar to make the item above visible
614 JScrollBar scrollbar = scroller.getVerticalScrollBar();
615 int scrollToNext = list.getScrollableUnitIncrement(super.getBounds(),
616 SwingConstants.VERTICAL,
617 SCROLL_UP);
619 scrollbar.setValue(scrollbar.getValue() - scrollToNext);
621 // If we haven't reached the begging of the combo box's list of items,
622 // then highlight next element above currently highlighted element
623 if (list.getSelectedIndex() != 0)
624 list.setSelectedIndex(list.getSelectedIndex() - 1);
628 * This method scrolls down list of combo box's and highlights item in the
629 * list that just became visible.
631 protected void autoScrollDown()
633 // scroll scrollbar down to make next item visible
634 JScrollBar scrollbar = scroller.getVerticalScrollBar();
635 int scrollToNext = list.getScrollableUnitIncrement(super.getBounds(),
636 SwingConstants.VERTICAL,
637 SCROLL_DOWN);
638 scrollbar.setValue(scrollbar.getValue() + scrollToNext);
640 // If we haven't reached the end of the combo box's list of items
641 // then highlight next element below currently highlighted element
642 if (list.getSelectedIndex() + 1 != comboBox.getItemCount())
643 list.setSelectedIndex(list.getSelectedIndex() + 1);
647 * This method helps to delegate focus to the right component in the
648 * JComboBox. If the comboBox is editable then focus is sent to
649 * ComboBoxEditor, otherwise it is delegated to JComboBox.
651 * @param e MouseEvent
653 protected void delegateFocus(MouseEvent e)
655 if (comboBox.isEditable())
656 comboBox.getEditor().getEditorComponent().requestFocus();
657 else
658 comboBox.requestFocus();
662 * This method displays combo box popup if the popup is not currently shown
663 * on the screen and hides it if it is currently visible
665 protected void togglePopup()
667 if (isVisible())
668 hide();
669 else
670 show();
674 * DOCUMENT ME!
676 * @param e DOCUMENT ME!
678 * @return DOCUMENT ME!
680 protected MouseEvent convertMouseEvent(MouseEvent e)
682 Point point = SwingUtilities.convertPoint((Component) e.getSource(),
683 e.getPoint(), list);
684 MouseEvent newEvent= new MouseEvent((Component) e.getSource(),
685 e.getID(), e.getWhen(),
686 e.getModifiers(), point.x, point.y,
687 e.getModifiers(),
688 e.isPopupTrigger());
689 return newEvent;
693 * Returns required height of the popup such that number of items visible in
694 * it are equal to the maximum row count. By default
695 * comboBox.maximumRowCount=8
697 * @param maxRowCount number of maximum visible rows in the combo box's
698 * popup list of items
700 * @return height of the popup required to fit number of items equal to
701 * JComboBox.maximumRowCount.
703 protected int getPopupHeightForRowCount(int maxRowCount)
705 int totalHeight = 0;
706 ListCellRenderer rend = list.getCellRenderer();
708 if (comboBox.getItemCount() < maxRowCount)
709 maxRowCount = comboBox.getItemCount();
711 for (int i = 0; i < maxRowCount; i++)
713 Component comp = rend.getListCellRendererComponent(list,
714 comboBox.getModel()
715 .getElementAt(i),
716 -1, false, false);
717 Dimension dim = comp.getPreferredSize();
718 totalHeight += dim.height;
721 return totalHeight == 0 ? 100 : totalHeight;
725 * DOCUMENT ME!
727 * @param px DOCUMENT ME!
728 * @param py DOCUMENT ME!
729 * @param pw DOCUMENT ME!
730 * @param ph DOCUMENT ME!
732 * @return DOCUMENT ME!
734 protected Rectangle computePopupBounds(int px, int py, int pw, int ph)
736 return new Rectangle(px, py, pw, ph);
740 * This method changes the selection in the list to the item over which the
741 * mouse is currently located.
743 * @param anEvent MouseEvent
744 * @param shouldScroll DOCUMENT ME!
746 protected void updateListBoxSelectionForEvent(MouseEvent anEvent,
747 boolean shouldScroll)
749 Point point = anEvent.getPoint();
750 if (list != null)
752 int index = list.locationToIndex(point);
753 if (index == -1)
755 if (point.y < 0)
756 index = 0;
757 else
758 index = comboBox.getModel().getSize() - 1;
760 if (list.getSelectedIndex() != index)
762 list.setSelectedIndex(index);
763 if (shouldScroll)
764 list.ensureIndexIsVisible(index);
770 * InvocationMouseHandler is a listener that listens to mouse events
771 * occuring in the combo box. Note that this listener doesn't listen to
772 * mouse events occuring in the popup portion of the combo box, it only
773 * listens to main combo box part(area that displays selected item). This
774 * listener is responsible for showing and hiding popup portion of the
775 * combo box.
777 protected class InvocationMouseHandler extends MouseAdapter
780 * Creates a new InvocationMouseHandler object.
782 protected InvocationMouseHandler()
784 // Nothing to do here.
788 * This method is invoked whenever mouse is being pressed over the main
789 * part of the combo box. This method will show popup if the popup is
790 * not shown on the screen right now, and it will hide popup otherwise.
792 * @param e MouseEvent that should be handled
794 public void mousePressed(MouseEvent e)
796 if (SwingUtilities.isLeftMouseButton(e) && comboBox.isEnabled())
798 delegateFocus(e);
799 togglePopup();
804 * This method is invoked whenever mouse event was originated in the combo
805 * box and released either in the combBox list of items or in the combo
806 * box itself.
808 * @param e MouseEvent that should be handled
810 public void mouseReleased(MouseEvent e)
812 Component component = (Component) e.getSource();
813 Dimension size = component.getSize();
814 Rectangle bounds = new Rectangle(0, 0, size.width - 1, size.height - 1);
815 // If mouse was released inside the bounds of combo box then do nothing,
816 // Otherwise if mouse was released inside the list of combo box items
817 // then change selection and close popup
818 if (! bounds.contains(e.getPoint()))
820 MouseEvent convEvent = convertMouseEvent(e);
821 Point point = convEvent.getPoint();
822 Rectangle visRect = new Rectangle();
823 list.computeVisibleRect(visRect);
824 if (visRect.contains(point))
826 updateListBoxSelectionForEvent(convEvent, false);
827 comboBox.setSelectedIndex(list.getSelectedIndex());
829 hide();
831 hasEntered = false;
832 stopAutoScrolling();
837 * InvocationMouseMotionListener is a mouse listener that listens to mouse
838 * dragging events occuring in the combo box.
840 protected class InvocationMouseMotionHandler extends MouseMotionAdapter
843 * Creates a new InvocationMouseMotionHandler object.
845 protected InvocationMouseMotionHandler()
847 // Nothing to do here.
851 * This method is responsible for highlighting item in the drop down list
852 * over which the mouse is currently being dragged.
854 public void mouseDragged(MouseEvent e)
856 if (isVisible())
858 MouseEvent convEvent = convertMouseEvent(e);
859 Rectangle visRect = new Rectangle();
860 list.computeVisibleRect(visRect);
861 if (convEvent.getPoint().y >= visRect.y
862 && (convEvent.getPoint().y <= visRect.y + visRect.height - 1))
864 hasEntered = true;
865 if (isAutoScrolling)
866 stopAutoScrolling();
867 Point point = convEvent.getPoint();
868 if (visRect.contains(point))
870 valueIsAdjusting = true;
871 updateListBoxSelectionForEvent(convEvent, false);
872 valueIsAdjusting = false;
875 else if (hasEntered)
877 int dir = convEvent.getPoint().y < visRect.y ? SCROLL_UP
878 : SCROLL_DOWN;
879 if (isAutoScrolling && scrollDirection != dir)
881 stopAutoScrolling();
882 startAutoScrolling(dir);
884 else if (!isAutoScrolling)
885 startAutoScrolling(dir);
887 else if (e.getPoint().y < 0)
889 hasEntered = true;
890 startAutoScrolling(SCROLL_UP);
897 * ItemHandler is an item listener that listens to selection events occuring
898 * in the combo box. FIXME: should specify here what it does when item is
899 * selected or deselected in the combo box list.
901 protected class ItemHandler extends Object implements ItemListener
904 * Creates a new ItemHandler object.
906 protected ItemHandler()
908 // Nothing to do here.
912 * This method responds to the selection events occuring in the combo box.
914 * @param e ItemEvent specifying the combo box's selection
916 public void itemStateChanged(ItemEvent e)
918 if (e.getStateChange() == ItemEvent.SELECTED && ! valueIsAdjusting)
920 valueIsAdjusting = true;
921 syncListSelection();
922 valueIsAdjusting = false;
923 list.ensureIndexIsVisible(comboBox.getSelectedIndex());
929 * ListMouseHandler is a listener that listens to mouse events occuring in
930 * the combo box's list of items. This class is responsible for hiding
931 * popup portion of the combo box if the mouse is released inside the combo
932 * box's list.
934 protected class ListMouseHandler extends MouseAdapter
936 protected ListMouseHandler()
938 // Nothing to do here.
941 public void mousePressed(MouseEvent e)
943 // Nothing to do here.
946 public void mouseReleased(MouseEvent anEvent)
948 comboBox.setSelectedIndex(list.getSelectedIndex());
949 hide();
954 * ListMouseMotionHandler listens to mouse motion events occuring in the
955 * combo box's list. This class is responsible for highlighting items in
956 * the list when mouse is moved over them
958 protected class ListMouseMotionHandler extends MouseMotionAdapter
960 protected ListMouseMotionHandler()
962 // Nothing to do here.
965 public void mouseMoved(MouseEvent anEvent)
967 Point point = anEvent.getPoint();
968 Rectangle visRect = new Rectangle();
969 list.computeVisibleRect(visRect);
970 if (visRect.contains(point))
972 valueIsAdjusting = true;
973 updateListBoxSelectionForEvent(anEvent, false);
974 valueIsAdjusting = false;
980 * This class listens to changes occuring in the bound properties of the
981 * combo box
983 protected class PropertyChangeHandler extends Object
984 implements PropertyChangeListener
986 protected PropertyChangeHandler()
988 // Nothing to do here.
991 public void propertyChange(PropertyChangeEvent e)
993 if (e.getPropertyName().equals("renderer"))
995 list.setCellRenderer(comboBox.getRenderer());
996 if (isVisible())
997 hide();
999 if (e.getPropertyName().equals("model"))
1001 ComboBoxModel oldModel = (ComboBoxModel) e.getOldValue();
1002 uninstallComboBoxModelListeners(oldModel);
1003 ComboBoxModel newModel = (ComboBoxModel) e.getNewValue();
1004 list.setModel(newModel);
1005 installComboBoxModelListeners(newModel);
1006 if (comboBox.getItemCount() > 0)
1007 comboBox.setSelectedIndex(0);
1008 if (isVisible())
1009 hide();
1014 // ------ private helper methods --------------------
1017 * This method uninstalls listeners installed by the UI
1019 private void uninstallListeners()
1021 uninstallComboBoxListeners();
1022 uninstallComboBoxModelListeners(comboBox.getModel());
1026 * This method uninstalls Listeners registered with combo boxes list of
1027 * items
1029 private void uninstallListListeners()
1031 list.removeMouseListener(listMouseListener);
1032 listMouseListener = null;
1034 list.removeMouseMotionListener(listMouseMotionListener);
1035 listMouseMotionListener = null;
1039 * This method uninstalls listeners listening to combo box associated with
1040 * this popup menu
1042 private void uninstallComboBoxListeners()
1044 comboBox.removeItemListener(itemListener);
1045 itemListener = null;
1047 comboBox.removePropertyChangeListener(propertyChangeListener);
1048 propertyChangeListener = null;
1051 void syncListSelection()
1053 int index = comboBox.getSelectedIndex();
1054 if (index == -1)
1055 list.clearSelection();
1056 else
1057 list.setSelectedIndex(index);
1060 // --------------------------------------------------------------------
1061 // The following classes are here only for backwards API compatibility
1062 // They aren't used.
1063 // --------------------------------------------------------------------
1066 * This class is not used any more.
1068 public class ListDataHandler extends Object implements ListDataListener
1070 public ListDataHandler()
1072 // Nothing to do here.
1075 public void contentsChanged(ListDataEvent e)
1077 // Nothing to do here.
1080 public void intervalAdded(ListDataEvent e)
1082 // Nothing to do here.
1085 public void intervalRemoved(ListDataEvent e)
1087 // Nothing to do here.
1092 * This class is not used anymore
1094 protected class ListSelectionHandler extends Object
1095 implements ListSelectionListener
1097 protected ListSelectionHandler()
1099 // Nothing to do here.
1102 public void valueChanged(ListSelectionEvent e)
1104 // Nothing to do here.
1109 * This class is not used anymore
1111 public class InvocationKeyHandler extends KeyAdapter
1113 public InvocationKeyHandler()
1115 // Nothing to do here.
1118 public void keyReleased(KeyEvent e)
1120 // Nothing to do here.