Frage

Ich habe eine Platte, auf der eine Reihe von Objekten erstellt gezogen wird. Jedes des Objekts wird als Maus-Ereignis-Listener zum Panel hinzugefügt. Wie ich weiß, nach einem Ereignis die Zuhörer auftritt benachrichtigt werden und der Code könnte (oder?) Sein in mehreren Threads ausgeführt. Ist es möglich, einen benutzerdefinierten Code zu befestigen, die ausgeführt wird nach für alle Zuhörer ihren Code vollständig ausgeführt?

War es hilfreich?

Lösung

Wie für Noel Kommentar:

  

Eine Sorge, dass diese Technik Stolper könnte, ist, wenn eine bestimmte Zuhörer Implementierung früh eine Benachrichtigung zurück und führt Arbeit „out-of-band“ auf einem separaten Thread. In diesem Fall muss das Ende der Mitteilung Rufsymbols nicht tatsächlich das Ende der Ausführung des Zuhörers. Ist dies eine tatsächliche Anliegen ist (das heißt, Sie sind bewusst und befasst sich mit anderen benutzerdefinierten, aufwendige Zuhörer, die diese Art der Sache zu tun, möchten Sie vielleicht verfeinern und das Problem erneut.

Mit dem SwingUtilities.invokeLater() Sie sicher sind, der Code ausgeführt wird, nachdem alle Zuhörer mitgeteilt wurden. Aber eine dieser Zuhörer durchführen kann es Arbeit in einem separaten Thread.

Wenn Sie Ihren Code, nachdem alle Zuhörer auszuführen nicht nur benachrichtigt wurden, aber sie beendeten ihre Arbeit, die Sie so etwas tun könnte:

Pseudo-Code:

Listener implements MouseListener 
    +mouseClicked( event: MouseEvent ) 
        SwingUtilities.invokeLater( // returns immediately 
              someTask() 
        )

    -someTask()
        // perform some long task.

Wenn Sie Ihre Zuhörer als

 addListener( new Listener() )
 addListener( new Listener() )
 addListener( new Listener() )
 addListener( new ExecuteAtTheEnd() ) 

Wenn alle (oder einige) Ihre Zuhörer ihre Arbeit in einem anderen Thread ausführen. Ihre ExecuteAtTheEnd sein können, es ist Code am Ende der Meldung, aber nicht am Ende der Ausführung der Zuhörer Code ausgeführt wird.

Also, was Sie tun?

Sie haben die Verwendung einiger Lockflag zu synchronisieren und den Code auszuführen, bis das Flag nicht verwendet wird.

Es kann ein Zähler sein, wird erhöht, wenn der Hörer ausführt und verringert, wenn nicht ist:

 Listener implements MouseListener 
    +mouseClicked( event: MouseEvent )
        lockFlagCount++ 
        SwingUtilities.invokeLater( 
              someTask() 
        )

    -someTask()
        // perform some long task.
        lockFlag--

Und dann gehen Sie einfach, bis dieser Flag ist falsch:

  ExecuteAtTheEndListener implements MouseListener 

       + mouseClicked( event: MouseEvent ) 
        SwingUtilities.invokeLater( 
              executeAtTheEnd() 
        )
       - executeAtTheEnd() 
            while( logFlagCount > 0 ) 
                wait()

             if( logFlagCount == 0 ) 
                 // continue with the task.                  

Natürlich ist es viel komplizierter, als ich es in dem Pseudo-Code zu setzen, aber es sollte funktionieren, , wenn Sie sind in dieser Art von Umständen.

Andere Tipps

Ist im selben Thread (der Event-Dispatcher-Thread) ausgeführt wird.

Zu tun, was Sie wollen, müssen Sie nur noch einen zusätzlichen Hörer hinzu und haben die Zuhörer a href aufrufen „executeLater“ -Methode von <= "http://java.sun.com/javase/6/docs/api/javax /swing/SwingUtilities.html“rel = "nofollow noreferrer"> SwingUtilities Klasse.

Was bedeutet wird, ist für den EDT-Thread warten, um die Meldungen beenden und dann den Code aufrufen.

Um es zu testen, fügen Sie diesen Hörer und sehen, was es tut:

 class MouseListener extends MouseAdapter {
     public void mouseClicked(MouseEvent e)  {
           // System.out.println("If uncommented this would be invoked with the rest of the listners");
           SwingUtilities.invokeLater( new Runnable() {
                public void run() {
                    System.out.println("Invoked after all the listeners were notified");
                }
            }
     }
 }

Zugegeben, es ist eine Maus Zuhörer, was du hast. Das Konzept ist das gleiche für alle anderen Zuhörer.

Ich glaube, dass das, was Sie wollen, ist die SwingUtilities.invokeLater() Methode zu verwenden, die eine Runnable Instanz auf dem Event Dispatch Thread aufrufen wird, nachdem alle anderen GUI-Ereignisse verarbeitet wurden.

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