KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > plaf > metal > MetalTabbedPaneUI


1 /*
2  * @(#)MetalTabbedPaneUI.java 1.36 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.swing.plaf.metal;
9
10 import javax.swing.*;
11 import javax.swing.event.*;
12 import java.awt.*;
13 import java.awt.event.*;
14 import javax.swing.plaf.*;
15 import java.io.Serializable JavaDoc;
16 import javax.swing.plaf.basic.BasicTabbedPaneUI JavaDoc;
17
18 /**
19  * The Metal subclass of BasicTabbedPaneUI.
20  * <p>
21  * <strong>Warning:</strong>
22  * Serialized objects of this class will not be compatible with
23  * future Swing releases. The current serialization support is
24  * appropriate for short term storage or RMI between applications running
25  * the same version of Swing. As of 1.4, support for long term storage
26  * of all JavaBeans<sup><font size="-2">TM</font></sup>
27  * has been added to the <code>java.beans</code> package.
28  * Please see {@link java.beans.XMLEncoder}.
29  *
30  * @version 1.19 08/28/98
31  * @author Tom Santos
32  */

33
34 public class MetalTabbedPaneUI extends BasicTabbedPaneUI JavaDoc {
35
36     protected int minTabWidth = 40;
37     // Background color for unselected tabs that don't have an explicitly
38
// set color.
39
private Color unselectedBackground;
40     protected Color tabAreaBackground;
41     protected Color selectColor;
42     protected Color selectHighlight;
43     private boolean tabsOpaque = true;
44
45     // Whether or not we're using ocean. This is cached as it is used
46
// extensively during painting.
47
private boolean ocean;
48     // Selected border color for ocean.
49
private Color oceanSelectedBorderColor;
50
51     public static ComponentUI createUI( JComponent x ) {
52         return new MetalTabbedPaneUI JavaDoc();
53     }
54
55     protected LayoutManager createLayoutManager() {
56     if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT) {
57             return super.createLayoutManager();
58     }
59         return new TabbedPaneLayout();
60     }
61
62     protected void installDefaults() {
63         super.installDefaults();
64
65         tabAreaBackground = UIManager.getColor("TabbedPane.tabAreaBackground");
66         selectColor = UIManager.getColor("TabbedPane.selected");
67         selectHighlight = UIManager.getColor("TabbedPane.selectHighlight");
68         tabsOpaque = UIManager.getBoolean("TabbedPane.tabsOpaque");
69         unselectedBackground = UIManager.getColor(
70                                          "TabbedPane.unselectedBackground");
71         ocean = MetalLookAndFeel.usingOcean();
72         if (ocean) {
73             oceanSelectedBorderColor = UIManager.getColor(
74                          "TabbedPane.borderHightlightColor");
75         }
76     }
77
78
79     protected void paintTabBorder( Graphics g, int tabPlacement,
80                                    int tabIndex, int x, int y, int w, int h,
81                                    boolean isSelected) {
82         int bottom = y + (h-1);
83         int right = x + (w-1);
84
85         switch ( tabPlacement ) {
86         case LEFT:
87             paintLeftTabBorder(tabIndex, g, x, y, w, h, bottom, right, isSelected);
88             break;
89         case BOTTOM:
90             paintBottomTabBorder(tabIndex, g, x, y, w, h, bottom, right, isSelected);
91             break;
92         case RIGHT:
93             paintRightTabBorder(tabIndex, g, x, y, w, h, bottom, right, isSelected);
94             break;
95         case TOP:
96         default:
97             paintTopTabBorder(tabIndex, g, x, y, w, h, bottom, right, isSelected);
98         }
99     }
100
101
102     protected void paintTopTabBorder( int tabIndex, Graphics g,
103                                       int x, int y, int w, int h,
104                                       int btm, int rght,
105                                       boolean isSelected ) {
106         int currentRun = getRunForTab( tabPane.getTabCount(), tabIndex );
107         int lastIndex = lastTabInRun( tabPane.getTabCount(), currentRun );
108         int firstIndex = tabRuns[ currentRun ];
109     boolean leftToRight = MetalUtils.isLeftToRight(tabPane);
110         int selectedIndex = tabPane.getSelectedIndex();
111         int bottom = h - 1;
112         int right = w - 1;
113
114         //
115
// Paint Gap
116
//
117

118         if (shouldFillGap( currentRun, tabIndex, x, y ) ) {
119             g.translate( x, y );
120
121         if ( leftToRight ) {
122             g.setColor( getColorForGap( currentRun, x, y + 1 ) );
123         g.fillRect( 1, 0, 5, 3 );
124         g.fillRect( 1, 3, 2, 2 );
125         } else {
126             g.setColor( getColorForGap( currentRun, x + w - 1, y + 1 ) );
127         g.fillRect( right - 5, 0, 5, 3 );
128         g.fillRect( right - 2, 3, 2, 2 );
129         }
130
131             g.translate( -x, -y );
132         }
133
134         g.translate( x, y );
135
136         //
137
// Paint Border
138
//
139

140         if (ocean && isSelected) {
141             g.setColor(oceanSelectedBorderColor);
142         }
143         else {
144             g.setColor( darkShadow );
145         }
146
147     if ( leftToRight ) {
148
149         // Paint slant
150
g.drawLine( 1, 5, 6, 0 );
151
152         // Paint top
153
g.drawLine( 6, 0, right, 0 );
154
155         // Paint right
156
if ( tabIndex==lastIndex ) {
157             // last tab in run
158
g.drawLine( right, 1, right, bottom );
159         }
160
161             if (ocean && tabIndex - 1 == selectedIndex &&
162                                 currentRun == getRunForTab(
163                                 tabPane.getTabCount(), selectedIndex)) {
164                 g.setColor(oceanSelectedBorderColor);
165             }
166
167         // Paint left
168
if ( tabIndex != tabRuns[ runCount - 1 ] ) {
169             // not the first tab in the last run
170
if (ocean && isSelected) {
171                     g.drawLine(0, 6, 0, bottom);
172                     g.setColor(darkShadow);
173                     g.drawLine(0, 0, 0, 5);
174                 }
175                 else {
176                     g.drawLine( 0, 0, 0, bottom );
177                 }
178         } else {
179             // the first tab in the last run
180
g.drawLine( 0, 6, 0, bottom );
181         }
182     } else {
183
184         // Paint slant
185
g.drawLine( right - 1, 5, right - 6, 0 );
186
187         // Paint top
188
g.drawLine( right - 6, 0, 0, 0 );
189
190         // Paint left
191
if ( tabIndex==lastIndex ) {
192             // last tab in run
193
g.drawLine( 0, 1, 0, bottom );
194         }
195
196             // Paint right
197
if (ocean && tabIndex - 1 == selectedIndex &&
198                                 currentRun == getRunForTab(
199                                 tabPane.getTabCount(), selectedIndex)) {
200                 g.setColor(oceanSelectedBorderColor);
201                 g.drawLine(right, 0, right, bottom);
202             }
203             else if (ocean && isSelected) {
204                 g.drawLine(right, 6, right, bottom);
205                 if (tabIndex != 0) {
206                     g.setColor(darkShadow);
207                     g.drawLine(right, 0, right, 5);
208                 }
209             }
210             else {
211                 if ( tabIndex != tabRuns[ runCount - 1 ] ) {
212                     // not the first tab in the last run
213
g.drawLine( right, 0, right, bottom );
214                 } else {
215                     // the first tab in the last run
216
g.drawLine( right, 6, right, bottom );
217                 }
218             }
219     }
220
221         //
222
// Paint Highlight
223
//
224

225         g.setColor( isSelected ? selectHighlight : highlight );
226
227     if ( leftToRight ) {
228
229         // Paint slant
230
g.drawLine( 1, 6, 6, 1 );
231
232         // Paint top
233
g.drawLine( 6, 1, right, 1 );
234
235         // Paint left
236
g.drawLine( 1, 6, 1, bottom );
237
238         // paint highlight in the gap on tab behind this one
239
// on the left end (where they all line up)
240
if ( tabIndex==firstIndex && tabIndex!=tabRuns[runCount - 1] ) {
241             // first tab in run but not first tab in last run
242
if (tabPane.getSelectedIndex()==tabRuns[currentRun+1]) {
243             // tab in front of selected tab
244
g.setColor( selectHighlight );
245         }
246         else {
247             // tab in front of normal tab
248
g.setColor( highlight );
249         }
250         g.drawLine( 1, 0, 1, 4 );
251         }
252     } else {
253
254         // Paint slant
255
g.drawLine( right - 1, 6, right - 6, 1 );
256
257         // Paint top
258
g.drawLine( right - 6, 1, 1, 1 );
259
260         // Paint left
261
if ( tabIndex==lastIndex ) {
262             // last tab in run
263
g.drawLine( 1, 1, 1, bottom );
264         } else {
265             g.drawLine( 0, 1, 0, bottom );
266         }
267     }
268
269         g.translate( -x, -y );
270     }
271
272     protected boolean shouldFillGap( int currentRun, int tabIndex, int x, int y ) {
273         boolean result = false;
274
275         if (!tabsOpaque) {
276             return false;
277         }
278         
279         if ( currentRun == runCount - 2 ) { // If it's the second to last row.
280
Rectangle lastTabBounds = getTabBounds( tabPane, tabPane.getTabCount() - 1 );
281         Rectangle tabBounds = getTabBounds( tabPane, tabIndex );
282             if (MetalUtils.isLeftToRight(tabPane)) {
283             int lastTabRight = lastTabBounds.x + lastTabBounds.width - 1;
284
285         // is the right edge of the last tab to the right
286
// of the left edge of the current tab?
287
if ( lastTabRight > tabBounds.x + 2 ) {
288             return true;
289         }
290         } else {
291             int lastTabLeft = lastTabBounds.x;
292         int currentTabRight = tabBounds.x + tabBounds.width - 1;
293
294         // is the left edge of the last tab to the left
295
// of the right edge of the current tab?
296
if ( lastTabLeft < currentTabRight - 2 ) {
297             return true;
298         }
299             }
300         } else {
301         // fill in gap for all other rows except last row
302
result = currentRun != runCount - 1;
303         }
304
305         return result;
306     }
307
308     protected Color getColorForGap( int currentRun, int x, int y ) {
309         final int shadowWidth = 4;
310         int selectedIndex = tabPane.getSelectedIndex();
311         int startIndex = tabRuns[ currentRun + 1 ];
312         int endIndex = lastTabInRun( tabPane.getTabCount(), currentRun + 1 );
313         int tabOverGap = -1;
314         // Check each tab in the row that is 'on top' of this row
315
for ( int i = startIndex; i <= endIndex; ++i ) {
316             Rectangle tabBounds = getTabBounds( tabPane, i );
317             int tabLeft = tabBounds.x;
318             int tabRight = (tabBounds.x + tabBounds.width) - 1;
319             // Check to see if this tab is over the gap
320
if ( MetalUtils.isLeftToRight(tabPane) ) {
321                 if ( tabLeft <= x && tabRight - shadowWidth > x ) {
322                     if (ocean) {
323                         if (selectedIndex == i) {
324                             return oceanSelectedBorderColor;
325                         }
326                         return getUnselectedBackgroundAt(i);
327                     }
328                     return selectedIndex == i ? selectColor : getUnselectedBackgroundAt( i );
329                 }
330             }
331             else {
332             if ( tabLeft + shadowWidth < x && tabRight >= x ) {
333                     if (ocean) {
334                         if (selectedIndex == i) {
335                             return oceanSelectedBorderColor;
336                         }
337                         return getUnselectedBackgroundAt(i);
338                     }
339                     return selectedIndex == i ? selectColor : getUnselectedBackgroundAt( i );
340                 }
341             }
342         }
343
344         return tabPane.getBackground();
345     }
346
347     protected void paintLeftTabBorder( int tabIndex, Graphics g,
348                                        int x, int y, int w, int h,
349                                        int btm, int rght,
350                                        boolean isSelected ) {
351         int tabCount = tabPane.getTabCount();
352         int currentRun = getRunForTab( tabCount, tabIndex );
353         int lastIndex = lastTabInRun( tabCount, currentRun );
354         int firstIndex = tabRuns[ currentRun ];
355
356         g.translate( x, y );
357
358         int bottom = h - 1;
359         int right = w - 1;
360
361         //
362
// Paint part of the tab above
363
//
364

365         if ( tabIndex != firstIndex && tabsOpaque ) {
366             g.setColor( tabPane.getSelectedIndex() == tabIndex - 1 ?
367                         selectColor :
368                         getUnselectedBackgroundAt( tabIndex - 1 ) );
369             g.fillRect( 2, 0, 4, 3 );
370             g.drawLine( 2, 3, 2, 3 );
371         }
372
373
374         //
375
// Paint Highlight
376
//
377

378         if (ocean) {
379             g.setColor(isSelected ? selectHighlight :
380                        MetalLookAndFeel.getWhite());
381         }
382         else {
383             g.setColor( isSelected ? selectHighlight : highlight );
384         }
385
386         // Paint slant
387
g.drawLine( 1, 6, 6, 1 );
388
389         // Paint left
390
g.drawLine( 1, 6, 1, bottom );
391
392         // Paint top
393
g.drawLine( 6, 1, right, 1 );
394
395         if ( tabIndex != firstIndex ) {
396             if (ocean) {
397                 g.setColor(MetalLookAndFeel.getWhite());
398             }
399             g.drawLine( 1, 0, 1, 4 );
400         }
401
402         //
403
// Paint Border
404
//
405

406         if (ocean) {
407             if (isSelected) {
408                 g.setColor(oceanSelectedBorderColor);
409             }
410             else {
411                 g.setColor( darkShadow );
412             }
413         }
414         else {
415             g.setColor( darkShadow );
416         }
417
418         // Paint slant
419
g.drawLine( 1, 5, 6, 0 );
420
421         // Paint top
422
g.drawLine( 6, 0, right, 0 );
423
424         // Paint bottom
425
if ( tabIndex == lastIndex ) {
426             g.drawLine( 0, bottom, right, bottom );
427         }
428
429         // Paint left
430
if (ocean) {
431             if (tabPane.getSelectedIndex() == tabIndex - 1) {
432                 g.drawLine(0, 5, 0, bottom);
433                 g.setColor(oceanSelectedBorderColor);
434                 g.drawLine(0, 0, 0, 5);
435             }
436             else if (isSelected) {
437                 g.drawLine( 0, 5, 0, bottom );
438                 if (tabIndex != 0) {
439                     g.setColor(darkShadow);
440                     g.drawLine(0, 0, 0, 5);
441                 }
442             }
443             else if ( tabIndex != firstIndex ) {
444                 g.drawLine( 0, 0, 0, bottom );
445             } else {
446                 g.drawLine( 0, 6, 0, bottom );
447             }
448         }
449         else { // metal
450
if ( tabIndex != firstIndex ) {
451                 g.drawLine( 0, 0, 0, bottom );
452             } else {
453                 g.drawLine( 0, 6, 0, bottom );
454             }
455         }
456
457         g.translate( -x, -y );
458     }
459
460
461     protected void paintBottomTabBorder( int tabIndex, Graphics g,
462                                          int x, int y, int w, int h,
463                                          int btm, int rght,
464                                          boolean isSelected ) {
465         int tabCount = tabPane.getTabCount();
466         int currentRun = getRunForTab( tabCount, tabIndex );
467         int lastIndex = lastTabInRun( tabCount, currentRun );
468         int firstIndex = tabRuns[ currentRun ];
469     boolean leftToRight = MetalUtils.isLeftToRight(tabPane);
470
471         int bottom = h - 1;
472         int right = w - 1;
473
474         //
475
// Paint Gap
476
//
477

478         if ( shouldFillGap( currentRun, tabIndex, x, y ) ) {
479             g.translate( x, y );
480
481         if ( leftToRight ) {
482             g.setColor( getColorForGap( currentRun, x, y ) );
483         g.fillRect( 1, bottom - 4, 3, 5 );
484         g.fillRect( 4, bottom - 1, 2, 2 );
485         } else {
486             g.setColor( getColorForGap( currentRun, x + w - 1, y ) );
487         g.fillRect( right - 3, bottom - 3, 3, 4 );
488         g.fillRect( right - 5, bottom - 1, 2, 2 );
489         g.drawLine( right - 1, bottom - 4, right - 1, bottom - 4 );
490         }
491
492             g.translate( -x, -y );
493         }
494
495         g.translate( x, y );
496
497
498         //
499
// Paint Border
500
//
501

502         if (ocean && isSelected) {
503             g.setColor(oceanSelectedBorderColor);
504         }
505         else {
506             g.setColor( darkShadow );
507         }
508
509     if ( leftToRight ) {
510
511         // Paint slant
512
g.drawLine( 1, bottom - 5, 6, bottom );
513
514         // Paint bottom
515
g.drawLine( 6, bottom, right, bottom );
516
517         // Paint right
518
if ( tabIndex == lastIndex ) {
519             g.drawLine( right, 0, right, bottom );
520         }
521
522         // Paint left
523
if (ocean && isSelected) {
524                 g.drawLine(0, 0, 0, bottom - 5);
525                 if ((currentRun == 0 && tabIndex != 0) ||
526                     (currentRun > 0 && tabIndex != tabRuns[currentRun - 1])) {
527                     g.setColor(darkShadow);
528                     g.drawLine(0, bottom - 5, 0, bottom);
529                 }
530             }
531             else {
532                 if (ocean && tabIndex == tabPane.getSelectedIndex() + 1) {
533                     g.setColor(oceanSelectedBorderColor);
534                 }
535                 if ( tabIndex != tabRuns[ runCount - 1 ] ) {
536                     g.drawLine( 0, 0, 0, bottom );
537                 } else {
538                     g.drawLine( 0, 0, 0, bottom - 6 );
539                 }
540             }
541     } else {
542
543         // Paint slant
544
g.drawLine( right - 1, bottom - 5, right - 6, bottom );
545
546         // Paint bottom
547
g.drawLine( right - 6, bottom, 0, bottom );
548
549         // Paint left
550
if ( tabIndex==lastIndex ) {
551             // last tab in run
552
g.drawLine( 0, 0, 0, bottom );
553         }
554
555         // Paint right
556
if (ocean && tabIndex == tabPane.getSelectedIndex() + 1) {
557                 g.setColor(oceanSelectedBorderColor);
558                 g.drawLine(right, 0, right, bottom);
559             }
560             else if (ocean && isSelected) {
561                 g.drawLine(right, 0, right, bottom - 6);
562                 if (tabIndex != firstIndex) {
563                     g.setColor(darkShadow);
564                     g.drawLine(right, bottom - 5, right, bottom);
565                 }
566             }
567         else if ( tabIndex != tabRuns[ runCount - 1 ] ) {
568             // not the first tab in the last run
569
g.drawLine( right, 0, right, bottom );
570         } else {
571             // the first tab in the last run
572
g.drawLine( right, 0, right, bottom - 6 );
573         }
574     }
575
576         //
577
// Paint Highlight
578
//
579

580         g.setColor( isSelected ? selectHighlight : highlight );
581
582     if ( leftToRight ) {
583
584         // Paint slant
585
g.drawLine( 1, bottom - 6, 6, bottom - 1 );
586
587         // Paint left
588
g.drawLine( 1, 0, 1, bottom - 6 );
589
590         // paint highlight in the gap on tab behind this one
591
// on the left end (where they all line up)
592
if ( tabIndex==firstIndex && tabIndex!=tabRuns[runCount - 1] ) {
593             // first tab in run but not first tab in last run
594
if (tabPane.getSelectedIndex()==tabRuns[currentRun+1]) {
595             // tab in front of selected tab
596
g.setColor( selectHighlight );
597         }
598         else {
599             // tab in front of normal tab
600
g.setColor( highlight );
601         }
602         g.drawLine( 1, bottom - 4, 1, bottom );
603         }
604     } else {
605
606         // Paint left
607
if ( tabIndex==lastIndex ) {
608             // last tab in run
609
g.drawLine( 1, 0, 1, bottom - 1 );
610         } else {
611             g.drawLine( 0, 0, 0, bottom - 1 );
612         }
613     }
614
615         g.translate( -x, -y );
616     }
617
618     protected void paintRightTabBorder( int tabIndex, Graphics g,
619                                         int x, int y, int w, int h,
620                                         int btm, int rght,
621                                         boolean isSelected ) {
622         int tabCount = tabPane.getTabCount();
623         int currentRun = getRunForTab( tabCount, tabIndex );
624         int lastIndex = lastTabInRun( tabCount, currentRun );
625         int firstIndex = tabRuns[ currentRun ];
626
627         g.translate( x, y );
628
629         int bottom = h - 1;
630         int right = w - 1;
631
632         //
633
// Paint part of the tab above
634
//
635

636         if ( tabIndex != firstIndex && tabsOpaque ) {
637             g.setColor( tabPane.getSelectedIndex() == tabIndex - 1 ?
638                         tabAreaBackground :
639                         getUnselectedBackgroundAt( tabIndex - 1 ) );
640             g.fillRect( right - 5, 0, 5, 3 );
641             g.fillRect( right - 2, 3, 2, 2 );
642         }
643
644
645         //
646
// Paint Highlight
647
//
648

649         g.setColor( isSelected ? selectHighlight : highlight );
650
651         // Paint slant
652
g.drawLine( right - 6, 1, right - 1, 6 );
653
654         // Paint top
655
g.drawLine( 0, 1, right - 6, 1 );
656
657         // Paint left
658
if ( !isSelected ) {
659         g.drawLine( 0, 1, 0, bottom );
660     }
661
662
663         //
664
// Paint Border
665
//
666

667         if (ocean && isSelected) {
668             g.setColor(oceanSelectedBorderColor);
669         }
670         else {
671             g.setColor( darkShadow );
672         }
673
674         // Paint bottom
675
if ( tabIndex == lastIndex ) {
676             g.drawLine( 0, bottom, right, bottom );
677         }
678
679         // Paint slant
680
if (ocean && tabPane.getSelectedIndex() == tabIndex - 1) {
681             g.setColor(oceanSelectedBorderColor);
682         }
683         g.drawLine( right - 6, 0, right, 6 );
684
685         // Paint top
686
g.drawLine( 0, 0, right - 6, 0 );
687
688         // Paint right
689
if (ocean && isSelected) {
690             g.drawLine(right, 6, right, bottom);
691             if (tabIndex != firstIndex) {
692                 g.setColor(darkShadow);
693                 g.drawLine(right, 0, right, 5);
694             }
695         }
696         else if (ocean && tabPane.getSelectedIndex() == tabIndex - 1) {
697             g.setColor(oceanSelectedBorderColor);
698             g.drawLine(right, 0, right, 6);
699             g.setColor(darkShadow);
700             g.drawLine(right, 6, right, bottom);
701         }
702         else if ( tabIndex != firstIndex ) {
703             g.drawLine( right, 0, right, bottom );
704         } else {
705             g.drawLine( right, 6, right, bottom );
706         }
707
708         g.translate( -x, -y );
709     }
710
711     public void update( Graphics g, JComponent c ) {
712     if ( c.isOpaque() ) {
713         g.setColor( tabAreaBackground );
714         g.fillRect( 0, 0, c.getWidth(),c.getHeight() );
715     }
716     paint( g, c );
717     }
718
719     protected void paintTabBackground( Graphics g, int tabPlacement,
720                                        int tabIndex, int x, int y, int w, int h, boolean isSelected ) {
721         int slantWidth = h / 2;
722         if ( isSelected ) {
723             g.setColor( selectColor );
724         } else {
725             g.setColor( getUnselectedBackgroundAt( tabIndex ) );
726         }
727
728     if (MetalUtils.isLeftToRight(tabPane)) {
729         switch ( tabPlacement ) {
730                 case LEFT:
731             g.fillRect( x + 5, y + 1, w - 5, h - 1);
732             g.fillRect( x + 2, y + 4, 3, h - 4 );
733             break;
734                 case BOTTOM:
735             g.fillRect( x + 2, y, w - 2, h - 4 );
736             g.fillRect( x + 5, y + (h - 1) - 3, w - 5, 3 );
737             break;
738                 case RIGHT:
739             g.fillRect( x, y + 1, w - 4, h - 1);
740             g.fillRect( x + (w - 1) - 3, y + 5, 3, h - 5 );
741             break;
742                 case TOP:
743                 default:
744             g.fillRect( x + 4, y + 2, (w - 1) - 3, (h - 1) - 1 );
745             g.fillRect( x + 2, y + 5, 2, h - 5 );
746         }
747     } else {
748         switch ( tabPlacement ) {
749                 case LEFT:
750             g.fillRect( x + 5, y + 1, w - 5, h - 1);
751             g.fillRect( x + 2, y + 4, 3, h - 4 );
752             break;
753                 case BOTTOM:
754             g.fillRect( x, y, w - 5, h - 1 );
755             g.fillRect( x + (w - 1) - 4, y, 4, h - 5);
756             g.fillRect( x + (w - 1) - 4, y + (h - 1) - 4, 2, 2);
757             break;
758                 case RIGHT:
759             g.fillRect( x + 1, y + 1, w - 5, h - 1);
760             g.fillRect( x + (w - 1) - 3, y + 5, 3, h - 5 );
761             break;
762                 case TOP:
763                 default:
764             g.fillRect( x, y + 2, (w - 1) - 3, (h - 1) - 1 );
765             g.fillRect( x + (w - 1) - 3, y + 4, 3, h - 4 );
766         }
767     }
768     }
769
770     /**
771      * Overridden to do nothing for the Java L&F.
772      */

