1

I'm writing a small function that will update my ProgressBar and a JLabel base on weighted random integers. The thread is sleeping correctly and the random values are coming through, however, my progress bar and jlabel are not updating.

It is also leaving my GUI unresponsive. It isn't locking my GUI completely (I'm able to click buttons, but it doesn't execute the functions associated with those buttons).

Throwing a print statement in the run() method is not printed out. So I'm thinking it never gets in there.

Here is my method so far:

private void updateProgressBar(int max) {
    final int maxDiamonds = max;
    int i = 0;
    while(i <= max) {
        //get random obstacle found
        final Obstacle o = obstacle.next();
        System.out.println("Obstacle: " + o.getName());
        //get random number of diamonds for obstacle
        int numDiamonds = Integer.parseInt(numFoundDiamonds.next());
        System.out.println("Number of Diamonds: " + numDiamonds);
        //set currentValue for the progress bar
        final int currentValue = i;

        for(int j = o.getRemovalTime(); j >= 0; j--) {
            final int rSecs = j;
            System.out.println("Time remaining to remove: " + rSecs);
            try {
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        progressBar.setString(currentValue + "/" + maxDiamonds);
                        statusLabel.setText("Found " + o.getName() + ". Removing: " + rSecs + " s Remaining.");
                    }
                });
                java.lang.Thread.sleep(1000);
            } catch (InterruptedException e) {
                JOptionPane.showMessageDialog(this, e.getMessage());
            }
        }
        i += numDiamonds;  
    }

}

Perhaps I'm overlooking something simple.

I can also provide more code regarding the other classes used, but I feel that the issue lies in the code provided.

WilliamShatner
  • 926
  • 2
  • 12
  • 25

1 Answers1

3

You're calling Thread.sleep(...) on the Swing event thread which will put the whole Swing thread and application to sleep. Use a background thread such as with a SwingWorker.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • This causes the thread to sleep prior to updating the progressbar and jlabel? – WilliamShatner Jul 31 '13 at 16:30
  • @WilliamShatner: yes. The Swing event thread is sleeping before the Swing event queue has had time to process events that have been placed on it. Again, use a SwingWorker. That's what it is for. – Hovercraft Full Of Eels Jul 31 '13 at 16:31
  • I wonder why so many tutorials show it in a similar fashion as my above method. I guess I'll go back to how you showed me to do it in the first place! http://stackoverflow.com/questions/10236995/how-do-i-make-my-swingworker-example-work-properly – WilliamShatner Jul 31 '13 at 16:32
  • @WilliamShatner: Exactly. SwingWorker has a progress state that a PropertyChangeListener can listen to. For example please check [this answer](http://stackoverflow.com/a/13538075/522444). – Hovercraft Full Of Eels Jul 31 '13 at 16:35
  • Hovercraft, what bothers me is that it seems like I'll have to write a custom class for whenever I want to use a JProgressBar correctly. If this is true, why doesn't JProgressBar just extend SwingWorker by default? – WilliamShatner Jul 31 '13 at 16:45
  • @WilliamShatner: that's the beauty of OOP. If you wanted to create a JProgressBar that is linked to a SwingWorker, there's nothing stopping you from creating this class yourself. My own feeling is that I prefer to keep my model/view/control separate. – Hovercraft Full Of Eels Jul 31 '13 at 16:52