package animation; import javax.swing.*; import java.awt.*; import java.awt.event.*; import animation.*; class animation extends JPanel { final int BOX_SIZE = 30; // number of frames per second. Movies use 24 frames per second, // but I am using 25 since it evenly divides 1000 milliseconds final int FRAMES_PER_SECOND = 25; final int FRAME_INTERVAL = 1000 / 25; LabeledBox boxes[]; int num_boxes; int num_seconds; Timer animationTimer; class mover implements ActionListener { int pixels_per_move = 4; final int UP = 0; final int RIGHT = 1; final int DOWN = 2; // the number of pixels that the boxes move vertically up or down final int VERTICAL_DISTANCE = 50; int action = UP; int startX; int endX; int startY; int endY; int totalDist; // total distance the boxes move LabeledBox upBox; LabeledBox downBox; public mover(LabeledBox box1, LabeledBox box2) { upBox = box1; downBox = box2; startX = upBox.getLeft(); endX = downBox.getLeft(); startY = upBox.getTop(); endY = startY - VERTICAL_DISTANCE; totalDist = 2*VERTICAL_DISTANCE + (endX - startX); pixels_per_move = totalDist / (FRAMES_PER_SECOND * num_seconds); } public void actionPerformed(ActionEvent evt) { int slack = 0; if (action == UP) { int tentativeTop = upBox.getTop() - pixels_per_move; if (tentativeTop > endY) { upBox.setPosition(upBox.getLeft(), tentativeTop); downBox.setPosition(downBox.getLeft(), downBox.getTop() + pixels_per_move); repaint(); return; } else { // start moving to the right by pegging the top and // bottom boxes to their maximum vertical extents and // take any additional pixels and add them to the x // direction action = RIGHT; slack = endY - tentativeTop; upBox.setPosition(startX, startY - VERTICAL_DISTANCE); downBox.setPosition(endX, startY + VERTICAL_DISTANCE); } } if (action == RIGHT) { int tentativeUpLeft; int tentativeDownLeft; if (slack != 0) { tentativeUpLeft = upBox.getLeft() + slack; tentativeDownLeft = downBox.getLeft() - slack; } else { tentativeUpLeft = upBox.getLeft() + pixels_per_move; tentativeDownLeft = downBox.getLeft() - pixels_per_move; } if (tentativeUpLeft < endX) { upBox.setPosition(tentativeUpLeft, upBox.getTop()); downBox.setPosition(tentativeDownLeft, downBox.getTop()); repaint(); return; } else { // peg the rectangles to their final Left positions and // start them moving vertically to their final vertical // positions action = DOWN; slack = tentativeUpLeft - endX; upBox.setPosition(endX, upBox.getTop()); downBox.setPosition(startX, downBox.getTop()); } } if (action == DOWN) { int tentativeTop; int tentativeBottom; if (slack == 0) { tentativeTop = upBox.getTop() + pixels_per_move; tentativeBottom = downBox.getTop() - pixels_per_move; } else { tentativeTop = upBox.getTop() + slack; tentativeBottom = downBox.getTop() - slack; } if (tentativeTop < startY) { upBox.setPosition(upBox.getLeft(), tentativeTop); downBox.setPosition(downBox.getLeft(), tentativeBottom); repaint(); return; } else { // we are done--peg the boxes to their new vertical positions upBox.setPosition(upBox.getLeft(), startY); downBox.setPosition(downBox.getLeft(), startY); repaint(); animationTimer.stop(); } } } } public animation(int number_of_boxes, int seconds) { num_seconds = seconds; num_boxes = number_of_boxes; Dimension size = getPreferredSize(); int starting_left = ((int)size.getWidth() - (num_boxes * BOX_SIZE)) / 2; int top = ((int)size.getHeight() - BOX_SIZE) / 2; boxes = new LabeledBox[num_boxes]; for (int i = 0; i < num_boxes; i++) { boxes[i] = new LabeledBox(String.valueOf(i), starting_left, top, BOX_SIZE); starting_left += BOX_SIZE; } ActionListener taskPerformer = new mover(boxes[1], boxes[6]); animationTimer = new Timer(FRAME_INTERVAL, taskPerformer); addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent me) { animationTimer.start(); } }); } public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D)g; for (int i = 0; i < num_boxes; i++) boxes[i].draw(g2); } public Dimension getPreferredSize() { return new Dimension(400, 300); } }