3 Replies - 11175 Views - Last Post: 16 June 2010 - 01:49 PM Rate Topic: -----

#1 TMeZ  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 15-June 10

Need help with Timer using action listener

Posted 15 June 2010 - 10:27 PM

I've set up an interface with 1 label and 2 buttons. I set label to invisible for the timer number to run in it. As for buttons, I have a start and stop button and I need to implement the action listener to it. Can you take a look at the codes and tell me what I did wrong or need to implement. Oh ya, I need to implement these using smth called "Threading".

 import java.awt.BorderLayout;
import java.awt.event.*;

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

public class TimerDemo {
	JLabel number = new JLabel();
	JPanel panel1 = new JPanel();
	JButton start = new JButton("Start");
	JButton stop = new JButton("Stop");
	JPanel panel2 = new JPanel();

	public TimerDemo() {
		JFrame frame = new JFrame();
		frame.setBounds(300,50,200,150);
		frame.setLayout(new BorderLayout());
		
		start.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
			Timer timer1 = new Timer(1000, this);
				timer1.start();
				//timer1.setText(number)
				
			}
		});
			
		
		panel1.add(number);
		panel2.add(start);
		panel2.add(stop);
		
		frame.add(panel1,BorderLayout.NORTH);
		frame.add(panel2,BorderLayout.SOUTH);
		
		
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);
		
	}
	
	public static void main(String[] args) throws InterruptedException{

		new TimerDemo();
	}
	
} 

This post has been edited by TMeZ: 15 June 2010 - 11:21 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Need help with Timer using action listener

#2 bcranger  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 252
  • View blog
  • Posts: 1,199
  • Joined: 01-February 10

Re: Need help with Timer using action listener

Posted 16 June 2010 - 03:07 AM

*
POPULAR

First, Java Swing and Threads are NOT NOT NOT safe. You should instead you a Swing Timer with Swing GUI. And you have a timer already, you don't need to be threading.

I did what you did earlier today...Don't create an instance of Timer inside the ActionPerformed method as everytime it is called, a new Timer object will be created and the old one will not be destroyed.

Your problem is that you have not set any action commands for your buttons so clicking them will do nothing. You must use the setActionCommand() method to specify a String that you will extract from the ActionEvent in the ActionPerformed method. Also, you do not have an action listener added to your stop button.

You also need to import from java.awt.*; I don't know the exact class, but your two awt imports will not cover setting action commands.

// this is the general formula for setting an action command; not all components, such as JPanels, have a setActionCommand

// component               the String to be passed onto as the Action Command
component.setActionCommand(String text);



start.setActionCommand("Start");
start.addActionListener(this);
stop.setActionCommand("Stop");
start.addActionListener(this);



For your action performed method, you should have something along the following:

Keep in mind, this is a separate method outside of the constructor, just like your main method.

public void actionPerformed(ActionEvent e)
{
  // this is not mandatory, but good convention as you don't want to keep typing "e.getActionCommand()"
  String actionCommand = e.getActionCommand();

  if(actionCommand.equals("whatever you set your component's action command as"))
  {....}
  if(...)
  {}
  ......
}



YOU: "I set label to invisible for the timer number to run in it."

Next, you should probably not use Swing Timer to keep track of time as an invisible stopwatch does since your watch time is not visible. If it were visible, it would be a good idea, but in this case, your timer is invisible. Swing Timer is primarily for reasons that need constant updating periodically such as games, where animation occurs through a paint method refreshed very quickly.

Since you used Swing Timer, I will show you how to use Swing Timer to successfully make it an "invisible stopwatch" but I'll also show you the more efficient and preferred way.

When using Swing Timer, you must specify a delay, that is, the increments/intervals at which it fires an action event.
For your timer purposes, I'll use 10 as the delay, which means 10 miliseconds. That gives you down to a hundreth of a second. Feel free to make changes but for a stopwatch not used for the Olympics, I daresay you need such precision ;)

IMPORTANT: KEEP the component action listener method and timer action listener methods separate!

This would be your Timer declaration:

// delay, action listener name
Timer timer;

// comes after putting in your action listener method
timer = new Timer(10,timerListener);



This would be your basic action listener for your timer:

ActionListener timerListener = new ActionListener() { 
public void actionPerformed(ActionEvent evt) { 
  // whatever you want timer to do...
}
}; //note semicolon b/c it is declaration




This would be your action listener method for your components (in your case, the start and stop buttons)

        public void actionPerformed(ActionEvent e)
        {
          String actionCommand = e.getActionCommand();
          
          if("Start".equals(actionCommand))
          {
            timer.start();
          }
          if("Stop".equals(actionCommand))
          {
            timer.stop();
          }
        }



