This is another fix from my ComboBox UI work. This time the
MetalComboBoxButton is reworked a little. The most important change here
is the fix for the paintComponent() method, which now correctly adjusts
the bounding boxes for the button itself as well as the renderer for the
value.

2006-03-17  Roman Kennke  <[EMAIL PROTECTED]>

        * javax/swing/plaf/metal/MetalComboBoxButton.java
        (rendererPane): Documented.
        (MetalComboBoxButton): Set enabled flag from ComboBox.
        Set focusable flag from ComboBox's enabled flag.
        (isFocusTraversable): Make button focus traversable if
        ComboBox is not editable but enable.
        (paintComponent): Fixed painting to correctly adjust
        the boxes of the renderer and button.

/Roman

-- 
“Improvement makes straight roads, but the crooked roads, without
Improvement, are roads of Genius.” - William Blake
Index: javax/swing/plaf/metal/MetalComboBoxButton.java
===================================================================
RCS file: /cvsroot/classpath/classpath/javax/swing/plaf/metal/MetalComboBoxButton.java,v
retrieving revision 1.7
diff -u -u -1 -0 -r1.7 MetalComboBoxButton.java
--- javax/swing/plaf/metal/MetalComboBoxButton.java	5 Mar 2006 22:01:58 -0000	1.7
+++ javax/swing/plaf/metal/MetalComboBoxButton.java	17 Mar 2006 21:11:14 -0000
@@ -31,44 +31,49 @@
 independent module, the terms and conditions of the license of that
 module.  An independent module is a module which is not derived from
 or based on this library.  If you modify this library, you may extend
 this exception to your version of the library, but you are not
 obligated to do so.  If you do not wish to do so, delete this
 exception statement from your version. */
 
 
 package javax.swing.plaf.metal;
 
+import java.awt.Color;
 import java.awt.Component;
 import java.awt.Graphics;
 import java.awt.Insets;
-import java.awt.Rectangle;
 
 import javax.swing.CellRendererPane;
 import javax.swing.Icon;
 import javax.swing.JButton;
 import javax.swing.JComboBox;
 import javax.swing.JList;
-import javax.swing.SwingUtilities;
+import javax.swing.ListCellRenderer;
+import javax.swing.UIManager;
 
 /**
  * A button used by the [EMAIL PROTECTED] MetalComboBoxUI} class.
  */
