001/* MetalComboBoxButton.java 002 Copyright (C) 2005 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038 039package javax.swing.plaf.metal; 040 041import java.awt.Color; 042import java.awt.Component; 043import java.awt.Graphics; 044import java.awt.Insets; 045 046import javax.swing.CellRendererPane; 047import javax.swing.Icon; 048import javax.swing.JButton; 049import javax.swing.JComboBox; 050import javax.swing.JList; 051import javax.swing.ListCellRenderer; 052import javax.swing.UIManager; 053 054/** 055 * A button used by the {@link MetalComboBoxUI} class. 056 */ 057public class MetalComboBoxButton 058 extends JButton 059{ 060 061 /** A reference to the JComboBox that the button belongs to. */ 062 protected JComboBox comboBox; 063 064 /** A reference to the JList. */ 065 protected JList listBox; 066 067 /** 068 * Used for rendering the selected item. 069 */ 070 protected CellRendererPane rendererPane; 071 072 /** The button icon. */ 073 protected Icon comboIcon; 074 075 /** Display just the icon, or the icon plus the label. */ 076 protected boolean iconOnly; 077 078 /** 079 * Creates a new button. 080 * 081 * @param cb the combo that the button is used for (<code>null</code> not 082 * permitted). 083 * @param i the icon displayed on the button. 084 * @param pane the rendering pane. 085 * @param list the list. 086 */ 087 public MetalComboBoxButton(JComboBox cb, Icon i, CellRendererPane pane, 088 JList list) 089 { 090 this(cb, i, cb.isEditable(), pane, list); 091 } 092 093 /** 094 * Creates a new button. 095 * 096 * @param cb the combo that the button is used for (<code>null</code> not 097 * permitted). 098 * @param i the icon displayed on the button. 099 * @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}