【发布时间】:2013-07-05 08:54:34
【问题描述】:
当我将 ActionListeners 与 Drag'n'Drop 结合使用时,我遇到了意外的行为。
运行以下示例并尝试以下操作:
- 将按钮 A 拖动到某处并释放鼠标按钮
- 不要再将鼠标移到按钮 A 上
- 点击按钮B
- 在 System.out 上,您会看到按钮 A 和 B 都会调用 actionPerformed
我不想为按钮 A 调用 actionPerformed。我究竟做错了什么?
这是完整的例子:
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.awt.event.*;
import java.io.IOException;
import javax.swing.*;
public class DragDropTest{
private static Color slightlyRed = new Color(255, 220, 220);
private static Color slightlyGreen = new Color(220, 255, 220);
private static class DragDropButton extends JButton implements DragSourceListener, DragGestureListener, Transferable, ActionListener{
private DragSource dragSource;
public DragDropButton(String string) {
super(string);
addActionListener(this);
dragSource = new DragSource();
dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_COPY, this);
}
// Interface DragSourceListener
@Override public void dragEnter(DragSourceDragEvent dsde) {}
@Override public void dragOver(DragSourceDragEvent dsde) {}
@Override public void dropActionChanged(DragSourceDragEvent dsde) {}
@Override public void dragExit(DragSourceEvent dse) {}
@Override public void dragDropEnd(DragSourceDropEvent dsde) {
System.out.println("Dragging of [" + getText() + "] ended");
}
// Interface DragGestureListener
@Override public void dragGestureRecognized(DragGestureEvent dge) {
dragSource.startDrag(dge, DragSource.DefaultMoveDrop, this, this);
}
// Interface Transferable
@Override public DataFlavor[] getTransferDataFlavors() {return null;}
@Override public boolean isDataFlavorSupported(DataFlavor flavor) {return false;}
@Override public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException, IOException {return null;}
// Interface ActionListener
@Override public void actionPerformed(ActionEvent e) {
System.out.println("Action on [" + getText() + "]");
}
}
private static class DropPanel extends JPanel implements DropTargetListener{
public DropPanel(){
setBorder(BorderFactory.createLineBorder(Color.BLACK));
setPreferredSize(new Dimension(300, 300));
setBackground(slightlyGreen);
new DropTarget(this, this);
}
@Override public void dragEnter(DropTargetDragEvent dtde) {}
@Override public void dragOver(DropTargetDragEvent dtde) {}
@Override public void dropActionChanged(DropTargetDragEvent dtde) {}
@Override public void dragExit(DropTargetEvent dte) {}
@Override public void drop(DropTargetDropEvent dtde) {
System.out.println("Drop complete");
dtde.dropComplete(true);
}
}
// Create Panels
private static JPanel leftSide(){
JPanel leftPanel = new JPanel();
leftPanel.setPreferredSize(new Dimension(300, 300));
leftPanel.setBackground(slightlyRed);
leftPanel.add(new DragDropButton("A"));
leftPanel.add(new DragDropButton("B"));
return leftPanel;
}
private static JPanel rightSide(){
JPanel leftPanel = new DropPanel();
return leftPanel;
}
// Create Window
private static JFrame boringFrame(String text){
JFrame boringFrame = new JFrame(text);
boringFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
boringFrame.getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER));
boringFrame.setVisible(true);
return boringFrame;
}
public static void main(String[] args){
JFrame boringFrame = boringFrame("boring");
boringFrame.add(leftSide());
boringFrame.add(rightSide()); // try to comment out this line!
boringFrame.pack();
}
}
我的项目中还有一些问题,但我不会用它们来打扰你,因为这似乎是我问题的主要来源,但这是我的另一个观察结果:
如果没有 DropTargetListener(如我的 DropPanel),问题就会消失。尝试注释掉以下行:
boringFrame.add(rightSide());
【问题讨论】:
-
您是否希望发生鼠标拖动事件而不是执行操作?
-
拖动事件按预期发生。之前拖动的按钮的附加 actionPerformed 让我很困扰。
-
因此您可以将鼠标拖动事件侦听器添加到表单而不是按钮。
-
“表格”是什么意思?顺便说一句:user2471439 已经帮助了我,但还是感谢您的支持
-
放置按钮的 JframeForm。
标签: java swing drag-and-drop actionlistener