TITLE:JTabbedPaneの余白にJCheckBoxを配置

JTabbedPaneの余白にJCheckBoxを配置

編集者:Terai Atsuhiro~

作成日:2006-04-03
更新日:2024-02-02 (金) 12:19:10
  • 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

概要

JTabbedPaneの余白にJCheckBoxを配置して特定のタブの表示・非表示を切り替えます。

概要

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

サンプルコード

#spanend
#spanadd
class TabbedPaneWithCompBorder implements Border, MouseListener, SwingConstants {
#spanend
  private final JCheckBox checkBox;
  private final JTabbedPane tab;
  private final Container rubberStamp = new JPanel();
  private final Rectangle rect = new Rectangle();

#spandel
#screenshot
#spanend
  protected TabbedPaneWithCompBorder(JCheckBox checkBox, JTabbedPane tab) {
    this.checkBox = checkBox;
    this.tab = tab;
  }

#spandel
**サンプルコード [#hd0302da]
#spanend
  @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.getBoundsAt(tab.getTabCount() - 1);
    int tabEnd = lastTab.x + lastTab.width;
    if (xx < tabEnd) {
      xx = tabEnd;
    }
    rect.setBounds(xx, -2, size.width, size.height);
    SwingUtilities.paintComponent(g, checkBox, rubberStamp, rect);
  }
#spanadd

#spanend
  @Override public Insets getBorderInsets(Component c) {
    return new Insets(0, 0, 0, 0);
  }
#spanadd

#spanend
  @Override public boolean isBorderOpaque() {
    return true;
  }
#spanadd

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

#spanend
  @Override public void mouseClicked(MouseEvent e) {
    dispatchEvent(e);
  }
#spanadd

#spanend
  @Override public void mouseEntered(MouseEvent e) {
    dispatchEvent(e);
  }
#spanadd

#spanend
  @Override public void mouseExited(MouseEvent e) {
    dispatchEvent(e);
  }
#spanadd

#spanend
  @Override public void mousePressed(MouseEvent e) {
    dispatchEvent(e);
  }
#spanadd

#spanend
  @Override public void mouseReleased(MouseEvent e) {
    dispatchEvent(e);
  }
#spanadd
}
#spanend
#spanadd
View in GitHub: Java, Kotlin

解説

  • JTabbedPaneBorderSwingUtilities.paintComponent(...)メソッドを使ってJCheckBoxを描画
  • JCheckBoxJTabbedPaneの子になってタブが増えないように、別途レンダリング用パネルを作成して中間コンテナに指定
  • JTabbedPaneで受け取ったマウスイベントをSwingUtilities.convertMouseEvent(...)メソッドを利用し、チェックボックス用に座標などを変換してイベント転送
  • タブとチェックボックスが重ならないようにフレームの最小サイズを設定
     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;
         Point pt = me.getPoint();
         pt.translate(0, 0);
         cbox.setBounds(rect);
         cbox.dispatchEvent(new MouseEvent(
           cbox, me.getID(), me.getWhen(), me.getModifiers(),
           pt.x, pt.y, me.getClickCount(), me.isPopupTrigger(), me.getButton()));
       }
       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);
       }
     }
    #spanadd
    frame.setMinimumSize(new Dimension(240, 80));
    #spanend
    
  • &jnlp;
  • &jar;
  • &zip;

解説

JTabbedPaneのBorderにSwingUtilities.paintComponentメソッドを使ってJCheckBoxを描画しています。JCheckBoxのイベントが伝播しないようにダミーパネルを中間コンテナに指定しています。
  • -
  • レイアウトマネージャーを利用して同様のことを行う方法もある
タブとチェックボックスが重ならないように、フレームの最小サイズを設定しています。

参考リンク

参考リンク

コメント

コメント