looks-2.2.0

       }
          x = x;
          width = maxTabWidth;
        }
        if (i == selectedIndex) {
          selectedRun = (runCount - 1);
        }
      }
      if (runCount > 1) {
        if (shouldRotateTabRuns(tabPlacement)) {
          rotateTabRuns(tabPlacement, selectedRun);
        }
      }
      for (i = runCount - 1; i >= 0; i--)
      {
        int start = tabRuns[i];
        int next = tabRuns[(i + 1)];
        int end = next != 0 ? next - 1 : tabCount - 1;
        int indent = getTabRunIndent(tabPlacement, i);
        if (!verticalTabRuns)
        {
          for (int j = start; j <= end; j++)
          {
            Rectangle rect = rects[j];
            y = y;
            x += indent;
          }
          if (shouldPadTabRun(tabPlacement, i)) {
            padTabRun(tabPlacement, start, end, returnAt - 2 * indent);
          }
          if (tabPlacement == 3) {
            y -= maxTabHeight - theTabRunOverlay;
          } else {
            y += maxTabHeight - theTabRunOverlay;
          }
        }
        else
        {
          for (int j = start; j <= end; j++)
          {
            Rectangle rect = rects[j];
            x = x;
            y += indent;
          }
          if (shouldPadTabRun(tabPlacement, i)) {
            padTabRun(tabPlacement, start, end, returnAt - 2 * indent);
          }
          if (tabPlacement == 4) {
            x -= maxTabWidth - theTabRunOverlay;
          } else {
            x += maxTabWidth - theTabRunOverlay;
          }
        }
      }
      padSelectedTab(tabPlacement, selectedIndex);
      if ((!leftToRight) && (!verticalTabRuns))
      {
        int rightMargin = width - (right + right);
        for (i = 0; i < tabCount; i++) {
          rects[i].x = (rightMargin - rects[i].x - rects[i].width + renderer.getTabsOverlay());
        }
      }
    }
    
    protected void padSelectedTab(int tabPlacement, int selectedIndex)
    {
      if (selectedIndex >= 0)
      {
        Rectangle selRect = rects[selectedIndex];
        Insets padInsets = getSelectedTabPadInsets(tabPlacement);
        x -= left;
        width += left + right;
        y -= top;
        height += top + bottom;
      }
    }
  }
  
  private boolean requestFocusForVisibleComponent()
  {
    Component visibleComponent = getVisibleComponent();
    if (visibleComponent.isFocusable())
    {
      visibleComponent.requestFocus();
      return true;
    }
    if (((visibleComponent instanceof JComponent)) && 
      (((JComponent)visibleComponent).requestDefaultFocus())) {
      return true;
    }
    return false;
  }
  
  private static class ScrollTabsForwardAction
    extends AbstractAction
  {
    ScrollTabsForwardAction(PlasticTabbedPaneUI.1 x0)
    {
      this();
    }
    
    public void actionPerformed(ActionEvent e)
    {
      JTabbedPane pane = null;
      Object src = e.getSource();
      if ((src instanceof JTabbedPane)) {
        pane = (JTabbedPane)src;
      } else if ((src instanceof PlasticArrowButton)) {
        pane = (JTabbedPane)((PlasticArrowButton)src).getParent();
      } else {
        return;
      }
      PlasticTabbedPaneUI ui = (PlasticTabbedPaneUI)pane.getUI();
      if (ui.scrollableTabLayoutEnabled()) {
        tabScroller.scrollForward(pane.getTabPlacement());
      }
    }
    
    private ScrollTabsForwardAction() {}
  }
  
  private static class ScrollTabsBackwardAction
    extends AbstractAction
  {
    ScrollTabsBackwardAction(PlasticTabbedPaneUI.1 x0)
    {
      this();
    }
    
    public void actionPerformed(ActionEvent e)
    {
      JTabbedPane pane = null;
      Object src = e.getSource();
      if ((src instanceof JTabbedPane)) {
        pane = (JTabbedPane)src;
      } else if ((src instanceof PlasticArrowButton)) {
        pane = (JTabbedPane)((PlasticArrowButton)src).getParent();
      } else {
        return;
      }
      PlasticTabbedPaneUI ui = (PlasticTabbedPaneUI)pane.getUI();
      if (ui.scrollableTabLayoutEnabled()) {
        tabScroller.scrollBackward(pane.getTabPlacement());
      }
    }
    
    private ScrollTabsBackwardAction() {}
  }
  
  private final class TabbedPaneScrollLayout
    extends PlasticTabbedPaneUI.TabbedPaneLayout
  {
    private TabbedPaneScrollLayout()
    {
      super(null);
    }
    
    TabbedPaneScrollLayout(PlasticTabbedPaneUI.1 x1)
    {
      this();
    }
    
    protected int preferredTabAreaHeight(int tabPlacement, int width)
    {
      return calculateMaxTabHeight(tabPlacement);
    }
    
    protected int preferredTabAreaWidth(int tabPlacement, int height)
    {
      return calculateMaxTabWidth(tabPlacement);
    }
    
    public void layoutContainer(Container parent)
    {
      int tabPlacement = tabPane.getTabPlacement();
      int tabCount = tabPane.getTabCount();
      Insets insets = tabPane.getInsets();
      int selectedIndex = tabPane.getSelectedIndex();
      Component visibleComponent = getVisibleComponent();
      
      calculateLayoutInfo();
      if (selectedIndex < 0)
      {
        if (visibleComponent != null) {
          setVisibleComponent(null);
        }
      }
      else
      {
        Component selectedComponent = tabPane.getComponentAt(selectedIndex);
        boolean shouldChangeFocus = false;
        if (selectedComponent != null)
        {
          if ((selectedComponent != visibleComponent) && (visibleComponent != null)) {
            if (SwingUtilities.findFocusOwner(visibleComponent) != null) {
              shouldChangeFocus = true;
            }
          }
          setVisibleComponent(selectedComponent);
        }
        Insets contentInsets = getContentBorderInsets(tabPlacement);
        Rectangle bounds = tabPane.getBounds();
        int numChildren = tabPane.getComponentCount();
        if (numChildren > 0)
        {
          int tw;
          int th;
          int tx;
          int ty;
          int cx;
          int cy;
          int cw;
          int ch;
          switch (tabPlacement)
          {
          case 2: 
            tw = calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth);
            
            th = height - top - bottom;
            tx = left;
            ty = top;
            
            cx = tx + tw + left;
            cy = ty + top;
            cw = width - left - right - tw - left - right;
            
            ch = height - top - bottom - top - bottom;
            
            break;
          case 4: 
            tw = calculateTabAreaWidth(tabPlacement, runCount, maxTabWidth);
            
            th = height - top - bottom;
            tx = width - right - tw;
            ty = top;
            
            cx = left + left;
            cy = top + top;
            cw = width - left - right - tw - left - right;
            
            ch = height - top - bottom - top - bottom;
            
            break;
          case 3: 
            tw = width - left - right;
            th = calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight);
            
            tx = left;
            ty = height - bottom - th;
            
            cx = left + left;
            cy = top + top;
            cw = width - left - right - left - right;
            
            ch = height - top - bottom - th - top - bottom;
            
            break;
          case 1: 
          default: 
            tw = width - left - right;
            th = calculateTabAreaHeight(tabPlacement, runCount, maxTabHeight);
            
            tx = left;
            ty = top;
            
            cx = tx + left;
            cy = ty + th + top;
            cw = width - left - right - left - right;
            
            ch = height - top - bottom - th - top - bottom;
          }
          for (int i = 0; i < numChildren; i++)
          {
            Component child = tabPane.getComponent(i);
            if ((tabScroller != null) && (child == tabScroller.viewport))
            {
              JViewport viewport = (JViewport)child;
              Rectangle viewRect = viewport.getViewRect();
              int vw = tw;
              int vh = th;
              Dimension butSize = tabScroller.scrollForwardButton.getPreferredSize();
              switch (tabPlacement)
              {
              case 2: 
              case 4: 
                int totalTabHeight = rects[(tabCount - 1)].y + rects[(tabCount - 1)].height;
                if (totalTabHeight > th)
                {
                  vh = th > 2 * height ? th - 2 * height : 0;
                  if (totalTabHeight - y <= vh) {
                    vh = totalTabHeight - y;
                  }
                }
                break;
              case 1: 
              case 3: 
              default: 
                int totalTabWidth = rects[(tabCount - 1)].x + rects[(tabCount - 1)].width + renderer.getTabsOverlay();
                if (totalTabWidth > tw)
                {
                  vw = tw > 2 * width ? tw - 2 * width : 0;
                  if (totalTabWidth - x <= vw) {
                    vw = totalTabWidth - x;
                  }
                }
                break;
              }
              child.setBounds(tx, ty, vw, vh);
            }
            else if ((tabScroller != null) && ((child == tabScroller.scrollForwardButton) || (child == tabScroller.scrollBackwardButton)))
            {
              Component scrollbutton = child;
              Dimension bsize = scrollbutton.getPreferredSize();
              int bx = 0;
              int by = 0;
              int bw = width;
              int bh = height;
              boolean visible = false;
              switch (tabPlacement)
              {
              case 2: 
              case 4: 
                int totalTabHeight = rects[(tabCount - 1)].y + rects[(tabCount - 1)].height + renderer.getTabsOverlay();
                if (totalTabHeight > th)
                {
                  visible = true;
                  bx = tabPlacement == 2 ? tx + tw - width : tx;
                  
                  by = child == tabScroller.scrollForwardButton ? height - bottom - height : height - bottom - 2 * height;
                }
                break;
              case 1: 
              case 3: 
              default: 
                int totalTabWidth = rects[(tabCount - 1)].x + rects[(tabCount - 1)].width + renderer.getTabsOverlay();
                if (totalTabWidth > tw)
                {
                  visible = true;
                  bx = child == tabScroller.scrollForwardButton ? width - left - width : width - left - 2 * width;
                  
                  by = tabPlacement == 1 ? ty + th - height : ty;
                }
                break;
              }
              child.setVisible(visible);
              if (visible) {
                child.setBounds(bx, by, bw, bh);
              }
            }
            else
            {
              child.setBounds(cx, cy, cw, ch);
            }
          }
          if ((shouldChangeFocus) && 
            (!PlasticTabbedPaneUI.this.requestFocusForVisibleComponent())) {
            tabPane.requestFocus();
          }
        }
      }
    }
    
    protected void calculateTabRects(int tabPlacement, int tabCount)
    {
      FontMetrics metrics = getFontMetrics();
      Dimension size = tabPane.getSize();
      Insets insets = tabPane.getInsets();
      Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
      int fontHeight = metrics.getHeight();
      int selectedIndex = tabPane.getSelectedIndex();
      boolean verticalTabRuns = (tabPlacement == 2) || (tabPlacement == 4);
      boolean leftToRight = PlasticUtils.isLeftToRight(tabPane);
      int x = left;
      int y = top;
      int totalWidth = 0;
      int totalHeight = 0;
      switch (tabPlacement)
      {
      case 2: 
      case 4: 
        maxTabWidth = calculateMaxTabWidth(tabPlacement);
        break;
      case 1: 
      case 3: 
      default: 
        maxTabHeight = calculateMaxTabHeight(tabPlacement);
      }
      runCount = 0;
      selectedRun = -1;
      if (tabCount == 0) {
        return;
      }
      selectedRun = 0;
      runCount = 1;
      for (int i = 0; i < tabCount; i++)
      {
        Rectangle rect = rects[i];
        if (!verticalTabRuns)
        {
          if (i > 0)
          {
            x = (rects[(i - 1)].x + rects[(i - 1)].width);
          }
          else
          {
            tabRuns[0] = 0;
            maxTabWidth = 0;
            totalHeight += maxTabHeight;
            x = x;
          }
          width = calculateTabWidth(tabPlacement, i, metrics);
          totalWidth = x + width + renderer.getTabsOverlay();
          maxTabWidth = Math.max(maxTabWidth, width);
          
          y = y;
          height = maxTabHeight;
        }
        else
        {
          if (i > 0)
          {
            y = (rects[(i - 1)].y + rects[(i - 1)].height);
          }
          else
          {
            tabRuns[0] = 0;
            maxTabHeight = 0;
            totalWidth = maxTabWidth;
            y = y;
          }
          height = calculateTabHeight(tabPlacement, i, fontHeight);
          totalHeight = y + height;
          maxTabHeight = Math.max(maxTabHeight, height);
          
          x = x;
          width = maxTabWidth;
        }
      }
      padSelectedTab(tabPlacement, selectedIndex);
      if ((!leftToRight) && (!verticalTabRuns))
      {
        int rightMargin = width - (right + right);
        for (int i = 0; i < tabCount; i++) {
          rects[i].x = (rightMargin - rects[i].x - rects[i].width);
        }
      }
      tabScroller.tabPanel.setPreferredSize(new Dimension(totalWidth, totalHeight));
    }
  }
  
  private final class ScrollableTabSupport
    implements ActionListener, ChangeListener
  {
    public PlasticTabbedPaneUI.ScrollableTabViewport viewport;
    public PlasticTabbedPaneUI.ScrollableTabPanel tabPanel;
    public JButton scrollForwardButton;
    public JButton scrollBackwardButton;
    public int leadingTabIndex;
    private final Point tabViewPosition = new Point(0, 0);
    
    ScrollableTabSupport(int tabPlacement)
    {
      viewport = new PlasticTabbedPaneUI.ScrollableTabViewport(PlasticTabbedPaneUI.this);
      tabPanel = new PlasticTabbedPaneUI.ScrollableTabPanel(PlasticTabbedPaneUI.this);
      viewport.setView(tabPanel);
      viewport.addChangeListener(this);
      createButtons();
    }
    
    void createButtons()
    {
      if (scrollForwardButton != null)
      {
        tabPane.remove(scrollForwardButton);
        scrollForwardButton.removeActionListener(this);
        tabPane.remove(scrollBackwardButton);
        scrollBackwardButton.removeActionListener(this);
      }
      int tabPlacement = tabPane.getTabPlacement();
      int width = UIManager.getInt("ScrollBar.width");
      if ((tabPlacement == 1) || (tabPlacement == 3))
      {
        scrollForwardButton = new PlasticTabbedPaneUI.ArrowButton(3, width);
        scrollBackwardButton = new PlasticTabbedPaneUI.ArrowButton(7, width);
      }
      else
      {
        scrollForwardButton = new PlasticTabbedPaneUI.ArrowButton(5, width);
        scrollBackwardButton = new PlasticTabbedPaneUI.ArrowButton(1, width);
      }
      scrollForwardButton.addActionListener(this);
      scrollBackwardButton.addActionListener(this);
      tabPane.add(scrollForwardButton);
      tabPane.add(scrollBackwardButton);
    }
    
    public void scrollForward(int tabPlacement)
    {
      Dimension viewSize = viewport.getViewSize();
      Rectangle viewRect = viewport.getViewRect();
      if ((tabPlacement == 1) || (tabPlacement == 3))
      {
        if (width < width - x) {}
      }
      else if (height >= height - y) {
        return;
      }
      setLeadingTabIndex(tabPlacement, leadingTabIndex + 1);
    }
    
    public void scrollBackward(int tabPlacement)
    {
      if (leadingTabIndex == 0) {
        return;
      }
      setLeadingTabIndex(tabPlacement, leadingTabIndex - 1);
    }
    
    public void setLeadingTabIndex(int tabPlacement, int index)
    {
      leadingTabIndex = index;
      Dimension viewSize = viewport.getViewSize();
      Rectangle viewRect = viewport.getViewRect();
      switch (tabPlacement)
      {
      case 1: 
      case 3: 
        tabViewPosition.x = (leadingTabIndex == 0 ? 0 : rects[leadingTabIndex].x - renderer.getTabsOverlay());
        if (width - tabViewPosition.x < width)
        {
          Dimension extentSize = new Dimension(width - tabViewPosition.x, height);
          
          viewport.setExtentSize(extentSize);
        }
        break;
      case 2: 
      case 4: 
        tabViewPosition.y = (leadingTabIndex == 0 ? 0 : rects[leadingTabIndex].y);
        if (height - tabViewPosition.y < height)
        {
          Dimension extentSize = new Dimension(width, height - tabViewPosition.y);
          
          viewport.setExtentSize(extentSize);
        }
        break;
      }
      viewport.setViewPosition(tabViewPosition);
    }
    
    public void stateChanged(ChangeEvent e)
    {
      JViewport viewport = (JViewport)e.getSource();
      int tabPlacement = tabPane.getTabPlacement();
      int tabCount = tabPane.getTabCount();
      Rectangle vpRect = viewport.getBounds();
      Dimension viewSize = viewport.getViewSize();
      Rectangle viewRect = viewport.getViewRect();
      
      leadingTabIndex = PlasticTabbedPaneUI.this.getClosestTab(x, y);
      if (leadingTabIndex + 1 < tabCount) {
        switch (tabPlacement)
        {
        case 1: 
        case 3: 
          if (rects[leadingTabIndex].x < x) {
            leadingTabIndex += 1;
          }
          break;
        case 2: 
        case 4: 
          if (rects[leadingTabIndex].y < y) {
            leadingTabIndex += 1;
          }
          break;
        }
      }
      Insets contentInsets = getContentBorderInsets(tabPlacement);
      switch (tabPlacement)
      {
      case 2: 
        tabPane.repaint(x + width, y, left, height);
        
        scrollBackwardButton.setEnabled((y > 0) && (leadingTabIndex > 0));
        
        scrollForwardButton.setEnabled((leadingTabIndex < tabCount - 1) && (height - y > height));
        
        break;
      case 4: 
        tabPane.repaint(x - right, y, right, height);
        
        scrollBackwardButton.setEnabled((y > 0) && (leadingTabIndex > 0));
        
        scrollForwardButton.setEnabled((leadingTabIndex < tabCount - 1) && (height - y > height));
        
        break;
      case 3: 
        tabPane.repaint(x, y - bottom, width, bottom);
        
        scrollBackwardButton.setEnabled((x > 0) && (leadingTabIndex > 0));
        
        scrollForwardButton.setEnabled((leadingTabIndex < tabCount - 1) && (width - x > width));
        
        break;
      case 1: 
      default: 
        tabPane.repaint(x, y + height, width, top);
        
        scrollBackwardButton.setEnabled((x > 0) && (leadingTabIndex > 0));
        
        scrollForwardButton.setEnabled((leadingTabIndex < tabCount - 1) && (width - x > width));
      }
    }
    
    public void actionPerformed(ActionEvent e)
    {
      ActionMap map = tabPane.getActionMap();
      if (map != null)
      {
        String actionKey;
        String actionKey;
        if (e.getSource() == scrollForwardButton) {
          actionKey = "scrollTabsForwardAction";
        } else {
          actionKey = "scrollTabsBackwardAction";
        }
        Action action = map.get(actionKey);
        if ((action != null) && (action.isEnabled())) {
          action.actionPerformed(new ActionEvent(tabPane, 1001, null, e.getWhen(), e.getModifiers()));
        }
      }
    }
  }
  
  private final class ScrollableTabViewport
    extends JViewport
    implements UIResource
  {
    public ScrollableTabViewport()
    {
      setName("TabbedPane.scrollableViewport");
      setScrollMode(0);
      setOpaque(tabPane.isOpaque());
      Color bgColor = UIManager.getColor("TabbedPane.tabAreaBackground");
      if (bgColor == null) {
        bgColor = tabPane.getBackground();
      }
      setBackground(bgColor);
    }
  }
  
  private final class ScrollableTabPanel
    extends JPanel
    implements UIResource
  {
    public ScrollableTabPanel()
    {
      super();
      setOpaque(tabPane.isOpaque());
      Color bgColor = UIManager.getColor("TabbedPane.tabAreaBackground");
      if (bgColor == null) {
        bgColor = tabPane.getBackground();
      }
      setBackground(bgColor);
    }
    
    public void paintComponent(Graphics g)
    {
      super.paintComponent(g);
      paintTabArea(g, tabPane.getTabPlacement(), tabPane.getSelectedIndex());
    }
  }
  
  private static final class ArrowButton
    extends JButton
    implements UIResource
  {
    private final int buttonWidth;
    private final int direction;
    private boolean mouseIsOver;
    
    ArrowButton(int direction, int buttonWidth)
    {
      this.direction = direction;
      this.buttonWidth = buttonWidth;
      setRequestFocusEnabled(false);
    }
    
    protected void processMouseEvent(MouseEvent e)
    {
      super.processMouseEvent(e);
      switch (e.getID())
      {
      case 504: 
        mouseIsOver = true;
        revalidate();
        repaint();
        break;
      case 505: 
        mouseIsOver = false;
        revalidate();
        repaint();
      }
    }
    
    protected void paintBorder(Graphics g)
    {
      if ((mouseIsOver) && (isEnabled())) {
        super.paintBorder(g);
      }
    }
    
    protected void paintComponent(Graphics g)
    {
      if (mouseIsOver)
      {
        super.paintComponent(g);
      }
      else
      {
        g.setColor(getBackground());
        g.fillRect(0, 0, getWidth(), getHeight());
      }
      paintArrow(g);
    }
    
    private void paintArrow(Graphics g)
    {
      Color oldColor = g.getColor();
      
      boolean isEnabled = isEnabled();
      g.setColor(isEnabled ? PlasticLookAndFeel.getControlInfo() : PlasticLookAndFeel.getControlDisabled());
      int arrowWidth;
      int arrowHeight;
      switch (direction)
      {
      case 1: 
      case 5: 
        arrowWidth = 9;
        arrowHeight = 5;
        break;
      case 2: 
      case 3: 
      case 4: 
      case 6: 
      case 7: 
      default: 
        arrowWidth = 5;
        arrowHeight = 9;
      }
      int x = (getWidth() - arrowWidth) / 2;
      int y = (getHeight() - arrowHeight) / 2;
      g.translate(x, y);
      
      boolean paintShadow = (!mouseIsOver) || (!isEnabled);
      Color shadow = isEnabled ? PlasticLookAndFeel.getControlShadow() : UIManager.getColor("ScrollBar.highlight");
      switch (direction)
      {
      case 1: 
        g.fillRect(0, 4, 9, 1);
        g.fillRect(1, 3, 7, 1);
        g.fillRect(2, 2, 5, 1);
        g.fillRect(3, 1, 3, 1);
        g.fillRect(4, 0, 1, 1);
        if (paintShadow)
        {
          g.setColor(shadow);
          g.fillRect(1, 5, 9, 1);
        }
        break;
      case 5: 
        g.fillRect(0, 0, 9, 1);
        g.fillRect(1, 1, 7, 1);
        g.fillRect(2, 2, 5, 1);
        g.fillRect(3, 3, 3, 1);
        g.fillRect(4, 4, 1, 1);
        if (paintShadow)
        {
          g.setColor(shadow);
          g.drawLine(5, 4, 8, 1);
          g.drawLine(5, 5, 9, 1);
        }
        break;
      case 7: 
        g.fillRect(0, 4, 1, 1);
        g.fillRect(1, 3, 1, 3);
        g.fillRect(2, 2, 1, 5);
        g.fillRect(3, 1, 1, 7);
        g.fillRect(4, 0, 1, 9);
        if (paintShadow)
        {
          g.setColor(shadow);
          g.fillRect(5, 1, 1, 9);
        }
        break;
      case 3: 
        g.fillRect(0, 0, 1, 9);
        g.fillRect(1, 1, 1, 7);
        g.fillRect(2, 2, 1, 5);
        g.fillRect(3, 3, 1, 3);
        g.fillRect(4, 4, 1, 1);
        if (paintShadow)
        {
          g.setColor(shadow);
          g.drawLine(1, 8, 4, 5);
          g.drawLine(1, 9, 5, 5);
        }
        break;
      }
      g.translate(-x, -y);
      g.setColor(oldColor);
    }
    
    public Dimension getPreferredSize()
    {
      return new Dimension(buttonWidth, buttonWidth);
    }
    
    public Dimension getMinimumSize()
    {
      return getPreferredSize();
    }
    
    public Dimension getMaximumSize()
    {
      return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
    }
  }
  
  private static abstract class AbstractRenderer
  {
    AbstractRenderer(JTabbedPane x0, PlasticTabbedPaneUI.1 x1)
    {
      this(x0);
    }
    
    protected static final Insets EMPTY_INSETS = new Insets(0, 0, 0, 0);
    protected static final Insets NORTH_INSETS = new Insets(1, 0, 0, 0);
    protected static final Insets WEST_INSETS = new Insets(0, 1, 0, 0);
    protected static final Insets SOUTH_INSETS = new Insets(0, 0, 1, 0);
    protected static final Insets EAST_INSETS = new Insets(0, 0, 0, 1);
    protected final JTabbedPane tabPane;
    protected final int tabPlacement;
    protected Color shadowColor;
    protected Color darkShadow;
    protected Color selectColor;
    protected Color selectLight;
    protected Color selectHighlight;
    protected Color lightHighlight;
    protected Color focus;
    
    private AbstractRenderer(JTabbedPane tabPane)
    {
      initColors();
      this.tabPane = tabPane;
      tabPlacement = tabPane.getTabPlacement();
    }
    
    private static AbstractRenderer createRenderer(JTabbedPane tabPane)
    {
      switch (tabPane.getTabPlacement())
      {
      case 1: 
        return new PlasticTabbedPaneUI.TopRenderer(tabPane, null);
      case 3: 
        return new PlasticTabbedPaneUI.BottomRenderer(tabPane, null);
      case 2: 
        return new PlasticTabbedPaneUI.LeftRenderer(tabPane, null);
      case 4: 
        return new PlasticTabbedPaneUI.RightRenderer(tabPane, null);
      }
      return new PlasticTabbedPaneUI.TopRenderer(tabPane, null);
    }
    
    private static AbstractRenderer createEmbeddedRenderer(JTabbedPane tabPane)
    {
      switch (tabPane.getTabPlacement())
      {
      case 1: 
        return new PlasticTabbedPaneUI.TopEmbeddedRenderer(tabPane, null);
      case 3: 
        return new PlasticTabbedPaneUI.BottomEmbeddedRenderer(tabPane, null);
      case 2: 
        return new PlasticTabbedPaneUI.LeftEmbeddedRenderer(tabPane, null);
      case 4: 
        return new PlasticTabbedPaneUI.RightEmbeddedRenderer(tabPane, null);
      }
      return new PlasticTabbedPaneUI.TopEmbeddedRenderer(tabPane, null);
    }
    
    private void initColors()
    {
      shadowColor = UIManager.getColor("TabbedPane.shadow");
      darkShadow = UIManager.getColor("TabbedPane.darkShadow");
      selectColor = UIManager.getColor("TabbedPane.selected");
      focus = UIManager.getColor("TabbedPane.focus");
      selectHighlight = UIManager.getColor("TabbedPane.selectHighlight");
      lightHighlight = UIManager.getColor("TabbedPane.highlight");
      selectLight = new Color((2 * selectColor.getRed() + selectHighlight.getRed()) / 3, (2 * selectColor.getGreen() + selectHighlight.getGreen()) / 3, (2 * selectColor.getBlue() + selectHighlight.getBlue()) / 3);
    }
    
    protected boolean isFirstDisplayedTab(int tabIndex, int position, int paneBorder)
    {
      return tabIndex == 0;
    }
    
    protected Insets getTabAreaInsets(Insets defaultInsets)
    {
      return defaultInsets;
    }
    
    protected Insets getContentBorderInsets(Insets defaultInsets)
    {
      return defaultInsets;
    }
    
    protected int getTabLabelShiftX(int tabIndex, boolean isSelected)
    {
      return 0;
    }
    
    protected int getTabLabelShiftY(int tabIndex, boolean isSelected)
    {
      return 0;
    }
    
    protected int getTabRunOverlay(int tabRunOverlay)
    {
      return tabRunOverlay;
    }
    
    protected boolean shouldPadTabRun(int run, boolean aPriori)
    {
      return aPriori;
    }
    
    protected int getTabRunIndent(int run)
    {
      return 0;
    }
    
    protected Insets getSelectedTabPadInsets()
    {
      return EMPTY_INSETS;
    }
    
    protected void paintContentBorderTopEdge(Graphics g, int x, int y, int w, int h, boolean drawBroken, Rectangle selRect, boolean isContentBorderPainted)
    {
      if (isContentBorderPainted)
      {
        g.setColor(selectHighlight);
        g.fillRect(x, y, w - 1, 1);
      }
    }
    
    protected void paintContentBorderBottomEdge(Graphics g, int x, int y, int w, int h, boolean drawBroken, Rectangle selRect, boolean isContentBorderPainted)
    {
      if (isContentBorderPainted)
      {
        g.setColor(darkShadow);
        g.fillRect(x, y + h - 1, w - 1, 1);
      }
    }
    
    protected void paintContentBorderLeftEdge(Graphics g, int x, int y, int w, int h, boolean drawBroken, Rectangle selRect, boolean isContentBorderPainted)
    {
      if (isContentBorderPainted)
      {
        g.setColor(selectHighlight);
        g.fillRect(x, y, 1, h - 1);
      }
    }
    
    protected void paintContentBorderRightEdge(Graphics g, int x, int y, int w, int h, boolean drawBroken, Rectangle selRect, boolean isContentBorderPainted)
    {
      if (isContentBorderPainted)
      {
        g.setColor(darkShadow);
        g.fillRect(x + w - 1, y, 1, h);
      }
    }
    
    protected int getTabsOverlay()
    {
      return 0;
    }
    
    protected abstract Insets getTabInsets(int paramInt, Insets paramInsets);
    
    protected abstract void paintFocusIndicator(Graphics paramGraphics, Rectangle[] paramArrayOfRectangle, int paramInt, Rectangle paramRectangle1, Rectangle paramRectangle2, boolean paramBoolean);
    
    protected abstract void paintTabBackground(Graphics paramGraphics, int paramInt1, int paramInt2, int paramInt3, int paramInt4, int paramInt5, boolean paramBoolean);
    
    protected abstract void paintTabBorder(Graphics paramGraphics, int paramInt1, int paramInt2, int paramInt3, int paramInt4, int paramInt5, boolean paramBoolean);
  }
  
  private static final class BottomEmbeddedRenderer
    extends PlasticTabbedPaneUI.AbstractRenderer
  {
    BottomEmbeddedRenderer(JTabbedPane x0, PlasticTabbedPaneUI.1 x1)
    {
      this(x0);
    }
    
    private BottomEmbeddedRenderer(JTabbedPane tabPane)
    {
      super(null);
    }
    
    protected Insets getTabAreaInsets(Insets insets)
    {
      return EMPTY_INSETS;
    }
    
    protected Insets getContentBorderInsets(Insets defaultInsets)
    {
      return SOUTH_INSETS;
    }
    
    protected Insets getSelectedTabPadInsets()
    {
      return EMPTY_INSETS;
    }
    
    protected Insets getTabInsets(int tabIndex, Insets tabInsets)
    {
      return new Insets(top, left, bottom, right);
    }
    
    protected void paintTabBackground(Graphics g, int tabIndex, int x, int y, int w, int h, boolean isSelected)
    {
      g.setColor(selectColor);
      g.fillRect(x, y, w + 1, h);
    }
    
    protected void paintTabBorder(Graphics g, int tabIndex, int x, int y, int w, int h, boolean isSelected)
    {
      int bottom = h;
      int right = w + 1;
      
      g.translate(x, y);
      if (isFirstDisplayedTab(tabIndex, x, tabPane.getBounds().x))
      {
        if (isSelected)
        {
          g.setColor(shadowColor);
          g.fillRect(right, 0, 1, bottom - 1);
          g.fillRect(right - 1, bottom - 1, 1, 1);
          
          g.setColor(selectHighlight);
          g.fillRect(0, 0, 1, bottom);
          g.fillRect(right - 1, 0, 1, bottom - 1);
          g.fillRect(1, bottom - 1, right - 2, 1);
        }
      }
      else if (isSelected)
      {
        g.setColor(shadowColor);
        g.fillRect(0, 0, 1, bottom - 1);
        g.fillRect(1, bottom - 1, 1, 1);
        g.fillRect(right, 0, 1, bottom - 1);
        g.fillRect(right - 1, bottom - 1, 1, 1);
        
        g.setColor(selectHighlight);
        g.fillRect(1, 0, 1, bottom - 1);
        g.fillRect(right - 1, 0, 1, bottom - 1);
        g.fillRect(2, bottom - 1, right - 3, 1);
      }
      else
      {
        g.setColor(shadowColor);
        g.fillRect(1, h / 2, 1, h - h / 2);
      }
      g.translate(-x, -y);
    }
    
    protected void paintContentBorderBottomEdge(Graphics g, int x, int y, int w, int h, boolean drawBroken, Rectangle selRect, boolean isContentBorderPainted)
    {
      g.setColor(shadowColor);
      g.fillRect(x, y + h - 1, w, 1);
    }
    
    protected void paintFocusIndicator(Graphics g, Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle textRect, boolean isSelected) {}
  }
  
  private static final class BottomRenderer
    extends PlasticTabbedPaneUI.AbstractRenderer
  {
    BottomRenderer(JTabbedPane x0, PlasticTabbedPaneUI.1 x1)
    {
      this(x0);
    }
    
    private BottomRenderer(JTabbedPane tabPane)
    {
      super(null);
    }
    
    protected Insets getTabAreaInsets(Insets defaultInsets)
    {
      return new Insets(top, left + 5, bottom, right);
    }
    
    protected int getTabLabelShiftY(int tabIndex, boolean isSelected)
    {
      return isSelected ? 0 : -1;
    }
    
    protected int getTabRunOverlay(int tabRunOverlay)
    {
      return tabRunOverlay - 2;
    }
    
    protected int getTabRunIndent(int run)
    {
      return 6 * run;
    }
    
    protected Insets getSelectedTabPadInsets()
    {
      return SOUTH_INSETS;
    }
    
    protected Insets getTabInsets(int tabIndex, Insets tabInsets)
    {
      return new Insets(top, left - 2, bottom, right - 2);
    }
    
    protected void paintFocusIndicator(Graphics g, Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle textRect, boolean isSelected)
    {
      if ((!tabPane.hasFocus()) || (!isSelected)) {
        return;
      }
      Rectangle tabRect = rects[tabIndex];
      int top = y;
      int left = x + 6;
      int height = height - 3;
      int width = width - 12;
      g.setColor(focus);
      g.drawRect(left, top, width, height);
    }
    
    protected void paintTabBackground(Graphics g, int tabIndex, int x, int y, int w, int h, boolean isSelected)
    {
      g.setColor(selectColor);
      g.fillRect(x, y, w, h);
    }
    
    protected void paintTabBorder(Graphics g, int tabIndex, int x, int y, int w, int h, boolean isSelected)
    {
      int bottom = h - 1;
      int right = w + 4;
      
      g.translate(x - 3, y);
      
      g.setColor(selectHighlight);
      
      g.fillRect(0, 0, 1, 2);
      g.drawLine(0, 2, 4, bottom - 4);
      g.fillRect(5, bottom - 3, 1, 2);
      g.fillRect(6, bottom - 1, 1, 1);
      
      g.fillRect(7, bottom, 1, 1);
      g.setColor(darkShadow);
      g.fillRect(8, bottom, right - 13, 1);
      
      g.drawLine(right + 1, 0, right - 3, bottom - 4);
      g.fillRect(right - 4, bottom - 3, 1, 2);
      g.fillRect(right - 5, bottom - 1, 1, 1);
      
      g.translate(-x + 3, -y);
    }
    
    protected void paintContentBorderBottomEdge(Graphics g, int x, int y, int w, int h, boolean drawBroken, Rectangle selRect, boolean isContentBorderPainted)
    {
      int bottom = y + h - 1;
      int right = x + w - 1;
      g.translate(x, bottom);
      if ((drawBroken) && (x >= x) && (x <= x + w))
      {
        g.setColor(darkShadow);
        g.fillRect(0, 0, x - x - 2, 1);
        if (x + width < x + w - 2)
        {
          g.setColor(darkShadow);
          g.fillRect(x + width + 2 - x, 0, right - x - width - 2, 1);
        }
      }
      else
      {
        g.setColor(darkShadow);
        g.fillRect(0, 0, w - 1, 1);
      }
      g.translate(-x, -bottom);
    }
    
    protected int getTabsOverlay()
    {
      return 4;
    }
  }
  
  private static final class LeftEmbeddedRenderer
    extends PlasticTabbedPaneUI.AbstractRenderer
  {
    LeftEmbeddedRenderer(JTabbedPane x0, PlasticTabbedPaneUI.1 x1)
    {
      this(x0);
    }
    
    private LeftEmbeddedRenderer(JTabbedPane tabPane)
    {
      super(null);
    }
    
    protected Insets getTabAreaInsets(Insets insets)
    {
      return EMPTY_INSETS;
    }
    
    protected Insets getContentBorderInsets(Insets defaultInsets)
    {
      return WEST_INSETS;
    }
    
    protected int getTabRunOverlay(int tabRunOverlay)
    {
      return 0;
    }
    
    protected boolean shouldPadTabRun(int run, boolean aPriori)
    {
      return false;
    }
    
    protected Insets getTabInsets(int tabIndex, Insets tabInsets)
    {
      return new Insets(top, left, bottom, right);
    }
    
    protected Insets getSelectedTabPadInsets()
    {
      return EMPTY_INSETS;
    }
    
    protected void paintTabBackground(Graphics g, int tabIndex, int x, int y, int w, int h, boolean isSelected)
    {
      g.setColor(selectColor);
      g.fillRect(x, y, w, h);
    }
    
    protected void paintTabBorder(Graphics g, int tabIndex, int x, int y, int w, int h, boolean isSelected)
    {
      int bottom = h;
      int right = w;
      
      g.translate(x, y);
      if (isFirstDisplayedTab(tabIndex, y, tabPane.getBounds().y))
      {
        if (isSelected)
        {
          g.setColor(selectHighlight);
          g.fillRect(0, 0, right, 1);
          g.fillRect(0, 0, 1, bottom - 1);
          g.fillRect(1, bottom - 1, right - 1, 1);
          g.setColor(shadowColor);
          g.fillRect(0, bottom - 1, 1, 1);
          g.fillRect(1, bottom, right - 1, 1);
        }
      }
      else if (isSelected)
      {
        g.setColor(selectHighlight);
        g.fillRect(1, 1, right - 1, 1);
        g.fillRect(0, 2, 1, bottom - 2);
        g.fillRect(1, bottom - 1, right - 1, 1);
        g.setColor(shadowColor);
        g.fillRect(1, 0, right - 1, 1);
        g.fillRect(0, 1, 1, 1);
        g.fillRect(0, bottom - 1, 1, 1);
        g.fillRect(1, bottom, right - 1, 1);
      }
      else
      {
        g.setColor(shadowColor);
        g.fillRect(0, 0, right / 3, 1);
      }
      g.translate(-x, -y);
    }
    
    protected void paintContentBorderLeftEdge(Graphics g, int x, int y, int w, int h, boolean drawBroken, Rectangle selRect, boolean isContentBorderPainted)
    {
      g.setColor(shadowColor);
      g.fillRect(x, y, 1, h);
    }
    
    protected void paintFocusIndicator(Graphics g, Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle textRect, boolean isSelected) {}
  }
  
  private static final class LeftRenderer
    extends PlasticTabbedPaneUI.AbstractRenderer
  {
    LeftRenderer(JTabbedPane x0, PlasticTabbedPaneUI.1 x1)
    {
      this(x0);
    }
    
    private LeftRenderer(JTabbedPane tabPane)
    {
      super(null);
    }
    
    protected Insets getTabAreaInsets(Insets defaultInsets)
    {
      return new Insets(top + 4, left, bottom, right);
    }
    
    protected int getTabLabelShiftX(int tabIndex, boolean isSelected)
    {
      return 1;
    }
    
    protected int getTabRunOverlay(int tabRunOverlay)
    {
      return 1;
    }
    
    protected boolean shouldPadTabRun(int run, boolean aPriori)
    {
      return false;
    }
    
    protected Insets getTabInsets(int tabIndex, Insets tabInsets)
    {
      return new Insets(top, left - 5, bottom + 1, right - 5);
    }
    
    protected Insets getSelectedTabPadInsets()
    {
      return WEST_INSETS;
    }
    
    protected void paintFocusIndicator(Graphics g, Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle textRect, boolean isSelected)
    {
      if ((!tabPane.hasFocus()) || (!isSelected)) {
        return;
      }
      Rectangle tabRect = rects[tabIndex];
      int top = y + 2;
      int left = x + 3;
      int height = height - 5;
      int width = width - 6;
      g.setColor(focus);
      g.drawRect(left, top, width, height);
    }
    
    protected void paintTabBackground(Graphics g, int tabIndex, int x, int y, int w, int h, boolean isSelected)
    {
      if (!isSelected)
      {
        g.setColor(selectLight);
        g.fillRect(x + 1, y + 1, w - 1, h - 2);
      }
      else
      {
        g.setColor(selectColor);
        g.fillRect(x + 1, y + 1, w - 3, h - 2);
      }
    }
    
    protected void paintTabBorder(Graphics g, int tabIndex, int x, int y, int w, int h, boolean isSelected)
    {
      int
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

Further reading...

For more information on Java 1.5 Tiger, you may find Java 1.5 Tiger, A developer's Notebook by D. Flanagan and B. McLaughlin from O'Reilly of interest.

New!JAR listings


Copyright 2006-2019. Infinite Loop Ltd