如何使jprogressbar与我的算法并行运行

可能重复:
Java GUI JProgressBar没有绘画
可以在main之外的类中使用进度条吗?

我正在使用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 

进度条确实显示并运行。但是当进度条值更新到结束时,只运行我的算法。 我看透了其他人的例子,但我真的不明白它是如何运作的。

谁能告诉我哪里出错了?

Swing中一些最重要的概念是

不要在事件调度线程(ETD)中执行任何长时间运行/阻塞操作。 这将导致UI显示为“冻结”且无响应。 什么是好的,你似乎明白这一点。

不要从EDT以外的任何线程创建或修改任何ui组件。 你不是这样做的。

您最好的行动原因是利用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 { @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 ;)