Java:setText()和线程

时间:2013-02-17 22:48:57

标签: java multithreading swing jlabel settext

我是java的初学者,不幸的是我遇到了这个问题。在代码中:

NewJFrame.java:

public class NewJFrame extends JFrame {

    public void showText() {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                jLabel1.setText("in show()"); //it does not work
                System.out.println("in show()"); //it works
            }
        });
    }

    public NewJFrame() {
        initComponents();
        jLabel1.setText("start"); //it works
    }

    public static void main(String args[]) {
        Timer timer = new Timer();
        timer.schedule(new NewClass(), 1000, 2000);

        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }
    private javax.swing.JLabel jLabel1;
}

NewClass.java:

package newpackage;

import java.util.TimerTask;

class NewClass extends TimerTask {

    public void run() {
        System.out.println("in NewClass.run()"); //it works
        new NewJFrame().showText();
    }
}

我遇到的问题是setText在从计时器线程调用时没有设置jLabel1。我试图使用invokeLater()解决问题,但仍然无法正常工作。 谢谢你的帮助。

3 个答案:

答案 0 :(得分:3)

您正在NewJFrame中创建一个永远不会显示的NewClass新实例:

new NewJFrame().showText();

您需要将可见实例传递给NewClass才能进行更新。

但是,最好使用javax.swing.Timer而不是java.util.Timer与Swing组件进行交互。来自How to Use Swing Timers

  

通常,我们建议使用Swing计时器而不是通用计时器来处理与GUI相关的任务,因为Swing计时器都共享相同的预先存在的计时器线程,并且GUI相关任务会在事件派发线程上自动执行。

另见:Concurrency in Swing

答案 1 :(得分:3)

JLabel永远不会添加到任何容器中。为什么会出现?

作为一般建议,不要扩展框架,只需保留一个引用,如@Reimeus所提到的,使用Swing Timer

答案 2 :(得分:0)

尝试在设置文本后立即添加repaint()

在屏幕上更改某些内容后,您必须始终重新绘制该框架。

jLabel1.setText("in show()");    //it does not work
repaint();                       //now it works
System.out.println("in show()"); //it works