Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何填充行之间的空格?_Java_Swing_Line_Paintcomponent - Fatal编程技术网

Java 如何填充行之间的空格?

Java 如何填充行之间的空格?,java,swing,line,paintcomponent,Java,Swing,Line,Paintcomponent,我正在尝试制作一个简单的绘画程序。我想做一个像铅笔这样的工具,可以自由画画。到目前为止,我的代码是: NPaintMain NPAINT窗口 NPaintCanvas 我这里的主要问题是,当拖动时,会绘制点,但它们之间有空间。我要加入连续线。如果您有任何进一步的建议,我们将不胜感激 您正在修改paintXXX中的对象状态-这是错误的。 绘制方法仅用于绘制当前状态 您应该在MouseListener中将鼠标点添加到列表中,并调用rapaint来标记要在EDT中重新绘制的画布类 和paintComp

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

NPaintMain

NPAINT窗口

NPaintCanvas


我这里的主要问题是,当拖动时,会绘制点,但它们之间有空间。我要加入连续线。如果您有任何进一步的建议,我们将不胜感激

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

您应该在MouseListener中将鼠标点添加到列表中,并调用rapaint来标记要在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。

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

您应该在MouseListener中将鼠标点添加到列表中,并调用rapaint来标记要在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。

您的问题是每次拖动鼠标时都会画一个点

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

在画布类中:

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);
}
  public void mouseReleased() {
    previousPoint = null;
    actualPoint = null;
  }
如果释放鼠标按钮,上一个点和实际点将设置为null

在事件类中:

 @Override
    public void mouseReleased(MouseEvent e) {
      canvas.mouseReleased();
    }
在画布类中:

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);
}
  public void mouseReleased() {
    previousPoint = null;
    actualPoint = null;
  }
这样,如果需要,可以以独立的方式绘制多条直线。

此外,我还通过使用点实例而不是double简化了代码。double使用整数表示坐标,但您可以使用多个double字段,在实践中不会有太多变化

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

您的问题是,每次鼠标拖动都会绘制一个点

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

在画布类中:

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);
}
  public void mouseReleased() {
    previousPoint = null;
    actualPoint = null;
  }
如果释放鼠标按钮,上一个点和实际点将设置为null

在事件类中:

 @Override
    public void mouseReleased(MouseEvent e) {
      canvas.mouseReleased();
    }
在画布类中:

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);
}
  public void mouseReleased() {
    previousPoint = null;
    actualPoint = null;
  }
这样,如果需要,可以以独立的方式绘制多条直线。

此外,我还通过使用点实例而不是double简化了代码。double使用整数表示坐标,但您可以使用多个double字段,在实践中不会有太多变化

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

有很多方法可以实现这一点。1在当前点和最后一点之间绘制线条2D。2将所有点添加到常规路径,并在每次添加新点时绘制该路径。顺便说一句:为了更快地得到更好的帮助,发布一个or。在这种情况下,要做到这一点,除了mainString[]类之外,有必要将所有类都缩减为默认值,并在nPainMain的末尾将它们放在后面,然后添加导入。@AndrewThompson我不确定是否正确。请参阅编辑后的注释。。哦,对了,我从来没有仔细研究过代码,直到有一个MCVE,在我的IDE中编译。有很多方法可以实现这一点。1在当前点和最后一点之间绘制线条2D。2将所有点添加到常规路径,并在每次添加新点时绘制该路径。顺便说一句:为了更快地得到更好的帮助,发布一个or。在这种情况下,要做到这一点,除了mainString[]类之外,有必要将所有类都缩减为默认值,并在nPainMain的末尾将它们放在后面,然后添加导入。@AndrewThompson我不确定是否正确。请参阅编辑后的注释。。哦,对了,直到有一个在我的IDE中编译的MCVE,我才仔细研究过代码。谢谢:。我知道在这个问题中并没有问这个问题,但你们能在这个问题上帮助我吗?->即使在释放鼠标并从面板的其他角落开始后,最后一点和新点也会连接起来。是因为我在使用ArrayList吗?你能帮我一点忙吗?不客气,不应该。这与你的名单无关。我的示例代码调用canvas.mouseRelease;在事件类中避免它。你可能忘了从我的例子中复制一些东西。我在回答中解释了这一点
油漆组件中的epaint错误/无效。看我的answer@krzydyn你完全正确,但你什么也没学到。你引用的代码不是我的,它来自我没有修改的原始版本。您可以看到,在原始代码中,有许多方面可能会得到改进。我回答了这个问题,并做了一些修改,以简化绘制线条的代码修改,我不会重写所有代码,使其成为一个完美的代码。这不是问题,所以做完整的代码审查是不可能的。是的,这是我的坏习惯:谢谢:。我知道在这个问题中并没有问这个问题,但你们能在这个问题上帮助我吗?->即使在释放鼠标并从面板的其他角落开始后,最后一点和新点也会连接起来。是因为我在使用ArrayList吗?你能帮我一点忙吗?不客气,不应该。这与你的名单无关。我的示例代码调用canvas.mouseRelease;在事件类中避免它。你可能忘了从我的例子中复制一些东西。我在回答中对此进行了解释。在paintComponent中调用repaint是错误的/无用的。看我的answer@krzydyn你完全正确,但你什么也没学到。你引用的代码不是我的,它来自我没有修改的原始版本。您可以看到,在原始代码中,有许多方面可能会得到改进。我回答了这个问题,并做了一些修改,以简化绘制线条的代码修改,我不会重写所有代码,使其成为一个完美的代码。这不是问题,所以做完整的代码审查是不可行的。是的,这是我的坏习惯: