Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 524
Stephan Avatar asked Jan 27 '12 16:01

Stephan


3 Answers

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.

like image 193
mKorbel Avatar answered Sep 22 '22 14:09

mKorbel


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();
    }
}
like image 5
shadi Avatar answered Sep 22 '22 14:09

shadi


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

like image 2
Adel Boutros Avatar answered Sep 19 '22 14:09

Adel Boutros