Swing/RowHeaderStyle のバックアップ(No.10)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/RowHeaderStyle へ行く。
- 1 (2012-11-05 (月) 14:47:06)
- 2 (2012-12-07 (金) 16:35:30)
- 3 (2012-12-25 (火) 18:12:21)
- 4 (2012-12-26 (水) 11:23:42)
- 5 (2013-01-28 (月) 02:12:56)
- 6 (2013-01-29 (火) 23:37:36)
- 7 (2014-06-06 (金) 18:37:18)
- 8 (2014-10-30 (木) 00:09:02)
- 9 (2015-02-22 (日) 21:03:18)
- 10 (2016-01-13 (水) 13:32:47)
- 11 (2017-06-28 (水) 17:27:41)
- 12 (2018-06-29 (金) 14:20:39)
- 13 (2020-06-11 (木) 22:59:13)
- 14 (2021-11-30 (火) 07:15:03)
- title: JTableの行ヘッダに列ヘッダのRendererを使用する tags: [JTable, JTableHeader, TableCellRenderer, Icon] author: aterai pubdate: 2012-11-05T14:47:06+09:00 description: JTableの行の描画に、JTableHeaderから取得した列ヘッダのRendererを適用します。
概要
JTable
の行の描画に、JTableHeader
から取得した列ヘッダのRenderer
を適用します。
Screenshot
Advertisement
サンプルコード
class RowHeaderRenderer extends JLabel implements TableCellRenderer {
private int rollOverRowIndex = -1;
public RowHeaderRenderer(JTable table) {
super();
RollOverListener rol = new RollOverListener();
table.addMouseListener(rol);
table.addMouseMotionListener(rol);
}
@Override public Component getTableCellRendererComponent(
JTable tbl, Object val, boolean isS, boolean hasF, int row, int col) {
TableCellRenderer tcr = tbl.getTableHeader().getDefaultRenderer();
boolean f = row == rollOverRowIndex;
JLabel l = (JLabel) tcr.getTableCellRendererComponent(
tbl, val, isS, f ? f : hasF, -1, -1);
if (tcr.getClass().getName().indexOf("XPDefaultRenderer") >= 0) {
l.setOpaque(!f);
this.setIcon(new ComponentIcon(l));
return this;
} else {
return l;
}
}
class RollOverListener extends MouseAdapter {
@Override public void mouseMoved(MouseEvent e) {
JTable table = (JTable) e.getComponent();
Point pt = e.getPoint();
int col = table.columnAtPoint(pt);
int column = table.convertColumnIndexToModel(col);
if (column != 0) {
return;
}
int prevRow = rollOverRowIndex;
rollOverRowIndex = table.rowAtPoint(pt);
if (rollOverRowIndex == prevRow) {
return;
}
Rectangle repaintRect;
if (rollOverRowIndex >= 0) {
Rectangle r = table.getCellRect(rollOverRowIndex, col, false);
if (prevRow >= 0) {
repaintRect = r.union(table.getCellRect(prevRow, col, false));
} else {
repaintRect = r;
}
} else {
repaintRect = table.getCellRect(prevRow, col, false);
}
table.repaint(repaintRect);
}
@Override public void mouseExited(MouseEvent e) {
JTable table = (JTable) e.getComponent();
Point pt = e.getPoint();
int col = table.columnAtPoint(pt);
int column = table.convertColumnIndexToModel(col);
if (column != 0) {
return;
}
if (rollOverRowIndex >= 0) {
table.repaint(table.getCellRect(rollOverRowIndex, col, false));
}
rollOverRowIndex = -1;
}
}
}
class ComponentIcon implements Icon {
private final JComponent cmp;
public ComponentIcon(JComponent cmp) {
this.cmp = cmp;
}
@Override public int getIconWidth() {
return 4000; //Short.MAX_VALUE;
}
@Override public int getIconHeight() {
return cmp.getPreferredSize().height + 4; //XXX: +4 for Windows 7
}
@Override public void paintIcon(Component c, Graphics g, int x, int y) {
SwingUtilities.paintComponent(
g, cmp, (Container) c, x, y, getIconWidth(), getIconHeight());
}
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、0
列目のセルの描画に、JTable#getTableHeader()#getDefaultRenderer()
で取得したレンダラーを使用するTableCellRenderer
を適用しています。
- ソートアイコンが列ヘッダに表示されていても、行ヘッダには表示しない
- 引数の行と列を両方
-1
にして、TableCellRenderer#getTableCellRendererComponent(...)
で描画用コンポーネント(JLabel
)をヘッダレンダラーから取得
- 引数の行と列を両方
WindowsLookAndFeel
- ロールオーバーを描画する場合は、
TableCellRenderer#getTableCellRendererComponent(...)
で取得したコンポーネントを透明にする - 右と下側に余白が発生するので、ヘッダレンダラーからサイズを変更したアイコンを作成して、
JLabel#setIcon(Icon)
で表示
- ロールオーバーを描画する場合は、