2012-12-31 18 views
0

可能重複:
Java GUI JProgressBar not painting
Can a progress bar be used in a class outside main?如何使對JProgressBar的並行與我的算法運行

我使用NetBeans拖放做一個應用程序。我將從用戶獲得輸入並使用輸入來運行我的算法。該算法將花費不同的時間運行,然後在新框架中顯示其結果。在等待算法運行時,我希望添加進度條。 當用戶點擊按鈕提交輸入時,我添加了下面的代碼。

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) { 

    final JProgressBar bar = new JProgressBar(0,250000); 
    bar.setValue(1000); 
    bar.setIndeterminate(false); 
    JOptionPane jO = new JOptionPane(bar); 

    Thread th = new Thread(){ 

    public void run(){ 
     for(int i = 1000 ; i < 250000 ; i+=10000){ 
      bar.setValue(i); 
      try { 
       Thread.sleep(100); 
      } catch (InterruptedException e) { 
      } 
     } 
    } 
}; 
th.start(); 

final JDialog dialog = jO.createDialog(jO,"Experiment X"); 
dialog.pack(); 
dialog.setVisible(true); 

//Algorithm goes here 

進度條顯示並運行。但是當進度條值更新到結束時,只有我的算法運行。我通過其他例子看到,但我不太瞭解它是如何工作的。

誰能告訴我在哪裏,我錯了嗎?

+1

這一直問和答覆很多次。使用後臺線程,例如可以由SwingWorker提供的後臺線程。請閱讀進度條和swingworker教程,以獲取有關Google可以幫助您找到的更多信息。 –

+0

下面是教程鏈接:[進度教程](http://docs.oracle.com/javase/tutorial/uiswing/components/progress.html),[併發在擺動(和的SwingWorker教程)](HTTP:// docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html) –

+0

*「..然後顯示其結果在一個新的框架。」 *請參閱[多JFrames,好/壞習慣的用?(HTTP ://stackoverflow.com/a/9554657/418556)評估(壞)和替代品(很多)。 –

回答

4

一些Swing中的最重要的概念是

不要執行任何長期運行/事件指派線程(ETD)內阻塞操作。這會導致用戶界面出現「凍結」和無響應。好的是,你似乎明白這一點。

不要創建或修改任何其他線程然後美國東部時間。你沒有這樣做。

你最好的行動的原因是採取SwingWorker的優勢,這可以讓你進行長時間運行的操作,同時提供進度反饋給聽衆。

public class TestProgress { 

    public static void main(String[] args) { 
     new TestProgress(); 
    } 

    public TestProgress() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException ex) { 
       } catch (InstantiationException ex) { 
       } catch (IllegalAccessException ex) { 
       } catch (UnsupportedLookAndFeelException ex) { 
       } 

       ProgressPane progressPane = new ProgressPane(); 
       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(progressPane); 
       frame.setSize(200, 200); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 

//    progressPane.doWork(); 
      } 
     }); 
    } 

    public class ProgressPane extends JPanel { 

     private JProgressBar progressBar; 
     private JButton startButton; 

     public ProgressPane() { 

      setLayout(new GridBagLayout()); 
      progressBar = new JProgressBar(); 

      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.gridx = 0; 
      gbc.gridy = 0; 
      add(progressBar, gbc); 
      startButton = new JButton("Start"); 
      gbc.gridy = 1; 
      add(startButton, gbc); 

      startButton.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        startButton.setEnabled(false); 
        doWork(); 
       } 
      }); 

     } 

     public void doWork() { 

      Worker worker = new Worker(); 
      worker.addPropertyChangeListener(new PropertyChangeListener() { 
       @Override 
       public void propertyChange(PropertyChangeEvent evt) { 
        if ("progress".equals(evt.getPropertyName())) { 
         progressBar.setValue((Integer) evt.getNewValue()); 
        } 
       } 
      }); 

      worker.execute(); 

     } 

     public class Worker extends SwingWorker<Object, Object> { 

      @Override 
      protected void done() { 
       startButton.setEnabled(true); 
      } 

      @Override 
      protected Object doInBackground() throws Exception { 

       for (int index = 0; index < 1000; index++) { 
        int progress = Math.round(((float) index/1000f) * 100f); 
        setProgress(progress); 

        Thread.sleep(10); 
       } 

       return null; 
      } 
     } 
    } 
} 

你其他的選擇是使用ProgressMonitor或者,如果你真的絕望了,用SwingUtilities#invokeLater(Runnable),但是,我真的建議您使用SwingWorker代替;)