2

Тонны JProgressBar вопросов, которые я знаю, но через все ответы, и я не могу показать свою проблему. Я обрабатываю файл с помощью программного обеспечения для проверки адреса. Я нажимаю кнопку «Процесс», и мне нужно, чтобы мой JProgressBar обновлялся с каждым обрабатываемым файлом. Вот кнопка:JProgressBar не будет обновляться до тех пор, пока процесс не будет завершен.

private JButton getJButton0() { 
... 
    jButton0.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent event) { 
     jButton0ActionActionPerformed(event); 
     t.start(); 
     } 
... 

За рекомендацию каждого, я использовал метод setValue() в потоке

Thread t = new Thread(){ 
    public void run() { 
    SwingUtilities.invokeLater(new Runnable() { 
    public void run() { 
     jProgressBar0.setValue(BulkProcessor.getPercentComplete()); 
    } 
}); 
try { 
    Thread.sleep(100); 
} catch (InterruptedException e) { 
} 
... 

BulkProcessor.getPercentComplete() является метод, который я звоню из другого класса, который представляет собой процент полной. Я проверил этот метод, и он обновляется корректно. Проблема в том, что индикатор выполнения не будет обновляться до тех пор, пока файлы не будут обработаны, а затем он перейдет на 100%. Приносим извинения, если это повторяющийся вопрос, но я сделал серьезный рыть на этом сайте без везения. Любая помощь очень ценится.

Edit:

Per рекомендуется дублировать, я попытался это:

public void update(){ 
    new SwingWorker<Void,Void>() { 
    protected Void doInBackground() throws Exception { 
    jProgressBar0.setValue(BulkProcessor.getPercentComplete()); 
    return null; 
}; 
}.execute(); 
} 

А затем попытался вызвать этот метод обновления() под actionPerformed() (переключился t.start() с update()). У меня все еще такая проблема.

Редактировать

По рекомендации user1676075, однако тот же вопрос:

public static void update(){ 
     new SwingWorker<Void,Integer>() { 
     protected Void doInBackground() throws Exception { 
      do 
      { 
      percentComplete = BulkProcessor.getPercentComplete(); 
      publish(percentComplete); 
      Thread.sleep(100); 
      } while(percentComplete < 100); 

     return null; 
     } 
     @Override 
    protected 
     void process(List<Integer> progress) 
     { 
      jProgressBar0.setValue(progress.get(0)); 
     } 
    }.execute(); 
    } 

Редактировать

Вот код из моего BulkProcessor класса

private String getOutputLine(String searchString, String inputLine) 
throws QasException 
{ 
..(code for processing lines).. 
countRecord++; 
    percentComplete = (int) Math.round((countRecord/totalRecord)*100); 

totalRecord обновляется в главном классе моего BulkProcessor класса

public static void main(String input, String output){ 
    count.clear(); 
    try{ 
     String inputFile = input; 
     String outputFile = output; 
     LineNumberReader lnr = new LineNumberReader(new FileReader(new File(input))); 
     lnr.skip(Long.MAX_VALUE); 
     totalRecord = lnr.getLineNumber() + 1; //line count in file 
     BulkProcessor bulk = new BulkProcessor(inputFile, outputFile, ConfigManager.DFLT_NAME); 
     bulk.process(); 
    }catch(Exception e){ 
     e.printStackTrace(); 
    } 

} 
+1

Не блокируйте EDT (Event Dispatch Thread) - графический интерфейс «замерзнет», когда это произойдет. Вместо вызова 'Thread.sleep (n)' реализовать Swing 'Timer' для повторения задач или' SwingWorker' для длительных задач. Подробнее см. [Параллелизм в Swing] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/). ..OK это комментарий, который я опубликовал, основываясь на названии. Но .. 'Thread.sleep (100);' * inside * a SwingWorker'? Это странность персонифицирована! Чтобы лучше помочь, опубликуйте [SSCCE] (http://sscce.org/). –

+0

Это [дубликат] (http://stackoverflow.com/questions/8251607/running-a-jframe-with-a-jprogressbar). –

+0

См. Приведенный выше раздел «Редактирование», я основывал это на дублирующей ссылке Uwe Plonus – TaylorSmolik

ответ

0

Похоже, вы смешивания использований. См. Документацию SwingWorker, пример вверху: http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html.

В идеале вы должны обновить свой BulkProcessor в методе doInBackground для SwingWorker, и это вызовет setProgress, и jProgressBar будет слушать эти обновления прогресса, как в примере.

Если это не сработает для вас, что, похоже, будет не просто основано на вышеуказанном, запустите SwingWorker из события нажатия кнопки. Реализовать методы SwingWorker вроде как это (псевдокод):

new SwingWorker<Void,Integer>() 
{ 
    doInBackground() 
    { 
    do 
    { 
     percentComplete = BulkProcessor.getPercentComplete(); 
     publish(percentCompete); 
     Thread.sleep(100); 
    } while (percentComplete < 100); 
    } 

    @Override 
    process(List<Integer> progress) 
    { 
    jProgressBar0.setValue(progress.get(0)); 
    } 
}.execute(); 

Вам нужно добавить обработку ошибок и проверки для полных и отказа случаев, но это должно вам начать и где вы хотите быть. doInBackground работает в фоновом потоке, поэтому ничего не будет блокировать, а процесс() работает на потоке рабочего качания, поэтому опубликует обновления.

+0

%, что у вас есть в цикле while, ссылаясь на мой getPercentComplete()? – TaylorSmolik

+0

Кроме того, не требуется ли какой-либо тип возврата? – TaylorSmolik

+0

Необходимо выполнить некоторую очистку. Я просто пытался поразить основные моменты. Вам действительно не нужно ничего возвращать (хотя вам нужен тип возврата, да, хотя Void/null действителен). Публикация (Integer) и, следовательно, процесс (Integer) являются основными для обработки обновлений статуса. process() действительно получит List , и вам просто понадобится элемент 0. Да, что касается% complete, вам нужен способ узнать, когда прекратить проверку и публикацию обновлений хода. Но предположительно у вас есть эта информация (проверка прогресса <100 - это всего лишь один способ). – user1676075

0

Ошибка, которую вы, вероятно, продолжали, вызывает t.Начало(); после jButton0ActionPerformed(event);, который делает, что после выполнения действия начнется нить. Поэтому значение индикатора выполнения не обновляется по назначению.

Вам необходимо запустить поток в jButton0ActionPerformed (event); а затем обновить значение в нем.

+0

Вы правы в этом, я действительно ухватился за это раньше, но я не обновил его в своем посте, извинения. – TaylorSmolik

0

Просто догадка, но ...

percentComplete = (int) Math.round((countRecord/totalRecord)*100); 

Вы уверены, что это не целочисленной арифметике? Я не знаю тип totalRecord, поэтому не могу сказать точно.

Я бы предположил, что все работает нормально, и только прогресс 0 все время, пока не закончится, где магически 100. Это связано с тем, что int, деленный на int, не будет иметь значений фракций (то есть 99/100 == 0, 100/100 == 1). Это идеально подходит для симптомов, которые вы испытываете.

Попробуйте заменить строку выше:

percentComplete = (int) Math.round((countRecord/(double) totalRecord)*100); 

, чтобы увидеть его я прав. :-)

+0

Я сделал system.out.print (percentComplete), и он печатает значения, которые я хочу в консоли (1,3,4,5, ...... 100). Поэтому я не считаю, что это будет проблемой. – TaylorSmolik

+0

Кроме того, totalRecord - это двойной – TaylorSmolik

+0

О, ну .. Это была хорошая теория. ;-) Никакой сигары тогда .. – haraldK

0

Вы пытались использовать PropertyChangeListener -interface?

Расчеты будут выполняться потоком Swingworker, а main-gui реализует этот интерфейс. Некоторые примеры кода

@Override 
public void actionPerformed(ActionEvent e) { 
    this.myButton.setEnabled(false); 
    MyWorkerThread thread = new MyWorkerThread(); //Data-processing 
    thread.addPropertyChangeListener(this.mainguiframe); //Separation of concern 
    thread.execute(); 
} 

Использование «setProgress» -метод свинг-рабоче-нить главный-гуй-нить будет уведомлен, если что-то случилось.

@Override 
public void propertyChange(PropertyChangeEvent property) { 
    Integer currentValue = new Integer(0); 
    currentValue = (Integer) property.getNewValue(); 
    this.progressBar.setValue(currentValue.intValue()); 
} 

Свинг не является потокобезопасным. Это не лучшее решение, но, возможно, оно может вам помочь. Прошу прокомментировать, если что-то ужасное.

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