How to Make a Stopwatch for a quiz system using java - java

I'm really stuck, thanks to my college.
I need code in Java to have a Stopwatch which shows time in 00:00:00(mm:ss:msms) format. I want to use Key events to run and pause and reset the timer. Like if I press S the stopwatch starts and P pauses and R resets.
the thing is the I also want to add key events on numbers for teams, like if I press 1, the "team 1" flashes, preferably with a beep, and so on with 2 3 4 5. im not able to understand how to do this.
i wrote this to print time in second only just to try...
import java.awt.event.*;
import javax.swing.*;
public class StopWatch2 extends JLabel
implements KeyListener, ActionListener {
private long startTime;
private boolean running;
private Timer timer;
public StopWatch2() {
super(" Press S ", JLabel.CENTER);
addKeyListener(this);
}
public void actionPerformed(ActionEvent evt) {
long time = (System.currentTimeMillis() - startTime) / 1000;
setText(Long.toString(time));
}
public void keyPressed(KeyEvent e) {
int keyCode=e.getKeyCode();
if (keyCode==KeyEvent.VK_S) {
running = true;
startTime = e.getWhen();
setText("Running: 0 seconds");
if (timer == null) {
timer = new Timer(100,this);
timer.start();
}
else
timer.restart();
}
if(keyCode==KeyEvent.VK_P)
{
timer.stop();
running = false;
long endTime = e.getWhen();
double seconds = (endTime - startTime) / 1000.0;
setText("Time: " + seconds + " sec.");
}
}
public void keyTyped(KeyEvent e)
{}
public void keyReleased(KeyEvent e)
{}
}
import java.awt.*;
import javax.swing.*;
public class Test2 extends JApplet {
public void init() {
StopWatch2 watch = new StopWatch2();
watch.setFont( new Font("SansSerif", Font.BOLD, 24) );
watch.setBackground(Color.white);
watch.setForeground( new Color(180,0,0) );
watch.setOpaque(true);
getContentPane().add(watch, BorderLayout.CENTER);
}
}
im trying stuff on my own n m pretty much self taught so im not able to understand whats going wrong

Do you mean something like:
/**
* Stopwatch is a simple timer.
*/
public class Stopwatch {
/**
* Stopwatch() Initialises a stopwatch.
*/
public Stopwatch() {
// Your code here.
}
/**
* elapsed() The elapsed time in milliseconds shown on the stopwatch.
*
* #return double The elapsed time in milliseconds as a double. Returns -1.0 if no meaningful
* value is available, i.e. if the watch is reset or has been started and not stopped.
*/
public double elapsed() {
// Your code here.
}
/**
* start() Starts the stopwatch and clears the previous elapsed time.
*/
public void start() {
// Your code here.
}
/**
* stop() If the stopwatch has been started this stops the stopwatch and calculates the
* elapsed time. Otherwise it does nothing.
*/
public void stop() {
// Your code here.
}
/**
* reset() Resets the stopwatch and clears the elapsed time.
*/
public void reset() {
// Your code here.
}
#Override
public String toString() {
// Your code here.
}
} // end class Stopwatch

Related

Why am I getting local variable 'timer' not initialized? [duplicate]

