# JLabel bewegen



## ownedbyme2009 (5. Jul 2012)

Hallo leute ich mal wieder 

Also nun will ich folgendes machen ich möchte mein JLabel auf meinem Frame von links nach rechts (bzw von rechts nach links)bewegen. Jedoch sowie ich es gemacht habe funktioniert es nicht. Habe setLocation und setBounds versucht. Als layout benutze ich ein Null Layout. Hatte mich halt bei google eingelesen und dachte es verstanden zu haben jedoch ja iwie nicht. Hier im forum habe ich jetzt auch nichts gefunden was sehr hilfreich war.

Edit: Bewegt sich jetzt habe ein 
	
	
	
	





```
label1.paintImmediately(label1.getVisibleRect());
```
 hinzugefügt jetzt habe ich aber das problem das das bild einen streifen hinterläst

Edit2: Zudem läuft das bild auch nicht flüssig was kann man da gegen tun?

Hier mal mein Ansatz(die methode die das label bewegen soll):


```
public static void labelBewegen(){
			bewegen = new Thread() {
				public void run() {
					
					javax.swing.Timer timer = new javax.swing.Timer( 1, new ActionListener() {
						  public void actionPerformed( ActionEvent e ) {
							  
							  SwingUtilities.invokeLater(new Runnable() {
								  public void run()  {
									  while(true){
										  while(bild1x != 0){
											  bild1x = bild1x-1;
											  System.out.println(bild1x);
											  label1.setBounds(bild1x, bild1y, 289, 132);
											  try {
												Thread.sleep(10);
											} catch (InterruptedException e) {
											}
										  }
										 while(bild1x != 1000){
											  bild1x = bild1x+1;
											  System.out.println(bild1x);
											  label1.setLocation(bild1x, bild1y);
											  try {
												Thread.sleep(10);
											} catch (InterruptedException e) {
											}
										  }
										  
									  }
									  
									  
								  };
								  });}
							  });
					timer.start();
					while(frame.getAus() == false){
						if(frame.getAus() == true){
							System.exit(0);
						}
						}
						  }
				};
				};
```

Mfg Owned

Ps : Ich denke das ist eine schöner Gänsehaut Code vom Aufbau her


----------



## SlaterB (5. Jul 2012)

das mit dem Timer und  SwingUtilities.invokeLater hast du blind kopiert ohne darüber nachzudenken,
wofür diese komplizierte Konstruktion gut ist?

es geht darum dass 
- die Aktione parallel zur GUI stattfindet, so dass der GUI-Thread auch Zeit zum Zeichnen hat, 
daher ein Timer statt einfacher z.B. nur sleep,
- die einzelnen Aktionen zwischen den Pausen müssen aber besser vom GUI-Thread ausgeführt werden, 
sonst mögliche Konflikte, wenn zwei Koche im Brei rühren, daher SwingUtilities.invokeLater 

wenn du aber in einem invokeLater die gesamte Aktion legst, dann passiert währenddessen gar nichts,
verwende den Timer so dass er alle 10ms aktiv wird (wobei ich persönlich Zweifel habe, dass alles unter 20-30ms überhaupt genau gerechnet wird)

und dann führe immer nur einen Schritt aus, der zu diesem Zeitpunkt sinnvoll ist, keine Schleifen, jedenfalls keine mit sleep,
das kommt durch die Timer-Schleife


----------



## ownedbyme2009 (5. Jul 2012)

Das mit invoke.later ist aus einer anderen methode von mir kopiert nicht aus dem internet


----------



## Michael... (5. Jul 2012)

ownedbyme2009 hat gesagt.:


> Ps : Ich denke das ist eine schöner Gänsehaut Code vom Aufbau her


Volle Zustimmung!!!

Besonders gruselig ist das hier:


ownedbyme2009 hat gesagt.:


