Java:如何在不使用TransferHandler的情况下拖动JTable行? [英] Java: How to drag JTable rows without usage of TransferHandler?

查看:120
本文介绍了Java:如何在不使用TransferHandler的情况下拖动JTable行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Java中,默认情况下,JTable不提供拖动JTable行以对表进行重新排序的功能.我在网上看到的许多答案都建议您使用自定义TransferHandler实现来实现此行为.但是,我发现这使事情变得非常复杂,并且需要一种更简单的方法来完成.任何人都可以提出有关如何更有效地拖动和拖动的建议.删除表格行以对表格重新排序?

In Java, JTable by default does not offer the functionality to drag JTable rows for reordering the table. Many of the answers I see online, suggest that you should use a custom TransferHandler implementation to achieve this behaviour. However, I find that that highly overcomplicates things and there needs to be an easier way to do so. Can anyone give suggestions on how to more efficiently drag & drop table rows for reordering the table?

推荐答案

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

In order to achieve this behavior, you can use a combination of a MouseListener and a MouseMotionListener. DefaultTableModel provides functionality with which you can translate the Point of an event to the row in which the event occured. Using this functionality, we can effectively drag table rows around. The code sample below shows a basic implementation with which table rows are dragged in real-time. Please note that the table and tableModel properties are weakified on purpose: We do not want the MouseHandler to keep a strong reference to either the table or the 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) {}

}

与大多数使用TransferHandler的建议相比,在我看来这是一种更干净,更友好的实现方式.

This in my eyes is a much cleaner and more friendly implementation than most of the suggestions out there that use TransferHandler.

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

Update 22th september 2019 11.51 CEST As suggested by @MadProgrammer, the original example has issues when dealing with filtered/sorted tables. The example has now been updated to also support those. When moving rows in a sorted table, the moved row will be inserted one index after the next visible row. This means that in the underlying model, the row may be moved more than one index at a time.

重要提示:如果要确保在移动行后表格保持过滤/排序状态,请确保在表格的排序器上调用了setSortsOnUpdates(true).

Important: When you want to ensure that your table remains filtered/sorted after moving the row, ensure that you called setSortsOnUpdates(true) on your table's sorter.

这篇关于Java:如何在不使用TransferHandler的情况下拖动JTable行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