Advertisements

Infinite progress bars in swing

Following are some infinite progress bars built in java swing 2d using JPanel’s paintComponent(Graphics g) method.

Windows XP

I have seen this kind of loading icon while setting up windows XP, you might have also seen it:
xp_loader
So how one can simulate same in swing? Here is the answer:

/**
 * Some custom infinite progress bars in JPanel using Graphics2D object.
 * @author harsh
 */
public class CustomInfiniteProgressBar extends JPanel {
    private static final long serialVersionUID = 223086939802246968L;
    private static final int DELAY = 100;
    private static final int MAX_AMOUNT = 100;
    private static final int SPACE = 30;
    private static final int NUMBER_OF_RECTS = 5;
    private Timer timer;
    private int value = 0, darkRect = 0;

    public CustomInfiniteProgressBar() {
        timer = new Timer(DELAY, new TimerActionListener());
        timer.start();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;

        // draw rectangular progress
        int paddingToFrameBorders = 10; //dummy values for position
        int smallerSize = 5, largerSize = 10; //dummy values for rectangle size

        int rectX, rectY;
        for (int i = 0; i < NUMBER_OF_RECTS; i++) {
            rectX = paddingToFrameBorders + i * SPACE;
            rectY = paddingToFrameBorders;
            if(darkRect == i) {
                g2d.fillRect(rectX, rectY, largerSize, largerSize);
            } else {
                // to center smaller rectangle respective to larger rectangle.
                rectX += (largerSize - smallerSize) / 2;
                rectY += (largerSize - smallerSize) / 2;

                g2d.drawRect(rectX, rectY, smallerSize, smallerSize);
            }
        }
    }

    /**
    * Action Listener of Timer.
    */
    private class TimerActionListener implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            value++;
            if(value == MAX_AMOUNT) { // you can have some condition here to stop the timer.
                timer.stop();
            }
            darkRect = (value % NUMBER_OF_RECTS);
            repaint();
        }
    }
}

Circular infinite progress bar

circles_loading

For this you just have to replace rectangle drawing logic to circle drawing logic and its done:

// global constants
private static final int RADIUS = 30;
private static final int NUMBER_OF_CIRCLES = 10;

private int darkCircle = 0;

//inside paintComponent(g) method
int centerX, centerY; centerX = centerY = 75; //dummy values for position
int circularX, circularY;
for (int i = 0; i < NUMBER_OF_CIRCLES; i++) {
    circularX = centerX + (int) (RADIUS * Math.sin((360 / NUMBER_OF_CIRCLES) * i * 3.14 / 180));
    circularY = centerY + (int) (RADIUS * Math.cos((360 / NUMBER_OF_CIRCLES) * i * 3.14 / 180));
    if(darkCircle == i) {
        g2d.fillOval(circularX, circularY, 10, 10);
    } else {
        g2d.drawOval(circularX, circularY, 10, 10);
    }
}

// in timer action class
darkCircle = NUMBER_OF_CIRCLES - 1 - (value % NUMBER_OF_CIRCLES);

Another example of such progress bar:
circular_loaing_2

for this use following code inside paintComponent(g) everything else will same as above:

//inside paintComponent(g) method
BasicStroke drawingStroke = new BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 0, new float[]{9}, 0);
g2d.setStroke(drawingStroke);
for (int i = 0; i < NUMBER_OF_CIRCLES; i++) {
    circularX = centerX + (int) (RADIUS * Math.sin((360 / NUMBER_OF_CIRCLES) * i * 3.14 / 180));
    circularY = centerY + (int) (RADIUS * Math.cos((360 / NUMBER_OF_CIRCLES) * i * 3.14 / 180));
    if(darkCircle == i) {
        g2d.setColor(new Color(100, 200, 150));
        g2d.drawLine(circularX, circularY, circularX + 10, circularY + 10);
    } else {
        g2d.setColor(Color.black);
        g2d.drawLine(circularX, circularY, circularX + 10, circularY + 10);
    }
}

Arrow shape for progress bar

I’m not sure if following can be used as progress bar, but it can be used for highlighting something or some similar kind of task.
arrow loading highlighting
The code for this as follows:

// inside paintComponent(g) method
for (int i = 0; i < NUMBER_OF_RECTS; i++) {
    if(darkRect == i)
        g2d.fill(getArrowShape(i * 10, 50, 150));
    else
        g2d.draw(getArrowShape(i * 10, 50, 150));
}

// the getArrowShape method
/**
 * Returns arrow shape(a triangle).
 * Points are:
 * A (x + i, y)
 * | \
 * |  \
 * |   \
 * |    C ((x + 10) + i, (y + 10))
 * |   /
 * |  /
 * | /
 * B (x + i, (y + 20))
*/
private Shape getArrowShape(int i, int x, int y) {
    final Polygon result = new Polygon();
    result.addPoint(x + i, y); // A
    result.addPoint(x + i, (y + 20)); // B
    result.addPoint((x + 10) + i, (y + 10)); // C
    return result;
}

That’s all for now.
Hope You like it. 🙂

Advertisements

Circular progress bar in Java Swing

Had you ever got thought of creating a circular progress bar in swing? yes, huh. At first it sounds difficult but then when you start building it then you might found that it is very easy if you have already made an clock application. 🙂

Final result would be like this:

circlePB

We will start by creating a circle animation by use of Timer and overriding paintComponent method of a JPanel:

/**
 * Circular progress bar panel.
 * @author harsh
 */
public class CircularProgressBar extends JPanel {
      private final static int MAX_PROGRESS_AMOUNT = 100;
      private static final int DELAY = 50;
      private Timer timer;
      private int prgValue = 0;

      public CircularProgressBar() {
            timer = new Timer(DELAY, new MyChangeListener());
            timer.start();
      }

      @Override
      protected void paintComponent(Graphics g) {
             Graphics2D g2 = (Graphics2D) g;
             g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
             if (prgValue <= MAX_PROGRESS_AMOUNT) {
                   g.setColor(Color.blue);
                   int angle = -(int) (((float) prgValue / MAX_PROGRESS_AMOUNT) * 360);
                   g.fillArc(0, 0, getWidth(), getHeight(), 90, angle);

            }
     }

     class MyChangeListener implements ActionListener {
         @Override
         public void actionPerformed(ActionEvent arg0) {
             prgValue++;
             repaint();
             if (prgValue >= MAX_PROGRESS_AMOUNT)
                  timer.stop();
        }
    }
}

if you run this you will see something like this:

It was easy, huh. Now the challenging part is to remove inner circular part and make it to view like first image. For that I decide to draw another circle with the same color as background. So here it is:


g2.setColor(getBackground());
g.fillArc(getWidth() / FRACTION / 2, getHeight() / FRACTION / 2,
getWidth() * (FRACTION - 1) / FRACTION, getHeight() * (FRACTION - 1) / FRACTION, 92, angle);

Add this code to paintComponent method and once again run the program. Now you will see something like in first picture.  In above code FRACTION is the width you want for your progress bar. Lesser value of fraction, wider the progress bar. One more difference in 2 fillArc method is in the start angle, in first method it is 90 and in second its 92. This difference will be width of the middle hand.

Here is the testing code:

JFrame frame = new JFrame("Circular Progress Bar by Harry Joy");
frame.add(new CircularProgressBar());
frame.setSize(350, 350);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);

Hope you like it. 🙂

%d bloggers like this: