2

I'm trying to make a stopwatch with three buttons, "Start", "Pause", and "Stop". My instructor only taught us how to set Action Listeners to two buttons. How do I set up Action Listeners to three buttons? Here is my coding so far

JButton startButton = new JButton("Start");
JButton stopButton = new JButton("Stop");
JButton pauseButton = new JButton("Pause");

startButton.addActionListener(this);
stopButton.addActionListener(this);

public void actionPerformed(ActionEvent actionEvent) {
    Calendar aCalendar = Calendar.getInstance();
    if (actionEvent.getActionCommand().equals("Start")){
        start = aCalendar.getTimeInMillis();
        aJLabel.setText("Stopwatch is running...");
    } else {
        aJLabel.setText("Elapsed time is: " + 
                (double) (aCalendar.getTimeInMillis() - start) / 1000 );

    }
}

I haven't made any Action Listeners for my "Pause" feature yet because I don't know how to pause the timer anyway. But I wanted to link the action to the button before I figured out how to pause.

Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • Why would `pauseButton.addActoinListener(this)` not work? Why would you not be able to add another `else if` statement to you code to test for it...? – MadProgrammer Jul 29 '14 at 05:04
  • Sorry what I had up originally did not work. The "e.getSource()==startButton)" did not work because startButton was not a variable. Not sure how to get that feature to work. – SeverelyConfused Jul 29 '14 at 05:06

3 Answers3

3

What you are looking for is a if-then-else if-then statement.

Basically, add the ActionListener to all three buttons as you have been doing...

JButton startButton = new JButton("Start");
JButton stopButton = new JButton("Stop");
JButton pauseButton = new JButton("Pause");

startButton.addActionListener(this);
stopButton.addActionListener(this);
pauseButton.addActionListener(this);

Then supply a if-else-if series of conditions to test for each possible occurrence (you are expecting)

public void actionPerformed(ActionEvent e) {
    Calendar aCalendar = Calendar.getInstance();
    if (e.getSource() == startButton){
        start = aCalendar.getTimeInMillis();
        aJLabel.setText("Stopwatch is running...");
    } else if (e.getSource() == stopButton) {
        aJLabel.setText("Elapsed time is: " + 
                (double) (aCalendar.getTimeInMillis() - start) / 1000 );
    } else if (e.getSource() == pauseButton) {
        // Do pause stuff
    }
}

Take a closer look at The if-then and if-then-else Statements for more details

Instead of trying to use the reference to the buttons, you might consider using the actionCommand property of the AcionEvent instead, this means you won't need to be able to reference the original buttons...

public void actionPerformed(ActionEvent e) {
    Calendar aCalendar = Calendar.getInstance();
    if ("Start".equals(e.getActionCommand())){
        start = aCalendar.getTimeInMillis();
        aJLabel.setText("Stopwatch is running...");
    } else if ("Stop".equals(e.getActionCommand())) {
        aJLabel.setText("Elapsed time is: " + 
                (double) (aCalendar.getTimeInMillis() - start) / 1000 );
    } else if ("Pause".equals(e.getActionCommand())) {
        // Do pause stuff
    }
}

It also means that you could re-use the ActionListener for things like JMenuItems, so long as they had the same actionCommand...

Now, having said that, I would encourage you not to follow this paradigm. Normally, I would encourage you to use the Actions API, but that might be a little too advanced for where you're up to right now, instead, I would encourage you to take advantage of Java's anonymous class support, for example....

startButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        start = aCalendar.getTimeInMillis();
        aJLabel.setText("Stopwatch is running...");
    }
});
stopButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        aJLabel.setText("Elapsed time is: "
                + (double) (aCalendar.getTimeInMillis() - start) / 1000);
    }
});
pauseButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        // Do pause stuff
    }
});

This isolates the responsibility for each button to a single ActionListener, which makes it easier to see what's going on and when required, modify them without fear or affecting the others.

It also does away with the need to maintain a reference to the button (as it can be obtained via the ActionEvent getSource property)

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Thank you for giving me so many options and thoroughly explaining each one. I don't think I knew about if-else-if conditions. This really helped! – SeverelyConfused Jul 29 '14 at 19:46
2

If you don't want to implement ActionListener you can add anonymous listener to your button like this:

 JButton startButton = new JButton("Start");
 JButton stopButton = new JButton("Stop");
 JButton pauseButton = new JButton("Pause");
 startButton.addActionListener(new ActionListener() 
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            //start action logic here
        }
    });
 stopButton.addActionListener(new ActionListener() 
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            //stop action logic here
        }
    });
 pauseButton.addActionListener(new ActionListener() 
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            //action logic here
        }
    });

And this solution have to work :)

mlethys
  • 436
  • 9
  • 29
0

All you need to add is this after the buttons creation.

startButton.setActionCommand("Start");
stopButton.setActionCommand("Stop");
pauseButton.setActionCommand("Pause");

and in actionPerformed method use this.

switch(actionEvent.getActionCommand())
{
// cases
}
Stelium
  • 1,207
  • 1
  • 12
  • 23