当前位置: 首页 > 面试题库 >

在循环中使JProgressBar更新值时出现问题(线程)

宗政浩慨
2023-03-14
问题内容

我试图让我的程序在执行某些操作的同时,在一种方法中不断更新进度条的值。但是,这种情况直到最后都不会发生,并且UI冻结。

在解决了与我的问题相关的类似问题之后,我尝试实现了公认的解决方案(使用线程),但是我无法使其正常工作。就像他们不在那里一样。

我的程序包含几个类,它们Main是由netbeans在JFrame 设计 模式下自动创建的,因此某些内容(例如static void main和)并public Main不能真正确定其某些内容。在下面,我将这些方法的摘录以及我的线程实现放在一起。

public class Main extends javax.swing.JFrame implements ActionListener, Runnable{
                                          // I added implements ActLis, Runn.....

...

static Main _this;      // I included this variable

...

public static void main(String args[]) {
        Main m = new Main();                               // Added by me
        new Thread(m).start();                             // Added by me
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new Main().setVisible(true);
            }
        });
 }

...

public Main() {
        initComponents();
        _this = this;        // Added by me
}


...

// I also included these 2 methods in the class

public void actionPerformed(ActionEvent e) {                                    
    synchronized(this){                                                         
        notifyAll();                                                            
    }                                                                           
}

public void run() {                                                             
    try{synchronized(this){wait();}}
    catch (InterruptedException e){}
    progressBar.setValue(50);                                                   
}

...

private void buttonPressed(java.awt.event.MouseEvent evt) {
   for(int i=0; i<=100; i++) {
      for(int j=0; j<=5; j++) {
         // does some work
      }
   run();
   }
}

我评论的所有内容I added...都是我根据在线看到的教程和答案发表的内容,但是似乎没有任何效果,感觉就像我尝试了近百万种不同的组合…

在此先感谢您的帮助。


问题答案:

这是供您查看的一些基础,如果您可以学习它并理解为什么其中每个代码段都存在,那么我认为它将有所帮助。随时在评论中提问(尽管我现在要睡觉了!)

例:

public class ProgressBarDemo extends JFrame {
    private final JProgressBar progressBar = new JProgressBar(0, 100);
    private int progressCounter = 0;

    public ProgressBarDemo() {
        setContentPane(progressBar);
        setPreferredSize(new Dimension(100, 100));
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
        new Thread(new Runnable() {
            public void run() {
                while (progressCounter <= 100) {
                    SwingUtilities.invokeLater(new Runnable() {
                        public void run() {
                            progressBar.setValue(progressCounter++);
                        }
                    });
                    try { Thread.sleep(500); } catch (InterruptedException e) {}
                }
            }
        }).start();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new ProgressBarDemo().setVisible(true);
            }
        });
    }
}

解决问题的两种不同方法,而使用SwingWorker:

SwingWorker示例1:

    ....
    public ProgressBarDemo() {
        setContentPane(progressBar);
        setPreferredSize(new Dimension(100, 100));
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();

        SwingWorker<Integer, Void> worker = new SwingWorker<Integer,Void>() {
            public Integer doInBackground() {
                while (progressCounter <= 100) {
                    setProgress(progressCounter++);
                    try { Thread.sleep(500); } catch (InterruptedException e) {}
                }
                return 0;
            }
        };
        worker.addPropertyChangeListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent event) {
                if ("progress".equals(event.getPropertyName())) {
                    progressBar.setValue((Integer)event.getNewValue());
                }
            }
        });
        worker.execute();
    }
    ....

SwingWorker示例2(虽然不太好,但是很有趣):

    ....
    public ProgressBarDemo() {
        setContentPane(progressBar);
        setPreferredSize(new Dimension(100, 100));
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();

        new SwingWorker<Integer,Integer>() {
            public Integer doInBackground() { 
                while (progressCounter <= 100) {
                    publish(progressCounter++);
                    try { Thread.sleep(500); } catch (InterruptedException e) {}                    
                }
                return 0;
            }
            public void process(List<Integer> progresses) {
                Integer maxProgress = null;
                for (int progress : progresses) {
                    if (maxProgress == null || progress > maxProgress) {
                        maxProgress = progress;
                    }
                }
                progressBar.setValue(maxProgress);
            }
        }.execute();
    }
    ....


 类似资料:
  • 问题内容: 我程序的想法是从以前保存在其他JFrame中的列表中选择一个名称。我想在标签中一个接一个地打印所有名称,它们之间的间隔很小,然后停在其中一个名称上。问题是,如果有多个代码,则无法正常工作。 这是我的代码的一部分: 问题答案: 不要使用循环或。只需使用即可。以下将导致每1000毫秒发生30 次迭代 。您可以相应地调整代码,使其适应每隔毫秒发生一次的情况。 如果需要,您可以在构造函数中设置

  • 我有一个表,我想用另一个表中的值更新该表,我正在使用以下代码: 尽管事实上,表。id是tableA的主键,我不断得到以下错误: 错误代码:1175。您使用的是安全更新模式,并且您试图更新一个没有使用键列禁用安全模式的表,请在“首选项”中切换该选项- 我做错了什么?

  • 问题内容: 我正在尝试使用一些conda环境创建一个docker容器。当我在交互模式下运行容器时 运行没有问题。但是,每当我尝试使用Docker文件执行这些命令时,我都会收到 Docker文件如下所示: 因此似乎使用了sh而不是bash,所以我将Dockerfile编辑为以下内容: 有以下错误 问题答案: 您必须在构建期间使用变量将anaconda添加到PATH中,然后才能在Dockerfile中

  • 问题内容: 我无法更新进度条…这是我的代码 进度栏状态仅在线程末尾更新。有人能帮我吗?? 问题答案: 谢谢大家 我这样解决了

  • 问题内容: 我知道该主题已经在许多问题上得到了解答,但仍然无法解决。 我只想 在提取 大型xml文件的 某些内容 时 更新progressBar 。我认为在另一个线程中使用耗时的循环就足够了,但是?。我设法得到的是ProgressBar要么根本不显示,要么在关闭之前最后进行更新。 在启动该应用程序附近的某个地方,我有: 在显示和更新带有JProgressBar的JDialog时: 所以我有这个 m

  • 我在循环节点时遇到了麻烦。我有一些工作示例,但是XML布局略有不同。 XML 我可以得到一个家庭的列表,但我需要得到每个家庭下的标签(如“喜欢在外面玩”)之间的随机信息列表。到目前为止,我只能得到一份姓氏的名单。 XSLT 只是不知道为什么这不起作用。