Java 拖动JPanel';在JFrame内

Java 拖动JPanel';在JFrame内,java,swing,jframe,jpanel,drag,Java,Swing,Jframe,Jpanel,Drag,我正在单击JButton按钮,将JPanel添加到JFrame。它将JPanel添加到帧中。该按钮将继续将JPanel添加到JFrame点击事件中。没有限制。单击按钮时,我也会将JPanels添加到列表中。我之所以这样做是因为添加了MouseMotionListener使用for循环来处理JPanel的拖动 我现在面临的问题是阻力。当我单击添加第一个JPanel时,如果我拖动它,它会正确地跟随鼠标光标坐标。当我添加第二个JPanel时,它也会完美地跟随鼠标。添加第二个后,如果尝试拖动第一个JPa

我正在单击
JButton
按钮,将
JPanel
添加到
JFrame
。它将
JPanel
添加到帧中。该按钮将继续将
JPanel
添加到
JFrame
点击事件中。没有限制。单击按钮时,我也会将
JPanels
添加到
列表中。我之所以这样做是因为添加了
MouseMotionListener
使用for循环来处理JPanel的拖动

我现在面临的问题是阻力。当我单击添加第一个
JPanel
时,如果我拖动它,它会正确地跟随鼠标光标坐标。当我添加第二个
JPanel
时,它也会完美地跟随鼠标。添加第二个后,如果尝试拖动第一个JPanel,则第一个JPanel似乎遵循不同的坐标,如,初始位置将更改为其他位置。我不知道我在哪里犯了这个错误。请帮我解决这个问题。请通读下面的代码

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

    }


}
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.MouseEvent;
导入java.awt.event.MouseMotionAdapter;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.SwingUtilities;
公共类MyFrame扩展了JFrame{
按钮;
List mypanels=new ArrayList();
公共MyFrame(){
jb=新的JButton(“添加面板”);
jb.立根(10,10,100,50);
设置尺寸(新尺寸(1000600));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(空);
添加(jb);
setVisible(真);
初始化();
}
公共无效初始化(){
jb.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件arg0){
//TODO自动生成的方法存根
JPanel面板=新的JPanel();
立根盘(150200200);
面板.立根背景(颜色.黑色);
添加(面板);
添加(面板);
重新油漆();
把手抹布();
}
});
}
公共无效手册(){

对于(int i=0;i,当列表中只添加了一个JPanel时,handleDrag方法似乎正在向每个JPanel添加一个新的匿名侦听器。只需添加一次侦听器,如果添加了多个侦听器,行为将变得怪异

下面是一个更新的handleDrag方法

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

        });
}
  • 也许你可以看看

  • 不要同时将
    ComponentMover
    ComponentResizer
    组合


    • 乔是正确的,这就是我在项目中对handleDrag方法的理解:

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

      这样,面板在单击时不会进行初始“跳转”。

      您是否在GUI数据模型中的某个位置存储JPanel的边界?不,我没有存储JPanel的任何边界。那么,您如何知道它们被拖动后在何处?我不知道为什么要这样做的实现细节,但您考虑过吗使用类似?(还有,its)的工具进行编程。只是确保您不会不必要地重新发明轮子:)@Gilbert,我在translate()中使用了me.getComponent().getLocation().x。我认为它给出了发生单击事件的特定JPanel的位置。+1,但您应该声明方法参数本身为final,而不仅仅是方法体中的一个相似对象。