1 /* 2 * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.swing.plaf.metal; 27 28 import java.awt.*; 29 import java.awt.event.*; 30 import javax.swing.plaf.basic.*; 31 import javax.swing.*; 32 import javax.swing.plaf.*; 33 import javax.swing.border.*; 34 import java.io.Serializable; 35 36 /** 37 * JButton subclass to help out MetalComboBoxUI 38 * <p> 39 * <strong>Warning:</strong> 40 * Serialized objects of this class will not be compatible with 41 * future Swing releases. The current serialization support is 42 * appropriate for short term storage or RMI between applications running 43 * the same version of Swing. As of 1.4, support for long term storage 44 * of all JavaBeans™ 45 * has been added to the <code>java.beans</code> package. 46 * Please see {@link java.beans.XMLEncoder}. 47 * 48 * @see MetalComboBoxButton 49 * @author Tom Santos 50 */ 51 @SuppressWarnings("serial") // Same-version serialization only 52 public class MetalComboBoxButton extends JButton { 53 protected JComboBox comboBox; 54 protected JList listBox; 55 protected CellRendererPane rendererPane; 56 protected Icon comboIcon; 57 protected boolean iconOnly = false; 58 59 public final JComboBox getComboBox() { return comboBox;} 60 public final void setComboBox( JComboBox cb ) { comboBox = cb;} 61 62 public final Icon getComboIcon() { return comboIcon;} 63 public final void setComboIcon( Icon i ) { comboIcon = i;} 64 65 public final boolean isIconOnly() { return iconOnly;} 66 public final void setIconOnly( boolean isIconOnly ) { iconOnly = isIconOnly;} 67 68 MetalComboBoxButton() { 69 super( "" ); 70 DefaultButtonModel model = new DefaultButtonModel() { 71 public void setArmed( boolean armed ) { 72 super.setArmed( isPressed() ? true : armed ); 73 } 74 }; 75 setModel( model ); 76 } 77 78 public MetalComboBoxButton( JComboBox cb, Icon i, 79 CellRendererPane pane, JList list ) { 80 this(); 81 comboBox = cb; 82 comboIcon = i; 83 rendererPane = pane; 84 listBox = list; 85 setEnabled( comboBox.isEnabled() ); 86 } 87 88 public MetalComboBoxButton( JComboBox cb, Icon i, boolean onlyIcon, 89 CellRendererPane pane, JList list ) { 90 this( cb, i, pane, list ); 91 iconOnly = onlyIcon; 92 } 93 94 public boolean isFocusTraversable() { 95 return false; 96 } 97 98 public void setEnabled(boolean enabled) { 99 super.setEnabled(enabled); 100 101 // Set the background and foreground to the combobox colors. 102 if (enabled) { 103 setBackground(comboBox.getBackground()); 104 setForeground(comboBox.getForeground()); 105 } else { 106 setBackground(UIManager.getColor("ComboBox.disabledBackground")); 107 setForeground(UIManager.getColor("ComboBox.disabledForeground")); 108 } 109 } 110 111 public void paintComponent( Graphics g ) { 112 boolean leftToRight = MetalUtils.isLeftToRight(comboBox); 113 114 // Paint the button as usual 115 super.paintComponent( g ); 116 117 Insets insets = getInsets(); 118 119 int width = getWidth() - (insets.left + insets.right); 120 int height = getHeight() - (insets.top + insets.bottom); 121 122 if ( height <= 0 || width <= 0 ) { 123 return; 124 } 125 126 int left = insets.left; 127 int top = insets.top; 128 int right = left + (width - 1); 129 int bottom = top + (height - 1); 130 131 int iconWidth = 0; 132 int iconLeft = (leftToRight) ? right : left; 133 134 // Paint the icon 135 if ( comboIcon != null ) { 136 iconWidth = comboIcon.getIconWidth(); 137 int iconHeight = comboIcon.getIconHeight(); 138 int iconTop = 0; 139 140 if ( iconOnly ) { 141 iconLeft = (getWidth() / 2) - (iconWidth / 2); 142 iconTop = (getHeight() / 2) - (iconHeight / 2); 143 } 144 else { 145 if (leftToRight) { 146 iconLeft = (left + (width - 1)) - iconWidth; 147 } 148 else { 149 iconLeft = left; 150 } 151 iconTop = (top + ((bottom - top) / 2)) - (iconHeight / 2); 152 } 153 154 comboIcon.paintIcon( this, g, iconLeft, iconTop ); 155 156 // Paint the focus 157 if ( comboBox.hasFocus() && (!MetalLookAndFeel.usingOcean() || 158 comboBox.isEditable())) { 159 g.setColor( MetalLookAndFeel.getFocusColor() ); 160 g.drawRect( left - 1, top - 1, width + 3, height + 1 ); 161 } 162 } 163 164 if (MetalLookAndFeel.usingOcean()) { 165 // With Ocean the button only paints the arrow, bail. 166 return; 167 } 168 169 // Let the renderer paint 170 if ( ! iconOnly && comboBox != null ) { 171 ListCellRenderer renderer = comboBox.getRenderer(); 172 Component c; 173 boolean renderPressed = getModel().isPressed(); 174 c = renderer.getListCellRendererComponent(listBox, 175 comboBox.getSelectedItem(), 176 -1, 177 renderPressed, 178 false); 179 c.setFont(rendererPane.getFont()); 180 181 if ( model.isArmed() && model.isPressed() ) { 182 if ( isOpaque() ) { 183 c.setBackground(UIManager.getColor("Button.select")); 184 } 185 c.setForeground(comboBox.getForeground()); 186 } 187 else if ( !comboBox.isEnabled() ) { 188 if ( isOpaque() ) { 189 c.setBackground(UIManager.getColor("ComboBox.disabledBackground")); 190 } 191 c.setForeground(UIManager.getColor("ComboBox.disabledForeground")); 192 } 193 else { 194 c.setForeground(comboBox.getForeground()); 195 c.setBackground(comboBox.getBackground()); 196 } 197 198 199 int cWidth = width - (insets.right + iconWidth); 200 201 // Fix for 4238829: should lay out the JPanel. 202 boolean shouldValidate = false; 203 if (c instanceof JPanel) { 204 shouldValidate = true; 205 } 206 207 if (leftToRight) { 208 rendererPane.paintComponent( g, c, this, 209 left, top, cWidth, height, shouldValidate ); 210 } 211 else { 212 rendererPane.paintComponent( g, c, this, 213 left + iconWidth, top, cWidth, height, shouldValidate ); 214 } 215 } 216 } 217 218 public Dimension getMinimumSize() { 219 Dimension ret = new Dimension(); 220 Insets insets = getInsets(); 221 ret.width = insets.left + getComboIcon().getIconWidth() + insets.right; 222 ret.height = insets.bottom + getComboIcon().getIconHeight() + insets.top; 223 return ret; 224 } 225 }