我有这段代码,应该在释放mousebutton时移动一些像素:

if (selected != -1) {
    Point to = e.getPoint();
    int dx = start.x - to.x;
    int dy = start.y - to.y;
    for (Point p: store.get(selected)) {
        int px = (int) p.getX();
        int py = (int) p.getY();
        p.move(px - dx, py - dy);
    }

    validate();


使用调试器显示Point p确实获得了新值,但视觉效果未得到更新。请帮帮我。

下面是我程序的全部代码。

public class Pisi extends JFrame implements MouseMotionListener, MouseListener {
ArrayList<ArrayList<Point>> store = new ArrayList<ArrayList<Point>>();
ArrayList<Point> pts = new ArrayList<Point>();
Point start;
static int xsize = 450;
static int ysize = 300;
int listNumber = 0;
int selected = -1;



public static void main(String[] args) {
    Pisi d = new Pisi();
    d.setSize(xsize, ysize);
    d.setLocationRelativeTo(null);
    d.addMouseMotionListener(d);
    d.addMouseListener(d);
    d.setResizable(false);
    d.setVisible(true);
}

@Override
public void update(Graphics g) {
    paint(g);
}
@Override
public void paint(Graphics g) {
    Point last = null;

    for (Point p : pts) {

        if (last == null) {
            last = p;
            continue;
        }
        g.drawLine(last.x, last.y, p.x, p.y);
        last = p;
    }
}

@Override
public void mouseDragged(MouseEvent e) {

    if (e.getButton() == MouseEvent.BUTTON1) {
        pts.add(e.getPoint());
        repaint();
    }

}

@Override
public void mouseMoved(MouseEvent e) {
    //To change body of implemented methods use File | Settings | File Templates.
}

@Override
public void mouseClicked(MouseEvent e) {
    //To change body of implemented methods use File | Settings | File Templates.
}

@Override
public void mousePressed(MouseEvent e) {
    Point point = e.getPoint();
    start = null;
    selected = -1;
    for (ArrayList<Point> points: store) {
        for (Point p : points) {
            double dist = point.distanceSq(p);
            if (dist < 10) {
                selected = store.indexOf(points);
            }
        }
    }
    if (selected != -1) {
        start = e.getPoint();
    }
    System.out.println(selected);
}


@Override
public void mouseReleased(MouseEvent e) {
    if (selected != -1) {
        Point to = e.getPoint();
        int dx = start.x - to.x;
        int dy = start.y - to.y;
        for (Point p: store.get(selected)) {
            int px = (int) p.getX();
            int py = (int) p.getY();
            p.move(px - dx, py - dy);
        }

        validate();
    } else if (e.getButton() == MouseEvent.BUTTON1 && pts.size() != 0) {
        store.add(new ArrayList<Point>(listNumber));
        for (int i = 0; i < pts.size(); i++) {
            store.get(listNumber).add(pts.get(i));
        }
        listNumber++;
    }
    pts.clear();

}

@Override
public void mouseEntered(MouseEvent e) {
    //To change body of implemented methods use File | Settings | File Templates.
}

@Override
public void mouseExited(MouseEvent mouseEvent) {
    //To change body of implemented methods use File | Settings | File Templates.
}
}

最佳答案

我建议:


首先,您要绘制JPanel的paintComponent(...)方法,而不是直接绘制JFrame的paint(...)方法。这将使您能够使用Swing的自动双缓冲,并且可以防止您弄乱JFrame的任何子级或边框的图形。
那不是使用ArrayList<Point>ArrayList<ArrayList<Point>>,而是使用Path2D和ArrayList<Path2D>
您将`paintComponent's Graphics对象转换为Graphics2D对象
您使用此Graphics2D对象为此目的使用draw(Shape s)方法绘制Path2D对象。
您使用Path2D contains(...)方法来查看是否在List<Path2D>所持有的Path2D对象上发生了鼠标按下
如果选择了Path2D,则可以使用AffineTransform通过transform方法移动它。


编辑:
否,contains(...)将不起作用,因为如果在Path2D所概述的凹入区域中按下鼠标,这是正确的。进一步研究...

编辑2:
解决此问题的一种方法是使用PathIterator遍历Path2D,以查看mousePress是否在构成Path2D的任何线段附近。

10-04 16:53