1

假设我有一个包含一些 JTextFields 的 JPanel。我想为此 JPanel 及其子项执行相同的放置操作。换句话说,我希望对孩子的拖放动作与对 JPanel 的拖放动作相同。

除了为 JPanel 及其子项设置相同的 DropTargetListener 之外,还有其他方法吗?


  1. 我知道如果我将那些 JTextFields 的 TransferHandler 设置为 null,则 JPanel 将接收拖放事件。但是,这将破坏文本字段的复制和粘贴功能。

  2. 我知道我可以用 JLayer 拦截鼠标事件。拖动事件有类似的东西吗?


最后,我分别为子组件添加了监听器。因为我还需要相对于父组件的放置位置,所以我在子组件上分别使用了 SwingUtilities.convertToPoint()。这意味着使用了很多不同的监听器——更多的内存使用。但似乎是目前最好的方法。

4

3 回答 3

1

如果您希望能够将项目放置在面板上,但又希望面板上的任何组件都被忽略以进行放置,您可以停用添加到面板的每个组件上的放置目标。您仍然可以在其中剪切和粘贴,甚至还有一种方法可以从它们开始拖动,但您将无法在它们上放置任何东西 - 放置事件直接通过它们到达关联的放置目标与面板。

为此,只需调用

component.getDropTarget().setActive(false);

对于面板上的每个组件。

我发现这在构建日历面板时很有用,我希望能够在其中拖动约会但将它们放在面板上,即使它(部分或完全)被其他约会覆盖。

于 2015-03-24T01:24:35.917 回答
1

在容器上实现一个自定义的 TransferHandler ,它酌情委托给它的孩子,类似于:

for (int i = 0; i < 5; i++) {
    parent.add(new JTextField("item" + i, 20));
};
TransferHandler handler = new TransferHandler() {

    @Override
    public boolean canImport(TransferSupport support) {
        TransferHandler childHandler = getTargetHandler();
        return childHandler.canImport(
                getTargetSupport(support));
    }

    protected TransferSupport getTargetSupport(TransferSupport support) {
        return new TransferSupport(getTarget(), support.getTransferable());
    }

    protected TransferHandler getTargetHandler() {
        return getTarget().getTransferHandler();
    }

    protected JComponent getTarget() {
        return (JComponent) parent.getComponent(0);
    }

    @Override
    public boolean importData(TransferSupport support) {
        return getTargetHandler().importData(getTargetSupport(support));
    }

};
parent.setTransferHandler(handler);
于 2013-09-26T10:24:23.690 回答
1

不确定这是否是您的想法,但是,我基本上将相同的内容添加DropTargetListener到我的所有组件中,这意味着我拖放传入请求的位置无关紧要,所有组件都触发了相同的事件.. .

在此处输入图像描述

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestDragNDrop100 {

    public static void main(String[] args) {

        new TestDragNDrop100();

    }

    public TestDragNDrop100() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel implements DropTargetListener {

        public TestPane() {

            DropTarget dt = new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, this, true);

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.fill = GridBagConstraints.HORIZONTAL;
            for (int y = 0; y < 4; y++) {
                gbc.gridy = y;
                for (int x = 0; x < 4; x++) {
                    gbc.gridx = x;
                    JTextField field = new JTextField(10);
                    DropTarget child = new DropTarget(field, DnDConstants.ACTION_COPY_OR_MOVE, this, true);
                    add(field, gbc);
                }
            }

        }

        @Override
        public void dragEnter(DropTargetDragEvent dtde) {
            System.out.println("DragEnter - " + dtde.getDropTargetContext().getComponent());
        }

        @Override
        public void dragOver(DropTargetDragEvent dtde) {
            System.out.println("DragOver - " + dtde.getDropTargetContext().getComponent());
        }

        @Override
        public void dropActionChanged(DropTargetDragEvent dtde) {
            System.out.println("dropActionChanged" + dtde.getDropTargetContext().getComponent());
        }

        @Override
        public void dragExit(DropTargetEvent dte) {
            System.out.println("dragExit" + dte.getDropTargetContext().getComponent());
        }

        @Override
        public void drop(DropTargetDropEvent dtde) {
            System.out.println("drop" + dtde.getDropTargetContext().getComponent());
        }

    }

}

我也应该注意。我测试了字段剪切/复制/粘贴功能并且没有问题。

于 2013-09-26T08:46:42.867 回答