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.plaf;
043:
044: import java.awt.Color;
045: import java.awt.Component;
046: import java.awt.Dimension;
047: import java.awt.FontMetrics;
048: import java.awt.Graphics;
049: import java.awt.Insets;
050: import java.awt.Rectangle;
051: import java.util.HashMap;
052: import java.util.Map;
053: import javax.swing.Icon;
054: import javax.swing.JComponent;
055: import javax.swing.UIManager;
056: import org.netbeans.swing.tabcontrol.TabDisplayer;
057:
058: import javax.swing.plaf.ComponentUI;
059:
060: import org.openide.awt.HtmlRenderer;
061:
062: /**
063: * User interface of view type tabs designed to be consistent with Swing metal
064: * look and feel.
065: *
066: * @author Dafe Simonek
067: */
068: public final class MetalViewTabDisplayerUI extends
069: AbstractViewTabDisplayerUI {
070:
071: /**
072: * *********** constants ******************
073: */
074: private static final int TXT_X_PAD = 5;
075:
076: private static final int ICON_X_LEFT_PAD = 5;
077: private static final int ICON_X_RIGHT_PAD = 2;
078:
079: private static final int BUMP_X_PAD = 5;
080: private static final int BUMP_Y_PAD = 4;
081:
082: /**
083: * ****** static fields **********
084: */
085:
086: private static Color inactBgColor, actBgColor, borderHighlight,
087: borderShadow;
088:
089: private static Map<Integer, String[]> buttonIconPaths;
090:
091: /**
092: * ******* instance fields *********
093: */
094:
095: private Dimension prefSize;
096:
097: /**
098: * Reusable Rectangle to optimize rectangle creation/garbage collection
099: * during paints
100: */
101: private Rectangle tempRect = new Rectangle();
102:
103: /**
104: * Should be constructed only from createUI method.
105: */
106: private MetalViewTabDisplayerUI(TabDisplayer displayer) {
107: super (displayer);
108: prefSize = new Dimension(100, 19);
109: }
110:
111: public static ComponentUI createUI(JComponent c) {
112: return new MetalViewTabDisplayerUI((TabDisplayer) c);
113: }
114:
115: public Dimension getPreferredSize(JComponent c) {
116: FontMetrics fm = getTxtFontMetrics();
117: int height = fm == null ? 21 : fm.getAscent() + 2
118: * fm.getDescent() + 4;
119: Insets insets = c.getInsets();
120: prefSize.height = height + insets.bottom + insets.top;
121: return prefSize;
122: }
123:
124: /**
125: * Overrides basic paint mathod, adds painting of overall blue or gray
126: * bottom area, depending on activation status value
127: */
128: public void paint(Graphics g, JComponent c) {
129: super .paint(g, c);
130: paintBottomBorder(g, c);
131: }
132:
133: /**
134: * Paints bottom "activation" line
135: */
136: private void paintBottomBorder(Graphics g, JComponent c) {
137: Color color = isActive() ? getActBgColor() : getInactBgColor();
138: g.setColor(color);
139: Rectangle bounds = c.getBounds();
140: g.fillRect(1, bounds.height - 3, bounds.width - 1, 2);
141: g.setColor(getBorderShadow());
142: g.drawLine(1, bounds.height - 1, bounds.width - 1,
143: bounds.height - 1);
144: }
145:
146: protected void paintTabContent(Graphics g, int index, String text,
147: int x, int y, int width, int height) {
148: FontMetrics fm = getTxtFontMetrics();
149: // setting font already here to compute string width correctly
150: g.setFont(getTxtFont());
151: int txtWidth = width;
152: if (isSelected(index)) {
153: Component buttons = getControlButtons();
154: int buttonsWidth = 0;
155: if (null != buttons) {
156: Dimension buttonsSize = buttons.getPreferredSize();
157: buttonsWidth = buttonsSize.width + ICON_X_LEFT_PAD
158: + ICON_X_RIGHT_PAD;
159: txtWidth = width - (buttonsWidth + 2 * TXT_X_PAD);
160: buttons.setLocation(x + txtWidth + 2 * TXT_X_PAD
161: + ICON_X_LEFT_PAD, y
162: + (height - buttonsSize.height) / 2 + 1);
163: }
164:
165: txtWidth = (int) HtmlRenderer.renderString(text, g, x
166: + TXT_X_PAD, height - fm.getDescent() - 4,
167: txtWidth, height, getTxtFont(), UIManager
168: .getColor("textText"),
169: HtmlRenderer.STYLE_TRUNCATE, true);
170: int bumpWidth = width
171: - (TXT_X_PAD + txtWidth + BUMP_X_PAD + buttonsWidth);
172: if (bumpWidth > 0) {
173: paintBump(index, g, x + TXT_X_PAD + txtWidth
174: + BUMP_X_PAD, y + BUMP_Y_PAD, bumpWidth, height
175: - 2 * BUMP_Y_PAD);
176: }
177: } else {
178: txtWidth = width - 2 * TXT_X_PAD;
179: HtmlRenderer.renderString(text, g, x + TXT_X_PAD, height
180: - fm.getDescent() - 4, txtWidth, height,
181: getTxtFont(), UIManager.getColor("textText"),
182: HtmlRenderer.STYLE_TRUNCATE, true);
183: }
184: }
185:
186: protected void paintTabBorder(Graphics g, int index, int x, int y,
187: int width, int height) {
188: Color highlight = getBorderHighlight();
189: Color shadow = getBorderShadow();
190: boolean isSelected = isSelected(index);
191:
192: boolean isFirst = index == 0;
193: boolean isLast = index == getDataModel().size() - 1;
194:
195: g.translate(x, y);
196:
197: // paint darker lines
198: g.setColor(shadow);
199: if (!isFirst) {
200: g.drawLine(0, 0, 0, height - 5);
201: }
202: if (!isSelected) {
203: g.drawLine(1, height - 5, isLast ? width - 1 : width,
204: height - 5);
205: }
206: // paint brighter lines
207: g.setColor(highlight);
208: g.drawLine(1, 0, width - 1, 0);
209: if (isFirst) {
210: g.drawLine(0, 0, 0, height - 2);
211: }
212: if (!isSelected) {
213: g.drawLine(0, height - 4, isLast ? width - 1 : width,
214: height - 4);
215: }
216:
217: g.translate(-x, -y);
218: }
219:
220: protected void paintTabBackground(Graphics g, int index, int x,
221: int y, int width, int height) {
222: boolean selected = isSelected(index);
223: boolean highlighted = selected && isActive();
224: boolean attention = isAttention(index);
225: if (highlighted && !attention) {
226: g.setColor(getActBgColor());
227: g.fillRect(x, y, width, height - 3);
228: } else if (attention) {
229: g.setColor(MetalEditorTabCellRenderer.ATTENTION_COLOR);
230: g.fillRect(x, y, width, height - 3);
231: } else {
232: g.setColor(getInactBgColor());
233: g.fillRect(x, y, width, height - 3);
234: }
235: }
236:
237: private void paintBump(int index, Graphics g, int x, int y,
238: int width, int height) {
239: ColorUtil.paintViewTabBump(g, x, y, width, height,
240: isFocused(index) ? ColorUtil.FOCUS_TYPE
241: : ColorUtil.UNSEL_TYPE);
242: }
243:
244: static Color getInactBgColor() {
245: if (inactBgColor == null) {
246: inactBgColor = (Color) UIManager.get("inactiveCaption");
247: if (inactBgColor == null) {
248: inactBgColor = new Color(204, 204, 204);
249: }
250: }
251: return inactBgColor;
252: }
253:
254: static Color getActBgColor() {
255: if (actBgColor == null) {
256: actBgColor = (Color) UIManager.get("activeCaption");
257: if (actBgColor == null) {
258: actBgColor = new Color(204, 204, 255);
259: }
260: }
261: return actBgColor;
262: }
263:
264: private Color getBorderHighlight() {
265: if (borderHighlight == null) {
266: borderHighlight = getInactBgColor().brighter();
267: }
268: return borderHighlight;
269: }
270:
271: private Color getBorderShadow() {
272: if (borderShadow == null) {
273: borderShadow = getInactBgColor().darker();
274: }
275: return borderShadow;
276: }
277:
278: private static void initIcons() {
279: if (null == buttonIconPaths) {
280: buttonIconPaths = new HashMap<Integer, String[]>(7);
281:
282: //close button
283: String[] iconPaths = new String[4];
284: iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/metal_bigclose_enabled.png"; // NOI18N
285: iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/metal_bigclose_pressed.png"; // NOI18N
286: iconPaths[TabControlButton.STATE_DISABLED] = iconPaths[TabControlButton.STATE_DEFAULT];
287: iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/metal_bigclose_rollover.png"; // NOI18N
288: buttonIconPaths.put(TabControlButton.ID_CLOSE_BUTTON,
289: iconPaths);
290:
291: //slide/pin button
292: iconPaths = new String[4];
293: iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/metal_slideright_enabled.png"; // NOI18N
294: iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/metal_slideright_pressed.png"; // NOI18N
295: iconPaths[TabControlButton.STATE_DISABLED] = iconPaths[TabControlButton.STATE_DEFAULT];
296: iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/metal_slideright_rollover.png"; // NOI18N
297: buttonIconPaths.put(TabControlButton.ID_SLIDE_RIGHT_BUTTON,
298: iconPaths);
299:
300: iconPaths = new String[4];
301: iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/metal_slideleft_enabled.png"; // NOI18N
302: iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/metal_slideleft_pressed.png"; // NOI18N
303: iconPaths[TabControlButton.STATE_DISABLED] = iconPaths[TabControlButton.STATE_DEFAULT];
304: iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/metal_slideleft_rollover.png"; // NOI18N
305: buttonIconPaths.put(TabControlButton.ID_SLIDE_LEFT_BUTTON,
306: iconPaths);
307:
308: iconPaths = new String[4];
309: iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/metal_slidebottom_enabled.png"; // NOI18N
310: iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/metal_slidebottom_pressed.png"; // NOI18N
311: iconPaths[TabControlButton.STATE_DISABLED] = iconPaths[TabControlButton.STATE_DEFAULT];
312: iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/metal_slidebottom_rollover.png"; // NOI18N
313: buttonIconPaths.put(TabControlButton.ID_SLIDE_DOWN_BUTTON,
314: iconPaths);
315:
316: iconPaths = new String[4];
317: iconPaths[TabControlButton.STATE_DEFAULT] = "org/netbeans/swing/tabcontrol/resources/metal_pin_enabled.png"; // NOI18N
318: iconPaths[TabControlButton.STATE_PRESSED] = "org/netbeans/swing/tabcontrol/resources/metal_pin_pressed.png"; // NOI18N
319: iconPaths[TabControlButton.STATE_DISABLED] = iconPaths[TabControlButton.STATE_DEFAULT];
320: iconPaths[TabControlButton.STATE_ROLLOVER] = "org/netbeans/swing/tabcontrol/resources/metal_pin_rollover.png"; // NOI18N
321: buttonIconPaths.put(TabControlButton.ID_PIN_BUTTON,
322: iconPaths);
323: }
324: }
325:
326: public Icon getButtonIcon(int buttonId, int buttonState) {
327: Icon res = null;
328: initIcons();
329: String[] paths = buttonIconPaths.get(buttonId);
330: if (null != paths && buttonState >= 0
331: && buttonState < paths.length) {
332: res = TabControlButtonFactory.getIcon(paths[buttonState]);
333: }
334: return res;
335: }
336: }
|