2013-08-23 4 views
0

Я делаю JLabel для отображения таймера, поэтому он обновляется каждую секунду, и я обновляю его с помощью потока. Я использую SwingWorker для обновления JLabel, но это не работает. Вот мой код ...setText jLabel не работает даже с SwingWorker

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 не обновляется, «в функции» отображается на обеих этикетках, и он не меняется. Просьба предложить альтернативный метод, если это возможно ...

+0

Try '' repaint'ing в JLabel' после установки текста. –

+0

Yikes .. ты усложнил ситуацию. Попробуйте [this] (http://stackoverflow.com/questions/6330945/how-to-display-changing-text-in-java-swing-ie-display-time-with-changing-secon/6331033#6331033). – mre

+0

, вы должны вызывать 'setText()' in 'done()', а не 'doInBackground()' im, не уверен, что вы получите обновление, потому что оно работает в другом потоке .. если вы хотите обеспечить 'SwingUtilities.invokeLater (new Runnable() {public void run() {label.setText ("123")}}); ' – nachokk

ответ

2

Может быть, вы можете использовать Timer, чтобы сделать это, но вам нужно запустить setText или любой свинг функции в Event dispatch thread.

Если вы хотите использовать SwingWorker, вам нужно вызвать функцию поворота в EDT. Вы можете попробовать что-то вроде этого:

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

Для этого вида работы, которую вы должны использовать Swing Timer. SwingWorker обычно используется для тяжелой задачи и не блокирует gui (Event Dispatch Thread), вызывающий запуск в разном потоке.

Не уверен, что если обновление вашего gui в doInBackground() будет отражено, как вы знаете, оно запускается в другом потоке. Для того, чтобы убедиться, что вы можете

1) Оберните ваш звонок в SwingUtilities.invokeLater(..)

2) Использование publish(..) и обновления здесь.

Но я рекомендую использовать для этой задачи Качели Таймер

Смежные вопросы