private void doInit() {
    initPreCommonValues();

    for (int i = 0; i < DIRECTIONS.length; i++) {
      PanePainter pane = paneHandler.getPainter(DIRECTIONS[i]);
      initValues(pane, i, DIRECTIONS[i]);
      reset(pane);
    }

    initPostCommonValues();
  }
  private void initPreCommonValues() {

    // Hack for some look and feels
    tabAreaNotVisibleFix =
        UIManager.getLookAndFeel().getClass().getName().indexOf(".WindowsLookAndFeel") > -1;

    // Icon text gap
    textIconGap = UIManager.getInt("TabbedPane.textIconGap");
    if (textIconGap <= 0) textIconGap = 4;

    // Opaque
    opaque = paneHandler.getPainter(Direction.UP).isOpaque();

    Boolean contentOp = (Boolean) UIManager.get("TabbedPane.contentOpaque");
    if (contentOp == null) contentOpaque = opaque;
    else contentOpaque = contentOp.booleanValue();

    tabAreaOpaque = opaque;

    tabAreaComponentsOpaque = false;
  }
  public void paintContentArea(
      TabbedPanelContentPanel p, Graphics g, int x, int y, int width, int height) {
    if (enabled && PAINT_CONTENT_AREA) {
      tabData.initialize(p.getTabbedPanel());
      PanePainter pane = paneHandler.getPainter(tabData.getAreaOrientation());

      initTabLocations(pane);

      int tx = 0;
      int ty = 0;

      if (tabData.getTabbedPanel().hasContentArea()) {
        Point l = getLocationInTabbedPanel(p, tabData.getTabbedPanel());

        int yComp = 0;
        int xComp = 0;

        if (pane.getTabCount() == 0 && tabData.getTabCount() > 0) {
          if (tabData.getAreaOrientation() == Direction.UP) {
            yComp = tabData.getTabAreaHeight();
          } else if (tabData.getAreaOrientation() == Direction.DOWN) {
            yComp = -tabData.getTabAreaHeight();
          } else if (tabData.getAreaOrientation() == Direction.LEFT) {
            xComp = tabData.getTabAreaWidth();
          } else {
            xComp = -tabData.getTabAreaWidth();
          }
        }

        tx = -l.x + (xComp > 0 ? xComp : 0);
        ty = -l.y + (yComp > 0 ? yComp : 0);

        int extraWidth = 0;
        int extraHeight = 0;

        if (tabAreaNotVisibleFix && !tabData.getTabbedPanel().isTabAreaVisible()) {
          extraWidth =
              !tabData.isHorizontalLayout()
                  ? tabMinimumSizes[getDirectionIndex(tabData.getAreaOrientation())].width
                      - raiseds[getDirectionIndex(tabData.getAreaOrientation())]
                      + (tabData.getAreaOrientation() == Direction.LEFT
                          ? areaInsets[getDirectionIndex(Direction.LEFT)].left
                          : areaInsets[getDirectionIndex(Direction.RIGHT)].right)
                  : 0;
          extraHeight =
              tabData.isHorizontalLayout()
                  ? tabMinimumSizes[getDirectionIndex(tabData.getAreaOrientation())].height
                      - raiseds[getDirectionIndex(tabData.getAreaOrientation())]
                      + (tabData.getAreaOrientation() == Direction.UP
                          ? areaInsets[getDirectionIndex(Direction.UP)].top
                          : areaInsets[getDirectionIndex(Direction.DOWN)].bottom)
                  : 0;
        }

        tx -= tabData.getAreaOrientation() == Direction.LEFT ? extraWidth : 0;
        ty -= tabData.getAreaOrientation() == Direction.UP ? extraHeight : 0;

        pane.setSize(
            tabData.getTabbedPanelSize().width - Math.abs(xComp) + extraWidth,
            tabData.getTabbedPanelSize().height - Math.abs(yComp) + extraHeight);

        pane.doValidation();
      } else {
        if (tabData.isHorizontalLayout()) {
          pane.setSize(p.getWidth(), p.getHeight() + tabData.getTabAreaHeight());
        } else {
          pane.setSize(p.getWidth() + tabData.getTabAreaWidth(), p.getHeight());
        }

        pane.doValidation();

        if (tabData.getAreaOrientation() == Direction.UP) ty -= tabData.getTabAreaHeight();
        else if (tabData.getAreaOrientation() == Direction.LEFT) tx -= tabData.getTabAreaWidth();
      }

      pane.paint(g, tx, ty);

      tabData.reset();

      reset(pane);
    }
  }
  public void paintTabArea(TabbedPanel tp, Graphics g, int x, int y, int width, int height) {
    int heightTemp = height;
    int widthTemp = width;
    int xTemp = x;
    int yTemp = y;
    if (enabled && tp.isTabAreaVisible()) {

      tabData.initialize(tp);

      PanePainter pane = paneHandler.getPainter(tabData.getAreaOrientation());

      initTabLocations(pane);
      Insets aInsets = getTabAreaInsets(tabData.getAreaOrientation());

      if (tp.getTabCount() > 0) {
        // Adjust x, y
        if (tabData.getAreaOrientation() == Direction.DOWN) {
          yTemp += tabData.getTabbedPanelHeight() - heightTemp;
        } else if (tabData.getAreaOrientation() == Direction.RIGHT) {
          xTemp += tabData.getTabbedPanelWidth() - widthTemp;
        }

        widthTemp = xTemp < 0 ? widthTemp + xTemp : widthTemp;
        heightTemp = yTemp < 0 ? heightTemp + yTemp : heightTemp;

        xTemp = Math.max(0, xTemp);
        yTemp = Math.max(0, yTemp);

        if (tabData.isHorizontalLayout())
          pane.setSize(tabData.getTabbedPanelSize().width, getTabbedPanelExtraSize());
        else pane.setSize(getTabbedPanelExtraSize(), tabData.getTabbedPanelHeight());

        if (PAINT_TAB_AREA && !(pane.getTabCount() == 0 && tabData.getTabCount() > 0)) {
          Shape originalClip = g.getClip();

          int tx =
              -xTemp
                  - (tabData.getAreaOrientation() == Direction.RIGHT
                      ? -tabData.getTabbedPanelWidth() + getTabbedPanelExtraSize()
                      : 0);
          int ty =
              -yTemp
                  - (tabData.getAreaOrientation() == Direction.DOWN
                      ? -tabData.getTabbedPanelHeight() + getTabbedPanelExtraSize()
                      : 0);

          Rectangle firstVisibleRect = (Rectangle) tabData.getVisibleTabRects().get(0);
          Rectangle lastVisibleRect =
              (Rectangle) tabData.getVisibleTabRects().get(tabData.getTabCount() - 1);
          Tab lastTab = (Tab) tabData.getTabList().get(tabData.getTabCount() - 1);

          if (tabData.isHorizontalLayout()) {
            int extraWidth =
                lastTab.getWidth() == lastVisibleRect.width
                    ? 0
                    : 2 * tabData.getTabbedPanelSize().width - tabData.getTabAreaWidth();
            pane.setSize(pane.getWidth() + extraWidth, pane.getHeight());

            pane.doValidation();

            // Before tabs
            g.clipRect(
                0,
                0,
                aInsets.left + (firstVisibleRect.width > 0 && firstVisibleRect.x == 0 ? 1 : 0),
                heightTemp);
            pane.paint(g, tx, ty);
            g.setClip(originalClip);

            // After tabs
            tx -= extraWidth;

            int clipExtraWidth = extraWidth == 0 ? 1 : 0;
            g.clipRect(
                aInsets.left + tabData.getTabAreaWidth() - clipExtraWidth,
                0,
                widthTemp - aInsets.left - tabData.getTabAreaWidth() + clipExtraWidth,
                heightTemp);
            pane.paint(g, tx, ty);
            g.setClip(originalClip);
          } else {
            int extraHeight =
                lastTab.getHeight() == lastVisibleRect.height
                    ? 0
                    : 2 * tabData.getTabbedPanelSize().height - tabData.getTabAreaHeight();
            pane.setSize(pane.getWidth(), pane.getHeight() + extraHeight);

            pane.doValidation();

            // Before tabs
            g.clipRect(
                0,
                0,
                widthTemp,
                aInsets.top + (firstVisibleRect.height > 0 && firstVisibleRect.y == 0 ? 1 : 0));
            pane.paint(g, tx, ty);
            g.setClip(originalClip);

            // After tabs
            ty -= extraHeight;

            int clipExtraHeight = extraHeight == 0 ? 1 : 0;
            g.clipRect(
                0,
                aInsets.top + tabData.getTabAreaHeight() - clipExtraHeight,
                widthTemp,
                heightTemp - aInsets.top - tabData.getTabAreaHeight() + clipExtraHeight);
            pane.paint(g, tx, ty);
            g.setClip(originalClip);
          }
        }

        // First and last tab
        paintTabs(pane, tabData, g, xTemp, yTemp, widthTemp, heightTemp);

        tabData.reset();

        reset(pane);
      }
    }
  }
 public Font getFont() {
   return paneHandler.getPainter(Direction.UP).getFont();
 }
 public void dispose() {
   enabled = false;
   paneHandler.dispose();
 }
 public void init() {
   paneHandler.update();
 }