Próbowałem utworzyć dowolny komponent, który można przeciągnąć, po prostu dodając detektory myszy i używając funkcji setLocation
z java.awt.Component
. Zacząłem od JButton
, aby sprawdzić, czy to możliwe, jak myślałem.Elementy komponentu Java z myszą
Oto przykładowy kod dla co próbuję zrobić:
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);
}
}
Jakoś to nie działa prawidłowo i nie rozumiem dlaczego. Rzeczywisty przebyta odległość to połowa odległości od ruchu myszy i migocze wokół tej odległości podczas przeciągania, tak jakby dwie pozycje myszy konkurowały o MouseMotionListener
.
Czy ktokolwiek może pomóc huśtawce? =) Bardzo dziękuję z góry.
Edit:
Ok, więc problem był taki, że nie wiedział, że zdarzenie będzie refire w każdej lokalizacji myszy z pozycji podlegającej względną do wypalania JComponent
(!). To jest poprawiony i działający kod:
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);
}
}
Dziękuję Adel za twoje wysiłki i mKorbel za link.
Zobacz również [ 'ChessBoard'] (http://stackoverflow.com/a/2562685/230513). – trashgod
Tak, szklana szyba to z pewnością sposób, w jaki można się tutaj udać, ale starałem się, aby przykład był tak prosty, jak to tylko możliwe, ale nadal można go kompilować. Mam nadzieję, że to nie zmyli przyszłych czytelników. UŻYJ GLASSPANE! (Lub [panel warstwowy] (http://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html) ze swoim DRAG_LAYER). – Stephan