import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.net.URL;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutionException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class PartialImagePanel extends JPanel implements PropertyChangeListener {
public static enum Orientation {
HORIZONTAL, VERTICAL;
}
public static enum Direction {
BACKWARD, FORWARD;
}
private Orientation orientation = Orientation.HORIZONTAL;
private Direction direction = Direction.FORWARD;
private Image img;
private int i;
@Override
protected void paintComponent(final Graphics g) {
super.paintComponent(g);
if (img != null) {
final Graphics2D g2 = (Graphics2D) g.create();
final Rectangle clip = g2.getClipBounds();
switch (orientation) {
case HORIZONTAL:
final int imgWidth = img.getWidth(null);
final int clipWidth = clip.x + imgWidth;
switch (direction) {
case BACKWARD:
g2.setClip((int) ((1 - i/100d) * clipWidth), clip.y, clipWidth, clip.y + clip.height);
break;
case FORWARD:
g2.setClip(clip.x, clip.y, (int) (i/100d * clipWidth), clip.y + clip.height);
break;
}
break;
case VERTICAL:
final int imgHeight = img.getHeight(null);
final int clipHeight = clip.y + imgHeight;
switch (direction) {
case BACKWARD:
g2.setClip(clip.x, (int) ((1 - i/100d) * clipHeight), clip.x + clip.width, clipHeight);
break;
case FORWARD:
g2.setClip(clip.x, clip.y, clip.x + clip.width, (int) (i/100d * clipHeight));
break;
}
break;
}
g2.drawImage(img, 0, 0, null);
g2.dispose();
}
g.drawString(String.format("%d %%", i), 0, getHeight());
}
public void setImg(final Image img) {
this.img = img;
repaint();
}
private void setI(final int i) {
this.i = i;
repaint();
}
public void setOrientation(final Orientation orientation) {
this.orientation = orientation;
repaint();
}
public void setDirection(final Direction direction) {
this.direction = direction;
repaint();
}
@Override
public void propertyChange(final PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("progress")) {
setI((Integer) evt.getNewValue());
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final JFrame frame = new JFrame();
final PartialImagePanel panel = new PartialImagePanel();
panel.setBackground(Color.WHITE);
panel.setOrientation(Orientation.VERTICAL);
panel.setDirection(Direction.BACKWARD);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
final SwingWorker<Void, Void> imgAnimator = new SwingWorker<Void, Void>() {
private final Timer counter = new Timer();
@Override
protected Void doInBackground() throws Exception {
counter.schedule(new TimerTask() {
private int count;
@Override
public void run() {
setProgress(++count);
if (count >= 100) {
counter.cancel();
}
}
}, 0, 50);
return null;
}
};
imgAnimator.addPropertyChangeListener(panel);
final SwingWorker<BufferedImage, Void> imgLoader = new SwingWorker<BufferedImage, Void>() {
@Override
protected BufferedImage doInBackground() throws Exception {
return ImageIO.read(new URL("http://www.java-forum.org/images/misc/java_forum_org.gif"));
}
@Override
protected void done() {
try {
panel.setImg(get());
imgAnimator.execute();
} catch (final ExecutionException | InterruptedException ex) {
throw new RuntimeException(ex);
}
}
};
frame.setSize(600, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
imgLoader.execute();
}
});
}
}