【问题标题】:drag and Drop for a JLabel: how to get the drag sourceJLabel 的拖放:如何获取拖动源
【发布时间】:2011-12-19 08:46:04
【问题描述】:

我正在开发一个应用程序,可以将一个 JLabel 的内容放到另一个 JLabel 中。我为此使用了 NameSlot 类:

public class NameSlot extends JLabel implements DropTargetListener{

NameSlot(String name){
    super(name);
    new DropTarget(this,this);

    this.setTransferHandler(new TransferHandler("foreground"));
    MouseListener listener = new MouseAdapter() {
      public void mousePressed(MouseEvent me) {
        JLabel comp = (JLabel) me.getSource();
        TransferHandler handler = comp.getTransferHandler();
        handler.exportAsDrag(comp, me, TransferHandler.COPY);
      }
    };
    this.addMouseListener(listener);
}



@Override
public void dragEnter(DropTargetDragEvent dtde) {
    // TODO Auto-generated method stub

}


@Override
public void dragExit(DropTargetEvent dte) {
    // TODO Auto-generated method stub

}


@Override
public void dragOver(DropTargetDragEvent dtde) {
    // TODO Auto-generated method stub

}


@Override
public void drop(DropTargetDropEvent dtde) {

//      DropTarget dt = (DropTarget) dtde.getSource();
//      NameSlot ns  = (NameSlot) dt.getComponent();

    try {
        JLabel l  =(JLabel) dtde.getTransferable().getTransferData(DataFlavor.stringFlavor);
        System.out.println("drop detected from "+l.getText()+" to "+this.getText());
    } catch (UnsupportedFlavorException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}


@Override
public void dropActionChanged(DropTargetDragEvent dtde) {
    // TODO Auto-generated method stub

}

我就是这样初始化的:

    this.setLayout(null);
    NameSlot ns = new NameSlot("test");
    ns.setLocation(20, 20);
    this.add(ns);

    NameSlot ns2 = new NameSlot("test2");
    ns2.setLocation(20, 20);
    this.add(ns2);

在尝试使用 dtde.getSource() 并因为 coolcfans 评论而将其废弃后,我现在尝试使用 DropTargetEvent 的 Transferable 获取拖动源。我得到了例外:

java.awt.datatransfer.UnsupportedFlavorException: Unicode String
    at javax.swing.TransferHandler$PropertyTransferable.getTransferData(Unknown Source)
    at sun.awt.dnd.SunDropTargetContextPeer.getTransferData(Unknown Source)
    at sun.awt.datatransfer.TransferableProxy.getTransferData(Unknown Source)
    at java.awt.dnd.DropTargetContext$TransferableProxy.getTransferData(Unknown Source)
    at an.judosoft.view.bracketSheets.factory.NameSlot.drop(NameSlot.java:71)

有人知道路吗?

【问题讨论】:

  • 这里使用的是拖放目标,因为拖放操作是从拖放源开始的,会不会有问题?
  • 我不明白你的意思。我应该怎么做?
  • 不需要setPosition() 方法。所有组件都已经支持setLocation() 方法来执行此操作。
  • @Anthea 没关系...我阅读了有关 awt 的 dnd 类的 api 文档,但未能理解...我只是想知道您是否可以使用 dtde.getSource 获取拖动事件的来源(),因为 dtde.getSource 应该返回 drop 事件的来源。抱歉没能帮上忙……
  • @camicr 更改了 @coolcfan 感谢您的评论,我现在尝试了另一种方式并编辑了问题...

标签: java swing drag-and-drop awt


【解决方案1】:

以下作品:

我把this.setTransferHandler(new TransferHandler("foreground"))改成了this.setTransferHandler(new TransferHandler("text"))

并将new DataFlavor("application/x-java-jvm-local-objectref; class=java.lang.String") 用于DataFlavor,尽管它返回String 而不是JLabel。如果您需要 JLabel,则需要更改 TransferHandler。

import java.awt.FlowLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
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 java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.TransferHandler;

public class NameSlot extends JLabel implements DropTargetListener {
    NameSlot(final String name) {
        super(name);
        new DropTarget(this, this);
        this.setTransferHandler(new TransferHandler("text"));
        final MouseListener listener = new MouseAdapter() {
            @Override
            public void mousePressed(final MouseEvent me) {
                final JLabel comp = (JLabel) me.getSource();
                System.out.println(comp);

                final TransferHandler handler = comp.getTransferHandler();
                handler.exportAsDrag(comp, me, TransferHandler.COPY);
            }
        };
        this.addMouseListener(listener);
    }

    @Override
    public void dragEnter(final DropTargetDragEvent dtde) {
        // TODO Auto-generated method stub

    }

    @Override
    public void dragExit(final DropTargetEvent dte) {
        // TODO Auto-generated method stub

    }

    @Override
    public void dragOver(final DropTargetDragEvent dtde) {
        // TODO Auto-generated method stub

    }

    @Override
    public void drop(final DropTargetDropEvent dtde) {

        // DropTarget dt = (DropTarget) dtde.getSource();
        // NameSlot ns = (NameSlot) dt.getComponent();

        try {
            final String s = (String) dtde.getTransferable().getTransferData(
                    new DataFlavor("application/x-java-jvm-local-objectref; class=java.lang.String"));

            System.out.println("drop detected from " + s + " to " + this.getText());
        }
        catch (final UnsupportedFlavorException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (final IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        catch (final ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    @Override
    public void dropActionChanged(final DropTargetDragEvent dtde) {
        // TODO Auto-generated method stub

    }

    public static void main(final String[] args) {
        final JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLayout(new FlowLayout());

        final NameSlot ns = new NameSlot("test");
        frame.add(ns);

        final NameSlot ns2 = new NameSlot("test2");
        frame.add(ns2);

        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

    }
}

【讨论】:

  • 感谢您的帮助,效果很好。是否可以在发送传输处理程序中应用任何其他文本信息然后显示?
  • 是的,但是您需要做的是扩展 TransferHandler 并为createTransferable 提供您自己的实现。然后,您返回的任何对象都是实际被复制的可转移对象。我会查看 TransferHandler 的源代码以了解它是如何工作的。
猜你喜欢
  • 2012-07-12
  • 1970-01-01
  • 1970-01-01
  • 2010-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
相关资源
最近更新 更多