I'm trying to stop a timer inside the the ActionListener. Below is the code of what i'm trying to do. I'm tring to stop the timer i created when a certain condition is met inside the actionPerformed method. timer.stop() does not work , the compiler does not let me do that.
Any help . suggestion , advice would be really helpful.
public class ToggleAnnotationsAction extends IdentifiedMultiAction {
//This status indicates if the Toggle action has been completed
/**
* Defines the toggling direction of a <code>ToggleAnnotationAction</code> instance.
*/
public static enum Direction {FORWARD, BACKWARD};
private Direction myDir;
/**
* Create an action with the direction presets given by the provided <code>Enum</code>.
*
* #param dir An <code>Enum</code> defined in this class which maps to the correct direction of toggling
* #see behaviors.multiact.IdentifiedMultiAction#IdentifiedMultiAction(Enum)
*/
public ToggleAnnotationsAction(Direction dir) {
super(dir);
this.myDir = dir;
}
/**
* Performs the toggling, moving the audio position to the next/previous annotation.
*
* Afterward sends an update to all <code>UpdatingActions<code>.
*
* Since the waveform display autonomously decides when to paint itself, this action may not result in an instant visual change.
*
* <p>Prints warnings if an appropriate Annotation could not be found, despite the action being enabled.
*
* #param e The <code>ActionEvent</code> provided by the trigger
*/
public void actionPerformed(ActionEvent e) {
//Reset Status to 0
status =0;
Annotation ann = findAnnotation(myDir, CurAudio.getMaster().framesToMillis(CurAudio.getAudioProgress()));
if(ann == null) {
System.err.println("It should not have been possible to call " + getClass().getName() + ". Could not find matching annotation");
}
else {
final long approxFrame = CurAudio.getMaster().millisToFrames(ann.getTime());
final long curFrame = CurAudio.getAudioProgress();
if(approxFrame < 0 || approxFrame > CurAudio.getMaster().durationInFrames() - 1) {
GiveMessage.errorMessage("The annotation I am toggling to isn't in range.\nPlease check annotation file for errors.");
return;
}
Timer timer = new Timer(10, new ActionListener() {
private long panFrame = curFrame;
private long endFrame = approxFrame;
public void actionPerformed(ActionEvent evt) {
if(myDir == Direction.FORWARD){
if (panFrame >= endFrame) {
//How do i Stop my timer here ?
return;
}
CurAudio.setAudioProgressWithoutUpdatingActions(panFrame);
panFrame += 4000;
}
else if(myDir == Direction.BACKWARD){
if (panFrame <= endFrame) {
// How do i Stop my timer here ?
return;
}
CurAudio.setAudioProgressWithoutUpdatingActions(panFrame);
panFrame -= 4000;
}
}
}
);
timer.start();
}
MyFrame.getInstance().requestFocusInWindow();
}
/**
* A forward (backward) <code>ToggleAnnotationsAction</code> should be enabled only when audio is open, not playing, and when there is an annotation following (preceding) the current position.
*/
#Override
public void update() {
if(CurAudio.audioOpen()) {
if(CurAudio.getPlayer().getStatus() == PrecisionPlayer.Status.PLAYING) {
setEnabled(false);
}
else {
double curTimeMillis = CurAudio.getMaster().framesToMillis(CurAudio.getAudioProgress());
if(findAnnotation(myDir, curTimeMillis) != null) {
setEnabled(true);
}
else {
setEnabled(false);
}
}
}
else {
setEnabled(false);
}
}
/**
* Finds the next/previous <code>Annotation</code> relative to a certain audio position in milliseconds.
*
* #param dir The direction of movement
* #param curTimeMillis The present time in milliseconds
*
* #return In principle, the <code>Annotation</code> after/before <code>curTimeMillis</code>
*/
private Annotation findAnnotation(Direction dir, double curTimeMillis) {
Annotation[] anns = AnnotationDisplay.getAnnotationsInOrder();
if(myDir == Direction.FORWARD) {
for(int i = 0; i < anns.length; i++) {
if(anns[i].getTime() - curTimeMillis > 1) {
return anns[i];
}
}
}
else {
for(int i = anns.length - 1; i >= 0; i--) {
if(curTimeMillis - anns[i].getTime() > 1) {
return anns[i];
}
}
}
return null;
}
}
Thanks in Advance
Krishnan
Also possible:
final Timer timer = new Timer(10, null);
timer.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
(as in the question, except that you can refer to timer here)
}
});
Or, use the event object to get the source (and cast it, boo):
final Timer timer = new Timer(10, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
((Timer)evt.getSource()).stop();
}
});
Or, keep the timer in an instance variable and you can reference it from your handler or have the handler call a method on your class which could stop/start it.
Fun problem.
You have to make Timer final to access it in the anonymous ActionListener you want to stop it in. But the anonymous ActionListener still won't compile because the Timer hasn't been initialized yet.
Note that a Timer may not be your best choice here. But to make this work as is, I'd wrap the Timer in an inner class.
In your ToggleAnnotationsAction.actionPerformed() method add a line like:
MyTimer timer = new MyTimer();
timer.start();
Then a class like this could be used, replacing my simple ActionListener code with your Timer's ActionListener code:
private class MyTimer implements ActionListener{
private Timer timer;
private MyTimer(){
timer = new Timer(10, this);
}
public void start(){
timer.start();
}
public void stop(){
timer.stop();
}
public void actionPerformed(ActionEvent e){
if(isTimeToStop()){
stop();
}
}
public boolean isTimeToStop(){
return true;
}
}

Get javax swing timer value

