0

画面に円を表示しようとしています。次に、ユーザーが円の内側をクリックすると、マウスが押されている間に円をドラッグできるようになります。

これは私がこれまでに持っているコードです。ドラッグは機能しますが、画面上のどこかが押されたときに、ユーザーが円の内側を押さずにドラッグできるようにします。

あまり混乱しないことを願っています

これが私が持っているコードです。修正が必要なコードを誰かが教えてくれれば、もう何時間も節約できます。

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class DragCircle extends JFrame {
    private static final long serialVersionUID = 1L;

    public static int size = 400;

    public static int r = 10;

    private int x;

    private int y;

    private int cX;

    private int cY;

    private int dX;

    private int dY;

    private MouseHandler mh;

    boolean isCircleClicked = false;

    public static void main(String[] args) {
        DragCircle c1 = new DragCircle();
        c1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    }

    public DragCircle() {

        super("Drag circle");

        cX = r + 100;
        cY = r + 100;

        mh = new MouseHandler();
        addMouseListener(mh);
        addMouseMotionListener(mh);

        setSize(size, size);
        setVisible(true);

    }

    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(Color.RED);
        g.fillOval(cX, cY, r * 2, r * 2);

    }

    private class MouseHandler extends MouseAdapter implements
            MouseMotionListener {
        public void mousePressed(MouseEvent me)

        {

            if ((cX - me.getX()) * (cX - me.getX()) + (cY - me.getY())
                    * (cY - me.getY()) < r * r) {
                isCircleClicked = true;
            }
        }

        public void mouseDragged(MouseEvent me) {
            if (isCircleClicked) {

                x = me.getX() - dX;
                y = me.getY() - dY;
                cX = x + r;
                cY = y + r;
                repaint();
            }
        }

        public void mouseReleased(MouseEvent e) {
            isCircleClicked = false;
        }

    }

}
4

2 に答える 2

2

あなたの1つの問題は

public void mouseDragged(MouseEvent me) {
    if (isCircleClicked = true) {

ここで行っているのは、マウスをドラッグするたびに設定isCircleClickedすることです。trueまた、このステートメントtrueは、どこにでもドラッグして円を移動できる理由を評価します。これをに変更

 if (isCircleClicked) {

あなたはここで大丈夫なはずです。

次の問題は、決して にリセットisCircleClickedしないことですfalse。これを行うか、次のようにmouseReleased変更する必要があります。mousePressed

public void mousePressed(MouseEvent me) {
    isCircleClicked =
        (cX - me.getX()) * (cX - me.getX()) +
        (cY - me.getY)) * (cY - me.getY()) < r * r;
}

それに応じて設定isCircleClickedされます。

ただし、まだやるべきことがあります。現在のフォームでは、以下に示すように、中心点の左上にドラッグを開始する必要があります。

+--------+
| | | |
| | .-|-.
| | / | \
+--------+ |
    \ /
     「-_-」

これはあなたの描画によるものです:fillOvalは、楕円の左上隅と、外接する四角形の幅と高さを取ります。中心点とそれぞれの直径ではありません。したがって、彼を次のように適応させる必要があります。

g.fillOval(cX - r, cY - r, r * 2, r * 2);

左と上への半径によるオフセットに注意してください。

さらに、ドラッグ コードにはもう少し作業が必要です。現在、ユーザーが円の中心をドラッグすると想定しています。必要なことは、マウス クリックの座標を保存し、最後の点に対するマウスの動きに基づいて円を移動することです。現在、円の中心に対して相対的に移動しているため、動きを良くするには、円の中心で正確にドラッグを開始する必要があります。私はあなたのための練習としてそれを残します:-)

さらに、リスナー クラスはすでに MouseAdapter を継承しているため、MouseAdapter が既に実装しているため、MouseMotionListener を明示的に実装する必要はありません。

于 2009-12-10T07:48:43.137 に答える
0

プログラムの構造が間違っています。JFrame の paint(...) メソッドをオーバーライドしないでください。これは古い AWT のトリックであり、Swing では使用しないでください。

適切なペイント方法の例については、カスタム ペイントに関する Swing チュートリアルのセクションを参照してください。基本は、JPanel の paintComponent(...) メソッドをオーバーライドしてから、パネルをフレームのコンテンツ ペインに追加することです。

あなたの質問に関して、より良い解決策は、円を表す Ellipse2D オブジェクトを作成することです。次に、カスタム ペインティングで Graphics2D クラスの drawShape(...) メソッドを使用できます。次に、MouseListener コードで、Shape.contains(...) メソッドを使用して、マウスが円をクリックしたかどうかを確認できます。

于 2009-12-10T07:37:18.447 に答える