Java中的写意画

时间:2011-10-20 22:41:20

标签: java awt java-2d mouselistener

我一直在写这个小小的绘画程序,但每当我释放鼠标并移动到屏幕上的另一个点时,就会在那里绘制线条。当鼠标被释放时我尝试清除点,但是删除了屏幕上的所有内容。

import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;

public class PaintingCanvas extends Canvas implements MouseMotionListener, MouseListener {

    private ArrayList<Point> points = new ArrayList<Point>();

    public PaintingCanvas(int width, int height) {
        setBounds(0, 0, width, height);
        addMouseMotionListener(this);
        addMouseListener(this);
    }

    public void paint(Graphics g) {

        for (int i = 0; i < points.size() - 2; i++) {
            Point p1 = points.get(i);
            Point p2 = points.get(i + 1);
            g.drawLine(p1.x, p1.y, p2.x, p2.y);
        }

    }

    @Override
        public void mouseDragged(MouseEvent e) {
        points.add(e.getPoint());
        repaint();
    }

}

6 个答案:

答案 0 :(得分:2)

我建议:

  • 首先在paint方法中调用super.paint(g);方法。
  • 释放鼠标时,将点ArrayList表示的图像绘制到BufferedImage,然后清除点ArrayList,然后调用repaint()
  • 在paint方法中绘制BufferedImage。在绘制线条之前(但先检查它是否为空)。您可以使用Graphics#drawImage(Image image, int x, int y, ...)方法执行此操作。
  • 更好,通过在JPanel的paintComponent方法中绘画,将其重写为在Swing中工作。

答案 1 :(得分:1)

当然这种情况正在发生 - 一旦你再次开始绘画,新的点就会在旧的点之后添加。一旦你在那之后画画,他们就包括在内。你需要分开彼此不同的路径。

答案 2 :(得分:1)

你看过Path类了吗?如果您只是将离散线绘制到屏幕上,GeneralPath类可能是一个简单的解决方案。

Drawing Arbitrary Shapes教程解释了如何使用它们。

基本上,每次用户按下鼠标(在mousePressed事件上),您都会调用路径的moveTo(x, y)方法。对于每个细分(替换您当前在mouseDragged()方法中执行的操作),您将调用路径的lineTo(x, y)方法。

无论如何,你 - 无限期地 - 需要处理mousePressedmouseReleased事件,或两者兼而有之,因为你正在寻找某种方式来指示新线路/路径的开始,而不是使用旧的。

答案 3 :(得分:1)

private void jPanel1MouseDragged(java.awt.event.MouseEvent evt) {
    points.add(evt.getPoint());

    for (int i = 0; i < points.size() - 2; i++)
    {
         Point p1 = points.get(i);
         Point p2 = points.get(i + 1);

       jPanel1.getGraphics().drawLine(p1.x, p1.y, p2.x, p2.y);
    }

}
private void jPanel1MousePressed(java.awt.event.MouseEvent evt) {
    points.clear();
    points.add(evt.getPoint());
}

答案 4 :(得分:0)

我会制作一个2d arraylist,其中第一个数组是添加的点,直到你抬起手指然后为第二行添加一个新数组等...

答案 5 :(得分:0)

-1,-1方法中的points方法中插入垃圾点mouseReleased并在paint方法中检查它并跳过该点。更新的代码:

@Override   
public void mouseReleased(MouseEvent e) {

    points.add(new Point(-1, -1));

}

@Override 
public void paint(Graphics g) {

    for (int i = 0; i < points.size() - 1; i++) {

        Point p = points.get(i+1);

        int x2 = p.x;
        int y2 = p.y;

        if ( x2 == -1 || y2 == -1) {
            ++i;
            //continue // Considered bad practice, can play havoc with your system. (source http://xkcd.com/292/ ).
        }
        else {
            p = points.get(i);
            int x1 = p.x;
            int y1 = p.y;
            g.drawLine(x1, y1, x2, y2);
        }
    }
}
OP,3年后看到这个问题的感觉如何? :d