KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > compiere > plaf > CompiereTabbedPaneUI


1 /******************************************************************************
2  * The contents of this file are subject to the Compiere License Version 1.1
3  * ("License"); You may not use this file except in compliance with the License
4  * You may obtain a copy of the License at http://www.compiere.org/license.html
5  * Software distributed under the License is distributed on an "AS IS" basis,
6  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
7  * the specific language governing rights and limitations under the License.
8  * The Original Code is Compiere ERP & CRM Business Solution
9  * The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc.
10  * Portions created by Jorg Janke are Copyright (C) 1999-2001 Jorg Janke, parts
11  * created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved.
12  * Contributor(s): ______________________________________.
13  *****************************************************************************/

14 package org.compiere.plaf;
15
16 import java.awt.Color JavaDoc;
17 import java.awt.Component JavaDoc;
18 import java.awt.Dimension JavaDoc;
19 import java.awt.Font JavaDoc;
20 import java.awt.FontMetrics JavaDoc;
21 import java.awt.GradientPaint JavaDoc;
22 import java.awt.Graphics JavaDoc;
23 import java.awt.Graphics2D JavaDoc;
24 import java.awt.Insets JavaDoc;
25 import java.awt.LayoutManager JavaDoc;
26 import java.awt.Polygon JavaDoc;
27 import java.awt.Rectangle JavaDoc;
28 import java.awt.Shape JavaDoc;
29
30 import javax.swing.Icon JavaDoc;
31 import javax.swing.JComponent JavaDoc;
32 import javax.swing.JPanel JavaDoc;
33 import javax.swing.SwingUtilities JavaDoc;
34 import javax.swing.plaf.ComponentUI JavaDoc;
35 import javax.swing.plaf.basic.BasicGraphicsUtils JavaDoc;
36 import javax.swing.plaf.metal.MetalTabbedPaneUI JavaDoc;
37
38 /**
39  * Same implementation detail as in CompierePanelUI.
40  * Additional handling of dwawing tabs.
41  * @see CompierePanelUI
42  *
43  * @author Jorg Janke
44  * @version $Id: CompiereTabbedPaneUI.java,v 1.14 2003/09/27 11:08:53 jjanke Exp $
45  */

46 public class CompiereTabbedPaneUI extends MetalTabbedPaneUI JavaDoc
47 {
48     /**
49      * Static Create UI
50      * @param c Component
51      * @return Compiere TabbedPaneUI
52      */

53     public static ComponentUI JavaDoc createUI(JComponent JavaDoc c)
54     {
55         return new CompiereTabbedPaneUI();
56     } // createUI
57

58     /**
59      * Install Defaults
60      */

61     protected void installDefaults()
62     {
63         super.installDefaults();
64         tabPane.setOpaque(false);
65     } // installDefaults
66

67     /*************************************************************************/
68
69     /**
70      * Update -
71      * This method is invoked by <code>JComponent</code> when the specified
72      * component is being painted.
73      *
74      * By default this method will fill the specified component with
75      * its background color (if its <code>opaque</code> property is
76      * <code>true</code>) and then immediately call <code>paint</code>.
77      *
78      * @param g the <code>Graphics</code> context in which to paint
79      * @param c the component being painted
80      *
81      * @see #paint
82      * @see javax.swing.JComponent#paintComponent
83      */

84     public void update (Graphics JavaDoc g, JComponent JavaDoc c)
85     {
86         /**
87         System.out.println (c.getClass().getName() + " ** " + c.isOpaque());
88         Container container = c.getParent();
89         while (container != null)
90         {
91             System.out.println (" - " + container.getClass() + " ** " + container.isOpaque() );
92             container = container.getParent();
93         }
94         */

95
96     // System.out.println("Tab: Bounds=" + c.getBounds() + " - " + c.getClass().getName());
97

98         if (c.isOpaque())
99             CompierePanelUI.updateIt (g, c); // tabAreaBackground
100
paint (g, c);
101     } // update
102

103     /**
104      * Paint it
105      * @param g graphics
106      * @param c component
107      */

108     public void paint( Graphics JavaDoc g, JComponent JavaDoc c )
109     {
110         int tabPlacement = tabPane.getTabPlacement();
111         Insets JavaDoc insets = c.getInsets();
112         Dimension JavaDoc size = c.getSize();
113
114         if ( tabPane.isOpaque() )
115         {
116             g.setColor(c.getBackground());
117             /** @todo Printing of area behind Tabs */
118             switch (tabPlacement)
119             {
120                 case LEFT:
121                     g.fillRect( insets.left, insets.top,
122                         calculateTabAreaWidth( tabPlacement, runCount, maxTabWidth ),
123                         size.height - insets.bottom - insets.top );
124                     break;
125                 case BOTTOM:
126                     int totalTabHeight = calculateTabAreaHeight( tabPlacement, runCount, maxTabHeight );
127                     g.fillRect( insets.left, size.height - insets.bottom - totalTabHeight,
128                         size.width - insets.left - insets.right,
129                         totalTabHeight );
130                     break;
131                 case RIGHT:
132                     int totalTabWidth = calculateTabAreaWidth( tabPlacement, runCount, maxTabWidth );
133                     g.fillRect( size.width - insets.right - totalTabWidth,
134                         insets.top, totalTabWidth,
135                         size.height - insets.top - insets.bottom );
136                     break;
137                 case TOP:
138                 default:
139                     g.fillRect( insets.left, insets.top,
140                         size.width - insets.right - insets.left,
141                         calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight) );
142                     paintHighlightBelowTab();
143             }
144         }
145         /**/
146         super.paint( g, c );
147     } // paint
148

