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

发布于 2024-10-19 19:01:22 字数 2025 浏览 6 评论 0原文

我试图让我的程序在执行某些操作时在方法内不断更新进度条值。然而,这种情况直到最后才发生,用户界面冻结了。

在查看了与我的问题类似的问题后,我尝试实现已接受的解决方案(使用线程),但我无法让它正常工作。就像他们不在那里一样。

我的程序包含多个类,Main 是 Netbeans 在 JFrame Design 模式下自动创建的类,因此存在某些内容,例如 static void main< /code> 和 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();
   }
}

我评论为我添加...的所有内容都是我根据我在网上看到的教程和答案放置的内容,但似乎没有任何效果,感觉我已经尝试了近一百万次不同的组合...

提前感谢您的帮助。

Am trying to get my program to update the progress bar values constantly within a method while performing some operations. However this does not happen until the end, and the UI freezes.

After looking around to similar questions with my problems, I tried to implement the accepted solutions (Using threads) however I cannot get it to work correctly. Is just like if they where not there.

My program contains several classes, the Main being the one automatically created by netbeans on the JFrame Design mode, so there are certain things such as the static void main and the public Main that am not really sure of some of its contents. Under i will put the snippets of those methods, together with my thread implementation.

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

All the things that I commented as I added... are things that I putted according to tutorials and answers I have seen online, but nothing seems to work and it feels like I have tried close to a million different combinations...

Thanks in advance for helping out.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦萦几度 2024-10-26 19:01:22

这里有一些基础供您查看,如果您可以研究它并理解为什么每段代码在那里,那么我认为这会有所帮助。请随意在评论中提出问题(尽管我现在就要睡觉了!)

示例:

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

Here's some basis for you to look at, if you can study it and understand why every piece of code is there then I think it will help. Feel free to ask questions in a comment (although I'm going to bed right now!)

Example:

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

Two different ways to approach the problem, using SwingWorker instead:

SwingWorker Example 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 Example 2 (not so nice, but interesting nonetheless):

    ....
    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();
    }
    ....
断桥再见 2024-10-26 19:01:22

您的代码有一些问题:(

  • 您创建了 Main 两次,最终等待一个实例并通知另一个实例。
  • 您手动调用 run() 并安排一个线程来执行此操作。 ..

忘记教程,从头开始编写代码,只添加您理解的内容。

There are a few things wrong with your code :(

  • you're creating Main twice, and you end up waiting on one instance and notifying the other.
  • you're manually calling run() as well as schedule a thread to do that too...

forget tutorials, write the code from scratch and only add things to it you understand.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文