Hi!. I'm new to swing so I thought I would try something simple like a clock. So the idea is a javax.swing.Timer that periodically checks if the time has changed and, if so calls a paintTime in a JFrame that displays the new time. The problem is that it doesn't work. But if I add a button in the frame that calls paintTime when clicked it does work. Both when I click the button and when the timer calls it paintTime executes in the event dispatching thread. My code is this:
//ClockView.java public class ClockView { ... public void paintTime(Calendar cal) { //we just make a setText in a couple of JLables here } }
> Hi!. > I'm new to swing so I thought I would try something simple > like a clock. > So the idea is a javax.swing.Timer that periodically > checks if the time has changed and, if so calls a > paintTime in a JFrame that displays the new time. The > problem is that it doesn't work. But if I add a button in > the frame that calls paintTime when clicked it does work. > > Both when I click the button and when the timer calls it > paintTime executes in the event dispatching thread. > My code is this: > > > //ClockView.java > public class ClockView { > ... > public void paintTime(Calendar cal) > { > //we just make a setText in a couple of JLables here > } > } > > //Clock.java > import java.awt.event.*; > import javax.swing.Timer; > import java.util.Calendar; > > public class Clock implements ActionListener > { > private Timer myTimer; > private ClockView view; > private Calendar time; > private int previousMinutes,currentMinutes; > > Clock(ClockView view,int delay) > { > myTimer=new Timer(delay,this); > myTimer.setInitialDelay(0); > this.view=view; > } > > > public void actionPerformed(ActionEvent e) > { > System.out.println("actionPerformed!"); > time=Calendar.getInstance(); > currentMinutes=time.get(Calendar.MINUTE); > if (currentMinutes!=previousMinutes) > { > System.out.println("inside condition"); > previousMinutes=currentMinutes; > view.paintTime(time); > } > } > > public void start() > { > myTimer.start(); > } > > public void stop() > { > myTimer.stop(); > } > } > > > Any ideas? > Thanks a lot!
I assume you call your start method from your main. Short of that I don't see why it should not work...
publicstaticvoid main(String []args){
new Clock().start();
}
> Your action is fired off every 1 second, this is similar > to using a button that has an ActionListener that listens > to a click every one second.
Yeah, that's what I thought and why I asked :).
I read somewhere that any code that operates on swing objects has to be executed from the event-dispatching thread, but in both cases my code executes in it (checked).
I'm looking at your code and looking at older code I've written (Splash Screen) that made use of the swing Timer class.
You have:
myTimer=new Timer(delay,this);
I think in fact the Timer class is meant to generate a new Instance of the ActionListener being called.
e.g.
myTimer = new Timer(delay, new ActionListenerDeclared());
I may be wrong but that's the only difference I can see with your implementation and what drives my Splash Screen. Not to mention it makes sense from the stand point that its a new Action each time.
maybe try:
myTimer = new Timer(delay, new Clock());
This will probably work. As opposed to calling "this" takes in a new ActionListener.