【问题标题】:Enable drop just for specific targets in Swing仅针对 Swing 中的特定目标启用 drop
【发布时间】:2012-12-26 17:22:58
【问题描述】:

我正在尝试使用两个 JList 实例在 java 中实现拖放。 基本流程工作正常。但是,当我从一个列表中拖动一个字符串时,我只想将放置目标限制为第二个列表。 我注意到,当我将一个字符串从一个列表拖到我的桌面时,它会创建一个包含该字符串的文件。

有没有办法避免这种情况?

public class SampleDnD extends JFrame{

    public static void main(String[] args) {
        new SampleDnD();

    }
    /**
     * new form of frame sample contain 2 JLists with drag enabled.
     */
    public SampleDnD(){
        JList l1 = new JList();
        JList l2 = new JList();
        JScrollPane jScrollPane1 = new javax.swing.JScrollPane();
        JScrollPane jScrollPane2 = new javax.swing.JScrollPane();
        DefaultListModel listModel1 = new DefaultListModel();
        DefaultListModel listModel2 = new DefaultListModel();

        String[] list1 = new String[]{"1","3","5","7","9"};
        String [] list2 = new String[]{"0","2","4","6","8"};
        for(int index=0;index<list1.length;index++){
            listModel1.add(index, list1[index]);
            listModel2.add(index, list2[index]);
        }
        l1.setModel(listModel1);
        l2.setModel(listModel2);
        l1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        l2.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        l1.setDropMode(DropMode.INSERT);
        l1.setDragEnabled(true);
        l2.setDragEnabled(true);
        l1.setTransferHandler(new ListTransferHandler());
        l2.setDropMode(DropMode.INSERT);
        l2.setTransferHandler(new ListTransferHandler());
        jScrollPane1.setViewportView(l1);
        jScrollPane2.setViewportView(l2);

        Container cp = getContentPane();
        cp.setLayout(new BoxLayout(cp,BoxLayout.Y_AXIS));
        setPreferredSize(new Dimension(800,500));
        getContentPane().add(jScrollPane1);
        getContentPane().add(jScrollPane2);
        setVisible(true);
        pack();

    }
    public class ListTransferHandler extends TransferHandler {


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

        /**
         * Bundle up the selected items in a single list for export.
         * 
         */
        protected Transferable createTransferable(JComponent c) {
            JList list = (JList)c;
            String value = (String)list.getSelectedValue();
            return new StringSelection(value);
        }

        /**
         * We support only move actions.
         */
        public int getSourceActions(JComponent c) {
            return TransferHandler.MOVE;
        }
        /**
         * Perform the actual import.  This demo only supports drag and drop.
         */
        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; }

            if (insert) {
                listModel.add(index++, data);
            } else {
                // If the items go beyond the end of the current
                // list, add them in.
                if (index < listModel.getSize()) {
                    listModel.set(index++, data);
                } else {
                    listModel.add(index++, data);
                }
            }
            return true;
        }
        /**
         * Remove the items moved from the list.
         */
        protected void exportDone(JComponent c, Transferable data, int action) {
            JList source = (JList)c;
            DefaultListModel listModel  = (DefaultListModel)source.getModel();
            if(action == TransferHandler.MOVE)
            {
                listModel.remove(source.getSelectedIndex());
            }
        }

    }
}

【问题讨论】:

  • 制作应用程序。全屏和不可调整大小?为了尽快获得更好的帮助,请发帖SSCCE
  • 全屏不是一个选项。
  • 我不明白,SSCCE 是一个代码示例。如果我有解决方案,那么我可能不会首先询问我寻找解决方案的示例。所以我再问一次:是否有任何代码可以仅针对 Swing 中的特定目标启用 drop?
  • "..SSCCE 是代码示例。" 是的。向我展示一个包含 2 个列表的示例代码,启用 D'n'D 以显示“拖动到桌面”问题,我更有可能在 IDE 中加载它,编译它并尝试解决方案 .我的意思是发布一个 broken 代码的简短示例。
  • 安德鲁是对的。您编写的代码已经为您工作,但还有一些您想解决的问题。您可能可以隔离这个特定的类,围绕它创建虚拟类(例如,提供数据),将其包装在一个简单的单帧主类中,然后将其发布到某个地方。然后我们就有了一个“玩”的起点。要么认为我们懒得想出这样的代码(但我们自己编写可能会偏离你自己的目标太多),要么认为我们走一半的路会让你更接近解决方案......

标签: java swing awt drag-and-drop


【解决方案1】:

有点晚了,但可能对其他人有帮助: 您需要创建自己的 DatFlavor,它只会被您自己的应用程序接受。

DataFlavor myObjectDataFlavor = new DataFlavor(MyObject.class, "java/MyObject");

传递这个而不是默认的DataFlavor.javaFileListFlavorDataFlavor.stringFlavor。你的 MyObject 类是一个 Pojo,只包含一个 String 类型的类变量或一个整数或任何你需要的类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-09-23
    • 2017-11-16
    • 2018-06-13
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    • 2020-05-13
    相关资源
    最近更新 更多