Image Bouncer
import java.awt.BorderLayout;
import java.awt.Checkbox;
import java.awt.Choice;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Label;
import java.awt.MediaTracker;
import java.awt.Panel;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.NumberFormat;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ImageBouncer extends JPanel implements Runnable {
private boolean trucking = true;
private long[] previousTimes; // milliseconds
private int previousIndex;
private boolean previousFilled;
private double frameRate; // frames per second
public static void main(String[] args) {
String filename = "java2sLogo.png";
if (args.length > 0)
filename = args[0];
Image image = null;
try {
image = blockingLoad(new URL(filename));
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
final ImageBouncer bouncer = new ImageBouncer(image);
Frame f = new AnimationFrame(bouncer);
f.setFont(new Font("Serif", Font.PLAIN, 12));
Panel controls = new Panel();
controls.add(bouncer.createCheckbox("Bilinear", ImageBouncer.BILINEAR));
controls.add(bouncer.createCheckbox("Transform", ImageBouncer.TRANSFORM));
final Choice typeChoice = new Choice();
typeChoice.add("TYPE_INT_RGB");
typeChoice.add("TYPE_INT_ARGB");
typeChoice.add("TYPE_INT_ARGB_PRE");
typeChoice.add("TYPE_3BYTE_BGR");
typeChoice.add("TYPE_BYTE_GRAY");
typeChoice.add("TYPE_USHORT_GRAY");
typeChoice.add("TYPE_USHORT_555_RGB");
typeChoice.add("TYPE_USHORT_565_RGB");
controls.add(typeChoice);
f.add(controls, BorderLayout.NORTH);
typeChoice.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent ie) {
String type = typeChoice.getSelectedItem();
bouncer.setImageType(type);
}
});
f.setSize(200,200);
f.setVisible(true);
}
private boolean mBilinear = false;
private boolean mTransform = false;
public static final int BILINEAR = 1;
public static final int TRANSFORM = 3;
private float mDeltaX, mDeltaY;
private float mX, mY, mWidth, mHeight;
private float mTheta;
private Image mOriginalImage;
private Image image;
public ImageBouncer(Image image) {
previousTimes = new long[128];
previousTimes[0] = System.currentTimeMillis();
previousIndex = 1;
previousFilled = false;
mOriginalImage = image;
setImageType("TYPE_INT_RGB");
Random random = new Random();
mX = random.nextFloat() * 500;
mY = random.nextFloat() * 500;
mWidth = image.getWidth(this);
mHeight = image.getHeight(this);
mDeltaX = random.nextFloat() * 3;
mDeltaY = random.nextFloat() * 3;
// Make sure points are within range.
addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent ce) {
Dimension d = getSize();
if (mX < 0)
mX = 0;
else if (mX + mWidth >= d.width)
mX = d.width - mWidth - 1;
if (mY < 0)
mY = 0;
else if (mY + mHeight >= d.height)
mY = d.height - mHeight - 1;
}
});
}
public void setSwitch(int item, boolean value) {
switch (item) {
case BILINEAR:
mBilinear = value;
break;
case TRANSFORM:
mTransform = value;
break;
default:
break;
}
}
public void setImageType(String s) {
int type = BufferedImage.TYPE_CUSTOM;
if (s.equals("TYPE_INT_RGB"))
type = BufferedImage.TYPE_INT_RGB;
else if (s.equals("TYPE_INT_ARGB"))
type = BufferedImage.TYPE_INT_ARGB;
else if (s.equals("TYPE_INT_ARGB_PRE"))
type = BufferedImage.TYPE_INT_ARGB_PRE;
else if (s.equals("TYPE_3BYTE_BGR"))
type = BufferedImage.TYPE_3BYTE_BGR;
else if (s.equals("TYPE_BYTE_GRAY"))
type = BufferedImage.TYPE_BYTE_GRAY;
else if (s.equals("TYPE_USHORT_GRAY"))
type = BufferedImage.TYPE_USHORT_GRAY;
else if (s.equals("TYPE_USHORT_555_RGB"))
type = BufferedImage.TYPE_USHORT_565_RGB;
else if (s.equals("TYPE_USHORT_565_RGB"))
type = BufferedImage.TYPE_USHORT_565_RGB;
else {
System.out.println("Unrecognized type.");
return;
}
image = makeBufferedImage(mOriginalImage, type);
}
protected Checkbox createCheckbox(String label, final int item) {
Checkbox check = new Checkbox(label);
check.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent ie) {
setSwitch(item, (ie.getStateChange() == ie.SELECTED));
}
});
return check;
}
public void timeStep() {
Dimension d = getSize();
if (mX + mDeltaX < 0)
mDeltaX = -mDeltaX;
else if (mX + mWidth + mDeltaX >= d.width)
mDeltaX = -mDeltaX;
if (mY + mDeltaY < 0)
mDeltaY = -mDeltaY;
else if (mY + mHeight + mDeltaY >= d.height)
mDeltaY = -mDeltaY;
mX += mDeltaX;
mY += mDeltaY;
mTheta += Math.PI / 192;
if (mTheta > (2 * Math.PI))
mTheta -= (2 * Math.PI);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
setTransform(g2);
setBilinear(g2);
// Draw the image.
g2
.drawImage(image,
AffineTransform.getTranslateInstance(mX, mY), null);
}
protected void setTransform(Graphics2D g2) {
if (mTransform == false)
return;
float cx = mX + mWidth / 2;
float cy = mY + mHeight / 2;
g2.rotate(mTheta, cx, cy);
}
protected void setBilinear(Graphics2D g2) {
if (mBilinear == false)
return;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
}
public void run() {
while (trucking) {
render();
timeStep();
calculateFrameRate();
}
}
protected void render() {
Graphics g = getGraphics();
if (g != null) {
Dimension d = getSize();
if (checkImage(d)) {
Graphics imageGraphics = image.getGraphics();
// Clear the image background.
imageGraphics.setColor(getBackground());
imageGraphics.fillRect(0, 0, d.width, d.height);
imageGraphics.setColor(getForeground());
// Draw this component offscreen.
paint(imageGraphics);
// Now put the offscreen image on the screen.
g.drawImage(image, 0, 0, null);
// Clean up.
imageGraphics.dispose();
}
g.dispose();
}
}
// Offscreen image.
protected boolean checkImage(Dimension d) {
if (d.width == 0 || d.height == 0)
return false;
if (image == null || image.getWidth(null) != d.width
|| image.getHeight(null) != d.height) {
image = createImage(d.width, d.height);
}
return true;
}
protected void calculateFrameRate() {
// Measure the frame rate
long now = System.currentTimeMillis();
int numberOfFrames = previousTimes.length;
double newRate;
// Use the more stable method if a history is available.
if (previousFilled)
newRate = (double) numberOfFrames
/ (double) (now - previousTimes[previousIndex]) * 1000.0;
else
newRate = 1000.0 / (double) (now - previousTimes[numberOfFrames - 1]);
firePropertyChange("frameRate", frameRate, newRate);
frameRate = newRate;
// Update the history.
previousTimes[previousIndex] = now;
previousIndex++;
if (previousIndex >= numberOfFrames) {
previousIndex = 0;
previousFilled = true;
}
}
public double getFrameRate() {
return frameRate;
}
// Property change support.
private transient AnimationFrame mRateListener;
public void setRateListener(AnimationFrame af) {
mRateListener = af;
}
public void firePropertyChange(String name, double oldValue, double newValue) {
mRateListener.rateChanged(newValue);
}
private static Component sComponent = new Component() {
};
private static final MediaTracker sTracker = new MediaTracker(sComponent);
private static int sID = 0;
public static boolean waitForImage(Image image) {
int id;
synchronized (sComponent) {
id = sID++;
}
sTracker.addImage(image, id);
try {
sTracker.waitForID(id);
} catch (InterruptedException ie) {
return false;
}
if (sTracker.isErrorID(id))
return false;
return true;
}
public Image blockingLoad(String path) {
Image image = Toolkit.getDefaultToolkit().getImage(path);
if (waitForImage(image) == false)
return null;
return image;
}
public static Image blockingLoad(URL url) {
Image image = Toolkit.getDefaultToolkit().getImage(url);
if (waitForImage(image) == false)
return null;
return image;
}
public BufferedImage makeBufferedImage(Image image) {
return makeBufferedImage(image, BufferedImage.TYPE_INT_RGB);
}
public BufferedImage makeBufferedImage(Image image, int imageType) {
if (waitForImage(image) == false)
return null;
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null),
image.getHeight(null), imageType);
Graphics2D g2 = bufferedImage.createGraphics();
g2.drawImage(image, null, null);
return bufferedImage;
}
}
class AnimationFrame extends JFrame {
private Label mStatusLabel;
private NumberFormat mFormat;
public AnimationFrame(ImageBouncer ac) {
super();
setLayout(new BorderLayout());
add(ac, BorderLayout.CENTER);
add(mStatusLabel = new Label(), BorderLayout.SOUTH);
// Create a number formatter.
mFormat = NumberFormat.getInstance();
mFormat.setMaximumFractionDigits(1);
// Listen for the frame rate changes.
ac.setRateListener(this);
// Kick off the animation.
Thread t = new Thread(ac);
t.start();
}
public void rateChanged(double frameRate) {
mStatusLabel.setText(mFormat.format(frameRate) + " fps");
}
}
Related examples in the same category