2016-11-02 4 views
1

私は簡単なペイントプログラムを作成しました。すべての機能が動作していますが、新しい行を作成すると、プログラムは新しい行を作成していると認識せず、ただ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

あなたはかなりのポイントの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メソッドは、すべてのセグメントを反復処理する必要があります:私は以下の2点を持つ行を無視するようにあなたの小切手を削除した

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に挿入すると、ポイントを簡単に追加できるようになりますが、最初に描画された線が後の行を上書きするという欠点があります。単純な解決策はListget(0)ではなくDequepeekLastを使用することです。

あなたが作ることができる他の多くの改善(特にパフォーマンス)がありますが、私はそれらの変更を自分で試してみて、うまくいきます。

Screen shot

関連する問題