149     /*************************************************************************/
150
151     /**
152      * Paint the actual Tab Background.
153      * Called from Basic.PaintTab (<- Basic.paintTabArea <- Basic.paint)
154      * <p>
155      * Based on MetalTabbedPaneUI.paintTabBackground:
156      * Differences:
157      * - Color based on primary Background of Tab
158      * - Selected Tab is painted
159      * <pre>
160      * selected not sel
161      * top ////////// ////////// (lighter)
162      * ++++++++++ (flat/darker)
163      *
164      * bottom ////////// (flat/lighter)
165      * ++++++++++ ++++++++++ (darker)
166      *
167      * sides ////////// (flat/ligher)
168      * ++++++++++ (flat/darker)
169      * </pre>
170      * @param g graphics
171      * @param tabPlacement tab placement
172      * @param tabIndex tab index
173      * @param x x
174      * @param y y
175      * @param w width
176      * @param h height
177      * @param isSelected selected
178      */

179      protected void paintTabBackground (Graphics JavaDoc g, int tabPlacement,
180         int tabIndex, int x, int y, int w, int h, boolean isSelected)
181     {
182         Graphics2D JavaDoc g2D = (Graphics2D JavaDoc)g;
183
184
185         // Get Background color of Tab
186
Component JavaDoc comp = tabPane.getComponentAt(tabIndex);
187     // System.out.println("Tab " + tabIndex + " Comp=" + comp.getName() + " " + comp.getClass().getName() + " x=" + x + ", y=" + y + ", w=" +w + ", h=" + h);
188
g2D.setPaint(comp.getBackground());
189         CompiereColor bg = null;
190         if (comp instanceof JPanel JavaDoc)
191         {
192             JPanel JavaDoc jp = (JPanel JavaDoc)comp;
193             try
194             {
195                 bg = (CompiereColor)jp.getClientProperty(CompierePLAF.BACKGROUND);
196             }
197             catch (Exception JavaDoc e)
198             {
199                 System.err.println("CompiereTabbedPaneUI - ClientProperty: " + e.getMessage());
200             }
201         }
202
203         if (bg == null) // No Background
204
{
205             if (CompiereUtils.isLeftToRight(tabPane))
206             {
207                 switch (tabPlacement)
208                 {
209                     case LEFT:
210                         g2D.fillRect( x + 5, y + 1, w - 5, h - 1);
211                         g2D.fillRect( x + 2, y + 4, 3, h - 4 );
212                         break;
213                     case BOTTOM:
214                         g2D.fillRect( x + 2, y, w - 2, h - 4 );
215                         g2D.fillRect( x + 5, y + (h - 1) - 3, w - 5, 3 );
216                         break;
217                     case RIGHT:
218                         g2D.fillRect( x + 1, y + 1, w - 5, h - 1);
219                         g2D.fillRect( x + (w - 1) - 3, y + 5, 3, h - 5 );
220                         break;
221                     case TOP:
222                     default:
223                         g2D.fillRect( x + 4, y + 2, (w - 1) - 3, (h - 1) - 1 );
224                         g2D.fillRect( x + 2, y + 5, 2, h - 5 );
225                 }
226             }
227             else
228             {
229                 switch (tabPlacement)
230                 {
231                     case LEFT:
232                         g2D.fillRect( x + 5, y + 1, w - 5, h - 1);
233                         g2D.fillRect( x + 2, y + 4, 3, h - 4 );
234                         break;
235                     case BOTTOM:
236                         g2D.fillRect( x, y, w - 5, h - 1 );
237                         g2D.fillRect( x + (w - 1) - 4, y, 4, h - 5);
238                         g2D.fillRect( x + (w - 1) - 4, y + (h - 1) - 4, 2, 2);
239                         break;
240                     case RIGHT:
241                         g2D.fillRect( x + 1, y + 1, w - 5, h - 1);
242                         g2D.fillRect( x + (w - 1) - 3, y + 5, 3, h - 5 );
243                         break;
244                     case TOP:
245                     default:
246                         g2D.fillRect( x, y + 2, (w - 1) - 3, (h - 1) - 1 );
247                         g2D.fillRect( x + (w - 1) - 3, y + 4, 3, h - 4 );
248                 }
249             }
250         }
251         else // we have a background
252
{
253             if (CompiereUtils.isLeftToRight(tabPane))
254             {
255                 switch (tabPlacement)
256                 {
257                     case LEFT:
258                         bg.paintRect (g2D, tabPane, x + 5, y + 1, w - 5, h - 1);
259                         bg.paintRect (g2D, tabPane, x + 2, y + 4, 3, h - 4 );
260                         break;
261                     case BOTTOM:
262                         bg.paintRect (g2D, tabPane, x + 2, y, w - 2, h - 4 );
263                         bg.paintRect (g2D, tabPane, x + 5, y + (h - 1) - 3, w - 5, 3 );
264                         break;
265                     case RIGHT:
266                     // bg.paintRect (g2D, tabPane, x + 1, y + 1, w - 5, h - 1);
267
bg.paintRect (g2D, tabPane, x, y + 2, w - 4, h - 2); // changed
268
bg.paintRect (g2D, tabPane, x + (w - 1) - 3, y + 5, 3, h - 5 );
269                         break;
270                     case TOP:
271                     default:
272                         bg.paintRect (g2D, tabPane, x + 4, y + 2, (w - 1) - 3, (h - 1) - 1 );
273                         bg.paintRect (g2D, tabPane, x + 2, y + 5, 2, h - 5 );
274                 }
275             }
276             else
277             {
278                 switch (tabPlacement)
279                 {
280                     case LEFT:
281                         bg.paintRect (g2D, tabPane, x + 5, y + 1, w - 5, h - 1);
282                         bg.paintRect (g2D, tabPane, x + 2, y + 4, 3, h - 4 );
283                         break;
284                     case BOTTOM:
285                         bg.paintRect (g2D, tabPane, x, y, w - 5, h - 1 );
286                         bg.paintRect (g2D, tabPane, x + (w - 1) - 4, y, 4, h - 5);
287                         bg.paintRect (g2D, tabPane, x + (w - 1) - 4, y + (h - 1) - 4, 2, 2);
288                         break;
289                     case RIGHT:
290                         bg.paintRect (g2D, tabPane, x + 1, y + 1, w - 5, h - 1);
291                         bg.paintRect (g2D, tabPane, x + (w - 1) - 3, y + 5, 3, h - 5 );
292                         break;
293                     case TOP:
294                     default:
295                         bg.paintRect (g2D, tabPane, x, y + 2, (w - 1) - 3, (h - 1) - 1 );
296                         bg.paintRect (g2D, tabPane, x + (w - 1) - 3, y + 4, 3, h - 4 );
297                 }
298             }
299         }
300
301         // Upper Part - not when selected and R/L/B
302
if (!(isSelected && (tabPlacement == RIGHT || tabPlacement == LEFT || tabPlacement == BOTTOM)))
303         {
304             Shape JavaDoc top = new Rectangle JavaDoc (x, y, w, h/2); // upper half
305
if (tabPlacement == TOP || tabPlacement == LEFT)
306                 top = new Polygon JavaDoc ( // top left triangle
307
new int[] {x+6, x+w, x+w, x, x },
308                     new int[] {y, y, y+(h/2), y+(h/2), y+6 }, 5);
309             else if (tabPlacement == RIGHT)
310                 top = new Polygon JavaDoc ( // top right triangle
311
new int[] {x, x+w-6, x+w, x+w, x },
312                     new int[] {y, y, y+6, y+(h/2), y+(h/2) }, 5);
313         // lighter
314
GradientPaint JavaDoc paint = new GradientPaint JavaDoc (
315                 x, y, CompiereUtils.COL_1TOP,
316                 x, y+(h/2), CompiereUtils.COL_1END);
317             g2D.setPaint(paint);
318             g2D.fill(top);
319         }
320
321         // Lower part - not when selected and T/R/L
322
if (!(isSelected && (tabPlacement == TOP || tabPlacement == RIGHT || tabPlacement == LEFT)))
323         {
324             Shape JavaDoc end = new Rectangle JavaDoc (x, y+(h/2), w, h/2); // lower half
325
if (tabPlacement == BOTTOM)
326                 end = new Polygon JavaDoc ( // bottom left triangle
327
new int[] {x, x+w, x+w, x+6, x },
328                     new int[] {y+(h/2), y+(h/2), y+h, y+h, y+h-6 }, 5);
329         // darker
330
GradientPaint JavaDoc paint = new GradientPaint JavaDoc (
331                 x, y+(h/2), CompiereUtils.COL_2TOP,
332                 x, y+h, CompiereUtils.COL_2END);
333             g2D.setPaint(paint);
334             g2D.fill(end);
335         }
336
337     } // paintTabBackground
338

