< prev index next >

src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboPopup.java

Print this page




  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.swing.plaf.basic;
  27 
  28 import javax.accessibility.AccessibleContext;
  29 import javax.swing.*;
  30 import javax.swing.border.Border;
  31 import javax.swing.border.LineBorder;
  32 import javax.swing.event.*;
  33 import java.awt.*;
  34 import java.awt.event.*;
  35 import java.beans.PropertyChangeListener;
  36 import java.beans.PropertyChangeEvent;
  37 import java.io.Serializable;
  38 
  39 
  40 /**
  41  * This is a basic implementation of the <code>ComboPopup</code> interface.
  42  *
  43  * This class represents the ui for the popup portion of the combo box.
  44  * <p>
  45  * All event handling is handled by listener classes created with the
  46  * <code>createxxxListener()</code> methods and internal classes.
  47  * You can change the behavior of this class by overriding the
  48  * <code>createxxxListener()</code> methods and supplying your own
  49  * event listeners or subclassing from the ones supplied in this class.
  50  * <p>
  51  * <strong>Warning:</strong>
  52  * Serialized objects of this class will not be compatible with
  53  * future Swing releases. The current serialization support is
  54  * appropriate for short term storage or RMI between applications running
  55  * the same version of Swing.  As of 1.4, support for long term storage
  56  * of all JavaBeans&trade;
  57  * has been added to the <code>java.beans</code> package.
  58  * Please see {@link java.beans.XMLEncoder}.
  59  *
  60  * @author Tom Santos
  61  * @author Mark Davidson
  62  */
  63 @SuppressWarnings("serial") // Same-version serialization only
  64 public class BasicComboPopup extends JPopupMenu implements ComboPopup {
  65     // An empty ListMode, this is used when the UI changes to allow
  66     // the JList to be gc'ed.
  67     private static class EmptyListModelClass implements ListModel<Object>, Serializable {
  68         public int getSize() { return 0; }
  69         public Object getElementAt(int index) { return null; }
  70         public void addListDataListener(ListDataListener l) {}
  71         public void removeListDataListener(ListDataListener l) {}
  72     };
  73 
  74     static final ListModel<Object> EmptyListModel = new EmptyListModelClass();
  75 
  76     private static Border LIST_BORDER = new LineBorder(Color.BLACK, 1);
  77 


 245             if ( selection[i] == this ) {
 246                 manager.clearSelectedPath();
 247                 break;
 248             }
 249         }
 250         if (selection.length > 0) {
 251             comboBox.repaint();
 252         }
 253     }
 254 
 255     /**
 256      * Implementation of ComboPopup.getList().
 257      */
 258     public JList<Object> getList() {
 259         return list;
 260     }
 261 
 262     /**
 263      * Implementation of ComboPopup.getMouseListener().
 264      *
 265      * @return a <code>MouseListener</code> or null
 266      * @see ComboPopup#getMouseListener
 267      */
 268     public MouseListener getMouseListener() {
 269         if (mouseListener == null) {
 270             mouseListener = createMouseListener();
 271         }
 272         return mouseListener;
 273     }
 274 
 275     /**
 276      * Implementation of ComboPopup.getMouseMotionListener().
 277      *
 278      * @return a <code>MouseMotionListener</code> or null
 279      * @see ComboPopup#getMouseMotionListener
 280      */
 281     public MouseMotionListener getMouseMotionListener() {
 282         if (mouseMotionListener == null) {
 283             mouseMotionListener = createMouseMotionListener();
 284         }
 285         return mouseMotionListener;
 286     }
 287 
 288     /**
 289      * Implementation of ComboPopup.getKeyListener().
 290      *
 291      * @return a <code>KeyListener</code> or null
 292      * @see ComboPopup#getKeyListener
 293      */
 294     public KeyListener getKeyListener() {
 295         if (keyListener == null) {
 296             keyListener = createKeyListener();
 297         }
 298         return keyListener;
 299     }
 300 
 301     /**
 302      * Called when the UI is uninstalling.  Since this popup isn't in the component
 303      * tree, it won't get it's uninstallUI() called.  It removes the listeners that
 304      * were added in addComboBoxListeners().
 305      */
 306     public void uninstallingUI() {
 307         if (propertyChangeListener != null) {
 308             comboBox.removePropertyChangeListener( propertyChangeListener );
 309         }
 310         if (itemListener != null) {
 311             comboBox.removeItemListener( itemListener );


 385     }
 386 
 387     protected void firePopupMenuWillBecomeInvisible() {
 388         super.firePopupMenuWillBecomeInvisible();
 389         comboBox.firePopupMenuWillBecomeInvisible();
 390     }
 391 
 392     protected void firePopupMenuCanceled() {
 393         super.firePopupMenuCanceled();
 394         comboBox.firePopupMenuCanceled();
 395     }
 396 
 397     /**
 398      * Creates a listener
 399      * that will watch for mouse-press and release events on the combo box.
 400      *
 401      * <strong>Warning:</strong>
 402      * When overriding this method, make sure to maintain the existing
 403      * behavior.
 404      *
 405      * @return a <code>MouseListener</code> which will be added to
 406      * the combo box or null
 407      */
 408     protected MouseListener createMouseListener() {
 409         return getHandler();
 410     }
 411 
 412     /**
 413      * Creates the mouse motion listener which will be added to the combo
 414      * box.
 415      *
 416      * <strong>Warning:</strong>
 417      * When overriding this method, make sure to maintain the existing
 418      * behavior.
 419      *
 420      * @return a <code>MouseMotionListener</code> which will be added to
 421      *         the combo box or null
 422      */
 423     protected MouseMotionListener createMouseMotionListener() {
 424         return getHandler();
 425     }
 426 
 427     /**
 428      * Creates the key listener that will be added to the combo box. If
 429      * this method returns null then it will not be added to the combo box.
 430      *
 431      * @return a <code>KeyListener</code> or null
 432      */
 433     protected KeyListener createKeyListener() {
 434         return null;
 435     }
 436 
 437     /**
 438      * Creates a list selection listener that watches for selection changes in
 439      * the popup's list.  If this method returns null then it will not
 440      * be added to the popup list.
 441      *
 442      * @return an instance of a <code>ListSelectionListener</code> or null
 443      */
 444     protected ListSelectionListener createListSelectionListener() {
 445         return null;
 446     }
 447 
 448     /**
 449      * Creates a list data listener which will be added to the
 450      * <code>ComboBoxModel</code>. If this method returns null then
 451      * it will not be added to the combo box model.
 452      *
 453      * @return an instance of a <code>ListDataListener</code> or null
 454      */
 455     protected ListDataListener createListDataListener() {
 456         return null;
 457     }
 458 
 459     /**
 460      * Creates a mouse listener that watches for mouse events in
 461      * the popup's list. If this method returns null then it will
 462      * not be added to the combo box.
 463      *
 464      * @return an instance of a <code>MouseListener</code> or null
 465      */
 466     protected MouseListener createListMouseListener() {
 467         return getHandler();
 468     }
 469 
 470     /**
 471      * Creates a mouse motion listener that watches for mouse motion
 472      * events in the popup's list. If this method returns null then it will
 473      * not be added to the combo box.
 474      *
 475      * @return an instance of a <code>MouseMotionListener</code> or null
 476      */
 477     protected MouseMotionListener createListMouseMotionListener() {
 478         return getHandler();
 479     }
 480 
 481     /**
 482      * Creates a <code>PropertyChangeListener</code> which will be added to
 483      * the combo box. If this method returns null then it will not
 484      * be added to the combo box.
 485      *
 486      * @return an instance of a <code>PropertyChangeListener</code> or null
 487      */
 488     protected PropertyChangeListener createPropertyChangeListener() {
 489         return getHandler();
 490     }
 491 
 492     /**
 493      * Creates an <code>ItemListener</code> which will be added to the
 494      * combo box. If this method returns null then it will not
 495      * be added to the combo box.
 496      * <p>
 497      * Subclasses may override this method to return instances of their own
 498      * ItemEvent handlers.
 499      *
 500      * @return an instance of an <code>ItemListener</code> or null
 501      */
 502     protected ItemListener createItemListener() {
 503         return getHandler();
 504     }
 505 
 506     private Handler getHandler() {
 507         if (handler == null) {
 508             handler = new Handler();
 509         }
 510         return handler;
 511     }
 512 
 513     /**
 514      * Creates the JList used in the popup to display
 515      * the items in the combo box model. This method is called when the UI class
 516      * is created.
 517      *
 518      * @return a <code>JList</code> used to display the combo box items
 519      */
 520     protected JList<Object> createList() {
 521         return new JList<Object>( comboBox.getModel() ) {
 522             public void processMouseEvent(MouseEvent e)  {
 523                 if (BasicGraphicsUtils.isMenuShortcutKeyDown(e))  {
 524                     // Fix for 4234053. Filter out the Control Key from the list.
 525                     // ie., don't allow CTRL key deselection.
 526                     Toolkit toolkit = Toolkit.getDefaultToolkit();
 527                     e = new MouseEvent((Component)e.getSource(), e.getID(), e.getWhen(),
 528                                        e.getModifiers() ^ toolkit.getMenuShortcutKeyMask(),
 529                                        e.getX(), e.getY(),
 530                                        e.getXOnScreen(), e.getYOnScreen(),
 531                                        e.getClickCount(),
 532                                        e.isPopupTrigger(),
 533                                        MouseEvent.NOBUTTON);
 534                 }
 535                 super.processMouseEvent(e);
 536             }
 537         };
 538     }


 641             scrollerMouseWheelListener = null;
 642         }
 643     }
 644 
 645     /**
 646      * This method adds the necessary listeners to the JComboBox.
 647      */
 648     protected void installComboBoxListeners() {
 649         if ((propertyChangeListener = createPropertyChangeListener()) != null) {
 650             comboBox.addPropertyChangeListener(propertyChangeListener);
 651         }
 652         if ((itemListener = createItemListener()) != null) {
 653             comboBox.addItemListener(itemListener);
 654         }
 655         installComboBoxModelListeners(comboBox.getModel());
 656     }
 657 
 658     /**
 659      * Installs the listeners on the combo box model. Any listeners installed
 660      * on the combo box model should be removed in
 661      * <code>uninstallComboBoxModelListeners</code>.
 662      *
 663      * @param model The combo box model to install listeners
 664      * @see #uninstallComboBoxModelListeners
 665      */
 666     protected void installComboBoxModelListeners( ComboBoxModel<?> model ) {
 667         if (model != null && (listDataListener = createListDataListener()) != null) {
 668             model.addListDataListener(listDataListener);
 669         }
 670     }
 671 
 672     /**
 673      * Registers keyboard actions.
 674      */
 675     protected void installKeyboardActions() {
 676 
 677         /* XXX - shouldn't call this method. take it out for testing.
 678         ActionListener action = new ActionListener() {
 679             public void actionPerformed(ActionEvent e){
 680             }
 681         };


 755      * BasicComboBoxUI ActionMap/InputMap methods.
 756      */
 757     public class InvocationKeyHandler extends KeyAdapter {
 758         public void keyReleased( KeyEvent e ) {}
 759     }
 760 
 761     /**
 762      * As of Java 2 platform v 1.4, this class is now obsolete, doesn't do anything, and
 763      * is only included for backwards API compatibility. Do not call or
 764      * override.
 765      */
 766     protected class ListSelectionHandler implements ListSelectionListener {
 767         public void valueChanged( ListSelectionEvent e ) {}
 768     }
 769 
 770     /**
 771      * As of 1.4, this class is now obsolete, doesn't do anything, and
 772      * is only included for backwards API compatibility. Do not call or
 773      * override.
 774      * <p>
 775      * The functionality has been migrated into <code>ItemHandler</code>.
 776      *
 777      * @see #createItemListener
 778      */
 779     public class ListDataHandler implements ListDataListener {
 780         public void contentsChanged( ListDataEvent e ) {}
 781 
 782         public void intervalAdded( ListDataEvent e ) {
 783         }
 784 
 785         public void intervalRemoved( ListDataEvent e ) {
 786         }
 787     }
 788 
 789     /**
 790      * This listener hides the popup when the mouse is released in the list.
 791      */
 792     protected class ListMouseHandler extends MouseAdapter {
 793         public void mousePressed( MouseEvent e ) {
 794         }
 795         public void mouseReleased(MouseEvent anEvent) {




  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.swing.plaf.basic;
  27 
  28 import javax.accessibility.AccessibleContext;
  29 import javax.swing.*;
  30 import javax.swing.border.Border;
  31 import javax.swing.border.LineBorder;
  32 import javax.swing.event.*;
  33 import java.awt.*;
  34 import java.awt.event.*;
  35 import java.beans.PropertyChangeListener;
  36 import java.beans.PropertyChangeEvent;
  37 import java.io.Serializable;
  38 
  39 
  40 /**
  41  * This is a basic implementation of the {@code ComboPopup} interface.
  42  *
  43  * This class represents the ui for the popup portion of the combo box.
  44  * <p>
  45  * All event handling is handled by listener classes created with the
  46  * {@code createxxxListener()} methods and internal classes.
  47  * You can change the behavior of this class by overriding the
  48  * {@code createxxxListener()} methods and supplying your own
  49  * event listeners or subclassing from the ones supplied in this class.
  50  * <p>
  51  * <strong>Warning:</strong>
  52  * Serialized objects of this class will not be compatible with
  53  * future Swing releases. The current serialization support is
  54  * appropriate for short term storage or RMI between applications running
  55  * the same version of Swing.  As of 1.4, support for long term storage
  56  * of all JavaBeans&trade;
  57  * has been added to the {@code java.beans} package.
  58  * Please see {@link java.beans.XMLEncoder}.
  59  *
  60  * @author Tom Santos
  61  * @author Mark Davidson
  62  */
  63 @SuppressWarnings("serial") // Same-version serialization only
  64 public class BasicComboPopup extends JPopupMenu implements ComboPopup {
  65     // An empty ListMode, this is used when the UI changes to allow
  66     // the JList to be gc'ed.
  67     private static class EmptyListModelClass implements ListModel<Object>, Serializable {
  68         public int getSize() { return 0; }
  69         public Object getElementAt(int index) { return null; }
  70         public void addListDataListener(ListDataListener l) {}
  71         public void removeListDataListener(ListDataListener l) {}
  72     };
  73 
  74     static final ListModel<Object> EmptyListModel = new EmptyListModelClass();
  75 
  76     private static Border LIST_BORDER = new LineBorder(Color.BLACK, 1);
  77 


 245             if ( selection[i] == this ) {
 246                 manager.clearSelectedPath();
 247                 break;
 248             }
 249         }
 250         if (selection.length > 0) {
 251             comboBox.repaint();
 252         }
 253     }
 254 
 255     /**
 256      * Implementation of ComboPopup.getList().
 257      */
 258     public JList<Object> getList() {
 259         return list;
 260     }
 261 
 262     /**
 263      * Implementation of ComboPopup.getMouseListener().
 264      *
 265      * @return a {@code MouseListener} or null
 266      * @see ComboPopup#getMouseListener
 267      */
 268     public MouseListener getMouseListener() {
 269         if (mouseListener == null) {
 270             mouseListener = createMouseListener();
 271         }
 272         return mouseListener;
 273     }
 274 
 275     /**
 276      * Implementation of ComboPopup.getMouseMotionListener().
 277      *
 278      * @return a {@code MouseMotionListener} or null
 279      * @see ComboPopup#getMouseMotionListener
 280      */
 281     public MouseMotionListener getMouseMotionListener() {
 282         if (mouseMotionListener == null) {
 283             mouseMotionListener = createMouseMotionListener();
 284         }
 285         return mouseMotionListener;
 286     }
 287 
 288     /**
 289      * Implementation of ComboPopup.getKeyListener().
 290      *
 291      * @return a {@code KeyListener} or null
 292      * @see ComboPopup#getKeyListener
 293      */
 294     public KeyListener getKeyListener() {
 295         if (keyListener == null) {
 296             keyListener = createKeyListener();
 297         }
 298         return keyListener;
 299     }
 300 
 301     /**
 302      * Called when the UI is uninstalling.  Since this popup isn't in the component
 303      * tree, it won't get it's uninstallUI() called.  It removes the listeners that
 304      * were added in addComboBoxListeners().
 305      */
 306     public void uninstallingUI() {
 307         if (propertyChangeListener != null) {
 308             comboBox.removePropertyChangeListener( propertyChangeListener );
 309         }
 310         if (itemListener != null) {
 311             comboBox.removeItemListener( itemListener );


 385     }
 386 
 387     protected void firePopupMenuWillBecomeInvisible() {
 388         super.firePopupMenuWillBecomeInvisible();
 389         comboBox.firePopupMenuWillBecomeInvisible();
 390     }
 391 
 392     protected void firePopupMenuCanceled() {
 393         super.firePopupMenuCanceled();
 394         comboBox.firePopupMenuCanceled();
 395     }
 396 
 397     /**
 398      * Creates a listener
 399      * that will watch for mouse-press and release events on the combo box.
 400      *
 401      * <strong>Warning:</strong>
 402      * When overriding this method, make sure to maintain the existing
 403      * behavior.
 404      *
 405      * @return a {@code MouseListener} which will be added to
 406      * the combo box or null
 407      */
 408     protected MouseListener createMouseListener() {
 409         return getHandler();
 410     }
 411 
 412     /**
 413      * Creates the mouse motion listener which will be added to the combo
 414      * box.
 415      *
 416      * <strong>Warning:</strong>
 417      * When overriding this method, make sure to maintain the existing
 418      * behavior.
 419      *
 420      * @return a {@code MouseMotionListener} which will be added to
 421      *         the combo box or null
 422      */
 423     protected MouseMotionListener createMouseMotionListener() {
 424         return getHandler();
 425     }
 426 
 427     /**
 428      * Creates the key listener that will be added to the combo box. If
 429      * this method returns null then it will not be added to the combo box.
 430      *
 431      * @return a {@code KeyListener} or null
 432      */
 433     protected KeyListener createKeyListener() {
 434         return null;
 435     }
 436 
 437     /**
 438      * Creates a list selection listener that watches for selection changes in
 439      * the popup's list.  If this method returns null then it will not
 440      * be added to the popup list.
 441      *
 442      * @return an instance of a {@code ListSelectionListener} or null
 443      */
 444     protected ListSelectionListener createListSelectionListener() {
 445         return null;
 446     }
 447 
 448     /**
 449      * Creates a list data listener which will be added to the
 450      * {@code ComboBoxModel}. If this method returns null then
 451      * it will not be added to the combo box model.
 452      *
 453      * @return an instance of a {@code ListDataListener} or null
 454      */
 455     protected ListDataListener createListDataListener() {
 456         return null;
 457     }
 458 
 459     /**
 460      * Creates a mouse listener that watches for mouse events in
 461      * the popup's list. If this method returns null then it will
 462      * not be added to the combo box.
 463      *
 464      * @return an instance of a {@code MouseListener} or null
 465      */
 466     protected MouseListener createListMouseListener() {
 467         return getHandler();
 468     }
 469 
 470     /**
 471      * Creates a mouse motion listener that watches for mouse motion
 472      * events in the popup's list. If this method returns null then it will
 473      * not be added to the combo box.
 474      *
 475      * @return an instance of a {@code MouseMotionListener} or null
 476      */
 477     protected MouseMotionListener createListMouseMotionListener() {
 478         return getHandler();
 479     }
 480 
 481     /**
 482      * Creates a {@code PropertyChangeListener} which will be added to
 483      * the combo box. If this method returns null then it will not
 484      * be added to the combo box.
 485      *
 486      * @return an instance of a {@code PropertyChangeListener} or null
 487      */
 488     protected PropertyChangeListener createPropertyChangeListener() {
 489         return getHandler();
 490     }
 491 
 492     /**
 493      * Creates an {@code ItemListener} which will be added to the
 494      * combo box. If this method returns null then it will not
 495      * be added to the combo box.
 496      * <p>
 497      * Subclasses may override this method to return instances of their own
 498      * ItemEvent handlers.
 499      *
 500      * @return an instance of an {@code ItemListener} or null
 501      */
 502     protected ItemListener createItemListener() {
 503         return getHandler();
 504     }
 505 
 506     private Handler getHandler() {
 507         if (handler == null) {
 508             handler = new Handler();
 509         }
 510         return handler;
 511     }
 512 
 513     /**
 514      * Creates the JList used in the popup to display
 515      * the items in the combo box model. This method is called when the UI class
 516      * is created.
 517      *
 518      * @return a {@code JList} used to display the combo box items
 519      */
 520     protected JList<Object> createList() {
 521         return new JList<Object>( comboBox.getModel() ) {
 522             public void processMouseEvent(MouseEvent e)  {
 523                 if (BasicGraphicsUtils.isMenuShortcutKeyDown(e))  {
 524                     // Fix for 4234053. Filter out the Control Key from the list.
 525                     // ie., don't allow CTRL key deselection.
 526                     Toolkit toolkit = Toolkit.getDefaultToolkit();
 527                     e = new MouseEvent((Component)e.getSource(), e.getID(), e.getWhen(),
 528                                        e.getModifiers() ^ toolkit.getMenuShortcutKeyMask(),
 529                                        e.getX(), e.getY(),
 530                                        e.getXOnScreen(), e.getYOnScreen(),
 531                                        e.getClickCount(),
 532                                        e.isPopupTrigger(),
 533                                        MouseEvent.NOBUTTON);
 534                 }
 535                 super.processMouseEvent(e);
 536             }
 537         };
 538     }


 641             scrollerMouseWheelListener = null;
 642         }
 643     }
 644 
 645     /**
 646      * This method adds the necessary listeners to the JComboBox.
 647      */
 648     protected void installComboBoxListeners() {
 649         if ((propertyChangeListener = createPropertyChangeListener()) != null) {
 650             comboBox.addPropertyChangeListener(propertyChangeListener);
 651         }
 652         if ((itemListener = createItemListener()) != null) {
 653             comboBox.addItemListener(itemListener);
 654         }
 655         installComboBoxModelListeners(comboBox.getModel());
 656     }
 657 
 658     /**
 659      * Installs the listeners on the combo box model. Any listeners installed
 660      * on the combo box model should be removed in
 661      * {@code uninstallComboBoxModelListeners}.
 662      *
 663      * @param model The combo box model to install listeners
 664      * @see #uninstallComboBoxModelListeners
 665      */
 666     protected void installComboBoxModelListeners( ComboBoxModel<?> model ) {
 667         if (model != null && (listDataListener = createListDataListener()) != null) {
 668             model.addListDataListener(listDataListener);
 669         }
 670     }
 671 
 672     /**
 673      * Registers keyboard actions.
 674      */
 675     protected void installKeyboardActions() {
 676 
 677         /* XXX - shouldn't call this method. take it out for testing.
 678         ActionListener action = new ActionListener() {
 679             public void actionPerformed(ActionEvent e){
 680             }
 681         };


 755      * BasicComboBoxUI ActionMap/InputMap methods.
 756      */
 757     public class InvocationKeyHandler extends KeyAdapter {
 758         public void keyReleased( KeyEvent e ) {}
 759     }
 760 
 761     /**
 762      * As of Java 2 platform v 1.4, this class is now obsolete, doesn't do anything, and
 763      * is only included for backwards API compatibility. Do not call or
 764      * override.
 765      */
 766     protected class ListSelectionHandler implements ListSelectionListener {
 767         public void valueChanged( ListSelectionEvent e ) {}
 768     }
 769 
 770     /**
 771      * As of 1.4, this class is now obsolete, doesn't do anything, and
 772      * is only included for backwards API compatibility. Do not call or
 773      * override.
 774      * <p>
 775      * The functionality has been migrated into {@code ItemHandler}.
 776      *
 777      * @see #createItemListener
 778      */
 779     public class ListDataHandler implements ListDataListener {
 780         public void contentsChanged( ListDataEvent e ) {}
 781 
 782         public void intervalAdded( ListDataEvent e ) {
 783         }
 784 
 785         public void intervalRemoved( ListDataEvent e ) {
 786         }
 787     }
 788 
 789     /**
 790      * This listener hides the popup when the mouse is released in the list.
 791      */
 792     protected class ListMouseHandler extends MouseAdapter {
 793         public void mousePressed( MouseEvent e ) {
 794         }
 795         public void mouseReleased(MouseEvent anEvent) {


< prev index next >