# JavaFX 2 (2.1 Beta) Threads



## Porenta (4. Feb 2012)

Hallo,
Ich habe einen Problem mit der neuen Version von JavaFX. In einem neuen thread möchte ich gerne eine Instanz einer Klasse erstellen und eine Methode aufrufen, in der ich mehrere Konstruktoren von JavaFX klassen aufrufe. Dies funktioniert leider nicht. Ich bekomme immer folgende fehlermeldung:

```
Exception in thread "main" java.lang.IllegalStateException: Not on FX application thread; currentThread = main
	at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:235)
	at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:394)
	at javafx.stage.Stage.<init>(Stage.java:140)
	at javafx.stage.Stage.<init>(Stage.java:126)
	at org.alternative.dev.MainThread.run(MainThread.java:15)
	at org.alternative.dev.MainActivity.main(MainActivity.java:32)
```
Ist es überhaupt möglich, hier mit Threads zu arbeiten?

P.S.: Ich glaube zwar nicht, dass es daran liegt, aber ich benutze eclipse statt NetBeans


----------



## schlingel (5. Feb 2012)

Das schaut sehr danach aus als möchtest du irgendetwas UI spezifisches auf einem anderen Thread erledigen. Darauf reagieren so ziemlich alle aktuellen Frameworks unerfreut (Android, Swing, etc.) und schmeißen ähnliche Exceptions.

Was du auch vorhast, probier es einmal mit dieser Platform-Klasse aufzurufen.


----------



## Porenta (5. Feb 2012)

Okay, also das mit der Platform-Klasse.runLater(Runnable); scheint schonmal zu funktionieren, nur irgendwie nicht als neuer Thread. Also mein Code sieht erstmal so aus:

```
public class MainActivity extends Application implements
		EventHandler<ActionEvent> {
...
private MainThread updater;
...
@Override
	public void start(Stage stage) {
		updater = new MainThread();
		updater.setInstance(this);
                ...
}
public void handle(ActionEvent arg0) {
		{
                    ...
		    Platform.runLater(new Thread(updater));
		}
```
MainThread.java:

```
package org.alternative.dev;

public class MainThread extends Thread {

	private MainActivity instance;
	
	public void setInstance(MainActivity in){
		instance = in;
	}
	
	public void run() {
			
		while (true) {
			try {
				instance.update();	
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

	}

	

}
```
die update() Methode aktualisiert den Wert eines Sliders.
Wenn ich das so ausführe hängt es sich auf, als wenn die while-Schleife im gleichen Thread läuft..
Platform.runLater(Runnable) kann ich nicht im Thread selber benutzen, weil ich dann den Error bekomme: Toolkit not initialized (liegt vermutlich daran, dass MainThread nicht Application extended)

MfG Porenta


----------



## schlingel (5. Feb 2012)

So wie der Code aussieht wird das schon als eigener Thread ausgeführt, allerdings hilft das alles nichts wenn der Update ständig auf den UI-Thread zugreift um den Slider zu aktualisieren.

Wo werden denn die Werte auf die sich der Slider bezieht abgerufen? Das riecht danach als wäre es klüger, hier einen Event einzurichten der den Slider jedesmal neu setzt wenn sich der bestimmte Wert geändert hat, als in einer Endlosschleife den Slider immer wieder neu zu setzen.


----------



## Porenta (5. Feb 2012)

Das ist auch schwer zu machen, weil der Wert von einem MediaPlayer kommt, bei dem sich der Wert natürlich kontinuierlich ändert, wenn ein Song abgespielt wird. Ich habe inzwischen gelsen, dass man solche sachen angeblich auch mit Tasks machen kann. Ich habe allerdings keine Idee, wie ich das damit machen sollte.  Ein funktionierendes Beispiel habe ich nämlich nicht gefunden.

MfG,
Porenta


----------



## schlingel (5. Feb 2012)

Hm, diese Task-Api sieht schon mal viel versprechend aus. Das solltest du dir genauer anschauen.

Aber um ein schnelles Ergebnis zu bekommen, könntest du den updater-Thread nach jedem Durchlauf 5sec schlafen legen. Dann hättest du noch immer 12 Updates in der Minute was für einen Mediaplayer ja mehr als genug ist.


----------



## Paddelpirat (5. Feb 2012)

Eventuell hier auf der Seite mal den Code von Example 6 ausprobieren?

Creating Transitions and Timeline Animation in JavaFX | JavaFX 2.0 Tutorials and Documentation


----------



## Porenta (5. Feb 2012)

Also mit Task hat es problemlos funktioniert. Einfach die Klasse Task<Void> extenden lass und dann new Thread(task).start(); 
Danke für eure Hilfe .


----------

