JTableHeaderの余白にヘッダを描画する
Total: 2024
, Today: 3
, Yesterday: 1
Posted by aterai at
Last-modified:
概要
JTableHeader
の列幅を自動調整しない場合に発生する余白に疑似ヘッダを描画します。
Screenshot
Advertisement
サンプルコード
class TableHeaderFillerLayerUI extends LayerUI<JScrollPane> {
private final JTable tempTable = new JTable(
new DefaultTableModel(new Object[] {""}, 0));
private final JTableHeader filler = tempTable.getTableHeader();
private final TableColumn fillerColumn = tempTable
.getColumnModel().getColumn(0);
@Override public void paint(Graphics g, JComponent c) {
super.paint(g, c);
if (c instanceof JLayer) {
JScrollPane scroll = (JScrollPane) ((JLayer<?>) c).getView();
JTable table = (JTable) scroll.getViewport().getView();
JTableHeader header = table.getTableHeader();
int width = header.getWidth();
TableColumnModel cm = header.getColumnModel();
for (int i = 0; i < cm.getColumnCount(); i++) {
width -= cm.getColumn(i).getWidth();
}
Point pt = SwingUtilities.convertPoint(header, 0, 0, c);
filler.setLocation(pt.x + header.getWidth() - width, pt.y);
filler.setSize(width, header.getHeight());
fillerColumn.setWidth(width);
SwingUtilities.paintComponent(g, filler, tempTable, filler.getBounds());
}
}
@Override public void installUI(JComponent c) {
super.installUI(c);
if (c instanceof JLayer) {
((JLayer<?>) c).setLayerEventMask(AWTEvent.COMPONENT_EVENT_MASK);
}
}
@Override public void uninstallUI(JComponent c) {
if (c instanceof JLayer) {
((JLayer<?>) c).setLayerEventMask(0);
}
super.uninstallUI(c);
}
@Override protected void processComponentEvent(
ComponentEvent e, JLayer<? extends JScrollPane> l) {
Component c = e.getComponent();
if (c instanceof JTableHeader) {
l.repaint(((JTableHeader) c).getBounds());
}
}
}
View in GitHub: Java, Kotlin解説
- 上: デフォルト
- 列幅の自動調整を
AUTO_RESIZE_OFF
で無効にしたJTable
- 列幅の自動調整を
- 下:
TableHeaderFiller
AUTO_RESIZE_OFF
を設定し列幅の自動調整を無効にしたJTable
でJTableHeader
に余白が発生する場合、そこに疑似ヘッダ列を描画- 疑似ヘッダの描画には
JLayer
を使用 JLayer
はJTable
やJTableHeader
ではなく親のJScrollPane
に設定JLayer
で疑似ヘッダへのMouseEvent
などは無効化、JTableHeader
がリサイズされてComponentEvent
が発生した場合はLayerUI#processComponentEvent(...)
をオーバーライドして疑似ヘッダの幅を更新
参考リンク
- the fun of Swing JTable column resizing - blog@l2fprod.com(web.archive.org)
JLayer
を使用せず直接JTableHeader
にリスナーなどを変更した疑似ヘッダを追加する場合のサンプル