2011-04-17 2 views
4

У меня странная проблема. Я поставил JProgressBar:ProgressBar не меняет свое значение в Java

private JProgressBar progressBar; 

public void foo() 
{ 
    ... 
    progressBar = new JProgressBar(0, 100); 
    progressBar.setValue(0); 
    progressBar.setStringPainted(true); 
    ... 
    contentPane.add(progressBar); 
    ... 
} 

Но она меняется только тогда, когда я ставлю SetValue функцию его в некоторых местах в коде, не везде:

public void foo2() 
{ 
    progressBar.setValue(100); //working 
    if(...) 
    { 
     System.out.println("These instructions are executing"); //working 
     progressBar.setValue(0);        //not working 
    }        
} 

Итак, что я делаю неправильно? Почему вторая инструкция не работает?

+2

После рассмотрения [Как использовать баги прогресса] (http://download.oracle.com/javase/tutorial/uiswing/components/progress.html), разместите [sscce] (http://sscce.org) что демонстрирует проблему. – trashgod

+2

Возможно ли, что foo2() не вызывается из потока gui, то есть не вызывается из какого-либо компонента-слушателя и вместо этого вызывается из основного потока? Если это так, то причина. Изменения в gui должны произойти в потоке gui. См. SwingUtilities.invokeLater – MeBigFatGuy

ответ

15

Значение индикатора выполнения действительно обновляется. Но это не просто на экране. Часто мы используем индикаторы выполнения в циклах. Но, пока вы находитесь в цикле, который вы, вероятно, вызывается нажатием кнопки, он не окрашен. Зачем? Потому что вы вызвали его, нажав кнопку. Когда вы нажимаете кнопку, весь код, который вы сделали для этой кнопки, выполняется AWTEventThread. Это тот же самый поток, который отслеживает все компоненты Swing и проверяет, должны ли они быть перекрашены. Это поток, который заставляет ваш JFrame оживать. Когда вы наведете кнопку и цвет немного изменится, это делается с помощью AWTEventThread.

Итак, пока вы работаете в цикле, AWTEventThread больше не может обновлять экран.

Это означает, что есть два решения:

  1. (рекомендуется) Вы должны создать отдельный поток, который выполняет петлю. Это означает, что AWTEventThread может обновить экран, если это необходимо (при вызове bar.setValue(...);)

    public void yourButtonClickMethod() 
    { 
        Runnable runner = new Runnable() 
        { 
         public void run() { 
         //Your original code with the loop here. 
         } 
        }; 
        Thread t = new Thread(runner, "Code Executer"); 
        t.start(); 
    } 
    
  2. вручную перекрасить индикатор. Я всегда делал это с bar.repaint();, но мне интересно, будет ли это работать. Я, хотя это был этот метод. Если это не сработает, попробуйте: bar.update(bar.getGraphics());.

+0

Thx. Я попробовал ваше первое решение, но я получаю ошибку от NetBeans - « не является абстрактным и не отменяет абстрактный метод run() в java.lang.Runnable« – Hoome

+0

Хорошо, глупо мне, все работает правильно, спасибо! – Hoome

+0

Добро пожаловать. –

-1

Несмотря на то, что на этот вопрос был дан ответ, я нашел другой способ, который действительно работал для меня. Я использовал swing worker и использовал propertyChange (null), чтобы обновить индикатор выполнения, было самым простым решением.

Просто хотел предложить эту альтернативу.

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