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));
+      }
   }
 }

Attachment: signature.asc
Description: Dies ist ein digital signierter Nachrichtenteil

Reply via email to