Java 6:如何拖动/移动一条线?

时间:2013-01-12 21:11:58

标签: java paint move point repaint

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

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.
}
}

2 个答案:

答案 0 :(得分:4)

我建议:

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

修改
不,contains(...)将不起作用,因为如果在Path2D概述的凹陷区域中按下鼠标,则为真。进一步研究......

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

答案 1 :(得分:0)

我建议您先尝试validate()方法(Container类的方法)

注意: information on validate() method

如果validate()方法不起作用,请尝试使用:

update()方法(调用paint()方法)或repaint()方法。