2016-08-05 78 views
1

我很抱歉添加到许多JProgressBar更新问题,但这真的让我疯了。JProgress酒吧不更新在SwingWorker

我有一个JProgressBar通过SwingWorker进行更新,但我仍然有完成后更新栏的典型问题。

下面是相关代码:

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import java.util.ArrayList; 
import java.util.Calendar; 
import java.util.List; 
import java.util.concurrent.ExecutionException; 
import javax.swing.*; 

public class SwingTest { 

    public static void main(String args[]) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       init(); 
      } 
     }); 
    } 

    public static void init() { 
     JFrame frame = new JFrame(); 
     JPanel panel = new JPanel(); 
     JProgressBar bar = new JProgressBar(); 

     JButton button = new JButton("Start"); 
     button.addActionListener(new ActionListener() 
     { 
      @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       bar.setMaximum(100); 
       bar.setValue(0); 

       SwingWorker worker = new SwingWorker<String, Void>() 
       { 
        @Override 
        public String doInBackground() 
        { 
         int val = 0; 
         // +1 to make inclusive 
         for (int i = 0; i < 100; i++) 
         { 
          try 
          { 
           Thread.sleep(50); 
          } catch (InterruptedException e) 
          { 
           e.printStackTrace(); 
          } 

          setProgress(++val); 
         } 

         return "Hello SwingWorker World"; 
        } 

        @Override 
        public void done() 
        { 
        } 
       }; 

       worker.addPropertyChangeListener(
         new PropertyChangeListener() 
         { 
          public void propertyChange(PropertyChangeEvent evt) 
          { 
           if ("progress".equals(evt.getPropertyName())) 
           { 
            bar.setValue((Integer)evt.getNewValue()); 
           } 
          } 
         } 
       ); 

       worker.execute(); 

       try 
       { 
        System.out.println("Return: " + worker.get().toString()); 
       } catch (InterruptedException e1) 
       { 
        e1.printStackTrace(); 
        System.out.println("Failed."); 
       } catch (ExecutionException e1) 
       { 
        e1.printStackTrace(); 
        System.out.println("Failed."); 
       } 
      } 
     }); 

     panel.add(button); 
     panel.add(bar); 

     frame.add(panel); 
     frame.pack(); 
     frame.setSize(200,90); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    } 
} 

如果问题可能是由于另一部分如果需要的话我会编辑我的问题有更多的代码。

在此先感谢。

编辑:剥离代码到最小的产品。

+0

为了尽快提供更好的帮助,请发布[MCVE]或[简短,独立,正确的示例](http://www.sscce.org/)。 –

回答

0

您发布的代码中存在的问题是当您启动SwingWorker时,您立即等待它运行。这将阻止事件线程,它可以防止显示器被更新:

worker.execute(); // This starts the thread in the background 

try 
{ 
    // This immediately stops the event handler waiting for the worker to finish 
    System.out.println("Return: " + worker.get().toString()); 
} catch (InterruptedException e1) 
{ 
    e1.printStackTrace(); 
    System.out.println("Failed."); 
} catch (ExecutionException e1) 
{ 
    e1.printStackTrace(); 
    System.out.println("Failed."); 
} 

如果您注释掉的try-catch块的整体,它会运行并更新显示。

如果您需要等待工作人员的结果,那么您应该在另一个线程上等待结果,并允许UI线程继续。

+0

太棒了!谢谢!所以,如果我在另一个线程上等待结果,我该如何去将它们返回到父函数?我想.wait()也会阻止美国东部时间。 –

+0

我很幸运地找到了解决方案。只需重构一些代码。再次感谢! –

1

嗯,我不确切知道你的代码在做什么,但是我没有看到你的代码中有任何“延迟”的地方。

因此,循环会继续执行,所有绘画请求会合并到一个请求中,因此您只能看到最终值。

您可以通过在setProgress(...)方法之后简单添加Thread.sleep()来验证是否存在此问题。

如果是这种情况,问题是您为什么使用进度条,因为代码执行得太快了。

阅读How to Use Progress Bars上的Swing教程部分,并从工作演示开始。然后,您可以修改工作代码,以查看进行更改时发生的情况。

+0

我编辑我的代码到更小的表示。完整的代码可能需要几分钟到一个多小时才能执行,假设我理解你,我不认为这是由于代码执行速度太快。 –