java - JList 中的拖放不起作用

标签 java swing jlist drag-and-drop

因此,我为我的应用程序编写了一个 TransferHandler(沿着 Oracle 站点的示例),但是当我尝试移动数据时,它没有移动。它所做的就是将索引处的数据(n-1,即如果我将项目移动到 n 位置)复制到索引 n。您能否检查一下出了什么问题,虽然我尝试了很多选择,但没有一个对我有用。

import javax.swing.TransferHandler;
import javax.swing.*;
import java.awt.datatransfer.*;

    public class ListTransferHandler extends TransferHandler {
        private int[] indices = null;
        private int addIndex = -1; //Location where items were added
        private int addCount = 0;  //Number of items added.

        public boolean canImport(TransferHandler.TransferSupport info) {
            // Check for String flavor
            if (!info.isDataFlavorSupported(DataFlavor.stringFlavor)) {
                return false;
            }
            return true;
        }

        protected Transferable createTransferable(JComponent c) {
            return new StringSelection(exportString(c));
        }

        public int getSourceActions(JComponent c) {
            return TransferHandler.MOVE;
        }

        public boolean importData(TransferHandler.TransferSupport info) {
            if (!info.isDrop()) {
                return false;
            }

            JList list = (JList)info.getComponent();
            DefaultListModel listModel = (DefaultListModel)list.getModel();
            JList.DropLocation dl = (JList.DropLocation)info.getDropLocation();
            int index = dl.getIndex();
            boolean insert = dl.isInsert();

            // Get the string that is being dropped.
            Transferable t = info.getTransferable();
            String data;
            try {
                data = (String)t.getTransferData(DataFlavor.stringFlavor);
            } 
            catch (Exception e) { return false; }

            // Perform the actual import.  
            if (insert) {
                listModel.add(index, data);
            } else {
                listModel.set(index, data);
            }
            return true;
        }

        protected void exportDone(JComponent c, Transferable data, int action) {
            cleanup(c, action == TransferHandler.MOVE);
        }

        //Bundle up the selected items in the list
        //as a single string, for export.
        protected String exportString(JComponent c) {
            JList list = (JList)c;
            indices = list.getSelectedIndices();
            Object[] values = list.getSelectedValues();

            StringBuffer buff = new StringBuffer();

            for (int i = 0; i < values.length; i++) {
                Object val = values[i];
                buff.append(val == null ? "" : val.toString());
                if (i != values.length - 1) {
                    buff.append("\n");
                }
            }

            return buff.toString();
        }

        //Take the incoming string and wherever there is a
        //newline, break it into a separate item in the list.
        protected void importString(JComponent c, String str) {
            JList target = (JList)c;
            DefaultListModel listModel = (DefaultListModel)target.getModel();
            int index = target.getSelectedIndex();

            //Prevent the user from dropping data back on itself.
            //For example, if the user is moving items #4,#5,#6 and #7 and
            //attempts to insert the items after item #5, this would
            //be problematic when removing the original items.
            //So this is not allowed.
            if (indices != null && index >= indices[0] - 1 &&
                  index <= indices[indices.length - 1]) {
                indices = null;
                return;
            }

            int max = listModel.getSize();
            if (index < 0) {
                index = max;
            } else {
                index++;
                if (index > max) {
                    index = max;
                }
            }
            addIndex = index;
            String[] values = str.split("\n");
            addCount = values.length;
            for (int i = 0; i < values.length; i++) {
                listModel.add(index++, values[i]);
            }
        }

        //If the remove argument is true, the drop has been
        //successful and it's time to remove the selected items 
        //from the list. If the remove argument is false, it
        //was a Copy operation and the original list is left
        //intact.
        protected void cleanup(JComponent c, boolean remove) {
            if (remove && indices != null) {
                JList source = (JList)c;
                DefaultListModel model  = (DefaultListModel)source.getModel();
                //If we are moving items around in the same list, we
                //need to adjust the indices accordingly, since those
                //after the insertion point have moved.
                if (addCount > 0) {
                    for (int i = 0; i < indices.length; i++) {
                        if (indices[i] > addIndex) {
                            indices[i] += addCount;
                        }
                    }
                }
                for (int i = indices.length - 1; i >= 0; i--) {
                    model.remove(indices[i]);
                }
            }
            indices = null;
            addCount = 0;
            addIndex = -1;
        }
}

最佳答案

导出成功完成后,您需要从源中“删除”数据。

为了做到这一点,您需要覆盖 TransferHandler.exportDone方法。

protected void exportDone(JComponent source, Transferable data, int action)

Invoked after data has been exported. This method should remove the data that was transferred if the action was MOVE.

This method is implemented to do nothing since MOVE is not a supported action of this implementation (getSourceActions does not include MOVE).

基本上,您需要检查 action 类型并确保目标组件已接受 MOVE 而不仅仅是 COPY'编辑它并从源列表中删除该元素。

关于java - JList 中的拖放不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12573312/

相关文章:

java - 在 Java 中将用户输入的单词转换为 unicode 数组

java - Spring REST Controller 在具有空格或逗号等特殊字符时理解字符串数组

java - 按日期和时间对 ArrayList 的对象进行排序

java - 自定义图标 JOptionPane.showInputDialog

java - Swing 。用 JList 填充 JScrollPane

java - 您可以反编译任何 .jar,这不是很奇怪\不安全吗?

java - 在 JTextPane 中禁用自动换行

java - JTextField 的 setText(String t) 无法更改文本字段的内容

java - 如何将 ArrayList 绑定(bind)到 JList

java - 从事件动态更新 JList