I'm trying to program a game where I output the time (in milliseconds) the player has been alive. I thought I can just use a timer and gets it value pretty easily.
public class InvaderPanel extends JPanel implements KeyListener,ActionListener {
private int timealive; //in ms, max value 2147483647 --->3.5 weeks
private Timer timer=new Timer(30,this); //I think it(30) should be 1 right ?
/**
* Create the panel.
*/
public InvaderPanel() {
addKeyListener(this);
setFocusable(true);
timer.start();
}
#Override
public void actionPerformed(ActionEvent e) {
if(playerdead){
timer.stop;
timealive=timer.value; // <--- That's what I'm looking for.
}
}
}
But here lies my problem: timer.value doesn't exist, so how do I get the value of my timer in milliseconds ?
Here is my solution for you. You need to create timer which exactly ticks 1 time per second. And each tick when player is alive increase the value of timealive variable. I have another solution for you, but I think this should be enough.
public class InvaderPanel extends JPanel implements KeyListener,ActionListener {
private int timealive; //in ms, max value 2147483647 --->3.5 weeks
private Timer timer=new Timer(1000,this); // 1000ms = 1 second, but you
// can also set it to 30ms.
/**
* Create the panel.
*/
public InvaderPanel() {
addKeyListener(this);
setFocusable(true);
timer.start();
}
#Override
public void actionPerformed(ActionEvent e) {
if(playerdead){
timer.stop();
// here we can use timealive value
} else {
// timealive++; if you want to get the value in seconds
// in this case the timer delay must be 1000ms
timealive += timer.getDelay(); // if you want to get the value in milliseconds
}
}

How can I start/stop a stop watch with only the spacebar?

I want to start/stop a stop watch only using the spacebar. I already made the KeyListeners, and that they only get activated when you press/release the spacebar.
What I tried so far:
I tried creating a stopwatch class, which SHOULD calculate the time difference between me pressing space for the first time, and second time. I tried it as follows:
public class Stopwatch {
public Stopwatch(int i) {
long time = System.currentTimeMillis();
if(i%2==1){
System.out.println("Timer Started at: " + time);
}else{
System.out.println("Timer stopped at: " + System.currentTimeMillis());
System.out.println("Time diff: " + (time - System.currentTimeMillis()));
}
}
}
int i increases with every second spacebar press.
I know the problem here is that everytime I start this class, time is getting reset to System.currentTimeMillis() because I only press Spacebar. Thus the difference is always 0.
How can I change this so that I can somehow save the time I first pressed space?
Here is the class with the Keylisteners. Ignore the Scrambler class, it has nothing to do with my Problem.
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;
public class StoppuhrFrame extends JFrame {
JLabel time, scramble;
public StoppuhrFrame() {
time = new JLabel("00:00:00");
time.setBounds(162, 45, 325, 80);
time.setFont(new Font("Arial", 100, 80));
add(time);
scramble = new JLabel("Scramble: ");
scramble.setBounds(165, 15, 370, 16);
add(scramble);
//Scrambler scrambler = new Scrambler(scramble);
addKeyListener(new timer());
setTitle("Cube Timer");
setLayout(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setSize(650, 270);
setVisible(true);
}
int i = 1;
public class timer implements KeyListener {
#Override
public void keyPressed(KeyEvent keyEvent) {
if(keyEvent.getKeyCode()==32){
new Stopwatch(i);
i++;
}
#Override
public void keyReleased(KeyEvent arg0) {
if (arg0.getKeyCode() == 32) {
if(i%2==0){
//new Scrambler(scramble);
}
}
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
}
}
Thanks in advance.
Sorry, I tried to add it as a comment but didn't let me to post the code.
Here is the example class I mentioned:
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Example implements KeyListener {
private static long hitTime = -1;
#Override
public void keyPressed(KeyEvent arg0) {
// This will allways return the time when first space bar was clicked
long start = getHitTime();
long actualTime = System.currentTimeMillis();
// In this case get the seconds..
long diff = (actualTime - start) / 1000;
System.out.println(String.format("TIme diff: %s", diff));
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
public synchronized static long getHitTime() {
if (hitTime < 0) {
hitTime = System.currentTimeMillis();
}
return hitTime;
}
}
You also dont need a stopwatch class as time will start passing after first key click (in this case not specific key was detected so any key hit will trigger the event), and will calculate the difference of time between first click and the last one in millis, I divide it by a thousand to get seconds between hits.
Hope this helps
Make time a static attribute of the StopWatch user class initialized with a negative value (as i understand it may be the listener instance). Then apply a synchronized method to get the value of the time attribute (static syncrhonized to ensure thread-safe access to that var when updating it). and apply a singleton pattern nto update the value, considering that a value > 0 is possible when a space bar has been pressed:
private static long hitTime = -1;
//...
public synchronized static long getFirstSpaceHitMillis() {
if (hitTime < 0) {
// this if ensures the variable will be only updated at first hit
hitTime = System.currentTimeMillis();
}
return hitTime;
}
In the StopWatch class the init time will be retrieved by a static call to the getFirstSpaceHitMillis method, so you'll get the time when first space was hit.
Hope this help, and sorry for not attaching a full implementation.

How to make a 3 minutes countdown timer

I want to use the method javax.swing.Timer to create a timer that will start at 3:00, then go down to 0:00. I have no idea how to use this method and how to proceed. From now on, I have this code, but I have no idea if it is good. One thing sure is that it doesn't work.
private javax.swing.Timer timer = new javax.swing.Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
int minute = 3;
int seconde = 60;
do {
lblTimer.setText(Integer.toString(seconde));
seconde--;
} while (seconde != 0);
}
});
In this example, a TimerButton responds after the delay passed to the constructor, e.g.
new TimerButton("Back in three minutes", 3 * 60 * 1000));
Your StopListener would take the desired action when the Timer expires, e.g.
private class StopListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
timer.stop();
// further actions here
}
}
See How to Use Swing Timers for additional details.

