首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

JTable 單元格滑鼠懸停效果實現:從 Renderer 到 Table 級監聽的轉折

     編輯:Java 相關知識

初衷:想在 Renderer 內加 MouseListener

自訂 NoteLabelRenderer extends JPanel implements TableCellRenderer,內含三個 JLabel (Icon/Content/Attach)。點選狀態 (isSelected) 好處理,但滑鼠懸停 (rollover) 在 Renderer 加 MouseMotionListener 無效 —— Renderer 只是「橡皮圖章」,不佔據真實組件幾何位置。

轉折:JTable 自帶 rowAtPoint(Point)

發現 JTable 有 rowAtPoint 可直接獲取滑鼠下的行號。於是在 JTable 子類掛 MouseMotionListener:

private int mouseAtRow = -1;
private Vector flagMouseOver = new Vector<>(); // 標記每行是否滑鼠懸停

public void mouseMoved(MouseEvent e) {
    int row = rowAtPoint(e.getPoint());
    if (row == -1) return; // 滑鼠不在表格內

    if (mouseAtRow == -1) { // 首次進入
        flagMouseOver.set(row, Boolean.TRUE);
        mouseAtRow = row;
    } else if (row != mouseAtRow) { // 移動到新行
        flagMouseOver.set(mouseAtRow, Boolean.FALSE);
        flagMouseOver.set(row, Boolean.TRUE);
        mouseAtRow = row;
    } else return; // 同行無變化

    repaint(); revalidate(); // 觸發重繪
}

關鍵:重寫 prepareRenderer 注入懸停邊框

public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
    Component comp = super.prepareRenderer(renderer, row, column);
    if (Boolean.TRUE.equals(flagMouseOver.get(row))) {
        ((JComponent) comp).setBorder(BorderFactory.createLineBorder(Color.GRAY, 1));
    } else {
        ((JComponent) comp).setBorder(null);
    }
    return comp;
}

prepareRenderer 是 JTable 繪製前準備組件的公共方法,攔截它即可在不修改 Renderer 邏輯下注入懸停樣式 (邊框/背景色均可)。

總結

Renderer 只負責「長什麼樣」,Table 負責「什麼時候長什麼樣」。懸停屬於 Table 級幾何狀態,應在 Table 層處理,配合 prepareRenderer 橋接渲染,乾淨解耦。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved