Vinay
Vinay

Reputation: 6881

Dragging JPanel's inside JFrame

I am adding JPanel to JFrame on a JButton click. It adds the JPanel to the frame. The button will keep on adding the JPanel to JFrame on click event. There are no limitations. I am adding the JPanels to a List as well when a button is clicked. I did this because of adding the MouseMotionListener using for loop to handle Dragging of JPanel's.

The problem which I am facing now is with the drag. When I add the first JPanel with a click and if I drag it, it follows the Mouse cursor coordinates properly. When I add a second JPanel, it too follows the mouse perfectly. After adding the second, if try to drag the first JPanel the first JPanel seems to follow different coordinates like, the initial position will change to some other location. I don't know where have I done the mistake. Please help me resolve this problem. Please go through the code below.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class MyFrame extends JFrame {

    JButton jb;
    List<JPanel> mypanels = new ArrayList<JPanel>();
    public MyFrame() {
        jb = new JButton("Add Panel");
        jb.setBounds(10, 10, 100, 50);
        setSize(new Dimension(1000, 600));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(null);
        add(jb);
        setVisible(true);
        initialize();
    }


    public void initialize() {

        jb.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                JPanel panel = new JPanel();
                panel.setBounds(150,150,200,200);
                panel.setBackground(Color.black);
                mypanels.add(panel);
                add(panel);
                repaint();
                handleDrag();
            }
        });

    }

    public void handleDrag(){
        for(int i=0;i<mypanels.size();i++) {
            final int j = i;
            mypanels.get(i).addMouseMotionListener(new MouseMotionAdapter() {

                @Override
                public void mouseDragged(MouseEvent me) {
                    me.translatePoint(me.getComponent().getLocation().x, me.getComponent().getLocation().y);
                    mypanels.get(j).setLocation(me.getX(), me.getY());
                }

            });
        }
    }

    public static void main(String args[]) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                // TODO Auto-generated method stub
                new MyFrame();
            }
        });

    }


}

Upvotes: 3

Views: 8102

Answers (3)

robokop
robokop

Reputation: 91

Joe is correct, this is what I made of the handleDrag method in my project:

public void handleDrag(final JPanel panel){
    panel.addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent me) {
             x = me.getX();
             y = me.getY();
        }
    });
    panel.addMouseMotionListener(new MouseMotionAdapter() {
        @Override
        public void mouseDragged(MouseEvent me) {
            me.translatePoint(me.getComponent().getLocation().x-x, me.getComponent().getLocation().y-y);
            panel.setLocation(me.getX(), me.getY());
        }
    });
}

This way the panel doesn't make an initial 'jump' when clicking on it.

Upvotes: 5

mKorbel
mKorbel

Reputation: 109815

Upvotes: 2

Joe
Joe

Reputation: 366

It looks like your handleDrag method is adding a new anonymous Listener to every JPanel when just one JPanel is added to the List. The listener only needs to be added once, if more than one listener is added the behavior will get weird.

here is an updated handleDrag method

    public void handleDrag(JPanel panel){
    final JPanel p = panel;
        panel.addMouseMotionListener(new MouseMotionAdapter() {

            @Override
            public void mouseDragged(MouseEvent me) {
                me.translatePoint(me.getComponent().getLocation().x, me.getComponent().getLocation().y);
                p.setLocation(me.getX(), me.getY());
            }

        });
}

Upvotes: 7

Related Questions