/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* This is a basic implementation of the <code>ComboPopup</code> interface.
*
* This class represents the ui for the popup portion of the combo box.
* <p>
* All event handling is handled by listener classes created with the
* <code>createxxxListener()</code> methods and internal classes.
* You can change the behavior of this class by overriding the
* <code>createxxxListener()</code> methods and supplying your own
* event listeners or subclassing from the ones supplied in this class.
* <p>
* <strong>Warning:</strong>
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is
* appropriate for short term storage or RMI between applications running
* the same version of Swing. As of 1.4, support for long term storage
* of all JavaBeans<sup><font size="-2">TM</font></sup>
* has been added to the <code>java.beans</code> package.
* Please see {@link java.beans.XMLEncoder}.
*
* @author Tom Santos
* @author Mark Davidson
*/
// An empty ListMode, this is used when the UI changes to allow
// the JList to be gc'ed.
};
/**
* This protected field is implementation specific. Do not access directly
* or override. Use the accessor methods instead.
*
* @see #getList
* @see #createList
*/
/**
* This protected field is implementation specific. Do not access directly
* or override. Use the create method instead
*
* @see #createScroller
*/
/**
* As of Java 2 platform v1.4 this previously undocumented field is no
* longer used.
*/
protected boolean valueIsAdjusting = false;
// Listeners that are required by the ComboPopup interface
/**
* Implementation of all the listener classes.
*/
/**
* This protected field is implementation specific. Do not access directly
* or override. Use the accessor or create methods instead.
*
* @see #getMouseMotionListener
* @see #createMouseMotionListener
*/
/**
* This protected field is implementation specific. Do not access directly
* or override. Use the accessor or create methods instead.
*
* @see #getMouseListener
* @see #createMouseListener
*/
/**
* This protected field is implementation specific. Do not access directly
* or override. Use the accessor or create methods instead.
*
* @see #getKeyListener
* @see #createKeyListener
*/
/**
* This protected field is implementation specific. Do not access directly
* or override. Use the create method instead.
*
* @see #createListSelectionListener
*/
// Listeners that are attached to the list
/**
* This protected field is implementation specific. Do not access directly
* or override. Use the create method instead.
*
* @see #createListMouseListener
*/
/**
* This protected field is implementation specific. Do not access directly
* or override. Use the create method instead
*
* @see #createListMouseMotionListener
*/
// Added to the combo box for bound properties
/**
* This protected field is implementation specific. Do not access directly
* or override. Use the create method instead
*
* @see #createPropertyChangeListener
*/
// Added to the combo box model
/**
* This protected field is implementation specific. Do not access directly
* or override. Use the create method instead
*
* @see #createListDataListener
*/
/**
* This protected field is implementation specific. Do not access directly
* or override. Use the create method instead
*
* @see #createItemListener
*/
/**
* This protected field is implementation specific. Do not access directly
* or override.
*/
protected boolean hasEntered = false;
protected boolean isAutoScrolling = false;
//========================================
// begin ComboPopup method implementations
//
/**
* Implementation of ComboPopup.show().
*/
public void show() {
}
/**
* Implementation of ComboPopup.hide().
*/
public void hide() {
if ( selection[i] == this ) {
break;
}
}
}
}
/**
* Implementation of ComboPopup.getList().
*/
return list;
}
/**
* Implementation of ComboPopup.getMouseListener().
*
* @return a <code>MouseListener</code> or null
* @see ComboPopup#getMouseListener
*/
if (mouseListener == null) {
}
return mouseListener;
}
/**
* Implementation of ComboPopup.getMouseMotionListener().
*
* @return a <code>MouseMotionListener</code> or null
* @see ComboPopup#getMouseMotionListener
*/
if (mouseMotionListener == null) {
}
return mouseMotionListener;
}
/**
* Implementation of ComboPopup.getKeyListener().
*
* @return a <code>KeyListener</code> or null
* @see ComboPopup#getKeyListener
*/
if (keyListener == null) {
}
return keyListener;
}
/**
* Called when the UI is uninstalling. Since this popup isn't in the component
* tree, it won't get it's uninstallUI() called. It removes the listeners that
* were added in addComboBoxListeners().
*/
public void uninstallingUI() {
if (propertyChangeListener != null) {
}
if (itemListener != null) {
}
// We do this, otherwise the listener the ui installs on
// the model (the combobox model in this case) will keep a
// reference to the list, causing the list (and us) to never get gced.
}
//
// end ComboPopup method implementations
//======================================
/**
* Removes the listeners from the combo box model
*
* @param model The combo box model to install listeners
* @see #installComboBoxModelListeners
*/
}
}
protected void uninstallKeyboardActions() {
// XXX - shouldn't call this method
// comboBox.unregisterKeyboardAction( KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, 0 ) );
}
//===================================================================
// begin Initialization routines
//
super();
setName("ComboPopup.popup");
// UI construction of the popup.
list = createList();
scroller = createScroller();
}
// Overriden PopupMenuListener notification methods to inform combo box
// PopupMenuListeners.
protected void firePopupMenuWillBecomeVisible() {
super.firePopupMenuWillBecomeVisible();
// comboBox.firePopupMenuWillBecomeVisible() is called from BasicComboPopup.show() method
// to let the user change the popup menu from the PopupMenuListener.popupMenuWillBecomeVisible()
}
protected void firePopupMenuWillBecomeInvisible() {
super.firePopupMenuWillBecomeInvisible();
}
protected void firePopupMenuCanceled() {
super.firePopupMenuCanceled();
}
/**
* Creates a listener
* that will watch for mouse-press and release events on the combo box.
*
* <strong>Warning:</strong>
* When overriding this method, make sure to maintain the existing
* behavior.
*
* @return a <code>MouseListener</code> which will be added to
* the combo box or null
*/
return getHandler();
}
/**
* Creates the mouse motion listener which will be added to the combo
* box.
*
* <strong>Warning:</strong>
* When overriding this method, make sure to maintain the existing
* behavior.
*
* @return a <code>MouseMotionListener</code> which will be added to
* the combo box or null
*/
return getHandler();
}
/**
* Creates the key listener that will be added to the combo box. If
* this method returns null then it will not be added to the combo box.
*
* @return a <code>KeyListener</code> or null
*/
return null;
}
/**
* Creates a list selection listener that watches for selection changes in
* the popup's list. If this method returns null then it will not
* be added to the popup list.
*
* @return an instance of a <code>ListSelectionListener</code> or null
*/
return null;
}
/**
* Creates a list data listener which will be added to the
* <code>ComboBoxModel</code>. If this method returns null then
* it will not be added to the combo box model.
*
* @return an instance of a <code>ListDataListener</code> or null
*/
return null;
}
/**
* Creates a mouse listener that watches for mouse events in
* the popup's list. If this method returns null then it will
* not be added to the combo box.
*
* @return an instance of a <code>MouseListener</code> or null
*/
return getHandler();
}
/**
* Creates a mouse motion listener that watches for mouse motion
* events in the popup's list. If this method returns null then it will
* not be added to the combo box.
*
* @return an instance of a <code>MouseMotionListener</code> or null
*/
return getHandler();
}
/**
* Creates a <code>PropertyChangeListener</code> which will be added to
* the combo box. If this method returns null then it will not
* be added to the combo box.
*
* @return an instance of a <code>PropertyChangeListener</code> or null
*/
return getHandler();
}
/**
* Creates an <code>ItemListener</code> which will be added to the
* combo box. If this method returns null then it will not
* be added to the combo box.
* <p>
* Subclasses may override this method to return instances of their own
* ItemEvent handlers.
*
* @return an instance of an <code>ItemListener</code> or null
*/
return getHandler();
}
}
return handler;
}
/**
* Creates the JList used in the popup to display
* the items in the combo box model. This method is called when the UI class
* is created.
*
* @return a <code>JList</code> used to display the combo box items
*/
public void processMouseEvent(MouseEvent e) {
if (BasicGraphicsUtils.isMenuShortcutKeyDown(e)) {
// Fix for 4234053. Filter out the Control Key from the list.
// ie., don't allow CTRL key deselection.
e.getXOnScreen(), e.getYOnScreen(),
e.getClickCount(),
e.isPopupTrigger(),
}
super.processMouseEvent(e);
}
};
}
/**
* Configures the list which is used to hold the combo box items in the
* popup. This method is called when the UI class
* is created.
*
* @see #createList
*/
protected void configureList() {
list.setFocusable( false );
}
/**
* Adds the listeners to the list control.
*/
protected void installListListeners() {
}
}
}
}
void uninstallListListeners() {
if (listMouseListener != null) {
}
if (listMouseMotionListener != null) {
}
if (listSelectionListener != null) {
}
}
/**
* Creates the scroll pane which houses the scrollable list.
*/
return sp;
}
/**
* Configures the scrollable portion which holds the list within
* the combo box popup. This method is called when the UI class
* is created.
*/
protected void configureScroller() {
scroller.setFocusable( false );
}
/**
* Configures the popup portion of the combo box. This method is called
* when the UI class is created.
*/
protected void configurePopup() {
setBorderPainted( true );
setOpaque( false );
setDoubleBuffered( true );
setFocusable( false );
}
/**
* This method adds the necessary listeners to the JComboBox.
*/
protected void installComboBoxListeners() {
}
}
}
/**
* Installs the listeners on the combo box model. Any listeners installed
* on the combo box model should be removed in
* <code>uninstallComboBoxModelListeners</code>.
*
* @param model The combo box model to install listeners
* @see #uninstallComboBoxModelListeners
*/
}
}
protected void installKeyboardActions() {
/* XXX - shouldn't call this method. take it out for testing.
ActionListener action = new ActionListener() {
public void actionPerformed(ActionEvent e){
}
};
comboBox.registerKeyboardAction( action,
KeyStroke.getKeyStroke( KeyEvent.VK_ENTER, 0 ),
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); */
}
//
// end Initialization routines
//=================================================================
//===================================================================
// begin Event Listenters
//
/**
* A listener to be registered upon the combo box
* (<em>not</em> its popup menu)
* to handle mouse events
* that affect the state of the popup menu.
* The main purpose of this listener is to make the popup menu
* appear and disappear.
* This listener also helps
* with click-and-drag scenarios by setting the selection if the mouse was
* released over the list during a drag.
*
* <p>
* <strong>Warning:</strong>
* We recommend that you <em>not</em>
* create subclasses of this class.
* If you absolutely must create a subclass,
* be sure to invoke the superclass
* version of each method.
*
* @see BasicComboPopup#createMouseListener
*/
/**
* Responds to mouse-pressed events on the combo box.
*
* @param e the mouse-press event to be handled
*/
getHandler().mousePressed(e);
}
/**
* Responds to the user terminating
* a click or drag that began on the combo box.
*
* @param e the mouse-release event to be handled
*/
getHandler().mouseReleased(e);
}
}
/**
* This listener watches for dragging and updates the current selection in the
* list if it is dragging over the list.
*/
getHandler().mouseDragged(e);
}
}
/**
* As of Java 2 platform v 1.4, this class is now obsolete and is only included for
* backwards API compatibility. Do not instantiate or subclass.
* <p>
* All the functionality of this class has been included in
*/
}
/**
* As of Java 2 platform v 1.4, this class is now obsolete, doesn't do anything, and
* is only included for backwards API compatibility. Do not call or
* override.
*/
}
/**
* As of 1.4, this class is now obsolete, doesn't do anything, and
* is only included for backwards API compatibility. Do not call or
* override.
* <p>
* The functionality has been migrated into <code>ItemHandler</code>.
*
* @see #createItemListener
*/
}
}
}
/**
* This listener hides the popup when the mouse is released in the list.
*/
}
}
}
/**
* 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.
*/
}
}
/**
* This listener watches for changes to the selection in the
* combo box.
*/
getHandler().itemStateChanged(e);
}
}
/**
* 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
*/
getHandler().propertyChange(e);
}
}
private int direction;
}
autoScrollUp();
}
else {
}
}
}
//
// MouseListener
// NOTE: this is added to both the JList and JComboBox
//
}
return;
}
return;
if ( comboBox.isEditable() ) {
comp.requestFocus();
}
}
else if (comboBox.isRequestFocusEnabled()) {
}
togglePopup();
}
// JList mouse listener
}
}
comboBox.setPopupVisible(false);
// workaround for cancelling an edited item (bug 4530953)
}
return;
}
// JComboBox mouse listener
list.computeVisibleRect( r );
}
}
comboBox.setPopupVisible(false);
}
hasEntered = false;
}
}
}
//
// MouseMotionListener:
// NOTE: this is added to both the List and ComboBox
//
list.computeVisibleRect( r );
updateListBoxSelectionForEvent( anEvent, false );
}
}
}
return;
}
if ( isVisible() ) {
list.computeVisibleRect( r );
hasEntered = true;
if ( isAutoScrolling ) {
}
updateListBoxSelectionForEvent( newEvent, false );
}
}
else {
if ( hasEntered ) {
}
else if ( !isAutoScrolling ) {
}
}
else {
if ( e.getPoint().y < 0 ) {
hasEntered = true;
}
}
}
}
}
//
// PropertyChangeListener
//
if ( propertyName == "model" ) {
if ( isVisible() ) {
hide();
}
}
else if ( propertyName == "renderer" ) {
if ( isVisible() ) {
hide();
}
}
else if (propertyName == "componentOrientation") {
// Pass along the new component orientation
// to the list and the scroller
}
}
if (o!=getComponentOrientation()) {
}
}
else if (propertyName == "lightWeightPopupEnabled") {
}
}
//
// ItemListener
//
}
}
}
//
// 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.
*/
// XXX - should be a private method within InvocationMouseMotionHandler
// if possible.
if ( isAutoScrolling ) {
}
isAutoScrolling = true;
SCROLL_UP) );
}
else if ( direction == SCROLL_DOWN ) {
list );
SCROLL_DOWN));
}
}
/**
* This protected method is implementation specific and should be private.
* do not call or override.
*/
protected void stopAutoScrolling() {
isAutoScrolling = false;
if ( autoscrollTimer != null ) {
}
}
/**
* This protected method is implementation specific and should be private.
* do not call or override.
*/
protected void autoScrollUp() {
if ( index > 0 ) {
}
}
/**
* This protected method is implementation specific and should be private.
* do not call or override.
*/
protected void autoScrollDown() {
}
}
//
// end Autoscroll methods
//=================================================================
//===================================================================
// begin Utility methods
//
/**
* Gets the AccessibleContext associated with this BasicComboPopup.
* The AccessibleContext will have its parent set to the ComboBox.
*
* @return an AccessibleContext for the BasicComboPopup
* @since 1.5
*/
return context;
}
/**
* 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.
*/
if ( comboBox.isEditable() ) {
comp.requestFocus();
}
}
else if (comboBox.isRequestFocusEnabled()) {
}
}
/**
* 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
*/
if ( selectedIndex == -1 ) {
}
else {
}
}
e.getID(),
e.getWhen(),
e.getModifiers(),
e.getXOnScreen(),
e.getYOnScreen(),
e.getClickCount(),
e.isPopupTrigger(),
return newEvent;
}
/**
* Retrieves the height of the popup based on the current
* ListCellRenderer and the maximum row count.
*/
// Set the cached value of the minimum row count
int height = 0;
for ( int i = 0; i < minRowCount; ++i ) {
}
if (height == 0) {
}
}
}
return 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
*/
// Calculate the desktop dimensions relative to the combo box.
}
else {
}
}
return rect;
}
/**
* Calculates the upper left location of the Popup.
*/
// reduce the width of the scrollpane by the insets so that the popup
// is the same width as the combo box.
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.
*/
// XXX - only seems to be called from this class. shouldScroll flag is
// never true
return;
if ( index == -1 ) {
if ( location.y < 0 )
index = 0;
else
}
if ( shouldScroll )
}
}
//
// end Utility methods
//=================================================================
}