我有一个JTable,它使用自定义RowSorter具有可排序的列。我假设RowSorter类会自动将自己作为MouseListener添加到表的ColumnHeader中,因为它会自动执行排序,而无需我添加任何自定义鼠标监听代码。这非常完美。
我还添加了一些代码(基于此示例),允许用户通过双击列标题中它们之间的空格来调整表格列的大小(模仿Excel的行为)。问题是,当用户双击标题以调整列大小时,它也会对该列进行排序。我想只在单击标题时对列进行排序。
我的第一个方法是使用Java接口Proxy来替换JTable的所有现有MouseListeners,拦截事件,并且只传递与单次点击相关的事件。不过,这似乎有些过分。有没有更好的方法?
我的第一种方法是使用Java接口代理来替换JTable的所有现有MouseListeners,拦截事件,并且只传递与单次点击相关的事件。
这基本上就是它的工作原理:
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);
}
}
此代码还使用表列调整器。