Reputation: 1084
I have a simple JFrame
which contains a JButton
and a JLabel
.
public class Frame extends JFrame {
public Frame() {
initComponents();
this.frameExample = new JFrameExample(jLabel1,jPanel1);
}
@SuppressWarnings("unchecked")
private void initComponents() {
//this method only place the button and the label to the frame, it is auto-genereted by Netbeans tool.
}
private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {
frameExample.count();
}
public static void main(String args[]) {
new Frame().setVisible(true);
}
JFrameExample frameExample;
private javax.swing.JButton jButton1;
private javax.swing.JLabel jLabel1;
private javax.swing.JPanel jPanel1;
}
And I have a simple class that gets the label
object by constructor, and sets some values to the label with count()
method.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class JFrameExample {
public JFrameExample(JLabel label, JPanel panel) {
this.label = label;
this.panel = panel;
setFrameRefreshTimer();
}
public void setFrameRefreshTimer() {
frameTimer = new Timer (100,new ActionListener() {
public void actionPerformed(ActionEvent e) {
label.revalidate();
label.repaint();
panel.revalidate();
panel.repaint();
System.out.println(label.getText());//doesn't print anything
}
});
}
public void count() {
frameTimer.start();
for (int i = 0; i <= 10; i++) {
label.setText(i + "");
try {
Thread.sleep(500);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
frameTimer.stop();
}
private JLabel label;
private JPanel panel;
private Timer frameTimer;
}
The problem is, I want to see the numbers when the count()
method calls the label
's setText()
method. But the frame doesn't refresh. At the end I only see the number 10
. I don't see the other numbers.
I used a timer, but it doesn't help. Am I using the timer wrong? Is there any other solution? I thought about multithreading
but I couldn't make it work. If anyone could help me with this problem, I will be grateful.
NOTE: I simplify my problem with this example, so the solutions which contains changing the constructor parameters or something like this won't provide me a solution.
Upvotes: 1
Views: 419
Reputation: 1084
I found another solution, maybe this answer will help other people.
I use Thread
instead of Timer
.
Changed the method jButton1MouseClicked()
with this.
private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {
thread = new Thread() {
public void run() {
frameExample.count(thread); //sent the thread to close it.
}
};
thread.start();
}
Change a little bit the method count
for closing the thread.
public void count(Thread thread) {
for (int i = 0; i <= 10; i++) {
label.setText(i + "");
try {
Thread.sleep(500);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
thread.stop();
}
With these changes I am able to see the counting from the label
. And you don't need to call label.setText(i + "");
from a Timer
.
Upvotes: 0
Reputation: 46841
Repeat the timer using setRepeat(true) method and break the loop after repeating 10 times via calling stop()
method inside the actionPerformed()
method.
Sample code:
private int counter = 0;
private Timer timer;
...
timer = new javax.swing.Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
counter++;
if(counter==10){
timer.stop();
}else{
label.setText(counter + "");
}
}
});
timer.setRepeats(true);
timer.start();
Don't use Thread.sleep()
that sometime hangs the whole swing application instead try with Swing Timer that is most suitable for swing application.
Read more How to Use Swing Timers
Upvotes: 2