home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / jfc.bin / MetalTabbedPaneUI.java < prev    next >
Text File  |  1998-02-26  |  19KB  |  646 lines

  1. /*
  2.  * @(#)MetalTabbedPaneUI.java    1.12 98/02/04
  3.  *
  4.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * This software is the confidential and proprietary information of Sun
  7.  * Microsystems, Inc. ("Confidential Information").  You shall not
  8.  * disclose such Confidential Information and shall use it only in
  9.  * accordance with the terms of the license agreement you entered into
  10.  * with Sun.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  13.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  14.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  15.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  16.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  17.  * THIS SOFTWARE OR ITS DERIVATIVES.
  18.  *
  19.  */
  20.  
  21. package com.sun.java.swing.plaf.metal;
  22.  
  23. import com.sun.java.swing.*;
  24. import com.sun.java.swing.event.*;
  25. import java.awt.*;
  26. import java.awt.event.*;
  27. import com.sun.java.swing.plaf.*;
  28. import java.io.Serializable; 
  29. import com.sun.java.swing.plaf.basic.BasicTabbedPaneUI;
  30.  
  31. /**
  32.  * The Metal subclass of BasicTabbedPaneUI.
  33.  * <p>
  34.  * Warning: serialized objects of this class will not be compatible with
  35.  * future swing releases.  The current serialization support is appropriate
  36.  * for short term storage or RMI between Swing1.0 applications.  It will
  37.  * not be possible to load serialized Swing1.0 objects with future releases
  38.  * of Swing.  The JDK1.2 release of Swing will be the compatibility
  39.  * baseline for the serialized form of Swing objects.
  40.  *
  41.  * @version 1.12 02/04/98
  42.  * @author Tom Santos
  43.  */
  44.  
  45. public class MetalTabbedPaneUI extends BasicTabbedPaneUI {
  46.  
  47.     protected static Insets tabsOnTopTabAreaInsets = new Insets(4,2,0,6);
  48.     protected static Insets tabsOnLeftTabAreaInsets = new Insets(6,4,0,0);
  49.     protected static Insets tabsOnBottomTabAreaInsets = new Insets(0,2,4,6);
  50.     protected static Insets tabsOnRightTabAreaInsets = new Insets(0,0,6,4);
  51.  
  52.     protected int minTabWidth = 40;
  53.     protected Color selectColor;
  54.     protected Color selectHighlight;
  55.  
  56.     public static ComponentUI createUI( JComponent x ) {
  57.         return new MetalTabbedPaneUI();
  58.     }    
  59.  
  60.  
  61.     protected void installDefaults( JComponent c ) {
  62.         JTabbedPane pane = (JTabbedPane)c;
  63.         super.installDefaults(c);
  64.         
  65.     selectColor = UIManager.getColor("TabbedPane.selected");
  66.     selectHighlight = UIManager.getColor("TabbedPane.selectHighlight");
  67.     }
  68.  
  69.  
  70.     protected void paintTabBorder( Graphics g, JTabbedPane pane, int tabPlacement,
  71.                                    int tabIndex, int x, int y, int w, int h, 
  72.                                    boolean isSelected) {
  73.         int bottom = y + (h-1);
  74.     int right = x + (w-1);
  75.  
  76.         switch(tabPlacement) {
  77.           case LEFT:
  78.               paintLeftTabBorder(pane, tabIndex, g, x, y, w, h, bottom, right, isSelected);
  79.               break;
  80.           case BOTTOM:
  81.               paintBottomTabBorder(pane, tabIndex, g, x, y, w, h, bottom, right, isSelected);
  82.               break;
  83.           case RIGHT:
  84.               paintRightTabBorder(pane, tabIndex, g, x, y, w, h, bottom, right, isSelected);
  85.               break;
  86.           case TOP:
  87.           default:
  88.               paintTopTabBorder(pane, tabIndex, g, x, y, w, h, bottom, right, isSelected);
  89.         }
  90.     }
  91.  
  92.  
  93.     protected void paintTopTabBorder( JTabbedPane pane, int tabIndex, Graphics g, 
  94.                                      int x, int y, int w, int h,
  95.                                      int btm, int rght,
  96.                                      boolean isSelected ) {
  97.         int currentRun = getRunForTab( pane, pane.getTabCount(), tabIndex );
  98.     int lastIndex = lastIndexInRun( currentRun, pane.getTabCount() );
  99.     int firstIndex = tabRuns[ currentRun ];
  100.  
  101.     //
  102.     // Paint Gap
  103.     //
  104.  
  105.     if ( shouldFillGap( pane, currentRun, tabIndex, x, y ) ) {
  106.         g.translate( x, y );
  107.  
  108.         g.setColor( selectColor );
  109.         g.fillRect( 1, 0, 5, 3 );
  110.         g.fillRect( 1, 3, 2, 2 );
  111.  
  112.         g.translate( -x, -y );
  113.     }
  114.  
  115.  
  116.         g.translate( x, y );
  117.  
  118.     int bottom = h - 1;
  119.     int right = w - 1;
  120.  
  121.     //
  122.     // Paint Border
  123.     //
  124.  
  125.     g.setColor( tabDarkShadow );
  126.  
  127.         // Paint slant
  128.     g.drawLine( 1,5 , 6,0 );
  129.  
  130.         // Paint top
  131.     g.drawLine( 6,0 , right,0 );
  132.     
  133.         // Paint right
  134.     if ( tabIndex == lastIndex ) {
  135.         g.drawLine( right,1 , right,bottom );
  136.     }
  137.  
  138.     // Paint left
  139.     if ( tabIndex != tabRuns[ runCount - 1 ] ) {
  140.         g.drawLine( 0,0 , 0,bottom );
  141.     }
  142.     else {
  143.         g.drawLine( 0,6 , 0,bottom );
  144.     }
  145.  
  146.  
  147.     //
  148.     // Paint Highlight
  149.     //
  150.  
  151.     g.setColor( isSelected ? selectHighlight : tabHighlight );
  152.     
  153.     // Paint slant
  154.     g.drawLine( 1,6 , 6,1 );
  155.  
  156.     // Paint top
  157.     g.drawLine( 6,1 , right,1 );
  158.  
  159.     // Paint left
  160.     g.drawLine( 1,6 , 1,bottom );
  161.     
  162.     if ( tabIndex == firstIndex && tabIndex != tabRuns[ runCount - 1 ] ) {
  163.         g.setColor( pane.getSelectedIndex() == tabRuns[ currentRun + 1 ] ? selectHighlight : tabHighlight );
  164.         g.drawLine( 1,0 , 1,4 );
  165.     }
  166.  
  167.     g.translate( -x, -y );
  168.     }
  169.  
  170.     protected boolean shouldFillGap( JTabbedPane pane, int currentRun, int tabIndex, int x, int y ) {
  171.         if ( currentRun == runCount - 1 ) {
  172.         return false;
  173.     }
  174.     else {
  175.         int selectedIndex = pane.getSelectedIndex();
  176.         if ( getRunForTab( pane, pane.getTabCount(), selectedIndex ) == currentRun + 1 ) {
  177.             Rectangle rect = rects[ selectedIndex ];
  178.         int rectRight = rect.x + (rect.width - 1);
  179.         if ( rect.x < x + 4 && rectRight > x + 1 ) {
  180.             return true;
  181.         }
  182.         else {
  183.             return false;
  184.         }
  185.         }
  186.         else {
  187.             return false;
  188.         }
  189.     }
  190.     }
  191.  
  192.     protected void paintLeftTabBorder( JTabbedPane pane, int tabIndex, Graphics g, 
  193.                                       int x, int y, int w, int h,
  194.                                       int btm, int rght,
  195.                                       boolean isSelected ) {
  196.         int currentRun = getRunForTab( pane, pane.getTabCount(), tabIndex );
  197.     int lastIndex = lastIndexInRun( currentRun, pane.getTabCount() );
  198.     int firstIndex = tabRuns[ currentRun ];
  199.  
  200.         g.translate( x, y );
  201.  
  202.     int bottom = h - 1;
  203.     int right = w - 1;
  204.  
  205.     //
  206.     // Paint part of the tab above
  207.     //
  208.  
  209.     if ( tabIndex != firstIndex ) {
  210.         g.setColor( pane.getSelectedIndex() == tabIndex - 1 ? selectColor : pane.getBackground() );
  211.         g.fillRect( 2, 0, 4, 3 );
  212.         g.drawLine( 2, 3, 2, 3 );
  213.     }
  214.  
  215.  
  216.     //
  217.     // Paint Highlight
  218.     //
  219.  
  220.     g.setColor( isSelected ? selectHighlight : tabHighlight );
  221.  
  222.     // Paint slant
  223.     g.drawLine( 1, 6, 6, 1 );
  224.  
  225.     // Paint top
  226.     g.drawLine( 6, 1, right, 1 );
  227.  
  228.     // Paint left
  229.     g.drawLine( 1, 6, 1, bottom );
  230.  
  231.     if ( tabIndex != firstIndex ) {
  232.         g.setColor( pane.getSelectedIndex() == tabIndex - 1 ? selectHighlight : tabHighlight );
  233.         g.drawLine( 1, 0, 1, 4 );
  234.     }
  235.  
  236.     //
  237.     // Paint Border
  238.     //
  239.  
  240.     g.setColor( tabDarkShadow );
  241.  
  242.     // Paint slant
  243.     g.drawLine( 1, 5, 6, 0 );
  244.  
  245.     // Paint top
  246.     g.drawLine( 6, 0, right, 0 );
  247.  
  248.     // Paint left
  249.     if ( tabIndex != firstIndex ) {
  250.         g.drawLine( 0, 0, 0, bottom );
  251.     }
  252.     else {
  253.         g.drawLine( 0, 6, 0, bottom );
  254.     }
  255.  
  256.     // Paint bottom
  257.     if ( tabIndex == lastIndex ) {
  258.         g.drawLine( 0, bottom, right, bottom );
  259.     }
  260.  
  261.     g.translate( -x, -y );
  262.     }
  263.  
  264.  
  265.     protected void paintBottomTabBorder( JTabbedPane pane, int tabIndex, Graphics g, 
  266.                                       int x, int y, int w, int h,
  267.                                       int btm, int rght,
  268.                                       boolean isSelected ) {
  269.         int currentRun = getRunForTab( pane, pane.getTabCount(), tabIndex );
  270.     int lastIndex = lastIndexInRun( currentRun, pane.getTabCount() );
  271.     int firstIndex = tabRuns[ currentRun ];
  272.  
  273.     int bottom = h - 1;
  274.     int right = w - 1;
  275.  
  276.     //
  277.     // Paint Gap
  278.     //
  279.  
  280.     if ( shouldFillGap( pane, currentRun, tabIndex, x, y ) ) {
  281.         g.translate( x, y );
  282.  
  283.         g.setColor( selectColor );
  284.         g.fillRect( 1, bottom - 4, 3, 5 );
  285.         g.fillRect( 4, bottom - 1, 2, 2 );
  286.  
  287.         g.translate( -x, -y );
  288.     }
  289.  
  290.         g.translate( x, y );
  291.  
  292.  
  293.     //
  294.     // Paint Border
  295.     //
  296.  
  297.     g.setColor( tabDarkShadow );
  298.  
  299.         // Paint slant
  300.     g.drawLine( 1, bottom - 5, 6, bottom );
  301.  
  302.         // Paint bottom
  303.     g.drawLine( 6, bottom, right, bottom );
  304.     
  305.         // Paint right
  306.     if ( tabIndex == lastIndex ) {
  307.         g.drawLine( right, 0, right, bottom );
  308.     }
  309.  
  310.     // Paint left
  311.     if ( tabIndex != tabRuns[ runCount - 1 ] ) {
  312.         g.drawLine( 0, 0, 0, bottom );
  313.     }
  314.     else {
  315.         g.drawLine( 0, 0, 0, bottom - 6 );
  316.     }
  317.  
  318.  
  319.     //
  320.     // Paint Highlight
  321.     //
  322.  
  323.     g.setColor( isSelected ? selectHighlight : tabHighlight );
  324.     
  325.     // Paint slant
  326.     g.drawLine( 1, bottom - 6, 6, bottom - 1 );
  327.  
  328.     // Paint left
  329.     g.drawLine( 1, 0, 1, bottom - 6 );
  330.  
  331.     if ( tabIndex == firstIndex && tabIndex != tabRuns[ runCount - 1 ] ) {
  332.         g.setColor( pane.getSelectedIndex() == tabRuns[ currentRun + 1 ] ? selectHighlight : tabHighlight );
  333.         g.drawLine( 1, bottom - 4, 1, bottom );
  334.     }
  335.  
  336.     g.translate( -x, -y );
  337.     }
  338.  
  339.     protected void paintRightTabBorder( JTabbedPane pane, int tabIndex, Graphics g, 
  340.                                       int x, int y, int w, int h,
  341.                                       int btm, int rght,
  342.                                       boolean isSelected ) {
  343.         int currentRun = getRunForTab( pane, pane.getTabCount(), tabIndex );
  344.     int lastIndex = lastIndexInRun( currentRun, pane.getTabCount() );
  345.     int firstIndex = tabRuns[ currentRun ];
  346.  
  347.         g.translate( x, y );
  348.  
  349.     int bottom = h - 1;
  350.     int right = w - 1;
  351.  
  352.     //
  353.     // Paint part of the tab above
  354.     //
  355.  
  356.     if ( tabIndex != firstIndex ) {
  357.         g.setColor( pane.getSelectedIndex() == tabIndex - 1 ? selectColor : pane.getBackground() );
  358.         g.fillRect( right - 5, 0, 5, 3 );
  359.         g.fillRect( right - 2, 3, 2, 2 );
  360.     }
  361.  
  362.  
  363.     //
  364.     // Paint Highlight
  365.     //
  366.  
  367.     g.setColor( isSelected ? selectHighlight : tabHighlight );
  368.  
  369.     // Paint slant
  370.     g.drawLine( right - 6, 1, right - 1, 6 );
  371.  
  372.     // Paint top
  373.     g.drawLine( 0, 1, right - 6, 1 );
  374.  
  375.     // Paint left
  376.     g.drawLine( 0, 1, 0, bottom );
  377.  
  378.  
  379.     //
  380.     // Paint Border
  381.     //
  382.  
  383.     g.setColor( tabDarkShadow );
  384.  
  385.     // Paint slant
  386.     g.drawLine( right - 6, 0, right, 6 );
  387.  
  388.     // Paint top
  389.     g.drawLine( 0, 0, right - 6, 0 );
  390.  
  391.     // Paint right
  392.     if ( tabIndex != firstIndex ) {
  393.         g.drawLine( right, 0, right, bottom );
  394.     }
  395.     else {
  396.         g.drawLine( right, 6, right, bottom );
  397.     }
  398.  
  399.     // Paint bottom
  400.     if ( tabIndex == lastIndex ) {
  401.         g.drawLine( 0, bottom, right, bottom );
  402.     }
  403.  
  404.     g.translate( -x, -y );
  405.     }
  406.  
  407.  
  408.     protected void paintTabBackground( Graphics g, JTabbedPane pane, int tabPlacement,
  409.                                        int tabIndex, int x, int y, int w, int h, boolean isSelected ) {
  410.  
  411.         int slantWidth = h / 2;
  412.     if ( isSelected ) {
  413.         g.setColor( selectColor );
  414.     }
  415.     else {
  416.         g.setColor( pane.getBackground() );
  417.     }
  418.         switch(tabPlacement) {
  419.           case LEFT:
  420.               g.fillRect(x + 5, y + 1, w - 5, h - 1);
  421.           g.fillRect( x + 2, y + 4, 3, h - 4 );
  422.               break;
  423.           case BOTTOM:
  424.               g.fillRect( x + 2, y, w - 2, h - 3 );
  425.           g.fillRect( x + 5, (y + (h - 1)) - 3, w - 5, 3 );
  426.               break;
  427.           case RIGHT:
  428.               g.fillRect(x + 1, y + 1, w - 5, h - 1);
  429.           g.fillRect( (x+(w-1)) - 3, y+5, 3, h - 1 );
  430.               break;
  431.           case TOP:
  432.           default:    
  433.           g.fillRect( x + 4, y + 2, (w - 1) - 3, (h - 1) - 1 );
  434.           g.fillRect( x + 2, y + 5, 2, h - 5 );
  435.         }
  436.     }
  437.  
  438.  
  439.     protected Insets getTabAreaInsets( JTabbedPane pane, int tabPlacement ) {
  440.         Insets insets;
  441.         switch(tabPlacement) {
  442.           case LEFT:
  443.               insets = tabsOnLeftTabAreaInsets;
  444.               break;
  445.           case BOTTOM:
  446.               insets = tabsOnBottomTabAreaInsets;
  447.               break;
  448.           case RIGHT:
  449.               insets = tabsOnRightTabAreaInsets;
  450.               break;
  451.           case TOP:
  452.           default:
  453.               insets = tabsOnTopTabAreaInsets;
  454.         }
  455.         return insets;
  456.     }
  457.  
  458.  
  459.     /**
  460.      * Overidden to do nothing for the Java L&F.
  461.      */
  462.     protected int calculateXNudge( JTabbedPane pane, int tabPlacement, 
  463.                                    int tabIndex, boolean isSelected ) {
  464.         return 0; 
  465.     }
  466.  
  467.  
  468.     /**
  469.      * Overidden to do nothing for the Java L&F.
  470.      */
  471.     protected int calculateYNudge( JTabbedPane pane, int tabPlacement, 
  472.                                    int tabIndex, boolean isSelected ) {
  473.         return 0; 
  474.     }
  475.  
  476.  
  477.     public void paint( Graphics g, JComponent c ) {
  478.         JTabbedPane pane = (JTabbedPane)c;
  479.         int tabPlacement = pane.getTabPlacement();
  480.  
  481.     Insets insets = c.getInsets();
  482.     Dimension size = c.getSize();
  483.     
  484.     // Paint the background for the tab area
  485.     g.setColor( c.getBackground() );
  486.         switch(tabPlacement) {
  487.           case LEFT:
  488.               g.fillRect( insets.left, insets.top, 
  489.                           totalTabWidth( pane, tabPlacement, runCount ),
  490.                           size.height - insets.bottom - insets.top );
  491.               break;
  492.           case BOTTOM:
  493.               int totalTabHeight = totalTabHeight( pane, tabPlacement, runCount );
  494.               g.fillRect( insets.left, size.height - insets.bottom - totalTabHeight, 
  495.               size.width - insets.left - insets.right,
  496.                           totalTabHeight );
  497.               break;
  498.           case RIGHT:
  499.               int totalTabWidth = totalTabWidth( pane, tabPlacement, runCount );
  500.               g.fillRect( size.width - insets.right - totalTabWidth,
  501.                           insets.top, totalTabWidth, 
  502.                           size.height - insets.top - insets.bottom );
  503.               break;
  504.           case TOP:
  505.           default:
  506.           g.fillRect( insets.left, insets.top, 
  507.                           size.width - insets.right - insets.left, 
  508.                           totalTabHeight(pane, tabPlacement, runCount) );
  509.           paintHighlightBelowTab( pane );
  510.         }
  511.  
  512.         super.paint( g, c );
  513.     }
  514.  
  515.     protected void paintHighlightBelowTab( JTabbedPane pane ) {
  516.         
  517.     }
  518.  
  519.  
  520.     protected void paintFocusIndicator(Graphics g, JTabbedPane pane, int tabPlacement,
  521.                                        Rectangle[] rects, int tabIndex, 
  522.                                        Rectangle iconRect, Rectangle textRect,
  523.                                        boolean isSelected) {
  524.         if (pane.hasFocus() && isSelected) {
  525.         Rectangle tabRect = rects[tabIndex];
  526.         g.setColor( focus );
  527.         g.translate( tabRect.x, tabRect.y );
  528.         int right = tabRect.width - 1;
  529.         int bottom = tabRect.height - 1;
  530.             switch(tabPlacement) {
  531.               case RIGHT:
  532.             g.drawLine( right - 6,2 , right - 2,6 );         // slant
  533.           g.drawLine( 1,2 , right - 6,2 );                 // top
  534.           g.drawLine( right - 2,6 , right - 2,bottom );    // right
  535.           g.drawLine( 1,2 , 1,bottom );                    // left
  536.           g.drawLine( 1,bottom , right - 2,bottom );       // bottom
  537.                   break;
  538.               case BOTTOM:
  539.           g.drawLine( 2,bottom - 6 , 6,bottom - 2 );       // slant
  540.           g.drawLine( 6,bottom - 2 , right,bottom - 2 );   // bottom
  541.           g.drawLine( 2,0 , 2,bottom - 6 );                // left
  542.           g.drawLine( 2,0 , right,0 );                     // top
  543.           g.drawLine( right,0 , right,bottom - 2 );        // right
  544.                   break;
  545.               case TOP:
  546.               case LEFT:
  547.               default:
  548.             g.drawLine( 2,6 , 6,2 );                         // slant
  549.           g.drawLine( 2,6 , 2,bottom - 1);                 // left
  550.           g.drawLine( 6,2 , right,2 );                     // top
  551.           g.drawLine( right,2 , right,bottom - 1 );        // right
  552.           g.drawLine( 2,bottom - 1 , right, bottom - 1 );  // bottom
  553.             }
  554.         g.translate( -tabRect.x, -tabRect.y );
  555.         }
  556.     }
  557.  
  558.  
  559.     protected void paintContentBorderTopEdge( Graphics g, int tabPlacement,
  560.                                              int selectedIndex,
  561.                                              int x, int y, int width, int height ) {    
  562.         g.setColor( tabDarkShadow );
  563.     g.drawLine(x-1, y, width-2, y);
  564.     }
  565.  
  566.  
  567.     protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
  568.                                                int selectedIndex,
  569.                                                int x, int y, int w, int h) { 
  570.         g.setColor( tabDarkShadow );
  571.     g.drawLine( x, y+(h-1), x+(w-1), y+(h-1) );
  572.     }
  573.  
  574.     protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
  575.                                                int selectedIndex,
  576.                                                int x, int y, int w, int h) { 
  577.         g.setColor( tabDarkShadow );
  578.     g.drawLine( x, y, x, y+(h-1) );
  579.     }
  580.     
  581.     protected void paintContentBorderRightEdge(Graphics g, int tabPlacement,
  582.                                                int selectedIndex,
  583.                                                int x, int y, int w, int h) {
  584.         g.setColor( tabDarkShadow );
  585.     g.drawLine( x+(w-1), y, x+(w-1), y+(h-1) );
  586.     }
  587.  
  588.     protected int maxTabHeight( JTabbedPane pane, FontMetrics metrics ) {
  589.         int height = metrics.getHeight();
  590.         boolean tallerIcons = false;
  591.  
  592.     for ( int i = 0; i < pane.getTabCount(); ++i ) {
  593.         Icon icon = pane.getIconAt( i );
  594.         if ( icon != null ) {
  595.             if ( icon.getIconHeight() > height ) {
  596.             tallerIcons = true;
  597.             break;
  598.         }
  599.         }
  600.     }
  601.         return super.maxTabHeight( pane, metrics ) - (tallerIcons ? (spacingHeight * 2) : 0);
  602.     }
  603.  
  604.  
  605.     protected int getTabOverlay( JTabbedPane pane, int tabPlacement ) {
  606.         // Tab runs layed out vertically should overlap
  607.         // at least as much as the largest slant
  608.         if (tabPlacement == LEFT || tabPlacement == RIGHT) {
  609.             int maxTabHeight = maxTabHeight(pane);
  610.             return maxTabHeight / 2;
  611.         }
  612.         return 0;
  613.     }
  614.  
  615.  
  616.     protected void normalizeTabRuns( JTabbedPane pane, int tabPlacement, int tabCount, 
  617.                                      int start, int max ) {
  618.         // Only normalize the runs for top & bottom;  normalizing
  619.         // doesn't look right for Metal's vertical tabs
  620.         // because the last run isn't padded and it looks odd to have
  621.         // fat tabs in the first vertical runs, but slimmer ones in the
  622.         // last (this effect isn't noticable for horizontal tabs).
  623.         if (tabPlacement == TOP || tabPlacement == BOTTOM) {
  624.             super.normalizeTabRuns(pane, tabPlacement, tabCount, start, max);
  625.         }
  626.     }
  627.  
  628.  
  629.     // Don't rotate runs!
  630.     protected void rotateTabRuns( JTabbedPane pane, int tabPlacement, int selectedRun ) {
  631.     }
  632.  
  633.  
  634.     // Don't pad last run
  635.     protected boolean shouldPadRun( JTabbedPane pane, int tabPlacement, int run ) {
  636.         return runCount > 1 && run < runCount - 1;
  637.     }
  638.  
  639.  
  640.     // Don't pad selected tab
  641.     protected void padSelectedTab( JTabbedPane pane, int tabPlacement, int selectedIndex ) {
  642.     }
  643.  
  644. }
  645.  
  646.