# Ein Thread soll ein Textfeld (SWT) ändern



## MrLinux (30. Mrz 2006)

Hallo zusammen,

ich bräuchte von euch mal einen Gedankenanstoß!

Ich versuche gerade mit einem zweiten Thread eine Textfeld (SWT) zu ändern.
Dazu habe ich folgendes zusammen geschrieben.


```
package gui;

import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import src.SensorThread;

public class JWatcher {

	private Shell sShell = null;
	public Text text = null;
	private Button button = null;
	public String temp = "a";
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Automatisch erstellter Methoden-Stub
		/* Before this is run, be sure to set up the launch configuration (Arguments->VM Arguments)
		 * for the correct SWT library path in order to run with the SWT dlls. 
		 * The dlls are located in the SWT plugin jar.  
		 * For example, on Windows the Eclipse SWT 3.1 plugin jar is:
		 *       installation_directory\plugins\org.eclipse.swt.win32_3.1.0.jar
		 */
		Display display = Display.getDefault();
		JWatcher thisClass = new JWatcher();
		thisClass.createSShell();
		thisClass.sShell.open();

		while (!thisClass.sShell.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
		display.dispose();
	}

	/**
	 * This method initializes sShell
	 */
	private void createSShell() {
		sShell = new Shell();
		sShell.setText("JWatcher");
		sShell.setSize(new Point(300, 200));
		text = new Text(sShell, SWT.BORDER);
		text.setBounds(new org.eclipse.swt.graphics.Rectangle(55,64,51,19));
		button = new Button(sShell, SWT.NONE);
		button.setBounds(new org.eclipse.swt.graphics.Rectangle(139,111,96,30));
		button.setText("Temperatur");
		button.addMouseListener(new org.eclipse.swt.events.MouseAdapter() {
			public void mouseDown(org.eclipse.swt.events.MouseEvent e) {
				System.out.println("mouseDown()"); // TODO Auto-generated Event stub mouseDown()
				test();
			}
		});
	}
	
	public void test() {
		Thread t = new SensorThread();
		t.start();
	}

}
```

Ich weiß nicht schön aber zum üben ausreichend.

Der Thread sieht so aus.


```
package src;

import java.io.InputStreamReader;
import java.io.BufferedReader;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Shell;

import gui.JWatcher;

public class SensorThread extends Thread {
	static String temperatur = "";
	String line = "";
	
	public void run(){
		int a = 0;
		while (true) {
			System.out.println("Hallo zum :" + a++);
		
			try
			{
			Process proc = Runtime.getRuntime().exec("cat /proc/acpi/thermal_zone/TZ1/temperature");
			BufferedReader input = new BufferedReader(new InputStreamReader(proc.getInputStream()));	
					
			line = input.readLine();
			
			//input.close();
			}
			catch (Exception k) { System.err.println(""+k); }

			System.out.println("Hallo zum :" + line);
			
			// Den Thread für 5 sec anhalten
			try {
				Thread.sleep(5000);
				}
				catch (InterruptedException e) {}
		}
	}
	
}
```

Das ganze läuft so weit, die Ausgabe auf der Konsole funktioniert.
Aber wie kann ich nun den String "line" aus dem Thread in das Textfeld auf der sShell schreiben?
Ich habe gesetern mal mit PipedInputStream und PipedOutputStream rum probiert aber ohne Erfolg.

Habe schon versucht das Beispiel unter http://www.java-forum.org/de/viewtopic.php?p=139877#139877 an zu passen. Beim verusch in das Textfeld zu schreiben bekomme ich immer eine Fehlermeldung "ungültiger Thread zugriff" 

Ziel des ganzen soll sein das Texfeld alle 5 sec. mit der aktuellen Prozessortemperatur zu überschreiben.

Wie muss ich in einem solchen Fall vorgehen? 


Gruß
     JB


----------



## KSG9|sebastian (30. Mrz 2006)

also, zuerst mal ein Runnable welches die Änderungen vornimmt:


```
final Runnable r = new Runnable() {
    public void run() {
        textFeld.setText("xyz");	
    }
};
```

Dann brauchst du den eigentlichen Thread:


```
Thread thr = new Thread(new Runnable() {
			public void run() {
				while (true) {
					Display.getDefault().syncExec(r);
				}
			}
		});
		thr.start();
```

So, also:

der Threead (thr) läuft endlos. In dem kannst du NICHT auf die GUI zugreifen. Mit "Display.getDefault.syncExec" kannst du ein anderes Runnable ausführen welches auf die GUI zugreifen darf.


