Java 如何填充行之间的空格?
我正在尝试制作一个简单的绘画程序。我想做一个像铅笔这样的工具,可以自由画画。到目前为止,我的代码是: NPaintMain NPAINT窗口 NPaintCanvasJava 如何填充行之间的空格?,java,swing,line,paintcomponent,Java,Swing,Line,Paintcomponent,我正在尝试制作一个简单的绘画程序。我想做一个像铅笔这样的工具,可以自由画画。到目前为止,我的代码是: NPaintMain NPAINT窗口 NPaintCanvas 我这里的主要问题是,当拖动时,会绘制点,但它们之间有空间。我要加入连续线。如果您有任何进一步的建议,我们将不胜感激 您正在修改paintXXX中的对象状态-这是错误的。 绘制方法仅用于绘制当前状态 您应该在MouseListener中将鼠标点添加到列表中,并调用rapaint来标记要在EDT中重新绘制的画布类 和paintComp
我这里的主要问题是,当拖动时,会绘制点,但它们之间有空间。我要加入连续线。如果您有任何进一步的建议,我们将不胜感激 您正在修改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你完全正确,但你什么也没学到。你引用的代码不是我的,它来自我没有修改的原始版本。您可以看到,在原始代码中,有许多方面可能会得到改进。我回答了这个问题,并做了一些修改,以简化绘制线条的代码修改,我不会重写所有代码,使其成为一个完美的代码。这不是问题,所以做完整的代码审查是不可行的。是的,这是我的坏习惯: