Merge from mainline (gomp-merge-2005-02-26).
[official-gcc.git] / libjava / javax / swing / plaf / basic / BasicComboBoxUI.java
blob9044ed76c8648f1c7aedbd1c78007be13766eb48
1 /* BasicComboBoxUI.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., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 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 java.awt.Color;
42 import java.awt.Component;
43 import java.awt.Container;
44 import java.awt.Dimension;
45 import java.awt.Graphics;
46 import java.awt.Insets;
47 import java.awt.LayoutManager;
48 import java.awt.Rectangle;
49 import java.awt.event.FocusEvent;
50 import java.awt.event.FocusListener;
51 import java.awt.event.ItemEvent;
52 import java.awt.event.ItemListener;
53 import java.awt.event.KeyAdapter;
54 import java.awt.event.KeyEvent;
55 import java.awt.event.KeyListener;
56 import java.awt.event.MouseAdapter;
57 import java.awt.event.MouseEvent;
58 import java.awt.event.MouseListener;
59 import java.awt.event.MouseMotionListener;
60 import java.beans.PropertyChangeEvent;
61 import java.beans.PropertyChangeListener;
63 import javax.accessibility.Accessible;
64 import javax.swing.CellRendererPane;
65 import javax.swing.ComboBoxEditor;
66 import javax.swing.ComboBoxModel;
67 import javax.swing.JButton;
68 import javax.swing.JComboBox;
69 import javax.swing.JComponent;
70 import javax.swing.JList;
71 import javax.swing.ListCellRenderer;
72 import javax.swing.UIDefaults;
73 import javax.swing.UIManager;
74 import javax.swing.event.ListDataEvent;
75 import javax.swing.event.ListDataListener;
76 import javax.swing.plaf.ComboBoxUI;
77 import javax.swing.plaf.ComponentUI;
79 /**
80 * UI Delegate for JComboBox
82 * @author Olga Rodimina
83 * @author Robert Schuster
85 public class BasicComboBoxUI extends ComboBoxUI
87 /**
88 * This arrow button that is displayed in the rigth side of JComboBox. This
89 * button is used to hide and show combo box's list of items
91 protected JButton arrowButton;
93 /**
94 * The combo box for which this UI delegate is for
96 protected JComboBox comboBox;
98 /**
99 * Component that is responsible for displaying/editting selected item of
100 * the combo box. By default JTextField is used as an editor for the
101 * JComboBox
103 protected Component editor;
106 * Listener listening to focus events occuring in the JComboBox
108 protected FocusListener focusListener;
111 * tells whether JComboBox currently has focus
113 protected boolean hasFocus;
116 * Listener listening to item events fired by the JComboBox
118 protected ItemListener itemListener;
121 * KeyListener listening to key events that occur while JComboBox has focus
123 protected KeyListener keyListener;
126 * MouseListener listening to mouse events occuring in the combo box
128 private MouseListener mouseListener;
131 * List used when rendering selected item of the combo box. The selection
132 * and foreground colors for combo box renderer are configured from this
133 * list
135 protected JList listBox;
138 * ListDataListener listening to JComboBox model
140 protected ListDataListener listDataListener;
143 * Popup list containing combo box's menu items
145 protected ComboPopup popup;
146 protected KeyListener popupKeyListener;
147 protected MouseListener popupMouseListener;
148 protected MouseMotionListener popupMouseMotionListener;
151 * Listener listening to changes in the bound properties of JComboBox
153 protected PropertyChangeListener propertyChangeListener;
156 * Colors that are used to render selected item in the combo box.
158 private Color shadow;
159 private Color darkShadow;
160 private Color highlight;
161 private Color lightHighlight;
163 /* Size of the largest item in the comboBox */
164 private Dimension largestItemSize;
166 // It seems that JComboBox doesn't have a border set explicitely. So we just
167 // paint the border everytime combo box is displayed.
169 /* border insets for this JComboBox*/
170 private static final Insets borderInsets = new Insets(2, 2, 2, 2);
172 // Width of the arrow button
173 private static int arrowButtonWidth = 15;
175 // FIXME: This fields aren't used anywhere at this moment.
176 protected Dimension cachedMinimumSize;
177 protected CellRendererPane currentValuePane;
178 protected boolean isMinimumSizeDirty;
181 * Creates a new BasicComboBoxUI object.
183 public BasicComboBoxUI()
188 * Factory method to create a BasicComboBoxUI for the given {@link
189 * JComponent}, which should be a {@link JComboBox}.
191 * @param c The {@link JComponent} a UI is being created for.
193 * @return A BasicComboBoxUI for the {@link JComponent}.
195 public static ComponentUI createUI(JComponent c)
197 return new BasicComboBoxUI();
201 * This method installs the UI for the given JComponent.
203 * @param c The JComponent to install a UI for.
205 public void installUI(JComponent c)
207 super.installUI(c);
209 if (c instanceof JComboBox)
211 comboBox = (JComboBox) c;
212 comboBox.setOpaque(true);
213 comboBox.setLayout(createLayoutManager());
214 installDefaults();
215 installComponents();
216 installListeners();
217 installKeyboardActions();
222 * This method uninstalls the UI.
224 * @param c The JComponent that is having this UI removed.
226 public void uninstallUI(JComponent c)
228 uninstallKeyboardActions();
229 uninstallListeners();
230 uninstallComponents();
231 uninstallDefaults();
232 comboBox = null;
236 * This method installs the defaults that are defined in the Basic look and
237 * feel for this {@link JComboBox}.
239 protected void installDefaults()
241 UIDefaults defaults = UIManager.getLookAndFeelDefaults();
243 comboBox.setBackground(defaults.getColor("ComboBox.background"));
244 comboBox.setFont(defaults.getFont("ComboBox.font"));
245 comboBox.setForeground(defaults.getColor("ComboBox.foreground"));
247 // Set default color that should be used to to render selected item
248 // of the combo box.
249 shadow = defaults.getColor("Button.shadow");
250 darkShadow = defaults.getColor("Button.darkShadow");
251 lightHighlight = defaults.getColor("Button.light");
252 highlight = defaults.getColor("Button.highlight");
256 * This method creates and installs the listeners for this UI.
258 protected void installListeners()
260 // install combo box's listeners
261 propertyChangeListener = createPropertyChangeListener();
262 comboBox.addPropertyChangeListener(propertyChangeListener);
264 focusListener = createFocusListener();
265 comboBox.addFocusListener(focusListener);
267 itemListener = createItemListener();
268 comboBox.addItemListener(itemListener);
270 keyListener = createKeyListener();
271 comboBox.addKeyListener(keyListener);
273 mouseListener = createMouseListener();
274 comboBox.addMouseListener(mouseListener);
276 // install listeners that listen to combo box model
277 listDataListener = createListDataListener();
278 comboBox.getModel().addListDataListener(listDataListener);
280 configureArrowButton();
284 * This method uninstalls the defaults and sets any objects created during
285 * install to null
287 protected void uninstallDefaults()
289 UIDefaults defaults = UIManager.getLookAndFeelDefaults();
291 comboBox.setBackground(null);
292 comboBox.setFont(null);
293 comboBox.setForeground(null);
295 shadow = null;
296 darkShadow = null;
297 lightHighlight = null;
298 highlight = null;
302 * Detaches all the listeners we attached in {@link #installListeners}.
304 protected void uninstallListeners()
306 comboBox.removePropertyChangeListener(propertyChangeListener);
307 propertyChangeListener = null;
309 comboBox.removeFocusListener(focusListener);
310 focusListener = null;
312 comboBox.removeItemListener(itemListener);
313 itemListener = null;
315 comboBox.removeKeyListener(keyListener);
316 keyListener = null;
318 comboBox.removeMouseListener(mouseListener);
319 mouseListener = null;
321 comboBox.getModel().removeListDataListener(listDataListener);
322 listDataListener = null;
324 unconfigureArrowButton();
328 * This method creates popup that will contain list of combo box's items
330 * @return popup containing list of combo box's items
332 protected ComboPopup createPopup()
334 return new BasicComboPopup(comboBox);
338 * Creates KeyListener to listen to key events.
340 * @return KeyListener that listens to key events.
342 protected KeyListener createKeyListener()
344 return new KeyHandler();
348 * This method create MouseListener that will listen to mouse event occuring
349 * in combo box.
351 * @return the MouseListener
353 private MouseListener createMouseListener()
355 return new MouseHandler();
359 * This method create FocusListener that will listen to changes in this
360 * JComboBox's focus.
362 * @return theFocusListener
364 protected FocusListener createFocusListener()
366 return new FocusHandler();
370 * This method create ListDataListener to listen to ComboBox's data model
372 * @return ListDataListener
374 protected ListDataListener createListDataListener()
376 return new ListDataHandler();
380 * This method creates ItemListener that will listen to to the changes in
381 * the JComboBox's selection.
383 * @return the ItemListener
385 protected ItemListener createItemListener()
387 return new ItemHandler();
391 * This method creates PropertyChangeListener to listen to the changes in
392 * the JComboBox's bound properties.
394 * @return the PropertyChangeListener
396 protected PropertyChangeListener createPropertyChangeListener()
398 return new PropertyChangeHandler();
402 * This method returns layout manager for the combo box.
404 * @return layout manager for the combo box
406 protected LayoutManager createLayoutManager()
408 return new ComboBoxLayoutManager();
412 * This method creates component that will be responsible for rendering the
413 * selected component in the combo box.
415 * @return render for the combo box
417 protected ListCellRenderer createRenderer()
419 return new BasicComboBoxRenderer();
423 * Creates component that will be responsible for displaying/editting
424 * selected item in the combo box. This editor is used only when combo box
425 * is editable.
427 * @return component that will be responsible for displaying/editting
428 * selected item in the combo box.
430 protected ComboBoxEditor createEditor()
432 return new BasicComboBoxEditor();
436 * This method installs components for this JComboBox. ArrowButton, main
437 * part of combo box (upper part) and popup list of items are created and
438 * configured here.
440 protected void installComponents()
442 // create and install arrow button
443 arrowButton = createArrowButton();
445 comboBox.add(arrowButton);
447 // Set list that will be used by BasicComboBoxRender
448 // in order to determine the right colors when rendering
449 listBox = new JList();
451 Color background = arrowButton.getBackground();
452 listBox.setBackground(background);
453 listBox.setSelectionBackground(background.darker());
455 Color foreground = arrowButton.getForeground();
456 listBox.setForeground(foreground);
457 listBox.setSelectionForeground(foreground);
459 // set editor and renderer for the combo box. Editor is used
460 // only if combo box becomes editable, otherwise renderer is used
461 // to paint the selected item; combobox is not editable by default.
462 comboBox.setRenderer(createRenderer());
464 comboBox.setEditor(createEditor());
465 editor = comboBox.getEditor().getEditorComponent();
467 // create drop down list of items
468 popup = createPopup();
470 comboBox.revalidate();
474 * This method uninstalls components from this JComboBox
476 protected void uninstallComponents()
478 // uninstall arrow button
479 unconfigureArrowButton();
480 comboBox.remove(arrowButton);
481 arrowButton = null;
483 listBox = null;
484 popup = null;
486 comboBox.setRenderer(null);
488 comboBox.setEditor(null);
489 editor = null;
493 * This method adds editor to the combo box
495 public void addEditor()
497 comboBox.add(editor);
501 * This method removes editor from the combo box
503 public void removeEditor()
505 comboBox.remove(editor);
509 * This method configures editor for this combo box.
511 protected void configureEditor()
513 // FIXME: Need to implement. Set font and add listeners.
517 * This method removes all the listeners for the editor.
519 protected void unconfigureEditor()
521 // FIXME: Need to implement
525 * This method adds listeners to the arrow button part of the combo box.
527 public void configureArrowButton()
529 arrowButton.addMouseListener(mouseListener);
533 * This method removes listeners from the arrow button part of the combo
534 * box.
536 public void unconfigureArrowButton()
538 arrowButton.removeMouseListener(mouseListener);
542 * This method create arrow button for this JComboBox. Arrow button is
543 * responsible for displaying / hiding drop down list of items when it is
544 * clicked.
546 * @return JButton arrow button for this JComboBox.
548 protected JButton createArrowButton()
550 return new BasicArrowButton(BasicArrowButton.SOUTH);
554 * This method checks if popup part of the combo box is visible on the
555 * screen
557 * @param c The JComboBox to check
559 * @return true if popup part of the JComboBox is visible and false
560 * otherwise.
562 public boolean isPopupVisible(JComboBox c)
564 return popup.isVisible();
568 * Displays/Hides JComboBox's list of items on the screen.
570 * @param c The combo box, for which list of items should be
571 * displayed/hidden
572 * @param v true if show popup part of the jcomboBox and false to hide.
574 public void setPopupVisible(JComboBox c, boolean v)
576 if (v)
577 popup.show();
578 else
579 popup.hide();
583 * JComboBox is focus traversable if it is editable and not otherwise.
585 * @param c combo box for which to check whether it is focus traversable
587 * @return true if focus tranversable and false otherwise
589 public boolean isFocusTraversable(JComboBox c)
591 if (comboBox.isEditable())
592 return true;
594 return false;
598 * Paints given menu item using specified graphics context
600 * @param g The graphics context used to paint this combo box
601 * @param c comboBox which needs to be painted.
603 public void paint(Graphics g, JComponent c)
605 if (c instanceof JComboBox)
607 JComboBox cb = (JComboBox) c;
609 paintBorder(g, comboBox.getBounds(), hasFocus);
611 Rectangle rect = rectangleForCurrentValue();
612 paintCurrentValueBackground(g, rect, hasFocus);
613 paintCurrentValue(g, rect, hasFocus);
617 private void paintBorder(Graphics g, Rectangle bounds, boolean hasFocus)
619 int x = 0;
620 int y = 0;
621 int width = bounds.width;
622 int height = bounds.height;
624 Color oldColor = g.getColor();
626 if (! arrowButton.getModel().isPressed())
627 BasicGraphicsUtils.drawEtchedRect(g, x, y, width, height, Color.gray,
628 Color.white, Color.gray, Color.white);
629 else
631 g.setColor(darkShadow);
632 g.drawRect(x, y, width, height);
633 g.setColor(shadow);
634 g.drawRect(x + 1, y + 1, width - 3, height - 3);
636 g.setColor(oldColor);
640 * Returns preferred size for the given menu item.
642 * @param c comboBox for which to get preferred size
644 * @return $Dimension$ preferred size for the given combo box
646 public Dimension getPreferredSize(JComponent c)
648 // return null to indicate that combo box's layout will determin its
649 // preferred size
650 return null;
654 * This method returns the minimum size for this {@link JComboBox} for this
655 * look and feel.
657 * @param c The {@link JComponent} to find the minimum size for.
659 * @return The dimensions of the minimum size.
661 public Dimension getMinimumSize(JComponent c)
663 return null;
667 * This method returns the maximum size for this {@link JComboBox} for this
668 * look and feel.
670 * @param c The {@link JComponent} to find the maximum size for
672 * @return The dimensions of the minimum size.
674 public Dimension getMaximumSize(JComponent c)
676 return null;
679 public int getAccessibleChildrenCount(JComponent c)
681 // FIXME: Need to implement
682 return 0;
685 public Accessible getAccessibleChild(JComponent c, int i)
687 // FIXME: Need to implement
688 return null;
692 * Returns true if the specified key is a navigation key and false otherwise
694 * @param keyCode a key for which to check whether it is navigation key or
695 * not.
697 * @return true if the specified key is a navigation key and false otherwis
699 protected boolean isNavigationKey(int keyCode)
701 return false;
705 * This method selects next possible item relative to the current selection
706 * to be next selected item in the combo box.
708 protected void selectNextPossibleValue()
710 int index = comboBox.getSelectedIndex();
711 if (index != comboBox.getItemCount() - 1)
712 comboBox.setSelectedIndex(index + 1);
716 * This method selects previous item relative to current selection to be
717 * next selected item.
719 protected void selectPreviousPossibleValue()
721 int index = comboBox.getSelectedIndex();
722 if (index != 0)
723 comboBox.setSelectedIndex(index - 1);
727 * This method displays combo box popup if the popup is not currently shown
728 * on the screen and hides it if it is currently shown
730 protected void toggleOpenClose()
732 setPopupVisible(comboBox, ! isPopupVisible(comboBox));
736 * This method returns bounds in which comboBox's selected Item will be
737 * displayed
739 * @return rectangle bounds in which comboBox's selected Item will be
740 * displayed
742 protected Rectangle rectangleForCurrentValue()
744 Rectangle cbBounds = comboBox.getBounds();
746 // Subtract width or the arrow button and border insets
747 Rectangle rectForCurrentValue = new Rectangle(cbBounds.x
748 + borderInsets.left,
749 cbBounds.y
750 + borderInsets.top,
751 cbBounds.width
752 - arrowButtonWidth
753 - borderInsets.left
754 - borderInsets.right,
755 cbBounds.height
756 - borderInsets.top
757 - borderInsets.bottom);
759 return rectForCurrentValue;
763 * This method returns insets of the current border.
765 * @return Insets representing space between combo box and its border
767 protected Insets getInsets()
769 return new Insets(0, 0, 0, 0);
773 * This method paints currently selected value in the main part of the combo
774 * box (part without popup).
776 * @param g graphics context
777 * @param bounds Rectangle representing the size of the area in which
778 * selected item should be drawn
779 * @param hasFocus true if combo box has focus and false otherwise
781 public void paintCurrentValue(Graphics g, Rectangle bounds, boolean hasFocus)
783 if (! comboBox.isEditable())
785 Object currentValue = comboBox.getSelectedItem();
786 boolean isPressed = arrowButton.getModel().isPressed();
788 /* Gets the component to be drawn for the current value.
789 * If there is currently no selected item we will take an empty
790 * String as replacement.
792 Component comp = comboBox.getRenderer()
793 .getListCellRendererComponent(listBox,
794 (currentValue != null ? currentValue : ""),
796 isPressed,
797 hasFocus);
798 if (! comboBox.isEnabled())
799 comp.setEnabled(false);
801 g.translate(borderInsets.left, borderInsets.top);
802 comp.setBounds(0, 0, bounds.width, bounds.height);
803 comp.paint(g);
804 g.translate(-borderInsets.left, -borderInsets.top);
806 comboBox.revalidate();
808 else
809 comboBox.getEditor().setItem(comboBox.getSelectedItem());
813 * This method paints background of part of the combo box, where currently
814 * selected value is displayed. If the combo box has focus this method
815 * should also paint focus rectangle around the combo box.
817 * @param g graphics context
818 * @param bounds Rectangle representing the size of the largest item in the
819 * comboBox
820 * @param hasFocus true if combo box has fox and false otherwise
822 public void paintCurrentValueBackground(Graphics g, Rectangle bounds,
823 boolean hasFocus)
825 // background is painted by renderer, so it seems that nothing
826 // should be done here.
830 * Returns default size for the combo box that doesn't contain any elements
831 * in it
833 * @return Default size of the combo box with no elements in it.
835 protected Dimension getDefaultSize()
837 return new Dimension(6, 17);
841 * Returns size of the largest item in the combo box. This size will be the
842 * size of the combo box, not including the arrowButton.
844 * @return dimensions of the largest item in the combo box.
846 protected Dimension getLargestItemSize()
848 ComboBoxModel model = comboBox.getModel();
849 int numItems = model.getSize();
851 // if combo box doesn't have any items then simply
852 // return its default size
853 if (numItems == 0)
855 largestItemSize = getDefaultSize();
856 return largestItemSize;
859 Dimension size = new Dimension(0, 0);
861 // ComboBox's display size should be equal to the
862 // size of the largest item in the combo box.
863 ListCellRenderer renderer = comboBox.getRenderer();
865 for (int i = 0; i < numItems; i++)
867 Object item = model.getElementAt(i);
868 String s = item.toString();
869 Component comp = renderer.getListCellRendererComponent(listBox, item,
870 -1, false, false);
872 if (comp.getPreferredSize().getWidth() > size.getWidth())
873 size = comp.getPreferredSize();
876 largestItemSize = size;
877 return largestItemSize;
881 * This method installs the keyboard actions for the JComboBox as specified
882 * by the look and feel.
884 protected void installKeyboardActions()
886 // FIXME: Need to implement.
890 * This method uninstalls the keyboard actions for the JComboBox there were
891 * installed by in {@link #installListeners}.
893 protected void uninstallKeyboardActions()
895 // FIXME: Need to implement.
899 * This class is Layout Manager for this combo box.
901 public class ComboBoxLayoutManager extends Object implements LayoutManager
904 * Creates a new ComboBoxLayoutManager object.
906 public ComboBoxLayoutManager()
910 public void addLayoutComponent(String name, Component comp)
912 // Do nothing
915 public void removeLayoutComponent(Component comp)
917 // Do nothing
921 * Returns preferred layout size of the JComboBox.
923 * @param parent Container for which preferred size should be calculated
925 * @return preferred size for the given container
927 public Dimension preferredLayoutSize(Container parent)
929 Dimension d = new Dimension(0, 0);
931 if (largestItemSize == null)
932 largestItemSize = getLargestItemSize();
934 // add size for the area that will display selected item
935 d.width += largestItemSize.getWidth();
936 d.height += largestItemSize.getHeight();
938 // add size of the arrow button
939 d.width += arrowButtonWidth;
941 // add width and height of the border
942 d.width += borderInsets.left + borderInsets.right;
943 d.height += borderInsets.left + borderInsets.right;
945 // Add combo box's insets
946 Insets insets = parent.getInsets();
947 d.width += insets.left + insets.right;
948 d.width += insets.left + insets.right;
950 return d;
953 public Dimension minimumLayoutSize(Container parent)
955 return preferredLayoutSize(parent);
959 * This method layouts out the components in the container. It puts arrow
960 * button right end part of the comboBox. If the comboBox is editable
961 * then editor is placed to the left of arrow button, starting from the
962 * beginning.
964 * @param parent Container that should be layed out.
966 public void layoutContainer(Container parent)
968 // Position editor component to the left of arrow button if combo box is
969 // editable
970 int editorWidth = comboBox.getBounds().width - arrowButtonWidth - 2;
972 if (comboBox.isEditable())
973 editor.setBounds(borderInsets.left, borderInsets.top, editorWidth,
974 comboBox.getBounds().height - borderInsets.left
975 - borderInsets.top);
977 arrowButton.setBounds(editorWidth, 2, arrowButtonWidth,
978 comboBox.getBounds().height - 4);
979 comboBox.revalidate();
984 * This class handles focus changes occuring in the combo box. This class is
985 * responsible for repainting combo box whenever focus is gained or lost
986 * and also for hiding popup list of items whenever combo box loses its
987 * focus.
989 public class FocusHandler extends Object implements FocusListener
992 * Creates a new FocusHandler object.
994 public FocusHandler()
999 * This mehtod is invoked when combo box gains focus. It repaints main
1000 * part of combo box accordingally.
1002 * @param e the FocusEvent
1004 public void focusGained(FocusEvent e)
1006 hasFocus = true;
1007 comboBox.repaint();
1011 * This method is invoked when combo box loses focus It repaint main part
1012 * of combo box accordingally and hides popup list of items.
1014 * @param e the FocusEvent
1016 public void focusLost(FocusEvent e)
1018 hasFocus = false;
1019 comboBox.repaint();
1020 popup.hide();
1025 * This class handles ItemEvent fired by the JComboBox when its selected
1026 * item changes.
1028 public class ItemHandler extends Object implements ItemListener
1031 * Creates a new ItemHandler object.
1033 public ItemHandler()
1038 * This method is invoked when selected item becomes deselected or when
1039 * new item becomes selected.
1041 * @param e the ItemEvent representing item's state change.
1043 public void itemStateChanged(ItemEvent e)
1045 comboBox.repaint();
1050 * KeyHandler handles key events occuring while JComboBox has focus.
1052 public class KeyHandler extends KeyAdapter
1054 public KeyHandler()
1059 * This method is invoked whenever key is pressed while JComboBox is in
1060 * focus.
1062 public void keyPressed(KeyEvent e)
1064 // FIXME: This method calls JComboBox.selectWithKeyChar if the key that was
1065 // pressed is not a navigation key.
1070 * This class handles to the changes occuring in the JComboBox's data model
1072 public class ListDataHandler extends Object implements ListDataListener
1075 * Creates a new ListDataHandler object.
1077 public ListDataHandler()
1082 * This method is invoked content's of JComboBox's data model are changed
1084 * @param e ListDataEvent describing the change.
1086 public void contentsChanged(ListDataEvent e)
1088 // if the item is selected or deselected
1092 * This method is invoked when items were added to the JComboBox's data
1093 * model.
1095 * @param e ListDataEvent describing the change.
1097 public void intervalAdded(ListDataEvent e)
1099 // must determine if the size of the combo box should change
1100 int start = e.getIndex0();
1101 int end = e.getIndex1();
1103 ComboBoxModel model = comboBox.getModel();
1104 ListCellRenderer renderer = comboBox.getRenderer();
1106 if (largestItemSize == null)
1107 largestItemSize = new Dimension(0, 0);
1109 for (int i = start - 1; i < end; i++)
1111 Object item = model.getElementAt(i);
1112 Component comp = renderer.getListCellRendererComponent(new JList(),
1113 item, -1,
1114 false, false);
1115 if (comp.getPreferredSize().getWidth() > largestItemSize.getWidth())
1116 largestItemSize = comp.getPreferredSize();
1121 * This method is invoked when items were removed from the JComboBox's
1122 * data model.
1124 * @param e ListDataEvent describing the change.
1126 public void intervalRemoved(ListDataEvent e)
1128 // recalculate display size of the JComboBox.
1129 largestItemSize = getLargestItemSize();
1130 comboBox.repaint();
1135 * This class handles PropertyChangeEvents fired by JComboBox.
1137 public class PropertyChangeHandler extends Object
1138 implements PropertyChangeListener
1140 public PropertyChangeHandler()
1145 * This method is invoked whenever bound property of JComboBox changes.
1147 public void propertyChange(PropertyChangeEvent e)
1149 if (e.getPropertyName().equals("enabled"))
1151 arrowButton.setEnabled(comboBox.isEnabled());
1153 if (comboBox.isEditable())
1154 comboBox.getEditor().getEditorComponent().setEnabled(comboBox
1155 .isEnabled());
1157 else if (e.getPropertyName().equals("editable"))
1159 if (comboBox.isEditable())
1161 configureEditor();
1162 addEditor();
1164 else
1166 unconfigureEditor();
1167 removeEditor();
1170 comboBox.revalidate();
1171 comboBox.repaint();
1173 else if (e.getPropertyName().equals("dataModel"))
1175 // remove ListDataListener from old model and add it to new model
1176 ComboBoxModel oldModel = (ComboBoxModel) e.getOldValue();
1177 if (oldModel != null)
1178 oldModel.removeListDataListener(listDataListener);
1180 if ((ComboBoxModel) e.getNewValue() != null)
1181 comboBox.getModel().addListDataListener(listDataListener);
1184 // FIXME: Need to handle changes in other bound properties.
1189 * MouseHandler listens to mouse events occuring in the combo box. This
1190 * class is responsible for repainting this JComboBox whenever the mouse is
1191 * being pressed or released over it.
1193 private class MouseHandler extends MouseAdapter
1196 * This method is invoked when mouse is pressed over the combo box. It
1197 * repaints the combo box accordinglly
1199 * @param e the MouseEvent
1201 public void mousePressed(MouseEvent e)
1203 if (comboBox.isEnabled())
1205 if (e.getSource() instanceof JComboBox)
1207 arrowButton.getModel().setPressed(true);
1208 arrowButton.getModel().setArmed(true);
1211 comboBox.repaint();
1213 if (e.getSource() instanceof BasicArrowButton)
1214 toggleOpenClose();
1219 * This method is invoked when mouse is released over the combo box. It
1220 * repaints the combo box accordinglly
1222 * @param e the MouseEvent
1224 public void mouseReleased(MouseEvent e)
1226 if (comboBox.isEnabled())
1228 if (e.getSource() instanceof JComboBox)
1230 arrowButton.getModel().setPressed(false);
1231 arrowButton.getModel().setArmed(false);
1234 comboBox.repaint();