在鼠标拖动时移动 Ellipse2D

Moving an Ellipse2D on mouse drag

正如标题所述,我想在鼠标拖动时移动椭圆。我首先声明了椭圆并通过 ArrayLists 绘制它们(因为我有 8 个椭圆,它们带有不同的颜色信息。四个是白色的,另一个是红色的)。我试着做我为矩形所做的事情:

public void mousePressed(MouseEvent e)
{
    x = e.getX();
    y = e.getY();
}

public void mouseDragged(MouseEvent e)
{   
    if(e.getSource()==MainPane)
    {
        int dx = e.getX() - x;
        int dy = e.getY() - y;
        Point p = getLocation();

        if(el1.getBounds().contains(x,y))
        {
            el1.x += dx;
            el1.y += dy;
        }
        x += dx;
        y += dy;
    }
}

但这似乎不起作用。它给我一个错误

cannot find symbol
symbol: variable x
location: <ellipse name> of type Ellipse2D

我有点困惑,因为我已经阅读了文档并且 Ellipse2D.Double.

存在这样的变量

这是一个 MCVE:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.awt.geom.AffineTransform;
import java.util.ArrayList;

public class Sample extends JFrame implements MouseListener, MouseMotionListener {

    JPanel MainPane;    
    Container contentPane;  
    ArrayList<Ellipse2D> redEl = new ArrayList<Ellipse2D>();
    ArrayList<Ellipse2D> whiteEl = new ArrayList<Ellipse2D>();
    Ellipse2D el1 = new Ellipse2D.Double(120,110,50, 50);
    Ellipse2D el2 = new Ellipse2D.Double(250,110,50, 50);
    Ellipse2D el3 = new Ellipse2D.Double(390,110,50, 50);
    Ellipse2D el4 = new Ellipse2D.Double(540,110,50, 50);
    Ellipse2D el5 = new Ellipse2D.Double(120,390,50, 50);
    Ellipse2D el6 = new Ellipse2D.Double(250,390,50, 50);
    Ellipse2D el7 = new Ellipse2D.Double(390,390,50, 50);
    Ellipse2D el8 = new Ellipse2D.Double(540,390,50, 50);
    int x;
    int y;

    public Sample(){

        redEl.add(el1);
        redEl.add(el2);
        redEl.add(el3);
        redEl.add(el4);
        whiteEl.add(el5);
        whiteEl.add(el6);
        whiteEl.add(el7);
        whiteEl.add(el8);

        MainPane = new JPanel()
        {
            public void paintComponent(Graphics g)
            {
                super.paintComponent(g);

                Graphics2D g2 = (Graphics2D) g; 

                    for (Shape red : redEl) {
                        g2.setColor(Color.RED);
                        g2.fill(red);
                        g2.draw(red);
                    }

                    for (Shape white : whiteEl) {
                        g2.setColor(Color.WHITE);
                        g2.fill(white);
                        g2.draw(white);
                    }
            }
        };  

        MainPane.setBackground(Color.BLACK);
        contentPane = this.getContentPane();
        contentPane.add(MainPane);
        MainPane.setLayout(null);

        setVisible(true);
        setSize(701, 701);
        setResizable(false);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

        MainPane.addMouseListener(this);
        MainPane.addMouseMotionListener(this);
        }

    public void mousePressed(MouseEvent e)
    {
        x = e.getX();
        y = e.getY();
    }

    public void mouseClicked(MouseEvent e){}
    public void mouseReleased(MouseEvent e){}
    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}

    public void mouseDragged(MouseEvent e)
    {   
        if(e.getSource() == MainPane)
        {
            int dx = e.getX() - x;
            int dy = e.getY() - y;

            if(el1.getBounds().contains(x,y))
            {

            }
            x += dx;
            y += dy;
        }
    }
    public void mouseMoved(MouseEvent e){}


    public static void main(String args[])
    {
        new Sample();
    }

}

那么是否有替代算法,或者我只是在语法中遗漏了一些东西?我想知道解决方案。谢谢。

更新:

通过MadProgrammer的建议解决了

这是我的 mouseDragged 方法。

