001 /* MetalComboBoxButton.java 002 Copyright (C) 2005 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. */ 037 038 039 package javax.swing.plaf.metal; 040 041 import java.awt.Color; 042 import java.awt.Component; 043 import java.awt.Graphics; 044 import java.awt.Insets; 045 046 import javax.swing.CellRendererPane; 047 import javax.swing.Icon; 048 import javax.swing.JButton; 049 import javax.swing.JComboBox; 050 import javax.swing.JList; 051 import javax.swing.ListCellRenderer; 052 import javax.swing.UIManager; 053 054 /** 055 * A button used by the {@link MetalComboBoxUI} class. 056 */ 057 public 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 }