JTabbedPaneのタブエリアレイアウトを変更して一覧表示ボタンなどを追加する
Total: 1337
, Today: 2
, Yesterday: 3
Posted by aterai at
Last-modified:
概要
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 viewport = tabArea.getViewport();
Rectangle r = tab.getBounds();
if (viewport.getViewRect().contains(r)) {
return null;
}
JLabel label = (JLabel) tab.getComponent(0);
String title = label.getText();
JMenuItem mi = new JRadioButtonMenuItem(title);
mi.addActionListener(e -> {
tab.setSelected(true);
cardLayout.show(contentsPanel, title);
viewport.scrollRectToVisible(SwingUtilities.convertRectangle(c, r, viewport));
});
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
が開く