栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

无法从SwingWorker类获取JProgressBar进行更新

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

无法从SwingWorker类获取JProgressBar进行更新

您是

doInBackground()
直接从代码中调用,类似于
run()
在可运行对象中直接调用。这意味着您的代码实际上并没有在后台线程上运行,因此您很可能会用长时间运行的代码破坏事件线程,从而导致Swing
GUI和进度条无法更新。

解决方案:不要这样做。

execute()
当您希望它运行时,请呼叫它的工人。

如果您需要进一步的帮助,则首先需要帮助我们。您了解您已经发布了大量的代码,其中大多数代码与您的问题完全无关,而且肯定比您要求志愿者通过的代码还要多。


编辑
您似乎也正在直接从EDT调用代码,这些代码应留在此处的工作线程中:

        signalSimulator.execute();        // ************* all these signalSimulator calls below ***********        if (rdbtnSineWave.isSelected()) {data = signalSimulator.generateSineWave(numOfdataPoints,      noiseAmp, offset);data = signalSimulator.addAnomalies(data, numOfLocalSpikes,      numOfExpSpikes);        } else { // Linear signal is selecteddata = signalSimulator.generateLinearSignal(numOfdataPoints,      noiseAmp, slope, offset);data = signalSimulator.addAnomalies(data, numOfLocalSpikes,      numOfExpSpikes);        }        signalSimulator.writeLogFile(path, ".txt", data);

您似乎还只创建了 一个 不合适的工作程序对象,因为您不能重复使用SwingWorker对象。

我建议您仅在需要时创建SwingWorker对象,然后将需要哪种信号的信息传递到其构造函数中。这样,可以从SwingWorker所属的doInBackground方法中调用上述方法。

例如,

signalSimulator = SignalSimulator(rdbtnSineWave.isSelected())signalSimulator.addPropertyChangeListener(...);signalSimulator.execute();

请注意,您在已发布的代码中还存在其他一些不相关的重大问题,但是必须在其他时间解决,但它们包括使用null布局和setBounds,这几乎总是一个非常糟糕的主意。


编辑

再次澄清一下,您的主要问题是您正在Swing事件线程上调用长时间运行的代码。仅仅因为方法位于您的Worker类中并不意味着调用它会自动使它在后台线程上运行。保证这一点的唯一方法是在您的

doInBackground()
方法中调用代码。同样,您想要做的是在
需要时 创建新的辅助对象,例如,在某个ActionListener内部,并在创建该辅助对象
将所有需要运行的信息传递给该辅助对象。然后添加您的PropertyChangeListener,然后添加您
.execute()
的工作程序。这样做,我敢打赌您的代码会更好。


编辑
例如

