# SWT Thread Problematik



## iTob87 (9. Juli 2009)

Hallo Leute,
ich habe folgendes Problem und weiß nicht genau, wie ich es anpacken soll:

Ich habe einen Thread A (ist nicht der Main-Thread). Dieser Thread A stößt zwei weitere Threads B und C an. Innerhalb von B + C sollen zwei Fenster mit SWT geöffnet werden (welche auch parallel bedienbar sein sollten). Bei mir öffnet sich max. immer nur ein Fenster, weil er dann hängen bleibt. wenn ich die GUI in B + C mit asyncExec() aufrufe, bekomme ich überhaupt nichts zu sehen. Als Display benutze ich in B + C Display.getDefault() (was ist hier eigentlich der Unterschied zu Display.getCurrent()), welches ich dann an die GUI weitergebe. Wichtig ist vielleicht noch, dass von der GUI in B + C jeweils eine eigene Instanz gebildet wird.

Kann mir vielleicht jemand einen groben plan geben, wie ich das architektonisch am besten anpacke, dass ich von den zwei threads (B + C) aus zwei GUIs öffnen kann, welche gleichzeitig bedienbar sind?



Vielen Dank für eure Hilfe!


Greetz, iTob


----------



## Thomas Darimont (15. Juli 2009)

Hallo,

von unterschiedlichen Threads aus SWT Shells aufzumachen macht die ganze Sache ein wenig komplizierter als gewöhnlich:

```
package de.tutorials.swt.training;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class SWTUI {

	final Lock lock = new ReentrantLock();
	final Condition displayReady = lock.newCondition();
	final ExecutorService executorService = Executors.newCachedThreadPool();
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new SWTUI().createAndRunUI();
	}

	private void shutdown() {
		System.out.println("shutting down...");
		executorService.shutdownNow();
	}

	private void createAndRunUI() {
		executorService.execute(new Runnable() {
			public void run() {
				lock.lock();

				System.out.println("booting swt display in: " + Thread.currentThread());

				Display display = Display.getDefault();
				
				try {
					displayReady.signal();
				} finally {
					lock.unlock();
				}
				
				while (!display.isDisposed()) {
					if (!display.readAndDispatch()) {
						display.sleep();
					}
				}

				System.out.println("Display disposed");
				shutdown();
			}
		});

		lock.lock();
		try {
			try {
				displayReady.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		} finally {
			lock.unlock();
		}

		executorService.execute(new Runnable() {
			public void run() {

				executorService.execute(new Runnable() {
					public void run() {
						showWindow("A");
					}
				});

				executorService.execute(new Runnable() {
					public void run() {
						showWindow("B");
					}
				});

				for (int i = 0; i < 100; i++) {
					System.out.println(i + " xxx");
					try {
						TimeUnit.MILLISECONDS.sleep(100);
					} catch (InterruptedException e) {
						System.out.println("Task cancelled...");
						break;
					}
				}

			}
		});
	}

	public void showWindow(final String title) {
		System.out.println("Creating window from: " + Thread.currentThread()
				+ " " + title);
		executorService.execute(new Runnable() {
			public void run() {
				final Display display = Display.getDefault();
				System.out.println("New Shell with: " + display + " " + display.getThread());
				display.asyncExec(new Runnable() {
					public void run() {
						Shell shell = new Shell(display);
						shell.setText(title);
						shell.setSize(320, 240);

						shell.addDisposeListener(new DisposeListener() {
							public void widgetDisposed(DisposeEvent e) {
								if (display.getShells().length == 1) {
									System.out.println("Last shell was closed");
									display.dispose();
								}
							}
						});

						shell.open();
					}
				});
			}
		});
	}
}
```

Eine weitere Möglichkeit das ganze ein wenig einfacher zu haben wäre es, JFace ApplicationWindows verwenden.

Gruß Tom


----------

