How can I reset the text of button every second?

J

jtl.zheng

I want to set the button's text every second
as: 1 -> 2 -> 3 -> 4 .........
my code is:
------------------------------------
public class Ooop {
public static void doIt() {
JFrame jFrame = new JFrame();
JButton jButton = new JButton("xxx");
jFrame.add(jButton);
jFrame.pack();
jFrame.setVisible(true);

int i=0;
while(true){
try {
Thread.sleep(1000);
}
catch (InterruptedException ex) {
}
jButton.setText(String.valueOf(i++));
}
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
doIt();
}
});
}
}
-------------------------------

I use Thread.sleep() to do it
but it can not work....
It show nothing all the time
just a blank frame, not button at all
why? is it about the Thread the UI using?
how can I reset the text fo button every second?

Thank you very much in advance.
 
J

jtl.zheng

Thank you very much
it work out now
:

timer = new java.util.Timer(true);
timer.schedule(
new java.util.TimerTask() {
public void run() {
jButton.setText(String.valueOf(i++));
if (i > 5) {
timer.cancel();
}
}
}, 0, 1000);
 
M

Matt Humphrey

jtl.zheng said:
I want to set the button's text every second
as: 1 -> 2 -> 3 -> 4 .........
my code is:
------------------------------------
public class Ooop {
public static void doIt() {
JFrame jFrame = new JFrame();
JButton jButton = new JButton("xxx");
jFrame.add(jButton);
jFrame.pack();
jFrame.setVisible(true);

int i=0;
while(true){
try {
Thread.sleep(1000);
}
catch (InterruptedException ex) {
}
jButton.setText(String.valueOf(i++));
}
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
doIt();
}
});
}
}
-------------------------------

I use Thread.sleep() to do it
but it can not work....
It show nothing all the time
just a blank frame, not button at all
why? is it about the Thread the UI using?

Yes, exactly. Your counter has taken over the event dispatch thread which
now cannot update the screen. The Timer class will run the counting and
waiting in a separate thread so that only the actual button update takes
place in the EDT (which is necessary).

Matt Humphrey (e-mail address removed) http://www.iviz.com/
 
T

Thomas Hawtin

jtl.zheng said:
Thank you very much
it work out now
:

timer = new java.util.Timer(true);

It might work, but it's not good. Threads and Swing don't mix. It might
work now, but then you might later (perhaps on a custom machine) can a
problem which does not appear to be related to this code.

java.util.Timer will create its own thread and execute code there. You
need to be on the normal "AWT Event Dispatch Thread" (EDT). So use
javax.swing.Timer instead, which calls java.awt.EventQueue.invokeLater
under the covers.

Tom Hawtin
 
J

jtl.zheng

Thank you very much for your help

I know a little now
what I guess is:
all the swing components have only one single thread to repaint
themselves
and it repaint themselves all the time
so if I call the Thread.sleep(500); inside this swing thread as I did
it stop the thread and also stop the repainting,
so it show nothing but a blank frame(not buttons)
is it right?

so if I want to reset the text of button every second
I must call another thread outside this swing thread
or use javax.swing.Timer as you said
is it right?

Thank you very much in advance
 
R

Rogan Dawes

jtl.zheng said:
Thank you very much for your help

I know a little now
what I guess is:
all the swing components have only one single thread to repaint
themselves
and it repaint themselves all the time
so if I call the Thread.sleep(500); inside this swing thread as I did
it stop the thread and also stop the repainting,
so it show nothing but a blank frame(not buttons)
is it right?

so if I want to reset the text of button every second
I must call another thread outside this swing thread
or use javax.swing.Timer as you said
is it right?

Thank you very much in advance

No, in fact you want to make sure that the code that updates the UI is
actually executing on the EDT (Event Dispatching Thread).

So, it makes a big difference whether you use java.util.Timer, or
javax.swing.Timer

java.util.Timer will execute your task on an internal thread created by
the Timer, while javax.swing.Timer will make sure that your task is
executed on the EDT.

Regards,

Rogan
 
M

Matt Humphrey

Rogan Dawes said:
No, in fact you want to make sure that the code that updates the UI is
actually executing on the EDT (Event Dispatching Thread).

So, it makes a big difference whether you use java.util.Timer, or
javax.swing.Timer

java.util.Timer will execute your task on an internal thread created by
the Timer, while javax.swing.Timer will make sure that your task is
executed on the EDT.

Rogan is quite right, but to continue to underscore the key point here (at
the risk of beating a dead horse) the *waiting* must *not* happen in the
EDT. The *updating* must happen on the EDT. javax.swing.Timer does both
for you.

The code you're looking for is something like this:

int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jButton.setText(String.valueOf(i++));
}
};

Timer aTimer = new Timer(delay, taskPerformer);
aTimer.start ();

Matt Humphrey (e-mail address removed) http://www.iviz.com/
 
J

jtl.zheng

No, in fact you want to make sure that the code that updates the UI is
actually executing on the EDT (Event Dispatching Thread).

So there are only one EDT thread at all
and any event handling or painting are all executed in this single EDT
if I call the Thread.sleep() inside EDT ,it also stop the painting,so
it just display a blank frame
and the swing.Timer also invoke the codes inside this EDT,so it's safe
to change the components
is it right?
 
M

Matt Humphrey

jtl.zheng said:
So there are only one EDT thread at all
and any event handling or painting are all executed in this single EDT
if I call the Thread.sleep() inside EDT ,it also stop the painting,so
it just display a blank frame
and the swing.Timer also invoke the codes inside this EDT,so it's safe
to change the components
is it right?

I think you're getting the idea now. The swing Timer has a separate thread
on which it does the waiting, but when it wakes up, it uses the
SwingUtilities.invokeLater to send the action to the EDT thread for
execution.

Matt Humphrey (e-mail address removed) http://www.iviz.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top