----------



## MrLinux (30. Mrz 2006)

Hallo,

habe es eben mal ausprobiert.
Es funktioniert einwandfrei ! Wieder mal was gelernt.

Anbei der Code der unter Suse 10 läuft.


```
package gui;



import java.io.BufferedReader;

import java.io.InputStreamReader;

import org.eclipse.swt.graphics.Point;

import org.eclipse.swt.widgets.Shell;

import org.eclipse.swt.widgets.Display;

import org.eclipse.swt.widgets.Text;

import org.eclipse.swt.SWT;

import org.eclipse.swt.widgets.Button;





public class JWatcher {



	private Shell sShell = null;

	public Text text = null;

	private Button button = null;

	String line = "";

	

	/**

	 * @param args

	 */

	public static void main(String[] args) {

		// TODO Automatisch erstellter Methoden-Stub

		/* Before this is run, be sure to set up the launch configuration (Arguments->VM Arguments)

		 * for the correct SWT library path in order to run with the SWT dlls. 

		 * The dlls are located in the SWT plugin jar.  

		 * For example, on Windows the Eclipse SWT 3.1 plugin jar is:

		 *       installation_directory\plugins\org.eclipse.swt.win32_3.1.0.jar

		 */

		Display display = Display.getDefault();

		JWatcher thisClass = new JWatcher();

		thisClass.createSShell();

		thisClass.sShell.open();



		while (!thisClass.sShell.isDisposed()) {

			if (!display.readAndDispatch())

				display.sleep();

		}

		display.dispose();

	}



	/**

	 * This method initializes sShell

	 */

	private void createSShell() {

		sShell = new Shell();

		sShell.setText("JWatcher");

		sShell.setSize(new Point(300, 200));

		sShell.addShellListener(new org.eclipse.swt.events.ShellAdapter() {

			public void shellClosed(org.eclipse.swt.events.ShellEvent e) {

				//

			}

		});

		text = new Text(sShell, SWT.BORDER);

		text.setBounds(new org.eclipse.swt.graphics.Rectangle(11,64,270,19));

		button = new Button(sShell, SWT.NONE);

		button.setBounds(new org.eclipse.swt.graphics.Rectangle(85,96,96,30));

		button.setText("Temperatur");

		button.addMouseListener(new org.eclipse.swt.events.MouseAdapter() {

			public void mouseDown(org.eclipse.swt.events.MouseEvent e) {

				System.out.println("mouseDown()"); // Für die Entwicklung

				test();

			}

		});

	}

	

	// Methode die den Thread erzeugt

	public void test() {

		Thread thr = new Thread(new Runnable() { 

	         public void run() { 

	            while (true) { 

	            	Display.getDefault().syncExec(r); 

	            	// Den Thread für 2 sec anhalten

	            	try {

	            		Thread.sleep(2000);

	   				}

	   				catch (InterruptedException e) {}

	            } 

	         } 

	     }); 

	    // Thread starten 

		thr.start(); 

	}

	

	// Runnable das das Textfeld ändern kann

	final Runnable r = new Runnable() { 

	    public void run() { 

			try {

				Process proc = Runtime.getRuntime().exec("cat /proc/acpi/thermal_zone/TZ1/temperature");

				BufferedReader input = new BufferedReader(new InputStreamReader(proc.getInputStream()));	

				// Die Temperatur in einen String schreiben	

				line = input.readLine();

				// und die Temperatur in das Textfeld schreiben

				text.setText(line);

			}

			catch (Exception k) { System.err.println(""+k); }

	    } 

	}; 

}
```

Jetzt muss ich nur noch raus bekommen wie ich den Thread beende.

Also Danke


----------



## Leroy42 (30. Mrz 2006)

Am besten beendet er sich selbst auf Anforderung

```
private boolean stopThisThread = false:
           public void run() { 

               while (!stopThisThread) { 

                  Display.getDefault().syncExec(r); 

                  // Den Thread für 2 sec anhalten 

                  try { 

                     Thread.sleep(2000); 

                  } 

                  catch (InterruptedException e) {} 

               } 

            }
```
Und von _außerhalb_ setzt du stopThisThread einfach auf true


----------



## MrLinux (30. Mrz 2006)

Und es funktioniert !

Mal schauen ob ich den JWatcher noch ein wenig ausbaue.

Danke und Gruß

 JB


----------

