001: /*
002: * Copyright (c) 2001-2007 JGoodies Karsten Lentzsch. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of JGoodies Karsten Lentzsch nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package com.jgoodies.looks.plastic;
032:
033: import java.awt.*;
034:
035: import javax.swing.*;
036: import javax.swing.plaf.ComponentUI;
037: import javax.swing.plaf.basic.BasicHTML;
038: import javax.swing.plaf.metal.MetalToggleButtonUI;
039: import javax.swing.text.View;
040:
041: /**
042: * The JGoodies Plastic L&F implementation of <code>ToggleButtonUI</code>.
043: * It differs from its superclass in that it can add a pseudo 3D effect,
044: * and that the border can paint the focus.
045: *
046: * @author Karsten Lentzsch
047: * @version $Revision: 1.4 $
048: */
049: public class PlasticToggleButtonUI extends MetalToggleButtonUI {
050:
051: private static final PlasticToggleButtonUI INSTANCE = new PlasticToggleButtonUI();
052:
053: /*
054: * Implementation note: The protected visibility prevents
055: * the String value from being encrypted by the obfuscator.
056: * An encrypted String key would break the client property lookup
057: * in the #paint method below.
058: */
059: protected static final String HTML_KEY = BasicHTML.propertyKey;
060:
061: private boolean borderPaintsFocus;
062:
063: public static ComponentUI createUI(JComponent b) {
064: return INSTANCE;
065: }
066:
067: /**
068: * In addition to the superclass we check if the border paints the focus.
069: */
070: public void installDefaults(AbstractButton b) {
071: super .installDefaults(b);
072: borderPaintsFocus = Boolean.TRUE.equals(UIManager
073: .get("ToggleButton.borderPaintsFocus"));
074: }
075:
076: // Painting ***************************************************************
077:
078: public void update(Graphics g, JComponent c) {
079: AbstractButton b = (AbstractButton) c;
080: if (c.isOpaque()) {
081: if (isToolBarButton(b)) {
082: c.setOpaque(false);
083: } else if (b.isContentAreaFilled()) {
084: g.setColor(c.getBackground());
085: g.fillRect(0, 0, c.getWidth(), c.getHeight());
086:
087: if (is3D(b)) {
088: Rectangle r = new Rectangle(1, 1, c.getWidth() - 2,
089: c.getHeight() - 1);
090: PlasticUtils.add3DEffekt(g, r);
091: }
092: }
093: }
094: paint(g, c);
095: }
096:
097: /**
098: * Paints the focus close to the button's border.
099: */
100: protected void paintFocus(Graphics g, AbstractButton b,
101: Rectangle viewRect, Rectangle textRect, Rectangle iconRect) {
102:
103: if (borderPaintsFocus)
104: return;
105:
106: boolean isDefault = false;
107: int topLeftInset = isDefault ? 3 : 2;
108: int width = b.getWidth() - 1 - topLeftInset * 2;
109: int height = b.getHeight() - 1 - topLeftInset * 2;
110:
111: g.setColor(getFocusColor());
112: g.drawRect(topLeftInset, topLeftInset, width - 1, height - 1);
113: }
114:
115: /**
116: * Unlike the BasicToggleButtonUI.paint, we don't fill the content area;
117: * this has been done by the update method before.
118: */
119: public void paint(Graphics g, JComponent c) {
120: AbstractButton b = (AbstractButton) c;
121: ButtonModel model = b.getModel();
122:
123: Dimension size = b.getSize();
124: FontMetrics fm = g.getFontMetrics();
125:
126: Insets i = c.getInsets();
127:
128: Rectangle viewRect = new Rectangle(size);
129:
130: viewRect.x += i.left;
131: viewRect.y += i.top;
132: viewRect.width -= (i.right + viewRect.x);
133: viewRect.height -= (i.bottom + viewRect.y);
134:
135: Rectangle iconRect = new Rectangle();
136: Rectangle textRect = new Rectangle();
137:
138: Font f = c.getFont();
139: g.setFont(f);
140:
141: // layout the text and icon
142: String text = SwingUtilities.layoutCompoundLabel(c, fm, b
143: .getText(), b.getIcon(), b.getVerticalAlignment(), b
144: .getHorizontalAlignment(), b.getVerticalTextPosition(),
145: b.getHorizontalTextPosition(), viewRect, iconRect,
146: textRect, b.getText() == null ? 0 : b.getIconTextGap());
147:
148: g.setColor(b.getBackground());
149:
150: if (model.isArmed() && model.isPressed() || model.isSelected()) {
151: paintButtonPressed(g, b);
152: } /*else if (b.isOpaque() && b.isContentAreaFilled() && !(is3D(b))) {
153: g.fillRect(0, 0, size.width, size.height);
154:
155: Insets insets = b.getInsets();
156: Insets margin = b.getMargin();
157:
158: g.fillRect(insets.left - margin.left, insets.top - margin.top,
159: size.width - (insets.left-margin.left) - (insets.right - margin.right),
160: size.height - (insets.top-margin.top) - (insets.bottom - margin.bottom));
161:
162: }*/
163:
164: // Paint the Icon
165: if (b.getIcon() != null) {
166: paintIcon(g, b, iconRect);
167: }
168:
169: // Draw the Text
170: if (text != null && !text.equals("")) {
171: View v = (View) c.getClientProperty(HTML_KEY);
172: if (v != null) {
173: v.paint(g, textRect);
174: } else {
175: paintText(g, c, textRect, text);
176: }
177: }
178:
179: // draw the dashed focus line.
180: if (b.isFocusPainted() && b.hasFocus()) {
181: paintFocus(g, b, viewRect, textRect, iconRect);
182: }
183: }
184:
185: // Private Helper Code **************************************************************
186:
187: /**
188: * Checks and answers if this is button is in a tool bar.
189: *
190: * @param b the button to check
191: * @return true if in tool bar, false otherwise
192: */
193: protected boolean isToolBarButton(AbstractButton b) {
194: Container parent = b.getParent();
195: return parent != null
196: && (parent instanceof JToolBar || parent.getParent() instanceof JToolBar);
197: }
198:
199: /**
200: * Checks and answers if this button shall use a pseudo 3D effect.
201: *
202: * @param b the button to check
203: * @return true indicates a 3D effect, false flat
204: */
205: protected boolean is3D(AbstractButton b) {
206: if (PlasticUtils.force3D(b))
207: return true;
208: if (PlasticUtils.forceFlat(b))
209: return false;
210: ButtonModel model = b.getModel();
211: return PlasticUtils.is3D("ToggleButton.")
212: && b.isBorderPainted() && model.isEnabled()
213: && !model.isPressed();
214: }
215:
216: }
|