2014-02-26 4 views
0

JProgressBar 설정 했으므로 원하는대로 작동하지 않습니다. 따라서 프로그램을 실행할 때마다 즉시 0에서 100으로 바뀝니다. 내가 ProgressMonitor, 작업을 사용하여 시도하고 SwingWorker 시도했지만 아무것도 노력했다.JProgressBar가 제대로 작동하지 않습니다.

int max = 10; 
for (int i = 0; i <= max; i++) { 
     final int progress = (int)Math.round(
      100.0 * ((double)i/(double)max) 
     ); 

     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException ex) { 
        Logger.getLogger(BandListGenerator.class.getName()).log(Level.SEVERE, null, ex); 
       } 
       jProgressBar2.setValue(progress); 
      } 
     }); 
    } 

@MadProgrammer 여기 스윙 노동자를 만들고 문서에 각각의 이름을 작성하고 진행 표시 줄을 업데이트하려고 시도한 것입니다 :

여기 내 프로그램입니다. 이 프로그램은 약 86 %에 달하며 멈추고 결코 완성 된 문서를 만들지 않습니다. 프로그램이 빈 문서를 만듭니다. 여기

public class GreenWorker extends SwingWorker<Object, Object> { 
    @Override 
    protected Object doInBackground() throws Exception { 
     int max = greenList.size(); 
     XWPFParagraph tmpParagraph; 
     XWPFRun tmpRun; 
     FileInputStream file = 
       new FileInputStream(location + "GreenBandList.docx"); 
     gDocument = new XWPFDocument(OPCPackage.open(file)); 
     for (int i = 0; i < max; i++) { 
      tmpParagraph = gDocument.getParagraphs().get(0); 
      tmpRun = tmpParagraph.createRun(); 
      if (greenList.get(i).length() == 1) { 
        tmpRun.setBold(true); 
        tmpRun.setText(greenList.get(i)); 
        tmpRun.setBold(false); 
      } else { 
        tmpRun.setText(greenList.get(i));//Write the names to the Word Doc 
      } 
      int progress = Math.round(((float) i/max) * 100f); 
      setProgress(progress); 
     } 
     return null; 
    }   
} 

그리고

