2012-01-27 115 views
12

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.

+0

Véase también [ 'ChessBoard'] (http://stackoverflow.com/a/2562685/230513). – trashgod

+1

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

Respuesta

11

Tienes que mover con JComponent, me olvido de estas definiciones en los huecos mousePressed/mouseDragged; en otras manos, no hay nada mejor como @[camickr][1] código excelente para ComponentMover.

+0

¡Dios mío, muchas gracias por ese enlace! Las primeras sentances me hicieron golpear mi cabeza. ^^ Edité mi publicación para mostrar el código correcto. – Stephan

+0

@Stephan: no deje de votar las respuestas que le parecieron útiles. – trashgod

+0

Bueno, no pude, hace poco. ;) – Stephan

2

¿Por qué no usa la interfaz java Transferable en su lugar?

Aquí hay un tutorial sobre cómo hacerlo: http://www.javaworld.com/javaworld/jw-03-1999/jw-03-dragndrop.html

+0

¿Admite java.awt.dnd la animación en movimiento de los componentes? No necesito la parte de caída de datos de Arrastrar y soltar (bueno, lo necesito, pero ese es un problema menor) en lugar de la animación en sí. La mayoría de los tutoriales que encontré solo describían la parte de transferencia de datos, donde solo el cursor indica una acción de arrastrar y soltar. Quiero que todo el Componente se mueva. (sry para mi inglés ^^) – Stephan

+0

@Stephan Transferible viene del paquete _java.awt.datatransfer_ Entonces puede soportar arrastrar y soltar en _awt_ –

+0

Sry, pero esto no responde mi pregunta, sin embargo, encontré un ejemplo funcional de un arrastre y soltar la animación (!) usando java.awt.dnd y java.awt.datatransfer: [link] (http://weblogs.java.net/blog/gfx/archive/2005/10/drag_and_drop_e.html). Trabajar a través de él no es divertido, ya que solo vinculó su código fuente. – Stephan

4
import javax.swing.*; 
import java.awt.event.*;  

public class movingButton extends JFrame{ 

    private JButton button ; 

    public movingButton() 
    { 
    super("Position helper"); 
     super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     super.setSize(500,520); 
     super.setVisible(true); 
     super.setLayout(null); 
     button = new JButton ("drag me "); 
     add(button); 
     button.setBounds(100, 100, 150, 40);   
     button.addMouseMotionListener(new MouseAdapter(){ 

      public void mouseDragged(MouseEvent E) 
      { 
       int X=E.getX()+button.getX(); 
       int Y=E.getY()+button.getY; 
       button.setBounds(X,Y,150,40); 
      } 
     }); 
    } 

    public static void main (String x[]) 
    {   
     new movingButton(); 
    } 
} 
+0

¿Funciona y es adecuado para lo que necesito hacer, pero el puntero del mouse está desplazado del componente real al arrastrarlo? ¿Algunas ideas? – unekwu

0

Es mejor si usted haría

int X=E.getX() + button.getX(); 
int Y=E.getY() + button.getY(); 
+0

No creo que su respuesta sea correcta: en primer lugar, no proporciona ningún comentario sobre el uso de ese fragmento y, en segundo lugar, utiliza un tamaño de letra diferente. –

Cuestiones relacionadas