java de déplacer des composants avec la souris

J'ai essayé de faire tout Composant déplaçable en ajoutant simplement des écouteurs de souris et en utilisant le setLocation fonction de java.awt.Component. J'ai commencé avec JButton pour tester si c'était possible, de la façon que je le pensais.

Voici un exemple de code pour ce que je suis en train de faire:

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);
    }
}

D'une certaine manière cela ne fonctionne pas correctement et je ne comprends pas pourquoi. La distance réelle traîné est la moitié de la distance de la souris mouvement et scintille autour de cette distance, tout en faisant glisser comme si deux positions souris sont en concurrence sur le MouseMotionListener.

Peut aider quelqu'un swing/awt noob? =)
Merci beaucoup à l'avance.

Edit:

Ok, donc le problème était que je ne savais pas que l'événement serait refire à chaque emplacement de souris avec le poste à relative(!) pour la cuisson de JComponent. C'est donc le corrigé et le code de travail:

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);
    }
}

Merci Adel pour vos efforts et votre mKorbel pour le lien.

Voir aussi ChessBoard.
Yep, le verre est certainement le chemin à parcourir ici, mais j'ai essayé de garder l'exemple aussi simple que possible, mais encore compilable. J'espère que ce ne pas le confondre les futurs lecteurs. UTILISATION GLASSPANE! (Ou un couches volet avec sa DRAG_LAYER)

OriginalL'auteur Stephan | 2012-01-27