001: /*
002: * SmoothGradientComboBoxButton.java
003: *
004: * Copyright (C) 2002, 2003, 2004, 2005, 2006 Takis Diakoumis
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: */
021:
022: package org.underworldlabs.swing.plaf.smoothgradient;
023:
024: import java.awt.Component;
025: import java.awt.Graphics;
026: import java.awt.Insets;
027:
028: import javax.swing.CellRendererPane;
029: import javax.swing.DefaultButtonModel;
030: import javax.swing.Icon;
031: import javax.swing.JButton;
032: import javax.swing.JComboBox;
033: import javax.swing.JComponent;
034: import javax.swing.JList;
035: import javax.swing.JPanel;
036: import javax.swing.ListCellRenderer;
037: import javax.swing.UIManager;
038:
039: /* ----------------------------------------------------------
040: * CVS NOTE: Changes to the CVS repository prior to the
041: * release of version 3.0.0beta1 has meant a
042: * resetting of CVS revision numbers.
043: * ----------------------------------------------------------
044: */
045:
046: /**
047: *
048: * @author Takis Diakoumis
049: * @version $Revision: 1.4 $
050: * @date $Date: 2006/05/14 06:56:07 $
051: */
052: final class SmoothGradientComboBoxButton extends JButton {
053:
054: private static final int LEFT_INSET = 2;
055: private static final int RIGHT_INSET = 3;
056:
057: private final JList listBox;
058: private final CellRendererPane rendererPane;
059:
060: private JComboBox comboBox;
061: private Icon comboIcon;
062: protected boolean iconOnly = false;
063: private boolean borderPaintsFocus;
064:
065: /**
066: * Constructs a <code>PlasticComboBoxButton</code>.
067: */
068: SmoothGradientComboBoxButton(JComboBox comboBox, Icon comboIcon,
069: boolean iconOnly, CellRendererPane rendererPane,
070: JList listBox) {
071: super ("");
072: setModel(new DefaultButtonModel() {
073: public void setArmed(boolean armed) {
074: super .setArmed(isPressed() || armed);
075: }
076: });
077: this .comboBox = comboBox;
078: this .comboIcon = comboIcon;
079: this .iconOnly = iconOnly;
080: this .rendererPane = rendererPane;
081: this .listBox = listBox;
082: setEnabled(comboBox.isEnabled());
083: setRequestFocusEnabled(comboBox.isEnabled());
084: setBorder(UIManager.getBorder("ComboBox.arrowButtonBorder"));
085: setMargin(new Insets(0, LEFT_INSET, 0, RIGHT_INSET));
086: borderPaintsFocus = Boolean.TRUE.equals(UIManager
087: .get("ComboBox.borderPaintsFocus"));
088: }
089:
090: public JComboBox getComboBox() {
091: return comboBox;
092: }
093:
094: public void setComboBox(JComboBox cb) {
095: comboBox = cb;
096: }
097:
098: public Icon getComboIcon() {
099: return comboIcon;
100: }
101:
102: public void setComboIcon(Icon i) {
103: comboIcon = i;
104: }
105:
106: public boolean isIconOnly() {
107: return iconOnly;
108: }
109:
110: public void setIconOnly(boolean b) {
111: iconOnly = b;
112: }
113:
114: public boolean isFocusTraversable() {
115: return SmoothGradientLookUtils.IS_BEFORE_14
116: && (!comboBox.isEditable()) && comboBox.isEnabled();
117: }
118:
119: public void setEnabled(boolean enabled) {
120: super .setEnabled(enabled);
121: // Set the background and foreground to the combobox colors.
122: if (enabled) {
123: setBackground(comboBox.getBackground());
124: setForeground(comboBox.getForeground());
125: } else {
126: setBackground(UIManager
127: .getColor("ComboBox.disabledBackground"));
128: setForeground(UIManager
129: .getColor("ComboBox.disabledForeground"));
130: }
131: }
132:
133: /**
134: * Checks and answers if we should paint a pseudo 3D effect.
135: */
136: private boolean is3D() {
137: if (SmoothGradientUtils.force3D(comboBox))
138: return true;
139: if (SmoothGradientUtils.forceFlat(comboBox))
140: return false;
141: return SmoothGradientUtils.is3D("ComboBox.");
142: }
143:
144: /**
145: * Paints the component; honors the 3D settings and
146: * tries to switch the renderer component to transparent.
147: */
148: public void paintComponent(Graphics g) {
149: super .paintComponent(g);
150: boolean leftToRight = SmoothGradientUtils
151: .isLeftToRight(comboBox);
152:
153: Insets insets = getInsets();
154:
155: int width = getWidth() - (insets.left + insets.right);
156: int height = getHeight() - (insets.top + insets.bottom);
157:
158: if (height <= 0 || width <= 0) {
159: return;
160: }
161:
162: int left = insets.left;
163: int top = insets.top;
164: int right = left + (width - 1);
165:
166: int iconWidth = 0;
167: int iconLeft = (leftToRight) ? right : left;
168:
169: // Paint the icon
170: if (comboIcon != null) {
171: iconWidth = comboIcon.getIconWidth();
172: int iconHeight = comboIcon.getIconHeight();
173: int iconTop;
174:
175: if (iconOnly) {
176: iconLeft = (getWidth() - iconWidth) / 2;
177: iconTop = (getHeight() - iconHeight) / 2;
178: } else {
179: if (leftToRight) {
180: iconLeft = (left + (width - 1)) - iconWidth;
181: } else {
182: iconLeft = left;
183: }
184: iconTop = (getHeight() - iconHeight) / 2;
185: }
186:
187: comboIcon.paintIcon(this , g, iconLeft, iconTop);
188:
189: }
190:
191: // Let the renderer paint
192: if (!iconOnly && comboBox != null) {
193: ListCellRenderer renderer = comboBox.getRenderer();
194: boolean renderPressed = getModel().isPressed();
195: Component c = renderer.getListCellRendererComponent(
196: listBox, comboBox.getSelectedItem(), -1,
197: renderPressed, false);
198: c.setFont(rendererPane.getFont());
199:
200: if (model.isArmed() && model.isPressed()) {
201: if (isOpaque()) {
202: c
203: .setBackground(UIManager
204: .getColor("Button.select"));
205: }
206: c.setForeground(comboBox.getForeground());
207: } else if (!comboBox.isEnabled()) {
208: if (isOpaque()) {
209: c.setBackground(UIManager
210: .getColor("ComboBox.disabledBackground"));
211: }
212: c.setForeground(UIManager
213: .getColor("ComboBox.disabledForeground"));
214: } else {
215: c.setForeground(comboBox.getForeground());
216: c.setBackground(comboBox.getBackground());
217: }
218:
219: int cWidth = width - (insets.right + iconWidth);
220:
221: // Fix for 4238829: should lay out the JPanel.
222: boolean shouldValidate = c instanceof JPanel;
223: int x = leftToRight ? left : left + iconWidth;
224: int myHeight = getHeight() - LEFT_INSET - RIGHT_INSET
225: - (SmoothGradientLookUtils.IS_BEFORE_14 ? 2 : 1);
226:
227: if (!is3D()) {
228: rendererPane.paintComponent(g, c, this , x, top + 1,
229: cWidth, myHeight, shouldValidate);
230: } else if (!(c instanceof JComponent)) {
231: rendererPane.paintComponent(g, c, this , x, top + 1,
232: cWidth, myHeight, shouldValidate);
233: //LookUtils.log("Custom renderer detected: " + c);
234: //LookUtils.log("Custom renderer superclass: " + c.getClass().getSuperclass().getName());
235: } else {
236: // In case, we are in 3D mode _and_ have a JComponent renderer,
237: // store the opaque state, set it to transparent, paint, then restore.
238: JComponent component = (JComponent) c;
239: boolean hasBeenOpaque = component.isOpaque();
240: component.setOpaque(false);
241: rendererPane.paintComponent(g, c, this , x, top + 1,
242: cWidth, myHeight, shouldValidate);
243: component.setOpaque(hasBeenOpaque);
244: }
245: }
246:
247: if (comboIcon != null) {
248: // Paint the focus
249: boolean hasFocus = SmoothGradientLookUtils.IS_BEFORE_14 ? hasFocus()
250: : comboBox.hasFocus();
251: if (!borderPaintsFocus && hasFocus) {
252: g.setColor(SmoothGradientLookAndFeel.getFocusColor());
253: int x = LEFT_INSET;
254: int y = LEFT_INSET;
255: int w = getWidth() - LEFT_INSET - RIGHT_INSET;
256: int h = getHeight() - LEFT_INSET - RIGHT_INSET;
257: g.drawRect(x, y, w - 1, h - 1);
258: }
259: }
260:
261: }
262:
263: }
|