001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.swing.tabcontrol;
043:
044: import java.awt.*;
045: import java.awt.geom.AffineTransform;
046: import javax.swing.AbstractButton;
047: import javax.swing.ButtonModel;
048: import javax.swing.JComponent;
049: import javax.swing.SwingUtilities;
050:
051: import javax.swing.plaf.ComponentUI;
052: import javax.swing.plaf.basic.BasicHTML;
053: import javax.swing.plaf.basic.BasicToggleButtonUI;
054: import javax.swing.text.View;
055: import org.netbeans.swing.tabcontrol.SlideBarDataModel;
056: import org.netbeans.swing.tabcontrol.SlidingButton;
057:
058: /** Button UI for SlidingButton component that can paint rotated text.
059: * To change appearance, provide a subclass of this class or subclass of ComponentUI
060: * and register it via UIDefaults in standard Swing way.
061: * Typically the methods of interest when
062: * subclassing are <code>paintBackground</code> and <code>paintIconAndText</code>.
063: * <p>
064: * Instances of this class should be stateless, taking all data from model,
065: * such that a single instance can manage any number of buttons.
066: *
067: * @see SlidingButton
068: *
069: * @author Tim Boudreau, Dafe Simonek
070: */
071: public class SlidingButtonUI extends BasicToggleButtonUI {
072:
073: //TODO - just a temporary solution to have some default impl..
074: private static final BasicToggleButtonUI INSTANCE = new SlidingButtonUI();
075:
076: /** Private, no need for outer classes to instantiate */
077: protected SlidingButtonUI() {
078: }
079:
080: public static ComponentUI createUI(JComponent c) {
081: return INSTANCE;
082: }
083:
084: protected String getPropertyPrefix() {
085: //TODO -define own prefix?
086: return "ToggleButton.";
087: }
088:
089: public void paint(Graphics g, JComponent c) {
090: AbstractButton b = (AbstractButton) c;
091: ButtonModel model = b.getModel();
092: Dimension size = b.getSize();
093: FontMetrics fm = g.getFontMetrics();
094: Insets i = c.getInsets();
095: Rectangle viewRect = new Rectangle(size);
096: Rectangle iconRect = new Rectangle();
097: Rectangle textRect = new Rectangle();
098: Font f = c.getFont();
099: g.setFont(f);
100:
101: Rectangle rotatedViewRect;
102: Rectangle rotatedIconRect = new Rectangle();
103: Rectangle rotatedTextRect = new Rectangle();
104: SlidingButton slide = (SlidingButton) b;
105: Graphics2D g2d = (Graphics2D) g;
106: int orientation = slide.getOrientation();
107: if (orientation == SlideBarDataModel.SOUTH) {
108: rotatedViewRect = new Rectangle(0, 0, viewRect.width,
109: viewRect.height);
110: } else {
111: rotatedViewRect = new Rectangle(0, 0, viewRect.height,
112: viewRect.width);
113: }
114:
115: // layout the text and icon
116: String text = SwingUtilities.layoutCompoundLabel(c, fm, b
117: .getText(), b.getIcon(), b.getVerticalAlignment(), b
118: .getHorizontalAlignment(), b.getVerticalTextPosition(),
119: b.getHorizontalTextPosition(), rotatedViewRect,
120: rotatedIconRect, rotatedTextRect,
121: b.getText() == null ? 0 : b.getIconTextGap());
122:
123: if (orientation == SlideBarDataModel.SOUTH) {
124: iconRect = new Rectangle(viewRect.x + rotatedIconRect.x,
125: viewRect.y + rotatedIconRect.y,
126: rotatedIconRect.width, rotatedIconRect.height);
127: textRect = new Rectangle(viewRect.x + rotatedTextRect.x,
128: viewRect.y + rotatedTextRect.y,
129: rotatedTextRect.width, rotatedTextRect.height);
130: }
131: if (orientation == SlideBarDataModel.WEST) {
132: iconRect = new Rectangle(viewRect.x + rotatedIconRect.y,
133: viewRect.y + viewRect.height - rotatedIconRect.x
134: - rotatedIconRect.width,
135: rotatedIconRect.height, rotatedIconRect.width);
136: textRect = new Rectangle(viewRect.x + rotatedTextRect.y,
137: viewRect.y + viewRect.height - rotatedTextRect.y
138: - rotatedTextRect.width,
139: rotatedTextRect.height, rotatedTextRect.width);
140: }
141: if (orientation == SlideBarDataModel.EAST) {
142: iconRect = new Rectangle(viewRect.x + viewRect.width
143: - rotatedIconRect.y - rotatedIconRect.height,
144: viewRect.y + rotatedIconRect.x,
145: rotatedIconRect.height, rotatedIconRect.width);
146: textRect = new Rectangle(viewRect.x + viewRect.width
147: - rotatedTextRect.y - rotatedTextRect.height,
148: viewRect.y + rotatedTextRect.x,
149: rotatedTextRect.height, rotatedTextRect.width);
150: }
151:
152: g.setColor(b.getBackground());
153:
154: if (model.isArmed() && model.isPressed() || model.isSelected()
155: || model.isRollover()) {
156: paintButtonPressed(g, b);
157: } else if (b.isOpaque()) {
158: paintBackground(g2d, b);
159: }
160:
161: // Paint the Icon
162: if (b.getIcon() != null) {
163: paintIcon(g, b, iconRect);
164: }
165:
166: // Draw the Text
167: if (text != null && !text.equals("")) {
168:
169: AffineTransform saveTr = g2d.getTransform();
170: if (orientation != SlideBarDataModel.SOUTH) {
171: if (orientation == SlideBarDataModel.WEST) {
172: // rotate 90 degrees counterclockwise for WEST orientation
173: g2d.rotate(-Math.PI / 2);
174: g2d.translate(-c.getHeight(), 0);
175: } else {
176: // rotate 90 degrees clockwise for EAST orientation
177: g2d.rotate(Math.PI / 2);
178: g2d.translate(0, -c.getWidth());
179: }
180: }
181:
182: View v = (View) c.getClientProperty(BasicHTML.propertyKey);
183: if (v != null) {
184: v.paint(g, rotatedTextRect);
185: } else {
186: paintText(g, b, rotatedTextRect, text);
187: }
188:
189: // restore transformation
190: g2d.setTransform(saveTr);
191: }
192:
193: // draw the dashed focus line.
194: if (b.isFocusPainted() && b.hasFocus()) {
195: paintFocus(g, b, viewRect, textRect, iconRect);
196: }
197:
198: }
199:
200: protected void paintBackground(Graphics2D g, AbstractButton b) {
201: Dimension size = b.getSize();
202:
203: Insets insets = b.getInsets();
204: Insets margin = b.getMargin();
205:
206: g.fillRect(insets.left - margin.left, insets.top - margin.top,
207: size.width - (insets.left - margin.left)
208: - (insets.right - margin.right), size.height
209: - (insets.top - margin.top)
210: - (insets.bottom - margin.bottom));
211: }
212:
213: public Dimension getMinimumSize(JComponent c) {
214: return getPreferredSize(c);
215: }
216:
217: public Dimension getPreferredSize(JComponent c) {
218: SlidingButton b = (SlidingButton) c;
219: Dimension prefSize = super .getPreferredSize(c);
220: int orientation = b.getOrientation();
221:
222: if (orientation == SlideBarDataModel.SOUTH) {
223: return prefSize;
224: } else {
225: return new Dimension(prefSize.height, prefSize.width);
226: }
227: }
228:
229: public Dimension getMaximumSize(JComponent c) {
230: return getPreferredSize(c);
231: }
232: }
|