2017-05-26 4 views
1
nicht

Hier ist mein Code:Repaint für javax arbeiten

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 
import javax.swing.SwingUtilities; 

public class Main { 
// code main 
public static void main(String[] args) { 
    JFrame frame = new JFrame(); 
    frame.setSize(460, 500); 
    frame.setTitle("Circles generator"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 


    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      frame.setVisible(true); 

     } 

    }); 

    String input = JOptionPane.showInputDialog("Enter n:"); 
    CustomComponents0 component = new CustomComponents0(); 
    frame.add(component); 
    frame.getContentPane().validate(); 
     System.out.println("work before"); 
    frame.getContentPane().repaint(); 
     System.out.println("work"); 

    frame.getContentPane().repaint(); 
     System.out.println("work after"); 

} 

// why is not JComponent 
static class CustomComponents0 extends JLabel { 

    private static final long serialVersionUID = 1L; 

    @Override 
    public Dimension getMinimumSize() { 
     return new Dimension(200, 100); 

    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(300, 200); 

    } 

    @Override 
    public void paintComponent(Graphics g) { 
     System.out.println("paint"); 
     int margin = 10; 
     Dimension dim = getSize(); 
     super.paintComponent(g); 
     g.setColor(Color.red); 
     g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2); 

    } 

} 

hier ist der Code und ich laufe vor der Arbeit neu streichen wollen und nach der Arbeit neu streichen laufen. Wenn ich es laufen, sollte es

work before 
paint 
work 
paint 
work after 

aber es gibt nur eine Farbe drucken und es ist nach der Arbeit, Warum geschieht das? Wie kann ich das beheben?

Danke.

+2

Warum? Was muss repariert werden? Warum sich genau darum kümmern, wann und ob ein Gemälde auftaucht? Verstehen Sie, dass Sie nur ein Gemälde anfordern können, das es (größtenteils) nicht benötigt. –

+3

So funktioniert Malerei nicht. Ein "repaint()" ist nur eine Aufforderung, eine Komponente zu malen. Wenn Sie zwei Anforderungen nacheinander haben, werden sie in einer einzigen Anfrage zusammengefasst. Was ist der Sinn dieser Logik? Wenn Sie zwischen dem Malen einen Zeitabstand benötigen, können Sie einen "Swing Timer" verwenden. Lesen Sie den Abschnitt aus dem Swing-Lernprogramm zu [Verwenden von Swing-Timern] (http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html). – camickr

Antwort

1

Sie must Konstrukt und manipulieren Swing-GUI-Objekte nur auf dem event dispatch thread. Da Ihr Programm falsch synchronisiert ist, ist jedes Ergebnis möglich. Es hängt teilweise davon ab, wie weit die initial thread vor dem Start der EventQueue kommt. Darüber hinaus println() selbst may be synchronized, und "Ereignisse, die auf die EventQueue gebucht werden können zusammengeführt werden."

Die folgende Variation zeigt zuverlässig die folgende Ausgabe, da Ereignisse ausgelöst werden "In der Reihenfolge, in der sie eingereiht werden." Beachten Sie insbesondere, wie die Aufrufe von repaint() zusammengeführt werden. Während dieser Ansatz veranschaulichend ist, ist er für Ihr wahrscheinliches Ziel unnötig umständlich. Verwenden Sie stattdessen javax.swing.Timer, um die Animation wie gezeigt zu stimulieren here.

Console:

paint 
work before 
work 
work after 
paint 

Code:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 

/** @see https://stackoverflow.com/a/44212328/230513 */ 
public class Main { 

    public static void main(String[] args) { 
     EventQueue.invokeLater(() -> { 
      JFrame frame = new JFrame(); 
      frame.setTitle("Circles generator"); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      CustomComponent component = new CustomComponent(); 
      frame.add(component); 
      frame.pack(); 
      frame.setLocationRelativeTo(null); 
      frame.setVisible(true); 
      EventQueue.invokeLater(() -> { System.out.println("work before"); }); 
      EventQueue.invokeLater(() -> { frame.repaint(); }); 
      EventQueue.invokeLater(() -> { System.out.println("work"); }); 
      EventQueue.invokeLater(() -> { frame.repaint(); }); 
      EventQueue.invokeLater(() -> { System.out.println("work after"); }); 
     }); 
    } 

    static class CustomComponent extends JLabel { 

     private static final int N = 10; 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(300, 200); 
     } 

     @Override 
     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      System.out.println("paint"); 
      g.setColor(Color.red); 
      g.fillRect(N, N, getWidth() - N * 2, getHeight() - N * 2); 
     } 
    } 
}