339     /*************************************************************************/
340
341     /**
342      * Paint Content Border (overwriting BasicTabbedPanelUI)
343      * Uses Color from actual Tab (not from TabbedPane)
344      * @param g graphics
345      * @param tabPlacement tab placement
346      * @param selectedIndex index
347      */

348     protected void paintContentBorder (Graphics JavaDoc g, int tabPlacement, int selectedIndex)
349     {
350     // System.out.println("TabContentBorder " );
351
int width = tabPane.getWidth();
352         int height = tabPane.getHeight();
353         Insets JavaDoc insets = tabPane.getInsets();
354
355         int x = insets.left;
356         int y = insets.top;
357         int w = width - insets.right - insets.left;
358         int h = height - insets.top - insets.bottom;
359
360         switch (tabPlacement)
361         {
362             case LEFT:
363                 x += calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth);
364                 w -= (x - insets.left);
365                 break;
366             case RIGHT:
367                 w -= calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth);
368                 break;
369             case BOTTOM:
370                 h -= calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight);
371                 break;
372             case TOP:
373             default:
374                 y += calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight);
375                 h -= (y - insets.top);
376         }
377
378         // Fill region behind content area - basically a border
379
Component JavaDoc comp = null;
380         if (selectedIndex != -1)
381             comp = tabPane.getComponentAt(selectedIndex);
382         if (comp != null && comp instanceof JComponent JavaDoc)
383         {
384             JComponent JavaDoc jc = (JComponent JavaDoc)comp;
385             CompiereColor bg = null;
386             try
387             {
388                 bg = (CompiereColor)jc.getClientProperty(CompierePLAF.BACKGROUND);
389             }
390             catch (Exception JavaDoc e)
391             {
392                 System.err.println("CompiereTabbedPaneUI - ClientProperty: " + e.getMessage());
393             }
394             if (bg == null)
395             {
396                 bg = new CompiereColor(jc.getBackground());
397                 jc.putClientProperty(CompierePLAF.BACKGROUND, bg);
398             }
399             bg.paintRect(g, jc, x,y, w,h);
400         }
401         // Not a JComponent - paint flat
402
else if (comp != null)
403         {
404             g.setColor(comp.getBackground());
405             g.fillRect(x,y, w,h);
406         }
407
408         paintContentBorderTopEdge(g, tabPlacement, selectedIndex, x, y, w, h);
409         paintContentBorderLeftEdge(g, tabPlacement, selectedIndex, x, y, w, h);
410         paintContentBorderBottomEdge(g, tabPlacement, selectedIndex, x, y, w, h);
411         paintContentBorderRightEdge(g, tabPlacement, selectedIndex, x, y, w, h);
412     } // paintContentBorder
413

