• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JTabbedPaneの余白にJCheckBoxを配置
#navi(../)
*JTabbedPaneの余白にJCheckBoxを配置 [#jf5f1d6a]
Posted by [[terai]] at 2006-04-03
---
category: swing
folder: TabbedPaneWithCheckBox
title: JTabbedPaneの余白にJCheckBoxを配置
tags: [JTabbedPane, JCheckBox, Border]
author: aterai
pubdate: 2006-04-03T01:35:12+09:00
description: JTabbedPaneの余白にJCheckBoxを配置して特定のタブの開閉を行います。
image: https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTUQ8ALIWI/AAAAAAAAAlw/7jfCbNrxWK8/s800/TabbedPaneWithCheckBox.png
---
* 概要 [#summary]
`JTabbedPane`の余白に`JCheckBox`を配置して特定のタブの表示・非表示を切り替えます。

#contents
#download(https://lh3.googleusercontent.com/_9Z4BYR88imo/TQTUQ8ALIWI/AAAAAAAAAlw/7jfCbNrxWK8/s800/TabbedPaneWithCheckBox.png)

**概要 [#mac165bc]
JTabbedPaneの余白にJCheckBoxを配置して特定のタブの開閉を行います。

-&jnlp;
-&jar;
-&zip;

#screenshot

**サンプルコード [#hd0302da]
#code{{
* サンプルコード [#sourcecode]
#code(link){{
class TabbedPaneWithCompBorder implements Border, MouseListener, SwingConstants {
  private final JComponent  dummy = new JPanel();;
  private final JCheckBox   cbox;
  private final JCheckBox checkBox;
  private final JTabbedPane tab;
  private Rectangle rect;
  public TabbedPaneWithCompBorder(JCheckBox cbox, JTabbedPane tab) {
    this.cbox = cbox;
    this.tab  = tab;
    tab.addMouseListener(this);
    cbox.setFocusPainted(false);
    cbox.addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent me) {
        JCheckBox cb = (JCheckBox)me.getSource();
        cb.setSelected(!cb.isSelected());
      }
    });
  private final Container rubberStamp = new JPanel();
  private final Rectangle rect = new Rectangle();

  protected TabbedPaneWithCompBorder(JCheckBox checkBox, JTabbedPane tab) {
    this.checkBox = checkBox;
    this.tab = tab;
  }
  public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
    Dimension size = cbox.getPreferredSize();

  @Override public void paintBorder(
      Component c, Graphics g, int x, int y, int width, int height) {
    Dimension size = checkBox.getPreferredSize();
    int xx = tab.getSize().width - size.width;
    Rectangle lastTab = tab.getUI().getTabBounds(tab, tab.getTabCount()-1);
    Rectangle lastTab = tab.getBoundsAt(tab.getTabCount() - 1);
    int tabEnd = lastTab.x + lastTab.width;
    if(xx<tabEnd) xx = tabEnd;
    rect = new Rectangle(xx, -2, size.width, size.height);
    SwingUtilities.paintComponent(g, cbox, dummy, rect);
    if (xx < tabEnd) {
      xx = tabEnd;
    }
    rect.setBounds(xx, -2, size.width, size.height);
    SwingUtilities.paintComponent(g, checkBox, rubberStamp, rect);
  }
  public Insets getBorderInsets(Component c) {
    return new Insets(0,0,0,0);

  @Override public Insets getBorderInsets(Component c) {
    return new Insets(0, 0, 0, 0);
  }
  public boolean isBorderOpaque() {

  @Override public boolean isBorderOpaque() {
    return true;
  }
  private void dispatchEvent(MouseEvent me) {
    if(rect==null || !rect.contains(me.getX(), me.getY())) return;
    cbox.setBounds(rect);
    cbox.dispatchEvent(SwingUtilities.convertMouseEvent(tab,me,cbox));

  private void dispatchEvent(MouseEvent e) {
    if (!rect.contains(e.getX(), e.getY())) {
      return;
    }
    checkBox.setBounds(rect);
    checkBox.dispatchEvent(SwingUtilities.convertMouseEvent(tab, e, checkBox));
  }
  public void mouseClicked(MouseEvent me) {
    dispatchEvent(me);

  @Override public void mouseClicked(MouseEvent e) {
    dispatchEvent(e);
  }
  public void mouseEntered(MouseEvent me) {
    dispatchEvent(me);

  @Override public void mouseEntered(MouseEvent e) {
    dispatchEvent(e);
  }
  public void mouseExited(MouseEvent me) {
    dispatchEvent(me);

  @Override public void mouseExited(MouseEvent e) {
    dispatchEvent(e);
  }
  public void mousePressed(MouseEvent me) {
    dispatchEvent(me);

  @Override public void mousePressed(MouseEvent e) {
    dispatchEvent(e);
  }
  public void mouseReleased(MouseEvent me) {
    dispatchEvent(me);

  @Override public void mouseReleased(MouseEvent e) {
    dispatchEvent(e);
  }
}
}}

**解説 [#md0e801a]
JTabbedPaneのBorderにSwingUtilities.paintComponentメソッドを使ってJCheckBoxを描画しています。JCheckBoxがJTabbedPaneの子になってタブが増えないように、ダミーパネルを中間コンテナに指定しています。
* 解説 [#explanation]
- `JTabbedPane`の`Border`に`SwingUtilities.paintComponent(...)`メソッドを使って`JCheckBox`を描画
- `JCheckBox`が`JTabbedPane`の子になってタブが増えないように、別途レンダリング用パネルを作成して中間コンテナに指定
- `JTabbedPane`で受け取ったマウスイベントを`SwingUtilities.convertMouseEvent(...)`メソッドを利用し、チェックボックス用に座標などを変換してイベント転送
- タブとチェックボックスが重ならないようにフレームの最小サイズを設定
#code{{
frame.setMinimumSize(new Dimension(240, 80));
}}

JTabbedPaneで受け取ったマウスイベントを、SwingUtilities.convertMouseEvent メソッドを利用し、チェックボックス用に座標などを変換して送り出しています。
----
- レイアウトマネージャーを利用して同様のことを行う方法もある
-- [https://community.oracle.com/thread/1389350 Swing - Any layout suggestions for this?]
--- レイアウトマネージャーを自作するweebibさんの投稿 (reply 1)
--- `OverlayLayout`を利用するcamickrさんの投稿 (reply 2)

%%タブとチェックボックスが重ならないように、フレームの最小サイズを設定しています。%%
* 参考リンク [#reference]
- [[JTabbedPaneの余白に文字列を表示>Swing/TabbedPaneWithText]]
- [[JTabbedPaneの余白にJButtonを配置>Swing/TabbedPaneWithButton]]

**参考リンク [#ze3b3f0b]
-[[JTabbedPaneの余白に文字列を表示>Swing/TabbedPaneWithText]]

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