使用 JProgressBar 运行 JFrame

2022-01-24 00:00:00 java swing jframe jprogressbar
public void myMethod {
   MyProgessBarFrame progFrame = new MyProgressBarFrame(); // this is a JFrame
   progFrame.setVisible(true); // show my JFrame loading

   // do some processing here while the progress bar is running
   // .....

   progFrame.setvisible(false); // hide my progress bar JFrame
} // end method myMethod

我有上面的代码.但是当我运行它时,在我关闭进度条 JFrame 之前,do some processing 部分不会处理.

I have the code above. But when I run it, the do some processing section does not process until I close the progress bar JFrame.

如何在 do 处理部分显示我的进度条并告诉 Java 继续?

How will I show my progress bar and tell Java to continue in the do processing section?

推荐答案

您遇到了并发和 Swing 的经典问题.您的问题是您正在主 Swing 线程、EDT 或事件调度线程上执行长时间运行的任务,这将锁定线程直到进程完成,阻止它执行包括与用户交互在内的任务和绘制 GUI 图形.

You've got a classic problem with concurrency and Swing. Your problem is that you're doing a long-running task on the main Swing thread, the EDT or Event Dispatch Thread, and this will lock the thread until the process is complete, preventing it from doing its tasks including interacting with the user and drawing GUI graphics.

解决方案是在后台线程中执行长时间运行的任务,例如 SwingWorker 对象提供的线程.然后您可以通过 SwingWorker 的发布/进程对更新进度条(如果是决定性的).有关这方面的更多信息,请阅读这篇关于Swing 中的并发 的文章.

The solution is to do the long-running task in a background thread such as that given by a SwingWorker object. Then you can update the progressbar (if determinant) via the SwingWorker's publish/process pair. For more on this, please read this article on Concurrency in Swing.

例如,

public void myMethod() {
  final MyProgessBarFrame progFrame = new MyProgessBarFrame();
  new SwingWorker<Void, Void>() {
     protected Void doInBackground() throws Exception {

        // do some processing here while the progress bar is running
        // .....
        return null;
     };

     // this is called when the SwingWorker's doInBackground finishes
     protected void done() {
        progFrame.setVisible(false); // hide my progress bar JFrame
     };
  }.execute();
  progFrame.setVisible(true);
}

此外,如果这是从另一个 Swing 组件显示的,那么您可能应该显示一个模态 JDialog 而不是 JFrame.这就是为什么我在 SwingWorker 代码之后 在窗口上调用 setVisible(true) 的原因——这样如果它是一个模态对话框,它就不会阻止 SwingWorker 被执行.

Also, if this is being displayed from another Swing component, then you should probably show a modal JDialog not a JFrame. This is why I called setVisible(true) on the window after the SwingWorker code -- so that if it is a modal dialog, it won't prevent the SwingWorker from being executed.

相关文章