0

As a test project, I'm trying to write a program that calculates my CPS.

To achieve that, I use the Timer scheduled at Fixed rate to count the given time in this example ten times the time is then displayed on a JProgressBar, while the user tries to click the button as often as possible.

But when I start the timer with the button, it takes about another 10 seconds for the timer to start and fill the bar.

Maybe its just because my computer is slow?

The code

import javax.swing.*;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Timer;
import java.util.TimerTask;


public class MCPS {
    JFrame frame;
    JProgressBar timeProgress;
    int stateTimeProgress;
    JButton button;
    Container pane;
    boolean inGame;
    int amountClicked;
    boolean isMeasured;
    int duration;
    java.util.Timer timer;

    public MCPS(int time){
        stateTimeProgress = 0;
        duration = time;
        frame = new JFrame("CPS");
        initLogic();
        initFrame();
        initProgressBar(duration);
        initButton();
        pane = new Container();
        pane.setLayout(new FlowLayout());

        init();
    }

    private void initProgressBar(int time) {
        timeProgress = new JProgressBar(0, time);
        timeProgress.setValue(0);

    }


    private void initLogic() {
        inGame = false;
        amountClicked = 0;
        isMeasured = false;
    }

    private void startTimer(int time) {
        timer = new Timer();
        timer.scheduleAtFixedRate(new TimerTask() {
            @Override
            public void run() {
                stateTimeProgress++;
                timeProgress.setValue(stateTimeProgress);
                if(stateTimeProgress == time){
                    timer.cancel();
                    stopGame();
                }
            }
        }, time*1000, 1000);
    }

    private void stopGame() {
        inGame = false;
    }

    private boolean isInGame() {
        return inGame;
    }

    private void initButton() {
        button = new JButton("Start");
        button.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if(isInGame()){
                    amountClicked++;
                }
                else{
                    if(isMeasured == false) {
                        button.setText("Click me!");
                        startGame();
                    }
                }
            }
            @Override
            public void mousePressed(MouseEvent e) {}
            @Override
            public void mouseReleased(MouseEvent e) {}
            @Override
            public void mouseEntered(MouseEvent e) {}
            @Override
            public void mouseExited(MouseEvent e) {}
        });
    }

    private void startGame() {
        inGame = true;
        isMeasured = true;
        startTimer(duration);
    }

    private void initFrame() {
        frame.setResizable(true);
        frame.setSize(350, 150);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
    }

    private void init() {
        pane.add(button);
        pane.add(timeProgress);

        frame.add(pane);
        frame.setVisible(true);
    }
}

Community
  • 1
  • 1
JGStyle
  • 147
  • 12
  • 1
    `java.util.Timer timer;` Use a `javax.swing.Timer` instead, when dealing with GUI components. Updates to them need to be on the EDT, and are, automatically when using the Swing `Timer`. – Andrew Thompson Feb 12 '20 at 16:32

2 Answers2

0

https://docs.oracle.com/javase/7/docs/api/java/util/Timer.html#scheduleAtFixedRate(java.util.TimerTask,%20long,%20long)

public void scheduleAtFixedRate(TimerTask task, long delay, long period)

Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay. Subsequent executions take place at approximately regular intervals, separated by the specified period.

The second parameter you've specified is the delay before the Timer starts. Set that to 0 instead to get it to start straight away

user27158
  • 297
  • 1
  • 5
0

Check the documentation:

public void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)

Parameters:

task - task to be scheduled.

firstTime - First time at which task is to be executed.

period - time in milliseconds between successive task executions.

You wrote :

    timer.scheduleAtFixedRate(new TimerTask()..., time*1000, 1000);

That means it will delay the first run by time*1000ms

To start the execution immediatly, simply change the code to

    timer.scheduleAtFixedRate(new TimerTask()..., 0, 1000);

Then, if you want to end the timer after after X seconds, there is some solutions on SO:

Community
  • 1
  • 1
jhamon
  • 3,603
  • 4
  • 26
  • 37