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: package org.netbeans.swing.tabcontrol.plaf;
042:
043: import javax.swing.*;
044: import java.awt.*;
045: import java.awt.event.WindowListener;
046: import java.awt.geom.Area;
047: import java.awt.geom.GeneralPath;
048:
049: /*
050: * GenericAquaPaintingThing.java
051: *
052: * Created on February 16, 2004, 12:17 AM
053: */
054:
055: /**
056: * The name pretty much says it all.
057: *
058: * @author Tim Boudreau
059: */
060: class GenericGlowingChiclet {
061: public static final int STATE_PRESSED = 1;
062: public static final int STATE_SELECTED = 2;
063: public static final int STATE_ACTIVE = 4;
064: public static final int STATE_CLOSING = 8;
065: public static final int STATE_ATTENTION = 16;
066:
067: //Basic apple colors. Package access so that GtkChiclet can install its own
068: //defaults if the GTK classes it proxies for colors are not available or
069: //have incompatibly changed
070: static Color[] selectedActive = new Color[] {
071: new Color(220, 238, 255), new Color(139, 187, 238),
072: new Color(90, 143, 229), new Color(190, 247, 255) };
073:
074: static Color[] selectedPressedActive = new Color[] {
075: selectedActive[0], new Color(50, 150, 229),
076: new Color(80, 80, 200), selectedActive[3] };
077:
078: static Color[] inactive = new Color[] { Color.WHITE,
079: new Color(222, 222, 227), new Color(205, 205, 205),
080: new Color(246, 243, 249) };
081:
082: static Color[] active = new Color[] { Color.WHITE,
083: new Color(222, 222, 227), new Color(205, 205, 205),
084: new Color(246, 243, 249) };
085:
086: static Color[] selectedInactive = new Color[] {
087: new Color(240, 250, 255), new Color(212, 222, 242),
088: new Color(180, 190, 200), new Color(230, 230, 255) };
089:
090: static Color[] closing = new Color[] { new Color(255, 238, 220),
091: new Color(238, 137, 109), new Color(255, 50, 50),
092: new Color(255, 237, 40) };
093:
094: static Color[] attention = new Color[] { new Color(255, 255, 220),
095: new Color(238, 237, 109), new Color(255, 255, 50),
096: new Color(255, 237, 40) };
097:
098: private Color upperTop = selectedActive[0];
099: private Color upperBottom = selectedActive[1];
100: private Color lowerTop = selectedActive[2];
101: private Color lowerBottom = selectedActive[3];
102:
103: private Rectangle scratch = new Rectangle();
104: private float fupperLeftArc = 0;
105: private float fupperRightArc = 0;
106: private float flowerLeftArc = 0;
107: private float flowerRightArc = 0;
108: private int upperLeftArc = 0;
109: private int upperRightArc = 0;
110: private int lowerLeftArc = 0;
111: private int lowerRightArc = 0;
112: private boolean usePercentages = false;
113:
114: private boolean notchRight = false;
115: private boolean notchLeft = false;
116:
117: protected boolean changed = false;
118: protected int state = STATE_ACTIVE | STATE_SELECTED;
119:
120: public static final GenericGlowingChiclet INSTANCE = new GenericGlowingChiclet();
121:
122: protected GenericGlowingChiclet() {
123: //Could listen for change in look and feel, but probably not worth doing for now -
124: //unlikely anyone will ever be able to change between GTK and Aqua L&Fs. Possibly
125: //useful for desktop theme changes on GTK, though. Support it later if need be.
126: }
127:
128: public void setColors(Color upperTop, Color upperBottom,
129: Color lowerTop, Color lowerBottom) {
130: changed |= !upperTop.equals(this .getUpperTop())
131: || !upperBottom.equals(this .getUpperBottom())
132: || !lowerTop.equals(this .getLowerTop())
133: || !lowerBottom.equals(this .getLowerBottom());
134: this .upperTop = upperTop;
135: this .upperBottom = upperBottom;
136: this .lowerTop = lowerTop;
137: this .lowerBottom = lowerBottom;
138: }
139:
140: public Color[] getColors() {
141: return new Color[] { getUpperTop(), getUpperBottom(),
142: getLowerTop(), getLowerBottom() };
143: }
144:
145: protected int getState() {
146: return state;
147: }
148:
149: public void setState(int i) {
150: changed |= state != i;
151: if (state != i) {
152: if ((state & STATE_PRESSED) != 0) {
153: state |= STATE_ACTIVE;
154: }
155: state = i;
156: Color[] nue;
157: if ((state & STATE_CLOSING) != 0) {
158: nue = closing;
159: } else if ((state & STATE_ATTENTION) != 0) {
160: nue = attention;
161: } else {
162: switch (state) {
163: case STATE_PRESSED | STATE_ACTIVE:
164: case STATE_PRESSED | STATE_ACTIVE | STATE_SELECTED:
165: nue = selectedPressedActive;
166: break;
167: case STATE_ACTIVE | STATE_SELECTED:
168: nue = selectedActive;
169: break;
170: case STATE_SELECTED:
171: nue = selectedInactive;
172: break;
173: case STATE_ACTIVE:
174: nue = active;
175: break;
176: default:
177: nue = inactive;
178: }
179: }
180: upperTop = nue[0];
181: upperBottom = nue[1];
182: lowerTop = nue[2];
183: lowerBottom = nue[3];
184: }
185: }
186:
187: private Rectangle bounds = new Rectangle();
188:
189: public void setBounds(int x, int y, int w, int h) {
190: changed |= x != bounds.x || y != bounds.y || w != bounds.width
191: || h != bounds.height;
192: bounds.setBounds(x, y, w, h - 1);
193: }
194:
195: private boolean allowVertical = false;
196:
197: public void setAllowVertical(boolean val) {
198: if (val != allowVertical) {
199: allowVertical = val;
200: changed = true;
201: }
202: }
203:
204: private Rectangle getBounds() {
205: scratch.setBounds(bounds);
206: return scratch;
207: }
208:
209: public void setArcs(int upperLeft, int upperRight, int lowerLeft,
210: int lowerRight) {
211: changed |= upperLeft != upperLeftArc
212: || upperRight != upperRightArc
213: || lowerLeft != lowerLeftArc
214: || lowerRight != lowerRightArc || usePercentages;
215:
216: upperLeftArc = upperLeft;
217: upperRightArc = upperRight;
218: lowerLeftArc = lowerLeft;
219: lowerRightArc = lowerRight;
220: usePercentages = false;
221: }
222:
223: public void setArcs(float upperLeft, float upperRight,
224: float lowerLeft, float lowerRight) {
225: changed |= upperLeft != fupperLeftArc
226: || upperRight != fupperRightArc
227: || lowerLeft != flowerLeftArc
228: || lowerRight != flowerRightArc || !usePercentages;
229:
230: fupperLeftArc = upperLeft;
231: fupperRightArc = upperRight;
232: flowerLeftArc = lowerLeft;
233: flowerRightArc = lowerRight;
234: usePercentages = true;
235: }
236:
237: public void setNotch(boolean right, boolean left) {
238: changed |= right != notchRight || left != notchLeft;
239: notchRight = right;
240: notchLeft = left;
241: }
242:
243: private int getNotchRightArc() {
244: int arc = getUpperRightArc();
245: if (arc == 0) {
246: arc = bounds.height / 2;
247: }
248: return arc / 3;
249: }
250:
251: private int getNotchLeftArc() {
252: int arc = getUpperLeftArc();
253: if (arc == 0) {
254: arc = bounds.height / 2;
255: }
256: return arc / 3;
257: }
258:
259: private int getUpperLeftArc() {
260: if (!usePercentages) {
261: return upperLeftArc;
262: } else {
263: return Math.round(fupperLeftArc
264: * Math.min(getBounds().height, getBounds().width));
265: }
266: }
267:
268: private int getUpperRightArc() {
269: if (!usePercentages) {
270: return upperRightArc;
271: } else {
272: return Math.round(fupperRightArc
273: * Math.min(getBounds().height, getBounds().width));
274: }
275: }
276:
277: private int getLowerLeftArc() {
278: if (!usePercentages) {
279: return lowerLeftArc;
280: } else {
281: return Math.round(flowerLeftArc
282: * Math.min(getBounds().height, getBounds().width));
283: }
284: }
285:
286: private int getLowerRightArc() {
287: if (!usePercentages) {
288: return lowerRightArc;
289: } else {
290: return Math.round(flowerRightArc
291: * Math.min(getBounds().height, getBounds().width));
292: }
293: }
294:
295: public void draw(Graphics2D g) {
296: if (bounds.width == 0 || bounds.height == 0) {
297: return;
298: }
299: drawInterior(g);
300: if (drawOutline) {
301: drawOutline(g);
302: }
303: changed = false;
304: }
305:
306: private boolean drawOutline = true;
307:
308: public void setDrawOutline(boolean b) {
309: drawOutline = b;
310: }
311:
312: private void drawOutline(Graphics2D g) {
313: Shape s = getClipShape();
314: g.setColor(dark());
315: g.setStroke(new BasicStroke(0.95f));
316: Rectangle r = getBounds();
317: r.height += 1;
318:
319: Shape clip = g.getClip();
320: if (clip != null) {
321: Area a = new Area(clip);
322: a.intersect(new Area(r));
323: g.setClip(a);
324: } else {
325: g.setClip(r);
326: }
327:
328: g.draw(s);
329: g.setColor(getOutlineDark());
330:
331: r = getBounds();
332: g.setStroke(new BasicStroke(0.70f));
333: if (getLowerRightArc() != 0) {
334: g.drawLine(Math.max(r.x, r.x + getLowerLeftArc() - 3), r.y
335: + r.height - 1, Math.min(r.x + r.width
336: - getLowerRightArc() + 3, r.x + r.width) - 1, r.y
337: + r.height - 1);
338: } else {
339: g.drawLine(Math.max(r.x, r.x + getLowerLeftArc() - 3), r.y
340: + r.height - 1, Math.min(r.x + r.width
341: - getLowerRightArc() + 3, r.x + r.width), r.y
342: + r.height - 1);
343: }
344: g.setClip(clip);
345: }
346:
347: protected Color getOutlineDark() {
348: return new Color(50, 50, 50);
349: }
350:
351: private void drawInterior(Graphics2D g) {
352: Shape s = getClipShape();
353: Area a = new Area(s);
354:
355: Shape clip = g.getClip();
356: if (clip != null) {
357: a.intersect(new Area(clip));
358: }
359:
360: Rectangle r;
361: if (isVertical()) {
362: r = getBounds();
363: r.width /= 2;
364: a.intersect(new Area(r));
365: g.setClip(a);
366:
367: g.setPaint(getLeftPaint());
368: g.fill(s);
369:
370: r = getBounds();
371: r.width /= 2;
372: r.x += r.width;
373: a = new Area(s);
374: if (clip != null) {
375: a.intersect(new Area(clip));
376: }
377: a.intersect(new Area(r));
378: g.setClip(a);
379:
380: g.setPaint(getRightPaint());
381: g.fill(s);
382: } else {
383: //paint the upper gradient into the top half of the shape
384: r = getBounds();
385: r.height /= 2;
386: a.intersect(new Area(r));
387:
388: g.setClip(a);
389:
390: g.setPaint(getUpperPaint());
391: g.fill(s);
392:
393: //paint the lower gradient into the bottom half of the shape
394: a = new Area(s);
395: if (clip != null) {
396: a.intersect(new Area(clip));
397: }
398: r = getBounds();
399: r.y += r.height / 2;
400: r.height -= r.height / 2;
401: a.intersect(new Area(r));
402:
403: g.setClip(a);
404: g.setPaint(getLowerPaint());
405: g.fill(s);
406: }
407:
408: Composite composite = g.getComposite();
409: AlphaComposite comp = AlphaComposite.getInstance(
410: AlphaComposite.SRC_OVER, 0.8f);
411: g.setComposite(comp);
412:
413: int arc = getUpperLeftArc();
414: r = getBounds();
415: r.width = arc;
416: r.height = r.height / 2;
417:
418: a = new Area(s);
419: if (clip != null) {
420: a.intersect(new Area(clip));
421: }
422: a.intersect(new Area(r));
423: g.setClip(a);
424: g.setPaint(getUpperLeftPaint());
425: g.fill(s);
426:
427: arc = getUpperRightArc();
428: r = getBounds();
429: r.x = r.x + r.width - arc;
430: r.width = arc;
431: r.height = r.height / 2;
432:
433: a = new Area(s);
434: if (clip != null) {
435: a.intersect(new Area(clip));
436: }
437: a.intersect(new Area(r));
438: g.setClip(a);
439: g.setPaint(getUpperRightPaint());
440: g.fill(s);
441:
442: arc = getLowerRightArc();
443: r = getBounds();
444: r.x = r.x + r.width - arc;
445: r.width = arc;
446: r.y = r.y + (r.height / 2);
447: r.height = r.height / 2;
448:
449: a = new Area(s);
450: if (clip != null) {
451: a.intersect(new Area(clip));
452: }
453: a.intersect(new Area(r));
454: g.setClip(a);
455: g.setPaint(getLowerRightPaint());
456: g.fill(s);
457:
458: arc = getLowerLeftArc();
459: r = getBounds();
460: r.width = arc;
461: r.y = r.y + (r.height / 2);
462: r.height = r.height / 2;
463:
464: a = new Area(s);
465: if (clip != null) {
466: a.intersect(new Area(clip));
467: }
468: a.intersect(new Area(r));
469: g.setClip(a);
470: g.setPaint(getLowerLeftPaint());
471: g.fill(s);
472:
473: g.setClip(clip);
474: g.setComposite(composite);
475: }
476:
477: private boolean isVertical() {
478: if (!allowVertical) {
479: return false;
480: } else {
481: return bounds.height > bounds.width;
482: }
483: }
484:
485: private GradientPaint getUpperPaint() {
486: Rectangle r = getBounds();
487: return ColorUtil.getGradientPaint(r.x, r.y + (r.height / 9),
488: getUpperTop(), r.x, r.y + (r.height / 2),
489: getUpperBottom(), true);
490: }
491:
492: private GradientPaint getLowerPaint() {
493: Rectangle r = getBounds();
494: return ColorUtil.getGradientPaint(r.x, r.y + (r.height / 2),
495: getLowerTop(), r.x, r.y + r.height, getLowerBottom(),
496: false);
497: }
498:
499: private GradientPaint getLeftPaint() {
500: Rectangle r = getBounds();
501: return ColorUtil.getGradientPaint(r.x, r.y, getUpperTop(), r.x
502: + (r.width / 2), r.y, getUpperBottom());
503: }
504:
505: private GradientPaint getRightPaint() {
506: Rectangle r = getBounds();
507: return ColorUtil.getGradientPaint(r.x + (r.width / 2), r.y,
508: getLowerTop(), r.x + r.width, r.y, getLowerBottom());
509: }
510:
511: private GradientPaint getUpperLeftPaint() {
512: Rectangle r = getBounds();
513: int arc = getUpperLeftArc();
514: if (!isVertical()) {
515: return ColorUtil.getGradientPaint(r.x,
516: r.y + (r.height / 2), dark(), r.x + (arc / 2), r.y
517: + (r.height / 2) - arc / 2, light());
518: } else {
519: return ColorUtil.getGradientPaint(r.x + (r.width / 2), r.y,
520: dark(), r.x + (r.width / 2) - (arc / 2), r.y + arc,
521: light());
522: }
523: }
524:
525: private GradientPaint getUpperRightPaint() {
526: Rectangle r = getBounds();
527: int arc = getUpperRightArc();
528: if (!isVertical()) {
529: return ColorUtil.getGradientPaint(r.x + r.width, r.y
530: + (r.height / 2), dark(),
531: r.x + r.width - (arc / 2), r.y + (r.height / 2)
532: - arc / 2, light());
533: } else {
534: return ColorUtil.getGradientPaint(r.x + (r.width / 2), r.y,
535: dark(), r.x + (r.width / 2) + (arc / 2), r.y + arc,
536: light());
537: }
538: }
539:
540: private GradientPaint getLowerRightPaint() {
541: Rectangle r = getBounds();
542: int arc = getLowerRightArc();
543: if (!isVertical()) {
544: return ColorUtil.getGradientPaint(r.x + r.width, r.y
545: + (r.height / 2), dark(),
546: r.x + r.width - (arc / 2), r.y + (r.height / 2)
547: + (arc / 2), light());
548: } else {
549: return ColorUtil.getGradientPaint(r.x + (r.width / 2), r.y
550: + r.height, dark(),
551: r.x + (r.width / 2) + (arc / 2), r.y + r.height
552: - arc, light());
553: }
554: }
555:
556: private GradientPaint getLowerLeftPaint() {
557: Rectangle r = getBounds();
558: int arc = getLowerLeftArc();
559: if (!isVertical()) {
560: return ColorUtil.getGradientPaint(r.x,
561: r.y + (r.height / 2), dark(), r.x + (arc / 2), r.y
562: + (r.height / 2) + (arc / 2), light());
563: } else {
564: return ColorUtil.getGradientPaint(r.x + (r.width / 2), r.y
565: + r.height, dark(),
566: r.x + (r.width / 2) - (arc / 2), r.y + r.height
567: - arc, light());
568: }
569: }
570:
571: private Shape clip = null;
572:
573: private Shape getClipShape() {
574: if (changed)
575: update();
576: if (clip == null) {
577: clip = createClip();
578: }
579: return clip;
580: }
581:
582: protected Color dark() {
583: if ((getState() & STATE_SELECTED) != 0
584: && (getState() & STATE_ACTIVE) != 0) {
585: return new Color(80, 80, 150);
586: } else {
587: return new Color(130, 130, 150);
588: }
589: }
590:
591: private Color light() {
592: Color dark = dark();
593: return new Color(dark.getRed(), dark.getGreen(),
594: dark.getBlue(), 0);
595: }
596:
597: private void update() {
598: clip = null;
599: }
600:
601: private Shape createClip() {
602: Rectangle bds = getBounds();
603: if (!notchLeft && !notchRight && !usePercentages
604: && upperRightArc == lowerRightArc
605: && lowerRightArc == lowerLeftArc
606: && lowerLeftArc == upperLeftArc && upperLeftArc == 0) {
607: return new Rectangle(getBounds());
608: }
609: int upperRightArc = getUpperRightArc();
610: int lowerRightArc = getLowerRightArc();
611: int upperLeftArc = getUpperLeftArc();
612: int lowerLeftArc = getLowerLeftArc();
613: int notchR = getNotchRightArc();
614: int notchL = getNotchLeftArc();
615:
616: GeneralPath gp = new GeneralPath();
617: if (notchLeft) {
618: gp.moveTo(bds.x + notchL, bds.y + (bds.height / 2));
619: gp.curveTo(bds.x + notchL, bds.y + (bds.height / 2), bds.x
620: + notchL, bds.y + (bds.height / 2) - notchL, bds.x,
621: bds.y + (bds.height / 2) - notchL);
622: if (bds.y + (bds.height / 2) - notchL > bds.y
623: + upperLeftArc) {
624: gp.lineTo(bds.x, bds.y + upperLeftArc);
625: }
626: gp.curveTo(bds.x, Math.min(bds.y + upperLeftArc, bds.y
627: + (bds.height / 2) - notchL), bds.x, bds.y, bds.x
628: + upperLeftArc, bds.y);
629: } else {
630: gp.moveTo(bds.x, bds.y + bds.height - lowerLeftArc);
631: if (bds.y + bds.height - lowerLeftArc > bds.y
632: + upperLeftArc) {
633: gp.lineTo(bds.x, bds.y + upperLeftArc);
634: }
635: gp.curveTo(bds.x, bds.y + upperLeftArc, bds.x, bds.y, bds.x
636: + upperLeftArc, bds.y);
637: }
638: if (bds.x + bds.width - upperLeftArc > bds.x + upperRightArc) {
639: gp.lineTo(bds.x + bds.width - upperRightArc, bds.y);
640: }
641:
642: if (notchRight) {
643: gp.curveTo(bds.x + bds.width - upperRightArc - 1, bds.y,
644: bds.x + bds.width - 1, bds.y,
645: bds.x + bds.width - 1, Math.min(bds.y
646: + upperRightArc, bds.y + (bds.height / 2)
647: - notchR));
648:
649: if (bds.y + upperRightArc < bds.y + (bds.height / 2)
650: - notchR) {
651: gp.lineTo(bds.x + bds.width - 1, bds.y
652: + (bds.height / 2) - notchR);
653: }
654: gp.curveTo(bds.x + bds.width - 1, bds.y + (bds.height / 2)
655: - notchR, bds.x + bds.width - notchR - 1, bds.y
656: + (bds.height / 2) - notchR, bds.x + bds.width
657: - notchR - 1, bds.y + (bds.height / 2));
658:
659: gp.curveTo(bds.x + bds.width - notchR - 1, bds.y
660: + (bds.height / 2), bds.x + bds.width - notchR - 1,
661: bds.y + (bds.height / 2) + notchR, bds.x
662: + bds.width - 1, bds.y + (bds.height / 2)
663: + notchR);
664:
665: if (bds.y + (bds.height / 2) + notchR < bds.y + bds.height
666: - lowerRightArc) {
667: gp.lineTo(bds.x + bds.width - 1, bds.y + bds.height
668: - lowerRightArc);
669: }
670:
671: gp.curveTo(bds.x + bds.width - 1, Math.max(bds.y
672: + (bds.height / 2) + notchR, bds.y + bds.height
673: - lowerRightArc), bds.x + bds.width - 1, bds.y
674: + bds.height,
675: bds.x + bds.width - lowerRightArc - 1, bds.y
676: + bds.height);
677:
678: } else {
679: if (upperRightArc != 0) {
680: gp.curveTo(bds.x + bds.width - upperRightArc - 1,
681: bds.y, bds.x + bds.width - 1, bds.y, bds.x
682: + bds.width - 1, bds.y + upperRightArc);
683: } else {
684: gp.curveTo(bds.x + bds.width - upperRightArc, bds.y,
685: bds.x + bds.width, bds.y, bds.x + bds.width,
686: bds.y + upperRightArc);
687: }
688: if (bds.y + upperRightArc < bds.y + bds.height
689: - lowerRightArc) {
690: if (upperRightArc != 0 && lowerRightArc != 0) {
691: gp.lineTo(bds.x + bds.width - 1, bds.y + bds.height
692: - lowerRightArc);
693: } else {
694: gp.lineTo(bds.x + bds.width, bds.y + bds.height
695: - lowerRightArc);
696: }
697: }
698: if (lowerRightArc != 0) {
699: gp.curveTo(bds.x + bds.width - 1, bds.y + bds.height
700: - lowerRightArc, bds.x + bds.width - 1, bds.y
701: + bds.height, bds.x + bds.width - lowerRightArc
702: - 1, bds.y + bds.height);
703: } else {
704: gp.curveTo(bds.x + bds.width, bds.y + bds.height
705: - lowerRightArc, bds.x + bds.width, bds.y
706: + bds.height,
707: bds.x + bds.width - lowerRightArc, bds.y
708: + bds.height);
709: }
710: }
711: if (bds.x + bds.width - lowerRightArc > bds.x + lowerLeftArc) {
712: gp.lineTo(bds.x + lowerLeftArc, bds.y + bds.height);
713: }
714:
715: if (notchLeft) {
716: gp.curveTo(bds.x + lowerLeftArc, bds.y + bds.height, bds.x,
717: bds.y + bds.height, bds.x, Math.max(bds.y
718: + bds.height - lowerLeftArc, bds.y
719: + (bds.height / 2) + notchL));
720: if (bds.y + bds.height - lowerLeftArc > bds.y
721: + (bds.height / 2) + notchL) {
722: gp.lineTo(bds.x, bds.y + (bds.height / 2) + notchL);
723: }
724: gp.curveTo(bds.x, bds.y + (bds.height / 2) + notchL, bds.x
725: + notchL, bds.y + (bds.height / 2) + notchL, bds.x
726: + notchL, bds.y + (bds.height / 2));
727: } else {
728: gp.curveTo(bds.x + lowerLeftArc, bds.y + bds.height, bds.x,
729: bds.y + bds.height, bds.x, bds.y + bds.height
730: - lowerLeftArc);
731: }
732: return gp;
733: }
734:
735: protected Color getUpperTop() {
736: return upperTop;
737: }
738:
739: protected Color getUpperBottom() {
740: return upperBottom;
741: }
742:
743: protected Color getLowerTop() {
744: return lowerTop;
745: }
746:
747: protected Color getLowerBottom() {
748: return lowerBottom;
749: }
750:
751: }
|