JProgressBar不确定线程

时间:2013-04-11 08:05:46

标签: java swing nullpointerexception jprogressbar swingutilities

我在创建设置为不确定的JProgressBar时遇到问题。 以下代码是我对JProgressBar的实现,并从另一个类调用/构造:

public class Progress implements Runnable
{
  private JFrame frameProgress;
  private JProgressBar progressBar;

  public Progress(String title, String message)
  {
    try
    {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    }
    catch (Exception e)
    {
      GlobalVariables.LOGGING_logger.error("Error instatiating progress bar.",
          e);
    }

    UIManager.put("ProgressBar.selectionForeground", Color.black);
    UIManager.put("ProgressBar.selectionBackground", Color.black);

    this.frameProgress = new JFrame(title);
    this.frameProgress.setIconImage(GlobalVariables.GUI_icon.getImage());
    this.frameProgress.setSize(300, 60);
    this.frameProgress.setLocation(16, 16);
    this.progressBar = new JProgressBar();
    this.progressBar.setStringPainted(true);
    this.progressBar.setString(message);
    this.progressBar.setIndeterminate(true);
    this.frameProgress.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.frameProgress.add(this.progressBar);
    this.frameProgress.setResizable(false);
    this.frameProgress.setVisible(true);
  }

  public void start()
  {
    new Thread(this).start();
  }

  public void close()
  {
    this.frameProgress.dispose();
    this.frameProgress = null;
    this.progressBar = null;
  }

  @Override
  public void run()
  {
    SwingUtilities.invokeLater(new Runnable()
    {
      public void run()
      {
        // do nothing, because progress bar is indeterminate
      }
    });
  }
}

此JProgressBar的调用者是以下代码片段:

    Progress p = new Progress("bla", "blub");
    p.start();
    boolean successfull = xmlWriter.writeCommonSettingsFromGUI(this);
    p.close();

现在我希望,xmlWriter.writeCommonSettingsFromGUI(this);正在做某事时,JProgressBar会向用户显示,并且在算法运行时正在运行。

我怎样才能做到这一点?我对其他许多论坛中的线程和搜索都不太了解,但我没有找到任何答案。

请帮助我,并提前感谢你;)

编辑: 进度JFrame打开时没有内容,算法正在运行。

1 个答案:

答案 0 :(得分:3)

您可能正面临Swing的并发问题。假设以下代码在EDT(事件调度线程)上运行:

Progress p = new Progress("bla", "blub");

最终,这将打开一个带有进度条的JFrame。

  • 我会考虑使用JDialog代替JFrame
  • 我不会强制JFrame的大小,而是调用pack()

然后,仍然在EDT上运行(从而阻止所有UI事件,例如重绘,鼠标点击等等),你调用p.start()启动new Thread()将调用{ {1}}本身称之为

run()

除了在EventQueue上推送一个额外的事件之外,它基本上不会做任何事情,它将在所有当前待处理的事件之后运行。这个事件将运行......“没什么”,因为你的Runnable只是空的。新线程几乎立即死亡。所以这些代码都没用。

仍在追求EDT,你打电话给SwingUtilities.invokeLater(new Runnable() { public void run() { // do nothing, because progress bar is indeterminate } }); (顺便说一下,“成功”只有一个'l'结束)。这将继续阻止EDT,防止重绘发生并阻止boolean successfull = xmlWriter.writeCommonSettingsFromGUI(this);绘制自身。最终你会处理JFrame,但由于所有这些代码都在EDT上运行,用户将看不到很多进度条,UI看起来会被冻结。

考虑阅读Swing tag wiki(特别是最后一部分有3个重要链接)。

使用JProgressBar可以帮助您解决此问题。