This is the last piece of my ComboBox work. There were some layout glitches in the MetalComboBoxUI that are fixed by the attached patch.
2006-03-17 Roman Kennke <[EMAIL PROTECTED]> * javax/swing/plaf/metal/MetalComboBoxUI.java (MetalComboBoxLayoutManager.layoutContainer): Forward to layoutComboBox(). (MetalPropertyChangeListener.propertyChange): Update focusable flag according to the enable and editable state. (editablePropertyChanged): Removed unnecessary code. (getMinimumSize): Rewritten to correctly compute the size, respecting the insets of the components and the icon, the visual properties of the combobox, etc. (configureEditor): Update listeners correctly. (unconfigureEditor): Update listeners correctly. (layoutComboBox): Implemented. /Roman -- “Improvement makes straight roads, but the crooked roads, without Improvement, are roads of Genius.” - William Blake
Index: javax/swing/plaf/metal/MetalComboBoxUI.java =================================================================== RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/metal/MetalComboBoxUI.java,v retrieving revision 1.9 diff -u -u -1 -0 -r1.9 MetalComboBoxUI.java --- javax/swing/plaf/metal/MetalComboBoxUI.java 22 Nov 2005 19:34:29 -0000 1.9 +++ javax/swing/plaf/metal/MetalComboBoxUI.java 17 Mar 2006 21:29:19 -0000 @@ -36,21 +36,20 @@ exception statement from your version. */ package javax.swing.plaf.metal; import java.awt.Container; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Insets; import java.awt.LayoutManager; -import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.CellRendererPane; import javax.swing.ComboBoxEditor; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JComponent; @@ -81,28 +80,21 @@ } /** * Arranges the editor (if visible) and button that comprise the combo * box. * * @param parent the parent. */ public void layoutContainer(Container parent) { - JComboBox cb = (JComboBox) parent; - if (!cb.isEditable()) - { - Rectangle bounds = parent.getBounds(); - arrowButton.setBounds(0, 0, bounds.width, bounds.height); - } - else - superLayout(parent); + layoutComboBox(parent, this); } /** * Calls the <code>layoutContainer(Container)</code> method in the super * class. * * @param parent the container. */ public void superLayout(Container parent) { @@ -127,23 +119,33 @@ } /** * Handles a property change event, updating the UI components as * appropriate. * * @param e the event. */ public void propertyChange(PropertyChangeEvent e) { - if (e.getPropertyName().equals("editable")) - editablePropertyChanged(e); super.propertyChange(e); + String name = e.getPropertyName(); + if (name.equals("editable")) + editablePropertyChanged(e); + if (name.equals("enabled")) + { + if (arrowButton instanceof MetalComboBoxButton) + { + arrowButton.setFocusable(!comboBox.isEditable() + && comboBox.isEnabled()); + comboBox.repaint(); + } + } } } /** * A popup menu for the combo-box. * * @see #createPopup() * * @deprecated 1.4 */ @@ -240,36 +242,22 @@ * @param e the event. * * @deprecated 1.4 */ protected void editablePropertyChanged(PropertyChangeEvent e) { if (arrowButton instanceof MetalComboBoxButton) { MetalComboBoxButton b = (MetalComboBoxButton) arrowButton; b.setIconOnly(comboBox.isEditable()); - } - if (comboBox.isEditable()) - { - arrowButton.setText(null); - if (editor != null) - editor.setVisible(true); - } - else - { - String text = ""; - Object selected = comboBox.getSelectedItem(); - if (selected != null) - text = selected.toString(); - arrowButton.setText(text); - if (editor != null) - editor.setVisible(true); + b.setFocusable(!comboBox.isEditable() && comboBox.isEnabled()); + comboBox.repaint(); } } /** * Creates a new layout manager for the UI delegate. * * @return A new layout manager. */ protected LayoutManager createLayoutManager() { @@ -288,65 +276,92 @@ /** * Returns the minimum size for the combo. * * @param c the component * * @return The minimum size for the combo box. */ public Dimension getMinimumSize(JComponent c) { - Dimension d = getDisplaySize(); - MetalComboBoxButton b = (MetalComboBoxButton) arrowButton; - Insets insets = b.getInsets(); - int insetsH = insets.top + insets.bottom; - int insetsW = insets.left + insets.right; - if (!comboBox.isEditable()) + if (!isMinimumSizeDirty) + return new Dimension(cachedMinimumSize); + + Dimension d; + if (!comboBox.isEditable() && arrowButton != null + && arrowButton instanceof MetalComboBoxButton) { + MetalComboBoxButton b = (MetalComboBoxButton) arrowButton; + d = getDisplaySize(); + Insets insets = b.getInsets(); + Insets arrowInsets = b.getInsets(); + Insets comboInsets = comboBox.getInsets(); Icon icon = b.getComboIcon(); - int iconWidth = icon.getIconWidth() + 6; - return new Dimension(d.width + insetsW + iconWidth, d.height + insetsH); + d.width += comboInsets.left + comboInsets.right; + d.width += arrowInsets.left + arrowInsets.right; + d.width += arrowInsets.right + icon.getIconWidth(); + d.height += comboInsets.top + comboInsets.bottom; + d.height += arrowInsets.top + arrowInsets.bottom; + } + else if (comboBox.isEditable() && arrowButton != null && editor != null) + { + d = super.getMinimumSize(c); + Insets arrowMargin = arrowButton.getMargin(); + Insets comboInsets = comboBox.getInsets(); + if (editor instanceof JComponent) + { + Insets editorInsets = ((JComponent) editor).getInsets(); + d.height += editorInsets.top + editorInsets.bottom; + } + d.height += arrowMargin.top + arrowMargin.bottom; + d.height += comboInsets.top + comboInsets.bottom; } else - // FIXME: the following dimensions pass most of the Mauve tests, but - // I don't yet understand the logic behind this...it is probably wrong - return new Dimension(d.width + insetsW + (d.height + insetsH) - 4, - d.height + insetsH + 1); + { + d = super.getMinimumSize(c); + } + cachedMinimumSize.setSize(d.width, d.height); + isMinimumSizeDirty = false; + return new Dimension(cachedMinimumSize); } /** * Configures the editor for this combo box. */ public void configureEditor() { - ComboBoxEditor cbe = comboBox.getEditor(); - if (cbe != null) - { - cbe.getEditorComponent().setFont(comboBox.getFont()); - cbe.setItem(comboBox.getSelectedItem()); - cbe.addActionListener(comboBox); - } + super.configureEditor(); + if (popupKeyListener != null) + editor.removeKeyListener(popupKeyListener); + if (focusListener != null) + editor.addFocusListener(focusListener); } - + /** * Unconfigures the editor for this combo box. */ public void unconfigureEditor() { - ComboBoxEditor cbe = comboBox.getEditor(); - if (cbe != null) - { - cbe.getEditorComponent().setFont(null); - cbe.setItem(null); - cbe.removeActionListener(comboBox); - } + super.unconfigureEditor(); + if (focusListener != null) + editor.removeFocusListener(focusListener); } /** * Lays out the ComboBox */ public void layoutComboBox(Container parent, MetalComboBoxUI.MetalComboBoxLayoutManager manager) { - manager.layoutContainer(parent); + if (comboBox.isEditable()) + manager.superLayout(parent); + else if (arrowButton != null) + { + Insets comboInsets = comboBox.getInsets(); + int width = comboBox.getWidth(); + int height = comboBox.getHeight(); + arrowButton.setBounds(comboInsets.left, comboInsets.top, + width - (comboInsets.left + comboInsets.right), + height - (comboInsets.top + comboInsets.bottom)); + } } }
signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil