如何填充行之间的空格?

时间:2016-07-24 07:47:21

标签: java swing line paintcomponent

我正在尝试制作一个简单的绘画程序。我正在尝试制作像铅笔一样的工具,允许自由绘图。到目前为止,我的代码是:

NPaintMain

public class NPaintMain {
    public static void main(String[] args) {
        new NPaintWindow();
    }
}

NPaintWindow

public class NPaintWindow {
    private JFrame windowFrame;
    private String windowTitle;
    private NPaintCanvas canvas;
    private Container easel;    
    public NPaintWindow() {
        windowTitle = "NPaint - a simple paint program.";
        windowFrame = new JFrame(windowTitle);
        windowFrame.setDefaultCloseOperation(windowFrame.EXIT_ON_CLOSE);
        windowFrame.setSize(500, 500);
        windowFrame.setLocationRelativeTo(null);
        canvas = new NPaintCanvas();
        easel = windowFrame.getContentPane();
        easel.add(canvas);   
        windowFrame.setVisible(true);
    }
}

NPaintCanvas

public class NPaintCanvas extends JPanel {
    double x, y, px, py;
    ArrayList<Line2D> l;
    public NPaintCanvas() {
        new NPaintMouseEvents(this);
        x = y = px = py = 0;
        l = new ArrayList<>();
    }
    @Override
    public void paintComponent(Graphics g){
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            for(Line2D ll: l){
                g2d.draw(ll);
            }
            l.add(new Line2D.Double(px, py, x, y));
            g.dispose();
            repaint();
    }
}

NPaintMouseEvents

public class NPaintMouseEvents implements MouseListener,MouseMotionListener {

    NPaintCanvas canvas;

    public NPaintMouseEvents(NPaintCanvas canvas) {
        this.canvas = canvas;
        this.canvas.addMouseMotionListener(this);
        this.canvas.addMouseListener(this);
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        if(canvas.px == 0 && canvas.py == 0){
           canvas.px = e.getX();
            canvas.py = e.getY();
        }
        canvas.x = e.getPoint().x;
        canvas.y = e.getPoint().y;
        canvas.px = canvas.x;
        canvas.py = canvas.y;
    }
}

我的主要问题是虽然拖动了点但是它们之间有空格like this。我想加入连续线。任何有关进一步提示的帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

您正在paintXXX修改对象状态 - 这是错误的。 paint方法仅用于绘制当前状态。

您应该在MouseListener的列表中添加鼠标点,然后致电rapaint,以便在canvas中标记要重新绘制的EDT课程。

paintComponent应该始终只绘制当前列表。

所以你应该这样做:

public class NPaintCanvas extends JPanel {
    ArrayList<Line2D> l;
    public NPaintCanvas() {
        new NPaintMouseEvents(this);
        l = new ArrayList<>();
    }
    @Override
    public void paintComponent(Graphics g){
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            for(Line2D ll: l){
                g2d.draw(ll);
            }
    }
}


public class NPaintMouseEvents implements MouseListener,MouseMotionListener {

    NPaintCanvas canvas;
    Point2D prev;
    public NPaintMouseEvents(NPaintCanvas canvas) {
        this.canvas = canvas;
        this.canvas.addMouseMotionListener(this);
        this.canvas.addMouseListener(this);
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        if (prev==null) {
            prev=e.getPoint();
            return;
        }
        Point2D p = new Line2D.Double(e.getPoint().x,e.getPoint().y);
        if (p.equals(prev)) return ; //not really moved
        canvas.l.add(prev, p);
        p=prev;
        canvas.repaint();
    }
}

注意:要获得最佳解决方案,您应该保留点并使用GeneralPath

答案 1 :(得分:2)

您的问题是您为每个鼠标拖动移动绘制一个点。

对于每条绘制的线:x1和x2相同,y1和y2相同。
您应该在两个不同点之间追踪一条线。 我已经更新了你的代码,通过引入两个不同的点来处理它:prev和实际点。
简单地说,仅当前一个点和实际点具有值时才绘制线。
当绘制线时,最后一个实际绘制点成为下一个绘制线的前一个点。这样,线之间就没有孔了。

在画布类:

if (previousPoint != null && actualPoint != null) {
     l.add(new Line2D.Double(previousPoint.x, previousPoint.y, actualPoint.x, actualPoint.y));
     previousPoint = new Point(actualPoint.x, actualPoint.y);
}

如果松开鼠标按钮,则先前和实际点将设置为空。

在Event类中:

 @Override
    public void mouseReleased(MouseEvent e) {
      canvas.mouseReleased();
    }

在画布类:

  public void mouseReleased() {
    previousPoint = null;
    actualPoint = null;
  }

通过这种方式,您可以根据需要以独立方式绘制多条线。

此外,我通过使用Point实例(而不是双打)简化了代码,它使用了坐标的int,但是你可以使用多个双打字段,它在实践中不会改变很多东西。

package paint;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Line2D;

import java.util.ArrayList;

import javax.swing.JPanel;

public class NPaintCanvas extends JPanel {
    ArrayList<Line2D> l;
    Point actualPoint;
    Point previousPoint;

    public NPaintCanvas() {
    new NPaintMouseEvents(this);
      l = new ArrayList<>();
    }



  @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        for (Line2D ll : l) {
            g2d.draw(ll);
        }
        if (previousPoint != null && actualPoint != null) {
            l.add(new Line2D.Double(previousPoint.x, previousPoint.y, actualPoint.x, actualPoint.y));
            previousPoint = new Point(actualPoint.x, actualPoint.y);
        }
        g.dispose();
        repaint();
    }

    public void mouseReleased() {
        previousPoint = null;
        actualPoint = null;
    }

    public void mousePressed(int x, int y) {
        previousPoint = new Point(x, y);
    }
}

NPaintMouseEvent

package paint;

import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

public class NPaintMouseEvents implements MouseListener, MouseMotionListener {

    NPaintCanvas canvas;

    public NPaintMouseEvents(NPaintCanvas canvas) {
      this.canvas = canvas;
      this.canvas.addMouseMotionListener(this);
      this.canvas.addMouseListener(this);
    }

    @Override
    public void mouseDragged(MouseEvent e) {
      if (canvas.actualPoint == null) {
         canvas.actualPoint = new Point();
      }
      canvas.actualPoint.x = e.getPoint().x;
      canvas.actualPoint.y = e.getPoint().y;
    }

    @Override
    public void mouseMoved(MouseEvent e) {
    }

    @Override
    public void mouseClicked(MouseEvent e) {
    }

    @Override
    public void mousePressed(MouseEvent e) {
      canvas.mousePressed((int) e.getX(), (int) e.getY());
    }

    @Override
    public void mouseReleased(MouseEvent e) {
      canvas.mouseReleased();
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }
}