如何填充行与行之间的空格?
how to fill spaces between lines?
我正在尝试制作一个简单的绘画程序。我正在尝试制作一种像铅笔这样可以自由绘图的工具。到目前为止我的代码是:
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;
}
}
我这里的主要问题是,在拖动点时绘制了点,但它们之间有 space like this。我想加入连续行。任何有关进一步提示的帮助将不胜感激。
您正在修改 paintXXX
中的对象状态 - 这是错误的。
paint
方法仅用于绘制当前状态。
您应该在 MouseListener
中将鼠标点添加到列表中并调用 rapaint
以标记您的 canvas
class 将在 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 点和实际点。
简单的说,只有前一个点和实际的点有值,才会画一条线。
并且当绘制一条线时,最后一个实际绘制的点成为下一条绘制线的前一个点。这样,你的行与行之间就没有空洞了。
在canvas Class :
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);
}
如果您松开鼠标按钮,前一个点和实际点将设置为空。
事件中 class :
@Override
public void mouseReleased(MouseEvent e) {
canvas.mouseReleased();
}
在canvas Class :
public void mouseReleased() {
previousPoint = null;
actualPoint = null;
}
这样你就可以根据需要独立绘制多条线了。
此外,我通过使用 Point 实例(而不是双精度)简化了代码,它使用整数作为坐标,但您可以使用多个双精度字段,这在实践中并没有改变很多东西。
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) {
}
}
我正在尝试制作一个简单的绘画程序。我正在尝试制作一种像铅笔这样可以自由绘图的工具。到目前为止我的代码是:
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;
}
}
我这里的主要问题是,在拖动点时绘制了点,但它们之间有 space like this。我想加入连续行。任何有关进一步提示的帮助将不胜感激。
您正在修改 paintXXX
中的对象状态 - 这是错误的。
paint
方法仅用于绘制当前状态。
您应该在 MouseListener
中将鼠标点添加到列表中并调用 rapaint
以标记您的 canvas
class 将在 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 点和实际点。
简单的说,只有前一个点和实际的点有值,才会画一条线。
并且当绘制一条线时,最后一个实际绘制的点成为下一条绘制线的前一个点。这样,你的行与行之间就没有空洞了。
在canvas Class :
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);
}
如果您松开鼠标按钮,前一个点和实际点将设置为空。
事件中 class :
@Override
public void mouseReleased(MouseEvent e) {
canvas.mouseReleased();
}
在canvas Class :
public void mouseReleased() {
previousPoint = null;
actualPoint = null;
}
这样你就可以根据需要独立绘制多条线了。
此外,我通过使用 Point 实例(而不是双精度)简化了代码,它使用整数作为坐标,但您可以使用多个双精度字段,这在实践中并没有改变很多东西。
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) {
}
}