简体   繁体   English

在过程完成之前,JProgressBar不会更新

[英]JProgressBar will not update until process is completed

Tons of JProgressBar questions on here I know, but through all the answers and I can't seem to diagnose my issue. 我知道这里有很多JProgressBar问题,但是通过所有答案,我似乎无法诊断出我的问题。 I am processing a file with some address verification software. 我正在使用某些地址验证软件来处理文件。 I click the Process button and I need my JProgressBar to update with each file processed. 我单击“处理”按钮,我需要我的JProgressBar来更新每个处理的文件。 Here is the button: 这是按钮:

private JButton getJButton0() {
...
   jButton0.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
         jButton0ActionActionPerformed(event);
         t.start();
      }
...

Per everybody's recommendation, I used the setValue() method within a thread 根据每个人的建议,我在线程中使用了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() is a method I'm calling from another class which represents the percentage complete. BulkProcessor.getPercentComplete()是我从另一个类(表示完成百分比)中调用的方法。 I have tested this method and it updates correctly. 我已经测试了这种方法,它可以正确更新。 The issue is that the progress bar will not update until the files are finished processing, and then it will jump to 100%. 问题在于,进度条在文件完成处理之前不会更新,然后它将跳到100%。 I apologize if this is a repeat question, but I have done some serious digging on this site with no luck. 如果这是一个重复的问题,我深表歉意,但是我在这个网站上做了大量认真的研究,没有运气。 Any help much appreciated. 任何帮助,不胜感激。

Edit: 编辑:

Per recommended duplicate, I tried this: 对于推荐的重复项,我尝试了以下操作:

public void update(){
   new SwingWorker<Void,Void>() {
   protected Void doInBackground() throws Exception {
   jProgressBar0.setValue(BulkProcessor.getPercentComplete());
   return null;
 };
 }.execute();
}

And then tried calling this update() method under the actionPerformed() (switched t.start() with update() ). 然后尝试在actionPerformed()下调用此update()方法(将t.start()update()切换)。 I am still having the same issue. 我仍然有同样的问题。

Edit 编辑

Based on user1676075's recommendation, however same issue: 根据user1676075的建议,但是存在相同的问题:

    public static void update(){
       new SwingWorker<Void,Integer>() {
       protected Void doInBackground() throws Exception {
           do
           {
           percentComplete = BulkProcessor.getPercentComplete();
           publish(percentComplete);
           Thread.sleep(100);
           } while(percentComplete < 100);

        return null;
       }
       @Override
    protected
       void process(List<Integer> progress)
       {
           jProgressBar0.setValue(progress.get(0));
       }
     }.execute();
   }

Edit 编辑

Here is the code from my BulkProcessor class 这是我的BulkProcessor类中的代码

 private String getOutputLine( String searchString, String inputLine )
throws QasException
{
 ..(code for processing lines)..
 countRecord++;
    percentComplete = (int) Math.round((countRecord/totalRecord)*100);

totalRecord is updated in the main class of my BulkProcessor class totalRecord在主类我的更新BulkProcessor

 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();
    }

}

Looks like you're mixing usages. 看起来您正在混合使用。 See the SwingWorker documentation, example at the top: http://docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html . 请参见顶部的SwingWorker文档示例: http : //docs.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html

Ideally you'd update your BulkProcessor in the doInBackground method of the SwingWorker, and that would call setProgress, and the jProgressBar would be listening for those progress updates as in the example. 理想情况下,您可以在SwingWorker的doInBackground方法中更新BulkProcessor,这将调用setProgress,并且jProgressBar将像示例中那样监听这些进度更新。

If that won't work for you, which it seems like it won't just based on the above, start a SwingWorker from the button press event. 如果这对您不起作用,似乎不仅仅是基于上述情况,请从按钮按下事件中启动SwingWorker。 Implement the SwingWorker methods kinda like this (pseudocode): 像下面这样实现SwingWorker方法(伪代码):

new SwingWorker<Void,Integer>()
{
  doInBackground()
  {
    do
    {
      percentComplete = BulkProcessor.getPercentComplete();
      publish(percentCompete);
      Thread.sleep(100);
    } while (percentComplete < 100);
  }

  @Override
  process(List<Integer> progress)
  {
     jProgressBar0.setValue(progress.get(0));
  }
}.execute();

You'll need to add error-handling and checks for complete and failure cases, but that should get you started and to where you want to be. 您需要添加错误处理并检查完整案例和失败案例,但这应该可以使您入门并达到您想要的目标。 doInBackground runs in a background thread so won't block anything, and process() runs on the swing worker thread so will post the updates. doInBackground在后台线程中运行,因此不会阻止任何操作,而process()在swing worker线程上运行,因此将发布更新。

The mistake you probably went on is calling the t.start(); 您可能继续发生的错误是调用t.start();。 after the jButton0ActionPerformed(event); jButton0ActionPerformed(event); which makes that after the action is performed the thread will start. 这使得在执行操作之后线程将启动。 Therefore the value of the progress bar is not updated as intended. 因此,进度条的值未按预期更新。

You need to start the thread in jButton0ActionPerformed(event); 您需要在jButton0ActionPerformed(event)中启动线程; and then update the value in it. 然后更新其中的值。

Just a hunch, but... 只是预感,但是...

    percentComplete = (int) Math.round((countRecord/totalRecord)*100);

Are you sure this is not integer arithmetic? 您确定这不是整数运算吗? I don't know the type of totalRecord , so I can't say for sure. 我不知道totalRecord的类型,所以我不能肯定地说。

I'd guess everything works fine, and just the progress is 0 all the time, until complete where it magically is 100. This is because an int divided by an int will not have fraction values (ie. 99/100 == 0, 100/100 == 1). 我猜一切都正常,只是进度一直都是0,直到完成神奇的100为止。这是因为一个整数除以一个整数不会得到分数值(即99/100 == 0, 100/100 == 1)。 This fits perfectly with the symptoms you are experiencing. 这非常适合您遇到的症状。

Try replacing the line above with: 尝试将上面的行替换为:

   percentComplete = (int) Math.round((countRecord/(double) totalRecord)*100);

to see it I'm right. 看到它我是对的。 :-) :-)

Have you tried to use the PropertyChangeListener -interface? 您是否尝试过使用PropertyChangeListener -interface?

The calculations will be done by the Swingworker-thread and the main-gui will implement this interface. 计算将由Swingworker线程完成,并且main-gui将实现此接口。 Some example-code 一些示例代码

@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();
}

Using the "setProgress"-method of the swing-worker-thread the main-gui-thread will be notified if something has happend. 使用swing-worker线程的“ setProgress”方法,如果发生某些情况,将通知main-gui线程。

@Override
public void propertyChange(PropertyChangeEvent property) {
     Integer currentValue = new Integer(0);
     currentValue = (Integer) property.getNewValue();
     this.progressBar.setValue(currentValue.intValue());
}

Swing is not thread-safe. 摆动不是线程安全的。 This is not the best solution but perhaps it can help you. 这不是最佳解决方案,但也许可以为您提供帮助。 Please comment if there is somethin horrible wrong. 如果有什么可怕的错误,请发表评论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM