没有JButton和PropertyChangeListener的JProgressBar

我是JProgressBar新手,也是OOPs概念的新手(学习它)并阅读了很多文章,并尽我所能去学习它。 显示的所有示例都有一个按钮,可以在其中开始进度但是如何创建方法以便在调用方法时它会开始进度?

这是我的代码

 import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.SwingWorker; public class ProgressDemo { JProgressBar ProgressBar; Task task; boolean done = false; class Task extends SwingWorker { @Override public Void doInBackground() { Random random = new Random(); int progress = 0; setProgress(0); while (progress < 100) { try { Thread.sleep(random.nextInt(1000)); } catch (InterruptedException ignore){} progress += random.nextInt(10); setProgress(Math.min(progress, 100)); } return null; } @Override public void done() { done = true; } } public void propertyChange(PropertyChangeEvent evt) { if(!done) { int progress = task.getProgress(); if(progress==0) { ProgressBar.setIndeterminate(true); } else { ProgressBar.setIndeterminate(false); ProgressBar.setString(null); ProgressBar.setValue(progress); } } } //I want to make a method here, so that it can be called when ever I want public void ExecuteTask() { task = new Task(); task.execute(); } public static void main(String[] args) { JFrame MainScreen = new JFrame(); JPanel MainPanel = new JPanel(); ProgressBar = new JProgressBar(0, 100); ProgressBar.setValue(0); ProgressBar.setStringPainted(false); MainPanel.add(ProgressBar); MainScreen.getContentPane().add(MainPanel); MainScreen.setVisible(true); } } 

当我调用ExecuteTask()方法时,我的jProgressBar没有监听。 如何让它调用ExecuteTask()并执行task和jProgressBar监听呢?

您永远不会将PropertyChangeListener添加到任何内容中,因此,由于没有任何内容正在侦听SwingWorker的更改,因此其更改永远不会传输到JProgressBar。 解决方案:在创建后将PropertyChangeListener添加到SwingWorker。 事实上 – 你没有PropertyChangeListener,只是一个从你没有使用过的方法(??)。

其他问题:学习OOP,至少学习Swing 之前的基础知识。 你不应该像在这里一样使用静态字段。

一些体面的链接:

  • 无法从SwingWorker类获取JProgressBar更新
  • 了解Java ExecutorService :我最近的最爱。
  • JProgressBar无法正常工作 :查看MadProgrammer的几个链接。 他是这方面的专家,几乎任何Swing

 import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Random; import java.util.concurrent.ExecutionException; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.SwingWorker; import javax.swing.Timer; @SuppressWarnings("serial") public class ProgressDemo extends JPanel { private JProgressBar progressBar = new JProgressBar(0, 100); private Task task; boolean done = false; public ProgressDemo() { progressBar.setStringPainted(true); progressBar.setIndeterminate(true); add(progressBar); } class Task extends SwingWorker { @Override public Void doInBackground() { Random random = new Random(); int progress = 0; setProgress(0); while (progress < 100) { try { Thread.sleep(random.nextInt(1000)); } catch (InterruptedException ignore) { } progress += random.nextInt(10); setProgress(Math.min(progress, 100)); } return null; } @Override public void done() { done = true; } } private class TaskListener implements PropertyChangeListener { @Override public void propertyChange(PropertyChangeEvent evt) { if ("progress".equals(evt.getPropertyName())) { int progress = task.getProgress(); progressBar.setIndeterminate(false); progressBar.setString(null); progressBar.setValue(progress); } if (SwingWorker.StateValue.DONE == evt.getNewValue()) { // always need to know when the SW is done // so we can call get() and trap exceptions try { task.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } } } } // I want to make a method here, so that it can be called when ever I want public void executeTask() { task = new Task(); task.addPropertyChangeListener(new TaskListener()); task.execute(); } public static void main(String[] args) { JFrame mainScreen = new JFrame(); mainScreen.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); final ProgressDemo demoPanel = new ProgressDemo(); mainScreen.getContentPane().add(demoPanel); mainScreen.pack(); mainScreen.setLocationByPlatform(true); mainScreen.setVisible(true); // just for yucks, let's wait 3 seconds before calling executeTask() int delay = 3 * 1000; new Timer(delay, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { demoPanel.executeTask(); // stop timer ((Timer) e.getSource()).stop(); } }).start(); } }