Changeset 5450 in josm for trunk/src/org/openstreetmap/josm/gui/widgets/JosmComboBox.java
- Timestamp:
- 2012-08-18T14:58:25+02:00 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/gui/widgets/JosmComboBox.java
r5429 r5450 2 2 package org.openstreetmap.josm.gui.widgets; 3 3 4 import java.awt.Toolkit; 4 5 import java.util.Vector; 5 6 7 import javax.accessibility.Accessible; 6 8 import javax.swing.ComboBoxModel; 7 9 import javax.swing.DefaultComboBoxModel; 8 10 import javax.swing.JComboBox; 9 10 import org.openstreetmap.josm.Main; 11 import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent; 12 import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener; 11 import javax.swing.JList; 12 import javax.swing.plaf.basic.ComboPopup; 13 13 14 14 /** 15 15 * Class overriding each {@link JComboBox} in JOSM to control consistently the number of displayed items at once.<br/> 16 * This is needed because of the default Java behaviour that may display the top-down list off the screen (see #). 17 * <p> 18 * The property {@code gui.combobox.maximum-row-count} can be setup to control this behaviour. 16 * This is needed because of the default Java behaviour that may display the top-down list off the screen (see #7917). 19 17 * 20 18 * @since 5429 21 19 */ 22 public class JosmComboBox extends JComboBox implements PreferenceChangedListener{20 public class JosmComboBox extends JComboBox { 23 21 24 22 /** 25 * This property allows to control the {@link #getMaximumRowCount} of all combo boxes used in JOSM. 23 * The default prototype value used to compute the maximum number of elements to be displayed at once before 24 * displaying a scroll bar 26 25 */ 27 public static final String PROP_MAXIMUM_ROW_COUNT = "gui.combobox.maximum-row-count";26 public static final String DEFAULT_PROTOTYPE_DISPLAY_VALUE = "Prototype display value"; 28 27 29 28 /** 30 29 * Creates a <code>JosmComboBox</code> with a default data model. 31 30 * The default data model is an empty list of objects. 32 * Use <code>addItem</code> to add items. 31 * Use <code>addItem</code> to add items. By default the first item 33 32 * in the data model becomes selected. 34 33 * … … 36 35 */ 37 36 public JosmComboBox() { 37 this(DEFAULT_PROTOTYPE_DISPLAY_VALUE); 38 } 39 40 /** 41 * Creates a <code>JosmComboBox</code> with a default data model and 42 * the specified prototype display value. 43 * The default data model is an empty list of objects. 44 * Use <code>addItem</code> to add items. By default the first item 45 * in the data model becomes selected. 46 * 47 * @param prototypeDisplayValue the <code>Object</code> used to compute 48 * the maximum number of elements to be displayed at once before 49 * displaying a scroll bar 50 * 51 * @see DefaultComboBoxModel 52 * @since 5450 53 */ 54 public JosmComboBox(Object prototypeDisplayValue) { 38 55 super(); 39 init( );56 init(prototypeDisplayValue); 40 57 } 41 58 42 59 /** 43 60 * Creates a <code>JosmComboBox</code> that takes its items from an 44 * existing <code>ComboBoxModel</code>. 61 * existing <code>ComboBoxModel</code>. Since the 45 62 * <code>ComboBoxModel</code> is provided, a combo box created using 46 63 * this constructor does not create a default combo box model and … … 53 70 public JosmComboBox(ComboBoxModel aModel) { 54 71 super(aModel); 55 init( );72 init(aModel != null && aModel.getSize() > 0 ? aModel.getElementAt(0) : DEFAULT_PROTOTYPE_DISPLAY_VALUE); 56 73 } 57 74 58 75 /** 59 76 * Creates a <code>JosmComboBox</code> that contains the elements 60 * in the specified array. 77 * in the specified array. By default the first item in the array 61 78 * (and therefore the data model) becomes selected. 62 79 * … … 66 83 public JosmComboBox(Object[] items) { 67 84 super(items); 68 init( );85 init(items != null && items.length > 0 ? items[0] : DEFAULT_PROTOTYPE_DISPLAY_VALUE); 69 86 } 70 87 71 88 /** 72 89 * Creates a <code>JosmComboBox</code> that contains the elements 73 * in the specified Vector. 90 * in the specified Vector. By default the first item in the vector 74 91 * (and therefore the data model) becomes selected. 75 92 * … … 79 96 public JosmComboBox(Vector<?> items) { 80 97 super(items); 81 init( );98 init(items != null && !items.isEmpty() ? items.get(0) : DEFAULT_PROTOTYPE_DISPLAY_VALUE); 82 99 } 83 100 84 protected void init() { 85 setMaximumRowCount(Main.pref.getInteger(PROP_MAXIMUM_ROW_COUNT, 20)); 86 } 87 88 /** 89 * Registers this combo box to the change of the property {@code gui.combobox.maximum-row-count}.<br/> 90 * Do not forget to call {@link #unregisterFromPreferenceChange} when the combo box is no longer needed. 91 * @see #unregisterFromPreferenceChange 92 */ 93 public final void registerToPreferenceChange() { 94 Main.pref.addPreferenceChangeListener(this); 95 } 96 97 /** 98 * Unregisters this combo box previously registered by {@link #registerToPreferenceChange}. 99 * @see #registerToPreferenceChange 100 */ 101 public final void unregisterFromPreferenceChange() { 102 Main.pref.removePreferenceChangeListener(this); 103 } 104 105 @Override 106 public void preferenceChanged(PreferenceChangeEvent e) { 107 if (PROP_MAXIMUM_ROW_COUNT.equals(e.getKey())) { 108 setMaximumRowCount(Main.pref.getInteger(PROP_MAXIMUM_ROW_COUNT, 20)); 101 protected void init(Object prototype) { 102 if (prototype != null) { 103 setPrototypeDisplayValue(prototype); 104 int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height; 105 // Compute maximum number of visible items based on the preferred size of the combo box. 106 // This assumes that items have the same height as the combo box, which is not granted by the look and feel 107 int maxsize = (screenHeight/getPreferredSize().height) / 2; 108 // If possible, adjust the maximum number of items with the real height of items 109 // It is not granted this works on every platform (tested OK on Windows) 110 for (int i = 0; i < getUI().getAccessibleChildrenCount(this); i++) { 111 Accessible child = getUI().getAccessibleChild(this, i); 112 if (child instanceof ComboPopup) { 113 JList list = ((ComboPopup)child).getList(); 114 if (list != null) { 115 if (list.getPrototypeCellValue() != prototype) { 116 list.setPrototypeCellValue(prototype); 117 } 118 int height = list.getFixedCellHeight(); 119 if (height > 0) { 120 maxsize = (screenHeight/height) / 2; 121 } 122 } 123 break; 124 } 125 } 126 setMaximumRowCount(Math.max(getMaximumRowCount(), maxsize)); 109 127 } 110 128 }
Note:
See TracChangeset
for help on using the changeset viewer.