• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JTabbedPaneのタイトルをクリップ
#navi(../)
*JTabbedPaneのタイトルをクリップ [#paeaad58]
>編集者:[[Terai Atsuhiro>terai]]~
作成日:2007-10-08~
更新日:&lastmod;

#contents

**概要 [#zcdc1d6d]
JDK 6 で導入されたタブにコンポーネントを追加する機能を使って、長いタイトルのタブは文字列をクリップして表示します。

#screenshot

**サンプルコード [#xad70fa1]
#code{{
class ClippedTitleTabbedPane extends JTabbedPane {
  private final Insets tabInsets = UIManager.getInsets("TabbedPane.tabInsets");
  private final Insets tabAreaInsets = UIManager.getInsets("TabbedPane.tabAreaInsets");
  public ClippedTitleTabbedPane() {
    super();
    addComponentListener(new ComponentAdapter() {
      @Override
      public void componentResized(ComponentEvent e) {
        initTabWidth();
      }
    });
    addChangeListener(new ChangeListener() {
      @Override
      public void stateChanged(ChangeEvent e) {
        initTabWidth();
      }
    });
  }
  @Override
  public void insertTab(String title, Icon icon, Component component, String tip, int index) {
    super.insertTab(title, icon, component, tip==null?title:tip, index);
    JLabel label = new JLabel(title, JLabel.CENTER);
    Dimension dim = label.getPreferredSize();
    label.setPreferredSize(new Dimension(0, dim.height+tabInsets.top+tabInsets.bottom));
    setTabComponentAt(index, label);
    initTabWidth();
  }
  private void initTabWidth() {
    int paneWidth  = getWidth() - 4; //?4?
    int tabCount   = getTabCount();
    int tabPlacement = getTabPlacement();
    int tabWidth   = tabInsets.left + tabInsets.right + 3;
    switch(tabPlacement) {
  public void initTabWidth() {
    Insets insets = getInsets();
    int areaWidth = getWidth() - tabAreaInsets.left - tabAreaInsets.right
                               - insets.left - insets.right;
    int tabCount  = getTabCount();
    int tabWidth  = tabInsets.left + tabInsets.right + 3;
    switch(getTabPlacement()) {
      case LEFT: case RIGHT:
      tabWidth = (int)(paneWidth/4) - tabWidth;
      tabWidth = (int)(areaWidth/4) - tabWidth;
      break;
      case BOTTOM: case TOP: default:
      tabWidth = (int)(paneWidth/tabCount) - tabWidth;
      tabWidth = (int)(areaWidth/tabCount) - tabWidth;
    }
    for(int i=0;i<tabCount;i++) {
      JLabel l = (JLabel)getTabComponentAt(i);
      if(l!=null) {
        Dimension dim = l.getPreferredSize();
        l.setPreferredSize(new Dimension(tabWidth, dim.height));
      }
      if(l==null) break;
      l.setPreferredSize(new Dimension(tabWidth, l.getPreferredSize().height));
    }
    revalidate();
  }
}
}}
-&jnlp;
-&jar;
-&zip;

**解説 [#xe7c3559]
下のJTabbedPaneでは、タブにJTabbedPane#setTabComponentAtメソッドを使ってJLabelを追加し、そのクリップ機能を利用して長いタイトル文字列をクリップしています。

[[JTabbedPaneのタブを等幅にしてタイトルをクリップ>Swing/ClippedTitleTab]]と、ほぼ同等((文字列の長さがばらばらでも、左右にタブをおいた場合は全体の1/4の幅に、上下にタブをおいた場合はすべてのタブ幅が均等になる))ですが、TabbedPaneUI#paintTextで文字列の描画をオーバーライドする必要も無く、ソースも短くて実装が簡単です。

**参考リンク [#r6054f8d]
-[[JTabbedPaneのタブを等幅にしてタイトルをクリップ>Swing/ClippedTitleTab]]

**コメント [#p47877ec]
- 以下の二点を変更しました: tabAreaInsetsを考慮するように修正、TOP-LEFTの切り替えの追加 -- [[terai]] &new{2008-02-26 (火) 22:15:27};

#comment