# Ampel mit Javafx



## lennero (15. Jul 2017)

Hallo. Ich möchte eine einfache Ampel mit delays programmieren. Folgender Code spuckt zwar keine Fehler aus, aber funktionieren tut es auch nicht ...




```
package vorb7;


import java.awt.Shape;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class Grafik extends Application{

    private boolean ampelAn;
    private int z =0;

    public static void main(String []args){

        launch(args);


    }

    @Override
    public void start(Stage pStage) throws Exception {

        StackPane sp = new StackPane();
        Circle circle1 = new Circle();
        circle1.setRadius(100);
        circle1.setFill(Color.GREY);
        Circle circle2 = new Circle();
        circle2.setRadius(100);
        circle2.setFill(Color.GREY);
        Circle circle3 = new Circle();
        circle3.setRadius(100);
        circle3.setFill(Color.GREY);
        VBox vb = new VBox();

        VBox vbt = new VBox();

        Button b1 = new Button();
        b1.setText("Start");




        b1.setOnAction(e-> {

            ampelAn = true;
            circle1.setFill(Color.RED);

            while(ampelAn){
            switch(z){

            case 0:
                try{
                    Thread.sleep(3000);
                }

                catch(InterruptedException e1){
                    Thread.currentThread().interrupt();
                }

            circle2.setFill(Color.YELLOW);
            z=1;

            case 1:
                try{
                    Thread.sleep(1000);
                    }

                catch(InterruptedException e2){
                    Thread.currentThread().interrupt();
                    }

                circle1.setFill(Color.GREY);
                circle2.setFill(Color.GREY);
                circle3.setFill(Color.GREEN);
                z=2;

            case 2:
                circle3.setFill(Color.GREY);
                z=0;
                }

            }






        });

        Button b2 = new Button();
        b2.setText("Stopp");

        b2.setOnAction(e-> {

            ampelAn = false;

        });




        vbt.getChildren().addAll(b1,b2);
        vbt.setAlignment(Pos.BASELINE_LEFT);
        vbt.setSpacing(15);
        vbt.setPadding(new Insets(10,10,10,10));

        vb.getChildren().addAll(circle1,circle2,circle3);
        vb.setAlignment(Pos.CENTER);
        sp.getChildren().addAll(vb,vbt);


        Scene scene = new Scene(sp,600,600);

        pStage.setTitle("Formen");
        pStage.setScene(scene);
        pStage.show();


    }


}
```


----------



## JCODA (15. Jul 2017)

Sobald du einmal den Button drückst, bist du in einer Endlosschleife. Damit wird dein Fenster nicht neu gezeichnet. Verwende für solche Dinge einen Timer. 
Zudem: Thread.sleep legt zusätzlich dein Programm lahm. Auch hier: das Fenster kann nicht neu gezeichnet werden. (Falls Thread.sleep im GUI_Thread ausgeführt wird.)
Ich hätte sowas in der Richtung gemacht: 


```
import java.util.Timer;
import java.util.TimerTask;

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;

public class Grafik extends Application {

    private int state = 0;
    private Circle[] circles = new Circle[3];
    private Timer timer = new Timer();
    private TimerTask tt = null;

    public static boolean states[][] = { { true, false, false }, { true, true, false }, { false, false, true },
            { false, true, false } };
    public static Color colors[] = { Color.RED, Color.YELLOW, Color.GREEN };

    public static void main(String[] args) {
        launch(args);
    }

    public void nextState() {
        state++;
        boolean[] currentState = states[state % 4];
        for (int i = 0; i < 3; i++) {
            if (currentState[i]) {
                circles[i].setFill(colors[i]);
            } else {
                circles[i].setFill(Color.GRAY);
            }
        }
    }

    public void startTimer() {
        if(tt != null){
            tt.cancel();
        }
        tt = new TimerTask() {
            @Override
            public void run() {

                nextState();
            }
        };
        timer.schedule(tt, 0, 2000);
    }

    @Override
    public void start(Stage pStage) throws Exception {

        StackPane sp = new StackPane();
        VBox vb = new VBox();
        vb.setAlignment(Pos.CENTER);
        for(int i = 0 ; i < 3 ; i++){
            circles[i] = new Circle();
            circles[i].setRadius(100);
            circles[i].setFill(Color.GREY);
            vb.getChildren().add(circles[i]);
        }   
       
        VBox vbt = new VBox();

        Button startbtn = new Button("Start");   
        Button stoppbtn = new Button("Stopp");
       
        startbtn.setOnAction(e -> startTimer());
        stoppbtn.setOnAction(e -> tt.cancel());
       
        vbt.getChildren().addAll(startbtn, stoppbtn);
        vbt.setAlignment(Pos.BASELINE_LEFT);
        vbt.setSpacing(15);
        vbt.setPadding(new Insets(10, 10, 10, 10));
       
        sp.getChildren().addAll(vb, vbt);

        Scene scene = new Scene(sp, 600, 600);

        pStage.setTitle("Ampelsteuerung");
        pStage.setScene(scene);
        pStage.show();

    }

}
```


----------



## lennero (16. Jul 2017)

Danke für die Hilfe. Hiermit klappt es, allerdings nur 1 mal. Wieso kann ich hier keine Endlosschleife verwenden ? 

```
b1.setOnAction(e-> {
           
           
            ampelAn = true;
            circle1.setFill(Color.RED);

           
           
                Timer z1 = new Timer();
                TimerTask a1 = new TimerTask() {

                    @Override
                    public void run() {
                        circle2.setFill(Color.YELLOW);
                    }
                };
               
                Timer z2 = new Timer();
                TimerTask a2 = new TimerTask(){

                    @Override
                    public void run() {
                        circle1.setFill(Color.GREY);
                        circle2.setFill(Color.GREY);
                        circle3.setFill(Color.GREEN);
                       
                    }
                   
                };
               
                Timer z3 = new Timer();
                TimerTask a3 = new TimerTask(){

                    @Override
                    public void run() {
                        circle1.setFill(Color.GREY);
                        circle2.setFill(Color.GREY);
                        circle3.setFill(Color.GREY);
                       
                    }
                   
                   
                };
               
               
               
               
                z1.schedule(a1, 3000);
                z2.schedule(a2, 4000);
                z3.schedule(a3, 8000);
           







        });

        Button b2 = new Button();
        b2.setText("Stopp");

        b2.setOnAction(e-> {
           
            ampelAn = false;

        });
```


----------

