• 追加された行はこの色です。
  • 削除された行はこの色です。
---
category: swing
folder: FlatTabbedPane
title: JTabbedPaneのタブ描画をフラットデザイン風に変更する
tags: [JTabbedPane, BasicLookAndFeel]
author: aterai
pubdate: 2018-08-20T16:17:33+09:00
description: JTabbedPaneのタブに描画される縁やテキストシフトなどを無効にしてフラットデザイン風に変更します。
image: https://drive.google.com/uc?id=1HQCaLqj1ikLRJCljsjabjF2MS_a-UDhuNw
hreflang:
    href: https://java-swing-tips.blogspot.com/2018/08/change-tab-of-jtabbedpane-to-flat.html
    lang: en
---
* 概要 [#summary]
`JTabbedPane`のタブに描画される縁やテキストシフトなどを無効にしてフラットデザイン風に変更します。

#download(https://drive.google.com/uc?id=1HQCaLqj1ikLRJCljsjabjF2MS_a-UDhuNw)

* サンプルコード [#sourcecode]
#code(link){{
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);
  }
};
}}

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

- `TabbedPane.selectedLabelShift`と`TabbedPane.labelShift`を`0`にして選択時の文字列シフトを無効化
-- 参考: [https://bugs.openjdk.java.net/browse/JDK-7010561 JDK-7010561 Tab text position with Synth based LaF is different to Java 5/6 - Java Bug System]
- `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));`で除去できた
-- [https://bugs.openjdk.org/browse/JDK-7010561 JDK-7010561 Tab text position with Synth based LaF is different to Java 5/6 - Java Bug System]
- `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))`などが使用可能
-- 縁飾りを選択背景色でベタ塗りする場合は、`BasicTabbedPaneUI#paintContentBorderLeftEdge(...)`メソッドなどをオーバーライドすることで対応可能
--- 参考: [https://stackoverflow.com/questions/51944426/java-jtabbedpane-border-of-stacked-tabs-removal swing - JAVA JTabbedPane - border of stacked tabs removal - Stack Overflow]

* 参考リンク [#reference]
- [[JTabbedPaneのタブエリア背景色などをテスト>Swing/TabAreaBackground]]
- [https://bugs.openjdk.java.net/browse/JDK-7010561 JDK-7010561 Tab text position with Synth based LaF is different to Java 5/6 - Java Bug System]
- [https://bugs.openjdk.org/browse/JDK-7010561 JDK-7010561 Tab text position with Synth based LaF is different to Java 5/6 - Java Bug System]
- [https://stackoverflow.com/questions/51944426/java-jtabbedpane-border-of-stacked-tabs-removal swing - JAVA JTabbedPane - border of stacked tabs removal - Stack Overflow]

* コメント [#comment]
#comment
#comment