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: * WinVistaEditorTabCellRenderer.java
043: *
044: */
045:
046: package org.netbeans.swing.tabcontrol.plaf;
047:
048: import javax.swing.*;
049: import java.awt.*;
050: import org.netbeans.swing.tabcontrol.TabDisplayer;
051:
052: /**
053: * Windows Vista implementation of tab renderer
054: *
055: * @author S. Aubrecht
056: */
057: final class WinVistaEditorTabCellRenderer extends
058: AbstractTabCellRenderer {
059: //Default insets values for Vista look and feel
060: private static final int TOP_INSET = 0;
061: private static final int LEFT_INSET = 3;
062: private static final int RIGHT_INSET = 0;
063: static final int BOTTOM_INSET = 0;
064:
065: //Painters which will be used for the various states, to pass to superclass
066: //constructor
067: private static final TabPainter leftClip = new WinVistaLeftClipPainter();
068: private static final TabPainter rightClip = new WinVistaRightClipPainter();
069: private static final TabPainter normal = new WinVistaPainter();
070:
071: /**
072: * Creates a new instance of WinVistaEditorTabCellRenderer
073: */
074: public WinVistaEditorTabCellRenderer() {
075: super (leftClip, normal, rightClip, new Dimension(32, 42));
076: }
077:
078: /**
079: * Vista look and feel makes selected tab wider by 2 pixels on each side
080: */
081: public int getPixelsToAddToSelection() {
082: return 0;
083: }
084:
085: public Dimension getPadding() {
086: Dimension d = super .getPadding();
087: d.width = isShowCloseButton()
088: && !Boolean.getBoolean("nb.tabs.suppressCloseButton") ? 32
089: : 16;
090: return d;
091: }
092:
093: private static final Color getUnselFillBrightUpperColor() {
094: Color result = UIManager
095: .getColor("tab_unsel_fill_bright_upper"); //NOI18N
096: if (result == null) {
097: result = new Color(235, 235, 235);
098: }
099: return result;
100: }
101:
102: private static final Color getUnselFillDarkUpperColor() {
103: Color result = UIManager.getColor("tab_unsel_fill_dark_upper"); //NOI18N
104: if (result == null) {
105: result = new Color(229, 229, 229);
106: }
107: return result;
108: }
109:
110: private static final Color getUnselFillBrightLowerColor() {
111: Color result = UIManager
112: .getColor("tab_unsel_fill_bright_lower"); //NOI18N
113: if (result == null) {
114: result = new Color(214, 214, 214);
115: }
116: return result;
117: }
118:
119: private static final Color getUnselFillDarkLowerColor() {
120: Color result = UIManager.getColor("tab_unsel_fill_dark_lower"); //NOI18N
121: if (result == null) {
122: result = new Color(203, 203, 203);
123: }
124: return result;
125: }
126:
127: private static final Color getSelFillColor() {
128: Color result = UIManager.getColor("tab_sel_fill"); //NOI18N
129: if (result == null) {
130: result = new Color(244, 244, 244);
131: }
132: return result;
133: }
134:
135: private static final Color getFocusFillUpperColor() {
136: Color result = UIManager.getColor("tab_focus_fill_upper"); //NOI18N
137: if (result == null) {
138: result = new Color(242, 249, 252);
139: }
140: return result;
141: }
142:
143: private static final Color getFocusFillBrightLowerColor() {
144: Color result = UIManager
145: .getColor("tab_focus_fill_bright_lower"); //NOI18N
146: if (result == null) {
147: result = new Color(225, 241, 249);
148: }
149: return result;
150: }
151:
152: private static final Color getFocusFillDarkLowerColor() {
153: Color result = UIManager.getColor("tab_focus_fill_dark_lower"); //NOI18N
154: if (result == null) {
155: result = new Color(216, 236, 246);
156: }
157: return result;
158: }
159:
160: private static final Color getMouseOverFillBrightUpperColor() {
161: Color result = UIManager
162: .getColor("tab_mouse_over_fill_bright_upper"); //NOI18N
163: if (result == null) {
164: result = new Color(223, 242, 252);
165: }
166: return result;
167: }
168:
169: private static final Color getMouseOverFillDarkUpperColor() {
170: Color result = UIManager
171: .getColor("tab_mouse_over_fill_dark_upper"); //NOI18N
172: if (result == null) {
173: result = new Color(214, 239, 252);
174: }
175: return result;
176: }
177:
178: private static final Color getMouseOverFillBrightLowerColor() {
179: Color result = UIManager
180: .getColor("tab_mouse_over_fill_bright_lower"); //NOI18N
181: if (result == null) {
182: result = new Color(189, 228, 250);
183: }
184: return result;
185: }
186:
187: private static final Color getMouseOverFillDarkLowerColor() {
188: Color result = UIManager
189: .getColor("tab_mouse_over_fill_dark_lower"); //NOI18N
190: if (result == null) {
191: result = new Color(171, 221, 248);
192: }
193: return result;
194: }
195:
196: private static final Color getTxtColor() {
197: Color result = UIManager.getColor("TabbedPane.foreground"); //NOI18N
198: if (result == null) {
199: result = new Color(0, 0, 0);
200: }
201: return result;
202: }
203:
204: static final Color getBorderColor() {
205: Color result = UIManager.getColor("tab_border"); //NOI18N
206: if (result == null) {
207: result = new Color(137, 140, 149);
208: }
209: return result;
210: }
211:
212: private static final Color getSelBorderColor() {
213: Color result = UIManager.getColor("tab_sel_border"); //NOI18N
214: if (result == null) {
215: result = new Color(60, 127, 177);
216: }
217: return result;
218: }
219:
220: private static final Color getBorderInnerColor() {
221: Color result = UIManager.getColor("tab_border_inner"); //NOI18N
222: if (result == null) {
223: result = new Color(255, 255, 255);
224: }
225: return result;
226: }
227:
228: public Color getSelectedActivatedForeground() {
229: return getTxtColor();
230: }
231:
232: public Color getSelectedForeground() {
233: return getTxtColor();
234: }
235:
236: private static void paintTabGradient(Graphics g,
237: WinVistaEditorTabCellRenderer ren, Polygon poly) {
238: Rectangle rect = poly.getBounds();
239: boolean selected = ren.isSelected();
240: boolean focused = selected && ren.isActive();
241: boolean attention = ren.isAttention();
242: boolean mouseOver = ren.isArmed();
243: if (focused && !attention) {
244: rect.height++;
245: ColorUtil.vistaFillRectGradient((Graphics2D) g, rect,
246: getFocusFillUpperColor(),
247: getFocusFillBrightLowerColor(),
248: getFocusFillDarkLowerColor());
249: } else if (selected && !attention) {
250: rect.height++;
251: g.setColor(getSelFillColor());
252: g.fillPolygon(poly);
253: } else if (mouseOver && !attention) {
254: ColorUtil.vistaFillRectGradient((Graphics2D) g, rect,
255: getMouseOverFillBrightUpperColor(),
256: getMouseOverFillDarkUpperColor(),
257: getMouseOverFillBrightLowerColor(),
258: getMouseOverFillDarkLowerColor());
259: } else if (attention) {
260: Color a = new Color(255, 255, 128);
261: Color b = new Color(230, 200, 64);
262: ColorUtil.xpFillRectGradient((Graphics2D) g, rect, a, b);
263: } else {
264: ColorUtil.vistaFillRectGradient((Graphics2D) g, rect,
265: getUnselFillBrightUpperColor(),
266: getUnselFillDarkUpperColor(),
267: getUnselFillBrightLowerColor(),
268: getUnselFillDarkLowerColor());
269: }
270:
271: }
272:
273: protected int getCaptionYAdjustment() {
274: return 0;
275: }
276:
277: protected int getIconYAdjustment() {
278: return -2;
279: }
280:
281: private static class WinVistaPainter implements TabPainter {
282:
283: public Insets getBorderInsets(Component c) {
284: return new Insets(TOP_INSET, LEFT_INSET, BOTTOM_INSET,
285: RIGHT_INSET);
286: }
287:
288: public void getCloseButtonRectangle(JComponent jc,
289: final Rectangle rect, Rectangle bounds) {
290:
291: WinVistaEditorTabCellRenderer ren = (WinVistaEditorTabCellRenderer) jc;
292:
293: if (!ren.isShowCloseButton()) {
294: rect.x = -100;
295: rect.y = -100;
296: rect.width = 0;
297: rect.height = 0;
298: return;
299: }
300: String iconPath = findIconPath(ren);
301: Icon icon = TabControlButtonFactory.getIcon(iconPath);
302: int iconWidth = icon.getIconWidth();
303: int iconHeight = icon.getIconHeight();
304: rect.x = bounds.x + bounds.width - iconWidth - 2;
305: rect.y = bounds.y
306: + (Math.max(0, bounds.height / 2 - iconHeight / 2));
307: rect.width = iconWidth;
308: rect.height = iconHeight;
309: }
310:
311: /**
312: * Returns path of icon which is correct for currect state of tab at given
313: * index
314: */
315: private String findIconPath(
316: WinVistaEditorTabCellRenderer renderer) {
317: if (renderer.inCloseButton() && renderer.isPressed()) {
318: return "org/netbeans/swing/tabcontrol/resources/vista_close_pressed.png"; // NOI18N
319: }
320: if (renderer.inCloseButton()) {
321: return "org/netbeans/swing/tabcontrol/resources/vista_close_rollover.png"; // NOI18N
322: }
323: return "org/netbeans/swing/tabcontrol/resources/vista_close_enabled.png"; // NOI18N
324: }
325:
326: public Polygon getInteriorPolygon(Component c) {
327: WinVistaEditorTabCellRenderer ren = (WinVistaEditorTabCellRenderer) c;
328:
329: Insets ins = getBorderInsets(c);
330: Polygon p = new Polygon();
331: int x = 0;
332: int y = 0;
333:
334: int width = ren.isRightmost() ? c.getWidth() - 1 : c
335: .getWidth();
336: int height = c.getHeight() - ins.bottom;
337:
338: //just a plain rectangle
339: p.addPoint(x, y + ins.top);
340: p.addPoint(x + width, y + ins.top);
341: p.addPoint(x + width, y + height - 1);
342: p.addPoint(x, y + height - 1);
343: return p;
344: }
345:
346: public boolean isBorderOpaque() {
347: return true;
348: }
349:
350: public void paintBorder(Component c, Graphics g, int x, int y,
351: int width, int height) {
352: WinVistaEditorTabCellRenderer ren = (WinVistaEditorTabCellRenderer) c;
353:
354: g.translate(x, y);
355:
356: Color borderColor = ((ren.isActive() && ren.isSelected()) || ren
357: .isArmed()) ? getSelBorderColor()
358: : getBorderColor();
359: g.setColor(borderColor);
360: int left = 0;
361: //left
362: if (ren.isLeftmost())
363: g.drawLine(0, 0, 0, height - 1);
364: //top
365: g.drawLine(0, 0, width - 1, 0);
366: //right
367: if ((ren.isActive() && ren.isNextTabSelected())
368: || ren.isNextTabArmed())
369: g.setColor(getSelBorderColor());
370: g.drawLine(width - 1, 0, width - 1, height - 2);
371: //bottom
372: g.setColor(getBorderColor());
373: if (!ren.isSelected()) {
374: g.drawLine(0, height - 1, width - 1, height - 1);
375: } else {
376: g
377: .drawLine(width - 1, height - 1, width - 1,
378: height - 1);
379: }
380:
381: //inner white border
382: g.setColor(getBorderInnerColor());
383: //top
384: g.drawLine(1, 1, width - 2, 1);
385: if (ren.isSelected())
386: height++;
387: //left
388: if (ren.isLeftmost())
389: g.drawLine(1, 1, 1, height - 2);
390: else
391: g.drawLine(0, 1, 0, height - 2);
392: //right
393: g.drawLine(width - 2, 1, width - 2, height - 2);
394:
395: g.translate(-x, -y);
396: }
397:
398: public void paintInterior(Graphics g, Component c) {
399: WinVistaEditorTabCellRenderer ren = (WinVistaEditorTabCellRenderer) c;
400: Polygon poly = getInteriorPolygon(ren);
401: paintTabGradient(g, ren, poly);
402:
403: //Get the close button bounds, more or less
404: Rectangle r = new Rectangle();
405: getCloseButtonRectangle(ren, r, new Rectangle(0, 0, ren
406: .getWidth(), ren.getHeight()));
407:
408: if (!g.hitClip(r.x, r.y, r.width, r.height)) {
409: return;
410: }
411:
412: //paint close button
413: String iconPath = findIconPath(ren);
414: Icon icon = TabControlButtonFactory.getIcon(iconPath);
415: icon.paintIcon(ren, g, r.x, r.y);
416: }
417:
418: public boolean supportsCloseButton(JComponent renderer) {
419: return renderer instanceof TabDisplayer ? ((TabDisplayer) renderer)
420: .isShowCloseButton()
421: : true;
422: }
423:
424: }
425:
426: private static class WinVistaLeftClipPainter implements TabPainter {
427:
428: public Insets getBorderInsets(Component c) {
429: return new Insets(TOP_INSET, LEFT_INSET, BOTTOM_INSET,
430: RIGHT_INSET);
431: }
432:
433: public Polygon getInteriorPolygon(Component c) {
434: WinVistaEditorTabCellRenderer ren = (WinVistaEditorTabCellRenderer) c;
435:
436: Insets ins = getBorderInsets(c);
437: Polygon p = new Polygon();
438: int x = 0;
439: int y = 0;
440:
441: int width = ren.isRightmost() ? c.getWidth() - 1 : c
442: .getWidth();
443: int height = c.getHeight() - ins.bottom;
444:
445: //just a plain rectangle
446: p.addPoint(x, y + ins.top);
447: p.addPoint(x + width, y + ins.top);
448: p.addPoint(x + width, y + height - 1);
449: p.addPoint(x, y + height - 1);
450: return p;
451: }
452:
453: public void paintBorder(Component c, Graphics g, int x, int y,
454: int width, int height) {
455:
456: WinVistaEditorTabCellRenderer ren = (WinVistaEditorTabCellRenderer) c;
457: g.translate(x, y);
458:
459: Color borderColor = ((ren.isActive() && ren.isSelected()) || ren
460: .isArmed()) ? getSelBorderColor()
461: : getBorderColor();
462: g.setColor(borderColor);
463: int left = 0;
464: //left
465: //no line
466: //top
467: g.drawLine(0, 0, width - 1, 0);
468: //right
469: if ((ren.isActive() && ren.isNextTabSelected())
470: || ren.isNextTabArmed())
471: g.setColor(getSelBorderColor());
472: g.drawLine(width - 1, 0, width - 1, height - 2);
473: //bottom
474: g.setColor(getBorderColor());
475: if (!ren.isSelected()) {
476: g.drawLine(0, height - 1, width - 1, height - 1);
477: } else {
478: g
479: .drawLine(width - 1, height - 1, width - 1,
480: height - 1);
481: }
482:
483: //inner white border
484: g.setColor(getBorderInnerColor());
485: //top
486: g.drawLine(0, 1, width - 2, 1);
487: if (ren.isSelected())
488: height++;
489: //left
490: //no line
491: //right
492: g.drawLine(width - 2, 1, width - 2, height - 2);
493:
494: g.translate(-x, -y);
495: }
496:
497: public void paintInterior(Graphics g, Component c) {
498: WinVistaEditorTabCellRenderer ren = (WinVistaEditorTabCellRenderer) c;
499:
500: Polygon poly = getInteriorPolygon(ren);
501: paintTabGradient(g, ren, poly);
502: }
503:
504: public boolean isBorderOpaque() {
505: return true;
506: }
507:
508: public boolean supportsCloseButton(JComponent renderer) {
509: return false;
510: }
511:
512: public void getCloseButtonRectangle(JComponent jc,
513: final Rectangle rect, Rectangle bounds) {
514: rect.setBounds(-20, -20, 0, 0);
515: }
516:
517: }
518:
519: private static class WinVistaRightClipPainter implements TabPainter {
520:
521: public Insets getBorderInsets(Component c) {
522: return new Insets(TOP_INSET, LEFT_INSET, BOTTOM_INSET,
523: RIGHT_INSET);
524: }
525:
526: public boolean isBorderOpaque() {
527: return true;
528: }
529:
530: public Polygon getInteriorPolygon(Component c) {
531: WinVistaEditorTabCellRenderer ren = (WinVistaEditorTabCellRenderer) c;
532:
533: Insets ins = getBorderInsets(c);
534: Polygon p = new Polygon();
535: int x = 0;
536: int y = 0;
537:
538: int width = c.getWidth() + 1;
539: int height = c.getHeight() - ins.bottom;
540:
541: //just a plain rectangle
542: p.addPoint(x, y + ins.top);
543: p.addPoint(x + width, y + ins.top);
544: p.addPoint(x + width, y + height - 1);
545: p.addPoint(x, y + height - 1);
546: return p;
547: }
548:
549: public void paintBorder(Component c, Graphics g, int x, int y,
550: int width, int height) {
551: WinVistaEditorTabCellRenderer ren = (WinVistaEditorTabCellRenderer) c;
552:
553: g.translate(x, y);
554:
555: Color borderColor = ((ren.isActive() && ren.isSelected()) || ren
556: .isArmed()) ? getSelBorderColor()
557: : getBorderColor();
558: g.setColor(borderColor);
559: int left = 0;
560: //left
561: //no line
562: //top
563: g.drawLine(0, 0, width, 0);
564: //right
565: //no line
566: //bottom
567: g.setColor(getBorderColor());
568: if (!ren.isSelected()) {
569: g.drawLine(0, height - 1, width - 1, height - 1);
570: } else {
571: g
572: .drawLine(width - 1, height - 1, width - 1,
573: height - 1);
574: }
575:
576: //inner white border
577: g.setColor(getBorderInnerColor());
578: //top
579: g.drawLine(1, 1, width, 1);
580: if (ren.isSelected())
581: height++;
582: //left
583: g.drawLine(0, 1, 0, height - 2);
584: //right
585: //no line
586:
587: g.translate(-x, -y);
588: }
589:
590: public void paintInterior(Graphics g, Component c) {
591: WinVistaEditorTabCellRenderer ren = (WinVistaEditorTabCellRenderer) c;
592:
593: Polygon poly = getInteriorPolygon(ren);
594: paintTabGradient(g, ren, poly);
595: }
596:
597: public boolean supportsCloseButton(JComponent renderer) {
598: return false;
599: }
600:
601: public void getCloseButtonRectangle(JComponent jc,
602: final Rectangle rect, Rectangle bounds) {
603: rect.setBounds(-20, -20, 0, 0);
604: }
605: }
606: }
|