Swing/CloseableTabbedPane のバックアップ(No.14)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/CloseableTabbedPane へ行く。
- 1 (2014-07-21 (月) 03:51:17)
- 2 (2014-07-22 (火) 14:22:56)
- 3 (2014-08-27 (水) 21:05:08)
- 4 (2014-10-31 (金) 01:41:08)
- 5 (2015-11-21 (土) 02:41:11)
- 6 (2017-04-07 (金) 13:51:51)
- 7 (2017-05-23 (火) 14:17:05)
- 8 (2018-05-15 (火) 18:18:14)
- 9 (2020-05-10 (日) 02:32:33)
- 10 (2021-10-31 (日) 01:10:06)
- 11 (2025-01-03 (金) 08:57:02)
- 12 (2025-01-03 (金) 09:01:23)
- 13 (2025-01-03 (金) 09:02:38)
- 14 (2025-01-03 (金) 09:03:21)
- 15 (2025-01-03 (金) 09:04:02)
- category: swing folder: CloseableTabbedPane title: JTabbedPaneの各タブにJButtonを右寄せで追加する tags: [JTabbedPane, JButton, JLayer] author: aterai pubdate: 2014-07-21T03:51:17+09:00 description: JTabbedPaneのタブ上にそれを閉じるためのJButtonをJLayerを使用して右寄せで描画します。 image:
Summary
JTabbedPane
のタブ上にそれを閉じるためのJButton
をJLayer
を使用して右寄せで描画します。
Screenshot
Advertisement
Source Code Examples
class CloseableTabbedPaneLayerUI extends LayerUI<JTabbedPane> {
private final JComponent rubberStamp = new JPanel();
private final Point pt = new Point(-100, -100);
private final JButton button = new JButton(new CloseTabIcon());
public CloseableTabbedPaneLayerUI() {
super();
button.setBorder(BorderFactory.createEmptyBorder());
button.setFocusPainted(false);
button.setBorderPainted(false);
button.setContentAreaFilled(false);
button.setRolloverEnabled(false);
}
@Override public void paint(Graphics g, JComponent c) {
super.paint(g, c);
if (c instanceof JLayer) {
JLayer jlayer = (JLayer) c;
JTabbedPane tabPane = (JTabbedPane) jlayer.getView();
for (int i = 0; i < tabPane.getTabCount(); i++) {
Rectangle rect = tabPane.getBoundsAt(i);
Dimension d = button.getPreferredSize();
int x = rect.x + rect.width - d.width - 2;
int y = rect.y + (rect.height - d.height) / 2;
Rectangle r = new Rectangle(x, y, d.width, d.height);
button.getModel().setRollover(r.contains(pt));
SwingUtilities.paintComponent(g, button, rubberStamp, r);
}
}
}
@Override public void installUI(JComponent c) {
super.installUI(c);
if (c instanceof JLayer) {
((JLayer) c).setLayerEventMask(
AWTEvent.MOUSE_EVENT_MASK |AWTEvent.MOUSE_MOTION_EVENT_MASK);
}
}
@Override public void uninstallUI(JComponent c) {
if (c instanceof JLayer) {
((JLayer) c).setLayerEventMask(0);
}
super.uninstallUI(c);
}
@Override protected void processMouseEvent(
MouseEvent e, JLayer<? extends JTabbedPane> l) {
if (e.getID() == MouseEvent.MOUSE_CLICKED) {
pt.setLocation(e.getPoint());
JTabbedPane tabbedPane = (JTabbedPane) l.getView();
int index = tabbedPane.indexAtLocation(pt.x, pt.y);
if (index >= 0) {
Rectangle rect = tabbedPane.getBoundsAt(index);
Dimension d = button.getPreferredSize();
int x = rect.x + rect.width - d.width - 2;
int y = rect.y + (rect.height - d.height) / 2;
Rectangle r = new Rectangle(x, y, d.width, d.height);
if (r.contains(pt)) {
tabbedPane.removeTabAt(index);
}
}
}
}
@Override protected void processMouseMotionEvent(
MouseEvent e, JLayer<? extends JTabbedPane> l) {
pt.setLocation(e.getPoint());
JTabbedPane tabbedPane = (JTabbedPane) l.getView();
int index = tabbedPane.indexAtLocation(pt.x, pt.y);
if (index >= 0) {
Point loc = e.getPoint();
loc.translate(-16, -16);
l.repaint(new Rectangle(loc, new Dimension(32, 32)));
}
}
}
View in GitHub: Java, KotlinExplanation
- 上
- JTabbedPaneにタブを閉じるボタンを追加
- タブに追加したコンポーネントは中央揃えで配置される
BasicTabbedPaneUI
などのデフォルト
- 下
JLayer
を使用してタブの余白にそれを閉じるためのJButton
を描画TabbedPaneUI
をオーバーライドする必要がない- JTabbedPaneにタブを閉じるアイコンを追加では、
BasicTabbedPaneUI#createLayoutManager()
をオーバーライドして、独自のTabbedPaneLayout
で右端に☓アイコンを描画
- タブの余白は
UIManager.put("TabbedPane.tabInsets", new Insets(2, 18, 2, 18));
で設定- この余白設定は、
NimbusLookAndFeel
などでは無効 - 左右の余白の合計よりタブが短くなる場合、ボタンがタイトルに重なってしまう
- この余白設定は、
参考リンク
- java - Closeable JTabbedPane - alignment of the close button - Stack Overflow
- JTabbedPaneにタブを閉じるボタンを追加
- JTabbedPaneにタブを閉じるアイコンを追加