在 Java 中从 JButton 拖放到 JComponent
Posted
技术标签:
【中文标题】在 Java 中从 JButton 拖放到 JComponent【英文标题】:Drag and Drop from JButton to JComponent in Java 【发布时间】:2015-05-04 20:35:35 【问题描述】:我在互联网上搜索了如何将 JButtons 拖放到对象的示例,但我无法使其工作。
我的程序所做的是,当我单击一个按钮时,对象会更新一个字段(使用 selectedobject.setField())。我希望能够做到这一点不是通过单击,而是通过拖动 JButton。
我该怎么做? 我找到了这个,并尝试输入我的代码:
btn.setTransferHandler(new ImageHandler());
btn.addMouseListener(new MouseAdapter()
public void mousePressed(MouseEvent e)
JComponent c = (JComponent)e.getSource();
TransferHandler handler = c.getTransferHandler();
handler.exportAsDrag(c, e, TransferHandler.COPY);
);
我从 here 获取了 ImageHandler 类。
【问题讨论】:
“获得新价值”是什么意思?你想把按钮的“值”拖到别的东西上吗? 按钮为选中的对象添加动画。我希望能够通过拖放将相同的动画添加到随机对象。 【参考方案1】:Drag'n'drop 是一袋有趣的松脆胡萝卜……没有“核心”API 和更新的“转移”API 的帮助,所以很容易混淆
以下示例使用“传输”API,基本上将 String
值从按钮传输到 JLabel
。
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.dnd.DnDConstants;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.TransferHandler;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class Test
public static void main(String[] args)
new Test();
public Test()
EventQueue.invokeLater(new Runnable()
@Override
public void run()
try
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex)
ex.printStackTrace();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
);
public class TestPane extends JPanel
public TestPane()
setLayout(new GridLayout(1, 2));
add(createLeftPanel());
add(createRightPanel());
protected JPanel createLeftPanel()
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
for (int index = 0; index < 10; index++)
JButton btn = new JButton(Integer.toString(index + 1));
panel.add(btn, gbc);
btn.setTransferHandler(new ValueExportTransferHandler(Integer.toString(index + 1)));
btn.addMouseMotionListener(new MouseAdapter()
@Override
public void mouseDragged(MouseEvent e)
JButton button = (JButton) e.getSource();
TransferHandler handle = button.getTransferHandler();
handle.exportAsDrag(button, e, TransferHandler.COPY);
);
return panel;
protected JPanel createRightPanel()
JPanel panel = new JPanel(new GridBagLayout());
JLabel label = new JLabel("Drop in");
label.setBorder(new CompoundBorder(new LineBorder(Color.DARK_GRAY), new EmptyBorder(20, 20, 20, 20)));
label.setTransferHandler(new ValueImportTransferHandler());
panel.add(label);
return panel;
public static class ValueExportTransferHandler extends TransferHandler
public static final DataFlavor SUPPORTED_DATE_FLAVOR = DataFlavor.stringFlavor;
private String value;
public ValueExportTransferHandler(String value)
this.value = value;
public String getValue()
return value;
@Override
public int getSourceActions(JComponent c)
return DnDConstants.ACTION_COPY_OR_MOVE;
@Override
protected Transferable createTransferable(JComponent c)
Transferable t = new StringSelection(getValue());
return t;
@Override
protected void exportDone(JComponent source, Transferable data, int action)
super.exportDone(source, data, action);
// Decide what to do after the drop has been accepted
public static class ValueImportTransferHandler extends TransferHandler
public static final DataFlavor SUPPORTED_DATE_FLAVOR = DataFlavor.stringFlavor;
public ValueImportTransferHandler()
@Override
public boolean canImport(TransferHandler.TransferSupport support)
return support.isDataFlavorSupported(SUPPORTED_DATE_FLAVOR);
@Override
public boolean importData(TransferHandler.TransferSupport support)
boolean accept = false;
if (canImport(support))
try
Transferable t = support.getTransferable();
Object value = t.getTransferData(SUPPORTED_DATE_FLAVOR);
if (value instanceof String)
Component component = support.getComponent();
if (component instanceof JLabel)
((JLabel) component).setText(value.toString());
accept = true;
catch (Exception exp)
exp.printStackTrace();
return accept;
我已经尽力将TransferHandler
s 分开,允许“拖放”版本。您不必“必须”执行此操作,您“可以”使用单个 TransferHandler
来执行这两个操作,这取决于您。
您必须修改ValueExportTransferHandler
以接受不同的值并相应地修改SUPPORTED_DATE_FLAVOR
,但这些是基础
你也可以看看Drag and Drop custom object from JList into JLabel作为另一个例子......
【讨论】:
那里出了点问题。我的意思是,不应该为每一个拖动事件调用“exportAsDrag”,对吗?即使它可能在实践中起作用。编辑:我刚刚运行它。它可以工作,并且由于某种原因,mouseDragged 方法只执行了一次,所以一切似乎都很好。 @DreamspacePresident 为什么不呢?exportAsDrag
在mouseDragged
上被调用,如果没有,那么应该什么时候调用? ps-我想你在想mouseMoved
;)
因为 exportAsDrag 的文档说“导致启动 Swing 拖动支持。”和“在此呼叫返回时,传输不一定已完成(即呼叫不会阻塞等待丢弃)。”对我来说,这清楚地暗示了这个东西将在每个 D&D 中被称为 一次。但是看看我对我的其他评论的编辑,一切似乎都很好。以上是关于在 Java 中从 JButton 拖放到 JComponent的主要内容,如果未能解决你的问题,请参考以下文章
JAVA SAP JCO3.0 抛出这个异常:java.lang.UnsatisfiedLinkError: no sapjco3 in java.library.path
JAVA SAP JCO3.0 抛出这个异常:java.lang.UnsatisfiedLinkError: no sapjco3 in java.library.path