TITLE:JTabbedPaneの余白にJCheckBoxを配置

Posted by aterai at 2006-04-03

JTabbedPaneの余白にJCheckBoxを配置

JTabbedPaneの余白にJCheckBoxを配置して特定のタブの開閉を行います。

  • &jnlp;
  • &jar;
  • &zip;
TabbedPaneWithCheckBox.png

サンプルコード

class TabbedPaneWithCompBorder implements Border, MouseListener, SwingConstants {
  private final JComponent  dummy = new JPanel();;
  private final JCheckBox   cbox;
  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());
      }
    });
  }
  public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
    Dimension size = cbox.getPreferredSize();
    int xx = tab.getSize().width - size.width;
    Rectangle lastTab = tab.getUI().getTabBounds(tab, 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);
  }
  public Insets getBorderInsets(Component c) {
    return new Insets(0,0,0,0);
  }
  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));
  }
  public void mouseClicked(MouseEvent me)  { dispatchEvent(me); }
  public void mouseEntered(MouseEvent me)  { dispatchEvent(me); }
  public void mouseExited(MouseEvent me)   { dispatchEvent(me); }
  public void mousePressed(MouseEvent me)  { dispatchEvent(me); }
  public void mouseReleased(MouseEvent me) { dispatchEvent(me); }
}

解説

JTabbedPaneのBorderにSwingUtilities.paintComponentメソッドを使ってJCheckBoxを描画しています。JCheckBoxがJTabbedPaneの子になってタブが増えないように、ダミーパネルを中間コンテナに指定しています。

JTabbedPaneで受け取ったマウスイベントを、SwingUtilities.convertMouseEvent メソッドを利用し、チェックボックス用に座標などを変換して送り出しています。


タブとチェックボックスが重ならないように、フレームの最小サイズを設定しています。

frame.setMinimumSize(new Dimension(240, 80));

他にも、レイアウトマネージャーを利用して同様のことを行う方法があります。

参考リンク

コメント