simple stuff in swing

D

defcon8

Hello, I have just started learning swing and I have tried to make a
small programme that shows a number that goes up by 1 every increment,
I am trying to figure out how I can make it sleep and so on. Could
anyone correct my code?

import javax.swing.JFrame;
import javax.swing.JLabel;

public class Grapho {
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setSize(400,400);
JLabel label = new JLabel();
int i = 0;
while(i != 10) {
label.setText(Integer.toString(i));
Thread.sleep(1);
frame.getContentPane().add(label);
frame.setvisible(true);
i++;
}
}
}
 
L

Leon

Demetz Markus said:
hi,

you can extend Thread and do the stuff in the run method!

You can also implement the Runnable interface, to save the extend for something
else.

class ClassX implements Runnable {

public void run() {
// some code ..
}
}

// now you can do the following:
Thread thread = new Thread( new ClassX() );
thread.start(); // will execute the run method.
 
Z

zero

Hello, I have just started learning swing and I have tried to make a
small programme that shows a number that goes up by 1 every increment,
I am trying to figure out how I can make it sleep and so on. Could
anyone correct my code?

import javax.swing.JFrame;
import javax.swing.JLabel;

public class Grapho {
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setSize(400,400);
JLabel label = new JLabel();
int i = 0;
while(i != 10) {
label.setText(Integer.toString(i));
Thread.sleep(1);
frame.getContentPane().add(label);
frame.setvisible(true);
i++;
}
}
}

Thread.sleep takes an argument in miliseconds. Try using a value of 1000:

Thread.sleep(1000);

That will make your thread sleep for 1 second.

Normally if you're mixing threads with Swing, you should use
SwingUtilities.invokeLater. For something as simple as this it doesn't
really matter, but for future reference you should look into it.

Also, you should take the frame.getContentPane().add(label) and
frame.setVisible(true); (note the capital V!) out of the while loop. Once
the label has been added and the frame displayed, you don't need to do it
again every time.
 
T

Thomas Hawtin

defcon8 said:
Hello, I have just started learning swing and I have tried to make a
small programme that shows a number that goes up by 1 every increment,
I am trying to figure out how I can make it sleep and so on. Could
anyone correct my code?

import javax.swing.JFrame;
import javax.swing.JLabel;

public class Grapho {
public static void main(String[] args)
{
JFrame frame = new JFrame();

First off, you shouldn't setVisible from the outside of the AWT Event
Dispatch Thread, as Swing is not thread-safe. You could get away with
that prior to 1.5, but it appears that these days the JVM is better
optimised and shows up thread bugs more often. It's better to create all
the components on the EDT. You can do this from main, with code like:

java.awt.EventQueue.invokeLater(new Runnable() { public void run() {
... your code here ...
}
});

All this is doing is making sure your code is working in a single
threaded environment.
frame.setSize(400,400);
JLabel label = new JLabel();
int i = 0;
while(i != 10) {
label.setText(Integer.toString(i));
Thread.sleep(1);

The time is specified in milliseconds. One millisecond is quite short.
To make it more explicit, from 1.5, you can write:

java.util.concurrent.TimeUnit.SECONDS.sleep(1);

You shouldn't sleep on the EDT, as it will prevent repaints.
frame.getContentPane().add(label);
frame.setvisible(true);

No need keep adding the label or making the frame visible.
i++;
}
}
}

Now, how to solve the problem. No need to get involved with threads
yourself. Use javax.swing.Timer (not java.util.Timer!), to execute an
action that updates the label, every 1000 milliseconds. The delay will
have to be milliseconds this time, although you can store the value in a
variable whose name ends in Millis or _MILLIS.

Tom Hawtin
 
D

defcon8

I finally solved it in the end. And here it is:

import javax.swing.*;
import java.util.Timer;
import java.util.TimerTask;

public class Grapho {

static JFrame frame;
static int i = 0;
static int j = 0;
static int o;
static Timer timer;
static JLabel label;

public static void Reminder(int seconds) {
while(i < 31) {
o = i;
j = 0;
label.setText(Integer.toString(i));
timer.schedule(new RemindTask(), seconds*1000);
while(j != 1) {
if(o + 1 == i) {
j++;
}
}

}
label.setText("I have finished");
}
static class RemindTask extends TimerTask {
public void run() {
i++;
}
}
public static void main(String[] args)
{
label = new JLabel();
timer = new Timer();
frame = new JFrame();
frame.setSize(500,500);
frame.getContentPane().add(label);
frame.setVisible(true);
Reminder(1);

}

}
 
R

Roedy Green

Now, how to solve the problem. No need to get involved with threads
yourself. Use javax.swing.Timer (not java.util.Timer!), to execute an
action that updates the label, every 1000 milliseconds. The delay will
have to be milliseconds this time, although you can store the value in a
variable whose name ends in Millis or _MILLIS.

for more details, see http://mindprod.com/jgloss/timer.html
 
Z

zero

I finally solved it in the end. And here it is:

import javax.swing.*;
import java.util.Timer;
import java.util.TimerTask;

public class Grapho {

static JFrame frame;
static int i = 0;
static int j = 0;
static int o;
static Timer timer;
static JLabel label;

public static void Reminder(int seconds) {
while(i < 31) {
o = i;
j = 0;
label.setText(Integer.toString(i));
timer.schedule(new RemindTask(), seconds*1000);

Have a look at the overloaded schedule methods in Timer. You don't need
to re-schedule it every time, you can tell the Timer to repeat every n
miliseconds after a specific time or delay.
while(j != 1) {
if(o + 1 == i) {
j++;
}
}

What does this while loop do? Seems like you're making this way more
complicated than it should be.
}
label.setText("I have finished");
}
static class RemindTask extends TimerTask {
public void run() {
i++;
}
}
public static void main(String[] args)
{
label = new JLabel();
timer = new Timer();
frame = new JFrame();
frame.setSize(500,500);
frame.getContentPane().add(label);
frame.setVisible(true);
Reminder(1);

}

}
 
D

defcon8

While I was gone i realised i only need this loop:

public static void Reminder(int seconds) {
while(i < 31) {
label.setText(Integer.toString(i));
o = i;
timer.schedule(new RemindTask(), seconds*1000);
while(o == i) {}
}

}
}

I couldn't actually figure out how to implement Thread's sleep method
into this programme. Maybe someone could help...
 
R

Roedy Green

I couldn't actually figure out how to implement Thread's sleep method
into this programme. Maybe someone could help...

The basic technique is this. You set up your timer then return in the
main method. Or in an event handler you set up your timer and return.
The timer then does its thing all on its own. It wakes up your code
periodically which does something then exits. You don't need a
babysitting task to worry. The Timer does that.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top