更改交通灯状态java切换按钮

时间:2017-03-22 14:49:24

标签: java user-interface jframe

我试图将交通信号灯从红色变为黄色再变为绿色并在java中重复,然后按一个按钮启动此过程。这是我的代码:

public class TrafficLight extends JFrame implements ActionListener {
  JButton b1, b2, b3;

  Signal green = new Signal(Color.green);
  Signal yellow = new Signal(Color.yellow);
  Signal red = new Signal(Color.red);

public TrafficLight(){
    super("Traffic Light");
    getContentPane().setLayout(new GridLayout(2, 1));
    b1 = new JButton("Change State");
    b1.addActionListener(this);


    green.turnOn(false);
    yellow.turnOn(false);
    red.turnOn(true);

    JPanel p1 = new JPanel(new GridLayout(3,1));
    p1.add(red);
    p1.add(yellow);
    p1.add(green);
    JPanel p2 = new JPanel(new FlowLayout());
    p2.add(b1);


    getContentPane().add(p1);
    getContentPane().add(p2);
    pack();
    }

我知道必须有其他的if / else陈述,但我不确定这是否是我应该进入的最佳方向。

public void actionPerformed(ActionEvent e){        
    if (e.getSource() == b1){
        green.turnOn(false);            
        yellow.turnOn(false);
        red.turnOn(true);

    }
}

4 个答案:

答案 0 :(得分:1)

如果你有Java8,你可以循环任何这样的集合:

List<Color> colors = Arrays.asList(GREEN, YELLOW, RED);
Iterator<Color> loop = Stream.generate(() -> colors).flatMap(List::stream).iterator();

在你完成它之后(并保存这个迭代器,因为那是你的应用程序状态):

actionPerformed(ActionEvent e) {
  Color clr = loop.next();
  if (clr == GREEN) {
    green.turnOn(true);
    yellow.turnOn(false);
    red.turnOn(false);
  }
  //<continue there for other colors>
}

我个人也建议进一步抽象,这样你的颜色每个都代表一个应用程序状态,所以你的颜色是一个类

interface Color {
  void activate();
}

您的事件监听器将只调用

loop.next().activate();

并且所有必要的工作都将在该方法内部完成,而不是在侦听器内部完成。

继续使用吸收路径还可以添加,例如,在前一个灯关闭之前闪烁。

答案 1 :(得分:0)

如果我是你,我会做这样的事情:

public void actionPerformed(ActionEvernt e) {
    // Turn off everything so you don't repeat yourself
    green.turnOn(false);
    yellow.turnOn(false);
    red.turnOn(false);

    // This is the work around with if/else statements.
    // Can be done with a switch statement too. 
    // No sure what you mean by 'b1', I will assume b1 is red, b2 is green, and b3 is yellow.
    if(e.getSource() == b1) {  
        red.turnOn(true);
    } else if (e.getSource() == b2) {
        green.turnOn(true);
    } else if (e.getSource() == b3) {
        yellow.turnOn(true);
    }
}

如果您有任何问题,请随时提出。

答案 2 :(得分:0)

这是另一种方法,创建一个Signals类,它将管理下一个灯打开(并关闭最后一个灯):

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;

public class Signals {

    private List<Signal> signalsList = new ArrayList<>();
    private int selectedIndex = 0;

    public Signals(final int selectedIndex, final Signal... signals) {

        for (Signal signal : signals) {

            signalsList.add(signal);

        }

        this.selectedIndex = selectedIndex;

        signalsList.get(selectedIndex).turnOn(true);
    }

    public void switchLights() {

        signalsList.get(selectedIndex).turnOn(false);

        selectedIndex = (selectedIndex + 1) > (signalsList.size() - 1) ? 0 : selectedIndex + 1;

        signalsList.get(selectedIndex).turnOn(true);

    }

}

在您的代码中,创建该类的实例

Signals signals = new Signals(2,green,yellow,red);

并以这种方式使用:

public void actionPerformed(ActionEvent e){        
    if (e.getSource() == b1){

        signals.switchLights();

    }
}

答案 3 :(得分:0)

尝试使用AWT计时器。这将允许您在每个之间设置恒定的变化率。只需为交通信号灯的每个状态执行一个if(或交换机,如果你使用枚举)。

LightTimer = new Timer(1000, null);
LightTimer.addActionListener(new ActionListener()  {

  @Override
  public void actionPerformed(ActionEvent event) {
    if(b1.getState() == true) {
      if (light.getState() == red)
        light.setState(yellow);
      else if(light.getState() == yellow)
        light.setState(green);
      else light.setState(red);
    }
  }
});