JTableHeaderで作成したタブエリアでCardLayoutのコンテナを切り替える
Total: 3854
, Today: 1
, Yesterday: 0
Posted by aterai at
Last-modified:
概要
JTableHeader
をタブエリアとして使用し、TableColumn
をクリックするとCardLayout
のコンテナが切り替わるようにマウスリスナーを設定します。
Screenshot
Advertisement
サンプルコード
class TableHeaderTabbedPane extends JPanel {
protected final CardLayout cardLayout = new CardLayout();
protected final JPanel tabPanel = new JPanel(new GridLayout(1, 0, 0, 0));
protected final JPanel contentsPanel = new JPanel(cardLayout);
protected final TableColumnModel model;
private final JTableHeader header;
private Object selectedColumn;
private int rolloverColumn = -1;
public TableHeaderTabbedPane() {
super(new BorderLayout());
int left = 1;
int right = 3;
tabPanel.setBorder(BorderFactory.createEmptyBorder(1, left, 0, right));
contentsPanel.setBorder(BorderFactory.createEmptyBorder(4, left, 2, right));
JTable table = new JTable(new DefaultTableModel(null, new String[] {}));
// table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
header = table.getTableHeader();
model = (TableColumnModel) header.getColumnModel();
MouseAdapter handler = new MouseInputHandler();
header.addMouseListener(handler);
header.addMouseMotionListener(handler);
final TabButton l = new TabButton();
header.setDefaultRenderer(new TableCellRenderer() {
@Override public Component getTableCellRendererComponent(
JTable tbl, Object val, boolean isS, boolean hasF, int row, int col) {
l.setText((String) val);
l.setSelected(Objects.equals(val, selectedColumn)
|| Objects.equals(col, rolloverColumn));
return l;
}
});
JScrollPane sp = new JScrollPane();
JViewport vp = new JViewport() {
@Override public Dimension getPreferredSize() {
return new Dimension();
}
};
vp.setView(table);
sp.setViewport(vp);
// JPanel wrapPanel = new JPanel(new BorderLayout(0, 0));
// wrapPanel.add(sp);
// add(wrapPanel, BorderLayout.NORTH);
add(sp, BorderLayout.NORTH);
add(contentsPanel);
}
public void addTab(final String title, final Component comp) {
contentsPanel.add(comp, title);
TableColumn tc = new TableColumn(
model.getColumnCount(), 75, header.getDefaultRenderer(), null);
tc.setHeaderValue(title);
model.addColumn(tc);
if (Objects.isNull(selectedColumn)) {
cardLayout.show(contentsPanel, title);
selectedColumn = title;
}
}
private class MouseInputHandler extends MouseAdapter {
@Override public void mousePressed(MouseEvent e) {
JTableHeader header = (JTableHeader) e.getComponent();
int index = header.columnAtPoint(e.getPoint());
if (index < 0) {
return;
}
Object title = model.getColumn(index).getHeaderValue();
cardLayout.show(contentsPanel, (String) title);
selectedColumn = title;
}
@Override public void mouseEntered(MouseEvent e) {
updateRolloverColumn(e);
}
@Override public void mouseMoved(MouseEvent e) {
updateRolloverColumn(e);
}
@Override public void mouseDragged(MouseEvent e) {
rolloverColumn = -1;
updateRolloverColumn(e);
}
@Override public void mouseExited(MouseEvent e) {
// int oldRolloverColumn = rolloverColumn;
rolloverColumn = -1;
}
// @see BasicTableHeaderUI.MouseInputHandler
private void updateRolloverColumn(MouseEvent e) {
if (Objects.isNull(header.getDraggedColumn())
&& header.contains(e.getPoint())) {
int col = header.columnAtPoint(e.getPoint());
if (col != rolloverColumn) {
// int oldRolloverColumn = rolloverColumn;
rolloverColumn = col;
// rolloverColumnUpdated(oldRolloverColumn, rolloverColumn);
}
}
}
}
}
View in GitHub: Java, Kotlin解説
このサンプルでは、CardLayout
とJTableHeader
を使用してコンテナの切り替えを実行するJTabbedPane
風のコンポーネントを作成しています。
JTableHeader
は空のJTable
を作成してそこから取得new JTableHeader(TableColumnModel cm)
より簡単なため
JScrollPane
にサイズ0
のJViewport
を設定し上記のJTable
を追加- 直接
JTableHeader
を追加するとうまくリサイズできない?
- 直接
JTableHeader
にMouseListener
を追加し、TableColumn
(タブとして代用)がクリックされるとそのタイトル文字列を引数にしてCardLayout#show(...)
を実行してコンテナの切り替えを行うJTableHeader
デフォルト機能であるドラッグ&ドロップによる入れ替えやヘッダ(タブ)幅のリサイズが利用可能