In das Label eines anderen Threads schreiben

Stormy744

Neues Mitglied
Hallöchen liebes Java-Forum!

Ich sitze hier seit einigen Stunden vor einem Problemchen, welches für euch hoffentlich keines ist...
Der Code sollte eigentlich ein Label erzeugen, in welchem eine ständig aktualisierte Uhrzeit erscheint.
Das Problem ist nun, dass die verwendeten Timer ja ihre eigenen Threads erzeugen und ich, um in das Label zu schreiben, von einem Thread auf einen anderen "zugreifen" müsste...
Kann mir dabei vllt jemand von euch helfen? Bin für jeden Tipp dankbar...
Zum besseren Verständnis würde ich mich über Code-Beispiele freuen...

Hier noch mein bisheriger Code in leicht gekürzter Form:
Java:
public class UhrR{

	static Shell shellX = new Shell(mainPro.display, SWT.ON_TOP | SWT.BORDER);
	private static Label labeli = new Label(shellX, SWT.NONE);
	private static String uhrzt = "Uhr"; //*****

	public static void main(String[] args) {
		shellX.setSize(1280/5, 1024/4);
		shellX.setLocation(0, 0);
		
		labeli.setText(uhrzt);
		labeli.setLocation(0, 0);
		labeli.setSize(150,20);
		
		//Timer 1 -> aktuelle Uhrzeit in String uhrzt schreiben
		final Timer timer = new Timer();
		TimerTask task = new TimerTask() {
		public void run() {

	   		//Zeit
	   		SimpleDateFormat hourSDF = new SimpleDateFormat("HH");
	   		SimpleDateFormat minSDF = new SimpleDateFormat("mm");
	   		SimpleDateFormat secSDF = new SimpleDateFormat("ss");
	   		
	   		String hourS = hourSDF.format(new Date());
	   		String minS = minSDF.format(new Date());
	   		String secS = secSDF.format(new Date());
	   		
	   		int hourI = Integer.valueOf(hourS).intValue();
	   		int minI = Integer.valueOf(minS).intValue();
	   		int secI = Integer.valueOf(secS).intValue();
	         
	        	uhrzt = hourI + ":" + minI + ":" + secI; //*****
			
		}
		};

		//Timer 2 -> Label aktualisieren
		TimerTask task2 = new TimerTask() {
		public void run() { 

			labeli.setText(uhrzt); //***** <- Im Original-Code ist dies Zeile 271
				
		}
		};

		//start der Timer:
		timer.scheduleAtFixedRate(task, 0, 1000);
		timer.scheduleAtFixedRate(task2, 1, 1000);
		
		//Shell öffnen
		shellX.open();
	}
}

Beim Ausführen des Codes liefert Eclipse mir nach einiger Zeit) folgende Fehlermeldung (ohne Programmabbruch):
Code:
Exception in thread "Timer-0" org.eclipse.swt.SWTException: Invalid thread access
	at org.eclipse.swt.SWT.error(Unknown Source)
	at org.eclipse.swt.SWT.error(Unknown Source)
	at org.eclipse.swt.SWT.error(Unknown Source)
	at org.eclipse.swt.widgets.Widget.error(Unknown Source)
	at org.eclipse.swt.widgets.Widget.checkWidget(Unknown Source)
	at org.eclipse.swt.widgets.Label.setText(Unknown Source)
	at Uhr$8.run(Uhr.java:271)
	at java.util.TimerThread.mainLoop(Unknown Source)
	at java.util.TimerThread.run(Unknown Source)

Schonmal vielen Dank im Vorraus für eure Unterztützung!!! :toll:


Stormy744
 
GUI Freeze ("EDT" bei SWT?)

Hier lag auch das Problem vor. Du brauchst:

Synchrones ausführen
Java:
display.syncExcec(Runnable);

Asynchrones ausführen
Java:
display.asyncExcec(Runnable);

Ich empfehle den Aufruf über die Display-Referenz (eigene Erfahrungen, die zugegebnermaßen nicht sonderlich groß sind ^^)

MFG

Tomate_Salat
 
Hier nochmal für alle, die ein ähnliches Problem haben, die Lösung:
Java:
public class UhrR{
 
    static Shell shellX = new Shell(mainPro.display, SWT.ON_TOP | SWT.BORDER);
    private static Label labeli = new Label(shellX, SWT.NONE);
    private static String uhrzt = "Uhr"; //*****
 
    public static void main(String[] args) {
        shellX.setSize(1280/5, 1024/4);
        shellX.setLocation(0, 0);
        
        labeli.setText(uhrzt);
        labeli.setLocation(0, 0);
        labeli.setSize(150,20);
        
        //Timer 1 -> aktuelle Uhrzeit in String uhrzt schreiben
        final Timer timer = new Timer();
        TimerTask task = new TimerTask() {
        public void run() {
 
            //Zeit
            SimpleDateFormat hourSDF = new SimpleDateFormat("HH");
            SimpleDateFormat minSDF = new SimpleDateFormat("mm");
            SimpleDateFormat secSDF = new SimpleDateFormat("ss");
            
            String hourS = hourSDF.format(new Date());
            String minS = minSDF.format(new Date());
            String secS = secSDF.format(new Date());
            
            int hourI = Integer.valueOf(hourS).intValue();
            int minI = Integer.valueOf(minS).intValue();
            int secI = Integer.valueOf(secS).intValue();
             
                uhrzt = hourI + ":" + minI + ":" + secI; //*****
            
        }
        };
 
        //Timer 2 -> Label aktualisieren
        TimerTask task2 = new TimerTask() {

			public void run() {

				mainPro.display.asyncExec(new Runnable() {
			        public void run() {
			        	labeli.setText(uhrzt); //*****
			        }
				});
			}
		};
 
        //start der Timer:
        timer.scheduleAtFixedRate(task, 0, 1000);
        timer.scheduleAtFixedRate(task2, 1, 1000);
        
        //Shell öffnen
        shellX.open();
    }
}


Und nochmal vielen Dank an Tomate_Salat :applaus:
 

Zurück
Oben