概要

JTabbedPaneのタブに描画される縁やテキストシフトなどを無効にしてフラットデザイン風に変更します。

サンプルコード

UIManager.put("TabbedPane.tabInsets", new Insets(5, 10, 5, 10));
UIManager.put("TabbedPane.tabAreaInsets", new Insets(0, 0, 0, 0));
UIManager.put("TabbedPane.selectedLabelShift", 0);
UIManager.put("TabbedPane.labelShift", 0);

// UIManager.put("TabbedPane.foreground", Color.WHITE);
// UIManager.put("TabbedPane.selectedForeground", Color.WHITE);
// UIManager.put("TabbedPane.unselectedBackground", UNSELECTED_BG);
UIManager.put("TabbedPane.tabAreaBackground", UNSELECTED_BG);

JTabbedPane tabs = new JTabbedPane() {
  @Override public void updateUI() {
    super.updateUI();
    setUI(new BasicTabbedPaneUI() {
      @Override protected void paintFocusIndicator(
          Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex,
          Rectangle iconRect, Rectangle textRect, boolean isSelected) {
        // Do not paint anything
      }
      @Override protected void paintTabBorder(
          Graphics g, int tabPlacement, int tabIndex,
          int x, int y, int w, int h, boolean isSelected) {
        // Do not paint anything
      }
      @Override  protected void paintTabBackground(
          Graphics g, int tabPlacement, int tabIndex,
          int x, int y, int w, int h, boolean isSelected) {
        g.setColor(isSelected ? SELECTED_BG : UNSELECTED_BG);
        g.fillRect(x, y, w, h);
      }
    });
    setOpaque(true);
    setForeground(Color.WHITE);
    setTabPlacement(SwingConstants.LEFT);
    setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
  }
};
view all

解説

上記のサンプルでは、タブの縁やフォーカスなどの描画を無効にしたBasicTabbedPaneUIを作成してJTabbedPaneに設定することで、フラットデザイン風のJTabbedPaneを実現しています。

  • TabbedPane.selectedLabelShiftTabbedPane.labelShift0にして選択時の文字列シフトを無効化
  • JTabbedPane#setOpaque(true)TabbedPane.tabAreaBackgroundを設定して、タブエリアの背景色を変更
  • BasicTabbedPaneUI#paintFocusIndicator(...)メソッドをオーバーライドして、フォーカスの点線を非表示
  • BasicTabbedPaneUI#paintTabBorder(...)メソッドをオーバーライドして、タブの縁を非表示
  • BasicTabbedPaneUI#paintTabBackground(...)メソッドをオーバーライドして、タブの背景を塗りつぶす
    • 例えばJTabbedPane#setTabPlacement(SwingConstants.LEFT)でタブエリアが左にある場合、タブの左側に1pxの隙間ができる
    • UIManager.put("TabbedPane.tabAreaInsets", new Insets(0, 0, 0, 0));で除去できた
    • TabbedPane.selectedLabelShiftまたはTabbedPane.labelShiftのデフォルト値が決め打ちで入っている?
    • このサンプルでは左に1pxタブ領域を拡大して対応
  • タブコンテンツの縁飾りを無くす場合は、UIManager.put("TabbedPane.contentBorderInsets", new Insets(0, 0, 0, 0));などが使用可能

参考リンク

コメント