Swing/TableHeaderFiller のバックアップソース(No.4)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - 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 --- * 概要 [#summary] `JTableHeader`の列幅を自動調整しない場合に発生する余白にダミーのヘッダを描画します。 #download(https://drive.google.com/uc?id=1S2FqsLneoDTvkP2Xx-RLfsgLXGkFcduAaw) * サンプルコード [#sourcecode] #code(link){{ 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()); } } } }} * 解説 [#explanation] - 上: デフォルト -- `AUTO_RESIZE_OFF`を設定し、列幅の自動調整を無効にした`JTable` - 下: `TableHeaderFiller` -- `AUTO_RESIZE_OFF`を設定し列幅の自動調整を無効にした`JTable`で`JTableHeader`に余白が発生する場合、そこにダミーのヘッダ列を描画 -- ダミーヘッダの描画には`JLayer`を使用 -- `JLayer`は`JTable`や`JTableHeader`ではなく親の`JScrollPane`に設定 -- `JLayer`でダミーヘッダへの`MouseEvent`などは無効化、`JTableHeader`がリサイズされて`ComponentEvent`が発生した場合は`LayerUI#processComponentEvent(...)`をオーバーライドしてダミーヘッダの幅を更新 * 参考リンク [#reference] - [https://web.archive.org/web/20120126055437/http://l2fprod.com/blog/2008/08/30/the-fun-of-swing-jtable-column-resizing/ the fun of Swing JTable column resizing - blog@l2fprod.com(web.archive.org)] -- `JLayer`は使用せず、直接`JTableHeader`にリスナーなどを変更したダミーヘッダを追加する場合のサンプル * コメント [#comment] #comment #comment