2011-03-02 74 views
2

首先,我一直在使用Java的Concurrency软件包,但是我发现了一个问题,我被卡住了。我想要和应用程序和应用程序可以有一个SplashScreen与状态栏和加载其他数据。所以我决定使用SwingUtilities.invokeAndWait(call the splash component here)SplashScreen然后出现JProgressBar并运行一组线程。但我似乎无法很好地处理事情。我已经看过SwingWorker并尝试使用它来达到这个目的,但是线程刚刚返回。这里有一些伪代码。和我试图达到的要点。带可更新JProgressBar的Java Swing线程

  • 有具有SplashScreen同时加载信息
  • 能够根据SplashScreen
  • 运行多个线程暂停的应用程序有SplashScreen更新,能够尚未退出的进度条,直到所有线程都完成。

启动闪屏

try { 
    SwingUtilities.invokeAndWait(SplashScreen); 
} catch (InterruptedException e) { 
} catch (InvocationTargetException e) { } 

闪屏建设

SplashScreen extends JFrame implements Runnable{ 

    public void run() { 
     //run threads 
     //while updating status bar 
    } 
} 

我已经尝试了很多事情,包括SwingWorkers,使用CountDownLatch的,和其他线程。 CountDownLatch实际上以我想要处理的方式工作,但我无法更新GUI。当使用SwingWorkers时,invokeAndWait基本上无效(这是它们的用途),或者即使使用PropertyChangedListener也不会更新GUI。如果其他人有一些想法,听到他们会很高兴。提前致谢。

我实际上已经准备好发布更好的代码来帮助并找到我的解决方案。我感谢所有帮助过的人。

+1

如果您可以创建并发布[SSCCE](http://SSCCE.org),则您的问题可能会更快更准确地得到解决。 – 2011-03-02 05:49:31

+0

对不起,我正在上床睡觉,因为我张贴了,我所有的都是非常丑陋的代码发布,所以我希望能得到这个想法,如果下面的答案不适合我,我会发布一些真实的代码。感谢您的建议。 – ars265 2011-03-02 13:15:02

回答

0

无需调用invokeAndWait中的框架,但应该像这样更新进度栏状态。

try { 
    SwingUtilities.invokeAndWait(new Runnable() { 
    public void run() { 
//update state of the progress bar here 
    } 
    }); 
} catch (InterruptedException e) { 
} catch (InvocationTargetException e) { } 
+0

谢谢,我会试试看看是否有帮助。 – ars265 2011-03-02 13:13:04

+0

我无法得到这与线程或SwingWorkers一起工作,我用一些更好的代码更新我的问题。感谢您一直以来的帮助。 – ars265 2011-03-03 17:31:47

5

要在后台运行一系列操作并报告进度,请使用SwingWorker

方法background做后台处理。
使用publish方法发布定期状态更新。
替代处理更新的process方法(process始终在EDT上执行)。

progressBar = new JProgressBar(); 
sw = new SwingWorker<Boolean,Integer>() { 
    protected Boolean doInBackground() throws Exception { 
     // If any of the operations fail, return false to notify done() 
     // Do thing 1 
     publish(25); // 25% done 
     // Do thing 2 
     publish(50); // 50% done 
     // Do thing 3 
     publish(75); // 75% done 
     // Do thing 4 
     return true; 
    } 
    protected void process(List<Integer> chunks) { 
     for (Integer i : chunks) 
      progressBar.setValue(i); 
    } 
    protected void done() { 
     try { 
      boolean b = get(); 
      if (b) 
       progressBar.setValue(100); // 100% done 
      else 
       // Notify the user processing failed 
     } 
     catch (InterruptedException ex) { 
       // Notify the user processing was interrupted 
     } 
     catch (ExecutionException ex) { 
       // Notify the user processing raised an exception 
     } 
    } 
}; 

附录:

这可以扩展到多个任务,它只是需要改变你的做法是如何设置的进度条。下面是想到的:

有一个完成计数器数组,每个任务一个。

int[] completions = new int[numTasks]; 
Arrays.fill(completions,0); 

启动SwingWorkers,每个都传递一个索引号。然后processdone方法调用这样的更新整体进度条。

void update(int index, int percComplete) { 
    completions[index] = percComplete; 
    int total = 0; 
    for(int comp: completions) 
     total += comp/numTasks; 
    overallPB.setValue(total); 
} 

(可选)显示每个任务的JProgressBar。

附录2:

如果任务完成时间变化(例如,缓存命中VS高速缓存未命中),你可能需要调查ProgressMonitor。这是一个进度对话框,只有当任务需要超过一些(可配置的,默认的500ms)时间时才会出现。

+0

这似乎并不奏效我需要多个swing工作人员,他们仍然继续执行下一个代码,这就是为什么我提到invokeAndWait()方法,因为我需要它等待,我需要多个SwingWorkers运行,我不想继续,直到所有的工人完成。 – ars265 2011-03-03 17:30:35