149 |
* Popup list containing the combo box's menu items. |
* Popup list containing the combo box's menu items. |
150 |
*/ |
*/ |
151 |
protected ComboPopup popup; |
protected ComboPopup popup; |
152 |
|
|
153 |
protected KeyListener popupKeyListener; |
protected KeyListener popupKeyListener; |
154 |
|
|
155 |
protected MouseListener popupMouseListener; |
protected MouseListener popupMouseListener; |
156 |
|
|
157 |
protected MouseMotionListener popupMouseMotionListener; |
protected MouseMotionListener popupMouseMotionListener; |
158 |
|
|
159 |
/** |
/** |
190 |
*/ |
*/ |
191 |
Dimension displaySize; |
Dimension displaySize; |
192 |
|
|
193 |
// FIXME: This fields aren't used anywhere at this moment. |
// FIXME: This field isn't used anywhere at this moment. |
|
protected Dimension cachedMinimumSize; |
|
194 |
protected CellRendererPane currentValuePane; |
protected CellRendererPane currentValuePane; |
195 |
protected boolean isMinimumSizeDirty; |
|
196 |
|
/** |
197 |
|
* The current minimum size if isMinimumSizeDirty is false. |
198 |
|
* Setup by getMinimumSize() and invalidated by the various listeners. |
199 |
|
*/ |
200 |
|
protected Dimension cachedMinimumSize; |
201 |
|
|
202 |
|
/** |
203 |
|
* Indicates whether or not the cachedMinimumSize field is valid or not. |
204 |
|
*/ |
205 |
|
protected boolean isMinimumSizeDirty = true; |
206 |
|
|
207 |
/** |
/** |
208 |
* Creates a new <code>BasicComboBoxUI</code> object. |
* Creates a new <code>BasicComboBoxUI</code> object. |
295 |
|
|
296 |
focusListener = createFocusListener(); |
focusListener = createFocusListener(); |
297 |
comboBox.addFocusListener(focusListener); |
comboBox.addFocusListener(focusListener); |
298 |
|
listBox.addFocusListener(focusListener); |
299 |
|
|
300 |
itemListener = createItemListener(); |
itemListener = createItemListener(); |
301 |
comboBox.addItemListener(itemListener); |
comboBox.addItemListener(itemListener); |
345 |
propertyChangeListener = null; |
propertyChangeListener = null; |
346 |
|
|
347 |
comboBox.removeFocusListener(focusListener); |
comboBox.removeFocusListener(focusListener); |
348 |
|
listBox.removeFocusListener(focusListener); |
349 |
focusListener = null; |
focusListener = null; |
350 |
|
|
351 |
comboBox.removeItemListener(itemListener); |
comboBox.removeItemListener(itemListener); |
494 |
ComboBoxEditor currentEditor = comboBox.getEditor(); |
ComboBoxEditor currentEditor = comboBox.getEditor(); |
495 |
if (currentEditor == null || currentEditor instanceof UIResource) |
if (currentEditor == null || currentEditor instanceof UIResource) |
496 |
{ |
{ |
497 |
comboBox.setEditor(createEditor()); |
currentEditor = createEditor(); |
498 |
editor = comboBox.getEditor().getEditorComponent(); |
comboBox.setEditor(currentEditor); |
499 |
} |
} |
500 |
|
editor = currentEditor.getEditorComponent(); |
501 |
|
|
502 |
comboBox.revalidate(); |
comboBox.revalidate(); |
503 |
} |
} |
624 |
public void setPopupVisible(JComboBox c, boolean v) |
public void setPopupVisible(JComboBox c, boolean v) |
625 |
{ |
{ |
626 |
if (v) |
if (v) |
627 |
popup.show(); |
{ |
628 |
|
popup.show(); |
629 |
|
popup.getList().requestFocus(); |
630 |
|
} |
631 |
else |
else |
632 |
popup.hide(); |
popup.hide(); |
633 |
} |
} |
677 |
|
|
678 |
/** |
/** |
679 |
* Returns the minimum size for this {@link JComboBox} for this |
* Returns the minimum size for this {@link JComboBox} for this |
680 |
* look and feel. |
* look and feel. Also makes sure cachedMinimimSize is setup correctly. |
681 |
* |
* |
682 |
* @param c The {@link JComponent} to find the minimum size for. |
* @param c The {@link JComponent} to find the minimum size for. |
683 |
* |
* |
685 |
*/ |
*/ |
686 |
public Dimension getMinimumSize(JComponent c) |
public Dimension getMinimumSize(JComponent c) |
687 |
{ |
{ |
688 |
Dimension d = getDisplaySize(); |
if (isMinimumSizeDirty) |
689 |
int arrowButtonWidth = d.height; |
{ |
690 |
Dimension result = new Dimension(d.width + arrowButtonWidth, d.height); |
Dimension d = getDisplaySize(); |
691 |
return result; |
int arrowButtonWidth = d.height; |
692 |
|
cachedMinimumSize = new Dimension(d.width + arrowButtonWidth, |
693 |
|
d.height); |
694 |
|
isMinimumSizeDirty = false; |
695 |
|
} |
696 |
|
return new Dimension(cachedMinimumSize); |
697 |
} |
} |
698 |
|
|
699 |
/** The value returned by the getMaximumSize() method. */ |
/** The value returned by the getMaximumSize() method. */ |
819 |
isPressed, hasFocus); |
isPressed, hasFocus); |
820 |
if (! comboBox.isEnabled()) |
if (! comboBox.isEnabled()) |
821 |
{ |
{ |
822 |
comp.setBackground(UIManager.getLookAndFeelDefaults().getColor( |
comp.setBackground(UIManager.getColor( |
823 |
"ComboBox.disabledBackground")); |
"ComboBox.disabledBackground")); |
824 |
comp.setForeground(UIManager.getLookAndFeelDefaults().getColor( |
comp.setForeground(UIManager.getColor( |
825 |
"ComboBox.disabledForeground")); |
"ComboBox.disabledForeground")); |
826 |
comp.setEnabled(false); |
comp.setEnabled(false); |
827 |
} |
} |
828 |
comp.setBounds(0, 0, bounds.width, bounds.height); |
comp.setBounds(0, 0, bounds.width, bounds.height); |
874 |
} |
} |
875 |
|
|
876 |
/** |
/** |
877 |
* Returns size of the largest item in the combo box. This size will be the |
* Returns the size of the display area for the combo box. This size will be |
878 |
* size of the combo box, not including the arrowButton. |
* the size of the combo box, not including the arrowButton. |
879 |
* |
* |
880 |
* @return dimensions of the largest item in the combo box. |
* @return The size of the display area for the combo box. |
881 |
*/ |
*/ |
882 |
protected Dimension getDisplaySize() |
protected Dimension getDisplaySize() |
883 |
{ |
{ |
884 |
Object prototype = comboBox.getPrototypeDisplayValue(); |
if (!comboBox.isEditable()) |
|
if (prototype != null) |
|
885 |
{ |
{ |
886 |
// calculate result based on prototype |
Object prototype = comboBox.getPrototypeDisplayValue(); |
887 |
ListCellRenderer renderer = comboBox.getRenderer(); |
if (prototype != null) |
|
Component comp = renderer.getListCellRendererComponent(listBox, |
|
|
prototype, -1, false, false); |
|
|
Dimension compSize = comp.getPreferredSize(); |
|
|
compSize.width += 2; // add 1 pixel margin around area |
|
|
compSize.height += 2; |
|
|
return compSize; |
|
|
} |
|
|
else |
|
|
{ |
|
|
ComboBoxModel model = comboBox.getModel(); |
|
|
int numItems = model.getSize(); |
|
|
|
|
|
// if combo box doesn't have any items then simply |
|
|
// return its default size |
|
|
if (numItems == 0) |
|
888 |
{ |
{ |
889 |
displaySize = getDefaultSize(); |
// calculate result based on prototype |
890 |
return displaySize; |
ListCellRenderer renderer = comboBox.getRenderer(); |
891 |
|
Component comp = renderer.getListCellRendererComponent(listBox, |
892 |
|
prototype, -1, false, false); |
893 |
|
Dimension compSize = comp.getPreferredSize(); |
894 |
|
compSize.width += 2; // add 1 pixel margin around area |
895 |
|
compSize.height += 2; |
896 |
|
return compSize; |
897 |
} |
} |
898 |
|
else |
|
Dimension size = new Dimension(0, 0); |
|
|
|
|
|
// ComboBox's display size should be equal to the |
|
|
// size of the largest item in the combo box. |
|
|
ListCellRenderer renderer = comboBox.getRenderer(); |
|
|
|
|
|
for (int i = 0; i < numItems; i++) |
|
899 |
{ |
{ |
900 |
Object item = model.getElementAt(i); |
ComboBoxModel model = comboBox.getModel(); |
901 |
Component comp = renderer.getListCellRendererComponent(listBox, |
int numItems = model.getSize(); |
902 |
|
|
903 |
|
// if combo box doesn't have any items then simply |
904 |
|
// return its default size |
905 |
|
if (numItems == 0) |
906 |
|
{ |
907 |
|
displaySize = getDefaultSize(); |
908 |
|
return displaySize; |
909 |
|
} |
910 |
|
|
911 |
|
Dimension size = new Dimension(0, 0); |
912 |
|
|
913 |
|
// ComboBox's display size should be equal to the |
914 |
|
// size of the largest item in the combo box. |
915 |
|
ListCellRenderer renderer = comboBox.getRenderer(); |
916 |
|
|
917 |
|
for (int i = 0; i < numItems; i++) |
918 |
|
{ |
919 |
|
Object item = model.getElementAt(i); |
920 |
|
Component comp = renderer.getListCellRendererComponent(listBox, |
921 |
item, -1, false, false); |
item, -1, false, false); |
922 |
|
|
923 |
Dimension compSize = comp.getPreferredSize(); |
Dimension compSize = comp.getPreferredSize(); |
924 |
if (compSize.width + 2 > size.width) |
if (compSize.width + 2 > size.width) |
925 |
size.width = compSize.width + 2; |
size.width = compSize.width + 2; |
926 |
if (compSize.height + 2 > size.height) |
if (compSize.height + 2 > size.height) |
927 |
size.height = compSize.height + 2; |
size.height = compSize.height + 2; |
928 |
|
} |
929 |
|
displaySize = size; |
930 |
|
return displaySize; |
931 |
} |
} |
932 |
displaySize = size; |
} |
933 |
|
else // an editable combo, |
934 |
|
{ |
935 |
|
Component comp = comboBox.getEditor().getEditorComponent(); |
936 |
|
Dimension prefSize = comp.getPreferredSize(); |
937 |
|
int width = prefSize.width; |
938 |
|
int height = prefSize.height + 2; |
939 |
|
Object prototype = comboBox.getPrototypeDisplayValue(); |
940 |
|
if (prototype != null) |
941 |
|
{ |
942 |
|
FontMetrics fm = comboBox.getFontMetrics(comboBox.getFont()); |
943 |
|
width = Math.max(width, fm.stringWidth(prototype.toString()) + 2); |
944 |
|
} |
945 |
|
displaySize = new Dimension(width, height); |
946 |
return displaySize; |
return displaySize; |
947 |
} |
} |
948 |
} |
} |
1076 |
*/ |
*/ |
1077 |
public void focusGained(FocusEvent e) |
public void focusGained(FocusEvent e) |
1078 |
{ |
{ |
1079 |
|
// Lets assume every change invalidates the minimumsize. |
1080 |
|
isMinimumSizeDirty = true; |
1081 |
|
|
1082 |
hasFocus = true; |
hasFocus = true; |
1083 |
comboBox.repaint(); |
comboBox.repaint(); |
1084 |
} |
} |
1091 |
*/ |
*/ |
1092 |
public void focusLost(FocusEvent e) |
public void focusLost(FocusEvent e) |
1093 |
{ |
{ |
1094 |
|
// Lets assume every change invalidates the minimumsize. |
1095 |
|
isMinimumSizeDirty = true; |
1096 |
|
|
1097 |
hasFocus = false; |
hasFocus = false; |
1098 |
setPopupVisible(comboBox, false); |
setPopupVisible(comboBox, false); |
1099 |
comboBox.repaint(); |
comboBox.repaint(); |
1122 |
*/ |
*/ |
1123 |
public void itemStateChanged(ItemEvent e) |
public void itemStateChanged(ItemEvent e) |
1124 |
{ |
{ |
1125 |
|
// Lets assume every change invalidates the minimumsize. |
1126 |
|
isMinimumSizeDirty = true; |
1127 |
|
|
1128 |
if (e.getStateChange() == ItemEvent.SELECTED && comboBox.isEditable()) |
if (e.getStateChange() == ItemEvent.SELECTED && comboBox.isEditable()) |
1129 |
comboBox.getEditor().setItem(e.getItem()); |
comboBox.getEditor().setItem(e.getItem()); |
1130 |
comboBox.repaint(); |
comboBox.repaint(); |
1172 |
public void contentsChanged(ListDataEvent e) |
public void contentsChanged(ListDataEvent e) |
1173 |
{ |
{ |
1174 |
// if the item is selected or deselected |
// if the item is selected or deselected |
1175 |
|
|
1176 |
|
// Lets assume every change invalidates the minimumsize. |
1177 |
|
isMinimumSizeDirty = true; |
1178 |
} |
} |
1179 |
|
|
1180 |
/** |
/** |
1184 |
*/ |
*/ |
1185 |
public void intervalAdded(ListDataEvent e) |
public void intervalAdded(ListDataEvent e) |
1186 |
{ |
{ |
1187 |
|
// Lets assume every change invalidates the minimumsize. |
1188 |
|
isMinimumSizeDirty = true; |
1189 |
|
|
1190 |
ComboBoxModel model = comboBox.getModel(); |
ComboBoxModel model = comboBox.getModel(); |
1191 |
ListCellRenderer renderer = comboBox.getRenderer(); |
ListCellRenderer renderer = comboBox.getRenderer(); |
1192 |
|
|
1208 |
*/ |
*/ |
1209 |
public void intervalRemoved(ListDataEvent e) |
public void intervalRemoved(ListDataEvent e) |
1210 |
{ |
{ |
1211 |
|
// Lets assume every change invalidates the minimumsize. |
1212 |
|
isMinimumSizeDirty = true; |
1213 |
|
|
1214 |
// recalculate display size of the JComboBox. |
// recalculate display size of the JComboBox. |
1215 |
displaySize = getDisplaySize(); |
displaySize = getDisplaySize(); |
1216 |
comboBox.repaint(); |
comboBox.repaint(); |
1238 |
*/ |
*/ |
1239 |
public void propertyChange(PropertyChangeEvent e) |
public void propertyChange(PropertyChangeEvent e) |
1240 |
{ |
{ |
1241 |
|
// Lets assume every change invalidates the minimumsize. |
1242 |
|
isMinimumSizeDirty = true; |
1243 |
|
|
1244 |
if (e.getPropertyName().equals("enabled")) |
if (e.getPropertyName().equals("enabled")) |
1245 |
{ |
{ |
1246 |
arrowButton.setEnabled(comboBox.isEnabled()); |
arrowButton.setEnabled(comboBox.isEnabled()); |