He intentado hacer que cualquier Componente sea arrastrable simplemente agregando oyentes de mouse y usando la función setLocation
de java.awt.Component
. Empecé con JButton
para probar si era posible de la manera que pensaba.java mover componentes con el mouse
Aquí es un ejemplo de código para lo que yo estoy tratando de hacer:
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);
}
}
De alguna manera esto no funciona correctamente y que no entiendo por qué. La distancia real arrastrada es la mitad de la distancia del movimiento del mouse y parpadea alrededor de esa distancia mientras arrastra como si dos posiciones de mouse estuvieran compitiendo sobre el MouseMotionListener
.
¿Alguien puede ayudar a un novato swing/awt? =) Muchas gracias de antemano.
Editar:
Ok, por lo que el problema era que no sabía que el evento se refire en cada lugar del ratón con ser la posición relativa al disparo JComponent
(!). Así que este es el código corregido y trabajando:
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);
}
}
Gracias Adel por sus esfuerzos y mKorbel para el enlace.
Véase también [ 'ChessBoard'] (http://stackoverflow.com/a/2562685/230513). – trashgod
Sí, el panel de vidrio es ciertamente el camino a seguir aquí, pero traté de mantener el ejemplo lo más simple posible, pero aún compilable. Sin embargo, espero que esto no confunda a los futuros lectores. ¡USE GLASSPANE! (O un [panel en capas] (http://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html) con su DRAG_LAYER) – Stephan