防止JTable在双击时自动排序 [英] Prevent JTable from Auto-Sorting on Double Click
问题描述
我有一个JTable,它具有使用自定义RowSorter进行排序的列.我假设RowSorter类自动将自身作为MouseListener添加到表的ColumnHeader中,因为它无需添加任何自定义的鼠标侦听代码即可自动执行排序.效果很好.
I have a JTable that has sortable columns using a custom RowSorter. I assume the RowSorter class automatically adds itself as a MouseListener to the table's ColumnHeader, because it automatically performs the sort without my having added any custom mouse listening code. This works perfectly.
我还添加了一些代码(基于此代码示例),从而允许用户通过在列标题中双击表列之间的空间来调整表列的大小(模仿Excel的行为).问题是,当用户双击标题以调整列的大小时,它也会对该列进行排序. 我只希望单击标题即可对列进行排序.
I also added some code (based off of this example) that allows the user to resize the table columns by double-clicking on the space between them in the column header (mimicking that behavior of Excel). The issue is that when a user double-clicks the header to resize a column, it also sorts that column. I want to only have the columns sort if the header is single-clicked.
我的第一种方法是使用Java接口代理来替换JTable的所有现有MouseListener,拦截事件,并仅传递与单击相关的事件.不过,这似乎有些过头了.有更好的方法吗?
My first approach was to use Java interface Proxy's to replace all of the existing MouseListeners of the JTable, intercept the events, and only pass on events related to single clicks. This seems like overkill, though. Is there a better way?
推荐答案
我的第一种方法是使用Java接口代理来替换JTable的所有现有MouseListener,拦截事件,并仅传递与单击相关的事件.
My first approach was to use Java interface Proxy's to replace all of the existing MouseListeners of the JTable, intercept the events, and only pass on events related to single clicks.
这基本上是这样工作的:
That is basically how this works:
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);
}
}
此代码还使用了表列调整器.
这篇关于防止JTable在双击时自动排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!