使用 transferHandler 将文本从 JLabel 拖放到 JTable

Drag and drop text from a JLabel to JTable using transferHandler

我正在学习下面提到的教程。在本教程的主题 Extending Default DnD Support 下,有一个带有 JTextAreaJListJTable 的应用程序。

而且效果很好。另外我用了一个JLabel。我将此标签的传输处理程序设置为:

jLabel1.setTransferHandler(new TransferHandler("text"));

当我将此标签拖到 table 上时,它不接受它。但它适用于文本区域中的字符串。

如何将文本从标签拖放到 table 上?

您似乎需要手动向标签添加鼠标事件处理程序才能执行此操作:

jLabel1.addMouseListener(new MouseAdapter() {
  public void mousePressed(MouseEvent evt) {
    JComponent comp = (JComponent) evt.getSource();
    TransferHandler th = comp.getTransferHandler();

    th.exportAsDrag(comp, evt, TransferHandler.COPY);
  }
});

来源:http://www.java2s.com/Tutorial/Java/0240__Swing/AddingDragandDropSupporttoaJLabelComponent.htm

new TransferHandler("text");

https://docs.oracle.com/javase/8/docs/api/javax/swing/TransferHandler.html

This class is implemented to provide a default behavior of transferring a component property simply by specifying the name of the property in the constructor. For example, to transfer the foreground color from one component to another either via the clipboard or a drag and drop operation a TransferHandler can be constructed with the string "foreground". The built in support will use the color returned by getForeground as the source of the transfer, and setForeground for the target of a transfer.

JTable 没有 setText(String) 方法。因此,您需要覆盖 TransferHander#importData(...) 方法以将数据导入 JTable.

的单元格中
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

public class DnDTest {
  public JComponent makeUI() {
    JTable table = new JTable(5, 3);
    table.setAutoCreateRowSorter(true);
    table.setTransferHandler(new ToTransferHandler());

    JLabel label = new JLabel("aaaaaaaaaaaa");
    label.setTransferHandler(new TransferHandler("text"));
    label.addMouseListener(new MouseAdapter() {
      @Override public void mousePressed(MouseEvent e) {
        JComponent c = (JComponent) e.getSource();
        c.getTransferHandler().exportAsDrag(c, e, TransferHandler.COPY);
      }
    });

    JPanel p = new JPanel(new BorderLayout());
    p.add(new JScrollPane(table));
    p.add(label, BorderLayout.SOUTH);
    return p;
  }
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new DnDTest().makeUI());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

//@see https://docs.oracle.com/javase/tutorial/uiswing/dnd/dropactiondemo.html
class ToTransferHandler extends TransferHandler {
  @Override public boolean canImport(TransferHandler.TransferSupport support) {
    return getPropertyDataFlavor(String.class, support.getDataFlavors()) != null;
  }
  @Override public boolean importData(TransferHandler.TransferSupport support) {
    // if we can't handle the import, say so
    if (!canImport(support)) {
      return false;
    }

    DataFlavor flavor = getPropertyDataFlavor(String.class, support.getDataFlavors());

    // fetch the data and bail if this fails
    String data;
    try {
      data = (String) support.getTransferable().getTransferData(flavor);
    } catch (UnsupportedFlavorException | java.io.IOException e) {
      return false;
    }

    JTable.DropLocation dl = (JTable.DropLocation) support.getDropLocation();
    JTable table = (JTable) support.getComponent();
    table.setValueAt(data, dl.getRow(), dl.getColumn());
    return true;
  }
  //@see TransferHandler.java private DataFlavor getPropertyDataFlavor(...) {
  private DataFlavor getPropertyDataFlavor(Class<?> k, DataFlavor[] flavors) {
    for (int i = 0; i < flavors.length; i++) {
      DataFlavor flavor = flavors[i];
      if ("application".equals(flavor.getPrimaryType()) &&
          "x-java-jvm-local-objectref".equals(flavor.getSubType()) &&
          k.isAssignableFrom(flavor.getRepresentationClass())) {
        return flavor;
      }
    }
    return null;
  }
}