773     protected int getTabLabelShiftX( int tabPlacement, int tabIndex, boolean isSelected ) {
774         return 0;
775     }
776
777
778     /**
779      * Overridden to do nothing for the Java L&F.
780      */

781     protected int getTabLabelShiftY( int tabPlacement, int tabIndex, boolean isSelected ) {
782         return 0;
783     }
784
785
786     public void paint( Graphics g, JComponent c ) {
787         int tabPlacement = tabPane.getTabPlacement();
788
789         Insets insets = c.getInsets(); Dimension size = c.getSize();
790
791         // Paint the background for the tab area
792
if ( tabPane.isOpaque() ) {
793             Color bg = UIManager.getColor("TabbedPane.tabAreaBackground");
794             if (bg != null) {
795                 g.setColor(bg);
796             }
797             else {
798                 g.setColor( c.getBackground() );
799             }
800             switch ( tabPlacement ) {
801             case LEFT:
802                 g.fillRect( insets.left, insets.top,
803                             calculateTabAreaWidth( tabPlacement, runCount, maxTabWidth ),
804                             size.height - insets.bottom - insets.top );
805                 break;
806             case BOTTOM:
807                 int totalTabHeight = calculateTabAreaHeight( tabPlacement, runCount, maxTabHeight );
808                 g.fillRect( insets.left, size.height - insets.bottom - totalTabHeight,
809                             size.width - insets.left - insets.right,
810                             totalTabHeight );
811                 break;
812             case RIGHT:
813                 int totalTabWidth = calculateTabAreaWidth( tabPlacement, runCount, maxTabWidth );
814                 g.fillRect( size.width - insets.right - totalTabWidth,
815                             insets.top, totalTabWidth,
816                             size.height - insets.top - insets.bottom );
817                 break;
818             case TOP:
819             default:
820                 g.fillRect( insets.left, insets.top,
821                             size.width - insets.right - insets.left,
822                             calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight) );
823                 paintHighlightBelowTab();
824             }
825         }
826
827         super.paint( g, c );
828     }
829
830     protected void paintHighlightBelowTab( ) {
831
832     }
833
834
835     protected void paintFocusIndicator(Graphics g, int tabPlacement,
836                                        Rectangle[] rects, int tabIndex,
837                                        Rectangle iconRect, Rectangle textRect,
838                                        boolean isSelected) {
839         if ( tabPane.hasFocus() && isSelected ) {
840             Rectangle tabRect = rects[tabIndex];
841         boolean lastInRun = isLastInRun( tabIndex );
842             g.setColor( focus );
843             g.translate( tabRect.x, tabRect.y );
844             int right = tabRect.width - 1;
845             int bottom = tabRect.height - 1;
846         boolean leftToRight = MetalUtils.isLeftToRight(tabPane);
847             switch ( tabPlacement ) {
848             case RIGHT:
849                 g.drawLine( right - 6,2 , right - 2,6 ); // slant
850
g.drawLine( 1,2 , right - 6,2 ); // top
851
g.drawLine( right - 2,6 , right - 2,bottom ); // right
852
g.drawLine( 1,2 , 1,bottom ); // left
853
g.drawLine( 1,bottom , right - 2,bottom ); // bottom
854
break;
855             case BOTTOM:
856             if ( leftToRight ) {
857             g.drawLine( 2, bottom - 6, 6, bottom - 2 ); // slant
858
g.drawLine( 6, bottom - 2,
859                 right, bottom - 2 ); // bottom
860
g.drawLine( 2, 0, 2, bottom - 6 ); // left
861
g.drawLine( 2, 0, right, 0 ); // top
862
g.drawLine( right, 0, right, bottom - 2 ); // right
863
} else {
864             g.drawLine( right - 2, bottom - 6,
865                 right - 6, bottom - 2 ); // slant
866
g.drawLine( right - 2, 0,
867                 right - 2, bottom - 6 ); // right
868
if ( lastInRun ) {
869             // last tab in run
870
g.drawLine( 2, bottom - 2,
871                     right - 6, bottom - 2 ); // bottom
872
g.drawLine( 2, 0, right - 2, 0 ); // top
873
g.drawLine( 2, 0, 2, bottom - 2 ); // left
874
} else {
875             g.drawLine( 1, bottom - 2,
876                     right - 6, bottom - 2 ); // bottom
877
g.drawLine( 1, 0, right - 2, 0 ); // top
878
g.drawLine( 1, 0, 1, bottom - 2 ); // left
879
}
880         }
881                 break;
882             case LEFT:
883                 g.drawLine( 2, 6, 6, 2 ); // slant
884
g.drawLine( 2, 6, 2, bottom - 1); // left
885
g.drawLine( 6, 2, right, 2 ); // top
886
g.drawLine( right, 2, right, bottom - 1 ); // right
887
g.drawLine( 2, bottom - 1,
888                             right, bottom - 1 ); // bottom
889
break;
890             case TOP:
891              default:
892             if ( leftToRight ) {
893                 g.drawLine( 2, 6, 6, 2 ); // slant
894
g.drawLine( 2, 6, 2, bottom - 1); // left
895
g.drawLine( 6, 2, right, 2 ); // top
896
g.drawLine( right, 2, right, bottom - 1 ); // right
897
g.drawLine( 2, bottom - 1,
898                     right, bottom - 1 ); // bottom
899
}
900             else {
901                 g.drawLine( right - 2, 6, right - 6, 2 ); // slant
902
g.drawLine( right - 2, 6,
903                     right - 2, bottom - 1); // right
904
if ( lastInRun ) {
905                 // last tab in run
906
g.drawLine( right - 6, 2, 2, 2 ); // top
907
g.drawLine( 2, 2, 2, bottom - 1 ); // left
908
g.drawLine( right - 2, bottom - 1,
909                     2, bottom - 1 ); // bottom
910
}
911             else {
912                 g.drawLine( right - 6, 2, 1, 2 ); // top
913
g.drawLine( 1, 2, 1, bottom - 1 ); // left
914
g.drawLine( right - 2, bottom - 1,
915                     1, bottom - 1 ); // bottom
916
}
917             }
918             }
919             g.translate( -tabRect.x, -tabRect.y );
920         }
921     }
922
923     protected void paintContentBorderTopEdge( Graphics g, int tabPlacement,
924                                               int selectedIndex,
925                                               int x, int y, int w, int h ) {
926     boolean leftToRight = MetalUtils.isLeftToRight(tabPane);
927     int right = x + w - 1;
928         Rectangle selRect = selectedIndex < 0? null :
929                            getTabBounds(selectedIndex, calcRect);
930         if (ocean) {
931             g.setColor(oceanSelectedBorderColor);
932         }
933         else {
934             g.setColor(selectHighlight);
935         }
936
937     // Draw unbroken line if tabs are not on TOP, OR
938
// selected tab is not in run adjacent to content, OR
939
// selected tab is not visible (SCROLL_TAB_LAYOUT)
940
//
941
if (tabPlacement != TOP || selectedIndex < 0 ||
942             (selRect.y + selRect.height + 1 < y) ||
943         (selRect.x < x || selRect.x > x + w)) {
944             g.drawLine(x, y, x+w-2, y);
945             if (ocean && tabPlacement == TOP) {
946                 g.setColor(MetalLookAndFeel.getWhite());
947                 g.drawLine(x, y + 1, x+w-2, y + 1);
948             }
949         } else {
950         // Break line to show visual connection to selected tab
951
boolean lastInRun = isLastInRun(selectedIndex);
952
953         if ( leftToRight || lastInRun ) {
954             g.drawLine(x, y, selRect.x + 1, y);
955         } else {
956             g.drawLine(x, y, selRect.x, y);
957         }
958
959             if (selRect.x + selRect.width < right - 1) {
960             if ( leftToRight && !lastInRun ) {
961             g.drawLine(selRect.x + selRect.width, y, right - 1, y);
962         } else {
963             g.drawLine(selRect.x + selRect.width - 1, y, right - 1, y);
964         }
965             } else {
966             g.setColor(shadow);
967                 g.drawLine(x+w-2, y, x+w-2, y);
968             }
969
970             if (ocean) {
971                 g.setColor(MetalLookAndFeel.getWhite());
972
973                 if ( leftToRight || lastInRun ) {
974                     g.drawLine(x, y + 1, selRect.x + 1, y + 1);
975                 } else {
976                     g.drawLine(x, y + 1, selRect.x, y + 1);
977                 }
978
979                 if (selRect.x + selRect.width < right - 1) {
980                     if ( leftToRight && !lastInRun ) {
981                         g.drawLine(selRect.x + selRect.width, y + 1,
982                                    right - 1, y + 1);
983                     } else {
984                         g.drawLine(selRect.x + selRect.width - 1, y + 1,
985                                    right - 1, y + 1);
986                     }
987                 } else {
988                     g.setColor(shadow);
989                     g.drawLine(x+w-2, y + 1, x+w-2, y + 1);
990                 }
991             }
992         }
993     }
994
995     protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
996                                                 int selectedIndex,
997                                                 int x, int y, int w, int h) {
998     boolean leftToRight = MetalUtils.isLeftToRight(tabPane);
999         int bottom = y + h - 1;
1000    int right = x + w - 1;
1001        Rectangle selRect = selectedIndex < 0? null :
1002                           getTabBounds(selectedIndex, calcRect);
1003
1004        g.setColor(darkShadow);
1005
1006    // Draw unbroken line if tabs are not on BOTTOM, OR
1007
// selected tab is not in run adjacent to content, OR
1008
// selected tab is not visible (SCROLL_TAB_LAYOUT)
1009
//
1010
if (tabPlacement != BOTTOM || selectedIndex < 0 ||
1011             (selRect.y - 1 > h) ||
1012         (selRect.x < x || selRect.x > x + w)) {
1013            if (ocean && tabPlacement == BOTTOM) {
1014                g.setColor(oceanSelectedBorderColor);
1015            }
1016            g.drawLine(x, y+h-1, x+w-1, y+h-1);
1017        } else {
1018        // Break line to show visual connection to selected tab
1019
boolean lastInRun = isLastInRun(selectedIndex);
1020
1021            if (ocean) {
1022                g.setColor(oceanSelectedBorderColor);
1023            }
1024
1025        if ( leftToRight || lastInRun ) {
1026            g.drawLine(x, bottom, selRect.x, bottom);
1027        } else {
1028            g.drawLine(x, bottom, selRect.x - 1, bottom);
1029        }
1030
1031            if (selRect.x + selRect.width < x + w - 2) {
1032            if ( leftToRight && !lastInRun ) {
1033            g.drawLine(selRect.x + selRect.width, bottom,
1034                                       right, bottom);
1035        } else {
1036            g.drawLine(selRect.x + selRect.width - 1, bottom,
1037                                           right, bottom);
1038        }
1039            }
1040        }
1041    }
1042
1043    protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
1044                                              int selectedIndex,
1045                                              int x, int y, int w, int h) {
1046        Rectangle selRect = selectedIndex < 0? null :
1047                           getTabBounds(selectedIndex, calcRect);
1048        if (ocean) {
1049            g.setColor(oceanSelectedBorderColor);
1050        }
1051        else {
1052            g.setColor(selectHighlight);
1053        }
1054
1055    // Draw unbroken line if tabs are not on LEFT, OR
1056
// selected tab is not in run adjacent to content, OR
1057
// selected tab is not visible (SCROLL_TAB_LAYOUT)
1058
//
1059
if (tabPlacement != LEFT || selectedIndex < 0 ||
1060            (selRect.x + selRect.width + 1 < x) ||
1061        (selRect.y < y || selRect.y > y + h)) {
1062            g.drawLine(x, y + 1, x, y+h-2);
1063            if (ocean && tabPlacement == LEFT) {
1064                g.setColor(MetalLookAndFeel.getWhite());
1065                g.drawLine(x + 1, y, x + 1, y + h - 2);
1066            }
1067        } else {
1068        // Break line to show visual connection to selected tab
1069
g.drawLine(x, y, x, selRect.y + 1);
1070            if (selRect.y + selRect.height < y + h - 2) {
1071          g.drawLine(x, selRect.y + selRect.height + 1,
1072             x, y+h+2);
1073            }
1074            if (ocean) {
1075                g.setColor(MetalLookAndFeel.getWhite());
1076                g.drawLine(x + 1, y + 1, x + 1, selRect.y + 1);
1077                if (selRect.y + selRect.height < y + h - 2) {
1078                    g.drawLine(x + 1, selRect.y + selRect.height + 1,
1079                               x + 1, y+h+2);
1080                }
1081            }
1082        }
1083    }
1084
1085    protected void paintContentBorderRightEdge(Graphics g, int tabPlacement,
1086                                               int selectedIndex,
1087                                               int x, int y, int w, int h) {
1088        Rectangle selRect = selectedIndex < 0? null :
1089                           getTabBounds(selectedIndex, calcRect);
1090
1091        g.setColor(darkShadow);
1092    // Draw unbroken line if tabs are not on RIGHT, OR
1093
// selected tab is not in run adjacent to content, OR
1094
// selected tab is not visible (SCROLL_TAB_LAYOUT)
1095
//
1096
if (tabPlacement != RIGHT || selectedIndex < 0 ||
1097             (selRect.x - 1 > w) ||
1098         (selRect.y < y || selRect.y > y + h)) {
1099            if (ocean && tabPlacement == RIGHT) {
1100                g.setColor(oceanSelectedBorderColor);
1101            }
1102            g.drawLine(x+w-1, y, x+w-1, y+h-1);
1103        } else {
1104        // Break line to show visual connection to selected tab
1105
if (ocean) {
1106                g.setColor(oceanSelectedBorderColor);
1107            }
1108            g.drawLine(x+w-1, y, x+w-1, selRect.y);
1109
1110            if (selRect.y + selRect.height < y + h - 2) {
1111                g.drawLine(x+w-1, selRect.y + selRect.height,
1112                           x+w-1, y+h-2);
1113            }
1114        }
1115    }
1116
1117    protected int calculateMaxTabHeight( int tabPlacement ) {
1118        FontMetrics metrics = getFontMetrics();
1119        int height = metrics.getHeight();
1120        boolean tallerIcons = false;
1121
1122        for ( int i = 0; i < tabPane.getTabCount(); ++i ) {
1123            Icon icon = tabPane.getIconAt( i );
1124            if ( icon != null ) {
1125                if ( icon.getIconHeight() > height ) {
1126                    tallerIcons = true;
1127                    break;
1128                }
1129            }
1130        }
1131        return super.calculateMaxTabHeight( tabPlacement ) -
1132                  (tallerIcons ? (tabInsets.top + tabInsets.bottom) : 0);
1133    }
1134
1135
1136    protected int getTabRunOverlay( int tabPlacement ) {
1137        // Tab runs laid out vertically should overlap
1138
// at least as much as the largest slant
1139
if ( tabPlacement == LEFT || tabPlacement == RIGHT ) {
1140            int maxTabHeight = calculateMaxTabHeight(tabPlacement);
1141            return maxTabHeight / 2;
1142        }
1143        return 0;
1144    }
1145
1146    // Don't rotate runs!
1147
protected boolean shouldRotateTabRuns( int tabPlacement, int selectedRun ) {
1148        return false;
1149    }
1150
1151    // Don't pad last run
1152
protected boolean shouldPadTabRun( int tabPlacement, int run ) {
1153        return runCount > 1 && run < runCount - 1;
1154    }
1155
1156    private boolean isLastInRun( int tabIndex ) {
1157        int run = getRunForTab( tabPane.getTabCount(), tabIndex );
1158    int lastIndex = lastTabInRun( tabPane.getTabCount(), run );
1159    return tabIndex == lastIndex;
1160    }
1161
1162    /**
1163     * Returns the color to use for the specified tab.
1164     */

