3

クリックで追加JPanelJFrameていJButtonます。フレームに を追加しJPanelます。ボタンはクリックイベントでJPaneltoを追加し続けます。JFrame制限はありません。ボタンがクリックされたときにもJPanelsaに追加しています。これは、 for ループを使用して JPanel のドラッグを処理するListために追加したためです。MouseMotionListener

私が今直面している問題は、ドラッグにあります。クリックで最初のものを追加してJPanelドラッグすると、マウスカーソルの座標に正しく追従します。秒を追加するとJPanel、それもマウスに完全に追従します。2 つ目を追加した後、最初の 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();
            }
        });

    }


}
4

3 に答える 3

7

JPanel が 1 つだけリストに追加されると、handleDrag メソッドがすべての JPanel に新しい匿名リスナーを追加しているようです。リスナーを追加する必要があるのは 1 回だけです。複数のリスナーを追加すると、動作がおかしくなります。

ここに更新された 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());
            }

        });
}
于 2012-10-02T17:50:56.387 に答える
5

ジョーは正しいです。これは、私のプロジェクトの 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());
        }
    });
}

このようにして、パネルをクリックしたときに最初の「ジャンプ」が行われません。

于 2013-09-16T15:52:36.957 に答える
2
  • @camickrのMoving Windows を見てください。

  • 同時に結合ComponentMoverしないComponentResizer

于 2012-10-02T18:38:21.030 に答える