javaswingactionlistenerabstract-actionaction-interface

Using boolean variable instead of ActionListner interface in swing


I have a small query please let me explain the scenario. I have a swing jframe in which i have a button named "start" which starts the timer in seconds so whenever i click on start it converts the the button itself to "reset" which should make the seconds to zero and should again convert itself to "start". My concern is for these both scenarios i have to run two set of codes for which i used two classes which implements ActionListener interface is there any way to include these two set of codes in the same class which implements ActionListener, and switch the block of code depending on a boolean variable which changes its value as the button changes.

I tried it but i am facing performance issues like freezing the application and not even working exactly as expected.

please review my code below.

 public class SuperTimer extends JFrame
{
    JButton start;
    private final StartCountDown countdown;
    public SuperTimer()
    {
        countdown= new StartCountDown();
        start.addActionListener(countdown);
    }
    public class StartCountDown implements ActionListener
    {
        public void actionPerformed(ActionEvent l)
        {
            if(l.getSource()==start)
            {
                count = Long.parseLong(input.getText());
                start.setText("Reset");
                reset = new Reset();
                start.removeActionListener(countdown);
                start.addActionListener(reset);
                invalid.setVisible(false);
            }
            TimeClass tc = new TimeClass(count);
            timer = new Timer(1000,tc);
            timer.start();
        }
    }
    public class Reset implements ActionListener
    {
        public void actionPerformed(ActionEvent j)
        {
            start.setText("Start");
            time.setText("00:00:00");
            input.setText("");
            timer.stop();
            timeup.setVisible(false);
            start.removeActionListener(reset);
            start.addActionListener(countdown);
        }
    }
}**

Solution

  • Use just one ActionListener or perhaps better, AbstractAction, give it a boolean variable, and then have it change its state based on the boolean variable.

    e.g.,

    import java.awt.event.ActionEvent;
    import javax.swing.*;
    
    public class ActionWithMultipleBehaviors extends JPanel {
       private TimerButtonAction timerBtnAction = new TimerButtonAction("Start", "Reset");
       private JButton timerButton = new JButton(timerBtnAction);
    
       public ActionWithMultipleBehaviors() {
          add(timerButton);
       }
    
       class TimerButtonAction extends AbstractAction {
          private boolean stateStart = true;
          private String name;
          private String secondName;
    
          public TimerButtonAction(String name, String secondName) {
             super(name);
             this.name = name;
             this.secondName = secondName;
          }
    
          @Override
          public void actionPerformed(ActionEvent e) {
             String newName;
             if (stateStart) {
                newName = secondName;
    
                // TODO: add start timer code
    
             } else {
                newName = name;
    
                // TODO: add reset timer code
    
             }
             putValue(NAME, newName);
             stateStart = !stateStart;
          }
       }
    
       private static void createAndShowGui() {
          ActionWithMultipleBehaviors mainPanel = new ActionWithMultipleBehaviors();
    
          JFrame frame = new JFrame("ActionWithMultipleBehaviors");
          frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
          frame.getContentPane().add(mainPanel);
          frame.pack();
          frame.setLocationByPlatform(true);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGui();
             }
          });
       }
    }