I have implemented a small example using InfiniteProgressDemo and works perfectly, showing the "loading wheel" rotating at the center of the frame.
Now I have ported it to my program. I have a button for a connect action (do not worry about the BussinessException):
public class ConnectAction extends AbstractAction {
private JFrame framePrincipal;
private InfiniteProgressPanel glassPane;
/**
* Constructor
* @param m
* @param pNodos
* @param pGraficas
* @param front
* @throws BusinessException
*/
public ConnectAction(Main main, DockFrontend front) throws BusinessException{
super();
this.framePrincipal = main.getFramePrincipal();
this.glassPane = new InfiniteProgressPanel();
framePrincipal.setGlassPane(glassPane);
}
private void perform() throws BusinessException {
// DOING SOME HEAVY STUFF...
System.out.println("You've successfully waited :)");
glassPane.stop();
}
@Override
public Object execute() throws BusinessException {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
glassPane.start();
Thread performer = new Thread(new Runnable() {
public void run() {
try {
perform();
} catch (BusinessException e) {
e.printStackTrace();
}
}
}, "Performer");
performer.start();
}
});
return null;
}
@Override
public void redo() throws BusinessException {
// TODO Auto-generated method stub
}
@Override
public void undo() throws BusinessException {
// TODO Auto-generated method stub
}
@Override
protected void initServices() throws BusinessException {
}
}
The only file I needed from the InfiniteProgressDemo demo was InfiniteProgressPane.
When I execute and push my button, the "loading wheel" appears, but not at the center of the frame. It appears on one corner... next second it appears on another corner, and so on. I don't know what's wrong.
I also attach here the InfiniteProgressDemo:
public class InfiniteProgressPanel extends JComponent implements MouseListener
{
protected Area[] ticker = null;
protected Thread animation = null;
protected boolean started = false;
protected int alphaLevel = 0;
protected int rampDelay = 300;
protected float shield = 0.70f;
protected String text = "";
protected int barsCount = 14;
protected float fps = 15.0f;
protected RenderingHints hints = null;
public InfiniteProgressPanel()
{
this("");
}
public InfiniteProgressPanel(String text)
{
this(text, 14);
}
public InfiniteProgressPanel(String text, int barsCount)
{
this(text, barsCount, 0.70f);
}
public InfiniteProgressPanel(String text, int barsCount, float shield)
{
this(text, barsCount, shield, 15.0f);
}
public InfiniteProgressPanel(String text, int barsCount, float shield, float fps)
{
this(text, barsCount, shield, fps, 300);
}
public InfiniteProgressPanel(String text, int barsCount, float shield, float fps, int rampDelay)
{
this.text = text;
this.rampDelay = rampDelay >= 0 ? rampDelay : 0;
this.shield = shield >= 0.0f ? shield : 0.0f;
this.fps = fps > 0.0f ? fps : 15.0f;
this.barsCount = barsCount > 0 ? barsCount : 14;
this.hints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
this.hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
this.hints.put(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
}
public void setText(String text)
{
repaint();
this.text = text;
}
public String getText()
{
return text;
}
public void start()
{
addMouseListener(this);
setVisible(true);
ticker = buildTicker();
animation = new Thread(new Animator(true));
animation.start();
}
public void stop()
{
if (animation != null) {
animation.interrupt();
animation = null;
animation = new Thread(new Animator(false));
animation.start();
}
}
public void interrupt()
{
if (animation != null) {
animation.interrupt();
animation = null;
removeMouseListener(this);
setVisible(false);
}
}
public void paintComponent(Graphics g)
{
if (started)
{
int width = getWidth();
int height = getHeight();
double maxY = 0.0;
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHints(hints);
g2.setColor(new Color(255, 255, 255, (int) (alphaLevel * shield)));
g2.fillRect(0, 0, getWidth(), getHeight());
for (int i = 0; i < ticker.length; i++)
{
int channel = 224 - 128 / (i + 1);
g2.setColor(new Color(channel, channel, channel, alphaLevel));
g2.fill(ticker[i]);
Rectangle2D bounds = ticker[i].getBounds2D();
if (bounds.getMaxY() > maxY)
maxY = bounds.getMaxY();
}
if (text != null && text.length() > 0)
{
FontRenderContext context = g2.getFontRenderContext();
TextLayout layout = new TextLayout(text, getFont(), context);
Rectangle2D bounds = layout.getBounds();
g2.setColor(getForeground());
layout.draw(g2, (float) (width - bounds.getWidth()) / 2,
(float) (maxY + layout.getLeading() + 2 * layout.getAscent()));
}
}
}
private Area[] buildTicker()
{
Area[] ticker = new Area[barsCount];
Point2D.Double center = new Point2D.Double((double) getWidth() / 2, (double) getHeight() / 2);
double fixedAngle = 2.0 * Math.PI / ((double) barsCount);
for (double i = 0.0; i < (double) barsCount; i++)
{
Area primitive = buildPrimitive();
AffineTransform toCenter = AffineTransform.getTranslateInstance(center.getX(), center.getY());
AffineTransform toBorder = AffineTransform.getTranslateInstance(45.0, -6.0);
AffineTransform toCircle = AffineTransform.getRotateInstance(-i * fixedAngle, center.getX(), center.getY());
AffineTransform toWheel = new AffineTransform();
toWheel.concatenate(toCenter);
toWheel.concatenate(toBorder);
primitive.transform(toWheel);
primitive.transform(toCircle);
ticker[(int) i] = primitive;
}
return ticker;
}
private Area buildPrimitive()
{
Rectangle2D.Double body = new Rectangle2D.Double(6, 0, 30, 12);
Ellipse2D.Double head = new Ellipse2D.Double(0, 0, 12, 12);
Ellipse2D.Double tail = new Ellipse2D.Double(30, 0, 12, 12);
Area tick = new Area(body);
tick.add(new Area(head));
tick.add(new Area(tail));
return tick;
}
protected class Animator implements Runnable
{
private boolean rampUp = true;
protected Animator(boolean rampUp)
{
this.rampUp = rampUp;
}
public void run()
{
Point2D.Double center = new Point2D.Double((double) getWidth() / 2, (double) getHeight() / 2);
double fixedIncrement = 2.0 * Math.PI / ((double) barsCount);
AffineTransform toCircle = AffineTransform.getRotateInstance(fixedIncrement, center.getX(), center.getY());
long start = System.currentTimeMillis();
if (rampDelay == 0)
alphaLevel = rampUp ? 255 : 0;
started = true;
boolean inRamp = rampUp;
while (!Thread.interrupted())
{
if (!inRamp)
{
for (int i = 0; i < ticker.length; i++)
ticker[i].transform(toCircle);
}
repaint();
if (rampUp)
{
if (alphaLevel < 255)
{
alphaLevel = (int) (255 * (System.currentTimeMillis() - start) / rampDelay);
if (alphaLevel >= 255)
{
alphaLevel = 255;
inRamp = false;
}
}
} else if (alphaLevel > 0) {
alphaLevel = (int) (255 - (255 * (System.currentTimeMillis() - start) / rampDelay));
if (alphaLevel <= 0)
{
alphaLevel = 0;
break;
}
}
try
{
Thread.sleep(inRamp ? 10 : (int) (1000 / fps));
} catch (InterruptedException ie) {
break;
}
Thread.yield();
}
if (!rampUp)
{
started = false;
repaint();
setVisible(false);
removeMouseListener(InfiniteProgressPanel.this);
}
}
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
}
Finally the problem is that getWidth() and getHeight() methods aren't getting the correct dimensions of the JFrame of my main windows, because they are called straigth forwards. Modifying the InfiniteProgressDemo constructors to receive a JFrame myFrame, and calling myFrame.getWidth() and myFrame.getHeight() got the animation working correctly in the center of the screen.