Swing/TableHeaderFiller のバックアップ(No.3)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/TableHeaderFiller へ行く。
- 1 (2019-03-11 (月) 15:15:00)
- 2 (2020-12-20 (日) 01:38:59)
- 3 (2023-05-16 (火) 16:50:29)
- 4 (2024-02-02 (金) 11:26:04)
- 5 (2024-03-01 (金) 15:53:20)
- category: swing folder: TableHeaderFiller title: JTableHeaderの余白にヘッダを描画する tags: [JTableHeader, JTable, JScrollPane, JLayer] author: aterai pubdate: 2019-03-11T15:07:56+09:00 description: JTableHeaderの列幅を自動調整しない場合に発生する余白にダミーのヘッダを描画します。 image: https://drive.google.com/uc?id=1S2FqsLneoDTvkP2Xx-RLfsgLXGkFcduAaw
概要
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
にリスナーなどを変更したダミーヘッダを追加する場合のサンプル