Java jLabel';s setText即使与SwingWorker也不起作用

Java jLabel';s setText即使与SwingWorker也不起作用,java,swing,swingworker,Java,Swing,Swingworker,我正在使一个JLabel显示一个计时器,因此它每秒钟都会更新一次,我正在使用一个线程来更新它。我正在使用SwingWorker更新JLabel,但它不起作用。 这是我的密码 long pos=-1; private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { try { pos=...value o

我正在使一个JLabel显示一个计时器,因此它每秒钟都会更新一次,我正在使用一个线程来更新它。我正在使用SwingWorker更新JLabel,但它不起作用。 这是我的密码

long pos=-1;
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         

     try
    {
        pos=...value of timer....
        jLabel1.setText("in function");
        jLabel3.setText("in function");
        timer=new Thread(new adsa());
        timer.start();

    }
    catch(Exception e)
    {    
        System.out.println("EXCEPTION CAUGHT");
    }
}                                        

/**
 *
 */
public void run()
{

    try
    {

        System.out.println(pos);

    while(pos!=0 && clip.isRunning())
    {
        label1.setText(String.valueOf(pos));
        System.out.println(pos);
        pos--;
        timer.sleep(1000);

        SwingWorker worker = new SwingWorker() {

            @Override
            public Object doInBackground(){

                try
                {
                jLabel3.setText(String.valueOf(pos));
                jLabel3.setText("ghfdxhc");
                label1.setText("hvgjh");
                System.out.println("zxc");

                return null;
                }
                catch(Exception e)
                {
                    return null;
                }

            }
        };
        worker.execute();
      }

    }
    catch(Exception e)
    {
        System.out.println("Error in run");
    }
}
所有println语句都在工作,即使是SwingWorker内部的语句,但jLabel没有更新,“in function”显示在两个标签上,并且没有更改。
如果可能,请建议另一种方法…

也许您可以使用
计时器来执行此操作,但您需要运行
setText
事件调度线程中的任何swing函数

如果您想使用SwingWorker,您需要在EDT中调用swing函数。 您可以尝试以下方法:

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
            pos=...value of timer....
            jLabel1.setText("in function");
            jLabel3.setText("in function");
            Ctimer timer = new CTimer(pos, jLabel1, jLabel2, jLabel3);
            timer.execute();

    } 

    class CTimer extends SwingWorker<Void, Long> {

      private long pos;
      private JLabel jLabel1, jLabel2, jLabel3;

      public CTimer(long pos, JLabel jLabel1, JLabel jLabel2, JLabel jLabel3) {
        this.pos = pos;
        this.jLabel1 = jLabel1;
        this.jLabel2 = jLabel2;
        this.jLabel3 = jLabel3;
      }

      @Override
      protected Void doInBackground() throws Exception {
        while (pos != 0 && clip.isRunning()) {
          publish(pos);
          pos--;
          Thread.sleep(1000);
        }
      }

      @Override
      protected void process(List<Long> times) {
        for (Long time : times) {
          jLabel1.setText("xyz");
          jLabel2.setText("ababa");
          jLabel3.setText("" + time);
        }
      }
    }
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt){
pos=…计时器的值。。。。
jLabel1.setText(“函数中”);
jLabel3.setText(“函数中”);
Ctimer定时器=新Ctimer(位置、jLabel1、jLabel2、jLabel3);
timer.execute();
} 
类CTimer扩展SwingWorker{
私人长pos;
专用JLabel jLabel1、jLabel2、jLabel3;
公共CTimer(长位置、JLabel jLabel1、JLabel jLabel2、JLabel jLabel3){
this.pos=pos;
this.jLabel1=jLabel1;
this.jLabel2=jLabel2;
this.jLabel3=jLabel3;
}
@凌驾
受保护的Void doInBackground()引发异常{
while(pos!=0&&clip.isRunning()){
发布(pos);
pos--;
睡眠(1000);
}
}
@凌驾
受保护的无效进程(列表次数){
用于(长时间:次){
jLabel1.setText(“xyz”);
jLabel2.setText(“亚的斯亚贝巴”);
jLabel3.setText(“+”时间);
}
}
}

