简单绘画程序 - 新行未被识别

时间:2016-11-02 01:55:38

标签: java

我创建了一个简单的绘图程序。所有功能都有效,但是当我创建一个新行时,程序无法识别它正在创建一个新行,而只是创建一个大行。如果运行它,代码将编译。任何帮助将不胜感激。谢谢!

Paint Program Output

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.ArrayList;

import javax.swing.*;

public class SimplePaint extends JFrame implements ActionListener{

private static final long serialVersionUID = 1L;
JButton action = new JButton();
JButton red = new JButton();
JButton blue = new JButton();
JButton yellow = new JButton();
Color initial = Color.MAGENTA;
JButton thin = new JButton();
JButton medium = new JButton();
JButton thick = new JButton();
Stroke stroke = new BasicStroke(3);
private static ArrayList<Point> points = new ArrayList<Point>();

JButton erase = new JButton();
JButton drawing = new JButton();
Point start = null;
Point end = null;
Line2D draw = new Line2D.Float();
JPanel panel = new JPanel();

public SimplePaint(){
    getContentPane().add(panel);
    setSize(450, 450);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    design();

    addMouseListener(new MouseAdapter(){
        public void mousePressed(MouseEvent e){
        //points.clear();
            points.add(e.getPoint());
        //    repaint();
        }

        public void mouseReleased(MouseEvent e){
            points.add(e.getPoint());

            // points.clear();
        //repaint();
        }
    });

    addMouseMotionListener(new MouseMotionAdapter(){

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

    blue.addActionListener(this);
    red.addActionListener(this);
    yellow.addActionListener(this);
    thin.addActionListener(this);
    medium.addActionListener(this);
    thick.addActionListener(this);
    erase.addActionListener(this);
    drawing.addActionListener(this);
}

public void design(){
    panel.setBackground(Color.BLACK);

    blue.setBackground(Color.BLUE);
    blue.setPreferredSize(new Dimension(50, 25));
    panel.add(blue);

    red.setBackground(Color.RED);
    red.setPreferredSize(new Dimension(50, 25));
    panel.add(red);

    yellow.setBackground(Color.yellow);
    yellow.setPreferredSize(new Dimension(50, 25));
    panel.add(yellow);

    thin.setText("Thin");
    panel.add(thin);

    medium.setText("Medium");
    panel.add(medium);

    thick.setText("Thick");
    panel.add(thick);

    erase.setText("Erase");
    panel.add(erase);

    drawing.setText("Draw");
    panel.add(drawing);
}

public void actionPerformed(ActionEvent e){
    if(e.getSource() == blue){
        initial = Color.BLUE;
    }else if(e.getSource() == red){
        initial = Color.RED;
    }else if(e.getSource() == yellow){
        initial = Color.YELLOW;
    }else if(e.getSource() == thin){
        stroke = new BasicStroke(1);
    }else if(e.getSource() == medium){
        stroke = new BasicStroke(5);
    }else if(e.getSource() == thick){
        stroke = new BasicStroke(10);
    }else if(e.getSource() == erase){
        initial = Color.BLACK;
    }

    //repaint();
}

@Override
public void paint(Graphics g){
    super.paint(g);
    Graphics2D g2 = (Graphics2D) g;
    g2.setColor(initial);
    g2.setStroke(stroke);

    if(points != null && points.size() > 1){
        for(int p = 0; p < points.size() - 1; p++){
            int x1 = points.get(p).x;
            int y1 = points.get(p).y;
            int x2 = points.get(p + 1).x;
            int y2 = points.get(p + 1).y;
            g2.drawLine(x1, y1, x2, y2);

        }
    }
    g2.dispose();
}

public static void main(String []args){
    SimplePaint s =new SimplePaint();
    s.setVisible(true);


}
}

1 个答案:

答案 0 :(得分:1)

在我看来,您需要分别存储线段而不是一个点列表。要做到这一点,你需要定义一个类来保存它们并存储一个段列表而不是点。

private class Segment {
    private final List<Point> points = new ArrayList<Point>();
    private final Color color = initial;
    private final Stroke stroke = SimplePaint.this.stroke;
}

private final List<Segment> segments = new ArrayList<>();

然后在每次按下鼠标时创建一个新段,并在每次拖动鼠标时将该点添加到当前段:

addMouseListener(new MouseAdapter() {
    public void mousePressed(MouseEvent e) {
        segments.add(0, new Segment());
        segments.get(0).points.add(e.getPoint());
    }
});

addMouseMotionListener(new MouseMotionAdapter() {
    public void mouseDragged(MouseEvent e) {
        segments.get(0).points.add(e.getPoint());
        repaint();
    }
});

释放鼠标时,您不需要执行任何操作,因为已经在拖动时添加了该点。您可以删除该侦听器。

然后你的绘画方法需要遍历所有片段:

public void paint(Graphics g) {
    super.paint(g);
    Graphics2D g2 = (Graphics2D) g;

    for (Segment segment : segments) {
        g2.setColor(segment.color);
        g2.setStroke(segment.stroke);
        for (int p = 0; p < segment.points.size() - 1; p++) {
            Point p1 = segment.points.get(p);
            Point p2 = segment.points.get(p + 1);
            g2.drawLine(p1.x, p1.y, p2.x, p2.y);
        }
    }
    g2.dispose();
}

我已经删除了您的支票,以忽略少于两个点的行:for循环将跳过这些,所以它是多余的。

在索引0处插入新段使得代码添加点简单,但缺点是首先绘制的行会覆盖后面的行。简单的解决方案是使用DequepeekLast而不是Listget(0)

您可以进行许多其他改进(特别是性能),但我自己尝试过这些更改并且工作正常。

Screen shot