基本不确定进度条使用情况

时间:2012-05-04 03:42:48

标签: java swing progress-bar swingworker jprogressbar

我只是想在进行长时间下载时在框架的左下角设置一个不确定的JProgressBar动画。

我查看了许多教程,其中没有一个对我很清楚。我只是想在后台下载文件时让它具有动画效果。我尝试过这种方式的每种方式都没有为进度条设置动画,直到完成下载后

我需要帮助知道下载()调用的位置。

class MyFunClass extends JFrame {
  JProgressBar progressBar = new JProgressBar();

  public void buttonClicked() {
    progressBar.setVisible(true);
    progressBar.setIndeterminate(true);

    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        progressBar.setIndeterminate(true);
        progressBar.setVisible(true);

        // Do I do my download() in here??

    }});

    // Do download() here???
    progressBar.setVisible(false);
  }
}

提前致谢!



解决方案

编辑:对于那些将来遇到类似问题的人来说,这是基本问题的基本解决方案。这不是我的代码,而是一般草图。在buttonClicked()内:

public void buttonClicked() {
  class MyWorker extends SwingWorker(String, Object) {
     protected String doInBackground() {
       progressBar.setVisible(true);
       progressBar.setIndeterminate(true);

       // Do my downloading code
       return "Done."
     }

     protected void done() {
        progressBar.setVisible(false)
     }
  }

  new MyWorker().execute();

}

1 个答案:

答案 0 :(得分:9)

您当前的代码显示没有创建后台线程,而是显示您尝试在Swing线程 中排除代码 Swing线程中没有&#39对这个问题有意义(虽然有时你可能想要这样做,但是再次,不是在这里)。成功的唯一方法是使用后台线程。标准Oracle JProgressBar tutorialConcurrency in Swing完成了所有这些工作。

基本的是你必须从Swing Thread更新JProgressBar才能在后台线程中执行长时间运行的进程,例如SwingWorker对象提供的进程。我们在这里查看的内容太多了,所以我所能做的就是提供一个链接,但是一旦您查看了教程,我们很乐意帮助您了解详细信息。如果您仍然遇到问题,请查看教程并回答您的具体问题。

编辑1
你说:

  

我可以在buttonClicked()函数中创建一个新的线程对象吗?

是的,您可以在buttonClicked() 方法中创建一个SwingWorker对象并在那里执行。

  

问题是我拥有我开发GUI所需的所有功能的API和库,并且似乎是一个在线程中包装该函数调用的长途解决方法。

很抱歉,但我不知道你在这里说什么,或者你认为线程会导致什么问题。 {em}必须buttonClicked()方法必须在EDT上运行,而不是在后台线程中运行。

另请注意,在我的大多数更复杂的Swing GUI中,我经常在不同的(模型)对象中进行文件下载,并在GUI对象的静态(控件)中创建我的SwingWorker(视图)。以这种方式执行它可能看起来更复杂,但是当我这样做时,它更容易调试,维护和增强我的程序,尤其是在以这种方式执行时, 很多 我大量使用接口来允许我单独测试所有程序组件。

编辑2
对您的解决方案发布的一些更正。你发布了:

public void buttonClicked() {
  class MyWorker extends SwingWorker(String, Object) {
     protected String runInBackground() {
       progressBar.setVisible(true);
       progressBar.setIndeterminate(true);

       // ...

有问题

  • 它是doInBackground(),而不是runInBackground()
  • 但更重要的是,你在后台线程中进行Swing调用,这是永远不应该做的事情(除非调用是线程安全的,即便如此......)。

所以改变它:

public void buttonClicked() {
  progressBar.setVisible(true);
  progressBar.setIndeterminate(true);
  class MyWorker extends SwingWorker<String, Void> {
     protected String doInBackground() {

       // ...