2016-04-03 3 views
0

私はSwingの基礎を学んでいます。私はこのプログラムを使ってマウスをドラッグして線を描くことができました。Jave Swing - マウスをドラッグして線を描く:私のコードはなぜ機能しますか?

public class SwingPaintDemo2 { 

    public static void main(String[] args) { 
     JFrame f = new JFrame("Swing Paint Demo"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setSize(300,300); 
     f.add(new MyPanel()); 
     f.setVisible(true); 
    } 
} 

class MyPanel extends JPanel { 

    private int x, y, x2, y2; 

    public MyPanel() { 

     setBorder(BorderFactory.createLineBorder(Color.black)); 
     addMouseMotionListener(new MouseAdapter() { 
      @Override 
      public void mouseDragged(MouseEvent e) { 
       x2 = e.getX(); 
       y2 = e.getY(); 
       repaint(); 
      } 
     }); 

     addMouseListener(new MouseAdapter() { 
      @Override 
      public void mousePressed(MouseEvent e) { 
       x = e.getX(); 
       y = e.getY(); 
      } 
     }); 
    } 

    public void paintComponent(Graphics g){ 
//  super.paintComponent(g); 
     g.setColor(Color.BLACK); 
     g.drawLine(x, y, x2, y2); 
     x = x2; 
     y = y2; 
    } 
} 

私は2つの質問があります:私はsuper.paintComponent(g)何も描かれていない呼び出す場合

1)、その理由は何ですか?上記のコードで

2)、IはpaintComponenet()x2, y2に等しくなるようにx, yをリセットし、私は元々そう等mouseDragged内にそれらをリセットしようとした:

public void mouseDragged(MouseEvent e) { 
      x2 = e.getX(); 
      y2 = e.getY(); 
      repaint(); 
      x = x2; 
      y = y2; 
     } 

しかし、これが唯一の行を作成しませんでした一連の点。私の理解では、これらの2つのアプローチは同等であったはずです。それらはどう違いますか?

+1

2番目は、マウスを動かすたびにコンポーネント全体が再描画されるためです。再ペイントには背景色のペイントが含まれます。つまり、再描画が発生するたびに前の図が消去されます。だから、あなたはちょうど絵の最後の少しを見ます。 – markspace

+0

私はまだかなりフォローしていないと思います。どちらの場合でも 'repaint()'が呼び出されています。両者の唯一の違いは間違ったアプローチだったので、 'paintControl 'の' mouseDragged'と 'x、y'をリセットしようとしました。 – Mystic

+0

'repaint()'には、ドキュメントを読んでください。 https://docs.oracle.com/javase/8/docs/api/java/awt/Component.html#repaint-- 'repaint()'は、コンポーネントがペイントする必要があるSwingのフラグですが、すぐに起こる。 – markspace

答えて

2

repaint()メソッドを呼び出すと、RepaintManagerが要求されます。次に、RepaintManagerは、複数のrepaint()要求を(潜在的に)組み合わせて、paint()メソッドの呼び出しを呼び出して、paintComponent()メソッドを呼び出します。

したがって、paintComponent()メソッドが呼び出されるときまでに、repaint()ステートメントの後のステートメントはすでに実行されているので、x/y値はすでに更新されています。

メソッドの開始時に常にsuper.paintComponent()を呼び出して、バックグラウンドがクリアされていることを確認する必要があります。インクリメンタルペインティングをしたい場合は、Custom Painting Approachesのチェックアウトでこれを行う一般的な2つの方法が説明されています。