414     /**
415      * Paint left content border edge
416      * @param g graphics
417      * @param tabPlacement tab placement
418      * @param selectedIndex index
419      * @param x x
420      * @param y y
421      * @param w width
422      * @param h height
423      */

424     protected void paintContentBorderLeftEdge (Graphics JavaDoc g, int tabPlacement,
425         int selectedIndex, int x, int y, int w, int h)
426     {
427         Rectangle JavaDoc selRect = selectedIndex < 0 ? null : getTabBounds(selectedIndex, calcRect);
428         g.setColor(selectHighlight);
429
430         // Draw unbroken line if tabs are not on LEFT, OR
431
// selected tab is not in run adjacent to content, OR
432
// selected tab is not visible (SCROLL_TAB_LAYOUT)
433
if (tabPlacement != LEFT || selectedIndex < 0
434                 || (selRect.x + selRect.width + 1 < x)
435                 || (selRect.y < y || selRect.y > y + h))
436         {
437             g.drawLine(x, y, x, y+h-2);
438         }
439         else
440         {
441             // Break line to show visual connection to selected tab
442
g.drawLine(x, y, x, selRect.y + 1);
443             if (selRect.y + selRect.height < y + h - 2)
444                 g.drawLine(x, selRect.y + selRect.height + 1, x, y+h-2); // bug
445
}
446     }
447
448     /**
449      * Paint bottom content area edge
450      * @param g graphics
451      * @param tabPlacement tab placement
452      * @param selectedIndex index
453      * @param x x
454      * @param y y
455      * @param w width
456      * @param h height
457      */

458     protected void paintContentBorderBottomEdge (Graphics JavaDoc g, int tabPlacement,
459         int selectedIndex, int x, int y, int w, int h)
460     {
461         boolean leftToRight = CompiereUtils.isLeftToRight(tabPane);
462         int bottom = y + h - 1;
463         int right = x + w - 1;
464         Rectangle JavaDoc selRect = selectedIndex < 0 ? null : getTabBounds(selectedIndex, calcRect);
465         g.setColor(shadow);
466
467         // Draw unbroken line if tabs are not on BOTTOM, OR
468
// selected tab is not in run adjacent to content, OR
469
// selected tab is not visible (SCROLL_TAB_LAYOUT)
470
if (tabPlacement != BOTTOM
471                 || selectedIndex < 0
472 // || (selRect.y - 1 > h) // bug!!
473
|| (selRect.x < x || selRect.x > x + w))
474         {
475             g.setColor(darkShadow);
476             g.drawLine(x, y+h-1, x+w-1, y+h-1);
477         }
478         else
479         {
480             // Break line to show visual connection to selected tab
481
boolean lastInRun = isLastInRun(selectedIndex);
482             g.setColor(darkShadow);
483             if ( leftToRight || lastInRun )
484                 g.drawLine(x, bottom, selRect.x, bottom);
485             else
486                 g.drawLine(x, bottom, selRect.x - 1, bottom);
487
488             if (selRect.x + selRect.width < x + w - 2)
489             {
490                 if ( leftToRight && !lastInRun )
491                     g.drawLine(selRect.x + selRect.width, bottom, right, bottom);
492                 else
493                     g.drawLine(selRect.x + selRect.width - 1, bottom, right, bottom);
494             }
495         }
496     } // paintContentBorderBottomEdge
497

498     /**
499      * Paint right Contenr border edge
500      * @param g graphics
501      * @param tabPlacement tab placement
502      * @param selectedIndex index
503      * @param x x
504      * @param y y
505      * @param w width
506      * @param h height
507      */

