diff options
Diffstat (limited to 'jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/ListChooser.java')
-rw-r--r-- | jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/ListChooser.java | 430 |
1 files changed, 0 insertions, 430 deletions
diff --git a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/ListChooser.java b/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/ListChooser.java deleted file mode 100644 index 600652ea49..0000000000 --- a/jpa/plugins/org.eclipse.jpt.utility/src/org/eclipse/jpt/utility/internal/swing/ListChooser.java +++ /dev/null @@ -1,430 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2007, 2010 Oracle. All rights reserved. - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0, which accompanies this distribution - * and is available at http://www.eclipse.org/legal/epl-v10.html. - * - * Contributors: - * Oracle - initial API and implementation - ******************************************************************************/ -package org.eclipse.jpt.utility.internal.swing; - -import java.awt.AWTEvent; -import java.awt.AWTException; -import java.awt.Component; -import java.awt.EventQueue; -import java.awt.Point; -import java.awt.Robot; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; -import java.awt.event.KeyListener; -import java.awt.event.MouseEvent; -import javax.swing.ComboBoxModel; -import javax.swing.DefaultListCellRenderer; -import javax.swing.JButton; -import javax.swing.JComboBox; -import javax.swing.JComponent; -import javax.swing.JLabel; -import javax.swing.JList; -import javax.swing.ListCellRenderer; -import javax.swing.SwingConstants; -import javax.swing.event.PopupMenuEvent; -import javax.swing.event.PopupMenuListener; -import javax.swing.plaf.basic.BasicComboBoxUI; -import org.eclipse.jpt.utility.internal.ReflectionTools; - -/** - * This component provides a way to handle selecting an item from a - * list that may grow too large to be handled conveniently by a combo-box. - * If the list's size is less than the designated "long" list size, - * the choice list will be displayed in a normal combo-box popup; - * otherwise, a dialog will be used to prompt the user to choose a selection. - * - * To change the browse mechanism, subclasses may - * - override the method #buildBrowser() - * - override the method #browse(), in which case the method - * #buildBrowser() may be ignored. - */ -public class ListChooser - extends JComboBox -{ - - /** the size of a "long" list - anything smaller is a "short" list */ - int longListSize = DEFAULT_LONG_LIST_SIZE; - - /** the default size of a "long" list, which is 20 (to match JOptionPane's behavior) */ - public static final int DEFAULT_LONG_LIST_SIZE = 20; - - /** property change associated with long list size */ - public static final String LONG_LIST_SIZE_PROPERTY = "longListSize"; //$NON-NLS-1$ - - static JLabel prototypeLabel = new JLabel("Prototype", new EmptyIcon(17), SwingConstants.LEADING); //$NON-NLS-1$ - - /** - * whether the chooser is choosable. if a chooser is not choosable, - * it only serves as a display widget. a user may not change its - * selected value. - */ - boolean choosable = true; - - /** property change associated with choosable */ - public static final String CHOOSABLE_PROPERTY = "choosable"; //$NON-NLS-1$ - - /** the browser used to make a selection from the long list - typically via a dialog */ - private ListBrowser browser; - - private NodeSelector nodeSelector; - - /** INTERNAL - The popup is being shown. Used to prevent infinite loop. */ - boolean popupAlreadyInProgress; - - - // **************** Constructors ****************************************** - - /** - * Construct a list chooser for the specified model. - */ - public ListChooser(ComboBoxModel model) { - this(model, new NodeSelector.DefaultNodeSelector()); - } - - public ListChooser(CachingComboBoxModel model) { - this(model, new NodeSelector.DefaultNodeSelector()); - } - - public ListChooser(ComboBoxModel model, NodeSelector nodeSelector) { - this(new NonCachingComboBoxModel(model), nodeSelector); - } - - public ListChooser(CachingComboBoxModel model, NodeSelector nodeSelector) { - super(model); - this.initialize(); - this.nodeSelector = nodeSelector; - } - // **************** Initialization **************************************** - - protected void initialize() { - this.addPopupMenuListener(this.buildPopupMenuListener()); - this.setRenderer(new DefaultListCellRenderer()); - this.addKeyListener(buildF3KeyListener()); - - //These are used to workaround problems with Swing trying to - //determine the size of a comboBox with a large model - setPrototypeDisplayValue(prototypeLabel); - listBox().setPrototypeCellValue(prototypeLabel); - } - - - private JList listBox() { - return (JList) ReflectionTools.getFieldValue(this.ui, "listBox"); //$NON-NLS-1$ - } - - /** - * When the popup is about to be shown, the event is consumed, and - * PopupHandler determines whether to reshow the popup or to show - * the long list browser. - */ - private PopupMenuListener buildPopupMenuListener() { - return new PopupMenuListener() { - public void popupMenuWillBecomeVisible(PopupMenuEvent e) { - ListChooser.this.aboutToShowPopup(); - } - public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { - // do nothing - } - public void popupMenuCanceled(PopupMenuEvent e) { - // do nothing - } - @Override - public String toString() { - return "pop-up menu listener"; //$NON-NLS-1$ - } - }; - } - - /** - * If this code is being reached due to the PopupHandler already being in progress, - * then do nothing. Otherwise, set the flag to true and launch the PopupHandler. - */ - void aboutToShowPopup() { - if (this.popupAlreadyInProgress) { - return; - } - - this.popupAlreadyInProgress = true; - EventQueue.invokeLater(new PopupHandler()); - } - - - private KeyListener buildF3KeyListener() { - return new KeyAdapter() { - @Override - public void keyPressed(KeyEvent e) { - if (e.getKeyCode() == KeyEvent.VK_F3) { - goToSelectedItem(); - } - } - @Override - public String toString() { - return "F3 key listener"; //$NON-NLS-1$ - } - }; - } - - public void goToSelectedItem() { - if (getSelectedItem() != null) { - ListChooser.this.nodeSelector.selectNodeFor(getSelectedItem()); - } - } - - // **************** Browsing ********************************************** - - /** - * Lazily initialize because subclasses may have further initialization to do - * before browser can be built. - */ - protected void browse() { - if (this.browser == null) { - this.browser = this.buildBrowser(); - } - - this.browser.browse(this); - } - - /** - * Return the "browser" used to make a selection from the long list, - * typically via a dialog. - */ - protected ListChooser.ListBrowser buildBrowser() { - return new SimpleListBrowser(); - } - - - // **************** Choosable functionality ******************************* - - /** override behavior - consume selection if chooser is not choosable */ - @Override - public void setSelectedIndex(int anIndex) { - if (this.choosable) { - super.setSelectedIndex(anIndex); - } - } - - private void updateArrowButton() { - try { - BasicComboBoxUI comboBoxUi = (BasicComboBoxUI) ListChooser.this.getUI(); - JButton arrowButton = (JButton) ReflectionTools.getFieldValue(comboBoxUi, "arrowButton"); //$NON-NLS-1$ - arrowButton.setEnabled(this.isEnabled() && this.choosable); - } - catch (Exception e) { - // this is a huge hack to try and make the combo box look right, - // so if it doesn't work, just swallow the exception - } - } - - - // **************** List Caching ******************************* - - void cacheList() { - ((CachingComboBoxModel) getModel()).cacheList(); - } - - void uncacheList() { - ((CachingComboBoxModel) getModel()).uncacheList(); - } - - boolean listIsCached() { - return ((CachingComboBoxModel) getModel()).isCached(); - } - - // **************** Public ************************************************ - - public int longListSize() { - return this.longListSize; - } - - public void setLongListSize(int newLongListSize) { - int oldLongListSize = this.longListSize; - this.longListSize = newLongListSize; - this.firePropertyChange(LONG_LIST_SIZE_PROPERTY, oldLongListSize, newLongListSize); - } - - public boolean isChoosable() { - return this.choosable; - } - - public void setChoosable(boolean newValue) { - boolean oldValue = this.choosable; - this.choosable = newValue; - this.firePropertyChange(CHOOSABLE_PROPERTY, oldValue, newValue); - this.updateArrowButton(); - } - - // **************** Handle selecting null as a value ********************** - - private boolean selectedIndexIsNoneSelectedItem(int index) { - return index == -1 && - getModel().getSize() > 0 && - getModel().getElementAt(0) == null; - } - - @Override - public int getSelectedIndex() { - boolean listNotCached = !listIsCached(); - if (listNotCached) { - cacheList(); - } - - int index = super.getSelectedIndex(); - - // Use index 0 to show the <none selected> item since the actual value is - // null and JComboBox does not handle null values - if (selectedIndexIsNoneSelectedItem(index)) { - index = 0; - } - - if (listNotCached) { - uncacheList(); - } - return index; - } - - //wrap the renderer to deal with the prototypeDisplayValue - @Override - public void setRenderer(final ListCellRenderer aRenderer) { - super.setRenderer(new ListCellRenderer(){ - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - if (value == prototypeLabel) { - return prototypeLabel; - } - return aRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - } - }); - } - - - // **************** Member classes **************************************** - - /** - * Define the API required by this ListChooser when it must - * prompt the user to select an item from the "long" list. - */ - public interface ListBrowser - { - /** - * Prompt the user to make a selection from the specified - * combo-box's model. - */ - void browse(ListChooser parentChooser); - } - - - /** - * Runnable class that consumes popup window and determines whether - * to reshow popup or to launch browser, based on the size of the list. - */ - private class PopupHandler - implements Runnable - { - /** The mouse event */ - private MouseEvent lastMouseEvent; - - /** The component from which the last mouse event was thrown */ - private JComponent eventComponent; - - /** The location of the component at the time the last mouse event was thrown */ - private Point componentLocation; - - /** The location of the mouse at the time the last mouse event was thrown */ - private Point mouseLocation; - - - PopupHandler() { - this.initialize(); - } - - private void initialize() { - AWTEvent event = EventQueue.getCurrentEvent(); - - if (event instanceof MouseEvent) { - this.lastMouseEvent = (MouseEvent) event; - this.eventComponent = (JComponent) this.lastMouseEvent.getSource(); - this.componentLocation = this.eventComponent.getLocationOnScreen(); - this.mouseLocation = this.lastMouseEvent.getPoint(); - } - else { - this.eventComponent = null; - this.componentLocation = null; - this.mouseLocation = null; - } - } - - public void run() { - ListChooser.this.hidePopup(); - - cacheList(); - if (ListChooser.this.choosable == true) { - // If the combo box model is of sufficient length, the browser will be shown. - // Asking the combo box model for its size should be enough to ensure that - // its size is recalculated. - if (ListChooser.this.getModel().getSize() > ListChooser.this.longListSize) { - this.checkComboBoxButton(); - ListChooser.this.browse(); - } - else { - ListChooser.this.showPopup(); - this.checkMousePosition(); - } - } - if (listIsCached()) { - uncacheList(); - } - - ListChooser.this.popupAlreadyInProgress = false; - } - - /** If this is not done, the button never becomes un-pressed */ - private void checkComboBoxButton() { - try { - BasicComboBoxUI comboBoxUi = (BasicComboBoxUI) ListChooser.this.getUI(); - JButton arrowButton = (JButton) ReflectionTools.getFieldValue(comboBoxUi, "arrowButton"); //$NON-NLS-1$ - arrowButton.getModel().setPressed(false); - } - catch (Exception ex) { - // this is a huge hack to try and make the combo box look right, - // so if it doesn't work, just swallow the exception - this.handleException(ex); - } - } - - private void handleException(@SuppressWarnings("unused") Exception ex) { - // do nothing for now - } - - /** - * Moves the mouse back to its original position before any jiggery pokery that we've done. - */ - private void checkMousePosition() { - if (this.eventComponent == null) { - return; - } - - final Point newComponentLocation = this.eventComponent.getLocationOnScreen(); - boolean componentMoved = - newComponentLocation.x - this.componentLocation.x != 0 - || newComponentLocation.y - this.componentLocation.y != 0; - - if (componentMoved) { - try { - new Robot().mouseMove( - newComponentLocation.x + this.mouseLocation.x, - newComponentLocation.y + this.mouseLocation.y - ); - } - catch (AWTException ex) { - // move failed - do nothing - } - } - } - } -} |