首页 > 代码库 > 使用鼠标监听器,使鼠标悬停在JTable某行时背景色改变

使用鼠标监听器,使鼠标悬停在JTable某行时背景色改变

一、需要知道的事实:

1、当鼠标悬停在JTable上时,相应的格子(cell)的渲染器(TableCellRenderer)的渲染方法(getTableCellRenererComponent)会被调用,但不够及时(这一点可以通过在渲染方法里打印一句话来自行测试),

而且只是鼠标覆盖的格子的渲染方法会被调用,与其同一行的其他格子的渲染方法并未被调用。所以,指望只通过修改渲染器就能达到目的是不可能的了。

2、JTable的所有监听器都在TableUI(默认使用的是BasicTableUI)中定义,从BasicTableUI源代码中可以发现,关于鼠标的监听器,只有MouseInputListener,并不支持对鼠标悬停事件的监听。所以,如果你

重写TableUI,给JTable添加鼠标悬停行为事件监听器应该也可达到目的,但本文不讨论这种实现方式。

二、总体思路:

能不能不重写TableUI,用一个最直接的鼠标监听器达到目的?

首先自定义TableCellRenderer,通过JTable对象获取当前鼠标所在行的行号,在渲染方法里根据行号修改背景颜色。

然后给JTable添加一个鼠标行为监听器(MouseMotionListener),当监听到JTable的某行上有鼠标悬停时,触发JTable的prepareRenderer方法,促使JTable相应行中的格子进行渲染。然后调用JTable的repaint。

三、代码片断

// 为了简便,直接在构造JTable时把渲染器里的处理写在其中了,正常的做法是不需要修改JTable代码,在自定义的TableCellRenderer中写这些逻辑。

JTable table = new JTable(model){

    @override

    public Component prepareRenderer(TableCellRenderer renderer, int row, int column){

        Component comp = super.prepareRenderer(renderer,row,column);

        Point p = getMousePosition();

        if(p!=null){

            int rowUnderMouse = rowAtPoint(p);

            if(rowUnderMouse = row){

                  comp.setBackground(Color.red);

           }else{

                  comp.setBackGround(DefaultLookup.getColor(this,ui,"Table.alternateRowColor"));

           }

        }

        return comp;

    }

}

class MyTableMouseMotionListener extends MouseMotionAdapter{

        private int rowUnderMouse = -1;

 

        @override

        public void mouseMoved(MouseEvent e){

             JTable table = (JTable)e.getSource();

             Point p = table.getMousePosition();

             if(p != null){

                  rowUnderMouse = table.rowAtPoint(p);

                  if(rowUnderMouse >= 0){

                          for(int i=0;i<table.getColumnCount();i++){

                                 table.prepareRenderer(table.getCellRenderer(rowUnderMouse,i),rowUnderMouse,i);

                                 if(rowUnderMouse != 0){

                                       table.prepareRenderer(table.getCellRenderer(rowUnderMouse-1,i),rowUnderMouse-1,i);

                                 }

                                 if(rowUnderMouse != table.getRowCount()-1){

                                       table.prepareRenderer(table.getCellRenderer(rowUnderMouse+1,i),rowUnderMouse+1,i);

                                 }

                          }

                          table.repaint(table.getVisibleRect());

                  }

             }

        }

}

 

最后,table.addMouseMotionListener(new MyTableMouseMotionListener());

使用鼠标监听器,使鼠标悬停在JTable某行时背景色改变