如何使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
你可以选择使用ProgressMonitor
或者如果你真的很绝望,可以使用SwingUtilities#invokeLater(Runnable)
,但是,我真的鼓励你使用SwingWorker
;)