1165    private Color getUnselectedBackgroundAt(int index) {
1166        Color color = tabPane.getBackgroundAt(index);
1167        if (color instanceof UIResource) {
1168            if (unselectedBackground != null) {
1169                return unselectedBackground;
1170            }
1171        }
1172        return color;
1173    }
1174
1175    /**
1176     * Returns the tab index of JTabbedPane the mouse is currently over
1177     */

1178    int getRolloverTabIndex() {
1179        return getRolloverTab();
1180    }
1181
1182    /**
1183     * This inner class is marked &quot;public&quot; due to a compiler bug.
1184     * This class should be treated as a &quot;protected&quot; inner class.
1185     * Instantiate it only within subclasses of MetalTabbedPaneUI.
1186     */

1187    public class TabbedPaneLayout extends BasicTabbedPaneUI.TabbedPaneLayout JavaDoc {
1188
1189    public TabbedPaneLayout() {
1190        MetalTabbedPaneUI.this.super();
1191    }
1192
1193        protected void normalizeTabRuns( int tabPlacement, int tabCount,
1194                                     int start, int max ) {
1195            // Only normalize the runs for top & bottom; normalizing
1196
// doesn't look right for Metal's vertical tabs
1197
// because the last run isn't padded and it looks odd to have
1198
// fat tabs in the first vertical runs, but slimmer ones in the
1199
// last (this effect isn't noticeable for horizontal tabs).
1200
if ( tabPlacement == TOP || tabPlacement == BOTTOM ) {
1201                super.normalizeTabRuns( tabPlacement, tabCount, start, max );
1202            }
1203        }
1204
1205        // Don't rotate runs!
1206
protected void rotateTabRuns( int tabPlacement, int selectedRun ) {
1207        }
1208
1209        // Don't pad selected tab
1210
protected void padSelectedTab( int tabPlacement, int selectedIndex ) {
1211        }
1212    }
1213
1214}
1215
1216
Popular Tags