java 基本的不确定 JProgress Bar 用法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10442406/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 01:04:05  来源:igfitidea点击:

Basic Indeterminate JProgress Bar Usage

javaswingprogress-barswingworkerjprogressbar

提问by Bill VB

I simply want to have an indeterminate JProgressBar animate in the bottom left corner of my frame when a long download is being done.

我只想在完成长时间下载时在我的框架的左下角有一个不确定的 JProgressBar 动画。

I've looked through many tutorials, none of which are clear to me. I simply want to have it animate while the file is being downloaded in the background. Each way I've tried this, it doesn't animate the progress bar until afterthe download is done.

我看过很多教程,但没有一个对我来说很清楚。我只想在后台下载文件时让它动画。每个我试过这种方式,它不会动画进度条,直到下载完成。

I need help knowing where to place my download() call.

我需要帮助知道在哪里放置我的 download() 调用。

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);
  }
}

Thanks in advance!

提前致谢!





Solution

解决方案

Edit:For those who have a similar issue to me in the future, this is the basic solution for a basic problem. This isn't my code verbatim, but a general sketch. Inside buttonClicked():

编辑:对于那些将来与我有类似问题的人,这是一个基本问题的基本解决方案。这不是我的逐字代码,而是一般草图。内部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();

}

回答by Hovercraft Full Of Eels

Your current code shows no creation of a background thread, but rather it shows you trying to queue code on the Swing thread from withinthe Swing thread which doesn't make sense for this problem (although there are occasional times when you may want to do this, but again, not here). The only way for this to succeed is to use a background thread. The standard Oracle JProgressBar tutorialand Concurrency in Swinggoes through all of this.

您当前的代码没有显示后台线程的创建,而是显示您尝试Swing 线程的 Swing 线程上排队代码,这对这个问题没有意义(尽管有时您可能想要这样做这个,但同样,不是在这里)。成功的唯一方法是使用后台线程。标准 Oracle JProgressBar 教程Swing 中的并发贯穿了所有这些。

The basic thing is that you must update the JProgressBar from the Swing Thread will doing your long-running process in the background thread, such as that provided by a SwingWorker object. There are too many details for us to review all here, and so all I can do is provide a link, but we'll be happy to help you understand the details once you review the tutorials. Just check the tutorials and come on back with your specific questions if you're still stuck.

基本的事情是你必须从 Swing 线程更新 JProgressBar 将在后台线程中执行你的长时间运行的进程,例如由 SwingWorker 对象提供的进程。此处的详细信息太多,无法一一查看,因此我所能做的就是提供一个链接,但是一旦您查看了教程,我们将很乐意帮助您了解详细信息。只需查看教程,如果您仍然遇到问题,请返回您的具体问题。

Edit 1
You state:

编辑 1
您声明:

can I just create a new thread object within the buttonClicked() function?

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

Yes, you can create a SwingWorker object inside of the buttonClicked()methodand execute it there.

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

The thing is I have my API and library of all the functionality that I'm developing the GUI to, and it seems like a longwinded workaround to wrap that function call in a thread.

问题是我有我的 API 和我正在开发 GUI 的所有功能的库,这似乎是一个冗长的解决方法来将该函数调用包装在一个线程中。

Sorry, but I have no idea what you're saying here or what issues you think threading will cause. The buttonClicked()method likely mustrun on the EDT and not in a background thread.

抱歉,我不知道你在这里说什么,也不知道你认为线程会导致什么问题。该buttonClicked()方法可能必须在 EDT 上运行,而不是在后台线程中运行。

Also note that in most of my more complex Swing GUI's, I often do my file downloading in a different (model) object and create my SwingWorker in a different object still (control) from the GUI object (the view). It may seem more complicated to do it this way, but it's a loteasier to debug, maintain and enhance my program when I do it this way, especially when I heavily use interfaces to allow me to test all program components in isolation.

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

Edit 2
Some corrections to your solution post. You posted:

编辑 2
对您的解决方案帖子进行一些更正。你发帖:

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

       // ...

which has problems

这有问题

  • it's doInBackground(), not runInBackground()
  • but more importantly, you're making Swing calls from within a background thread, something that should never be done (unless the call is thread safe, and even then...).
  • doInBackground(),不是runInBackground()
  • 但更重要的是,您正在后台线程中进行 Swing 调用,这是永远不应该做的事情(除非调用是线程安全的,即使如此……)。

So change it:

所以改变它:

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

       // ...