import java.awt.event.*;import java.beans.PropertyChangeEvent;import java.beans.PropertyChangeListener;import java.util.Random;import java.util.concurrent.ExecutionException;import javax.swing.*;public class ProgressExampleGui {   private JPanel mainPanel = new JPanel();   private JProgressBar progressBar = new JProgressBar();   private JButton pressMeBtn  = new JButton(new MyAction("Press Me", KeyEvent.VK_P, this));   public ProgressExampleGui() {      progressBar.setStringPainted(true);      progressBar.setString("");      mainPanel.add(pressMeBtn);      mainPanel.add(progressBar);   }   public void setProgress(int progress) {      progressBar.setValue(progress);      progressBar.setString(progress + "%");   }   public JComponent getMainComponent() {      return mainPanel;   }   public void setEnabled(boolean enabled) {      pressMeBtn.setEnabled(enabled);   }   private static void createAndShowGui() {      ProgressExampleGui progExampleGui = new ProgressExampleGui();      Jframe frame = new Jframe("Progress Example");      frame.setDefaultCloseOperation(Jframe.DISPOSE_ON_CLOSE);      frame.getContentPane().add(progExampleGui.getMainComponent());      frame.pack();      frame.setLocationByPlatform(true);      frame.setVisible(true);   }   public static void main(String[] args) {      SwingUtilities.invokeLater(new Runnable() {         public void run() { createAndShowGui();         }      });   }}@SuppressWarnings("serial")class MyAction extends AbstractAction {   private ProgressExampleGui gui;   public MyAction(String name, int mnemonic, ProgressExampleGui gui) {      super(name);      putValue(MNEMONIC_KEY, mnemonic);      this.gui = gui;   }   @Override   public void actionPerformed(ActionEvent e) {      AbstractButton source = (AbstractButton) e.getSource();      gui.setProgress(0);      source.setEnabled(false);      MyWorker myWorker = new MyWorker();      myWorker.addPropertyChangeListener(new WorkerPropChngListener(gui));      myWorker.execute();   }}class WorkerPropChngListener implements PropertyChangeListener {   private ProgressExampleGui gui;   public WorkerPropChngListener(ProgressExampleGui gui) {      this.gui = gui;   }   @Override   public void propertyChange(PropertyChangeEvent pcEvt) {      MyWorker myWorker = (MyWorker) pcEvt.getSource();      if ("progress".equals(pcEvt.getPropertyName())) {         int progress = ((Integer)pcEvt.getNewValue()).intValue();         gui.setProgress(progress);      }      if (SwingWorker.Statevalue.DONE.equals(pcEvt.getNewValue())) {         try { myWorker.get();         } catch (InterruptedException | ExecutionException e) { e.printStackTrace();         }         gui.setEnabled(true);      }   }}class MyWorker extends SwingWorker<Void, Void> {   private static final int MAX_INCR = 8;   private static final long SLEEP_TIME = 200;   private static final int MAX_VALUE = 100;   private int value = 0;   private Random random = new Random();   @Override   protected Void doInBackground() throws Exception {      while (value < MAX_VALUE) {         value += random.nextInt(MAX_INCR);         value = Math.min(value, MAX_VALUE);         Thread.sleep(SLEEP_TIME);         setProgress(value);      }      return null;   }}

编辑
关于新代码,您有两个 主要 问题:

查看数据输出的结果:

Value in setProgress: 0.0Value in setProgress: 0.001Value in setProgress: 0.002Value in setProgress: 0.003Value in setProgress: 0.004Value in setProgress: 0.005Value in setProgress: 0.006Value in setProgress: 0.007Value in setProgress: 0.008Value in setProgress: 0.009Value in setProgress: 0.01Value in setProgress: 0.011Value in setProgress: 0.012Value in setProgress: 0.013Value in setProgress: 0.014Value in setProgress: 0.015Value in setProgress: 0.016Value in setProgress: 0.017Value in setProgress: 0.018Value in setProgress: 0.019Value in setProgress: 0.02Value in setProgress: 0.021Value in setProgress: 0.022Value in setProgress: 0.023Value in setProgress: 0.024Value in setProgress: 0.025Value in setProgress: 0.026Value in setProgress: 0.027Value in setProgress: 0.028Value in setProgress: 0.029

按照这样的步伐,当下一个冰河时代到来时,您的进度值将达到1,并导致PropertyChangeListener和JProgressBar发生明显变化。因此,首先,改变您的睡眠时间,并将您的大量数字更改为更合理的数字。

接下来,对重要变量进行阴影处理,尤其是JProgressBar变量progressBar。在这里声明它并在类中对其进行初始化:

