2011-02-28 2 views
5

일부 작업을 수행하는 동안 내 프로그램에서 메서드 내에서 진행률 막대 값을 지속적으로 업데이트하려고합니다. 그러나 이것이 끝날 때까지는 일어나지 않으며 UI가 정지됩니다.Loop (Threaded)에서 JProgressBar 업데이트 값을 만드는 데 문제가 있습니다.

내 문제가 비슷한 질문을 둘러 보았지만 허용 된 솔루션 (스레드 사용)을 구현하려했지만 올바르게 작동하지 못했습니다. 마치 그들이없는 곳에있는 것처럼.

내 프로그램은 Main 자동으로 JFrame의 디자인 모드에 넷빈즈에 의해 생성 된 하나되는 몇 가지 클래스가 포함되어 있습니다, 그래서 그 내용의 일부를 정말 확실하지 오전 같은 static void mainpublic Main 같은 특정 일이있다. 내가 쓰레드 구현과 함께 그 메소드의 스 니펫을 넣을 것이다.

public class Main extends javax.swing.JFrame implements ActionListener, Runnable{ 
              // I added implements ActLis, Runn..... 

... 

static Main _this;  // I included this variable 

... 

public static void main(String args[]) { 
     Main m = new Main();        // Added by me 
     new Thread(m).start();        // Added by me 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       new Main().setVisible(true); 
      } 
     }); 
} 

... 

public Main() { 
     initComponents(); 
     _this = this;  // Added by me 
} 


... 

// I also included these 2 methods in the class 

public void actionPerformed(ActionEvent e) {          
    synchronized(this){               
     notifyAll();                
    }                   
}                    

public void run() {                
    try{synchronized(this){wait();}} 
    catch (InterruptedException e){} 
    progressBar.setValue(50);             
} 

... 

private void buttonPressed(java.awt.event.MouseEvent evt) { 
    for(int i=0; i<=100; i++) { 
     for(int j=0; j<=5; j++) { 
     // does some work 
     } 
    run(); 
    } 
} 

내가 I added...로 주석 모든 일들이 내가 자습서 및 I 온라인 보았다 답변에 따라 퍼트 것들,하지만 아무것도 작동하는 것 같다없고, 내가 가까이 만 다른 조합을 시도처럼 느낀다 ..

미리 감사드립니다.

답변

10

솜이야 당신이 그것을보고 공부할 수 있고 모든 코드 조각이 왜 있는지 이해할 수 있다면 당신이 볼 기초가 될 것입니다. (나는 지금 침대에 갈거야하지만!) 댓글에 질문을 자유롭게

예 :이 문제를 접근하는

public class ProgressBarDemo extends JFrame { 
    private final JProgressBar progressBar = new JProgressBar(0, 100); 
    private int progressCounter = 0; 

    public ProgressBarDemo() { 
     setContentPane(progressBar); 
     setPreferredSize(new Dimension(100, 100)); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     pack(); 
     new Thread(new Runnable() { 
      public void run() { 
       while (progressCounter <= 100) { 
        SwingUtilities.invokeLater(new Runnable() { 
         public void run() { 
          progressBar.setValue(progressCounter++); 
         } 
        }); 
        try { Thread.sleep(500); } catch (InterruptedException e) {} 
       } 
      } 
     }).start(); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       new ProgressBarDemo().setVisible(true); 
      } 
     }); 
    } 
} 

두 가지 다른 방법을 대신 SwingWorker를 사용 :

SwingWorker의 실시 예 1 :

.... 
    public ProgressBarDemo() { 
     setContentPane(progressBar); 
     setPreferredSize(new Dimension(100, 100)); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     pack(); 

     SwingWorker<Integer, Void> worker = new SwingWorker<Integer,Void>() { 
      public Integer doInBackground() { 
       while (progressCounter <= 100) { 
        setProgress(progressCounter++); 
        try { Thread.sleep(500); } catch (InterruptedException e) {} 
       } 
       return 0; 
      } 
     }; 
     worker.addPropertyChangeListener(new PropertyChangeListener() { 
      public void propertyChange(PropertyChangeEvent event) { 
       if ("progress".equals(event.getPropertyName())) { 
        progressBar.setValue((Integer)event.getNewValue()); 
       } 
      } 
     }); 
     worker.execute(); 
    } 
    .... 

SwingWorker Example 2 (그렇게 좋지는 않지만 그럼에도 불구하고 흥미 롭습니다.) :

.... 
    public ProgressBarDemo() { 
     setContentPane(progressBar); 
     setPreferredSize(new Dimension(100, 100)); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     pack(); 

     new SwingWorker<Integer,Integer>() { 
      public Integer doInBackground() { 
       while (progressCounter <= 100) { 
        publish(progressCounter++); 
        try { Thread.sleep(500); } catch (InterruptedException e) {}      
       } 
       return 0; 
      } 
      public void process(List<Integer> progresses) { 
       Integer maxProgress = null; 
       for (int progress : progresses) { 
        if (maxProgress == null || progress > maxProgress) { 
         maxProgress = progress; 
        } 
       } 
       progressBar.setValue(maxProgress); 
      } 
     }.execute(); 
    } 
    .... 
+0

+1 좋은 예; '@ Override' 주석을 추가하는 것을 고려하십시오. – trashgod

+0

와우, 친구 정말 항상 나에게 많은 것을 의미하며 스레딩을 이해하고 문제를 해결하는 데 도움이되었다고 생각했습니다. 나는 첫 번째 예를 사용하여 그것을 할 수 있었다고 다행스럽게 생각합니다. 어디에서 가장 좋아하는 괴물 같은 대답으로 3 번 ** 진드기를합니까? – Fabian

3

이 몇 가지 코드 :(두 번 홈페이지를 만드는

  • 잘못이다, 당신은 하나 개의 인스턴스에서 대기하고 다른 통지 끝낸다. 수동 실행을 호출하고
  • ()뿐만 아니라 처음부터 코드를 작성,

튜토리얼을 잊지 ... 너무 할 스레드를 예약하고 만 이해 거기에 물건을 추가 할 수 있습니다. 여기

+0

+1 iluxa가 맞습니다. 이 [예제] (http://stackoverflow.com/questions/4637725)에서 제안 된 것처럼 SwingWorker를 고려하십시오. – trashgod

관련 문제