Frage

Ich habe eine Menge von Fragen zu einem Projekt gefragt ich vor kurzem gearbeitet habe. Hier ist das Szenario, das ich bin in und jede Hilfe oder Punkt in der richtigen Richtung viel helfen würde ...

Dies ist ein Netzwerk-Programm mit einem Server und mehreren Clients aufgebaut. Jeder Kunde hat eine GUI, die vom Server gesendet entsprechend Befehlen handeln. Jeder Kunde wird innerhalb einer Klasse namens Player gewickelt. Diese Player hat eine GUI (JFrame erstreckt) und einen Hauptverfahren und der Server über eine Hauptmethode nur (kein GUI). Zuerst diese Klasse wurde im Hauptthread wie folgt erstellt:

EventQueue.invokeLater(new Runnable()
{
    public void run()
    {
        new Player().setVisible(true);
    }
 });

Das war adaequat, bis ich, dass die gesamte Player Klasse realisierte nun im EDT ausführt. Also, wenn ich für Befehle vom Server warte die gesamte GUI blockiert, bis dieser Befehl gesendet und die richtigen Aktionen ausgeführt werden. Wie Sie sich vorstellen können, ist dies eine schreckliche Design und erwies sich als eine echte Schmerzen einer Codierungsumgebung sein, wenn Sie jedes Mal etwas überprüfen wollen, müssen Sie ein paar verrückte Arbeit um finden, so dass die GUI noch intakt bleibt.

Natürlich, ich muss für die Befehle überprüfen vom Server in einem separaten Thread und die GUI-Komponenten im EDT laufen. Meine zweite Implementierung hatte zwei Klassen - eine für die GUI und eine für den Player. Die Idee war, dass die Player eine Variable hatte, die die GUI gehalten, so dass ich die GUI von der Player Klasse zugreifen konnte, so etwas wie folgt aus:

class Player
{
    public GUI gui;

    ...

    // And then start this gui inside of the EDT.
    EventQueue.invokeLater(new Runnable()
    {
         public void run()
         {
              this.gui = new GUI().setVisible(true);
         }
    }

Das funktioniert auch nicht, weil this innerhalb des neuen Runnable Objekts des Runnable Objekt bezieht, nicht die Player.

Wie kann ich zwischen der Player Klasse in einem Thread und die entsprechende GUI-Klasse im EDT Thread kommunizieren?

Andere Tipps

Um Ihr Problem mit dem this Zeiger umgehen, sollten Sie schreiben:

class Player
{
    public GUI gui;

    ...

    // And then start this gui inside of the EDT.
    EventQueue.invokeLater(new Runnable()
    {
         public void run()
         {
              Playser.this.gui = new GUI().setVisible(true);
         }
    }
}

Boris Pavlovic wird die Syntax rechts (eigentlich könnte man einfach die this. entfernen), aber immer noch der Code keinen Sinn. Das gui Feld wird irgendwann nach dem Runnable Ereignisse initialisiert in der Warteschlange gestellt, so ist es nicht sicher für die Spieler Thread, es zu benutzen.

Sie könnten Player am EDT bauen (aber das Netzwerk-off EDT tun). Oder registrieren Sie die GUI als Zuhörer (Beobachter) des Player. invokeAndWait funktionieren würde, ist aber gefährlich, wie es oft führt zu gelegentlichen schwer zu debuggen Deadlock.

Sie können versuchen, diese:

Klasse-Spieler {     public GUI gui;

...

// And then start this gui inside of the EDT.
EventQueue.invokeLater(new Runnable()
{
     public void run()
     {
          Player.this.gui = new GUI().setVisible(true);
     }
}

„bis ich, dass die gesamte Klasse Spieler realisierte nun im EDT ausführt“

Der Konstruktor tritt am EDT aber bei dieser Klasse namens Methoden möglicherweise nicht.

Sie sollten die Spieler GUI-Konstrukt, wie ursprünglich vorgesehen.

 EventQueue.invokeLater(new Runnable() 
 {
    public void run()
    {
        new Player().setVisible(true);
    }
 });

Aber Spieler können einen separaten Thread im Konstruktor starten (ich persönlich würde eine Verbindung zwischen den Spielern teilen).

Natürlich sollten die Callback-Methoden vom Server verwenden invokeLater (), wenn sichtbare Komponenten zu ändern.

Statt eine anonyme innere Klasse zu verwenden, warum nicht nur eine Klasse deklariert die Geräte Runnable und einen Konstruktor hat, die eine GUI-Instanz als Argument?

Auch wenn Ihre GUI-Klasse ist nicht Thread-sicher, sollten Sie eine Nachrichtenwarteschlange mit zwischen dem EDT & Haupt-Thread zu kommunizieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top