public class ProgressBarTest implements PropertyChangeListener {   private Jframe frame;   private JButton btnRun;   static JProgressBar progressBar = new JProgressBar(0, 100);

附带说明一下,绝对不应声明此变量

static
,但这不是当前问题的原因。原因是实际上您在初始化方法的其他地方 重新声明
了相同的变量,然后将此新对象添加到GUI中:

private void initialize() {  frame = new Jframe();  // .....  JProgressBar progressBar = new JProgressBar();  // .....  frame.getContentPane().add(progressBar);

请理解,这个新的progressBar变量引用了完全不同的JProgressBar,因此,如果您推进在类中创建的对象的值,则GUI将不显示任何内容,因为它显示的是完全不同的对象。为了解决这个问题,**不要在initialize方法中重新声明和初始化新变量。而是使用在类中创建的对象。

代码的其他问题:您经常使用null布局和setBounds。这将向所有人表明您是一名新手Swing程序员,因为这意味着您喜欢创建很难升级的刚性程序,并且在所有系统上看起来都不太好。而是使用布局管理器。例如,这是您的代码,其中有一些更改,所有更改都由注释指出:

import java.awt.*;import java.awt.event.*;import java.beans.*;import javax.swing.*;//!! no need to implement PropertyChangeListener//!! public class ProgressBarTest implements PropertyChangeListener {public class ProgressBarTest2 {   private Jframe frame;   private JButton btnRun;   // !! this shouldn't be static!   // !! static JProgressBar progressBar = new JProgressBar(0, 100);   private JProgressBar progressBar = new JProgressBar(0, 100); // !!   public static void main(String[] args) {      EventQueue.invokeLater(new Runnable() {         public void run() { try {    UIManager          .setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");    ProgressBarTest2 window = new ProgressBarTest2();    window.frame.setVisible(true); } catch (Exception e) {    e.printStackTrace(); }         }      });   }   public ProgressBarTest2() {      initialize();   }   private void initialize() {      frame = new Jframe();      // !!frame.setBounds(100, 100, 450, 300);      frame.setDefaultCloseOperation(Jframe.EXIT_ON_CLOSE);      //!! frame.getContentPane().setLayout(null); //!! never use null layouts      frame.setResizable(false);      // !! don't create a shadowed variable      // !! JProgressBar progressBar = new JProgressBar();      progressBar.setAlignmentX(Component.RIGHT_ALIGNMENT);      //!! progressBar.setBounds(0, 252, 444, 20);      progressBar.setStringPainted(true);      //!! frame.getContentPane().add(progressBar);      frame.getContentPane().add(progressBar, BorderLayout.SOUTH);      btnRun = new JButton("Start Long Run"); //!! no shadowing      //!! btnRun.setBounds(167, 214, 159, 31);      JPanel panel = new JPanel(); //!!      panel.setPreferredSize(new Dimension(450, 300)); //!!      panel.setLayout(new GridBagLayout()); //!!      panel.add(btnRun); //!!      frame.getContentPane().add(panel, BorderLayout.CENTER); //!!      btnRun.addActionListener(new ActionListener() {         @Override         public void actionPerformed(ActionEvent e) { longRun();         }      });      //!!      frame.pack();      frame.setLocationRelativeTo(null);      frame.setVisible(true);   }   private void longRun() {    //!! use a more realistic value, one that should show change in listener      //!! LongRunner longRunner = new LongRunner(100000);      LongRunner2 longRunner = new LongRunner2(10000);        longRunner.addPropertyChangeListener(new PropertyChangeListener() {         @Override         public void propertyChange(PropertyChangeEvent evt) { if ("progress".equals(evt.getPropertyName())) {    int progress = (int) evt.getNewValue();    System.out.println("Value in propertyChangeListener: "          + progress);    progressBar.setValue(progress); }         }      });      longRunner.execute();   }   // !! @Override // !! not needed   // public void propertyChange(PropertyChangeEvent evt) {   // }}class LongRunner2 extends SwingWorker<Integer, Double> {   private static final long SLEEP_TIME = 15; // !!   int numOfPoints;   double progress;   public LongRunner2(int numOfPoints) {      this.numOfPoints = numOfPoints;      this.progress = 0;   }   private void runLong(int bigNum) {      for (int i = 0; i < bigNum; i++) {         try { // !! quicker turn-over so that our bigNum can change // in a realistic way // !! Thread.sleep(100); Thread.sleep(SLEEP_TIME);// !!         } catch (InterruptedException e) { e.printStackTrace();         }         progress = (((double) i * 100) / (double) bigNum);         setProgress((int) progress);         // !! System.out.println("Value in setProgress: " + progress); //!! This will slow us down      }   }   @Override   protected Integer doInBackground() throws Exception {      runLong(numOfPoints);      return null;   }}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/595247.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号