그것을 시작하고 내 재산 변경 이벤트가있는 버튼에 대한 코드입니다 : 여기에 먼저 두 가지 방법 내가 만든 SwingWorker의 객체되어 있습니다.
private void GenerateGreenList() throws IOException, InterruptedException { 
    //Need to fix the bug that removes the Letter Header in Yellow Band list 
    //********************************************************************\\ 

    //Delete the old list and make a new one 
    File templateFile = new File(location + "\\backup\\GreenTemplate.docx"); 
    FileUtils.deleteQuietly(new File(location + "GreenBandList.docx")); 
    FileUtils.copyFile(templateFile, new File(location + 
      "GreenBandList.docx")); 
    //Get the New Entries 
    String[] entries = jTextPane3.getText().split("\n"); 
    for (String s : entries) { 
     if (s != null) { 
      greenList.add(s); 
     } 
    } 
    //Resort the list 
    Collections.sort(greenList); 
    //Write the names to the document 
    GreenWorker worker = new GreenWorker(); 
    worker.addPropertyChangeListener(new PropertyChangeListener() { 
     @Override 
     public void propertyChange(PropertyChangeEvent evt) { 
      if ("progress".equals(evt.getPropertyName())) { 
       jProgressBar2.setValue((Integer) evt.getNewValue()); 
      } 
     } 
    }); 
    worker.execute(); 
    if (worker.isDone()) { 
     try { 
      gDocument.write(new FileOutputStream(new File(location + "GreenBandList.docx"))); 
      //////////////////////////////////////////////////////////// 
     } catch (IOException ex) { 
      Logger.getLogger(BandListGenerator.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     JOptionPane.showMessageDialog(null, "Green Band List Created!"); 
     jProgressBar2.setValue(0); 
    } 
} 

나는 다른 게시물 중 하나에서 프로퍼티 변경 리스너를 사용하지만 난 정말 당신이 쓴 사람이 무엇을하거나 일반적으로 무엇을 이해하지?

+0

내 멍청한 짓이야. Brent

답변

5

스윙은 단일 스레드 환경입니다. 다시 그리기 이벤트를 포함하여 시스템 내에서 발생하는 모든 이벤트를 처리하는 단일 스레드가 있습니다. 아무것도 어떤 이유로 든이 스레드를 차단해야합니다, 그것은 ... 이벤트를 칠하고, 새로운 이벤트를 처리 포함에서

EventQueue.invokeLater(new Runnable() { 
    @Override 
    public void run() { 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(BandListGenerator.class.getName()).log(Level.SEVERE, null, ex);  } 
     jProgressBar2.setValue(progress); 
    } 
}); 

지속적으로 이벤트 파견 스레드를 일시 중지되도록

이 모든 ... 스윙을 방지 할 수 있습니다 , 실제로 어떤 업데이트 (또는 적어도 그들을 무작위로 간격을 두는 것)를 방지합니다 ...

외부 루프가 EDT의 컨텍스트 내에서 실행되었을 가능성이 있습니다. 즉, 존재할 때까지 이벤트 대기열이 처리됩니다. 모든 다시 칠하기 요청은 하나의 페인트 요청과 즉시 적용되는 진행률 표시 줄로 통합됩니다 ...

정말 사용해야합니다 SwingWorker - 당신이 시도했지만 어떤 코드도 표시하지 않았다는 것을 알고 있습니다. 이 점에있어서 당신의 시도에 관해서는, 그러나 그것은 왜 효과가 없었는지 알기가 어렵습니다 ...

그리고 우리는 이것을 말했다하지 않은 경우 용서 몇 번 전에 : P

+0

나는 당신이 가지고있는 곳으로 Thread.sleep을 옮겼다. 그리고 최대 값이 커질 때 (나는 최대 값을 위해 그것을 사용하려고하는 것이 꽤 클 것이다.) 프로그램이 멈춰 버렸을 때 나는 여전히 같은 문제를 가지고있다. – Brent

+0

예제를 보았습니까? Fro. 그것의 소리, 당신은 외부 for 루프입니다 또한 EDT 컨텍스트 내에서 실행됩니다. – MadProgrammer

+0

SwingWorker에 대한 코드가 없기 때문에 필자는 그것들이 어떻게 작동하는지 이해하지 못하기 때문에. 코드를 살펴보고 있지만 Worker Object를 이해하지 못한다. 진행 막대 앞에 루프 컨셉을 사용할 때 그 점이 무엇일까? – Brent

1

EvokeLater 안에 Thread.sleep을 불러오고 있습니다. 이는 for 루프와 다른 스레드에서 실행 중임을 의미합니다. 즉, for 루프는 즉시 완료됩니다 (물론, 거의 순간적으로 1에서 100까지 반복적으로 반복됩니다).

Thread.sleepEvokeLater 외부로 이동하면 의도 한대로 작동합니다.

int max = 10; 
    for (int i = 0; i <= max; i++) { 
     final int progress = (int)Math.round(
      100.0 * ((double)i/(double)max) 
     ); 

     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       jProgressBar2.setValue(progress); 
      } 
     }); 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException ex) { 
      Logger.getLogger(BandListGenerator.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

편집 : @MadProgrammer와 동의하십시오. 이것은 단지 설명을위한 질문 일 뿐이지 만 여기에서 성취하고자하는 것은 무엇이든 SwingWorker을 사용해야합니다.

+0

Tread.sleep을 모두 제거했는데 최대 크기가 커지면 같은 문제가 발생합니다. 최대 크기가 커지면 프로그램이 멈 춥니 다. – Brent

관련 문제