Swing/TabAreaLayout のバックアップ(No.1)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/TabAreaLayout へ行く。
- 1 (2022-01-10 (月) 02:50:11)
- 2 (2022-01-10 (月) 08:04:34)
- category: swing folder: TabAreaLayout title: JTabbedPaneのタブエリアレイアウトを変更して一覧表示ボタンなどを追加する tags: [JTabbedPane, CardLayout, OverlayLayout, FlowLayout, JPopupMenu] author: aterai pubdate: 2022-01-10T02:47:34+09:00 description: JTabbedPaneのタブエリアレイアウトを変更して余白や右端にタブの一覧表示ボタンなどを追加します。 image: https://drive.google.com/uc?id=1J3-SXZfSQEEuctw_T-zb8dsSiSDeoIeJ
概要
JTabbedPaneのタブエリアレイアウトを変更して余白や右端にタブの一覧表示ボタンなどを追加します。
Screenshot
Advertisement
サンプルコード
protected CardLayoutTabbedPane() {
super(new BorderLayout());
setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
setBackground(new Color(16, 16, 16));
tabPanel.setInheritsPopupMenu(true);
hiddenTabs.addActionListener(e -> {
JButton b = (JButton) e.getSource();
Point p = b.getLocation();
JPopupMenu popup = new JPopupMenu();
for (int i = 0; i < tabPanel.getComponentCount(); i++) {
JMenuItem mi = makeRadioMenuItem(tabPanel, i);
if (mi != null) {
popup.add(mi);
}
}
p.x += b.getWidth() - popup.getPreferredSize().width - 1;
p.y += b.getHeight();
popup.show(b.getParent(), p.x, p.y);
});
JPanel buttons = new JPanel(new GridBagLayout());
buttons.add(hiddenTabs);
JPanel header = new JPanel(new BorderLayout());
header.add(new JLayer<>(tabArea, new HorizontalScrollLayerUI()));
header.add(buttons, BorderLayout.EAST);
add(header, BorderLayout.NORTH);
add(contentsPanel);
}
private JMenuItem makeRadioMenuItem(Container c, int i) {
JToggleButton tab = (JToggleButton) c.getComponent(i);
JViewport vp = (JViewport) SwingUtilities.getAncestorOfClass(JViewport.class, c);
Rectangle rect = SwingUtilities.convertRectangle(c, tab.getBounds(), vp);
if (vp.getBounds().contains(rect)) {
return null;
}
JLabel l = (JLabel) tab.getComponent(0);
String title = l.getText();
JMenuItem mi = new JRadioButtonMenuItem(title);
mi.addActionListener(e -> {
tab.setSelected(true);
cardLayout.show(contentsPanel, title);
tab.scrollRectToVisible(rect);
});
return mi;
}
View in GitHub: Java, Kotlin解説
- 上:
JTabbedPane
+Box
+OverlayLayout
- タブエリアの右端に余白を設定した
JTabbedPane
と、右端にJButton
を配置した透明なBox
をOverlayLayout
で同じサイズで重ねて表示- JTabbedPaneの余白にJButtonを配置の余白と配置を右端に変更
- 右端に追加した
JButton
をクリックするとタブ選択状態を変更可能なJPopupMenu
が開く JTabbedPane
のタブレイアウトポリシーがSCROLL_TAB_LAYOUT
の場合、UIManager.put("TabbedPane.tabAreaInsets", new Insets(...))
などで設定した余白はスクロールボタンなどで無視される仕様?ため、このサンプルのポップアップボタンと重なってしまうSCROLL_TAB_LAYOUT
で使用する場合はこの仕様を回避するよりBox
を不透明にして各タブを表示するJScrollPane
を追加するほうが簡単かもしれない
- タブエリアの右端に余白を設定した
- 下:
JPanel
+CardLayout
+JScrollPane
+FlowLayout
+BorderLayout
CardLayout
でJTabbedPane
風のコンポーネントを作成し、そのタブエリアの中央にJScrollPane
と右端にJButton
を追加- 右端に追加した
JButton
をクリックするとJViewport
外のタブを選択しscrollRectToVisible(...)
メソッドを実行してスクロール表示可能なJPopupMenu
が開く