我有这段代码,应该在释放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的任何线段附近。