508     protected void paintContentBorderRightEdge (Graphics JavaDoc g, int tabPlacement,
509         int selectedIndex, int x, int y, int w, int h)
510     {
511         Rectangle JavaDoc selRect = selectedIndex < 0 ? null : getTabBounds(selectedIndex, calcRect);
512         g.setColor(shadow);
513
514         // Draw unbroken line if tabs are not on RIGHT, OR
515
// selected tab is not in run adjacent to content, OR
516
// selected tab is not visible (SCROLL_TAB_LAYOUT)
517
if (tabPlacement != RIGHT
518                 || selectedIndex < 0
519 // || (selRect.x - 1 > w) // bug !!
520
|| (selRect.y < y || selRect.y > y + h)
521                 )
522         {
523             g.setColor(darkShadow);
524             g.drawLine(x+w-1, y, x+w-1, y+h-1);
525         }
526         else
527         {
528             // Break line to show visual connection to selected tab
529
g.setColor(darkShadow);
530             g.drawLine(x+w-1, y, x+w-1, selRect.y);
531             if (selRect.y + selRect.height < y + h - 2)
532             {
533                 g.setColor(darkShadow);
534                 g.drawLine(x+w-1, selRect.y + selRect.height, x+w-1, y+h-2);
535             }
536         }
537     } // paintContentBorderRightEdge
538

539     /**
540      * Is Last Run
541      * @param tabIndex index
542      * @return true if last tab run
543      */

544     private boolean isLastInRun (int tabIndex)
545     {
546         int run = getRunForTab( tabPane.getTabCount(), tabIndex );
547         int lastIndex = lastTabInRun( tabPane.getTabCount(), run );
548         return tabIndex == lastIndex;
549     } // isLastRun
550

551     /*************************************************************************/
552
553     /**
554      * Fill Tab gap triangle (no)
555      * @param currentRun current run
556      * @param tabIndex tab index
557      * @param x x
558      * @param y y
559      * @return false
560      */

561     protected boolean shouldFillGap (int currentRun, int tabIndex, int x, int y)
562     {
563         return false;
564     } // shouldFillGap
565

566     /**
567      * Paint Top Tab Border
568      * @param tabIndex index
569      * @param g graphics
570      * @param x x
571      * @param y y
572      * @param w width
573      * @param h height
574      * @param btm bottom
575      * @param rght right
576      * @param isSelected selected
577      */

578     protected void paintTopTabBorder ( int tabIndex, Graphics JavaDoc g,
579         int x, int y, int w, int h, int btm, int rght, boolean isSelected )
580     {
581         int currentRun = getRunForTab( tabPane.getTabCount(), tabIndex );
582         int lastIndex = lastTabInRun( tabPane.getTabCount(), currentRun );
583         int firstIndex = tabRuns[ currentRun ];
584         boolean leftToRight = CompiereUtils.isLeftToRight(tabPane);
585         int bottom = h - 1;
586         int right = w - 1;
587
588         // ** Paint Gap **
589
if ( shouldFillGap( currentRun, tabIndex, x, y ) )
590         {
591             g.translate( x, y );
592             if ( leftToRight )
593             {
594                 g.setColor( getColorForGap( currentRun, x, y + 1 ) );
595                 g.fillRect( 1, 0, 5, 3 );
596                 g.fillRect( 1, 3, 2, 2 );
597             }
598             else
599             {
600                 g.setColor( getColorForGap( currentRun, x + w - 1, y + 1 ) );
601                 g.fillRect( right - 5, 0, 5, 3 );
602                 g.fillRect( right - 2, 3, 2, 2 );
603             }
604             g.translate( -x, -y );
605         }
606
607         g.translate( x, y );
608         // ** Paint Border **
609
g.setColor( darkShadow );
610         if (leftToRight)
611         {
612             // Paint slant
613
g.drawLine( 1, 5, 6, 0 );
614             // Paint top
615
g.drawLine( 6, 0, right, 0 );
616             // Paint right
617
if ( tabIndex==lastIndex ) // last tab in run
618
g.drawLine( right, 1, right, bottom );
619             // Paint left
620
if ( tabIndex != tabRuns[ runCount - 1 ] ) // not the first tab in the last run
621
g.drawLine( 0, 0, 0, bottom );
622             else // the first tab in the last run
623
g.drawLine( 0, 6, 0, bottom );
624         }
625         else
626         {
627             // Paint slant
628
g.drawLine( right - 1, 5, right - 6, 0 );
629             // Paint top
630
g.drawLine( right - 6, 0, 0, 0 );
631             // Paint right
632
if ( tabIndex != tabRuns[ runCount - 1 ] ) // not the first tab in the last run
633
g.drawLine( right, 0, right, bottom );
634             else // the first tab in the last run
635
g.drawLine( right, 6, right, bottom );
636             // Paint left
637
if ( tabIndex==lastIndex ) // last tab in run
638
g.drawLine( 0, 1, 0, bottom );
639         }
640
641         // Paint button
642
if (!isSelected)
643             g.drawLine(0, bottom, right, bottom); // added
644

645         // ** Paint Highlight **
646
g.setColor( isSelected ? selectHighlight : highlight );
647         if ( leftToRight )
648         {
649             // Paint slant
650
g.drawLine( 1, 6, 6, 1 );
651             // Paint top
652
if (tabIndex == lastIndex)
653                 g.drawLine( 6, 1, right-1, 1 );
654             else
655                 g.drawLine( 6, 1, right, 1 ); // bug !!
656
// Paint left
657
g.drawLine( 1, 6, 1, bottom );
658
659             // paint highlight in the gap on tab behind this one
660
// on the left end (where they all line up)
661
if ( tabIndex==firstIndex && tabIndex!=tabRuns[runCount - 1] )
662             {
663                 // first tab in run but not first tab in last run
664
if (tabPane.getSelectedIndex()==tabRuns[currentRun+1])
665                 {
666                     // tab in front of selected tab
667
g.setColor( selectHighlight );
668                 }
669                 else
670                 {
671                     // tab in front of normal tab
672
g.setColor( highlight );
673                 }
674                 g.drawLine( 1, 0, 1, 4 );
675             }
676         }
677         else
678         {
679             // Paint slant
680
g.drawLine( right - 1, 6, right - 6, 1 );
681             // Paint top
682
g.drawLine( right - 6, 1, 1, 1 );
683
684             // Paint left
685
if ( tabIndex==lastIndex ) // last tab in run
686
g.drawLine( 1, 1, 1, bottom );
687             else
688                 g.drawLine( 0, 1, 0, bottom );
689         }
690         g.translate( -x, -y );
691     } // paintTopTabBorder
692

