Stephan
Stephan

Reputation: 163

java move components with mouse

I tried to make any Component draggable by simply adding mouse listeners and using the setLocation function of java.awt.Component. I started with JButton to test if it were possible the way i thought.

Here is a code example for what I am trying to do:

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

Somehow this fails to work properly and I don't get why. The actual distance dragged is half the distance of the mouse movement and it flickers around that distance while dragging as if two mouse positions are competing over the MouseMotionListener.

May anyone help a swing/awt noob? =) Many thanks in advance.

Edit:

Ok, so the problem was that I did not know that the event would refire at each mouse location with the position being relative(!) to the firing JComponent. So this is the corrected and working code:

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

Thanks Adel for your efforts and mKorbel for the link.

Upvotes: 16

Views: 20977

Answers (4)

shadi
shadi

Reputation: 51

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

Upvotes: 5

Marco
Marco

Reputation: 1

It is better if you would do

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

Upvotes: 0

mKorbel
mKorbel

Reputation: 109815

You have to move with JComponent, I miss this definitions in voids mousePressed/mouseDragged; in other hands, there nothing better around as @[camickr][1] excellent code for ComponentMover.

Upvotes: 13

Adel Boutros
Adel Boutros

Reputation: 10285

Why don't you use the java Transferable interface instead?

Here's a tutorial on how to do it: http://www.javaworld.com/javaworld/jw-03-1999/jw-03-dragndrop.html

Upvotes: 2

Related Questions