import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Exercise16_22 extends JFrame {
final static int NUMBER_OF_SLOTS = 9;
final static int NUMBER_OF_ROWS = NUMBER_OF_SLOTS - 2;
private int shift = 0;
private int[] slots = new int[NUMBER_OF_SLOTS];
private int numberOfBallsDropped = 0;
private int moveCount = 0;
private int position = 0;
private BeanMachinePanel paintPanel = new BeanMachinePanel();
private Timer timer = new Timer(200, new ActionListener() {
public void actionPerformed(ActionEvent e) {
moveCount++;
if (moveCount <= NUMBER_OF_ROWS) {
if (Math.random() < 0.5)
paintPanel.moveRedBallLeft();
else {
paintPanel.moveRedBallRight();
position++;
}
}
else {
slots[position]++;
paintPanel.startRedBall();
shift = 0;
moveCount = 0;
position = 0;
numberOfBallsDropped++;
if (numberOfBallsDropped == 10) {
timer.stop();
paintPanel.hideRedBall();
}
}
}
});
public Exercise16_22() {
add(paintPanel);
timer.start();
}
class BeanMachinePanel extends JPanel {
final static int HGAP = 20;
final static int VGAP = 20;
final static int RADIUS = 5;
final static int LENGTH_OF_SLOTS = 40;
final static int LENGTH_OF_OPENNING = 15;
final static int Y_FOR_FIRST_NAIL = 50;
final static int RED_BALL_START_Y = Y_FOR_FIRST_NAIL - RADIUS;
private int yRed = RED_BALL_START_Y;
private boolean hideRedBall = false;
/** Move the red ball down left */
public void moveRedBallLeft() {
shift -= HGAP / 2;
yRed += VGAP;
repaint();
}
/** Move the red ball down right */
public void moveRedBallRight() {
shift += HGAP / 2;
yRed += VGAP;
repaint();
}
/** Move the red ball down right */
public void startRedBall() {
yRed = RED_BALL_START_Y;
hideRedBall = false;
repaint();
}
/** Move the red ball down right */
public void hideRedBall() {
hideRedBall = true;
repaint();
}
/** Paint message */
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int y = Y_FOR_FIRST_NAIL;
int xCenter = getWidth() / 2;
// Draw the red ball
if (!hideRedBall) {
g.setColor(Color.RED);
int xRed = xCenter + shift;
g.fillOval(xRed - RADIUS, yRed - RADIUS, 2 * RADIUS, 2 * RADIUS);
}
// Draw pegs in multiple lines
g.setColor(Color.GREEN);
for (int i = 0; i < NUMBER_OF_ROWS; i++) {
y += VGAP;
for (int k = 0; k <= i; k++) {
g.fillOval(xCenter - i * HGAP / 2 + k * HGAP - RADIUS, y - RADIUS, 2 * RADIUS, 2 * RADIUS);
}
}
// Draw vertical lines for slots
g.setColor(Color.BLACK);
y = y + RADIUS;
for (int i = 0; i < NUMBER_OF_SLOTS; i++) {
int x = xCenter - (NUMBER_OF_ROWS - 1) * HGAP / 2 + (i - 1) * HGAP;
g.drawLine(x, y, x, y + LENGTH_OF_SLOTS);
}
// Draw a horizontal line for bottom
g.drawLine(xCenter - (NUMBER_OF_ROWS - 1) * HGAP / 2 - HGAP, y + LENGTH_OF_SLOTS,
xCenter - (NUMBER_OF_ROWS - 1) * HGAP / 2 + NUMBER_OF_ROWS * HGAP, y + LENGTH_OF_SLOTS);
// Draw two side lines
g.drawLine(xCenter + HGAP / 2, Y_FOR_FIRST_NAIL + RADIUS, xCenter - (NUMBER_OF_ROWS - 1) * HGAP / 2 + NUMBER_OF_ROWS * HGAP, y);
g.drawLine(xCenter - HGAP / 2, Y_FOR_FIRST_NAIL + RADIUS, xCenter - (NUMBER_OF_ROWS - 1) * HGAP / 2 - HGAP, y);
// Draw two vertical lines for the openning
g.drawLine(xCenter - HGAP / 2, Y_FOR_FIRST_NAIL + RADIUS, xCenter - HGAP / 2, Y_FOR_FIRST_NAIL - LENGTH_OF_OPENNING);
g.drawLine(xCenter + HGAP / 2, Y_FOR_FIRST_NAIL + RADIUS, xCenter + HGAP / 2, Y_FOR_FIRST_NAIL - LENGTH_OF_OPENNING);
// Paint the balls in the slots
g.setColor(Color.RED);
for (int i = 0; i < slots.length; i++) {
int x = xCenter - (NUMBER_OF_ROWS) * HGAP / 2 + i * HGAP;
for (int j = 0; j < slots[i]; j++) {
g.fillOval(x - RADIUS, y + LENGTH_OF_SLOTS - 2 * RADIUS - j * 2 * RADIUS, 2 * RADIUS, 2 * RADIUS);
}
}
}
}
public static void main(String[] args) {
JFrame frame = new Exercise16_22();
frame.setTitle("Exercise16_22");
frame.setSize(300, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}