2

I'm trying to create animation for a traffic light simulation that uses a timer. There is a button to stop the simulation, but clicking it does not seem to affect the animation. I did check in the animation but the animation seem like different places. Please help.

In the main class:

DataModels dm = new DataModels();
Simulation sm = new Simulation(dm);
sm.go();

Here is the simulation class:

public class Simulation extends JPanel implements ActionListener {
    DataModels dm;
    Timer tm = new Timer(20, this);
    private boolean ss = false;

    public Simulation(DataModels dm) {
        this.dm = dm;
        // redLightTime= dm.getRedLight()*1000;
    }

    public void go() {
        sm = new Simulation(dm);
        simulation = new JFrame();
        simulation.setTitle("Traffic light and Car park Siumulation");
        simulation.setSize(800, 700);
        simulation.setResizable(false);
        simulation.setVisible(true);
        simulation.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        simulation.add(sm, BorderLayout.CENTER);

        // Command button panel
        JPanel command = new JPanel();
        command.setPreferredSize(new Dimension(800, 100));
        // Pause or play button
        JButton pauseplayB = new JButton("Pause");
        pauseplayB.setSize(new Dimension(50, 50));
        pauseplayB.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                // Execute when button is pressed
                ss = true;
                System.out.println("You clicked the button");
            }
        });
        command.add(pauseplayB);
        JButton stopB = new JButton("Stop");
        JButton saveB = new JButton("Save");

        command.setLayout(new GridLayout(1, 1));
        command.add(stopB);
        command.add(saveB);
        simulation.add(command, BorderLayout.SOUTH);
    }

Now paintComponent will change based on timer change. The following code is also in the Simulation class.

public void paintComponent(Graphics g) {
    // Many other actions
    // ....
    startAnimation();
}

public void startAnimation() {
    if ( !false) {
        tm.start();
    } else {
        tm.stop();
    }
    // Checking button click
    System.out.println(ss);
}

According to the console output, the ss value never changes.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Cao Linh Truong
  • 253
  • 8
  • 20
  • Is the JPanel being painted after you click the button? Why don't you try forcing your JPanel to repaint or invalidate itself when you click the button? *Although, a button click should invalidate the JPanel* – Redandwhite Aug 29 '12 at 19:42
  • 1
    Also, consider changing your `if` statement to something more, *modern:* `if (!ss) { ... }` – Redandwhite Aug 29 '12 at 19:44
  • Painted?? In the console line: got the check: You clicked the button but the value ss not change – Cao Linh Truong Aug 29 '12 at 19:46
  • Does `System.out.println("You clicked the button");` get printed? (It's in your action listener.) – Roddy of the Frozen Peas Aug 29 '12 at 19:48
  • I think this guy got same problem with me:http://stackoverflow.com/questions/8088002/how-to-use-a-swing-timer-to-start-stop-animation but which one was my answer – Cao Linh Truong Aug 29 '12 at 20:02
  • For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Aug 30 '12 at 00:25
  • 1
    to emphasize @JTMon 's answer: *never-ever* change the state of a component in its paintComponent. Also, I would suggest to change the name of the startAnimation, so it gets obvious that it is responsible for both starting and stopping. BTW: from your snippet, it's expected that ss always is the same, you never change it - could be that it's changed somewhere else - all the more reason to show an SSCCE instead of snippets :-) Unrelated: a) never-ever call setXXSize (instead, use a LayoutManager which suits your needs), b) remove pausePlayB.setSize, it has no effect anyway – kleopatra Aug 30 '12 at 06:09

2 Answers2

4

The button's action listener should call the function to stop the timer somehow and not rely on the paint event to do it.

EDIT: Here is some code :)

public void actionPerformed(ActionEvent e) {
    // Execute when button is pressed
    ss = true;
    System.out.println("You clicked the button");
    startAnimation();
}

And the startAnimation method should have if(!ss) instead of if(!false)

JTMon
  • 3,189
  • 22
  • 24
3

In addition to JTMon's suggestion, your startAnimation method contains a logic bomb

public void startAnimation() {
    if ( !false) { //<-- this will ALWAYS be true
        tm.start();
    } else {
        tm.stop();
    }
    // Checking button click
    System.out.println(ss);
}

The if statement that controls the timer will ALWAYS try & start the timer

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • That must be a typo in response to @RedAnwhite's comment as the original post had if(ss==false) :) – JTMon Aug 29 '12 at 20:38