Java JProgressBar在进程完成之前不会更新
我知道这里有大量的Java JProgressBar在进程完成之前不会更新,java,swing,swingworker,event-dispatch-thread,jprogressbar,Java,Swing,Swingworker,Event Dispatch Thread,Jprogressbar,我知道这里有大量的JProgressBar问题,但通过所有的答案,我似乎无法诊断我的问题。我正在用地址验证软件处理一个文件。我单击“处理”按钮,需要使用我的JProgressBar更新处理的每个文件。 这是按钮: private JButton getJButton0() { ... jButton0.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) {
JProgressBar
问题,但通过所有的答案,我似乎无法诊断我的问题。我正在用地址验证软件处理一个文件。我单击“处理”按钮,需要使用我的JProgressBar
更新处理的每个文件。
这是按钮:
private JButton getJButton0() {
...
jButton0.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
jButton0ActionActionPerformed(event);
t.start();
}
...
根据大家的建议,我在线程中使用了setValue()
方法
Thread t = new Thread(){
public void run() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
jProgressBar0.setValue(BulkProcessor.getPercentComplete());
}
});
try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
...
BulkProcessor.getPercentComplete()
是我从另一个类调用的方法,它表示完成百分比。我已经测试了这个方法,它更新正确。问题是进度条在文件处理完成之前不会更新,然后会跳到100%。我很抱歉,如果这是一个重复的问题,但我做了一些认真的挖掘在这个网站上没有运气。非常感谢您的帮助
编辑:
根据推荐的副本,我尝试了以下方法:
public void update(){
new SwingWorker<Void,Void>() {
protected Void doInBackground() throws Exception {
jProgressBar0.setValue(BulkProcessor.getPercentComplete());
return null;
};
}.execute();
}
编辑
这是我的BulkProcessor
类中的代码
private String getOutputLine( String searchString, String inputLine )
throws QasException
{
..(code for processing lines)..
countRecord++;
percentComplete = (int) Math.round((countRecord/totalRecord)*100);
public static void main( String input, String output ){
count.clear();
try{
String inputFile = input;
String outputFile = output;
LineNumberReader lnr = new LineNumberReader(new FileReader(new File(input)));
lnr.skip(Long.MAX_VALUE);
totalRecord = lnr.getLineNumber() + 1; //line count in file
BulkProcessor bulk = new BulkProcessor(inputFile, outputFile, ConfigManager.DFLT_NAME);
bulk.process();
}catch(Exception e ){
e.printStackTrace();
}
}
totalRecord
在myBulkProcessor
类的主类中更新
private String getOutputLine( String searchString, String inputLine )
throws QasException
{
..(code for processing lines)..
countRecord++;
percentComplete = (int) Math.round((countRecord/totalRecord)*100);
public static void main( String input, String output ){
count.clear();
try{
String inputFile = input;
String outputFile = output;
LineNumberReader lnr = new LineNumberReader(new FileReader(new File(input)));
lnr.skip(Long.MAX_VALUE);
totalRecord = lnr.getLineNumber() + 1; //line count in file
BulkProcessor bulk = new BulkProcessor(inputFile, outputFile, ConfigManager.DFLT_NAME);
bulk.process();
}catch(Exception e ){
e.printStackTrace();
}
}
看起来你在混合用法。请参阅SwingWorker文档,顶部的示例: 理想情况下,您应该使用SwingWorker的doInBackground方法更新BulkProcessor,这将调用setProgress,而jProgressBar将监听这些进度更新,如示例所示 如果这对你不起作用,这似乎不仅仅是基于上述,那么从按钮按下事件启动SwingWorker。实现类似这样的SwingWorker方法(伪代码):
newswingworker()
{
doInBackground()
{
做
{
percentComplete=BulkProcessor.getPercentComplete();
出版(竞争);
睡眠(100);
}完成率<100%;
}
@凌驾
流程(列出进度)
{
jProgressBar0.setValue(progress.get(0));
}
}.execute();
您需要添加错误处理和检查完整和失败案例,但这应该可以让您开始并达到您想要的目的。doInBackground在后台线程中运行,因此不会阻止任何内容,而process()在swing worker线程中运行,因此会发布更新。您可能犯的错误是调用t.start();执行
jbutton0action后(事件)代码>这使得执行操作后线程将启动。因此,进度条的值不会按预期更新
您需要在jButton0ActionPerformed(事件)中启动线程;然后更新其中的值。只是一种预感,但是
percentComplete = (int) Math.round((countRecord/totalRecord)*100);
你确定这不是整数算术吗?我不知道totalRecord的类型,所以我不能肯定
我猜一切都很好,只是进度一直是0,直到完成,神奇地是100。这是因为一个整数除以一个整数将没有分数值(即99/100==0,100/100==1)。这完全符合你所经历的症状
尝试将上面的行替换为:
percentComplete = (int) Math.round((countRecord/(double) totalRecord)*100);
看得出我是对的。:-) 您是否尝试过使用-界面
计算将由Swingworker线程完成,主gui将实现此接口。一些示例代码
@Override
public void actionPerformed(ActionEvent e) {
this.myButton.setEnabled(false);
MyWorkerThread thread = new MyWorkerThread(); //Data-processing
thread.addPropertyChangeListener(this.mainguiframe); //Separation of concern
thread.execute();
}
使用swing worker线程的“setProgress”方法,如果发生了什么事情,将通知主gui线程
@Override
public void propertyChange(PropertyChangeEvent property) {
Integer currentValue = new Integer(0);
currentValue = (Integer) property.getNewValue();
this.progressBar.setValue(currentValue.intValue());
}
Swing不是线程安全的。这不是最好的解决方案,但也许它可以帮助你。如果出现严重错误,请发表评论。不要阻止EDT(事件调度线程)-发生这种情况时,GUI将“冻结”。不要调用Thread.sleep(n)
为重复任务执行Swing计时器,或为长时间运行的任务执行SwingWorker
。有关更多详细信息,请参阅。。好的,这是我根据标题发表的评论。但是<代码>线程睡眠(100)代码>在一个SwingWorker
内?那是怪诞的化身!为了更快地获得更好的帮助,请发布一个。这是一个。请参阅上面的编辑,我基于Uwe Plonus的重复链接,一些在JTable标签下,这里有SwingWoker和Runnable@Threaddifferent类不是问题,只要线程正确交互,while循环中的%complete是指我的getPercentComplete()?另外,不需要返回类型吗?需要进行一些清理。我只是想抓住要点。您实际上不需要返回任何内容(尽管您确实需要返回类型,但是Void/null是有效的)。发布(整数)和进程(整数)是处理状态更新的主要方法。process()将实际获取列表,您只需要项0。是的,对于完成百分比,您需要知道何时停止检查和发布进度更新。但你大概有这个信息(检查进度<100只是一种方法)。在你的例子中,process方法从未被读取(查看我上一次编辑时使用的代码)查看我的编辑:1)将while循环更改为do while,在循环中读取大容量处理器值。2) 将@Override注释添加到process()方法中,以确保签名正确(应该是一个整数列表,您只关心第一个整数)。这一点您是对的,我之前确实了解到了这一点,但是我没有在我的帖子中更新它,抱歉。我已经完成了system.out.print(percentComplete)它在控制台中打印出我想要的值(1,3,4,5,…100)。所以我不相信这会是个问题。而且,totalRecord是一个双重记录