KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jgoodies > looks > plastic > PlasticComboBoxButton


1 /*
2  * Copyright (c) 2001-2005 JGoodies Karsten Lentzsch. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * o Redistributions of source code must retain the above copyright notice,
8  * this list of conditions and the following disclaimer.
9  *
10  * o Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * o Neither the name of JGoodies Karsten Lentzsch nor the names of
15  * its contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31 package com.jgoodies.looks.plastic;
32
33 import java.awt.Component JavaDoc;
34 import java.awt.Graphics JavaDoc;
35 import java.awt.Insets JavaDoc;
36
37 import javax.swing.*;
38
39 /**
40  * The default button for combo boxes in the JGoodies Plastic Look&Feel.
41  * <p>
42  * It differs from <code>MetalComboBoxButton</code> in that the border
43  * is quite the same as for text fields: a compound border with an inner
44  * <code>MarginBorder</code>.
45  * <p>
46  * Also, we try to switch the <code>ListCellRenderer</code> to transparent,
47  * which works for most <code>JComponent</code> renderes including the
48  * <code>BasicComboBoxRenderer</code>.
49  *
50  * @author Karsten Lentzsch
51  * @version $Revision: 1.3 $
52  */

53 final class PlasticComboBoxButton extends JButton {
54
55     private static final int LEFT_INSET = 2;
56     private static final int RIGHT_INSET = 3;
57
58     private final JList listBox;
59     private final CellRendererPane rendererPane;
60
61     private JComboBox comboBox;
62     private Icon comboIcon;
63     protected boolean iconOnly = false;
64     private boolean borderPaintsFocus;
65
66     /**
67      * Constructs a <code>PlasticComboBoxButton</code>.
68      */

69     PlasticComboBoxButton(
70         JComboBox comboBox,
71         Icon comboIcon,
72         boolean iconOnly,
73         CellRendererPane rendererPane,
74         JList listBox) {
75         super("");
76         setModel(new DefaultButtonModel() {
77             public void setArmed(boolean armed) {
78                 super.setArmed(isPressed() || armed);
79             }
80         });
81         this.comboBox = comboBox;
82         this.comboIcon = comboIcon;
83         this.iconOnly = iconOnly;
84         this.rendererPane = rendererPane;
85         this.listBox = listBox;
86         setEnabled(comboBox.isEnabled());
87         setFocusable(false);
88         setRequestFocusEnabled(comboBox.isEnabled());
89         setBorder(UIManager.getBorder("ComboBox.arrowButtonBorder"));
90         setMargin(new Insets JavaDoc(0, LEFT_INSET, 0, RIGHT_INSET));
91         borderPaintsFocus = UIManager.getBoolean("ComboBox.borderPaintsFocus");
92     }
93
94     public JComboBox getComboBox() {
95         return comboBox;
96     }
97     
98     public void setComboBox(JComboBox cb) {
99         comboBox = cb;
100     }
101
102     public Icon getComboIcon() {
103         return comboIcon;
104     }
105     
106     public void setComboIcon(Icon i) {
107         comboIcon = i;
108     }
109
110     public boolean isIconOnly() {
111         return iconOnly;
112     }
113     
114     public void setIconOnly(boolean b) {
115         iconOnly = b;
116     }
117
118     public void setEnabled(boolean enabled) {
119         super.setEnabled(enabled);
120         // Set the background and foreground to the combobox colors.
121
if (enabled) {
122             setBackground(comboBox.getBackground());
123             setForeground(comboBox.getForeground());
124         } else {
125             setBackground(UIManager.getColor("ComboBox.disabledBackground"));
126             setForeground(UIManager.getColor("ComboBox.disabledForeground"));
127         }
128     }
129
130     /**
131      * Checks and answers if we should paint a pseudo 3D effect.
132      */

133     private boolean is3D() {
134         if (PlasticUtils.force3D(comboBox))
135             return true;
136         if (PlasticUtils.forceFlat(comboBox))
137             return false;
138         return PlasticUtils.is3D("ComboBox.");
139     }
140
141     /**
142      * Paints the component; honors the 3D settings and
143      * tries to switch the renderer component to transparent.
144      */

145     public void paintComponent(Graphics JavaDoc g) {
146         super.paintComponent(g);
147         boolean leftToRight = PlasticUtils.isLeftToRight(comboBox);
148
149         Insets JavaDoc insets = getInsets();
150
151         int width = getWidth() - (insets.left + insets.right);
152         int height = getHeight() - (insets.top + insets.bottom);
153
154         if (height <= 0 || width <= 0) {
155             return;
156         }
157
158         int left = insets.left;
159         int top = insets.top;
160         int right = left + (width - 1);
161
162         int iconWidth = 0;
163         int iconLeft = (leftToRight) ? right : left;
164
165         // Paint the icon
166
if (comboIcon != null) {
167             iconWidth = comboIcon.getIconWidth();
168             int iconHeight = comboIcon.getIconHeight();
169             int iconTop;
170
171             if (iconOnly) {
172                 iconLeft = (getWidth() - iconWidth) / 2;
173                 iconTop = (getHeight() - iconHeight) / 2;
174             } else {
175                 if (leftToRight) {
176                     iconLeft = (left + (width - 1)) - iconWidth;
177                 } else {
178                     iconLeft = left;
179                 }
180                 iconTop = (getHeight() - iconHeight) / 2;
181             }
182
183             comboIcon.paintIcon(this, g, iconLeft, iconTop);
184
185         }
186
187         // Let the renderer paint
188
if (!iconOnly && comboBox != null) {
189             ListCellRenderer renderer = comboBox.getRenderer();
190             boolean renderPressed = getModel().isPressed();
191             Component JavaDoc c =
192                 renderer.getListCellRendererComponent(
193                     listBox,
194                     comboBox.getSelectedItem(),
195                     -1,
196                     renderPressed,
197                     false);
198             c.setFont(rendererPane.getFont());
199
200             if (model.isArmed() && model.isPressed()) {
201                 if (isOpaque()) {
202                     c.setBackground(UIManager.getColor("Button.select"));
203                 }
204                 c.setForeground(comboBox.getForeground());
205             } else if (!comboBox.isEnabled()) {
206                 if (isOpaque()) {
207                     c.setBackground(
208                         UIManager.getColor("ComboBox.disabledBackground"));
209                 }
210                 c.setForeground(
211                     UIManager.getColor("ComboBox.disabledForeground"));
212             } else {
213                 c.setForeground(comboBox.getForeground());
214                 c.setBackground(comboBox.getBackground());
215             }
216
217             int cWidth = width - (insets.right + iconWidth);
218
219             // Fix for 4238829: should lay out the JPanel.
220
boolean shouldValidate = c instanceof JPanel;
221             int x = leftToRight ? left : left + iconWidth;
222             int myHeight = getHeight() - LEFT_INSET - RIGHT_INSET - 1;
223
224             if (!is3D()) {
225                 rendererPane.paintComponent(
226                     g,
227                     c,
228                     this,
229                     x,
230                     top + 2,
231                     cWidth,
232                     myHeight,
233                     shouldValidate);
234             } else if (!(c instanceof JComponent)) {
235                 rendererPane.paintComponent(
236                     g,
237                     c,
238                     this,
239                     x,
240                     top + 2,
241                     cWidth,
242                     myHeight,
243                     shouldValidate);
244                 //LookUtils.log("Custom renderer detected: " + c);
245
//LookUtils.log("Custom renderer superclass: " + c.getClass().getSuperclass().getName());
246
} else if (!c.isOpaque()) {
247                 rendererPane.paintComponent(
248                     g,
249                     c,
250                     this,
251                     x,
252                     top + 2,
253                     cWidth,
254                     myHeight,
255                     shouldValidate);
256             } else {
257                 // In case, we are in 3D mode _and_ have a non-transparent
258
// JComponent renderer, store the opaque state, set it
259
// to transparent, paint, then restore.
260
JComponent component = (JComponent) c;
261                 boolean hasBeenOpaque = component.isOpaque();
262                 component.setOpaque(false);
263                 rendererPane.paintComponent(
264                     g,
265                     c,
266                     this,
267                     x,
268                     top + 2,
269                     cWidth,
270                     myHeight,
271                     shouldValidate);
272                 component.setOpaque(hasBeenOpaque);
273             }
274         }
275         
276         if (comboIcon != null) {
277             // Paint the focus
278
boolean hasFocus = comboBox.hasFocus();
279             if (!borderPaintsFocus && hasFocus) {
280                 g.setColor(PlasticLookAndFeel.getFocusColor());
281                 int x = LEFT_INSET;
282                 int y = LEFT_INSET;
283                 int w = getWidth() - LEFT_INSET - RIGHT_INSET;
284                 int h = getHeight() - LEFT_INSET - RIGHT_INSET;
285                 g.drawRect(x, y, w - 1, h - 1);
286             }
287         }
288
289     }
290
291 }
292
Popular Tags