> ```
> while(frame.getAus() == false){
> if(frame.getAus() == true){
> System.exit(0);
> ...


In einer Schleife ständig Status eine Variablen zu pollen (schon mal die Auslastung des Prozessors dabei beobachtet?) ist ein No Go. Dafür gibt es Listener, Observer...

Dann verwendet man entweder Thread (besser Runnable) oder Timer - nicht beides verschachtelt - mach diesem Fall keinen Sinn. Hier sind wohl mehrere Informationsquellen kombiniert worden.

Bin mir nicht sicher, ob setLocation die Aktualisierung des Layouts anstößt. Vermutlich nein. Änderungen am Layout sind immer recht "schwerwiegend" und müssen durch ein validate() Aufruf am Container gerade gezogen werden.


----------



## SlaterB (5. Jul 2012)

Michael... hat gesagt.:


> Bin mir nicht sicher, ob setLocation die Aktualisierung des Layouts anstößt. Vermutlich nein. Änderungen am Layout sind immer recht "schwerwiegend" und müssen durch ein validate() Aufruf am Container gerade gezogen werden.


ist ja null-Layout


----------



## ownedbyme2009 (5. Jul 2012)

Also habe ich das jetzt richtig verstanden ich soll die berechnungen vor dem Invoke.later machen und dann erst timer + die neuen koordinaten?



Michael... hat gesagt.:


> Dann verwendet man entweder Thread (besser Runnable) oder Timer - nicht beides verschachtelt - mach diesem Fall keinen Sinn. Hier sind wohl mehrere Informationsquellen kombiniert worden.



Da hast du vollkommen recht. Weil es an den meisten stellen im internet nicht genau erklärt wird.



Michael... hat gesagt.:


> In einer Schleife ständig Status eine Variablen zu pollen (schon mal die Auslastung des Prozessors dabei beobachtet?) ist ein No Go. Dafür gibt es Listener, Observer...



Das hatten wir in der Schule so gelernt weil wir noch keine listner und so hatten, deswegen habe ich es so gemacht


----------



## SlaterB (5. Jul 2012)

nein du sollst aus dem InvokeLater die Schleife streichen, evtl. ein if, jedenfalls nur EINE Aktion ausführen, kein sleep,
und den Timer auf 10ms stellen, dieser stellt die Schleife da, 1ms wie im Moment ist halt schneller

über endgültigen Abbruch des Times musst du vielleicht noch nachdenken, 
aber ich kann nun wirklich nicht alles selber machen..

"Also nun will ich folgendes machen ich möchte ..."
klingt ja auch wie Vorstellung des Tagespensums und andere sollen es lösen,
ohne Kenntnisse und langes Lesen von Büchern geht sowas nicht..


----------



## ownedbyme2009 (5. Jul 2012)

Ja der entgültige abbruch ist dafür da das sich Alle Threads wirklich schließen und nicht vieleicht doch weiter laufen habe halt mehrere in diesem Projekt.


----------



## njans (5. Jul 2012)

ActionListener#actionPerformed werden immer auf dem EDT ausgeführt. Daher brauchst du das invokeLater nicht.


----------



## SlaterB (5. Jul 2012)

der Swing-Timer führt den ActionListener im GUI-Thread aus, 
ich hatte überlegt, aber nicht nachgeforscht

```
synchronized void post() {
        if (notify == false || !coalesce) {
            notify = true;
            SwingUtilities.invokeLater(doPostEvent);
        }
    }
[..]
  /**
     * DoPostEvent is a runnable class that fires actionEvents to 
     * the listeners on the EventDispatchThread, via invokeLater.
     * @see #post
     */
    class DoPostEvent [..]
```

aber Vorsicht, ich kann in meinem eigenen Thread auch ein ActionListener-Objekt erstellen,
gar actionPerformed() von GUI-Listenern aufrufen 
die Klasse selber ist nicht gesichert


----------



## Michael... (5. Jul 2012)

SlaterB hat gesagt.:


> ist ja null-Layout


Stimmt ist ja das allseits beliebte null Layout. Da gibt's ja kein Layout, dass validiert werden kann/muss


----------

