/******************************************************************************* * Copyright (c) 2016 Weasis Team and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Nicolas Roduit - initial API and implementation *******************************************************************************/ package org.weasis.core.api.gui.task; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import javax.swing.ImageIcon; import javax.swing.JProgressBar; import org.weasis.core.api.gui.util.AnimatedIconStatic; import org.weasis.core.api.gui.util.ImageSectionIcon; import org.weasis.core.api.util.FontTools; import org.weasis.core.api.util.LocalUtil; @SuppressWarnings("serial") public class CircularProgressBar extends JProgressBar { private static final Color BACK_COLOR = new Color(82, 152, 219); public static final ImageIcon ICON = new ImageIcon(CircularProgressBar.class.getResource("/icon/22x22/process-working.png")); //$NON-NLS-1$ private volatile Animate animateThread; public CircularProgressBar() { init(); } public CircularProgressBar(int min, int max) { super(min, max); init(); } private void init() { this.setOpaque(false); this.setSize(30, 30); Dimension dim = new Dimension(30, 30); this.setPreferredSize(dim); this.setMaximumSize(dim); } @Override public void paint(Graphics g) { if (g instanceof Graphics2D) { if (isIndeterminate()) { drawInderminate((Graphics2D) g); } else { draw((Graphics2D) g); } } } private void drawInderminate(Graphics2D g) { if (animateThread != null) { animateThread.paintIcon(this, g); } } private void draw(Graphics2D g2) { int h = this.getHeight(); int w = this.getWidth(); int range = this.getMaximum() - this.getMinimum(); if (range < 1) { range = 1; } int a = 360 - this.getValue() * 360 / range; String str = LocalUtil.getPercentInstance().format((double) this.getValue() / range); float x = w / 2.0f - g2.getFontMetrics().stringWidth(str) / 2.0f; final float fontHeight = FontTools.getAccurateFontHeight(g2); final float midfontHeight = fontHeight * FontTools.getMidFontHeightFactor(); float y = h / 2.0f + midfontHeight; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setPaint(Color.WHITE); g2.fillArc(0, 0, w, h, 0, 360); g2.setPaint(BACK_COLOR); g2.fillArc(0, 0, w, h, a, 360 - a); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_DEFAULT); g2.setPaint(Color.BLACK); g2.drawString(str, x, y); } @Override public synchronized void setIndeterminate(boolean newValue) { if (animateThread != null) { stopIndeterminate(); } if (newValue != this.isIndeterminate()) { if (newValue && animateThread == null) { animateThread = new Animate(50); animateThread.start(); } super.setIndeterminate(newValue); } } public synchronized void stopIndeterminate() { Thread moribund = animateThread; animateThread = null; if (moribund != null) { moribund.interrupt(); } } protected class Animate extends Thread { private final AnimatedIconStatic indeterminateIcon; private final long refresh; public Animate(long refresh) { super.setDaemon(true); this.refresh = refresh; indeterminateIcon = new ImageSectionIcon(ICON, 22, 22, 0, 32); } public void paintIcon(CircularProgressBar circularProgressBar, Graphics2D g) { int h = circularProgressBar.getHeight(); int w = circularProgressBar.getWidth(); int x = (w - indeterminateIcon.getIconWidth()) / 2; int y = (h - indeterminateIcon.getIconHeight()) / 2; g.setPaint(Color.WHITE); g.fillRect(x, y, indeterminateIcon.getIconWidth(), indeterminateIcon.getIconHeight()); indeterminateIcon.paintIcon(circularProgressBar, g, x, y); } @Override public void run() { while (!this.isInterrupted()) { indeterminateIcon.animate(); CircularProgressBar.this.repaint(); try { Thread.sleep(this.refresh); } catch (InterruptedException e) { this.interrupt(); } } } } }