// ReboundGUI.java // Animation with event listener (mouse and timer) // Descended from Lewis/Loftus example // The timer does the animation by repainting every DELAY msecs // in a newly computed position, reversing direction when the border // is bumped. The mouse is used to stop the animation and restart it // with a steeper angle of travel (up to a limit, then back to horizontal). import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ReboundGUI extends JPanel { private final int IMAGE_SIZE = 35, DELAY = 20; private final int PIXELS = 3; // Distance to move X private ImageIcon image; private Timer timer; private int x, y, dirX, dirY; // coordinates and direction private int rise; // Distance to move Y // Start the GUI in a window public static void main(String[] args) { JFrame frame = new JFrame("Rebound"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(new ReboundGUI()); frame.pack(); frame.setVisible(true); } /** Constructor sets up the GUI, including the timer for the animation */ public ReboundGUI() { addMouseListener(new ReboundMouseListener()); timer = new Timer(DELAY, new ReboundActionListener()); image = new ImageIcon("happyface.gif"); // Inital coordiantes, direction, angle x = 0; y = IMAGE_SIZE; dirX = 1; dirY = 1; rise = PIXELS; setPreferredSize(new Dimension(300, 200)); setBackground(Color.black); timer.start(); } /** Draws the image in the current location */ public void paintComponent(Graphics page) { super.paintComponent(page); image.paintIcon(this, page, x, y); } /** Start or stop the animation and change angle */ private void toggleAnimation() { // If timer is going, stop it; if stopped, start it if (timer.isRunning()) timer.stop(); else { // Change the rise rise = (rise + 1) % (3*PIXELS); timer.start(); } } // Private inner class for the action listener for the timer private class ReboundActionListener implements ActionListener { // Updates the position of the image and possibly the direction // of movement whenever the timer fires an action event. public void actionPerformed(ActionEvent event) { x += dirX * PIXELS; y += dirY * rise; // Reverse if bumping border if (x <= 0 || x >= getWidth()-IMAGE_SIZE) dirX = dirX * -1; if (y <= 0 || y >= getHeight()-IMAGE_SIZE) dirY = dirY * -1; repaint(); } } // Private inner class for the mouse listener for the gui private class ReboundMouseListener implements MouseListener { // Stops or starts the timer (and therefore the animation) // when the mouse button is clicked. public void mouseClicked(MouseEvent event) { toggleAnimation(); } // Provide empty definitions for unused event methods. public void mouseEntered (MouseEvent event) {} public void mouseExited (MouseEvent event) {} public void mousePressed (MouseEvent event) {} public void mouseReleased (MouseEvent event) {} } }