java - 使用移动列表处理拖放

标签 java swing drag-and-drop

我正在使用拖放操作。用户必须将列表中的某些内容拖到其他位置。但是,当接收到 ListSelectionEvent 时,列表将会移动,因此当用户更改选择时,他可能会意外地执行拖放操作

我的代码:

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

class Main {
    public static void createGUI() {
        JFrame f = new JFrame();

        JList<String> list = new JList<>(new String[] { "Text A", "Text B" });
        list.setFont(list.getFont().deriveFont(24f));
        list.setDragEnabled(true);
        // list.setTransferHandler(new TransferHandler() { /* ... */ });
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.addListSelectionListener(e -> f.setLocation(f.getX(),
                f.getY() + f.getHeight()));
        list.setSelectedIndex(0);

        f.add(list, BorderLayout.CENTER);
        f.pack();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLocationByPlatform(true);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(Main::createGUI);
    }
}

要重现,请启动此应用程序,将其放在某个接受拖放的应用程序(例如 Eclipse、Notepad++)上方,然后多次切换选择。

我使用的是 Windows 7 和 JDK 1.8.0_5。

我尝试过,但找不到解决方法。 如何解决此问题?

<小时/>

[不太相关]这是我真正的应用程序:(包括绿色十字图标)

Screenshot (Empty) Screenshot (TopCoder)

最佳答案

好的,我想我理解您的问题:您希望启用 DnD,但不是在用户更改其选择时启用。您应该尝试一下(在 Java 7 中,我对 lambda 表达式还不太熟悉,所以我仍然没有使用 Java 8。不过它可以在 Java 8 上工作):

class Main {
    private static boolean listChanging = false;

    public static void createGUI() {
        final JFrame f = new JFrame();
        JList<String> list = new JList<String>(new String[] { "Text A", "Text B" });
        list.setFont(list.getFont().deriveFont(24f));
        list.setDragEnabled(true);
        list.setTransferHandler(new TransferHandler() {
            private static final long serialVersionUID = 1L;

            @Override
            public int getSourceActions(JComponent c) {
                if (listChanging) {
                    listChanging = false;
                    return NONE;
                } else {
                    return COPY;
                }
            }

            @Override
            @SuppressWarnings("unchecked")
            public Transferable createTransferable(JComponent c) {
                return new StringSelection(((JList<String>) c).getSelectedValue());
            }
        });
        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        list.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                f.setLocation(f.getX(), f.getY() + f.getHeight());
                listChanging = true;
            }
        });
        list.setSelectedIndex(0);
        f.add(list, BorderLayout.CENTER);
        f.pack();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLocationByPlatform(true);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                Main.createGUI();
            }
        });
    }
}

此代码的作用是,当用户更改选择时,它将变量 listChanging 设置为 true。当用户拖动(意外或故意)时,它会检查 listChanging 是否为 true,这意味着这可能是意外拖动。如果列表没有改变,那么它允许COPY拖动。

基本上,如果在列表更改期间进行拖动,则会禁用 DnD。如果列表没有更改,并且用户故意拖动它,则会启用 DnD。

希望这能满足您的所有需求:)

关于java - 使用移动列表处理拖放,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24981186/

相关文章:

java - 有没有一种检查 Datastax Session.executeAsync() 是否抛出异常的好方法?

java - 在 Java 中下拉搜索窗口

java - 当主窗口最小化时,半透明的 JDialogs 消失

java - "the value of the local variable is not used"的多个实例

javascript - 使多个元素在放置时可见

python - 将项目文本从 QTreeView 拖放到 QLineEdit

java - 在 java 中,commons-Digester 如何处理输入的 XML 文件?

java - 捕获焦点组件及其容器的 "Tab"按键

java - 如何在二维数组上调用接受数组作为参数的方法?

cocoa - 当启用多选时,NSCollectionView 在拖动之前出现烦人的延迟