# GUI verändern mit JavaFX



## Sugan (15. Jul 2016)

Hallo zusammen,

ich möchte, dass sich bei meinem Spiel verschiedene Dinge bewegen...
Zum einem im Hintergrund eine dauerhafte Schleife und zum underen per Knopfdruck. Dabei ist es wichtig, dass alle Bewegungen gleichzeitig angezeigt werden, also eigentlich was ganz normales.
Ich programmiere seit einiger Zeit mit JavaFX und habe dann auch irgendwann rausfinden dürfen, dass die guten alten Threads nicht mehr die GUI verändern dürfen. Stattdessen benutze ich jetzt Services, die über updateValue bestimmte Werte ändern. So weit so gut, doch ich kann ja schlecht für jede Bewegung einen Service programmieren 

Oder etwa doch? Ich hab das Gefühl, dass es hier eine viel leichtere Lösung geben muss...

Mir würde hierzu ein einfaches Bsp. helfen:

In der Mitte des Bildschirms ist ein Knopf. Immer, wenn man auf den Knopf drückt, erscheint ein kleines Symbol (der einfachheit halber ein Label) und "fliegt" dann nach oben. Wenn man schnell hintereinander drückt, sollen entsprechend mehrere Labels sichtbar sein, da sie hintereinander nach oben "fliegen".

Hier mein Code dazu (bis jetzt mit einem Service, entsprechend kann immer nur ein Label angezeigt werden):


```
import javafx.application.Application;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

public class Game extends Application{
  
    int max = 10;
    int click = 0;

    AnchorPane root = new AnchorPane();
    Button button = new Button("Bitte\ndrücken");
    Label[] labels = new Label[max];
    Service<Integer> label0Thread;
  
    @Override
    public void start(Stage stage) throws Exception {
      
         label0Thread = new Service<Integer>() {
             protected Task<Integer> createTask() {
                 return new Task<Integer>(){
                     @Override
                     protected Integer call() throws Exception {
                         labels[0].setVisible(true);
                         for(int i=0; i<50; i++){
                             updateValue(250-i*2);
                             Thread.sleep(10);
                         }
                         labels[0].setVisible(false);
                         return null;
                     }
                 };
             }
         };
      
        for(int i=0; i<max; i++){
            labels[i] = new Label();
            labels[i].setText("ping");
            root.getChildren().add(labels[i]);
            labels[i].setVisible(false);
            labels[i].setTranslateX(288);  
            labels[i].setTranslateY(230);
        }
        labels[0].translateYProperty().bind(label0Thread.valueProperty());
      
        button.setPrefSize(100, 100);
        button.setTranslateX(250);
        button.setTranslateY(250);
         button.setOnAction(event -> {
             label0Thread.restart();
         });
       
         root.getChildren().add(button);
       
        Scene scene = new Scene(root,600,600);      
         stage.setScene(scene);
         stage.show();
       
    }
    public static void main(String[] args){
        launch(args);
    }  
}
```



vielen Dank für eure Hilfe!

Sugan


----------



## TheBohne (1. Aug 2016)

Wie wäre es mit einer Klasse die alle grafischen Objekte beinhaltet und in der es einen Thread gibt der mittels 

```
Platform.runLater(new Runnable() {

             @Override
             public void run() {
}
})
```
alle Objekte Aktualisiert. Diese Methode kannst du ja dann alle 100ms aufrufen und mittels wait und notify warten bis sie duchgelaufen ist.


----------

