【发布时间】:2012-02-20 15:28:51
【问题描述】:
我试图通过简单地添加鼠标侦听器并使用java.awt.Component 的setLocation 函数来使任何组件可拖动。我从JButton 开始测试是否可以按照我的想法进行。
这是我正在尝试做的代码示例:
import java.awt.*;
import javax.swing.*;
public class DragButton extends JButton{
private volatile int draggedAtX, draggedAtY;
public DragButton(String text){
super(text);
setDoubleBuffered(false);
setMargin(new Insets(0, 0, 0, 0));
setSize(25, 25);
setPreferredSize(new Dimension(25, 25));
addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
draggedAtX = e.getX() - getLocation().x;
draggedAtY = e.getY() - getLocation().y;
}
});
addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
setLocation(e.getX() - draggedAtX, e.getY() - draggedAtY);
}
});
}
public static void main(String[] args){
JFrame frame = new JFrame("DragButton");
frame.setLayout(null);
frame.getContentPane().add(new DragButton("1"));
frame.getContentPane().add(new DragButton("2"));
frame.getContentPane().add(new DragButton("3"));
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
不知何故,这无法正常工作,我不明白为什么。拖动的实际距离是鼠标移动距离的一半,并且在拖动时会在该距离周围闪烁,就好像两个鼠标位置在MouseMotionListener 上竞争。
有人可以帮助摇摆/awt 菜鸟吗? =) 非常感谢。
编辑:
好的,所以问题是我不知道该事件会在每个鼠标位置重新触发,位置相对(!)到触发JComponent。所以这是正确且有效的代码:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DragButton extends JButton{
private volatile int draggedAtX, draggedAtY;
public DragButton(String text){
super(text);
setDoubleBuffered(false);
setMargin(new Insets(0, 0, 0, 0));
setSize(25, 25);
setPreferredSize(new Dimension(25, 25));
addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
draggedAtX = e.getX();
draggedAtY = e.getY();
}
});
addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
setLocation(e.getX() - draggedAtX + getLocation().x,
e.getY() - draggedAtY + getLocation().y);
}
});
}
public static void main(String[] args){
JFrame frame = new JFrame("DragButton");
frame.setLayout(null);
frame.getContentPane().add(new DragButton("1"));
frame.getContentPane().add(new DragButton("2"));
frame.getContentPane().add(new DragButton("3"));
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
感谢 Adel 的努力和 mKorbel 的链接。
【问题讨论】:
-
另见
ChessBoard。 -
是的,玻璃窗格当然是这里的最佳选择,但我试图让示例尽可能简单,但仍然可以编译。我希望这不会让未来的读者感到困惑。使用玻璃板! (或带有 DRAG_LAYER 的 layered pane)
标签: java swing drag-and-drop awt mouselistener