693     /**
694      * Paint Border of Left Tab.
695      * Does not fill triangle
696      *
697      * @param tabIndex index
698      * @param g graphics
699      * @param x x
700      * @param y y
701      * @param w width
702      * @param h height
703      * @param btm bottom
704      * @param rght right
705      * @param isSelected selected
706      */

707     protected void paintLeftTabBorder (int tabIndex, Graphics JavaDoc g,
708         int x, int y, int w, int h, int btm, int rght, boolean isSelected)
709     {
710         int tabCount = tabPane.getTabCount();
711         int currentRun = getRunForTab( tabCount, tabIndex );
712         int lastIndex = lastTabInRun( tabCount, currentRun );
713         int firstIndex = tabRuns[ currentRun ];
714
715         g.translate( x, y );
716
717         int bottom = h - 1;
718         int right = w - 1;
719
720         // ** Paint Highlight **
721
g.setColor( isSelected ? selectHighlight : highlight );
722         // Paint slant
723
g.drawLine( 1, 6, 6, 1 );
724         // Paint top
725
g.drawLine( 6, 1, right, 1 );
726         // Paint left
727
g.drawLine( 1, 6, 1, bottom );
728         // Paint right
729
if (!isSelected)
730             g.drawLine(right-1, 0, right-1, bottom );
731
732         // ** Paint Border **
733
g.setColor( darkShadow );
734         // Paint slant
735
g.drawLine( 1, 5, 6, 0 );
736         // Paint top
737
g.drawLine( 6, 0, right, 0 );
738         // Paint left
739
g.drawLine( 0, 6, 0, bottom );
740         // Paint bottom
741
g.drawLine( 0, bottom, right, bottom );
742         // Paint right
743
if (!isSelected)
744             g.drawLine(right, 0, right, bottom );
745         //
746
g.translate( -x, -y );
747     } // paintLeftTabBorder
748

749
750     /**
751      * Paint Border of Right Tab.
752      * Does not fill triangle
753      *
754      * @param tabIndex index
755      * @param g graphics
756      * @param x x
757      * @param y y
758      * @param w width
759      * @param h height
760      * @param btm bottom
761      * @param rght right
762      * @param isSelected selected
763      */

764     protected void paintRightTabBorder (int tabIndex, Graphics JavaDoc g,
765         int x, int y, int w, int h, int btm, int rght, boolean isSelected)
766     {
767         int tabCount = tabPane.getTabCount();
768         int currentRun = getRunForTab( tabCount, tabIndex );
769         int lastIndex = lastTabInRun( tabCount, currentRun );
770         int firstIndex = tabRuns[ currentRun ];
771
772         g.translate( x, y );
773
774         int bottom = h - 1;
775         int right = w - 1;
776
777         // ** Paint Highlight **
778
g.setColor( isSelected ? selectHighlight : highlight );
779         // Paint slant
780
g.drawLine (right-6, 1, right-1, 6 );
781         // Paint top
782
g.drawLine (0, 1, right - 6, 1 );
783         // Paint right
784
g.drawLine (right-1, 6, right-1, bottom-1);
785         // Paint left
786
if (!isSelected)
787             g.drawLine (0, 1, 0, bottom-1);
788
789         // ** Paint Border **
790
g.setColor( darkShadow );
791         // Paint slant
792
g.drawLine (right - 6, 0, right, 6 );
793         // Paint top
794
g.drawLine (0, 0, right - 6, 0 );
795         // Paint right
796
g.drawLine (right, 6, right, bottom );
797         // Paint bottom
798
g.drawLine( 0, bottom, right, bottom );
799
800         g.translate( -x, -y );
801     } // paintRightTabBorder
802

803
804     /*************************************************************************/
805
806     /**
807      * Calculate Tab Width.
808      * We may have to overwrite to adjust width for TabHirarchyLevel
809      * @param tabPlacement tab placement
810      * @param tabIndex tab index
811      * @param metrics metcics
812      * @return tab width
813      */

