Swing/AutoResizeTableHeader のバックアップ(No.1)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/AutoResizeTableHeader へ行く。
- 1 (2025-12-01 (月) 00:05:40)
- category: swing folder: AutoResizeTableHeader title: JTableHeaderと各行の高さを親JScrollPaneが埋まるまで均等に自動調整 title-en: Auto adjusts the heights of JTableHeader and rows evenly to fill the parent JScrollPane tags: [JTable, JTableHeader, JScrollPane, Calendar] author: aterai pubdate: 2025-12-01T00:16:26+09:00 description: JTableHeaderとJTableの行の高さの合計が親JScrollPaneの高さまを埋めるまで均等に自動拡大・縮小します。 summary-jp: JTableHeaderとJTableの行の高さの合計が親JScrollPaneの高さまを埋めるまで均等に自動拡大・縮小します。 summary-en: Automatically resize the JTableHeader and JTable rows evenly to fill the height of the parent JScrollPane. image: https://drive.google.com/uc?id=1sN5ERINi9nhOhb5s5MmYFxwPfFLXt8fs
Summary
JTableHeaderとJTableの行の高さの合計が親JScrollPaneの高さを埋めるまで均等に自動拡大・縮小します。
Screenshot

Advertisement
Source Code Examples
class MonthTable extends JTable {
@Override protected JTableHeader createDefaultTableHeader() {
return new JTableHeader(columnModel) {
@Override public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
JTable tbl = getTable();
Container c = SwingUtilities.getAncestorOfClass(JScrollPane.class, tbl);
if (c instanceof JScrollPane) {
int rowCount = tbl.getModel().getRowCount() + 1;
Rectangle r = SwingUtilities.calculateInnerArea((JScrollPane) c, null);
d.height = Math.max(r.height / rowCount, 24);
}
return d;
}
};
}
@Override public void doLayout() {
super.doLayout();
Class<JViewport> clz = JViewport.class;
Optional.ofNullable(SwingUtilities.getAncestorOfClass(clz, this))
.filter(clz::isInstance).map(clz::cast)
.ifPresent(this::updateRowsHeight);
}
private void updateRowsHeight(JViewport viewport) {
int height = viewport.getExtentSize().height;
int rowCount = getModel().getRowCount();
int defaultRowHeight = height / rowCount;
int remainder = height % rowCount;
for (int i = 0; i < rowCount; i++) {
int a = defaultRowHeight + Math.min(1, Math.max(0, remainder--));
setRowHeight(i, Math.max(1, a));
}
}
// ...
}
View in GitHub: Java, KotlinDescription
JScrollPaneの高さが変更された場合、JScrollPane#doLayout()内でScrollPaneLayout#layoutContainer(...)が呼ばれ、JTableHeader#getPreferredSize()でヘッダのサイズを取得し、その高さや存在すればスクロールバーの高さなどを除去してJViewportの高さが決まる- このため、このサンプルでは
JTableHeader#getPreferredSize()をオーバーライドしてJTableHeaderの高さをJScrollPaneの高さの1/6になるよう設定- 上記の分母
6はJTableが5行とJTableHeaderが1個の合計 - JTableHeaderの高さを変更
- 上記の分母
JTableの各行の高さはJTable#doLayout()をオーバーライドしてJViewportの高さを満たすよう調整- 以下のように
JScrollPane#doLayout()をオーバーライドしてJViewportの高さを決めるまえにJTableHeaderの高さを調整する方法もある
class MonthScrollPane extends JScrollPane {
protected MonthScrollPane(Component view) {
super(view);
}
@Override public void updateUI() {
super.updateUI();
setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_NEVER);
}
@Override public void doLayout() {
JTable tbl = (JTable) getViewport().getView();
int rowCount = tbl.getModel().getRowCount() + 1;
JTableHeader header = tbl.getTableHeader();
Dimension d = header.getPreferredSize();
Rectangle r = SwingUtilities.calculateInnerArea(this, null);
d.height = Math.max(r.height / rowCount, 24);
header.setPreferredSize(d);
super.doLayout();
}
}
Reference
- JTableHeaderの高さを変更
- JTableの行高がJViewportの高さに合うまで調整する
- JTableHeaderのヘッダカラムセルの背景色を変更
- カレンダー部分は上記のリンク先のサンプルを流用