2014-12-14 3 views
0

Так у меня есть класс JFrame с помощью этой функции внутри:JProgressBar не обновит dynamicaly

o=1; 
private String performTest(int i,File file) throws IOException, InterruptedException { 
     //CRAPPY CODE 
       while(o<=20) { 
       Thread.sleep(1000); 
       progressBar.setValue((o/20)*100);    
       o++; 
       } 
     //CRAPPY CODE 
    } 

Таким образом, индикатор должен обновляться каждый второй с большим значением, но все это я получаю является всего лишь 1 окончательное обновление (до 100), когда функция завершает работу; Возможно, есть некоторые способы исправить эту проблему? Благодарим вас в ожидании. Полный код.

btnTesteaz.addActionListener(new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      int i = choice.getSelectedIndex(); 
      File file = fc.getSelectedFile(); 


      StringBuilder builder = new StringBuilder();   
      Thread t = new Thread(new Runnable() { 
       @Override 
       public void run() { 

         String name = Problems[i]; 
         int o = 1; 
         try { 

         String pathToPas = file.getPath(); 
         String pathToExe = pathToPas.replace(".pas", ".exe"); 
         Process process = Runtime.getRuntime().exec("ppc386 "+pathToPas); 
         Thread.sleep(1000); 
         process.destroy(); 

         while (new File("Res\\"+Problems[i]+"\\"+"Input"+o+".txt").exists()) { 
          //FILES WITH INPUTS FROM RES 
          File in = new File("Res\\"+Problems[i]+"\\"+"Input"+o+".txt"); 
          //FILES FOR .PAS 
          File inputtxt = new File(file.getParent()+"\\Input.txt"); 



          BufferedReader bf = new BufferedReader(new FileReader(in)); 
          PrintWriter w = new PrintWriter(new FileWriter(inputtxt));  
          String s = null; 
          while ((s = bf.readLine())!=null) { 
           w.println(s); 
          } 
          w.close();   
          bf.close(); 
          Process process1 = Runtime.getRuntime().exec(pathToExe,null, new File(file.getParent())); 
          Thread.sleep(1000); 
          process1.destroy(); 

          File outputtxt = new File(file.getParent()+"\\Output.txt"); 
          File out = new File("Res\\"+Problems[i]+"\\"+"Output"+o+".txt"); 
          BufferedReader r1 = new BufferedReader(new FileReader(out)); 
          BufferedReader r2 = new BufferedReader(new FileReader(outputtxt));     
          StringBuilder ansRes = new StringBuilder(); 
          StringBuilder ansPas = new StringBuilder();  
           while ((s=r1.readLine())!=null) ansRes.append(s); 
           while ((s=r2.readLine())!=null) ansPas.append(s); 

          if (ansRes.toString().trim().equals(ansPas.toString().trim())) { 
           builder.append("<p font color=green>"+(o)+". Test succesful </p> ") ; 
          } 
          else builder.append("<p font color=red>"+(o)+". Test failed </p>"); 
          r1.close(); 
          r2.close(); 

           inputtxt.delete(); 
           outputtxt.delete(); 

           final int temp = o; 
           SwingUtilities.invokeLater(new Runnable() { 
            public void run() { 
             model.setValue((int) (((float) temp/20.0f) * 100)); 
            } 
           });        
           o++; 
         } 
         File f = new File(pathToExe); 
         f.delete(); 
         File fa = new File(file.getAbsolutePath().replace(".pas",".o")); 
         fa.delete(); 
         } 
         catch (Exception e) { 
          e.printStackTrace(); 
         } 
       } 
      }); 
      t.run(); 
     Result.setText(builder.toString()); 
     } 
    }); 

ответ

2

Это классическая проблема, когда в Swing. Свинг делает все графические обновления от своего основного потока, так что вы не должны делать длительные операции оттуда (вы не позволите это перекрасить!)

Попробуйте принимать вашу длинную операцию на другой поток, как в этом учебнике:

https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

Это научит вас, как сделать долгое время трудоемких задач в фоновом режиме, при обновлении пользовательского интерфейса в режиме реального времени без баловаться с свинг архитектуры

0

Добавление к проблеме Swing UI замораживания, вы также разделяющая два целых числа, которые всегда округляются до ближайшего целого числа, поэтому вы «Повторно установив индикатор для 0*100 каждый раз, за ​​исключением последнего времени, когда o == 20, поэтому дополнительно к использованию нити, типажи o к float и разделяющему по 20.0f должен сделать трюк:

private String performTest(...) { 
    Thread t = new Thread(new Runnable() { 
     @Override 
     public void run() { 
      int o = 1; 
      while (o <= 20) { 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 

       //Notice typecasts 
       progressBar.setValue((int) (((float) o/20.0f) * 100)); 

       o++; 
      } 
     } 
    }); 
    t.run(); 
} 
+0

Я попробовал вашу идею с «Темой», но он по-прежнему заморожен и обновляется только до 100% –

+0

я опробованный точно той же самой вещи, и она работала для меня. – Marv

-1

Попробуйте изменить Int удвоится

double o=1; 
final double max = 100.00; 
final double per = 20.00 
private String performTest(int i,File file) throws IOException, InterruptedException { 
     //HAPPY CODE 
     while(o<=20) { 
      Thread.sleep(1000); 
      progressBar.setValue((int)((o/per)*max));    
      o++; 
     } 
     //HAPPY CODE 
} 
+0

Проблема по-прежнему сохраняется. –

+0

Просьба показать мне ваш полный код, чтобы я мог видеть, что блокирует поток пользовательского интерфейса. @ DenisRozimovschi – neferpitou

+0

Я редактировал вопрос, чтобы вы могли видеть полный код. –