2016-11-02 46 views
1

我創建了一個簡單的塗料程序。所有的功能都在起作用,但是當我去創建一個新行時,程序不會識別它正在創建一個新行,而只是創建一條巨大行。如果你運行它,代碼將被編譯。任何幫助將不勝感激。謝謝!簡單塗料程序 - 新行不被識別

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

在我看來好像你需要單獨存儲線段而不是點的一個列表。要做到這一點,你需要定義一個類來保存它們,並存儲段的列表而不是點。

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

你不需要的時候做任何事情鼠標被釋放,因爲該點將在拖動時添加。您可以刪除該偵聽器。然後

你的paint方法需要通過所有段迭代:

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

我已經刪除您的支票忽略小於2分線:for循環會跳過那些反正所以它是多餘的。

在索引0處插入新段會使代碼添加點變得簡單,但缺點是繪製的線首先會覆蓋後面的線。簡單的解決方案是使用DequepeekLast而不是Listget(0)

還有很多其他改進(特別是性能),但我已經嘗試過自己修改這些更改,並且它們工作正常。

Screen shot