2010-07-04 4 views
2

Я не могу обновить свой прогрессбар ... это мой кодUpdate JProgressBar

Thread t=new Thread(new Runnable(){ 
     public void run(){ 
      int i=1; 
      jProgBar.setMinimum(0); 
      jProgBar.setMaximum(100); 
      try { 
       while(i<=100 || true){ 
        jProgBar.setValue(i); 
        i++; 
        Thread.sleep(50); 
       } 
      } 
      catch (InterruptedException ex){ 
       jProgBar.setValue(jProgBar.getMaximum()); 
      } 
     } 
    }); 
    t.start(); 

    .... Something code that correctly works 

    t.interrupt(); 

состояние прогресс бар обновляется только в конце нити. Может кто-нибудь мне помочь?

ответ

1

Спасибо всем. Я решил таким образом

try{ 
     jProgBar.setIndeterminate(true); 
     jProgBar.setStringPainted(true); 
     jProgBar.setBorderPainted(true); 
     new Thread(new Runnable() { 
      public void run() { 
       ... 
       // here is code that i've to wait 
       // after this i stop my jProgressBar 
       ... 
       jProgBar.setStringPainted(false); 
       jProgBar.setBorderPainted(true); 
       jProgBar.setIndeterminate(false); 
     } 
     }).start(); 
    } 
    catch(IllegalStateException ex){ 
     //some code 
    } 
4

Перед сном добавьте вызов SwingUtilties.invokeLater(), который порождает поток, чтобы запустить firePropertyChange на панели прогресса в EDT.

+0

Да, это в соответствии с принципом, что любые изменения в состоянии компонентов должны быть сделаны из событий диспетчерского Thread. Очевидно, что Swing был разработан таким образом (с одной резьбой), чтобы избежать слишком большой сложности. Любые вызовы извне могут вызвать потенциальную блокировку. Я понимаю, что invokeLater() помещает вызов в конце очереди выполнения. –

1

Лучший совет для вашей ситуации - использование SwingWorker. Проверьте API на http://java.sun.com/javase/6/docs/api/javax/swing/SwingWorker.html

метод процесса Override обновить значение прогресс бар (тогда это будет сделано правильно на EDT)

Более подробную информацию можно получить на http://java.sun.com/products/jfc/tsc/articles/threads/threads2.html

3

Использование модели вместо JProgressBar непосредственно:

DefaultBoundedRangeModel model = new DefaultBoundedRangeModel(); 
JProgressBar bar = new JProgressBar(model); 

// Somewhere else, perhaps in another Thread 
model.setValue(i) 

следующий пример работает нормально:

public static void main(String[] args) throws InterruptedException { 
    JFrame frame = new JFrame(); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setSize(200, 100); 
    frame.setVisible(true); 
    final DefaultBoundedRangeModel model = new DefaultBoundedRangeModel(); 
    frame.add(new JProgressBar(model)); 
    Thread t = new Thread(new Runnable() { 
     public void run() { 
      int i = 1; 
      model.setMinimum(0); 
      model.setMaximum(100); 
      try { 
       while (i <= 100 || true) { 
        model.setValue(i); 
        i++; 
        Thread.sleep(50); 
       } 
      } catch (InterruptedException ex) { 
       model.setValue(model.getMaximum()); 
      } 
     } 
    }); 
    t.start(); 

    Thread.sleep(2000); 

    t.interrupt(); 
} 
+2

Если он не делает это на EDT, это не сработает. –

+0

Да, это работает. См. Строки BasicProgressBarUI 1226-1229 в JDK1.6.0_20, в котором возникает repaint(), приводящая к Toolkit.getEventQueue(). PostEvent (e); – mhaller

1

Per eugener, SwingWorker определенно то, что вы хотите использовать здесь, или в любое время, когда возникает многолетняя задача, которая в противном случае могла бы заблокировать ваш графический интерфейс до завершения. Полное руководство по использованию прогресс бары с SwingWorker доступен из Sun^H^H^HOracle здесь:

http://java.sun.com/docs/books/tutorial/uiswing/components/progress.html

0

Положив этот фрагмент

SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
     jProgBar.repaint(); 
    } 
} 

между 'я ++' и «Thread.sleep () 'должен выполнять эту работу. Для его компиляции отметьте jProgBar как «final».