Source for javax.swing.plaf.metal.MetalComboBoxButton

   1: /* MetalComboBoxButton.java
   2:    Copyright (C) 2005 Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.swing.plaf.metal;
  40: 
  41: import java.awt.Color;
  42: import java.awt.Component;
  43: import java.awt.Graphics;
  44: import java.awt.Insets;
  45: 
  46: import javax.swing.CellRendererPane;
  47: import javax.swing.Icon;
  48: import javax.swing.JButton;
  49: import javax.swing.JComboBox;
  50: import javax.swing.JList;
  51: import javax.swing.ListCellRenderer;
  52: import javax.swing.UIManager;
  53: 
  54: /**
  55:  * A button used by the {@link MetalComboBoxUI} class.
  56:  */
  57: public class MetalComboBoxButton
  58:   extends JButton
  59: {
  60: 
  61:   /** A reference to the JComboBox that the button belongs to. */
  62:   protected JComboBox comboBox;
  63: 
  64:   /** A reference to the JList. */
  65:   protected JList listBox;
  66: 
  67:   /**
  68:    * Used for rendering the selected item.
  69:    */
  70:   protected CellRendererPane rendererPane;
  71: 
  72:   /** The button icon. */
  73:   protected Icon comboIcon;
  74: 
  75:   /** Display just the icon, or the icon plus the label. */
  76:   protected boolean iconOnly;
  77: 
  78:   /**
  79:    * Creates a new button.
  80:    *
  81:    * @param cb  the combo that the button is used for (<code>null</code> not
  82:    *            permitted).
  83:    * @param i  the icon displayed on the button.
  84:    * @param pane  the rendering pane.
  85:    * @param list  the list.
  86:    */
  87:   public MetalComboBoxButton(JComboBox cb, Icon i, CellRendererPane pane,
  88:       JList list)
  89:   {
  90:     this(cb, i, cb.isEditable(), pane, list);
  91:   }
  92: 
  93:   /**
  94:    * Creates a new button.
  95:    *
  96:    * @param cb  the combo that the button is used for (<code>null</code> not
  97:    *            permitted).
  98:    * @param i  the icon displayed on the button.
  99:    * @param onlyIcon  a flag that specifies whether the button displays only an
 100:    *                  icon, or text as well.
 101:    * @param pane  the rendering pane.
 102:    * @param list  the list.
 103:    */
 104:   public MetalComboBoxButton(JComboBox cb, Icon i, boolean onlyIcon,
 105:       CellRendererPane pane, JList list)
 106:   {
 107:     super();
 108:     if (cb == null)
 109:       throw new NullPointerException("Null 'cb' argument");
 110:     comboBox = cb;
 111:     comboIcon = i;
 112:     iconOnly = onlyIcon;
 113:     listBox = list;
 114:     rendererPane = pane;
 115:     setRolloverEnabled(false);
 116:     setEnabled(comboBox.isEnabled());
 117:     setFocusable(comboBox.isEnabled());
 118:   }
 119: 
 120:   /**
 121:    * Returns the combo box that the button is used with.
 122:    *
 123:    * @return The combo box.
 124:    */
 125:   public final JComboBox getComboBox()
 126:   {
 127:     return comboBox;
 128:   }
 129: 
 130:   /**
 131:    * Sets the combo box that the button is used with.
 132:    *
 133:    * @param cb  the combo box.
 134:    */
 135:   public final void setComboBox(JComboBox cb)
 136:   {
 137:     comboBox = cb;
 138:   }
 139: 
 140:   /**
 141:    * Returns the icon displayed by the button.  By default, this will be an
 142:    * instance of {@link MetalComboBoxIcon}.
 143:    *
 144:    * @return The icon displayed by the button.
 145:    */
 146:   public final Icon getComboIcon()
 147:   {
 148:     return comboIcon;
 149:   }
 150: 
 151:   /**
 152:    * Sets the icon displayed by the button.
 153:    *
 154:    * @param i  the icon.
 155:    */
 156:   public final void setComboIcon(Icon i)
 157:   {
 158:     comboIcon = i;
 159:   }
 160: 
 161:   /**
 162:    * Returns a flag that controls whether the button displays an icon only,
 163:    * or text as well.
 164:    *
 165:    * @return A boolean.
 166:    */
 167:   public final boolean isIconOnly()
 168:   {
 169:     return iconOnly;
 170:   }
 171: 
 172:   /**
 173:    * Sets the flag that controls whether the button displays an icon only,
 174:    * or text as well.
 175:    *
 176:    * @param isIconOnly  the flag.
 177:    */
 178:   public final void setIconOnly(boolean isIconOnly)
 179:   {
 180:     iconOnly = isIconOnly;
 181:   }
 182: 
 183:   /**
 184:    * Returns <code>false</code>, to indicate that this component is not part
 185:    * of the focus traversal group.
 186:    *
 187:    * @return <code>false</code>
 188:    */
 189:   public boolean isFocusTraversable()
 190:   {
 191:     return false;
 192:   }
 193: 
 194:   /**
 195:    * Enables or disables the button.
 196:    *
 197:    * @param enabled  the new status.
 198:    */
 199:   public void setEnabled(boolean enabled)
 200:   {
 201:     super.setEnabled(enabled);
 202:     if (enabled)
 203:       {
 204:         setBackground(comboBox.getBackground());
 205:         setForeground(comboBox.getForeground());
 206:       }
 207:     else
 208:       {
 209:         setBackground(UIManager.getColor("ComboBox.disabledBackground"));
 210:         setForeground(UIManager.getColor("ComboBox.disabledForeground"));
 211:       }
 212:   }
 213: 
 214:   /**
 215:    * Paints the component.
 216:    *
 217:    * @param g  the graphics device.
 218:    */
 219:   public void paintComponent(Graphics g)
 220:   {
 221:     super.paintComponent(g);
 222:     Insets insets = this.getInsets();
 223:     int w = getWidth() - (insets.left + insets.right);
 224:     int h = getHeight() - (insets.top + insets.bottom);
 225:     if (h > 0 && w > 0)
 226:       {
 227:         int x1 = insets.left;
 228:         int y1 = insets.top;
 229:         int x2 = x1 + (w - 1);
 230:         int y2 = y1 + (h - 1);
 231:         int iconWidth = 0;
 232:         int iconX = x2;
 233:         if (comboIcon != null)
 234:           {
 235:             iconWidth = comboIcon.getIconWidth();
 236:             int iconHeight = comboIcon.getIconHeight();
 237:             int iconY;
 238:             if (iconOnly)
 239:               {
 240:                 iconX = getWidth() / 2 - iconWidth / 2;
 241:                 iconY = getHeight() / 2 - iconHeight / 2;
 242:               }
 243:             else
 244:               {
 245:                 iconX = x1 + (w - 1) - iconWidth;
 246:                 iconY = y1 + (y2 - y1) / 2 - iconHeight / 2;
 247:               }
 248:             comboIcon.paintIcon(this, g, iconX, iconY);
 249:             if (this.hasFocus())
 250:               {
 251:                 g.setColor(MetalLookAndFeel.getFocusColor());
 252:                 g.drawRect(x1 - 1, y1 - 1, w + 3, h + 1);
 253:               }
 254:           }
 255:         if (! iconOnly && comboBox != null)
 256:           {
 257:             ListCellRenderer renderer = comboBox.getRenderer();
 258:             boolean pressed = this.getModel().isPressed();
 259:             Component comp = renderer.getListCellRendererComponent(listBox,
 260:                 comboBox.getSelectedItem(), -1, false, false);
 261:             comp.setFont(rendererPane.getFont());
 262: 
 263:             if ((model.isArmed() && model.isPressed())
 264:                 || (comboBox.isFocusOwner() && !comboBox.isPopupVisible()))
 265:               {
 266:                 if (isOpaque())
 267:                   {
 268:                     comp.setBackground(UIManager.getColor("Button.select"));
 269:                     comp.setForeground(comboBox.getForeground());
 270:                   }
 271:               }
 272:             else if (! comboBox.isEnabled())
 273:               {
 274:                 if (this.isOpaque())
 275:                   {
 276:                     Color dbg =
 277:                       UIManager.getColor("ComboBox.disabledBackground");
 278:                     comp.setBackground(dbg);
 279:                     Color dfg =
 280:                       UIManager.getColor("ComboBox.disabledForeground");
 281:                     comp.setForeground(dfg);
 282:                   }
 283:               }
 284:             else
 285:               {
 286:                 comp.setForeground(comboBox.getForeground());
 287:                 comp.setBackground(comboBox.getBackground());
 288:               }
 289:             int wr = w - (insets.right + iconWidth);
 290:             rendererPane.paintComponent(g, comp, this, x1, y1, wr, h);
 291:           }
 292:       }
 293:   }
 294: }