Code
class SolidGaugeUI extends BasicProgressBarUI {
private final int[] pallet;
private final double extent;
protected SolidGaugeUI(int range, double extent) {
super();
this.pallet = makeGradientPallet(range);
this.extent = extent;
}
@Override public void paint(Graphics g, JComponent c) {
Rectangle rect = SwingUtilities.calculateInnerArea(progressBar, null);
if (rect.isEmpty()) {
return;
}
Graphics2D g2 = (Graphics2D) g.create();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
// double extent = -150d;
double start = 90d + extent * .5;
double degree = extent * progressBar.getPercentComplete();
double or = Math.min(rect.width, rect.height);
double cx = rect.getCenterX();
double cy = rect.getMaxY();
double sz = or * 2d;
double ir = or * .6;
Shape inner = new Arc2D.Double(
cx - ir, cy - ir, ir * 2d, ir * 2d, start, -extent, Arc2D.PIE);
Shape outer = new Arc2D.Double(
cx - or, cy - or, sz, sz, start, -extent, Arc2D.PIE);
Shape sector = new Arc2D.Double(
cx - or, cy - or, sz, sz, start, -degree, Arc2D.PIE);
Area foreground = new Area(sector);
Area background = new Area(outer);
Area hole = new Area(inner);
foreground.subtract(hole);
background.subtract(hole);
// Draw the track
g2.setPaint(new Color(0xDD_DD_DD));
g2.fill(background);
// Draw the circular sector
g2.setPaint(getColorFromPallet(
pallet, progressBar.getPercentComplete()));
g2.fill(foreground);
// Draw ...
Font font = progressBar.getFont();
float fsz = font.getSize2D();
float min = (float) (cx - or - fsz);
float max = (float) (cx + or + 4d);
g2.setPaint(progressBar.getForeground());
g2.drawString(
Objects.toString(progressBar.getMinimum()), min, (float) cy);
g2.drawString(Objects.toString(
progressBar.getMaximum()), max, (float) cy);
// Deal with possible text painting
if (progressBar.isStringPainted()) {
float h = (float) cy - fsz;
String str = String.format("%d", progressBar.getValue());
float vx = (float) cx - g2.getFontMetrics().stringWidth(str) * .5f;
g2.drawString(str, vx, h);
float ksz = fsz * .66f;
g2.setFont(font.deriveFont(ksz));
String kmh = "㎞/h";
float tx = (float) cx - g2.getFontMetrics().stringWidth(kmh) * .5f;
g2.drawString(kmh, tx, h + ksz);
}
g2.dispose();
}
private static int[] makeGradientPallet(int range) {
BufferedImage image = new BufferedImage(
range, 1, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = image.createGraphics();
Point2D start = new Point2D.Float();
Point2D end = new Point2D.Float(range - 1f, 0f);
float[] dist = {0f, .8f, .9f, 1f};
Color[] colors = {Color.GREEN, Color.YELLOW, Color.ORANGE, Color.RED};
g2.setPaint(new LinearGradientPaint(start, end, dist, colors));
g2.fillRect(0, 0, range, 1);
g2.dispose();
int width = image.getWidth(null);
int[] pallet = new int[width];
PixelGrabber pg = new PixelGrabber(image, 0, 0, width, 1, pallet, 0, width);
try {
pg.grabPixels();
} catch (InterruptedException ex) {
ex.printStackTrace();
Toolkit.getDefaultToolkit().beep();
Thread.currentThread().interrupt();
}
return pallet;
}
private static Color getColorFromPallet(int[] pallet, double pos) {
if (pos < 0d || pos > 1d) {
throw new IllegalArgumentException("Parameter outside of expected range");
}
int i = (int) (pallet.length * pos);
int max = pallet.length - 1;
int index = Math.min(Math.max(i, 0), max);
return new Color(pallet[index] & 0x00_FF_FF_FF);
}
}
References