814     protected int calculateTabWidth (int tabPlacement, int tabIndex, FontMetrics JavaDoc metrics)
815     {
816         boolean calculate = !(tabPlacement == TOP || tabPlacement == BOTTOM);
817         // HTML
818
if (getTextViewForTab(tabIndex) != null)
819             calculate = false;
820         // No spaces in title
821
String JavaDoc title = tabPane.getTitleAt(tabIndex);
822         int pos = title.indexOf(" ");
823         if (calculate && pos == -1)
824             calculate = false;
825         if (!calculate)
826             return super.calculateTabWidth (tabPlacement, tabIndex, metrics);
827         //
828
Icon JavaDoc icon = getIconForTab(tabIndex);
829         Insets JavaDoc tabInsetsLocal = getTabInsets(tabPlacement, tabIndex);
830         int width = tabInsetsLocal.left + tabInsetsLocal.right + 3;
831
832         if (icon != null)
833             width += icon.getIconWidth() + textIconGap;
834
835         String JavaDoc firstLine = title.substring(0, pos);
836         String JavaDoc secondLine = title.substring(pos+1);
837         width += Math.max(SwingUtilities.computeStringWidth (metrics, firstLine),
838             SwingUtilities.computeStringWidth (metrics, secondLine));
839         return width;
840     } // calculateTabWidth
841

842     /**
843      * Calculate TabHeight
844      * @param tabPlacement tab placement
845      * @param tabIndex tab index
846      * @param fontHeight font height
847      * @return tab height
848      */

849     protected int calculateTabHeight(int tabPlacement, int tabIndex, int fontHeight)
850     {
851         boolean calculate = !(tabPlacement == TOP || tabPlacement == BOTTOM);
852         // HTML
853
if (getTextViewForTab(tabIndex) != null)
854             calculate = false;
855         // No spaces in title
856
String JavaDoc title = tabPane.getTitleAt(tabIndex);
857         int pos = title.indexOf(" ");
858         if (calculate && pos == -1)
859             calculate = false;
860         if (!calculate)
861             return super.calculateTabHeight (tabPlacement, tabIndex, fontHeight);
862         //
863
int height = fontHeight * 2;
864         Icon JavaDoc icon = getIconForTab(tabIndex);
865         Insets JavaDoc tabInsetsLocal = getTabInsets(tabPlacement, tabIndex);
866         if (icon != null)
867             height = Math.max(height, icon.getIconHeight());
868         height += tabInsetsLocal.top + tabInsetsLocal.bottom + 2;
869         return height;
870     }
871
872     /**
873      * Layout Label
874      * @param tabPlacement tab placement
875      * @param metrics fint metrics
876      * @param tabIndex tab index
877      * @param title title
878      * @param icon icon
879      * @param tabRect tab bounds
880      * @param iconRect icon bounds
881      * @param textRect text bounds
882      * @param isSelected selected
883      */

884     protected void layoutLabel(int tabPlacement,
885         FontMetrics JavaDoc metrics, int tabIndex, String JavaDoc title, Icon JavaDoc icon,
886         Rectangle JavaDoc tabRect, Rectangle JavaDoc iconRect, Rectangle JavaDoc textRect, boolean isSelected)
887     {
888         boolean calculate = !(tabPlacement == TOP || tabPlacement == BOTTOM);
889         // HTML
890
if (getTextViewForTab(tabIndex) != null)
891             calculate = false;
892         if (!calculate)
893         {
894             super.layoutLabel (tabPlacement, metrics, tabIndex, title, icon,
895                 tabRect, iconRect, textRect, isSelected);
896         // System.out.println("1.tabRect=" + tabRect + " - textRect=" + textRect + " - " + title);
897
return;
898         }
899         //
900
textRect.x = textRect.y = iconRect.x = iconRect.y = 0;
901         SwingUtilities.layoutCompoundLabel(tabPane,
902             metrics, title, icon,
903             SwingUtilities.TOP, // vert
904
SwingUtilities.LEFT, // horiz
905
SwingUtilities.CENTER, // vert Text
906
SwingUtilities.TRAILING, // horiz Text
907
tabRect,
908             iconRect,
909             textRect,
910             textIconGap);
911         tabPane.putClientProperty("html", null);
912         int xNudge = getTabLabelShiftX(tabPlacement, tabIndex, isSelected);
913         int yNudge = getTabLabelShiftY(tabPlacement, tabIndex, isSelected);
914         // positioned top left - add gap
915
Insets JavaDoc tabInsetsLocal = getTabInsets(tabPlacement, tabIndex);
916         xNudge += tabInsetsLocal.left;
917         yNudge += tabInsetsLocal.top + 1;
918         iconRect.x += xNudge;
919         iconRect.y += yNudge;
920         textRect.x += xNudge;
921         textRect.y += yNudge;
922     // System.out.println("2.tabRect=" + tabRect + " - textRect=" + textRect + " - " + title);
923
}
924
925     /**
926      * Paint Tab
927      * @param g graphics
928      * @param tabPlacement tab placement
929      * @param font font
930      * @param metrics font metrics
931      * @param tabIndex tab index
932      * @param title title
933      * @param textRect text bounds
934      * @param isSelected selected
935      */

