用Java swing画一条线会画多条线 [英] Drawing a line with Java swing draws multiple lines

查看:98
本文介绍了用Java swing画一条线会画多条线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Java Swing画线.目的是在面板内部打开图像并在该图像上绘制线条.当我尝试画一条线并拖动鼠标时,会出现以下现象:

I'm trying to draw lines with Java Swing. The goal is to open an image inside the panel and draw lines on that image. When I try to draw a single line and drag the mouse, I get this behavior:

我的代码:

// 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();
    }   
}

推荐答案

您提供的绘图代码正确.这里的问题是,每当您移动鼠标光标时,该程序都会从​​起点到当前鼠标位置绘制另一条线,从而产生向您展示的效果(您只是忘记删除旧行).

The code you provide for drawing is correct. The issue here is that whenever you move your mouse cursor, the program is going to draw another line from the starting point to your current mouse position, resulting in the effect you show us (you're just forgetting to delete the old line).

要解决此问题,每次移动鼠标时,您需要:

To fix this, every time the mouse is moved you need to:

  1. 使用 XOR模式重新绘制上一行/li>
  2. 画第二行.
  1. Draw the previous line again using XOR mode
  2. Draw the second line.

这意味着您需要在调用 mouseDragged()时存储先前的鼠标位置.

This means you need to store the previous mouse position for when mouseDragged() is called.

我使用 JOGL 代替了 Graphics ,实现了非常相似的功能,使用 setXORMode(Color color).这也可用于Graphics类.您可以在此处中了解有关XOR模式的信息.和此处.
我不知道您要在项目中增加多少复杂性,但是如果您预计会有更多的复杂性,我建议您使用JOGL之类的库.非常有用.

I implemented something very similar using JOGL instead of Graphics, using setXORMode(Color color). This is also available for the Graphics class. You can read about the XOR mode in the Graphics class here and here.
I don't know how much complexity you're going to put on your project, but if you're anticipating more complexity I would advise using a library like JOGL. It's VERY useful.

更新:解决重叠的行

这是一项更具挑战性的任务.首先,如果您好奇并想完全理解重叠的行为什么会产生如此吸引人的效果,我建议您阅读

This is a more challenging task. First, if you're curious and want to fully understand why overlapped lines produce such an intriguing effect, I would advise you to read this.

我想唯一的方法是存储每个线坐标,并在每次绘制新线后重新绘制它们.

I guess the only way is to store every line coordinates and redraw them after each new line drawing

这是一个非常好的第一种方法.保留数据结构将使所有顶点及其关联的形状使您能够继续调用 repaint().您还必须注意,这样做时,相交点将不会在屏幕上突出显示(您将看到一种线色或另一种线色,没有中间色),但这已经是您的意图.

This is a very good first approach. Keeping a data structure will all vertices and the shapes they are associated with would allow you to keep calling repaint(). You must also be aware that in doing so the intersect points will not stand out in your screen (you'll see either one line color or the other, no intermediate colors), but this should already be your intent.

您知道边界框是什么吗?您可以为任何线条(或形状)创建边界框,该边界框只是围绕您的点的矩形.

Do you know what a bounding box is? You can create a bounding box for any line (or shape) which is just a rectangle that surrounds your points.

假设您确实为每行保留了一个边框.添加新行时,您可以:

Let's assume you do in fact keep a bounding box for each line. When adding a new line, you could:

  1. 检查您要绘制的线是否与边界框相交
  2. 如果是,请重新绘制与这些边界框关联的所有线
  3. 添加没有XOR模式的新行

此技术比重新绘制整个屏幕更好,因为可能已经存在任意数量的线,并且您可以编写一种效率很高的算法来检查边界框的交点.

This technique is better than redrawing the entire screen because there could be an arbitrary number of lines already present, and you can write a decently efficient algorithm to check for bounding box intersections.

请注意,拦截边界框并不意味着存在重叠,因为存在一些例外情况(例如,平行线),这会导致错误的假设.还请记住,避免看到由于XOR模式而涂有不同颜色的线相交的唯一方法是在不使用XOR模式的情况下绘制它们.您将必须非常小心,在正确的时间打开和关闭XOR模式.

Note that intercepting a bounding box does not imply that there is overlapping, because there are some exceptions (e.g. parallel lines) that make this a wrong assumption. Also keep in mind that the only way to avoid seeing line intersections painted with a distinct color due to XOR mode is to draw them without XOR mode. You will have to be very careful toggling XOR mode on and off at the right times.

我找到了一个有趣的页面,其中介绍了解决此问题的其他方法,您可以检查它此处.

I found an interesting page about additional ways you could tackle this problem, you can check it here.

这篇关于用Java swing画一条线会画多条线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