Reputation: 6881
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
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
Reputation: 109815
maybe have look at Moving Windows by @camickr
do not combine ComponentMover
with ComponentResizer
in the same time
Upvotes: 2
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