2010-06-10 9 views
9

In Java, zu erstellen und einen neuen JFrame zu zeigen, ich dies einfach tun:Warum Menschen laufen Java GUIs auf der Ereignis-Queue

public static void main(String[] args) { 
    new MyCustomFrameClass().setVisible(true); 
} 

Aber ich habe viele Leute gesehen, wie dies zu tun:

public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     public void run() { 
      new MyCustomFrameClass().setVisible(true); 
     } 
    }); 
} 

Warum? Gibt es irgendwelche Vorteile?

Antwort

8

Die Regeln, die festlegen, was an der EDT durchgeführt werden muss (ich sehe "EDT" häufiger als "Event Queue"), haben sich während der Lebensdauer von Java geändert. Und jedes Mal, wenn sich die "Regeln" änderten, riet Sun, mehr und mehr GUI-bezogene Arbeiten am EDT zu machen.

Warum laufen die Java GUI auf dem EDT?

  • Da die offiziellen Richtlinien so raten zu tun.

  • Weil dies hilft, eine Menge Threading-Bugs im Zusammenhang mit der GUI auszuweichen.

Hinweis, und das ist nicht sehr gut bekannt, dass die EDT tatsächlich tut Absturz einmal in einer Weile, weil Schwingen selbst ein paar Fehler hat. Jede nicht-triviale Swing-Anwendung verwendet Swing-APIs, die, naja, Bugs haben und daher hin und wieder den EDT abstürzen.

Sie sehen es nie und es ist kein Grund zur Sorge, denn wenn der EDT stirbt, wird er automatisch neu gestartet.

Grundsätzlich alle GUI-bezogene Sachen auf dem EDT machen und alle länglichen Operationen außerhalb des EDT durchführen (um den EDT nicht zu blockieren).

BEARBEITEN Sie haben nach einem Beispiel gefragt, wie Sie eine längliche Operation außerhalb der EDT ausführen können. Es gibt mehrere Möglichkeiten, dies zu tun. Im einfachsten Fall erstellen und starten Sie einfach einen neuen Thread aus dem EDT. Hier ist ein Beispiel: der Hörer Rückruf wird aufgerufen, wenn der Benutzer klickt auf eine Schaltfläche, wissen wir, dass dies auf der EDT passieren soll ...

JButton jb = ... 
    jb.addActionListener(new ActionListener() { 
     public void actionPerformed(final ActionEvent e) { 
      final Thread t = new Thread(new Runnable() { 
      public void run() { 
      // this shall get executed, after start() has been called, outside the EDT  
      } 
      }); 
      t.start(); 
     } 
    }); 

Für kompliziertere Beispiele wollen Sie sich auf Swingworker lesen usw.

+0

Wie kann ich Operationen außerhalb des EDT ausführen, wenn sie über meine GUI gestartet werden müssen? (Knopf-Ereignis, usw.) Muss ich den EDT auch nur für den Hauptrahmen benutzen? Wenn der Benutzer einen anderen JFrame aus dem Hauptrahmen öffnet (z. B. ein Optionsfenster), muss ich ihn dann auf dem EDT starten? – asmo

+0

@asmo: Ich werde meine Frage bearbeiten, um ein Beispiel zu geben – NoozNooz42

+0

@asmo: Sie brauchen die Arbeit am EDT für * alles * bezogen auf die GUI (also in Ihrem * "Optionsfenster" * Beispiel, yup, das muss) auch auf dem EDT gemacht werden). – NoozNooz42

4

Diese Linie wird Modifizieren einer Swing-Komponente, da Ihre Individuellen Rahmen eine Unterklasse von JFrame ist:

new MyCustomFrameClass().setVisible(true); 

Im Allgemeinen sollten Sie nie eine Swing-Komponente ändern, wenn Sie auf der Event Dispatch Thread (EDT) sind.

Der folgende Code wird ausgeführt, was in der Runnable auf dem EDT ist.

EventQueue.invokeLater(Runnable); 

Nun wird der setVisible(true) Anruf wird auf dem EDT sein, wie es sollte.

+0

Ich wollte eine Instanz einer JFrame-Unterklasse erstellen, nicht direkt ein JFrame. Entschuldigung für die Verwirrung.(Ich habe meinen ursprünglichen Beitrag aktualisiert) – asmo

+0

Dasselbe gilt immer noch für jede Unterklasse einer beliebigen Swing-Komponente. Es ändert nichts. (@asmo) – jjnguy

+0

Danke für die Klarstellung. – asmo

Verwandte Themen