user2640782
user2640782

Reputation: 1084

Couldn't refresh the JFrame

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

Answers (2)

user2640782
user2640782

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

Braj
Braj

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();

Note:

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

Related Questions