2012-05-08 2 views
0

Ниже приведен пример SwingWorker, который не обновлял графический интерфейс Java, как я ожидал.Обновление Java Gui Использование SwingWorker

SwingWorker реализован внутри прослушивателя действий для кнопки. min и max, которые определяют цикл, являются «конечными int», которые являются локальными для прослушивателя действий.

SwingWorker должен на каждом итерационном вызове использовать метод go() объекта, который рекурсивно находит все решения для n-queens. Затем вызывается NQueens объект toString(), после которого публикуется String, чтобы метод process() обновил jProgressBar и jTextArea. Однако при нажатии кнопки ничего не происходит. Является ли это тем, как я должен внедрять интенсивный процесс в сочетании с обновлениями компонентов GUI?

new SwingWorker <Void,String>() 
{  
    private int totalPercent; 
    @Override 
    protected Void doInBackground() 
    { 
     int diff = max - min + 1; 
     int percent = 100; 
     if(diff != 0) 
     { 
       percent = 100/diff; 
     } 
     totalPercent = 0; 
     NQueens queens = new NQueens(min); 
     for(int j = min; j <= max; j++) 
     { 
       queens.go(); 
       totalPercent += percent; 
       String newText = queens.toString(); 
       publish(newText); 
       queens.nextSet(); 
     } 

     isCalced = true; 

     return null; 
     } 

     protected void process(String results) 
     { 
      jTextArea2.append(results); 
      jProgressBar1.setValue(totalPercent); 
      jProgressBar1.repaint(); 
     }         
    }.execute(); 
+0

[Как использовать Bars Progress] (http://docs.oracle.com/javase/tutorial/uiswing/components/progress.html) – oers

+0

Выглядит нормально для меня , Вы знаете, если он вызывает процесс() вообще? Может быть, добавить простую отладку System.out? Также попробуйте переопределить done() и вызвать get() внутри этого, он сделает все исключения, которые произошли во время doInBackground(), чтобы получить «re-throw». – Jim

ответ

0

Возможно, причина в том, что вы не реализовали правильный метод обработки? Я считаю, что правильной сигнатурой процесса будет

process(List<String> results) { 
    for(String result : results) { 
    jTextArea2.append(result); 
    } 
} 

Что касается обновления контрольной панели; метод doInBackground работает в отдельном потоке, в то время как метод процесса работает в потоке, на который вы вызвали работника. Вы не должны писать переменную totalPercent из doInBackground и читать ее из process(). См. thread visibility для получения дополнительной информации об этом. Вместо этого создайте что-то вроде класса, называемого ProgressUpdateEvent, который может содержать процентное значение и сообщение. Таким образом, можно сделать следующим образом:

new SwingWorker <Void,ProgressUpdateEvent>() { 

    protected Void doInBackground() { 
    for (int i = 0; i <= 100; i++) { 
     publish(new ProgressUpdateEvent("At " + i + "% right now", i); 
    } 
    } 

    protected void process(List<ProgressUpdateEvent> events) { 
    for (ProgressUpdateEvent event : events) { 
     jTextArea2.append(event.getMessage()); 
     jProgressBar1.setValue(event.getPercent()); 
    } 
    } 
} 
Смежные вопросы