public void mouseDragged(MouseEvent e)
{   
    if(e.getSource()==MainPane)
    {
        int dx = e.getX() - x;
        int dy = e.getY() - y;
        Point p = getLocation();

        if(el1.getBounds().contains(x,y))
        {
            double xc = el1.getX();
            double yc = el1.getY();
            el1.setFrame(xc+=dx, yc+=dy, 50, 50);
            MainPane.repaint();
        }
        x += dx;
        y += dy;
    }
}

所以通过 JavaDocs for Ellipse2D 查看一下,很明显 Ellipse2D 没有公开公开 x/y 属性。

相反,您必须改用 setFrame 方法之一。

这个例子是对你的例子的轻微修改,它决定了当 mousePressed 事件发生时应该移动哪个椭圆,因为在我看来,在mouseDragged 事件,除非你想把所有的省略号都捡起来。它还定义了 "click" 点和椭圆位置之间的偏移量,因此它们不会 "jump" 到鼠标的位置。

import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Sample extends JFrame implements MouseListener, MouseMotionListener {

    JPanel MainPane;
    Container contentPane;
    ArrayList<Ellipse2D> redEl = new ArrayList<Ellipse2D>();
    ArrayList<Ellipse2D> whiteEl = new ArrayList<Ellipse2D>();
    Ellipse2D el1 = new Ellipse2D.Double(120, 110, 50, 50);
    Ellipse2D el2 = new Ellipse2D.Double(250, 110, 50, 50);
    Ellipse2D el3 = new Ellipse2D.Double(390, 110, 50, 50);
    Ellipse2D el4 = new Ellipse2D.Double(540, 110, 50, 50);
    Ellipse2D el5 = new Ellipse2D.Double(120, 390, 50, 50);
    Ellipse2D el6 = new Ellipse2D.Double(250, 390, 50, 50);
    Ellipse2D el7 = new Ellipse2D.Double(390, 390, 50, 50);
    Ellipse2D el8 = new Ellipse2D.Double(540, 390, 50, 50);
    int x;
    int y;
    private Point2D.Double offSet;

    public Sample() {

        redEl.add(el1);
        redEl.add(el2);
        redEl.add(el3);
        redEl.add(el4);
        whiteEl.add(el5);
        whiteEl.add(el6);
        whiteEl.add(el7);
        whiteEl.add(el8);

        MainPane = new JPanel() {
            public void paintComponent(Graphics g) {
                super.paintComponent(g);

                Graphics2D g2 = (Graphics2D) g;

                for (Shape red : redEl) {
                    g2.setColor(Color.RED);
                    g2.fill(red);
                    g2.draw(red);
                }

                for (Shape white : whiteEl) {
                    g2.setColor(Color.WHITE);
                    g2.fill(white);
                    g2.draw(white);
                }
            }
        };

        MainPane.setBackground(Color.BLACK);
        contentPane = this.getContentPane();
        contentPane.add(MainPane);
        MainPane.setLayout(null);

        setVisible(true);
        setSize(701, 701);
        setResizable(false);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        MainPane.addMouseListener(this);
        MainPane.addMouseMotionListener(this);
    }

    private Ellipse2D selected = null;

    public void mousePressed(MouseEvent e) {
        x = e.getX();
        y = e.getY();
        List<Ellipse2D> all = new ArrayList<>(redEl);
        all.addAll(whiteEl);
        for (Ellipse2D el : all) {
            if (el.contains(x, y)) {
                selected = el;
                offSet = new Point2D.Double(x - el.getX(), y - el.getY());
                break;
            }
        }
    }

    public void mouseClicked(MouseEvent e) {
        selected = null;
    }

    public void mouseReleased(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public void mouseDragged(MouseEvent e) {

        if (selected != null) {

            double x = e.getX() - offSet.x;
            double y = e.getY() - offSet.y;

            Rectangle2D bounds = selected.getBounds2D();
            bounds.setFrame(new Rectangle2D.Double(x, y, bounds.getWidth(), bounds.getHeight()));

            selected.setFrame(bounds);
            repaint();

        }
    }

    public void mouseMoved(MouseEvent e) {
    }

    public static void main(String args[]) {
        new Sample();
    }

}