-public class MetalComboBoxButton extends JButton {
+public class MetalComboBoxButton
+  extends JButton
+{
 
   /** A reference to the JComboBox that the button belongs to. */
   protected JComboBox comboBox;
 
   /** A reference to the JList. */
   protected JList listBox;
   
-  /** ??? */
+  /**
+   * Used for rendering the selected item.
+   */
   protected CellRendererPane rendererPane;
   
   /** The button icon. */
   protected Icon comboIcon;
   
   /** Display just the icon, or the icon plus the label. */
   protected boolean iconOnly;
   
   /**
    * Creates a new button.
@@ -100,20 +105,22 @@
       CellRendererPane pane, JList list)
   {
     super();
     if (cb == null)
       throw new NullPointerException("Null 'cb' argument");
     comboBox = cb;
     comboIcon = i;
     iconOnly = onlyIcon;
     listBox = list;
     rendererPane = pane;
+    setEnabled(comboBox.isEnabled());
+    setFocusable(comboBox.isEnabled());
   }
   
   /**
    * Returns the combo box that the button is used with.
    * 
    * @return The combo box.
    */
   public final JComboBox getComboBox()
   {
     return comboBox;
@@ -173,21 +180,21 @@
   }
   
   /**
    * Returns <code>false</code>, to indicate that this component is not part
    * of the focus traversal group.
    * 
    * @return <code>false</code>
    */
   public boolean isFocusTraversable()
   {
-    return false;
+    return !comboBox.isEditable() && comboBox.isEnabled();
   }
   
   /**
    * Enables or disables the button.
    * 
    * @param enabled  the new status.
    */
   public void setEnabled(boolean enabled)
   {
     super.setEnabled(enabled);
@@ -196,46 +203,82 @@
   }
   
   /**
    * Paints the component.
    * 
    * @param g  the graphics device.
    */
   public void paintComponent(Graphics g)
   {
     super.paintComponent(g);
-    if (iconOnly)
-      {
-        Rectangle bounds = getBounds();
-        int x = (bounds.width - comboIcon.getIconWidth()) / 2;
-        int y = (bounds.height - comboIcon.getIconHeight()) / 2;
-        comboIcon.paintIcon(comboBox, g, x, y);  
-      }
-    else
+    Insets insets = this.getInsets();
+    int w = getWidth() - (insets.left + insets.right);
+    int h = getHeight() - (insets.top + insets.bottom);
+    if (h > 0 && w > 0)
       {
-        Object selected = comboBox.getModel().getSelectedItem();
-        if (selected == null)
-          selected = "";
-        Rectangle bounds = comboBox.getBounds();
-        Rectangle innerArea = SwingUtilities.calculateInnerArea(this, null);
-        Insets insets = comboBox.getInsets();
-        Rectangle renderArea = new Rectangle(innerArea.x, innerArea.y, 
-            innerArea.width - comboIcon.getIconWidth() - 4, innerArea.height);
-        Component cellRenderer 
-            = comboBox.getRenderer().getListCellRendererComponent(this.listBox,
-                    selected, comboBox.getSelectedIndex(), false, false);
-        cellRenderer.setBackground(comboBox.getBackground());
-        cellRenderer.setEnabled(comboBox.isEnabled());
-        rendererPane.paintComponent(g, cellRenderer, this, renderArea);
-        if (comboBox.hasFocus())
+        int x1 = insets.left;
+        int y1 = insets.top;
+        int x2 = x1 + (w - 1);
+        int y2 = y1 + (h - 1);
+        int iconWidth = 0;
+        int iconX = x2;
+        if (comboIcon != null)
+          {
+            iconWidth = comboIcon.getIconWidth();
+            int iconHeight = comboIcon.getIconHeight();
+            int iconY;
+            if (iconOnly)
+              {
+                iconX = getWidth() / 2 - iconWidth / 2;
+                iconY = getHeight() / 2 - iconHeight / 2;
+              }
+            else
+              {
+                iconX = x1 + (w - 1) - iconWidth;
+                iconY = y1 + (y2 - y1) / 2 - iconHeight / 2;
+              }
+            comboIcon.paintIcon(this, g, iconX, iconY);
+            if (this.hasFocus())
+              {
+                g.setColor(MetalLookAndFeel.getFocusColor());
+                g.drawRect(x1 - 1, y1 - 1, w + 3, h + 1);
+              }
+          }
+        if (! iconOnly && comboBox != null)
           {
-            g.setColor(MetalLookAndFeel.getFocusColor());
-            g.drawRect(innerArea.x, innerArea.y - 1, innerArea.width - 1, 
-                    innerArea.height);
+            ListCellRenderer renderer = comboBox.getRenderer();
+            boolean pressed = this.getModel().isPressed();
+            Component comp= renderer.getListCellRendererComponent(listBox,
+                                                    comboBox.getSelectedItem(),
+                                                    -1, false, false);
+            comp.setFont(rendererPane.getFont());
+            if (model.isArmed() && model.isPressed())
+              {
+                if (isOpaque())
+                  {
+                    comp.setBackground(UIManager.getColor("Button.select"));
+                    comp.setForeground(comboBox.getForeground());
+                  }
+              }
+            else if (! comboBox.isEnabled())
+              {
+                if (this.isOpaque())
+                  {
+                    Color dbg =
+                      UIManager.getColor("ComboBox.disabledBackground");
+                    comp.setBackground(dbg);
+                    Color dfg =
+                      UIManager.getColor("ComboBox.disabledForeground");
+                    comp.setForeground(dfg);
+                  }
+              }
+            else
+              {
+                comp.setForeground(comboBox.getForeground());
+                comp.setBackground(comboBox.getBackground());
+              }
+            int wr = w - (insets.right + iconWidth);
+            rendererPane.paintComponent(g, comp, this, x1, y1, wr, h);
           }
-        int iconX = bounds.width - insets.right - comboIcon.getIconWidth() - 7;
-        int iconY = insets.top 
-            + (bounds.height - comboIcon.getIconHeight()) / 2; 
-        comboIcon.paintIcon(comboBox, g, iconX, iconY);
       }
   }
 }

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

Reply via email to