也许您可以使用
计时器来执行此操作,但您需要运行
setText
事件调度线程中的任何swing函数

如果您想使用SwingWorker,您需要在EDT中调用swing函数。 您可以尝试以下方法:

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
            pos=...value of timer....
            jLabel1.setText("in function");
            jLabel3.setText("in function");
            Ctimer timer = new CTimer(pos, jLabel1, jLabel2, jLabel3);
            timer.execute();

    } 

    class CTimer extends SwingWorker<Void, Long> {

      private long pos;
      private JLabel jLabel1, jLabel2, jLabel3;

      public CTimer(long pos, JLabel jLabel1, JLabel jLabel2, JLabel jLabel3) {
        this.pos = pos;
        this.jLabel1 = jLabel1;
        this.jLabel2 = jLabel2;
        this.jLabel3 = jLabel3;
      }

      @Override
      protected Void doInBackground() throws Exception {
        while (pos != 0 && clip.isRunning()) {
          publish(pos);
          pos--;
          Thread.sleep(1000);
        }
      }

      @Override
      protected void process(List<Long> times) {
        for (Long time : times) {
          jLabel1.setText("xyz");
          jLabel2.setText("ababa");
          jLabel3.setText("" + time);
        }
      }
    }
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt){
pos=…计时器的值。。。。
jLabel1.setText(“函数中”);
jLabel3.setText(“函数中”);
Ctimer定时器=新Ctimer(位置、jLabel1、jLabel2、jLabel3);
timer.execute();
} 
类CTimer扩展SwingWorker{
私人长pos;
专用JLabel jLabel1、jLabel2、jLabel3;
公共CTimer(长位置、JLabel jLabel1、JLabel jLabel2、JLabel jLabel3){
this.pos=pos;
this.jLabel1=jLabel1;
this.jLabel2=jLabel2;
this.jLabel3=jLabel3;
}
@凌驾
受保护的Void doInBackground()引发异常{
while(pos!=0&&clip.isRunning()){
发布(pos);
pos--;
睡眠(1000);
}
}
@凌驾
受保护的无效进程(列表次数){
用于(长时间:次){
jLabel1.setText(“xyz”);
jLabel2.setText(“亚的斯亚贝巴”);
jLabel3.setText(“+”时间);
}
}
}

对于此类工作,您应该使用。SwingWorker通常用于繁重的任务,并且不会阻塞gui(),因为它在不同的线程中运行

我不确定在
doInBackground()
中更新gui是否会反映出来,正如您所知,它是在另一个线程中运行的。确保你能

1) 在
SwingUtilities.invokeLater(..)中包装调用

2) 使用
发布(…)
并在此处更新


但是我建议您在执行此任务时使用Swing Timer(摆动计时器)。对于此类工作,您应该使用。SwingWorker通常用于繁重的任务,并且不会阻塞gui(),因为它在不同的线程中运行

我不确定在
doInBackground()
中更新gui是否会反映出来,正如您所知,它是在另一个线程中运行的。确保你能

1) 在
SwingUtilities.invokeLater(..)中包装调用

2) 使用
发布(…)
并在此处更新


但是我建议在设置文本后,使用Swing Timer来执行此任务。。试试看。你应该在
done()
中调用
setText()
,而不是在
doInBackground()
中调用
。。如果要确保
SwingUtilities.invokeLater(new Runnable(){public void run(){label.setText(“123”)})Josh M-repaint不起作用…mre-我必须在线程中使用JLabel,因为计时器必须工作很长时间,如果我使用按钮侦听器以正常方式使用它,则按钮将保持按下状态,直到JLabel脱离循环设置文本后尝试
repaint
重新绘制
ing
JLabel
。哎呀..你让事情变得复杂了。试试看。你应该在
done()
中调用
setText()
,而不是在
doInBackground()
中调用
。。如果要确保
SwingUtilities.invokeLater(new Runnable(){public void run(){label.setText(“123”)})Josh M-repaint不起作用…mre-I必须在线程中使用JLabel,因为计时器必须工作很长时间,如果我以正常方式使用按钮侦听器,按钮将保持按下状态,直到JLabel退出其循环