home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 November
/
Chip_1998-11_cd.bin
/
tema
/
Cafe
/
jfc.bin
/
BasicComboBoxUI.java
< prev
next >
Wrap
Text File
|
1998-02-26
|
37KB
|
1,016 lines
/*
* @(#)BasicComboBoxUI.java 1.63 98/02/02
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of Sun
* Microsystems, Inc. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Sun.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.sun.java.swing.plaf.basic;
import java.awt.*;
import java.awt.event.*;
import com.sun.java.swing.*;
import com.sun.java.swing.FocusManager;
import com.sun.java.swing.plaf.*;
import com.sun.java.swing.border.*;
import java.io.Serializable;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
/**
* Basic UI for JComboBox
* <p>
* Warning: 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 Swing1.0 applications. It will
* not be possible to load serialized Swing1.0 objects with future releases
* of Swing. The JDK1.2 release of Swing will be the compatibility
* baseline for the serialized form of Swing objects.
*
* @version 1.63 02/02/98
* @author Arnaud Weber
*/
public class BasicComboBoxUI
extends ComboBoxUI
implements
LayoutManager, MouseListener, MouseMotionListener, ItemListener,
FocusListener, KeyListener, PropertyChangeListener, Serializable
{
protected final static Color selectionBackgroundColor = new Color(0,0,128);
protected static final int BORDER_THICKNESS = 2;
protected JComboBox comboBox;
protected CellRendererPane currentValuePane = new CellRendererPane();
protected JButton arrowButton;
protected Component editor;
protected JPopupMenu menu;
protected JList listBox = null;
protected JScrollPane scrollPane;
protected Timer autoscrollTimer;
protected Point lastMouseLocation;
protected static JComboBox showingComboBox = null;
/** Location of the comboBox last time it was popped up (showPopup). */
protected Point popupLocation;
protected boolean hasFocus = false;
public static ComponentUI createUI(JComponent c) {
return new BasicComboBoxUI();
}
public void installUI(JComponent c) {
comboBox = (JComboBox)c;
addArrowButton();
comboBox.add(currentValuePane);
comboBox.setLayout(this);
comboBox.addItemListener(this);
comboBox.addFocusListener(this);
comboBox.addMouseListener(this);
comboBox.addMouseMotionListener(this);
comboBox.addKeyListener(this);
comboBox.addPropertyChangeListener(this);
if(comboBox.getRenderer() == null)
comboBox.setRenderer((ListCellRenderer)(UIManager.get("ComboBox.renderer")));
editablePropertyChanged();
addKeyAccelerators(comboBox);
configureComboBox();
}
public void uninstallUI(JComponent c) {
hidePopup();
removeEditor();
removeArrowButton();
comboBox.setLayout(null);
comboBox.removeFocusListener(this);
if(listBox != null) {
listBox.removeMouseListener(this);
listBox.removeMouseMotionListener(this);
}
comboBox.removeItemListener(this);
comboBox.removeMouseListener(this);
comboBox.removeMouseMotionListener(this);
comboBox.removeKeyListener(this);
comboBox.resetKeyboardActions();
comboBox.remove(currentValuePane);
comboBox.removePropertyChangeListener(this);
if(comboBox.getRenderer() instanceof UIResource)
comboBox.setRenderer(null);
if(comboBox.getEditor() instanceof UIResource)
comboBox.setEditor(null);
comboBox = null;
unconfigureComboBox();
}
public boolean isFocusTraversable() {
return !comboBox.isEditable();
}
protected void configureComboBox() {
LookAndFeel.installColorsAndFont(comboBox,"ComboBox.background","ComboBox.foreground",
"ComboBox.font");
}
protected void unconfigureComboBox() {
}
public void editablePropertyChanged() {
if(comboBox.isEditable())
addEditor();
else
removeEditor();
}
public void enablePropertyChanged() {
boolean cbIsEnabled = comboBox.isEnabled();
if(cbIsEnabled) {
if(editor != null)
editor.setEnabled(true);
if(arrowButton != null)
arrowButton.setEnabled(true);
} else {
if(editor != null)
editor.setEnabled(false);
if(arrowButton != null)
arrowButton.setEnabled(false);
}
comboBox.repaint();
}
public void addEditor() {
if(editor != null)
removeEditor();
if(comboBox.getEditor() == null)
comboBox.setEditor((ComboBoxEditor)(UIManager.get("ComboBox.editor")));
editor = comboBox.getEditor().getEditorComponent();
comboBox.add(editor);
editor.setFont(comboBox.getFont());
editor.setBackground(comboBox.getBackground());
editor.setForeground(comboBox.getForeground());
comboBox.configureEditor(comboBox.getEditor(),comboBox.getSelectedItem());
}
public void removeEditor() {
if(editor != null) {
comboBox.remove(editor);
editor=null;
}
}
public void addArrowButton() {
arrowButton = createArrowButton();
arrowButton.setRequestFocusEnabled(false);
arrowButton.addMouseListener(this);
arrowButton.addMouseMotionListener(this);
arrowButton.resetKeyboardActions();
comboBox.add(arrowButton);
}
public void removeArrowButton() {
if(arrowButton != null) {
comboBox.remove(arrowButton);
arrowButton.removeMouseListener(this);
arrowButton.removeMouseMotionListener(this);
arrowButton = null;
}
}
protected JList createListBox(ComboBoxModel aModel) {
return new JList(aModel);
}
public JList getList() {
return listBox;
}
protected JButton createArrowButton() {
return new BasicArrowButton(BasicArrowButton.SOUTH);
}
public void paint(Graphics g, JComponent c) {
Rectangle b = c.getBounds();
BasicGraphicsUtils.drawEtchedRect(g,0,0,b.width,b.height);
boolean hasFocus = comboBox.hasFocus();
if(!comboBox.isEditable()) {
Rectangle r = rectangleForCurrentValue();
paintCurrentValueBackground(g,r,hasFocus);
paintCurrentValue(g,r,hasFocus);
}
}
public void paintCurrentValue(Graphics g,Rectangle bounds,boolean hasFocus) {
ListCellRenderer renderer = comboBox.getRenderer();
Component c;
validateMenu();
if(hasFocus && !popupIsVisible()) {
c = renderer.getListCellRendererComponent(listBox, comboBox.getSelectedItem(), -1, true, false);
} else {
c = renderer.getListCellRendererComponent(listBox, comboBox.getSelectedItem(), -1, false, false);
c.setBackground(UIManager.getColor("ComboBox.background"));
}
c.setFont(comboBox.getFont());
if(hasFocus && !popupIsVisible()) {
c.setForeground(listBox.getSelectionForeground());
c.setBackground(listBox.getSelectionBackground());
} else {
if(comboBox.isEnabled()) {
c.setForeground(comboBox.getForeground());
c.setBackground(comboBox.getBackground());
} else {
c.setForeground(UIManager.getColor("ComboBox.disabledForeground"));
c.setBackground(UIManager.getColor("ComboBox.disabledBackground"));
}
}
currentValuePane.paintComponent(g,c,comboBox,bounds.x,bounds.y,
bounds.width,bounds.height);
}
public void paintCurrentValueBackground(Graphics g,Rectangle bounds,boolean hasFocus) {
Color t = g.getColor();
if(comboBox.isEnabled())
g.setColor(UIManager.getColor("ComboBox.background"));
else
g.setColor(UIManager.getColor("ComboBox.disabledBackground"));
g.fillRect(bounds.x,bounds.y,bounds.width,bounds.height);
g.setColor(t);
}
/** Return the dimension the the combo box should have if by default
* if there is no current value and no value in the list of possible
* values
*/
protected Dimension getDefaultSize() {
return new Dimension(100,20);
}
protected Dimension getMaxPreferredSize() {
int i,c;
Dimension result = new Dimension();
ListCellRenderer renderer = comboBox.getRenderer();
ComboBoxModel model = comboBox.getModel();
Component cpn;
Dimension d;
validateMenu();
if(renderer != null && model.getSize() > 0) {
for(i=0,c=model.getSize();i<c;i++) {
cpn = renderer.getListCellRendererComponent(listBox, model.getElementAt(i),-1, false, false);
currentValuePane.add(cpn);
cpn.setFont(comboBox.getFont());
d = cpn.getPreferredSize();
currentValuePane.remove(cpn);
result.width = Math.max(result.width,d.width);
result.height = Math.max(result.height,d.height);
}
if(comboBox.isEditable()) {
d = editor.getPreferredSize();
result.width = Math.max(result.width,d.width);
result.height = Math.max(result.height,d.height);
}
return result;
} else
return getDefaultSize();
}
protected Dimension getMaxMinimumSize() {
int i,c;
Dimension result = new Dimension();
ListCellRenderer renderer = comboBox.getRenderer();
ComboBoxModel model = comboBox.getModel();
Component cpn;
Dimension d;
validateMenu();
if(renderer != null && model.getSize() > 0) {
for(i=0,c=model.getSize();i<c;i++) {
cpn = renderer.getListCellRendererComponent(listBox, model.getElementAt(i),-1, false, false);
currentValuePane.add(cpn);
cpn.setFont(comboBox.getFont());
d = cpn.getMinimumSize();
currentValuePane.remove(cpn);
result.width = Math.max(result.width,d.width);
result.height = Math.max(result.height,d.height);
}
if(comboBox.isEditable()) {
d = editor.getMinimumSize();
result.width = Math.max(result.width,d.width);
result.height = Math.max(result.height,d.height);
}
return result;
} else
return getDefaultSize();
}
protected Dimension getMaxMaximumSize() {
int i,c;
Dimension result = new Dimension();
ListCellRenderer renderer = comboBox.getRenderer();
ComboBoxModel model = comboBox.getModel();
Component cpn;
Dimension d;
validateMenu();
if(renderer != null && model.getSize() > 0) {
for(i=0,c=model.getSize();i<c;i++) {
cpn = renderer.getListCellRendererComponent(listBox, model.getElementAt(i),-1, false, false);
currentValuePane.add(cpn);
cpn.setFont(comboBox.getFont());
d = cpn.getMaximumSize();
currentValuePane.remove(cpn);
result.width = Math.max(result.width,d.width);
result.height = Math.max(result.height,d.height);
}
if(comboBox.isEditable()) {
d = editor.getMaximumSize();
result.width = Math.max(result.width,d.width);
result.height = Math.max(result.height,d.height);
}
return result;
} else
return getDefaultSize();
}
public Dimension getPreferredSize(JComponent c) {
Dimension dim;
int buttonSize;
dim = getMaxPreferredSize();
dim.height += (2*BORDER_THICKNESS);
buttonSize = dim.height - (2*BORDER_THICKNESS);
dim.width += ((2*BORDER_THICKNESS) + buttonSize);
return dim;
}
public Dimension getMinimumSize(JComponent c) {
Dimension dim;
int buttonSize;
dim = getMaxMinimumSize();
dim.height += (2*BORDER_THICKNESS);
buttonSize = dim.height - (2*BORDER_THICKNESS);
dim.width += ((2*BORDER_THICKNESS) + buttonSize);
return dim;
}
public Dimension getMaximumSize(JComponent c) {
Dimension dim;
dim = getMaxMaximumSize();
dim.height += (2*BORDER_THICKNESS);
dim.width = Short.MAX_VALUE;
return dim;
}
public void addLayoutComponent(String name, Component comp) {}
public void removeLayoutComponent(Component comp) {}
public Dimension preferredLayoutSize(Container parent) {
JComboBox cb = (JComboBox)parent;
return parent.getPreferredSize();
}
public Dimension minimumLayoutSize(Container parent) {
JComboBox cb = (JComboBox)parent;
return parent.getMinimumSize();
}
protected Rectangle rectangleForCurrentValue() {
Dimension cbSize = comboBox.getSize();
int buttonSize = cbSize.height - (2*BORDER_THICKNESS);
return new Rectangle(BORDER_THICKNESS,BORDER_THICKNESS,
cbSize.width - (2*BORDER_THICKNESS) - buttonSize,
cbSize.height - (2*BORDER_THICKNESS));
}
public void layoutContainer(Container parent) {
JComboBox cb = (JComboBox)parent;
Dimension cbSize = cb.getSize();
int buttonSize = cbSize.height - (2*BORDER_THICKNESS);
Rectangle cvb;
if(editor != null){
cvb = rectangleForCurrentValue();
editor.setBounds(cvb);
}
if(arrowButton != null)
arrowButton.setBounds(BORDER_THICKNESS + cbSize.width - (2*BORDER_THICKNESS) - buttonSize,
BORDER_THICKNESS,
buttonSize,buttonSize);
}
public void itemStateChanged(ItemEvent e) {
ComboBoxModel model = comboBox.getModel();
Object v = model.getSelectedItem();
if(editor != null)
comboBox.configureEditor(comboBox.getEditor(),v);
else {
Rectangle r = rectangleForCurrentValue();
comboBox.repaint(0,r.x,r.y,r.width,r.height);
}
if(popupIsVisible())
updateListBoxSelection();
}
public void focusGained(FocusEvent e) {
if(!comboBox.isEditable()) {
repaintCurrentValue();
hasFocus = true;
}
}
public void focusLost(FocusEvent e) {
if(!comboBox.isEditable()) {
repaintCurrentValue();
hasFocus = false;
}
}
public void propertyChange(PropertyChangeEvent e) {
String propertyName = e.getPropertyName();
if (propertyName.equals("model")) {
if(listBox != null) {
listBox.setModel(comboBox.getModel());
if(popupIsVisible())
hidePopup();
}
}
}
void repaintCurrentValue() {
Rectangle r = rectangleForCurrentValue();
comboBox.repaint(r.x,r.y,r.width,r.height);
}
public void mouseClicked(MouseEvent anEvent) {}
public void mouseEntered(MouseEvent anEvent) {}
public void mouseExited(MouseEvent anEvent) {}
public void mouseReleased(MouseEvent anEvent) {
Object sv;
stopAutoscrolling();
if(popupIsVisible()) {
if(anEvent.getSource() == listBox) {
updateListBoxSelectionForEvent(anEvent,true); /** Just make sure ...**/
comboBox.getModel().setSelectedItem(listBox.getSelectedValue());
hidePopup();
} else if(anEvent.getSource() == arrowButton &&
!(SwingUtilities.getLocalBounds(arrowButton).contains(anEvent.getPoint()))) {
MouseEvent tmp = convertEventToListBox(anEvent);
updateListBoxSelectionForEvent(tmp,true);
sv = listBox.getSelectedValue();
if(sv != null)
comboBox.getModel().setSelectedItem(sv);
hidePopup();
} else if(anEvent.getSource() == comboBox &&
!(SwingUtilities.getLocalBounds(comboBox).contains(anEvent.getPoint()))) {
MouseEvent tmp = convertEventToListBox(anEvent);
updateListBoxSelectionForEvent(tmp,true);
sv = listBox.getSelectedValue();
if(sv != null)
comboBox.getModel().setSelectedItem(sv);
hidePopup();
}
}
}
protected boolean shouldActivatePopupForEvent(MouseEvent anEvent) {
Rectangle r = rectangleForCurrentValue();
if(r.contains(anEvent.getPoint()))
return true;
else
return false;
}
public void mousePressed(MouseEvent anEvent) {
Rectangle r;
if(!SwingUtilities.isLeftMouseButton(anEvent))
return;
if(!comboBox.isEnabled())
return;
if(anEvent.getSource() == arrowButton) {
r = SwingUtilities.getLocalBounds(arrowButton);
if(r.contains(anEvent.getX(),anEvent.getY())) {
if(popupIsVisible())
hidePopup();
else
showPopup();
}
} else if(anEvent.getSource() == comboBox) {
if(shouldActivatePopupForEvent(anEvent)) {
if(popupIsVisible())
hidePopup();
else
showPopup();
}
}
}
public void mouseDragged(MouseEvent anEvent) {
Window sourceWindow;
if(popupIsVisible()) {
if((anEvent.getSource() == arrowButton &&
!(SwingUtilities.getLocalBounds(arrowButton).contains(anEvent.getPoint()))) ||
(anEvent.getSource() == comboBox &&
!(SwingUtilities.getLocalBounds(comboBox).contains(anEvent.getPoint())))) {
MouseEvent tmp = convertEventToListBox(anEvent);
updateListBoxSelectionForEvent(tmp,true);
lastMouseLocation = SwingUtilities.convertPoint((Component)anEvent.getSource(),anEvent.getPoint(),null);
sourceWindow = SwingUtilities.windowForComponent((Component)anEvent.getSource());
lastMouseLocation.x += sourceWindow.getBounds().x;
lastMouseLocation.y += sourceWindow.getBounds().y;
startAutoscrolling();
}
}
}
public void mouseMoved(MouseEvent anEvent) {
Object source = anEvent.getSource();
if(popupIsVisible() && source == listBox) {
Point location = anEvent.getPoint();
Rectangle r = new Rectangle();
listBox.computeVisibleRect(r);
if(r.contains(location))
updateListBoxSelectionForEvent(anEvent,false);
}
}
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
public void keyPressed(KeyEvent e) {
if(e.getSource() == comboBox && !comboBox.isEditable() ||
e.getSource() == listBox && !comboBox.isEditable()) {
if(comboBox.selectWithKeyChar(e.getKeyChar()))
e.consume();
}
}
public void validateMenu() {
if(menu == null) {
menu = new JPopupMenu();
menu.setLayout(new BoxLayout(menu,BoxLayout.Y_AXIS));
menu.setBorderPainted(true);
menu.setBorder(BorderFactory.createLineBorder(Color.black));
menu.setOpaque(false);
listBox = createListBox(comboBox.getModel());
listBox.setRequestFocusEnabled(false);
listBox.setBorder(null);
listBox.setCellRenderer(comboBox.getRenderer());
listBox.addMouseListener(this);
listBox.addMouseMotionListener(this);
listBox.addKeyListener(this);
listBox.setBorder(null);
scrollPane = new JScrollPane(listBox,ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setRequestFocusEnabled(false);
scrollPane.getVerticalScrollBar().setRequestFocusEnabled(false);
scrollPane.setBorder(null);
menu.add(scrollPane);
menu.setDoubleBuffered(true);
menu.registerKeyboardAction(new AbstractAction() {
public void actionPerformed(ActionEvent e) {
hidePopup();
}
public boolean isEnabled() {
return true;
}
},KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0),JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
menu.registerKeyboardAction(new AbstractAction() {
public void actionPerformed(ActionEvent e) {
hidePopup();
}
public boolean isEnabled() {
return true;
}
},KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
addKeyAccelerators(menu);
}
}
private Dialog getDialog() {
Container parent;
for(parent = comboBox.getParent() ; parent != null && !(parent instanceof Dialog)
&& !(parent instanceof Window) ; parent = parent.getParent());
if(parent instanceof Dialog)
return (Dialog) parent;
else
return null;
}
private boolean inModalDialog() {
return (getDialog() != null);
}
protected Rectangle computePopupBounds(int px,int py,int pw,int ph) {
Rectangle absBounds;
Rectangle r = new Rectangle(px,py,pw,ph);
boolean inModalDialog = inModalDialog();
/** Workaround for modal dialogs. See also JPopupMenu.java **/
if(inModalDialog) {
Dialog dlg = getDialog();
Point p;
if(dlg instanceof JDialog) {
JRootPane rp = ((JDialog)dlg).getRootPane();
p = rp.getLocationOnScreen();
absBounds = rp.getBounds();
absBounds.x = p.x;
absBounds.y = p.y;
} else
absBounds = dlg.getBounds();
p = new Point(absBounds.x,absBounds.y);
SwingUtilities.convertPointFromScreen(p,comboBox);
absBounds.x = p.x;
absBounds.y = p.y;
} else {
Point p;
Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize();
absBounds = new Rectangle();
p = new Point(0,0);
SwingUtilities.convertPointFromScreen(p,comboBox);
absBounds.x = p.x;
absBounds.y = p.y;
absBounds.width = scrSize.width;
absBounds.height= scrSize.height;
}
if(SwingUtilities.isRectangleContainingRectangle(absBounds,r))
return r;
else {
Rectangle r2 = new Rectangle(0,-r.height,r.width,r.height);
if(SwingUtilities.isRectangleContainingRectangle(absBounds,r2))
return r2;
if(inModalDialog) {
SwingUtilities.computeIntersection(absBounds.x,absBounds.y,absBounds.width,absBounds.height,r);
SwingUtilities.computeIntersection(absBounds.x,absBounds.y,absBounds.width,absBounds.height,r2);
if(r.height > r2.height)
return r;
else
return r2;
} else
return r2;
}
}
public void showPopup() {
Border border;
Dimension ds,popupSize;
Rectangle cbBounds = comboBox.getBounds();
Rectangle popupBounds;
popupLocation = new Point(cbBounds.x, cbBounds.y);
if(showingComboBox != null && showingComboBox != comboBox) {
showingComboBox.getUI().hidePopup();
showingComboBox = null;
}
validateMenu();
comboBox.requestFocus();
setupListBox(listBox, comboBox);
popupSize = new Dimension(cbBounds.width,
getPopupHeightForRowCount(comboBox.getMaximumRowCount()));
border = menu.getBorder();
if(border != null) {
Insets in = border.getBorderInsets(menu);
popupSize.width -= (in.left + in.right);
popupSize.height -= (in.top + in.bottom);
}
updateListBoxSelection();
listBox.invalidate();
popupBounds = computePopupBounds(0,comboBox.getBounds().height,popupSize.width,popupSize.height);
popupSize.width = popupBounds.width;
popupSize.height= popupBounds.height;
scrollPane.setMaximumSize(popupSize);
scrollPane.setPreferredSize(popupSize);
scrollPane.setMinimumSize(popupSize);
menu.setLightWeightPopupEnabled(comboBox.isLightWeightPopupEnabled());
menu.show(comboBox,popupBounds.x,popupBounds.y);
menu.repaint();
comboBox.registerKeyboardAction(new AbstractAction() {
public void actionPerformed(ActionEvent e) {
hidePopup();
}
public boolean isEnabled() {
return true;
}
},KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0),JComponent.WHEN_IN_FOCUSED_WINDOW);
comboBox.registerKeyboardAction(new AbstractAction() {
public void actionPerformed(ActionEvent e) {
hidePopup();
}
public boolean isEnabled() {
return true;
}
},KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),JComponent.WHEN_IN_FOCUSED_WINDOW);
repaintCurrentValue();
listBox.requestFocus();
showingComboBox = comboBox;
}
protected void setupListBox(JList listBox, JComboBox comboBox) {
listBox.setFont(comboBox.getFont());
listBox.setForeground(comboBox.getForeground());
listBox.setBackground(comboBox.getBackground());
}
public void hidePopup() {
if(menu == null || listBox == null)
return;
if(!popupIsVisible())
return;
menu.setVisible(false);
requestFocusLater();
comboBox.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0));
comboBox.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0));
}
protected void requestFocusLater() {
if(comboBox.isEditable()) {
requestFocusLaterForComponent(comboBox.getEditor().getEditorComponent());
} else {
requestFocusLaterForComponent(comboBox);
repaintCurrentValue();
}
}
protected int getPopupHeightForRowCount(int maxRowCount) {
int currentElementCount = comboBox.getModel().getSize();
if(currentElementCount > 0) {
Rectangle r = listBox.getCellBounds(0,0);
/** listbox returns a wrong height the first time. Remove this hack when
* listbox will be fixed
*/
if(r.height <=2)
r.height = 17;
/** End hack **/
if(maxRowCount < currentElementCount)
return (r.height * maxRowCount) + 2;
else
return (r.height * currentElementCount) + 2;
} else
return 100;
}
public boolean popupIsVisible() {
if(menu == null)
return false;
else {
validateMenu();
return menu.isVisible();
}
}
public void maximumRowCountChanged() {
if(popupIsVisible()) {
hidePopup();
showPopup();
}
}
protected void updateListBoxSelection() {
Object sObject = comboBox.getModel().getSelectedItem();
if(sObject == null && listBox != null) {
listBox.setSelectedIndex(-1);
return;
}
listBox.setSelectedValue(sObject,true);
}
protected void startAutoscrolling() {
if(autoscrollTimer == null)
autoscrollTimer = new Timer(100,new AbstractAction() {
public void actionPerformed(ActionEvent e) {
autoscroll();
}
public boolean isEnabled() {
return true;
}
});
autoscrollTimer.start();
}
protected void stopAutoscrolling() {
if(autoscrollTimer != null)
autoscrollTimer.stop();
lastMouseLocation = null;
}
protected void autoscroll() {
if(listBox == null)
return;
Window win = SwingUtilities.windowForComponent(listBox);
if(lastMouseLocation != null && win != null) {
Point tmp = new Point(lastMouseLocation.x - win.getBounds().x,
lastMouseLocation.y - win.getBounds().y);
tmp = SwingUtilities.convertPoint(null,tmp,listBox);
int index = listBox.locationToIndex(tmp);
if(index == -1) {
if(tmp.y < 0)
index = 0;
else
index = comboBox.getModel().getSize() - 1;
}
listBox.setSelectedIndex(index);
listBox.ensureIndexIsVisible(index);
}
}
protected void updateListBoxSelectionForEvent(MouseEvent anEvent,boolean shouldScroll) {
Point location = anEvent.getPoint();
if(listBox == null)
return;
int index = listBox.locationToIndex(location);
if(index == -1) {
if(location.y < 0)
index = 0;
else
index = comboBox.getModel().getSize() - 1;
}
listBox.setSelectedIndex(index);
if(shouldScroll)
listBox.ensureIndexIsVisible(index);
}
protected void selectNextPossibleValue() {
int si;
validateMenu();
if(popupIsVisible())
si = listBox.getSelectedIndex();
else
si = comboBox.getSelectedIndex();
if(si < comboBox.getModel().getSize() - 1)
comboBox.setSelectedIndex(si+1);
}
protected void selectPreviousPossibleValue() {
int si;
validateMenu();
if(popupIsVisible())
si = listBox.getSelectedIndex();
else
si = comboBox.getSelectedIndex();
if(si > 0)
comboBox.setSelectedIndex(si-1);
}
protected void toggleOpenClose() {
if(popupIsVisible())
hidePopup();
else
showPopup();
}
protected MouseEvent convertEventToListBox(MouseEvent anEvent) {
Rectangle bo;
Window sourceWindow,destWindow;
MouseEvent tmp = SwingUtilities.convertMouseEvent((Component)anEvent.getSource(),anEvent,null);
sourceWindow = SwingUtilities.windowForComponent((Component)anEvent.getSource());
bo = sourceWindow.getBounds();
tmp.translatePoint(bo.x,bo.y);
destWindow = SwingUtilities.windowForComponent(listBox);
bo = destWindow.getBounds();
tmp.translatePoint(-bo.x,-bo.y);
tmp = SwingUtilities.convertMouseEvent(null,tmp,listBox);
return tmp;
}
protected void addKeyAccelerators(JComponent comp) {
comp.registerKeyboardAction(
new AbstractAction() {
public void actionPerformed(ActionEvent e) {
selectNextPossibleValue();
}
public boolean isEnabled() {
return comboBox.isEnabled();
}
},KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,0),JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
comp.registerKeyboardAction(
new AbstractAction() {
public void actionPerformed(ActionEvent e) {
selectPreviousPossibleValue();
}
public boolean isEnabled() {
return comboBox.isEnabled();
}
},KeyStroke.getKeyStroke(KeyEvent.VK_UP,0),JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
comp.registerKeyboardAction(
new AbstractAction() {
public void actionPerformed(ActionEvent e) {
toggleOpenClose();
}
public boolean isEnabled() {
return comboBox.isEnabled();
}
},KeyStroke.getKeyStroke(KeyEvent.VK_UP,InputEvent.ALT_MASK),JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
comp.registerKeyboardAction(
new AbstractAction() {
public void actionPerformed(ActionEvent e) {
toggleOpenClose();
}
public boolean isEnabled() {
return comboBox.isEnabled();
}
},KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,InputEvent.ALT_MASK),JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
}
protected void removeKeyAccelerators(JComponent comp) {
comp.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,0));
comp.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_UP,0));
comp.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN,InputEvent.ALT_MASK));
comp.unregisterKeyboardAction(KeyStroke.getKeyStroke(KeyEvent.VK_UP,InputEvent.ALT_MASK));
}
protected static void requestFocusLaterForComponent(Component c) {
new FocusRequestHelper(c);
}
static class FocusRequestHelper implements WindowListener,ActionListener, Serializable {
Window window;
Component component;
Timer timer;
FocusRequestHelper(Component c) {
window = null;
component = c;
for(Container p = c.getParent() ; p != null ; p = p.getParent())
if(p instanceof Window) {
window = (Window)p;
break;
}
if(window == null)
return;
else
window.addWindowListener(this);
}
public void windowOpened(WindowEvent e){}
public void windowClosing(WindowEvent e){}
public void windowClosed(WindowEvent e){ window.removeWindowListener(this);}
public void windowIconified(WindowEvent e){}
public void windowDeiconified(WindowEvent e){}
public void windowActivated(WindowEvent e){
window.removeWindowListener(this);
startTimer();
}
public void windowDeactivated(WindowEvent e){}
void startTimer() {
timer = new Timer(20,this);
timer.start();
}
public void actionPerformed(ActionEvent e) {
if (timer != null) {
timer.stop();
}
if (component != null) {
component.requestFocus();
}
component = null;
timer = null;
window = null;
}
}
}