1

我正在尝试为我的大型 Swing 程序添加一个精美的InfiniteProgressPanel作为 GlassPane。但是,它没有出现。它看起来类似于:

...
InfiniteProgressPanel glassPane = new InfiniteProgressPanel();
setGlassPane(glassPane);
...
glassPane.start();
doSomeStuff();
glassPane.stop();
...

我相信它与它要掩盖的长进程在同一个线程中运行。我承认,我对线程的了解还不够,我可能应该弄清楚如何在单独的线程中运行 InfiniteProgressPanel GlassPane,以及在它自己的线程中运行长进程。

4

3 回答 3

4

务必:

  • 在后台线程中运行所有长时间运行的代码。这是必须的。

    听起来很棒!我该怎么做?将所有长时间运行的代码封装在 .invokeLater 方法中?那应该是 SwingUtilities.invokeLater 还是 EventQueue.invokeLater?无论如何,有什么区别?

    • 不,通过使用SwingUtilities.invokeLater(new MyRunnable)你做的恰恰相反——你保证将在 Swing 事件线程上调用长时间运行的代码——这与你想要的完全相反。而是使用 SwingWorker 的doInBackground()方法来运行长时间运行的代码。SwingUtilities.invokeLater关于您的第二点,和之间没有任何区别EventQueue.invokeLater
  • 在 Swing 事件线程上进行大多数 Swing 调用,这也是必须的。

    极好的!再说一次,我该怎么做?和上面一样吗?

    • 通过SwingUtilities.invokeLater(new MyRunnable)如上所述使用,或者如果您使用的是 SwingWorker,则使用其发布/处理方法对,因为 SwingWorker 教程将向您展示。
  • 调用setVisible(true)您的玻璃窗格,因为根据 JRootPane API,默认情况下所有玻璃窗格都是不可见的。

    Romain Guy 的 InfiniteProgressPanel 似乎不需要 setVisible(true)。它在调用 InfiniteProgressPanel.start() 方法时出现。

    • 这个我不熟悉,有链接吗?
于 2015-01-23T22:34:51.130 回答
2

线程本身是同一程序中的不同进程。

在 java 中,有许多不同的线程类型,而您需要的一种是SwingWorker.

来自 Oracle 的文档的定义/使用是:

当 Swing 程序需要执行一个长时间运行的任务时,它通常使用其中一个工作线程,也称为后台线程。在工作线程上运行的每个任务都由 javax.swing.SwingWorker 的一个实例表示。SwingWorker 本身是一个抽象类;您必须定义一个子类才能创建 SwingWorker 对象;匿名内部类对于创建非常简单的 SwingWorker 对象通常很有用。

如您所见,这就是您所需要的;一个后台线程。


final InfiniteProgressPanel glassPane;

...

class GlassPaneHandler extends SwingWorker<String, Object> {
    @Override
   public String doInBackground() {
       glassPane.start();
       return setUpPaneAndStuff();
   }

    @Override
   protected void done() {
       try {
           glassPane.stop();
       } catch (Exception e) {  } //ignore
   }

   private void setUpPaneAndStuff() {
       //code
   }
}

...

(new GlassPaneHandler()).execute(); //place this in your code where you want to initiate the pane

有关更多信息,请参阅:http ://docs.oracle.com/javase/8/docs/api/javax/swing/SwingWorker.html

于 2015-01-23T22:34:22.067 回答
1

当您更新一个 Swing UI 时,您需要在 Swing 的事件线程中进行。这包括创建组件或任何类型的进度更新。您可以通过SwingUtilities.invokeLater(Runnable)方法执行此操作。

因此,如果在后台线程中,您应该创建玻璃窗格并通过 invokeLater 显示它。从长期运行的进程线程对玻璃窗格的任何进度更新都应通过 invokeLater 完成。

于 2015-01-23T22:33:02.420 回答