我试图用Java Swing绘制线条。目标是在面板内打开图像并在该图像上绘制线条。当我尝试绘制单个行并拖动鼠标时,我会遇到这种情况:
我的代码:
// Somewhere in the code:
imgLabel= new JLabel(new ImageIcon(buffImage)); // buffImage is a BufferedImage
...
Point point1;
Point point2;
Line2D line2d;
public void draw() {
Graphics2D g1 = this.buffImage.createGraphics();
g1.setRenderingHint(enderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g1.setColor(Color.RED);
g1.setStroke(new BasicStroke(1.5f));
if (point1 != null && point2 != null) {
g1.draw(line2d);
this.imgLabel.repaint();
}
}
class ImageMouseListener extends MouseAdapter {
@Override
public void mousePressed(MouseEvent me) {
point1 = me.getPoint();
}
@Override
public void mouseDragged(MouseEvent me) {
point2 = me.getPoint();
line2d = new Line2D.Double(point1, point2);
draw();
}
}
答案 0 :(得分:4)
您为绘图提供的代码是正确的。这里的问题是,每当你移动鼠标光标时,程序将从起点到当前鼠标位置绘制另一条线,从而产生你向我们展示的效果(你只是忘记删除旧线)。
要解决此问题,每次移动鼠标时都需要:
这意味着您需要在调用mouseDragged()
时存储上一个鼠标位置。
我使用Graphics
使用JOGL代替setXORMode(Color color)
实现了非常相似的功能。这也适用于Graphics类。您可以在Graphics类here和here中阅读XOR模式
我不知道你将在你的项目中投入多少复杂性,但如果你预计会有更多的复杂性,我会建议使用像JOGL这样的库。它非常有用。
更新:解决重叠的行
这是一项更具挑战性的任务。首先,如果您有点好奇并希望完全理解为什么重叠的线会产生如此有趣的效果,我建议您阅读this。
我想唯一的方法是存储每个线坐标并在每个新线条图之后重绘它们
这是一个非常好的第一种方法。保持数据结构将所有顶点和它们关联的形状允许您继续调用repaint()
。你还必须意识到这样做,交叉点不会在你的屏幕中突出(你会看到一种颜色或另一种颜色,没有中间颜色),但这应该是你的意图。
你知道bounding box是什么吗?您可以为任何线条(或形状)创建边界框,该边框只是围绕您的点的矩形。
假设您确实为每一行保留了一个边界框。添加新行时,您可以:
这种技术比重绘整个屏幕更好,因为可能存在任意数量的行,并且您可以编写一个非常有效的算法来检查边界框交叉点。
请注意,拦截边界框并不意味着存在重叠,因为有一些例外(例如平行线)使得这是一个错误的假设。另外请记住,避免看到由于XOR模式而使用不同颜色绘制的线条交叉点的唯一方法是在没有XOR模式的情况下绘制它们。您必须非常小心地在正确的时间打开和关闭XOR模式。
我找到了一个有趣的网页,介绍了解决此问题的其他方法,您可以查看here。
答案 1 :(得分:0)
你的问题是代码的这一部分
public void mouseDragged(MouseEvent me) {
point2 = me.getPoint();
line2d = new Line2D.Double(point1, point2);
draw();
具体是line2d = new Line2D.Double(point1,point2); 它正在绘制一条拖动鼠标的新线。