---
category: swing
folder: TableCellBorderHoverEffects
title: JTableのセルBorderをホバー効果でハイライトする
tags: [JTable, MouseMotionListener, RadialGradientPaint, Calendar]
author: aterai
pubdate: 2025-05-12T02:47:51+09:00
description: JTableのセルにすき間を設定し、マウスポインタ周辺のすき間のみを描画することでセルの縁を強調表示します。
image: https://drive.google.com/uc?id=1nUJ8fMADXR9DEfEXEw2fa6GzqwRnAjfL
---
* Summary [#summary]
`JTable`のセルにすき間を設定し、マウスポインタ周辺のすき間のみを描画することでセルの縁を強調表示します。
#download(https://drive.google.com/uc?id=1nUJ8fMADXR9DEfEXEw2fa6GzqwRnAjfL)
* Source Code Examples [#sourcecode]
#code(link){{
private final class MonthTable extends JTable {
private final Point pt = new Point(-1000, -1000);
private transient MouseAdapter listener;
@Override public void updateUI() {
removeMouseListener(listener);
removeMouseMotionListener(listener);
super.updateUI();
setFillsViewportHeight(true);
setOpaque(false);
setShowGrid(false);
setIntercellSpacing(new Dimension(2, 2));
setFont(getFont().deriveFont(Font.BOLD));
setDefaultRenderer(LocalDate.class, new CalendarTableRenderer());
JTableHeader header = getTableHeader();
TableCellRenderer r = new CenterAlignmentHeaderRenderer();
TableColumnModel cm = getColumnModel();
EventQueue.invokeLater(() -> {
for (int i = 0; i < cm.getColumnCount(); i++) {
cm.getColumn(i).setHeaderRenderer(r);
}
});
header.setResizingAllowed(false);
header.setReorderingAllowed(false);
listener = new SpotlightListener();
addMouseListener(listener);
addMouseMotionListener(listener);
}
@Override protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setComposite(AlphaComposite.Src);
Point2D center = new Point2D.Float(pt.x, pt.y);
float[] dist = {0.0f, 0.5f, 1.0f};
Color[] colors = {Color.GRAY, Color.LIGHT_GRAY, Color.WHITE};
Rectangle cr = getCellRect(0, 0, true);
int r = Math.max(cr.width, cr.height) * 2;
g2.setPaint(new RadialGradientPaint(center, r, dist, colors));
int r2 = r + r;
g2.fill(new Ellipse2D.Float(pt.x - r, pt.y - r, r2, r2));
g2.dispose();
super.paintComponent(g);
}
private final class SpotlightListener extends MouseAdapter {
@Override public void mouseExited(MouseEvent e) {
pt.setLocation(-1000, -1000);
repaint();
}
@Override public void mouseEntered(MouseEvent e) {
update(e);
}
@Override public void mouseDragged(MouseEvent e) {
update(e);
}
@Override public void mouseMoved(MouseEvent e) {
update(e);
}
private void update(MouseEvent e) {
pt.setLocation(e.getPoint());
Rectangle cr = getCellRect(0, 0, true);
int r = Math.max(cr.width, cr.height) * 2;
int r2 = r + r;
repaint(new Rectangle(pt.x - r, pt.y - r, r2, r2));
}
}
// ...
}
}}
* Description [#description]
- `JTable#setShowGrid(false)`で水平・垂直グリッド線を非表示に設定
- `JTable#setIntercellSpacing(new Dimension(2, 2))`で各セルに縦横`2px`のすき間を設定
-- `JTable#setOpaque(false)`で`JTable`の背景を描画しないよう設定
- `JTable`に`MouseListener`と`MouseMotionListener`を追加してマウスポインタの座標を取得可能に設定し、マウスポインタの座標が変化したらその周辺を`JTable#repaint(Rectangle)`で再描画
- `JTable#paintComponent(...)`をオーバーライドしてマウスポインタの座標を中心とした`Ellipse2D`図形を作成し、その内部を`RadialGradientPaint`で塗りつぶす
-- 上記の塗りつぶしの後で`super.paintComponent(g)`を実行して`JTable`のセルなどを描画するが、`JTable#setIntercellSpacing(new Dimension(2, 2))`で設定したセル間のすき間はなに上書きされないのでセル`Border`がホバー効果風にハイライト表示される
-- 上記の塗りつぶしの後で`super.paintComponent(g)`を実行して`JTable`のセルなどを描画するが、`JTable#setIntercellSpacing(new Dimension(2, 2))`で設定したセル間のすき間は先に描画したグラデーション図形がそのまま残るのでセル`Border`がホバー効果風にハイライト表示になる
* Reference [#reference]
- [[JButtonのホバーエフェクトを円放射状グラデーションで表現する>Swing/RadialGradientButton]]
- [[JTableのセルを斜めに分割する>Swing/DiagonallySplitCellCalendar]]
- [[JTableのグリッド線描画をUIDefaultsから復元する>Swing/TableShowGrid]]
* Comment [#comment]
#comment
#comment