JProgressBar not triggering propertyChange on setProgress

后端 未结 3 2022
再見小時候
再見小時候 2020-12-22 06:38

I\'ve read many different articles about JProgressBar...including the dodgy code found over at Java; here.

Most indicate you need a SwingWorker to get things happeni

相关标签:
3条回答
  • 2020-12-22 06:49

    If you want listeners to be called immediately, you can try the following (which worked for me):

    setProgress(1);
    firePropertyChange("progress", 0, 1);
    
    0 讨论(0)
  • 2020-12-22 07:06

    Yeah, so I should have read the Javadocs better;

    Because PropertyChangeListeners are notified asynchronously on the Event Dispatch Thread multiple invocations to the setProgress method might occur before any PropertyChangeListeners are invoked. For performance purposes all these invocations are coalesced into one invocation with the last invocation argument only.

    For example, the following invokations:
    setProgress(1);
    setProgress(2);
    setProgress(3);
    might result in a single PropertyChangeListener notification with the value 3.

    I.E. my assumption that setProgress was firing too quickly was correct. A ProgressMonitor might be a better solution. I've confirmed this with the SSCCE and my program, both are simply firing setProgress too quickly and as a result, only the last value passed to setProgress is being passed through to the PropertyChange event.

    0 讨论(0)
  • 2020-12-22 07:09

    This isn't an answer but a demonstration sscce, to show you just what I meant:

    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    import java.util.Random;
    
    import javax.swing.*;
    
    public class TestProgBar {
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                ProgBar progBar = new ProgBar();
    
    
                // **** this is key and where your code may be deficient ***
                JProgressBar prog = progBar.getProg(); 
    
    
                progBar.execute();
                JOptionPane.showMessageDialog(null, prog);
             }
          });
       }
    }
    
    class ProgBar extends SwingWorker<Void, Void> {
       private JProgressBar loginProg = new JProgressBar();
    
       public ProgBar() {
          addPropertyChangeListener(new PropertyChangeListener() {
    
             @Override
             public void propertyChange(PropertyChangeEvent evt) {
                if ("progress".equals(evt.getPropertyName())) {
                   int value = (Integer) evt.getNewValue();
                   System.out.println("propertyChange called with: " + value);
                   loginProg.setValue(value);
                }
             }
          });
    
          loginProg.setStringPainted(true);
          loginProg.setValue(0);
          setProgress(0);
       }
    
       public JProgressBar getProg() {
          return loginProg;
       }
    
       @Override
       public Void doInBackground() throws InterruptedException {
          int count = 0;
          int max = 5;
          Random random = new Random();
    
          // simulate uploading files
          while (count < 100) {
             count += random.nextInt(max);
             if (count > 100) {
                count = 100;
             }
             setProgress(count);
             Thread.sleep(400);
          }
          // for (Folder f : folders) {
          // setProgress((int) Math.min(((double) count / folders.length) * 100.0,
          // 100.0));
          // }
          return null;
       }
    
       @Override
       public void done() {
          System.out.println("Done called.");
          setProgress(100);
          loginProg.setValue(100);
       }
    }
    

    Again, this code works fine, suggesting that the code you've loaded does not show the error. You need to do further work isolating the error and getting it into code so we can test it.

    0 讨论(0)
提交回复
热议问题