📄 basiccombopopup.java
字号:
} /** * This listener changes the selected item as you move the mouse over the list. * The selection change is not committed to the model, this is for user feedback only. */ protected class ListMouseMotionHandler extends MouseMotionAdapter { public void mouseMoved( MouseEvent anEvent ) { Point location = anEvent.getPoint(); Rectangle r = new Rectangle(); list.computeVisibleRect( r ); if ( r.contains( location ) ) { updateListBoxSelectionForEvent( anEvent, false ); } } } /** * This listener watches for changes to the selection in the * combo box. */ protected class ItemHandler implements ItemListener { public void itemStateChanged( ItemEvent e ) { if (e.getStateChange() == ItemEvent.SELECTED) { JComboBox comboBox = (JComboBox)e.getSource(); setListSelection(comboBox.getSelectedIndex()); } } } /** * This listener watches for bound properties that have changed in the * combo box. * <p> * Subclasses which wish to listen to combo box property changes should * call the superclass methods to ensure that the combo popup correctly * handles property changes. * * @see #createPropertyChangeListener */ protected class PropertyChangeHandler implements PropertyChangeListener { public void propertyChange( PropertyChangeEvent e ) { JComboBox comboBox = (JComboBox)e.getSource(); String propertyName = e.getPropertyName(); if ( propertyName.equals("model") ) { ComboBoxModel oldModel = (ComboBoxModel)e.getOldValue(); ComboBoxModel newModel = (ComboBoxModel)e.getNewValue(); uninstallComboBoxModelListeners(oldModel); installComboBoxModelListeners(newModel); list.setModel(newModel); if ( isVisible() ) { hide(); } } else if ( propertyName.equals( "renderer" ) ) { list.setCellRenderer( comboBox.getRenderer() ); if ( isVisible() ) { hide(); } } else if (propertyName.equals("componentOrientation")) { // Pass along the new component orientation // to the list and the scroller ComponentOrientation o =(ComponentOrientation)e.getNewValue(); JList list = getList(); if (list!=null && list.getComponentOrientation()!=o) { list.setComponentOrientation(o); } if (scroller!=null && scroller.getComponentOrientation()!=o) { scroller.setComponentOrientation(o); } if (o!=getComponentOrientation()) { setComponentOrientation(o); } } else if (propertyName.equals("lightWeightPopupEnabled")) { setLightWeightPopupEnabled(comboBox.isLightWeightPopupEnabled()); } } } // // end Event Listeners //================================================================= /** * Overridden to unconditionally return false. */ public boolean isFocusTraversable() { return false; } //=================================================================== // begin Autoscroll methods // /** * This protected method is implementation specific and should be private. * do not call or override. */ protected void startAutoScrolling( int direction ) { // XXX - should be a private method within InvocationMouseMotionHandler // if possible. if ( isAutoScrolling ) { autoscrollTimer.stop(); } isAutoScrolling = true; if ( direction == SCROLL_UP ) { scrollDirection = SCROLL_UP; Point convertedPoint = SwingUtilities.convertPoint( scroller, new Point( 1, 1 ), list ); int top = list.locationToIndex( convertedPoint ); list.setSelectedIndex( top ); ActionListener timerAction = new ActionListener() { public void actionPerformed(ActionEvent e) { autoScrollUp(); } }; autoscrollTimer = new Timer( 100, timerAction ); } else if ( direction == SCROLL_DOWN ) { scrollDirection = SCROLL_DOWN; Dimension size = scroller.getSize(); Point convertedPoint = SwingUtilities.convertPoint( scroller, new Point( 1, (size.height - 1) - 2 ), list ); int bottom = list.locationToIndex( convertedPoint ); list.setSelectedIndex( bottom ); ActionListener timerAction = new ActionListener() { public void actionPerformed(ActionEvent e) { autoScrollDown(); } }; autoscrollTimer = new Timer( 100, timerAction ); } autoscrollTimer.start(); } /** * This protected method is implementation specific and should be private. * do not call or override. */ protected void stopAutoScrolling() { isAutoScrolling = false; if ( autoscrollTimer != null ) { autoscrollTimer.stop(); autoscrollTimer = null; } } /** * This protected method is implementation specific and should be private. * do not call or override. */ protected void autoScrollUp() { int index = list.getSelectedIndex(); if ( index > 0 ) { list.setSelectedIndex( index - 1 ); list.ensureIndexIsVisible( index - 1 ); } } /** * This protected method is implementation specific and should be private. * do not call or override. */ protected void autoScrollDown() { int index = list.getSelectedIndex(); int lastItem = list.getModel().getSize() - 1; if ( index < lastItem ) { list.setSelectedIndex( index + 1 ); list.ensureIndexIsVisible( index + 1 ); } } // // end Autoscroll methods //================================================================= //=================================================================== // begin Utility methods // /** * This is is a utility method that helps event handlers figure out where to * send the focus when the popup is brought up. The standard implementation * delegates the focus to the editor (if the combo box is editable) or to * the JComboBox if it is not editable. */ protected void delegateFocus( MouseEvent e ) { if ( comboBox.isEditable() ) { Component comp = comboBox.getEditor().getEditorComponent(); if ((!(comp instanceof JComponent)) || ((JComponent)comp).isRequestFocusEnabled()) { comp.requestFocus(); } } else if (comboBox.isRequestFocusEnabled()) { comboBox.requestFocus(); } } /** * Makes the popup visible if it is hidden and makes it hidden if it is * visible. */ protected void togglePopup() { if ( isVisible() ) { hide(); } else { show(); } } /** * Sets the list selection index to the selectedIndex. This * method is used to synchronize the list selection with the * combo box selection. * * @param selectedIndex the index to set the list */ private void setListSelection(int selectedIndex) { if ( selectedIndex == -1 ) { list.clearSelection(); } else { list.setSelectedIndex( selectedIndex ); list.ensureIndexIsVisible( selectedIndex ); } } protected MouseEvent convertMouseEvent( MouseEvent e ) { Point convertedPoint = SwingUtilities.convertPoint( (Component)e.getSource(), e.getPoint(), list ); MouseEvent newEvent = new MouseEvent( (Component)e.getSource(), e.getID(), e.getWhen(), e.getModifiers(), convertedPoint.x, convertedPoint.y, e.getClickCount(), e.isPopupTrigger() ); return newEvent; } /** * Retrieves the height of the popup based on the current * ListCellRenderer and the maximum row count. */ protected int getPopupHeightForRowCount(int maxRowCount) { // Set the cached value of the minimum row count int minRowCount = Math.min( maxRowCount, comboBox.getItemCount() ); int height = 0; ListCellRenderer renderer = list.getCellRenderer(); Object value = null; for ( int i = 0; i < minRowCount; ++i ) { value = list.getModel().getElementAt( i ); Component c = renderer.getListCellRendererComponent( list, value, i, false, false ); height += c.getPreferredSize().height; } return height == 0 ? 100 : height; } /** * Calculate the placement and size of the popup portion of the combo box based * on the combo box location and the enclosing screen bounds. If * no transformations are required, then the returned rectangle will * have the same values as the parameters. * * @param px starting x location * @param py starting y location * @param pw starting width * @param ph starting height * @return a rectangle which represents the placement and size of the popup */ protected Rectangle computePopupBounds(int px,int py,int pw,int ph) { Toolkit toolkit = Toolkit.getDefaultToolkit(); Rectangle screenBounds; // Calculate the desktop dimensions relative to the combo box. GraphicsConfiguration gc = comboBox.getGraphicsConfiguration(); Point p = new Point(); SwingUtilities.convertPointFromScreen(p, comboBox); if (gc != null) { Insets screenInsets = toolkit.getScreenInsets(gc); screenBounds = gc.getBounds(); screenBounds.width -= (screenInsets.left + screenInsets.right); screenBounds.height -= (screenInsets.top + screenInsets.bottom); screenBounds.x += (p.x + screenInsets.left); screenBounds.y += (p.y + screenInsets.top); } else { screenBounds = new Rectangle(p, toolkit.getScreenSize()); } Rectangle rect = new Rectangle(px,py,pw,ph); if (py+ph > screenBounds.y+screenBounds.height && ph < screenBounds.height) { rect.y = -rect.height; } return rect; } /** * Calculates the upper left location of the Popup. */ private Point getPopupLocation() { Dimension popupSize = comboBox.getSize(); Insets insets = getInsets(); // reduce the width of the scrollpane by the insets so that the popup // is the same width as the combo box. popupSize.setSize(popupSize.width - (insets.right + insets.left), getPopupHeightForRowCount( comboBox.getMaximumRowCount())); Rectangle popupBounds = computePopupBounds( 0, comboBox.getBounds().height, popupSize.width, popupSize.height); Dimension scrollSize = popupBounds.getSize(); Point popupLocation = popupBounds.getLocation(); scroller.setMaximumSize( scrollSize ); scroller.setPreferredSize( scrollSize ); scroller.setMinimumSize( scrollSize ); list.revalidate(); return popupLocation; } /** * A utility method used by the event listeners. Given a mouse event, it changes * the list selection to the list item below the mouse. */ protected void updateListBoxSelectionForEvent(MouseEvent anEvent,boolean shouldScroll) { // XXX - only seems to be called from this class. shouldScroll flag is // never true Point location = anEvent.getPoint(); if ( list == null ) return; int index = list.locationToIndex(location); if ( index == -1 ) { if ( location.y < 0 ) index = 0; else index = comboBox.getModel().getSize() - 1; } if ( list.getSelectedIndex() != index ) { list.setSelectedIndex(index); if ( shouldScroll ) list.ensureIndexIsVisible(index); } } // // end Utility methods //=================================================================}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -