java move components with mouse

19,905

Solution 1

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.

Solution 2

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

Solution 3

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

Share:
19,905
Stephan
Author by

Stephan

Updated on June 04, 2022

Comments

  • Stephan
    Stephan almost 2 years

    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.

  • Stephan
    Stephan over 12 years
    Does java.awt.dnd support the moving animation of components? I do not need the data dropping portion of Drag and Drop (well I do need it but thats a minor problem) rather than the animation itself. The most tutorials I found only described the data transfer portion, where only the cursor indicates a drag and drop. I want the whole Component to move. (sry for my english^^)
  • Adel Boutros
    Adel Boutros over 12 years
    @Stephan Transferable comes from the package java.awt.datatransfer So it can support drag and drop in awt
  • Stephan
    Stephan over 12 years
    Sry, but this does not answer my question, however I found a working example of a drag and drop animation(!) using java.awt.dnd and java.awt.datatransfer: link. Working through it is not fun though, since he only linked his source code.
  • Stephan
    Stephan over 12 years
    I read through those articles but in my understanding it is not common to make a drag animation without using Graphics and drawing it manually. So I even more want my approach to work. =) If it is even possible that way, that is...
  • Adel Boutros
    Adel Boutros over 12 years
    The interface i proposed to you is what we are using in your company. The only problem is that it's not me who does it, i just use it. So can't help you on that. Sorry
  • Stephan
    Stephan over 12 years
    Oh my god, thank you so much for that link! The first few sentances made me hit my head. ^^ I edited my post to show the correct code.
  • Stephan
    Stephan about 12 years
    Well I could not, quite recently. ;)
  • Eel Lee
    Eel Lee over 10 years
    I don't think your answer is proper - firstly you don't provide any comment about using that snippet, and secondly you're using different letter size.
  • Emmanuel John
    Emmanuel John over 9 years
    Works and adequate for what I need to do but mouse pointer is offset from the actual component when dragging? Any ideas?
  • Emmanuel John
    Emmanuel John over 9 years
    +1 for ComponentMover. Saved me a lot of trouble. Thanks
  • Ryan
    Ryan over 7 years
    I know this is old, but do you know how to get ComponentMover to work on multiple monitors?
  • mKorbel
    mKorbel over 7 years
    @Ryan no idea right now, nor in Java8 (can't awaiting some changes in comparing with Java6), is there some issue with, then create a new question with description about issue, link to code repository, your code and Java version, event. with Native OS, maybe someone can test that :-)