Monday 10 October 2011

Java Custom Component - Colored Progress Bar

After getting slightly bored of the standard Java components available to me I decided to spice things up a little. I wanted to be able to have a clean, colourful and customizable progress bar. I also wanted the progress bar to be able to change colour at certain values, such as when it reaches a low percent it will go red.

Essentially I extend JComponent and use paintComponent method which is called automatically by Java to draw the progress bar.

This code can be easily extended and customized to change/add more colours as well as editing the percentages of the bar as to when it will change colour

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;

import javax.swing.JComponent;

public class ProgressBarColored extends JComponent
{

 private static final long serialVersionUID = 1L;

 private Rectangle clipRect = new Rectangle(); // creating new rectangular area to draw on

 private double accuracy = 100; // how accurately the progress bar is drawn
 private double percentage; // progress bar percentage (%)
 private double maximumValue = 100; // maximum value of progress bar
 private double value = 0; // value of progress bar

 private volatile Color backgroundColor = Color.black; // background color of progress bar
 
 private volatile Color foregroundColor;
 private Color startColor = new Color(0, 255, 0); // green color when progress bar is high %
 private Color middleColor = new Color(255, 255, 0); // yellow color when progress bar is medium %
 private Color endColor = new Color(204, 0, 0); // red color when progress bar is low %

 private int hPadding = 10; // horizontal padding
 private int vPadding = 10; // vertical padding

 /**
  * 
  * Creates a new ProgressBarColored with a maximum value and initial starting value
  * 
  * @param maximumValue
  * @param initialValue
  */
 public ProgressBarColored(final int maximumValue, int initialValue)
 {
  this.maximumValue = maximumValue;
  this.value = initialValue;
  this.setDoubleBuffered(true);
  setValue(value);
 }

 
 protected void paintComponent(Graphics g)
 {
  accuracy = getWidth() / maximumValue;

  g.getClipBounds(clipRect); // get progress bar's drawing area
  Graphics2D g2d = (Graphics2D) g.create(); // create Graphics2D object based on clipped graphics area
 
  g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // setting rendering hints
  
  drawBackground(g2d); // draw progress bar background
  drawForground(g2d); // draw progress bar progress graphic in foreground
  
  g2d.dispose(); // clean up
 }


 private void drawBackground(Graphics2D g2d)
 {
  g2d.setColor(backgroundColor);
  g2d.fillRect(hPadding/2, vPadding/2, getWidth() - hPadding , getHeight() - vPadding);
 }

 private void drawForground(Graphics2D g2d)
 {
  g2d.setColor(foregroundColor);
  g2d.fillRect(hPadding/2, vPadding/2, (int) ((getWidth() - hPadding) / ((maximumValue * accuracy) / (value * accuracy))), getHeight() - vPadding);
 }

 /**
  * 
  * Sets the value of the progress bar and automatically assigns the color of it
  * 
  * @param newValue
  */
 public void setValue(double newValue)
 {
  value = newValue;
  accuracy = getWidth() / maximumValue;
  percentage = ((getValue() * 1.0) / getMaximum()) * 100;
  if (percentage == 100) // when between 40% and 100%
  {
   setForeground(startColor);
  }
  else if (percentage >= 20 && percentage < 40) // when between 20% and 40%
  {
   setForeground(middleColor);
  }
  else if (percentage >= 0 && percentage < 20) // when between 0% and 20%
  {
   setForeground(endColor);
  }
  repaint();
 }
 
 public double getValue()
 {
  return value;
 }

 public void setMaximum(double newMaximumValue)
 {
  maximumValue = newMaximumValue;
  repaint();
 }
 
 public double getMaximum()
 {
  return maximumValue;
 }

 @Override
 public void setForeground(Color color)
 {
  this.foregroundColor = color;
 }
 
 @Override
 public Color getForeground()
 {
  return foregroundColor;
 }

 @Override
 public void setBackground(Color color)
 {
  this.backgroundColor = color;
 }

 @Override
 public Color getBackground()
 {
  return backgroundColor;
 }
 
 @Override
 public Dimension getPreferredSize()
 {
  return new Dimension(100, 30);
 }
 
 @Override
 public Dimension getMinimumSize()
 {
  return new Dimension(10, 5);
 }

}

Here is some example code that will enable you to test the component using a timer decreasing from 100 to 0. Copy and paste this code somewhere in a gui to test it out.
...
ProgressBarColored progressBarColored = new ProgressBarColored(100, 100);
...
for (int i = 0; i <= 100; i++)
{
 try
 {
  Thread.sleep(50);
  progressBarColored.setValue(100 - i);
 }
 catch (InterruptedException e)
 {
  e.printStackTrace();
 }
}

Below is a screenshot of the progress bar within an interface with a low percentage, the percent is between 20 and 40 percent so the color is yellow.


Any feedback or questions are welcome!

No comments:

Post a Comment