# Frage zu SwingUtilities.invokeLater



## Guest (1. Nov 2008)

Ein wunderschönen guten Samstag, den 1.November 2008, 

ok ich hör ja schon auf, ich hätte gerne eine Frage zu dem "invokeLater" Konstrukt: In unserem Programm benutze ich das, um einen längeren Task auszuführen und die Benutzereingaben während dieser Zeit zu blockieren (in dem Fall sei das mal ok)


```
SwingUtilities.invokeLater(new Runnable(){

  public void run(){
       setCursor(CURSOR_WAIT);
       //do something
  }
});
```

Das scheint auch soweit ok zu sein, nur, wenn die Anwendung während dieser Zeit in den Hintergrund bzw. minimiert und anschließend wieder geholt wird, bleibt die komplette Oberfläche während dieser Zeit grau. Ist das normal so, oder wie müsste man das ändern ?


Danke.
Robobot


----------



## Gast (1. Nov 2008)

Du verwechselst hier das "invokeLater" mit dem SwingWorker. 
Der SwingWorker ist für länger laufende Tasks gedacht.
invokeLater dient nur dazu, etwas sicher im EDT (Event Dispatcher Tread) auszuführen


----------



## Robobot (1. Nov 2008)

Das Problem ist, dass ich diesen SwingWorker nicht verwenden kann, da wir Java5 verwenden müssen. Leider versteh ich für meinen Anwendungsfall immer noch nicht ganz, welches Konstrukt man verwenden sollte. Wer kann mir helfen, oder hat jemand einen anderen Vorschlag ?

Wenn der ActionListener ausgelöst wird, wird eine längere Rechenoperation durchgeführt. Während dieser Zeit soll die GUI blockiert werden. 

Was ist nun das Richtige ?  ???:L  Danke auch. 


```
public void actionPerformed(ActionEvent arg0) {

		//Variante 1
		SwingUtilities.invokeLater(new Runnable(){
			public void run() {
			   //führe eine längere Operation aus 
			  // und sperre während dieser Zeit die gui
			}
		});

		//Variante 2
		Thread thread = new Thread(){
			public void run() {
				   //führe eine längere Operation aus 
				  // und sperre während dieser Zeit die gui
			}
		};
		thread.start();
		
                //Variante 3
		Thread thread = new Thread(new Runnable(){
			public void run() {
				 //führe eine längere Operation aus 
				  // und sperre während dieser Zeit die gui
				
			}
		});
		thread.start();

               //Variante n ??
                
		
	}	
	button.addActionListener(this);
```


----------



## Gast (1. Nov 2008)

Zu deinen Varianten:
1: Ist Blödsinn, da das die Operation EXPLIZIT im EDT ausführt, also 100 % die GUI blockiert.

Die anderen beiden Varianten kannst du verwenden, aber eben genau für sowas gibt es den SwingWorker.

Du kannst den SwingWorker schon mit Java 5 verwenden.
Es gibt einen Backport:
https://swingworker.dev.java.net/

Einfach die 2-3 Klassen deinem Projekt hinzufügen und freuen =)
Mach ich auch immer, wenn Java5 Kompatibilität gefordert wird.


Hier ein einfaches, leicht verständliches SwingWorker Tutorial:
http://www.0x13.de/index.php/code-snippets/38-code-snippets/51-swingworker-tutorial.html


----------



## Robobot (1. Nov 2008)

Danke dir, ist nun ein wenig klarer geworden


----------



## Gast (1. Nov 2008)

Wenn du die GUI während der Zeit unbedingt blockieren willst, dann mach, so lange der SwingWorker arbeitet, einen Dialog auf, in dem bsp. Bitte Warten steht.


----------



## Robobot (2. Nov 2008)

Hello again, 
muss mich nochmal zurückmelden 

eine hätte ich noch: Eine Swing Klasse (extends JPanel) hat eine Instanz eines JDialogs (DetailDialog). Per Button wird dieser Dialog , falls noch nicht verhanden erzeugt, und das Objekt, von welchem man sich Details anzeigen lassen will, gesetzt. Wenn ich das nun richtig verstanden habe, wäre es der korrekte Weg dies so zu machen: (unter der Annahme dass hier keine zeitintensiven  sondern lediglich GUI Operationen durchgeführt werden , z.B. setVisible(true) )


```
//Neu
detailsButton.addActionListener(new ActionListener(){
  
    public void actionPerformed(ActionEvent e) {
        SwingUtilities.invokeLater(new Runnable() {
           public void run() {
              if(detailDialog == null)
                  detailDialog = new DetailDialog();
              }
              detailDialog.setData(currentData); 
              detailDialog.setVisible(true); 
              
           }
        });
 
    }
});


//Bisher
detailsButton.addActionListener(new ActionListener(){
  
    public void actionPerformed(ActionEvent e) {
            if(detailDialog == null)
                detailDialog = new DetailDialog();
            }
            detailDialog.setData(currentData); 
            detailDialog.setVisible(true); 

 
    }
});
```

daher auch mal eine generelle Frage: Bisher sah ich die Verwendung von invokeLater immer nur am Beispiel in der main Methode, da diese im EDT ausgeführt wird. Wann sollte man dies typischerweise noch verwenden ? 

Danke.  - Robobot


----------



## Gast (2. Nov 2008)

Nein, in obiger Methode brauchst du kein invokeLater(), weil der Button und der ActionListener schon im EDT laufen, also auch dein new DetailDialog() im EDT aufgerufen wird. Das invokeLater() macht zwar nichts kaputt, wird aber im Allgemeinen nicht so gemacht.


Nein, die main Methode wird standardmäßig nicht im EDT ausgeführt. GUIs wie AWT oder Swing laufen im EDT. Ein Hello-World Programm auf der Konsole dagegen läuft zwar auch in einem Thread, der aber nicht EDT genannt wird.

Das invokeLater in der Main Methode hat bei GUI Anwendungen den zweck, dass 100% sichergestellt wird, dass die GUI auch im EDT gestartet wird.

das invokeLater verwendet man im allgemeinen, wenn man mehrere Threads hat und diese auf die GUI, bsp eine Tabelle oder Liste zugreifen wollen. Swing ist nicht theadsicher, daher wird durch invokelater erreicht, dass nur ein einziger thread, nämlich der EDT die GUI manipuliert.


----------



## Robobot (2. Nov 2008)

Besten Dank nochmal. Jetzt hab ichs.
edit: ich meine irgendwo mal gelesen zu haben, wie man den Haken setzt, ich finds leider nimmer.


----------



## André Uhres (2. Nov 2008)

Robobot hat gesagt.:
			
		

> ich meine irgendwo mal gelesen zu haben, wie man den Haken setzt, ich finds leider nimmer.


Wenn ein Gast den Thread startet, geht das wohl nicht :wink:





Zum Thema siehe auch: Lesson: Concurrency in Swing


----------

