我有一个使用自定义RowSorter可排序列的JTable。我假设RowSorter类自动将自身作为MouseListener添加到表的ColumnHeader中,因为它无需执行任何自定义鼠标侦听代码即可自动执行排序。这很完美。
我还添加了一些代码(基于此示例),该代码允许用户通过双击列标题中的表之间的空间来调整表列的大小(模仿Excel的行为)。问题是,当用户双击标题以调整列的大小时,它也会对该列进行排序。 如果标题是单击的,我只希望对列进行排序。
我的第一种方法是使用Java接口代理替换JTable的所有现有MouseListener,拦截事件,并仅传递与单击相关的事件。不过,这似乎有些过分。有没有更好的办法?
我的第一种方法是使用Java接口代理替换JTable的所有现有MouseListener,拦截事件,并仅传递与单击相关的事件。
基本上就是这样工作的:
import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.*; public class ResizeColumnListener implements MouseListener { private static Cursor resizeCursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR); private MouseListener uiListener; private JTableHeader header; private TableColumnAdjuster tca; public ResizeColumnListener(JTable table) { header = table.getTableHeader(); tca = new TableColumnAdjuster( table ); MouseListener[] listeners = header.getMouseListeners(); for (MouseListener ml: listeners) { String className = ml.getClass().toString(); if (className.contains("BasicTableHeaderUI")) { uiListener = ml; header.removeMouseListener(ml); header.addMouseListener( this ); } } } @Override public void mouseClicked( MouseEvent e ) { if (header.getCursor() != resizeCursor) { uiListener.mouseClicked( e ); return; } // Handle the double click event to resize the column // Note: The last 3 pixels + 3 pixels of next column are for resizing, // so we need to adjust the mouse point to get the actual column. if (e.getClickCount() == 2) { Point p = e.getPoint(); p.x -= 3; int column = header.columnAtPoint( p ); tca.adjustColumn( column ); // Generate event to reset the cursor header.dispatchEvent(new MouseEvent( header, MouseEvent.MOUSE_MOVED, e.getWhen(), e.getModifiers(), e.getX(), e.getY(), 0, false)); } } @Override public void mouseEntered( MouseEvent e ) { uiListener.mouseEntered( e ); } @Override public void mouseExited( MouseEvent e ) { uiListener.mouseExited( e ); } @Override public void mousePressed( MouseEvent e ) { uiListener.mousePressed( e ); } @Override public void mouseReleased( MouseEvent e ) { uiListener.mouseReleased( e ); } public static void main(String[] args) { try { // UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { } DefaultTableModel model = new DefaultTableModel(5, 5); model.setValueAt("Row 0 : Column 0", 0, 0); model.setValueAt("Row 1 : Column 1", 1, 1); model.setValueAt("Row 2 : Column 2", 2, 2); model.setValueAt("Row 3 : Column 3", 3, 3); model.setValueAt("Row 4 : Column 4", 4, 4); JTable table = new JTable( model ); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); table.setAutoCreateRowSorter(true); JScrollPane scrollPane = new JScrollPane( table ); new ResizeColumnListener(table); JFrame frame = new JFrame(); frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); frame.add( scrollPane ); frame.setSize(400, 200); frame.setVisible(true); } }
此代码还使用“ 表列调整器”。