简体   繁体   中英

How do i switch traffic lights in java for each light should blow only for 3 seconds respectively using multithreading?

I made a traffic light stimulation system in which each traffic light ie green , red, yellow will blow for 3 seconds each respectively. I successfully created the GUI of this system.

public class TrafficLightSimulator extends Application implements Runnable{
    Circle red = new Circle();
    Circle green = new Circle();
    Circle yellow = new Circle();
    Button b1 = new Button();
@Override
public void start(Stage stage) {
    //Drawing a Rectangle 
    Rectangle rectangle = new Rectangle();


    //grid layout
    GridPane grid = new GridPane();
    grid.setHgap(20);
    grid.setVgap(5);
//buttons
    HBox hbButtons = new HBox();

    Button buttonStart = new Button("Start");
    Button buttonStop = new Button("Stop");
  buttonStart.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent event) {
        green.setFill(Color.YELLOW);
}
    });
   buttonStop.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent event) {
   TrafficLightSimulator tl=new TrafficLightSimulator();
   Thread t1=new Thread(tl);
   t1.start();
        }
    });
    //labels and textfeilds
    Label lblGreen = new Label("Green");
    TextField tfGreen = new TextField("3");
    Label lblYellow = new Label("Yellow");
    TextField tfYellow = new TextField("3");
    Label lblRed = new Label("Red");
    TextField tfRed = new TextField("3");

    grid.add(lblGreen, 0, 0);
    grid.add(tfGreen, 1, 0);
    grid.add(lblYellow, 0, 1);
    grid.add(tfYellow, 1, 1);
    grid.add(lblRed, 0, 2);
    grid.add(tfRed, 1, 2);
    grid.setPadding(new Insets(320, 5, 30, 40));


    hbButtons.getChildren().addAll(buttonStart, buttonStop);
    hbButtons.setAlignment(Pos.BOTTOM_CENTER);
    //Setting the properties of the rectangle 
    rectangle.setX(150);
    rectangle.setY(75);
    rectangle.setWidth(400);
    rectangle.setHeight(200);

    rectangle.setArcHeight(50);
    rectangle.setArcWidth(50);
    Color c = Color.web("#404040");
    Color color1 = Color.web("#404040");
    Color color2 = Color.web("#808080");
    Color greenColor = Color.web("#00FF00");

    rectangle.setFill(c);
    //setting circle properties

    green.setCenterX(230);
    green.setCenterY(170);
    green.setRadius(50);
    green.setFill(greenColor);

    yellow.setCenterX(345);
    yellow.setCenterY(170);
    yellow.setRadius(50);
    yellow.setFill(color2);
    red.setCenterX(465);
    red.setCenterY(170);
    red.setRadius(50);
    red.setFill(color2);
    hbButtons.setPadding(new Insets(15, 12, 15, 12));
    hbButtons.setSpacing(10);   // Gap between nodes
    //Creating a Group object  
    StackPane rootPane = new StackPane();
    Pane p1 = new Pane(red, green, yellow);
    Pane p2 = new Pane(rectangle);
    grid.add(hbButtons, 2, 2, 2, 1);
    //  grid.add(grid, 2, 0, 0, 0);

    rootPane.getChildren().addAll(p2, p1, grid);
    //Creating a scene object 
    Scene scene = new Scene(rootPane, 600, 500);

    //Setting title to the Stage 
    stage.setTitle("Drawing a Rectangle");

    //Adding scene to the stage 
    stage.setScene(scene);

    //Displaying the contents of the stage 
    stage.show();
}

I'm new to multithreading, but I'm unable to implement the code by which lights can change the color for particular timing like this

I've code some part of it

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

@Override
public void run() {
    while (true) {
        try {
            Thread.sleep(400);
        } catch (InterruptedException e) {
            System.out.println(e);
        }
        green.setFill(Color.RED);
        //  green.setFill(Color.GREEN);
        System.out.println("hello");
    }
}

Change the event handler of the start button to:

buttonStart.setOnAction(new EventHandler<ActionEvent>() {
    public void handle(ActionEvent event) {
        Thread t = new Thread() {
            @Override
            public void run() {
                try {
                    green.setFill(Color.GREEN);

                    Thread.sleep(3000L);
                    green.setFill(Color.GRAY);
                    yellow.setFill(Color.YELLOW);

                    Thread.sleep(3000L);
                    yellow.setFill(Color.GRAY);
                    red.setFill(Color.RED);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        t.start();
    }
});

Notice the color of the circles is updated in a new thread.

In JavaFX, both events and UI updates are handled by the same JavaFX Application thread. If we would not run these UI updates in a different thread, the rendering would block until the event handler finishes.

Thanks!!! Its working fine but I think we have to change little bit in a code to get the text value from the textbox for a timer. and also we need to add a button stop action listener to stop the Thread

buttonStart.setOnAction(new EventHandler<ActionEvent>() {
            public void handle(ActionEvent event) {
                Thread t = new Thread() {
                    @Override
                    public void run() {
                        try {

                            green.setFill(Color.GREEN);
                            System.out.println(Long.parseLong(tfGreen.getText()));
                            Thread.sleep(Long.parseLong(tfGreen.getText()) * 1000);
                            green.setFill(Color.GRAY);

                            yellow.setFill(Color.YELLOW);
                            Thread.sleep(Long.parseLong(tfYellow.getText()) * 1000);
                            yellow.setFill(Color.GRAY);

                            red.setFill(Color.RED);
                            Thread.sleep(Long.parseLong(tfRed.getText()) * 1000);
                            red.setFill(Color.GRAY);

                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                };
                t.start();

                buttonStop.setOnAction(new EventHandler<ActionEvent>() {
                    public void handle(ActionEvent event) {
                        green.setFill(Color.GRAY);
                        yellow.setFill(Color.GRAY);
                        red.setFill(Color.GRAY);
                        t.stop();
                    }
                });
            }
        });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM