Timer creates a new Window on Start

115 Views Asked by At

My timer is creating a new window with non-working buttons when I hit the start button. The change in display only happens in the new window but the start/stop functionality only works in the old window. I'm not sure what's going on here. Can someone help me figure out how to stop it from creating a new window when start is pressed?

I have three classes I'm working with. The first runs the timer.

package timer;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import java.awt.event.*;

public class TaskTimer extends TaskTimerWindow {

    int seconds = 0;
    int minutes = 0;
    int hours = 0;
    final int UNIT = 1000;
    boolean stopped = false;
    Timer timer;

    public TaskTimer() {

        ActionListener go = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                count();    
            }   
        };

        timer = new Timer(UNIT, go);
        timer.start();      
    }

    public void resume() {
        if(stopped) {
            seconds = 0;
            minutes = 0;
            hours = 0;
        }   
    }

    public void end() {
        timer.stop();   
    }

    public void count() {
        if(seconds < 59) {
            seconds++;
        } else if(minutes < 59) {
            seconds = 0;
            minutes++;
        } else {
            seconds = 0;
            minutes = 0;
            hours++;
        }
        changeDisplay(String.format("%02d", hours) + ":" 
             + String.format("%02d", minutes)  + ":" 
             + String.format("%02d", seconds));
    }
}

The second creates and updates the display.

package timer;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;


public class TaskTimerWindow extends JFrame {

    JLabel timeDisplay;
    JButton start, stop, pause;

    public TaskTimerWindow() {

        JPanel timerWindow = new JPanel();
        JPanel buttonSpace = new JPanel();

        timeDisplay = new JLabel("00:00:00");
        timeDisplay.setHorizontalAlignment((int) CENTER_ALIGNMENT); 
        timeDisplay.setFont(new Font("Arial", Font.PLAIN, 48));

        timeDisplay.setBackground(Color.WHITE);

        timerWindow.add(timeDisplay);

        start = new JButton("Start");
        stop = new JButton("Stop");
        pause = new JButton("Pause");

        buttonSpace.add(start);
        buttonSpace.add(stop);
        buttonSpace.add(pause);

        getContentPane().add(timerWindow, BorderLayout.NORTH);
        getContentPane().add(buttonSpace);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        setLocationRelativeTo(null);
        setTitle("Task Timer");
        pack();
    }

    public JLabel getText() {
        return timeDisplay;
    }

    public void changeDisplay(String time) {
        getText().setText(time);
    }

}

And the third is the controller.

package timer;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class ControlTimer {
    boolean stopped = false;
    boolean paused = false;
    TaskTimer timer;


    public ControlTimer() {
        TaskTimerWindow window = new TaskTimerWindow();
        window.start.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                timer = new TaskTimer();
            }
        });

        window.stop.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                stopped = true;
                timer.end();
            }
        });

        window.pause.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                paused = true;
            }
        });
    }
}
1

There are 1 best solutions below

0
Pavlo Viazovskyy On BEST ANSWER

So the main problem is in your ControlTimer class. As TaskTimer extends TaskTimerWindow it was creating new window each time start button was pressed. You should modify it like following:

public class ControlTimer {
    boolean stopped = false;
    boolean paused = false;
    TaskTimer timer;


    public ControlTimer() {
        timer = new TaskTimer();
        timer.start.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                timer.resume();
                timer.start();
            }
        });

        timer.stop.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                timer.stopped = true;
                timer.end();
            }
        });

        timer.pause.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                timer.end();
            }
        });
    }
}

Also there're some minor changes in TaskTimer class (removing timer.start() from constructor and introducing separate start() method instead:

public TaskTimer() {

    ActionListener go = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            count();
        }
    };

    timer = new Timer(UNIT, go);
}

public void start() {
    timer.start();
}