java - JTable - 拖放

标签 java swing drag-and-drop jtable

好吧,这个问题超出了我的能力范围。我正在尝试在 swing 中实现一个 GUI 小部件,它允许将文件拖放到 JTable 上,并允许拖动 JTable 的行以进行重新排序。想想 VLC 的播放列表或 iTunes 中的播放列表。

我从操作系统(Explorer、Finder 等)中删除文件工作得很好,但是一旦文件进入,我就无法重新排列表格的行。问题是当我将自定义 TransferHandler 添加到表中时, 表中拖动会立即被终止。下面是一些示例代码:

import javax.swing.*;

public class TableTest
{
    public static void main (String [] argv)
    {
        // setup table data
        String [] columns = new String [] {"Foo", "Bar", "Baz", "Quux"};
        String [][] data = new String [][] {{"A", "B", "C", "D"},
                        {"1", "2", "3", "4"},
                        {"i", "ii", "iii", "iv"}};
        // create table
        JTable table = new JTable(data, columns);

        // set up drag and drop
        table.setDragEnabled(true);
        table.setDropMode(DropMode.INSERT_ROWS);
        table.setFillsViewportHeight(true);
        TransferHandler dnd = new TransferHandler() {
            // here be code to handle drops, and one would
            // presume drag exporting, too
        };
        table.setTransferHandler(dnd);
        JScrollPane scroll = new JScrollPane(table);

        // create and show window
        JFrame window = new JFrame();
        window.getContentPane().add(scroll);
        window.pack();
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setVisible(true);
    }
}

按原样运行此代码,您会发现无法在表格上发起拖动。如果您在表格上注释掉对 setTransferHandler() 的调用,则拖动有效(即,当我开始拖动表格行时,我得到 X'd out circle cursor 说我不能放在那里)。但是一旦为表设置了 TransferHandler,我就无法拖动任何行。问题一定出在TransferHandler上,但是我已经彻底排查和调试了它,并且确定一旦 table 上有TransferHandler就不会开始拖动。我做错了什么?

最佳答案

我遇到了同样的问题,这与您自定义的 TransferHandler 实现无关。当您替换 TransferHandler 时,您还需要获取默认的 DragSource 并告诉它识别拖动手势。您可能还需要实现自己的 Transferable,因为您需要将其传递给 DragGestureEvent.startDrag() 方法。

    table.setTransferHandler(new MyTransferHandler());
    table.setDragEnabled(true);
    DragSource source = DragSource.getDefaultDragSource();
    source.createDefaultDragGestureRecognizer(table, DnDConstants.ACTION_COPY, new DragGestureListener() {

        @Override
        public void dragGestureRecognized(DragGestureEvent dge) {
            //grab the selected files from the table model
            ArrayList<File> files = new ArrayList<File>();
            for (int row : table.getSelectedRows()) {
                files.add((File) dm.getValueAt(row, 1));
            }

            //FileTransferable is a custom Transferable implementation
            Transferable transferable = new FileTransferable(files); 

            //and this is the magic right here
            dge.startDrag(null,transferable);
        }
    });

关于java - JTable - 拖放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/715332/

相关文章:

java - 小后台任务的选项

java - java 8中两个列表的合并函数

Java awt/swing AffineTransformation 在形状周围移动

ios - 如何在 `UICollectionViewCell` 位置更改时正确移动数组项

wpf - 如何在 WPF ItemsControl 中保留项目的排序顺序?

java - 如何选择集合中最大的元素之一

java - Eclipse Java 编译器和 OpenJDK 编译器之间的类型推断差异 (Java 8)

java - 使线程在来自 EDT 的非 EDT(事件调度线程)线程上运行

java - 我们可以将 JPanel 倾斜一定角度吗?

javascript - 拖放以重新排序 HTML 列表