Alright, now for using your timer to act as a stopwatch...

You should declare your JLabel as such, starting it at 0.00

JLabel number = new JLabel("0.00");



Now, you should use your timer to update your jLabel every .01 of a second

ActionListener timerListener = new ActionListener() { 
        public void actionPerformed(ActionEvent evt) { 
                           // convert previous JLabel string to double, add .01, set that as new String/time
            number.setText(Double.parseDouble(number.getText()) + .01 + "");
        } 
                };



Now, you should also keep in mind, that according to your preferred design, the timer should NOT be visible.
So in your constructor, set "number" to false (not visible). In your action listener, when the stop button is pressed,
you should make the label visible then. However, I'd tell you to just let the label be visible the entire time...personal opinion, but I'll follow your style at the moment.

Alright, so when you click start, your timer should start, and when you click stop, your timer should stop. Your time variable should track accordingly.

One thing you should keep in mind, for appearance sake, is roundoff error. This happens since you're using a double value. For your purposes, your rounding can be simple. It's a wrong method technically, but it works for a watch purpose. Just truncate the digits after the hundreth place (that is, simply make the label of form m:ss). Well, since it's 5 AM...I'll leave the rounding part to you =p

Now, if you want, as you posted, an invisible timer, a simpler and more efficient way of handling this would be to use use the currentTimeMillis() method of java.lang.system. The method returns the current time in a long value. When the start button is pressed, store the current time in a long variable. When the stop button is pressed, call the method again. Subtract the differences...ta-da! There's your time elapsed between start and stop. All you have to do is convert the milliseconds to whatever time format you want (min, sec, hr, etc) and set the JLabel text as the time and then set visible =)

long startTime = currentTimeMillis();
long stopTime = currentTimeMillis();
long length = stopTime - startTime;



As always, for asthetic purposes...truncate some digits.

Here's the your modified code using Swing Timer if you want it: I made the label visible from start so it is more like a stopwatch.

import java.awt.BorderLayout; 
import java.awt.event.*; 
import java.awt.*;
 
import javax.swing.Timer; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
 
public class TimerDemo extends JFrame implements ActionListener{ 
        JLabel number = new JLabel("0.00"); 
        JPanel panel1 = new JPanel(); 
        JButton start = new JButton("Start"); 
        JButton stop = new JButton("Stop"); 
        JPanel panel2 = new JPanel(); 
        
        Timer timer;
 
        public TimerDemo() { 
                JFrame frame = new JFrame(); 
                frame.setBounds(300,50,200,150); 
                frame.setLayout(new BorderLayout()); 
                 
                start.setActionCommand("Start");
                start.addActionListener(this);
                stop.setActionCommand("Stop");
                stop.addActionListener(this);
                                   
                panel1.add(number); 
                panel2.add(start); 
                panel2.add(stop); 
                
                frame.add(panel1,BorderLayout.NORTH); 
                frame.add(panel2,BorderLayout.SOUTH); 
                 
                 
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
                frame.setVisible(true); 
                
                ActionListener timerListener = new ActionListener() { 
        public void actionPerformed(ActionEvent evt) { 
            number.setText(Double.parseDouble(number.getText()) + .01 + "");
        } 
                };
                
                timer = new Timer(10,timerListener);
                 
        } 
         
        public void actionPerformed(ActionEvent e)
        {
          String actionCommand = e.getActionCommand();
          
          if("Start".equals(actionCommand))
          {
            timer.start();
          }
          if("Stop".equals(actionCommand))
          {
            timer.stop();
            number.setVisible(true);
          }
        }
        
        public static void main(String[] args){ 
                new TimerDemo(); 
        } 
         
} 





WHEW LONGEST POST I HAVE EVER WRITTEN LOL

Bored at 5 a.m. gets you this nice little "guide" ;)

This post has been edited by bcranger: 16 June 2010 - 03:13 AM

Was This Post Helpful? 5
  • +
  • -

#3 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 10566
  • View blog
  • Posts: 39,107
  • Joined: 27-December 08

Re: Need help with Timer using action listener

Posted 16 June 2010 - 11:52 AM

@bcranger: I think you're in the wrong section with that post. That looks like a tutorial to me. :) Good show.
Was This Post Helpful? 0
  • +
  • -

#4 Luckless  Icon User is offline

  • </luck>
  • member icon

Reputation: 292
  • View blog
  • Posts: 1,146
  • Joined: 31-August 09

Re: Need help with Timer using action listener

Posted 16 June 2010 - 01:49 PM

Not much else to say, eh? For your sake though, you don't have to use anything but the generic ActionPistener if your program doesn't need to. You would simply set the timer up to be
Timer time = new Timer(10, this);


and it would go to the default ActionPerformed method
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1