936     protected void paintText (Graphics JavaDoc g, int tabPlacement,
937         Font JavaDoc font, FontMetrics JavaDoc metrics, int tabIndex,
938         String JavaDoc title, Rectangle JavaDoc textRect, boolean isSelected)
939     {
940         boolean calculate = !(tabPlacement == TOP || tabPlacement == BOTTOM);
941         // HTML
942
if (getTextViewForTab(tabIndex) != null)
943             calculate = false;
944         if (!calculate)
945         {
946             super.paintText (g, tabPlacement, font, metrics, tabIndex,
947                 title, textRect, isSelected);
948             return;
949         }
950
951     // System.out.println("3.textRect " + textRect + " - " + title);
952
String JavaDoc firstLine = title;
953         String JavaDoc secondLine = null;
954         int pos = title.indexOf(' ');
955         if (pos != -1)
956         {
957             firstLine = title.substring(0, pos);
958             secondLine = title.substring(pos+1);
959         }
960
961         g.setFont(font);
962         int mnemIndex = tabPane.getDisplayedMnemonicIndexAt(tabIndex);
963         if (tabPane.isEnabled() && tabPane.isEnabledAt(tabIndex))
964         {
965             Color JavaDoc c = tabPane.getForegroundAt(tabIndex);
966             if (!isSelected)
967             {
968                 if (c.equals(Color.black))
969                     c = Color.darkGray;
970                 else
971                     c = c.brighter();
972             }
973             g.setColor(c);
974             // first line
975
BasicGraphicsUtils.drawStringUnderlineCharAt
976                 (g, firstLine, mnemIndex, textRect.x, textRect.y + metrics.getAscent());
977             // secondLine
978
if (secondLine != null)
979                 BasicGraphicsUtils.drawStringUnderlineCharAt
980                     (g, secondLine, mnemIndex-firstLine.length(),
981                     textRect.x, textRect.y + metrics.getAscent() + metrics.getHeight());
982         }
983         else
984         { // tab disabled
985
g.setColor(tabPane.getBackgroundAt(tabIndex).brighter());
986             BasicGraphicsUtils.drawStringUnderlineCharAt
987                 (g, firstLine, mnemIndex, textRect.x, textRect.y + metrics.getAscent());
988             // secondLine
989
if (secondLine != null)
990                 BasicGraphicsUtils.drawStringUnderlineCharAt
991                     (g, secondLine, mnemIndex-firstLine.length(),
992                     textRect.x, textRect.y + metrics.getAscent() + metrics.getHeight());
993             //
994
g.setColor(tabPane.getBackgroundAt(tabIndex).darker());
995             BasicGraphicsUtils.drawStringUnderlineCharAt
996                 (g, firstLine, mnemIndex, textRect.x -1, textRect.y + metrics.getAscent() -1);
997             // secondLine
998
if (secondLine != null)
999                 BasicGraphicsUtils.drawStringUnderlineCharAt
1000                    (g, secondLine, mnemIndex-firstLine.length(),
1001                    textRect.x -1, textRect.y + metrics.getAscent() + metrics.getHeight() -1);
1002        }
1003    } // paintText
1004

1005    /*************************************************************************/
1006
1007    /**
1008     * Create Layout Manager to size & position tabs
1009     * @return Layout Manager
1010     */

1011    protected LayoutManager JavaDoc createLayoutManager()
1012    {
1013        return new TabbedPaneLayout();
1014    } // createLayoutManager
1015

1016    /**
1017     * Layout Manager to overwrite TabRect size
1018     */

1019    public class TabbedPaneLayout extends MetalTabbedPaneUI.TabbedPaneLayout JavaDoc
1020    {
1021        /**
1022         * Calculate Tab Rectangle Size
1023         * @param tabPlacement tab placement
1024         * @param tabCount no of tabs
1025         */

1026        protected void calculateTabRects(int tabPlacement, int tabCount)
1027        {
1028            super.calculateTabRects(tabPlacement, tabCount);
1029            if (tabPlacement == TOP || tabPlacement == BOTTOM)
1030                return;
1031        // System.out.println("calculateTabRects " + tabCount);
1032
int tabHeight = calculateMaxTabHeight(tabPlacement);
1033            for (int i = 0; i < rects.length; i++)
1034            {
1035                int level = 0;
1036                Component JavaDoc comp = tabPane.getComponentAt(i);
1037                if (comp instanceof JComponent JavaDoc)
1038                {
1039                    JComponent JavaDoc jc = (JComponent JavaDoc)comp;
1040                    try
1041                    {
1042                        Integer JavaDoc ll = (Integer JavaDoc)jc.getClientProperty(CompierePLAF.TABLEVEL);
1043                        if (ll != null)
1044                            level = ll.intValue();
1045                    }
1046                    catch (Exception JavaDoc e)
1047                    {
1048                        System.err.println("CompiereTabbedPaneUI - ClientProperty: " + e.getMessage());
1049                    }
1050                }
1051                if (level != 0)
1052                {
1053                    if (tabPlacement == LEFT)
1054                        rects[i].x += level * 5;
1055                    rects[i].width -= level * 5;
1056                }
1057                // Height
1058
rects[i].height = tabHeight;
1059                if (i > 0)
1060                    rects[i].y = rects[i-1].y + tabHeight; // rects[i-1].height;
1061
} // for all rects
1062
} // calculate TabRects
1063

1064    } // TabbedPaneLayout
1065

1066} // CompiereTabbedPaneUI
1067
Popular Tags