【问题标题】:JProgressBar indeterminate threadJProgressBar 不确定线程
【发布时间】:2013-04-11 08:05:46
【问题描述】:

我在创建设置为不确定的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的调用者是如下代码sn-p:

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

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

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

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

编辑: Progress JFrame 打开时没有任何内容,算法正在运行。

【问题讨论】:

  • 您能描述一下您当前的代码有什么问题吗?
  • 进度条不显示,我得到一个异常:线程“AWT-EventQueue-0”中的异常 java.lang.NullPointerException at de.Progress$1.run(Progress.java:63 ) 在 java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:251) 在 java.awt.EventQueue.dispatchEventImpl(EventQueue.java:727) 在 java.awt.EventQueue.access$200(EventQueue.java:103)) ...
  • 好的...没有更多错误...但是:如果我启动线程,它会打开 Progress JFrame,但其中没有内容(没有 JProgressBar)...跨度>
  • 不要将重要的细节添加为 cmets。 Edit your question 并添加信息。请包含一个完整的堆栈跟踪。
  • 没有错误了...在此代码的旧版本中...

标签: java swing nullpointerexception jprogressbar swingutilities


【解决方案1】:

您可能面临 Swing 的并发问题。假设以下代码在 EDT(Event Dispatching Thread)上运行:

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

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

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

然后,仍然在 EDT 上运行(并因此阻止所有 UI 事件,例如重绘、鼠标单击等...),您调用 p.start() 启动 new Thread() 将调用 run() 本身来电

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

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

仍在 EDT 上追求,您致电 boolean successfull = xmlWriter.writeCommonSettingsFromGUI(this);(顺便说一句,“成功”仅以一个“l”结尾)。这将继续阻止 EDT,防止发生重绘并阻止 JProgressBar 自行绘制。最终您将处理 JFrame,但由于所有这些代码都在 EDT 上运行,因此用户将看不到太多进度条,并且 UI 看起来会冻结。

考虑阅读Swing tag wiki(尤其是最后一部分,其中包含 3 个重要链接)。

使用SwingWorker 应该可以帮助您解决这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    相关资源
    最近更新 更多