Java:如何在不使用TransferHandler的情况下拖动JTable行?

时间:2019-09-21 20:06:18

标签: java swing user-interface drag-and-drop jtable

在Java中,默认情况下,JTable不提供拖动JTable行以重新排序表格的功能。我在网上看到的许多答案都建议您使用自定义TransferHandler实现来实现此目的。但是,我发现这会使事情变得过于复杂,因此需要一种更简单的方法。谁能提供有关如何更有效地拖放表格行以对表格重新排序的建议?

1 个答案:

答案 0 :(得分:1)

为了实现此行为,可以结合使用MouseListenerMouseMotionListenerDefaultTableModel提供的功能可用于将事件的Point转换为事件发生的行。使用此功能,我们可以有效地拖动表行。下面的代码示例显示了一种基本实现,通过该基本实现可以实时拖动表行。请注意,tabletableModel属性是有意削弱的:我们不希望MouseHandler保持对table或{{1}的强烈引用}。

tableModel

在我看来,这是比使用public class MouseHandler implements MouseListener, MouseMotionListener { private Integer row = null; private final WeakReference<JTable> table; private final WeakReference<DefaultTableModel> tableModel; public MouseHandler(JTable table, DefaultTableModel model) { this.table = new WeakReference<>(table); this.tableModel = new WeakReference<>(model); } @Override public void mouseClicked(MouseEvent event) {} @Override public void mousePressed(MouseEvent event) { JTable table; if((table = this.table.get()) == null) { return; } int viewRowIndex = table.rowAtPoint(event.getPoint()); row = table.convertRowIndexToModel(viewRowIndex); } @Override public void mouseReleased(MouseEvent event) { row = null; } @Override public void mouseEntered(MouseEvent event) {} @Override public void mouseExited(MouseEvent event) {} @Override public void mouseDragged(MouseEvent event) { JTable table; DefaultTableModel tableModel; if((table = this.table.get()) == null || (tableModel = this.tableModel.get()) == null) { return; } int viewRowIndex = table.rowAtPoint(event.getPoint()); int currentRow = table.convertRowIndexToModel(viewRowIndex); if(row == null || currentRow == row) { return; } tableModel.moveRow(row, row, currentRow); row = currentRow; table.setRowSelectionInterval(viewRowIndex, viewRowIndex); } @Override public void mouseMoved(MouseEvent event) {} } 的大多数建议更干净,更友好的实现。

更新2019年9月22日11.51 CEST 正如@MadProgrammer所建议的那样,原始示例在处理经过过滤/排序的表时存在问题。该示例现在已更新为也支持这些示例。在排序表中移动行时,将在下一个可见行之后的一个索引处插入移动的行。这意味着在基础模型中,该行一次可以移动多个索引。

重要提示:要确保在移动行后表格保持过滤/排序状态,请确保在表格的排序器上调用了TransferHandler