Friday, August 15, 2014

Using JProgressBar (and javax.swing.Timer) to indicate the progress of tasks [Java][Swing]

This program has a JProgressBar to indicate the progress of some task. [It also shows the usage of javax.swing.Timer class]

The progress rate is to

1. Decrease more and more as progress approaches 100%.
2. Randomly increase so it will periodically look like it’s starting to speed up.



Source:

import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;

class Progressing extends JFrame {

    JProgressBar pb = new JProgressBar(0, 100);
    JLabel jl
            = new JLabel("Progressing...");

    /*
     My Not-So-Good Attempt. 
     Knowing about tm.setDelay() would have produced better code
     3 problems with this code:
      
     1. 300ms delay everytime
     2. Values have ranges (28, 68, 100) and not like
     based on the percentage of task completed
     3. Makes me feel bad!
     */
    Timer tm = new Timer(300, new ActionListener() {
        Random rand = new Random();

        public void actionPerformed(ActionEvent e) {
            int add = 0,
                    max = pb.getMaximum(),
                    current = pb.getValue();
            if (current < 28) {
                add = 8;
                add -= rand.nextInt(3);
            } else if (current < 68) {
                add = 4;
                add -= rand.nextInt(5);
            } else if (current < 100) {
                add = 2;
                add -= rand.nextInt(3);
            }
            current += add;
            if (current >= 100) {
                current = 100;
                tm.stop();
            }
            pb.setValue(current);
            jl.setText(current + "% complete...");
        }
    });

    //tm2 code as given in the solution book of [TIJ4]
    Timer tm2 = new Timer(50, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            if (pb.getValue() == pb.getMaximum()) {
                tm2.stop();
                jl.setText("Completed!");
            }
            double percent
                    = (double) pb.getValue()
                    / (double) pb.getMaximum();
            tm2.setDelay((int) (tm2.getDelay() * (1.0 + percent * 0.07)));
            pb.setValue(pb.getValue() + 1);
            if (percent > 0.90) {
                if (Math.random() < 0.25) {
                    pb.setValue(pb.getValue() - 10);
                }
            }
        }
    });

    public Progressing() {
        setLayout(new FlowLayout());
        add(pb);
        add(jl);
        pb.setValue(1);
        tm.start();     //Comment it out if you're uncommenting the next line
//        tm2.start(); //Uncomment to see the solution as given by the author of TIJ4

        setTitle("Some task in progress...");
        setSize(300, 80);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
}

public class ProgressIndicate {

    public static void main(String args[]) {
        try {
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (Exception e) {
            // If Nimbus is not available, you can set the GUI to another look and feel.
        }
        new Progressing();
    }
}

No comments:

Post a Comment