/*
* Swing version.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/*
* Moves a foreground image in front of a background image.
* See MovingLabels.java for an alternative implementation
* that uses two labels instead of doing its own painting.
*/
public class MovingImageTimer extends JApplet
implements ActionListener {
int frameNumber = -1;
boolean frozen = false;
Timer timer;
AnimationPane animationPane;
static String fgFile = "images/rocketship.gif";
static String bgFile = "images/starfield.gif";
//Invoked only when run as an applet.
public void init() {
//Get the images.
Image bgImage = getImage(getCodeBase(), bgFile);
Image fgImage = getImage(getCodeBase(), fgFile);
buildUI(getContentPane(), bgImage, fgImage);
}
void buildUI(Container container, Image bgImage, Image fgImage) {
int fps = 10;
//How many milliseconds between frames?
int delay = (fps > 0) ? (1000 / fps) : 100;
//Set up a timer that calls this object's action handler.
timer = new Timer(delay, this);
timer.setInitialDelay(0);
timer.setCoalesce(true);
animationPane = new AnimationPane(bgImage, fgImage);
container.add(animationPane, BorderLayout.CENTER);
animationPane.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if (frozen) {
frozen = false;
startAnimation();
} else {
frozen = true;
stopAnimation();
}
}
});
}
//Invoked by a browser only.
public void start() {
startAnimation();
}
//Invoked by a browser only.
public void stop() {
stopAnimation();
}
//Can be invoked from any thread.
public synchronized void startAnimation() {
if (frozen) {
//Do nothing. The user has requested that we
//stop changing the image.
} else {
//Start animating!
if (!timer.isRunning()) {
timer.start();
}
}
}
//Can be invoked from any thread.
public synchronized void stopAnimation() {
//Stop the animating thread.
if (timer.isRunning()) {
timer.stop();
}
}
public void actionPerformed(ActionEvent e) {
//Advance animation frame.
frameNumber++;
//Display it.
animationPane.repaint();
}
class AnimationPane extends JPanel {
Image background, foreground;
public AnimationPane(Image background, Image foreground) {
this.background = background;
this.foreground = foreground;
}
//Draw the current frame of animation.
public void paintComponent(Graphics g) {
super.paintComponent(g); //paint any space not covered
//by the background image
int compWidth = getWidth();
int compHeight = getHeight();
int imageWidth, imageHeight;
//If we have a valid width and height for the
//background image, draw it.
imageWidth = background.getWidth(this);
imageHeight = background.getHeight(this);
if ((imageWidth > 0) && (imageHeight > 0)) {
g.drawImage(background,
(compWidth - imageWidth)/2,
(compHeight - imageHeight)/2, this);
}
//If we have a valid width and height for the
//foreground image, draw it.
imageWidth = foreground.getWidth(this);
imageHeight = foreground.getHeight(this);
if ((imageWidth > 0) && (imageHeight > 0)) {
g.drawImage(foreground,
((frameNumber*5)
% (imageWidth + compWidth))
- imageWidth,
(compHeight - imageHeight)/2,
this);
}
}
}
//Invoked only when run as an application.
public static void main(String[] args) {
Image bgImage = Toolkit.getDefaultToolkit().getImage(
MovingImageTimer.bgFile);
Image fgImage = Toolkit.getDefaultToolkit().getImage(
MovingImageTimer.fgFile);
JFrame f = new JFrame("MovingImageTimer");
final MovingImageTimer controller = new MovingImageTimer();
controller.buildUI(f.getContentPane(), bgImage, fgImage);
f.addWindowListener(new WindowAdapter() {
public void windowIconified(WindowEvent e) {
controller.stopAnimation();
}
public void windowDeiconified(WindowEvent e) {
controller.startAnimation();
}
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.setSize(new Dimension(500, 125));
f.setVisible(true);
controller.startAnimation();
}
}
|