1 /*
2 * Copyright 1998-2004 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any 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<sup><font size="-2">TM</font></sup>
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 public class MetalComboBoxButton extends JButton {
52 protected JComboBox comboBox;
53 protected JList listBox;
54 protected CellRendererPane rendererPane;
55 protected Icon comboIcon;
56 protected boolean iconOnly = false;
57
58 public final JComboBox getComboBox() { return comboBox;}
59 public final void setComboBox( JComboBox cb ) { comboBox = cb;}
60
61 public final Icon getComboIcon() { return comboIcon;}
62 public final void setComboIcon( Icon i ) { comboIcon = i;}
63
64 public final boolean isIconOnly() { return iconOnly;}
65 public final void setIconOnly( boolean isIconOnly ) { iconOnly = isIconOnly;}
66
67 MetalComboBoxButton() {
68 super( "" );
69 DefaultButtonModel model = new DefaultButtonModel() {
70 public void setArmed( boolean armed ) {
71 super.setArmed( isPressed() ? true : armed );
72 }
73 };
74 setModel( model );
75 }
76
77 public MetalComboBoxButton( JComboBox cb, Icon i,
78 CellRendererPane pane, JList list ) {
79 this();
80 comboBox = cb;
81 comboIcon = i;
82 rendererPane = pane;
83 listBox = list;
84 setEnabled( comboBox.isEnabled() );
85 }
86
87 public MetalComboBoxButton( JComboBox cb, Icon i, boolean onlyIcon,
88 CellRendererPane pane, JList list ) {
89 this( cb, i, pane, list );
90 iconOnly = onlyIcon;
91 }
92
93 public boolean isFocusTraversable() {
94 return false;
95 }
96
97 public void setEnabled(boolean enabled) {
98 super.setEnabled(enabled);
99
100 // Set the background and foreground to the combobox colors.
101 if (enabled) {
102 setBackground(comboBox.getBackground());
103 setForeground(comboBox.getForeground());
104 } else {
105 setBackground(UIManager.getColor("ComboBox.disabledBackground"));
106 setForeground(UIManager.getColor("ComboBox.disabledForeground"));
107 }
108 }
109
110 public void paintComponent( Graphics g ) {
111 boolean leftToRight = MetalUtils.isLeftToRight(comboBox);
112
113 // Paint the button as usual
114 super.paintComponent( g );
115
116 Insets insets = getInsets();
117
118 int width = getWidth() - (insets.left + insets.right);
119 int height = getHeight() - (insets.top + insets.bottom);
120
121 if ( height <= 0 || width <= 0 ) {
122 return;
123 }
124
125 int left = insets.left;
126 int top = insets.top;
127 int right = left + (width - 1);
128 int bottom = top + (height - 1);
129
130 int iconWidth = 0;
131 int iconLeft = (leftToRight) ? right : left;
132
133 // Paint the icon
134 if ( comboIcon != null ) {
135 iconWidth = comboIcon.getIconWidth();
136 int iconHeight = comboIcon.getIconHeight();
137 int iconTop = 0;
138
139 if ( iconOnly ) {
140 iconLeft = (getWidth() / 2) - (iconWidth / 2);
141 iconTop = (getHeight() / 2) - (iconHeight / 2);
142 }
143 else {
144 if (leftToRight) {
145 iconLeft = (left + (width - 1)) - iconWidth;
146 }
147 else {
148 iconLeft = left;
149 }
150 iconTop = (top + ((bottom - top) / 2)) - (iconHeight / 2);
151 }
152
153 comboIcon.paintIcon( this, g, iconLeft, iconTop );
154
155 // Paint the focus
156 if ( comboBox.hasFocus() && (!MetalLookAndFeel.usingOcean() ||
157 comboBox.isEditable())) {
158 g.setColor( MetalLookAndFeel.getFocusColor() );
159 g.drawRect( left - 1, top - 1, width + 3, height + 1 );
160 }
161 }
162
163 if (MetalLookAndFeel.usingOcean()) {
164 // With Ocean the button only paints the arrow, bail.
165 return;
166 }
167
168 // Let the renderer paint
169 if ( ! iconOnly && comboBox != null ) {
170 ListCellRenderer renderer = comboBox.getRenderer();
171 Component c;
172 boolean renderPressed = getModel().isPressed();
173 c = renderer.getListCellRendererComponent(listBox,
174 comboBox.getSelectedItem(),
175 -1,
176 renderPressed,
177 false);
178 c.setFont(rendererPane.getFont());
179
180 if ( model.isArmed() && model.isPressed() ) {
181 if ( isOpaque() ) {
182 c.setBackground(UIManager.getColor("Button.select"));
183 }
184 c.setForeground(comboBox.getForeground());
185 }
186 else if ( !comboBox.isEnabled() ) {
187 if ( isOpaque() ) {
188 c.setBackground(UIManager.getColor("ComboBox.disabledBackground"));
189 }
190 c.setForeground(UIManager.getColor("ComboBox.disabledForeground"));
191 }
192 else {
193 c.setForeground(comboBox.getForeground());
194 c.setBackground(comboBox.getBackground());
195 }
196
197
198 int cWidth = width - (insets.right + iconWidth);
199
200 // Fix for 4238829: should lay out the JPanel.
201 boolean shouldValidate = false;
202 if (c instanceof JPanel) {
203 shouldValidate = true;
204 }
205
206 if (leftToRight) {
207 rendererPane.paintComponent( g, c, this,
208 left, top, cWidth, height, shouldValidate );
209 }
210 else {
211 rendererPane.paintComponent( g, c, this,
212 left + iconWidth, top, cWidth, height, shouldValidate );
213 }
214 }
215 }
216
217 public Dimension getMinimumSize() {
218 Dimension ret = new Dimension();
219 Insets insets = getInsets();
220 ret.width = insets.left + getComboIcon().getIconWidth() + insets.right;
221 ret.height = insets.bottom + getComboIcon().getIconHeight() + insets.top;
222 return ret;
223 }
224 }