package org.orbisgis.toolboxeditor.utils;
import org.xnap.commons.i18n.I18n;
import org.xnap.commons.i18n.I18nFactory;
import javax.swing.*;
import javax.swing.plaf.LayerUI;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
/**
* Wait layer displayed on doing an update on the list.
*
* @author Sylvain PALOMINOS
*/
public class WaitLayerUI extends LayerUI<JComponent> implements ActionListener {
private boolean mIsRunning;
private boolean mIsFadingOut;
private Timer mTimer;
private int mAngle;
private int mFadeCount;
private int mFadeLimit = 15;
private static final I18n I18N = I18nFactory.getI18n(WaitLayerUI.class);
@Override
public void paint(Graphics g, JComponent c) {
int w = c.getWidth();
int h = c.getHeight();
// Paint the view.
super.paint (g, c);
if (!mIsRunning) {
return;
}
Graphics2D g2 = (Graphics2D)g.create();
float fade = (float)mFadeCount / (float)mFadeLimit;
// Gray it out.
Composite urComposite = g2.getComposite();
g2.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, .5f * fade));
g2.fillRect(0, 0, w, h);
g2.setComposite(urComposite);
// Paint the wait indicator.
int s = Math.min(w, h) / 5;
int cx = w / 2;
int cy = h / 2;
g2.setPaint(Color.white);
//"Loading source" painting
Font font = g2.getFont().deriveFont(Font.PLAIN, s / 3);
g2.setFont(font);
FontMetrics metrics = g2.getFontMetrics(font);
int w1 = metrics.stringWidth(I18N.tr("Loading"));
int w2 = metrics.stringWidth(I18N.tr("fields"));
int h1 = metrics.getHeight();
g2.drawString(I18N.tr("Loading"), cx - w1 / 2, cy - h1 / 2);
g2.drawString(I18N.tr("source"), cx - w2 / 2, cy + h1 / 2);
//waiter painting
g2.setStroke(new BasicStroke(s / 4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.rotate(Math.PI * mAngle / 180, cx, cy);
for (int i = 1; i < 12; i++) {
float scale = (11.0f - (float)i) / 11.0f;
g2.drawLine(cx + s, cy, cx + s * 2, cy);
g2.rotate(-Math.PI / 6, cx, cy);
g2.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, scale * fade));
}
Toolkit.getDefaultToolkit().sync();
g2.dispose();
}
public void actionPerformed(ActionEvent e) {
if (mIsRunning) {
firePropertyChange("tick", 0, 1);
mAngle += 3;
if (mAngle >= 360) {
mAngle = 0;
}
if (mIsFadingOut) {
if (--mFadeCount <= 0) {
mIsRunning = false;
mTimer.stop();
}
}
else if (mFadeCount < mFadeLimit) {
mFadeCount++;
}
}
}
public void start() {
if (mIsRunning) {
return;
}
// Run a thread for animation.
mIsRunning = true;
mIsFadingOut = false;
mFadeCount = 0;
int fps = 24;
int tick = 1000 / fps;
mTimer = new Timer(tick, this);
mTimer.start();
}
public void stop() {
mIsFadingOut = true;
}
@Override
public void applyPropertyChange(PropertyChangeEvent pce, JLayer l) {
if ("tick".equals(pce.getPropertyName())) {
l.repaint();
}
}
}