Не удалось обновить JFrame

У меня простой JFrame который содержит JButton и 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;
}

И у меня есть простой класс, который получает label объект за конструктором, и устанавливает некоторые значения для метки с count() метод.

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;
}

Проблема в том, что я хочу видеть цифры, когда count() метод вызывает label"s setText() метод. Но кадр не обновляется. В конце я вижу только номер 10, Я не вижу других номеров.

Я использовал таймер, но это не помогает. Я неправильно использую таймер? Есть ли другое решение? Я думал о multithreading но я не мог заставить это работать. Если кто-нибудь может помочь мне с этой проблемой, я буду благодарен.

ПРИМЕЧАНИЕ: я упростил мою проблему с этим примером, поэтому решения, которые содержат изменение параметров конструктора или что-то подобное, не предоставят мне решение.

2 ответа

Решение

Повторите таймер с помощью метода setRepeat (true) и прервите цикл после повторения 10 раз с помощью вызова. stop() метод внутри actionPerformed() метод.

Образец кода:

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

Замечания:

Не использовать Thread.sleep() что когда-нибудь зависает все приложение Swing, вместо этого попробуйте использовать Swing Timer, который наиболее подходит для приложения Swing.

Читать дальше Как использовать Swing Timers

Я нашел другое решение, возможно, этот ответ поможет другим людям.

я использую Thread вместо Timer,

Поменял метод jButton1MouseClicked() с этим.

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

Немного измени метод count для закрытия потока.

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

С этими изменениями я могу видеть подсчет от label, И вам не нужно звонить label.setText(i + ""); из Timer,

Другие вопросы по тегам