Using timer to count as a stopwatch in Java Applet

I'm wanting to create a stopwatch so to speak in order to score my game. Lets say I have a variable: int sec = 0. When the game starts I want a g.drawString to draw the time to the applet. So for example each second, sec will increment by 1.
How do I go about making it g.drawString(Integer.toString(sec), 40, 400) increment by 1 and draw each second?
Thanks.
EDIT:
I've figured out how to increment it and print it to the screen by using ActionListener and putting g.drawString in there but it prints ontop of each other. If I put g.drawString into the paint method and only increment sec by 1 in the ActionListener there is a a flicker. Should I use Double Buffering? If so how do I go about doing this?
import java.awt.event.*;
import javax.swing.*;
public class StopWatch extends JLabel
implements MouseListener, ActionListener {
private long startTime; // Start time of stopwatch.
// (Time is measured in milliseconds.)
private boolean running; // True when the stopwatch is running.
private Timer timer; // A timer that will generate events
// while the stopwatch is running
public StopWatch() {
// Constructor.
super(" Click to start timer. ", JLabel.CENTER);
addMouseListener(this);
}
public void actionPerformed(ActionEvent evt) {
// This will be called when an event from the
// timer is received. It just sets the stopwatch
// to show the amount of time that it has been running.
// Time is rounded down to the nearest second.
long time = (System.currentTimeMillis() - startTime) / 1000;
setText("Running: " + time + " seconds");
}
public void mousePressed(MouseEvent evt) {
// React when user presses the mouse by
// starting or stopping the stopwatch. Also start
// or stop the timer.
if (running == false) {
// Record the time and start the stopwatch.
running = true;
startTime = evt.getWhen(); // Time when mouse was clicked.
setText("Running: 0 seconds");
if (timer == null) {
timer = new Timer(100,this);
timer.start();
}
else
timer.restart();
}
else {
// Stop the stopwatch. Compute the elapsed time since the
// stopwatch was started and display it.
timer.stop();
running = false;
long endTime = evt.getWhen();
double seconds = (endTime - startTime) / 1000.0;
setText("Time: " + seconds + " sec.");
}
}
public void mouseReleased(MouseEvent evt) { }
public void mouseClicked(MouseEvent evt) { }
public void mouseEntered(MouseEvent evt) { }
public void mouseExited(MouseEvent evt) { }
} // end StopWatchRunner
A small applet to test the component:
/*
A trivial applet that tests the StopWatchRunner component.
The applet just creates and shows a StopWatchRunner.
*/
import java.awt.*;
import javax.swing.*;
public class Test1 extends JApplet {
public void init() {
StopWatch watch = new StopWatch();
watch.setFont( new Font("SansSerif", Font.BOLD, 24) );
watch.setBackground(Color.white);
watch.setForeground( new Color(180,0,0) );
watch.setOpaque(true);
getContentPane().add(watch, BorderLayout.CENTER);
}
}

Categories