JProgressBar无法正常工作
所以我设置的JProgressBar
不按我想要的方式工作。 因此,每当我运行程序时,它立即从0变为100。 我尝试使用ProgressMonitor
,一个任务,并尝试了一个SwingWorker
但我没有尝试过。
这是我的计划:
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%左右并停止,从不创建完成的文档。 该程序创建一个空白文档。 以下是两种方法,首先是我制作的SwingWorker对象:
public class GreenWorker extends SwingWorker { @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; } }
以下是启动它并具有我的属性更改事件的按钮的代码。
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); } }
我使用了你的其他post中的属性更改监听器,但是我真的不明白你写的那个或者它的作用是什么?
Swing是一个单线程环境,也就是说,有一个线程负责处理系统内发生的所有事件,包括重绘事件。 如果出于任何原因阻止此线程,它将阻止Swing处理任何新事件,包括重绘事件……
这一切……
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
– 我知道你说你试过一个,但你没有显示任何关于你在这方面的尝试的代码,所以很难知道为什么它不起作用,但是……
-
SwingWorker
和JProgressBar
示例 -
SwingWorker
和JProgressBar
示例 -
SwingWorker
和JProgressBar
示例 -
SwingWorker
和JProgressBar
示例 -
SwingWorker
和双焊接JProgressBar
例子 -
SwingWorker
和JProgressBar
示例
如果我们之前没有说过几次,请原谅我:P
你在EvokeLater
中唤起了Thread.sleep
,这意味着它在你的for循环之外的另一个线程上运行。 即,你的for循环正在瞬间完成(好吧,无论多长时间从1循环到100,这几乎是瞬间完成)。
将Thread.sleep
EvokeLater
之外,它应该按照您的意图工作。
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
。