2016-04-03 4 views
0

Ich lerne die Grundlagen von Swing, und ich habe es geschafft, dieses Programm zu zeichnen, indem Sie die Maus ziehen.Jave Swing - Zeichnen von Linien durch Ziehen mit der Maus: Warum funktioniert mein Code?

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

Ich habe zwei Fragen:

1) Wenn ich super.paintComponent(g) nichts nennen gezogen wird, warum ist das so?

2) In dem obigen Code, setze ich x, y gleich in paintComponenet()-x2, y2 zu sein, aber ich versuchte, sie ursprünglich innerhalb mouseDragged wie so zurückgesetzt werden:

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

Doch diese Zeilen nicht erstellt haben, nur eine Reihe von Punkten. Nach meinem Verständnis hätten diese beiden Ansätze gleichwertig sein müssen. Wie sind sie anders?

+1

Ich bin ziemlich sicher, der zweite ist, weil die gesamte Komponente jedes Mal neu gezeichnet wird, wenn Sie die Maus bewegen. Ein Repaint enthält eine Farbe der Hintergrundfarbe, was bedeutet, dass die vorherige Zeichnung jedes Mal gelöscht wird, wenn das Repaint auftritt. Du siehst also nur das letzte bisschen der Zeichnung. – markspace

+0

Ich denke ich folge immer noch nicht ganz. 'repaint()' wird in beiden Fällen aufgerufen. Der einzige Unterschied zwischen den beiden war der falsche Ansatz, ich habe versucht, 'x, y 'in' mouseDragged' vs in 'paintComponent' zurückzusetzen. – Mystic

+0

Für 'repaint()', lesen Sie die Dokumentation. https://docs.oracle.com/javase/8/docs/api/java/awt/Component.html#repaint-- 'repaint()' ist ein Flag zum Swing, dass eine Komponente malen muss, tut es aber nicht passiert sofort. – markspace

Antwort

2

Wenn Sie die Methode repaint() aufrufen, wird eine Anfrage an die RepaintManager gestellt. Dann wird RepaintManager dann (möglicherweise) mehrere repaint() Anfragen in einmal Anruf an die paint() Methode der Komponente kombinieren, die wiederum die paintComponent() Methode aufrufen wird.

Also die Methode paintComponent() aufgerufen wird die Anweisungen nach der repaint() -Anweisung bereits ausgeführt worden, so dass die x/y-Werte bereits aktualisiert worden sind.

Sie sollten immer super.paintComponent() am Anfang Ihrer Methode aufrufen, um sicherzustellen, dass der Hintergrund gelöscht wird. Wenn Sie inkrementelles Malen tun möchten, überprüfen Sie die Custom Painting Approaches, die die beiden üblichen Möglichkeiten erläutert.

Verwandte Themen