Sie sind auf Seite 1von 103

Whack

A Java Mole

Table of Contents
Introduction

Coding 1: Getting started

Coding 2: Creating the Game Window

Coding 3: Panels and Labels

Coding 4: Creating the holes

Coding 5: Hit the moles

Coding 6: Timer, Start Button, Labels

Coding 7: Wrapping up - saving the highscore

Lesson 1: Getting started with Java

Lesson 2: Java basics

Lesson 3: Loops

10

Lesson 4: Classes and Objects

11

Lesson 5: An exercise on classes and objects

12

Lesson 6: File IO

13

Lesson 7: Graphical User Interface

14

Whack A Java Mole

Whack A Java Mole


Coding Curriculum Project 2016
Created by Byoung Hun Min, Wentao Wei, Hyojong Kim,
Xiaofeng Fu
This tutorial is designed for high school students between the age of 16-18 as it
requires some perseverance and problem-solving skills.
It is aimed to challenge the students and make them think computationally.

Introduction
By the end of this tutorial you will have the skills necessary to be able to create a
modified version of the Whack A Mole game in Java.
We will guide you through 7 coding lessons which will guide you through step-bystep on how to make the whack a mole game.
For those of you who need some basic knowledge in Java, we also provide 7
lessons which teach the core concepts of Java programming and Object-oriented
principles.

Before we begin..
Make sure you are:
Motivated to learn new things
Mentally prepared for challenges
Ready to focus and avoid getting distracted
It will also be useful to have the following:
The basic principles of programming
Familiar with using a text editor such as Notepad or basic IDE such as

Introduction

Whack A Java Mole


Eclipse
Preferably a Windows computer (Linux and Mac users can exit now ..........
Just kidding!)
We will guide you STEP-BY-STEP

Introduction

Whack A Java Mole

Coding 1: Getting started


What will we be creating?

A 4x4 Whack A Mole game where a mole will randomly


appear on any of the 16 holes and your objective is to
'whack' as many moles in the limited time of 30 seconds.

Before reading any further, it is highly recommended that you first read "Lesson
1: Get started with Java"
Unless you have prior experience with using Java and Eclipse IDE.

Now let's get started...


Start up Eclipse IDE and create a new 'Java Project'

Coding 1: Getting started

Whack A Java Mole


You can name the project anything you like, but here I name it:
'WhackAJavaMole"

Just click on 'Finish' and the project should now appear on the side Package
Explorer

Now we need to create a class.


So let's go ahead and right click on 'src' folder and click new -> class

Coding 1: Getting started

Whack A Java Mole

Next we will name the class Game and click Finish

Great! You are now all set up and ready to begin coding.

Coding 1: Getting started

Whack A Java Mole

Coding 2: Creating the Game Window


We will be using Java's Swing Library to create our Game Window.
If you would like to know more about Swing and Graphical User Interfaces, read
more about them in Lesson 7.
Carrying on from Coding 1...
Open up the Game class and you should see an empty class:
public class Game {
}

First, we need to inherit Swing Library's JFrame class in order to make our Game
class represent our Game Window. If you are unfamiliar with the concepts of
inheritence, I recommend you to read Lesson 4.
So how do we do this?
Simply extend the JFrame class:
public class Game extends JFrame{
}

Eclipse should tell you that JFrame cannot be resolved to a type. This is
because we haven't imported the library to our class, so we can do this now by
adding the following code to the top:
import javax.swing.JFrame;

The next thing we need in this class is a main function, which is the first function
that is executed when the program starts. So let's go ahead and make a main
method:

Coding 2: Creating the Game Window

Whack A Java Mole

public static void main(String[] args) {


}

Before we write the code for the main method, let's first create a constructor for
the game class like this:
public Game() {
}

In this constructor, we will initialise our JFrame attributes which will determine the
characteristics of our game window.
public Game() {
setTitle("Whack A Mole");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 608, 720);
}

setTitle("Whack A Mole") - sets the title of the window


setResizable(false) - forces the window to be a fixed size
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) - configures the window
such that when the user clicks the 'X' button on the top-right corner of the window,
the program will exit
setBounds(100, 100, 608, 720) - sets the x, y position of the window and the
width and height of the window (x, y, width, height)

Now that we have a constructor for the Game class, let's go


ahead and initialise a Game object in the main function.

Coding 2: Creating the Game Window

Whack A Java Mole

public static void main(String[] args) {


Game frame = new Game();
frame.setVisible(true);
}

Game frame = new Game() - instantiates a Game object called 'frame'


frame.setVisible(true) - makes the frame (Game object) visible on the screen

Now it's time to test our code we wrote so far...


Click on the green play button or hit Ctrl+F11

You should see an empty window on your screen with the title: WhackAMole

If you can't get this to show, do not worry, the full code for each coding lesson will
be posted at the bottom of the page.

Coding 2: Source Code

Coding 2: Creating the Game Window

10

Whack A Java Mole

import javax.swing.JFrame;
public class Game extends JFrame{
public Game() {
setTitle("Whack A Mole");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 608, 720);
}
public static void main(String[] args) {
Game frame = new Game();
frame.setVisible(true);
}
}

Coding 2: Creating the Game Window

11

Whack A Java Mole

Coding 3: JPanels and JLabels


In this coding lesson, we will be making a JPanel and some
Label components

What is a JPanel?
A JPanel is a container that can hold objects inside it. In order to display
something on our game window (JFrame) we need to create a content panel which is, as the name suggests, the container that displays the content of the
game window.
The content panel is the top-layer which will contain all the objects that are
displayed on the game window.

Create a content pane (JPanel)


In our constructor:
public Game() {
setTitle("Whack A Mole");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 608, 720);
}

Let's create a JPanel object


JPanel contentPane = new JPanel();

Did you forget to do something?


That's right. We need to import the JPanel first...

Coding 3: Panels and Labels

12

Whack A Java Mole

import javax.swing.JPanel;

It is quite tedious to have to import everytime we want to use a new Swing


component.. so there is a quick shortcut/trick to this: Press ctrl+shift+o to
automatically import all the libraries we need.
We can also customize our content panel, by setting a few attributes:
contentPane.setBackground(new Color(0, 51, 0));
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);

Finally, let's set the Content Panel of our JFrame (window) to this contentPane
object we just created
setContentPane(contentPane);

Now our constructor should look like this:


public Game() {
setTitle("Whack A Mole");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 608, 720);
JPanel contentPane = new JPanel();
contentPane = new JPanel();
contentPane.setBackground(new Color(0, 51, 0));
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);
setContentPane(contentPane);
}

If you run the program now, it should display a window with a green background.

Coding 3: Panels and Labels

13

Whack A Java Mole


The content panel will contain all of the objects that are displayed on the
screen, including the title, score, time remaining and moles.

Create a JLabel
To create a JLabel is very simple, it is the same procedure as creating a JPanel:
JLabel label = new JLabel();

So what is the purpose of a JLabel?


We can use the JLabel for displaying things such as: images, icons, titles,
descriptions, etc.
For our WhackAMole game, we will be using JLabels to display the Mole
images and to display some text

Add a title
Let's now use the JLabel component to display a title on our game window:
JLabel lblTitle = new JLabel("Whack A Mole");

Now let's set some attributes to it:


lblTitle.setForeground(new Color(153, 204, 0));
lblTitle.setHorizontalAlignment(SwingConstants.CENTER);
lblTitle.setFont(new Font("Century Gothic", Font.BOLD, 20));
lblTitle.setBounds(0, 0, 602, 47);

And finally add it to the content panel:


contentPane.add(lblTitle);

Coding 3: Panels and Labels

14

Whack A Java Mole


Now our game should look like this:

Coding 3: Source Code


import java.awt.Color;
import java.awt.Font;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;

public class Game extends JFrame{


public Game() {
setTitle("Whack A Mole");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 608, 720);

Coding 3: Panels and Labels

15

Whack A Java Mole

JPanel contentPane = new JPanel();


contentPane = new JPanel();
contentPane.setBackground(new Color(0, 51, 0));
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);
JLabel lblTitle = new JLabel("Whack A Mole");
lblTitle.setForeground(new Color(153, 204, 0));
lblTitle.setHorizontalAlignment(SwingConstants.CENTER);
lblTitle.setFont(new Font("Century Gothic", Font.BOLD, 20));
lblTitle.setBounds(0, 0, 602, 47);
contentPane.add(lblTitle);
setContentPane(contentPane);
}
public static void main(String[] args) {
Game frame = new Game();
frame.setVisible(true);
}
}

Coding 3: Panels and Labels

16

Whack A Java Mole

Coding 4: Creating the holes


In this coding lesson, we will finally be creating the holes!

How many holes do we need to create?


Our WhackAMole game is going to be played on a 4x4 grid so there will be 16
holes in total.
The grid should look something like this: (where the circle represents a mole)

Create a new JPanel on top of the content panel


We should now create a new JPanel which will represent the grid, where all the
holes will be displayed.
This time, our JPanel should not be declared inside the constructor. Instead, it
should be declared as a global variable. This means it is declared outside the
function and can therefore be accessed from anywhere within the class.

Coding 4: Creating the holes

17

Whack A Java Mole

public class Game extends JFrame{


private JPanel panel;
public Game() {
...
}
...

private simply means the panel object can only be accessed within this class:
Game
Now let's also set some attributes to this JPanel:
panel = new JPanel(); //initialise the object
panel.setBackground(new Color(0, 102, 0));
panel.setBounds(32, 105, 535, 546);
panel.setLayout(null);

Finally we can add the JPanel on top of the content panel:


contentPane.add(panel);

Inside the panel we want to add the 16 holes which we will represent using
JLabels. For this we will first create an array of size 16 which will store the
JLabels.
If you do not know what an array is or you're unfamiliar with using arrays in
Java, it is highly recommended to read Lesson 2: Java basics
The array will also be declared as a global variable so it can be accessed by
other functions (which we will implement later):

Coding 4: Creating the holes

18

Whack A Java Mole

public class Game extends JFrame{


private JPanel panel;
private JLabel[] holes = new JLabel[16];
public Game() {
...
panel = new JPanel();
panel.setBackground(new Color(0, 102, 0));
panel.setBounds(32, 105, 535, 546);
panel.setLayout(null);
contentPane.add(panel);
...
}
...

As you can see here we created a one-dimensional array of JLabels called: holes
and initialised the array to be size 16.
Now inside the constructor we can start creating the 16 JLabels, for instance:
holes[0] = new JLabel("0");
holes[0].setName("0");
holes[0].setBounds(0, 396, 132, 132);

And add it to our panel:


panel.add(holes[0]);

We simply have to repeat this 15 more times, only slightly modifying the numbers
each time (in setBounds the position would have to change so that the labels are
arranged in a 4x4 grid):
holes[0] = new JLabel("0");

Coding 4: Creating the holes

19

Whack A Java Mole


holes[0].setName("0");
holes[0].setBounds(0, 396, 132, 132);
panel.add(holes[0]);
holes[1] = new JLabel("1");
holes[1].setName("1");
holes[1].setBounds(132, 396, 132, 132);
panel.add(holes[1]);
holes[2] = new JLabel("2");
holes[2].setName("2");
holes[2].setBounds(264, 396, 132, 132);
panel.add(holes[2]);
holes[3] = new JLabel("3");
holes[3].setName("3");
holes[3].setBounds(396, 396, 132, 132);
panel.add(holes[3]);
holes[4] = new JLabel("4");
holes[4].setName("4");
holes[4].setBounds(0, 264, 132, 132);
panel.add(holes[4]);
holes[5] = new JLabel("5");
holes[5].setName("5");
holes[5].setBounds(132, 264, 132, 132);
panel.add(holes[5]);
holes[6] = new JLabel("6");
holes[6].setName("6");
holes[6].setBounds(264, 264, 132, 132);
panel.add(holes[6]);
holes[7] = new JLabel("7");
holes[7].setName("7");
holes[7].setBounds(396, 264, 132, 132);
panel.add(holes[7]);
holes[8] = new JLabel("8");

Coding 4: Creating the holes

20

Whack A Java Mole


holes[8].setName("8");
holes[8].setBounds(0, 132, 132, 132);
panel.add(holes[8]);
holes[9] = new JLabel("9");
holes[9].setName("9");
holes[9].setBounds(132, 132, 132, 132);
panel.add(holes[9]);
holes[10] = new JLabel("10");
holes[10].setName("10");
holes[10].setBounds(264, 132, 132, 132);
panel.add(holes[10]);
holes[11] = new JLabel("11");
holes[11].setName("11");
holes[11].setBounds(396, 132, 132, 132);
panel.add(holes[11]);
holes[12] = new JLabel("12");
holes[12].setName("12");
holes[12].setBounds(0, 0, 132, 132);
panel.add(holes[12]);
holes[13] = new JLabel("13");
holes[13].setName("13");
holes[13].setBounds(132, 0, 132, 132);
panel.add(holes[13]);
holes[14] = new JLabel("14");
holes[14].setName("14");
holes[14].setBounds(264, 0, 132, 132);
panel.add(holes[14]);
holes[15] = new JLabel("15");
holes[15].setName("15");
holes[15].setBounds(396, 0, 132, 132);
panel.add(holes[15]);

Coding 4: Creating the holes

21

Whack A Java Mole


You may have noticed that we are not setting any image to the labels at the
moment, so right now they just display a number: 0-15.
Since all the JLabels will have the same initial image (a empty hole image)
we can use a loop to set all of the JLabel images to display an empty hole.
If you are unfamiliar with loops, please read Lesson 5

First, go ahead and save the following image: moleIn.png


Right click on your project folder and click New -> Source Folder:

Create a new source folder called: res


This folder will contain the images (resources) used in this game.
So now simply drag and drop the moleIn.png image file into the res folder.

Now we are ready to add the image to our JLabels


Let's make a function that will help us load the image
private ImageIcon loadImage(String path){
}

Coding 4: Creating the holes

22

Whack A Java Mole


This function takes in a string and returns an ImageIcon object

Inside the function, we will first create an ImageIcon object, by calling it's
constructor with the relative path we give it.
Image image = new ImageIcon(this.getClass().getResource(path)).getImage();

The following segment of the line:


this.getClass().getResource

simply points to the "res" folder we just created.

Next, we need to scale (resize) our image to fit the Label dimension is
132x132 pixels

Image scaledImage = image.getScaledInstance(132, 132, java.awt.Image.SCALE_

Finally, we can convert our scaled image back into an ImageIcon object and
return it
return new ImageIcon(scaledImage);

Now our loadImage function should look like this:


private ImageIcon loadImage(String path){

Image image = new ImageIcon(this.getClass().getResource(path)).getImage(

Image scaledImage = image.getScaledInstance(132, 132, java.awt.Image.SC


return new ImageIcon(scaledImage);
}

Coding 4: Creating the holes

23

Whack A Java Mole


Now we can loop through our array of labels and set each of it's icon to
moleIn.png
Make sure to do this inside the constructor after initialising all the labels in the
'holes' array.
for(int i = 0; i < 16; i++){
holes[i].setIcon(loadImage("/moleIn.png"));
}

It's time to test the program! Let's run it.

If you have this showing on your screen right now, congratulations you have
followed the steps correctly so far.
If not, do not worry.
Your code up to this point should look like this:
import java.awt.Color;
import java.awt.Font;
import java.awt.Image;

Coding 4: Creating the holes

24

Whack A Java Mole


import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;

public class Game extends JFrame{


private JPanel panel;
private JLabel[] holes = new JLabel[16];
private ImageIcon loadImage(String path){

Image image = new ImageIcon(this.getClass().getResource(path)).getIm

Image scaledImage = image.getScaledInstance(132, 132, java.awt.Imag


return new ImageIcon(scaledImage);
}
public Game() {
setTitle("Whack A Mole");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 608, 720);
JPanel contentPane = new JPanel();
contentPane = new JPanel();
contentPane.setBackground(new Color(0, 51, 0));
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);
JLabel lblTitle = new JLabel("Whack A Mole");
lblTitle.setForeground(new Color(153, 204, 0));
lblTitle.setHorizontalAlignment(SwingConstants.CENTER);
lblTitle.setFont(new Font("Century Gothic", Font.BOLD, 20));
lblTitle.setBounds(0, 0, 602, 47);
contentPane.add(lblTitle);
panel = new JPanel();
panel.setBackground(new Color(0, 102, 0));

Coding 4: Creating the holes

25

Whack A Java Mole


panel.setBounds(32, 105, 535, 546);
panel.setLayout(null);
contentPane.add(panel);
holes[0] = new JLabel("0");
holes[0].setName("0");
holes[0].setBounds(0, 396, 132, 132);
panel.add(holes[0]);
holes[1] = new JLabel("1");
holes[1].setName("1");
holes[1].setBounds(132, 396, 132, 132);
panel.add(holes[1]);
holes[2] = new JLabel("2");
holes[2].setName("2");
holes[2].setBounds(264, 396, 132, 132);
panel.add(holes[2]);
holes[3] = new JLabel("3");
holes[3].setName("3");
holes[3].setBounds(396, 396, 132, 132);
panel.add(holes[3]);
holes[4] = new JLabel("4");
holes[4].setName("4");
holes[4].setBounds(0, 264, 132, 132);
panel.add(holes[4]);
holes[5] = new JLabel("5");
holes[5].setName("5");
holes[5].setBounds(132, 264, 132, 132);
panel.add(holes[5]);
holes[6] = new JLabel("6");
holes[6].setName("6");
holes[6].setBounds(264, 264, 132, 132);
panel.add(holes[6]);
holes[7] = new JLabel("7");

Coding 4: Creating the holes

26

Whack A Java Mole


holes[7].setName("7");
holes[7].setBounds(396, 264, 132, 132);
panel.add(holes[7]);
holes[8] = new JLabel("8");
holes[8].setName("8");
holes[8].setBounds(0, 132, 132, 132);
panel.add(holes[8]);
holes[9] = new JLabel("9");
holes[9].setName("9");
holes[9].setBounds(132, 132, 132, 132);
panel.add(holes[9]);
holes[10] = new JLabel("10");
holes[10].setName("10");
holes[10].setBounds(264, 132, 132, 132);
panel.add(holes[10]);
holes[11] = new JLabel("11");
holes[11].setName("11");
holes[11].setBounds(396, 132, 132, 132);
panel.add(holes[11]);
holes[12] = new JLabel("12");
holes[12].setName("12");
holes[12].setBounds(0, 0, 132, 132);
panel.add(holes[12]);
holes[13] = new JLabel("13");
holes[13].setName("13");
holes[13].setBounds(132, 0, 132, 132);
panel.add(holes[13]);
holes[14] = new JLabel("14");
holes[14].setName("14");
holes[14].setBounds(264, 0, 132, 132);
panel.add(holes[14]);
holes[15] = new JLabel("15");

Coding 4: Creating the holes

27

Whack A Java Mole


holes[15].setName("15");
holes[15].setBounds(396, 0, 132, 132);
panel.add(holes[15]);
for(int i = 0; i < 16; i++){
holes[i].setIcon(loadImage("/moleIn.png"));
}
setContentPane(contentPane);
}
public static void main(String[] args) {
Game frame = new Game();
frame.setVisible(true);
}
}

Now we need to start implementing the Game Board array


which will determine the state of each of the 16 holes (mole
peeking out or mole hidden inside)
We will use an int to represent the state: 0 = empty hole, 1 = mole peeking out
of hole
So let's go ahead an create a one-dimensional integer array of size 16:
private int[] board = new int[16];

Make sure it is a global variable (do not place it inside any function or the
constructor)
Now go back to the code that loops through the labels:

Coding 4: Creating the holes

28

Whack A Java Mole

for(int i = 0; i < 16; i++){


holes[i].setIcon(loadImage("/moleIn.png"));
}

And add a line of code inside the loop which initialises the 'board' array values to
0:
for(int i = 0; i < 16; i++){
holes[i].setIcon(loadImage("/moleIn.png"));
board[i] = 0;
}

Create a function which generates a random number 0-15


which determines which hole a mole will appear from
The scope of our game will be limited so that one mole can appear from any hole
at one point and the goal is to hit the mole as fast as possible.
So let's create the function
private void genRandMole(){

Random rnd = new Random(System.currentTimeMillis()); //seeding random wi


int moleID = rnd.nextInt(16);
board[moleID] = 1;
holes[moleID].setIcon(loadImage("/moleOut.png"));
}

Random rnd = new Random(System.currentTimeMillis()); - initialises a


Random object
int moleID = rnd.nextInt(16); - declares a variable 'moleID' and assigns it to a
random integer between 0 and 15
board[moleID] = 1; - set's the board index 'moleID' to 1 which indicates that the
mole is peeking out of the hole.

Coding 4: Creating the holes

29

Whack A Java Mole


holes[moleID].setIcon(loadImage("/moleOut.png")); - set's the label from the
'holes' array at index 'moleID' to the image displaying the mole peeking out of the
hole.
Note that moleOut.png should also be saved in the 'res' folder of the project
for this to work. Simply save the following image as: 'moleOut.png' and move it
into the 'res' folder.

We will use this function in the next lesson so stay


tuned.
Coding 4: Source Code
import java.awt.Color;
import java.awt.Font;
import java.awt.Image;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;

public class Game extends JFrame{


private JPanel panel;
private JLabel[] holes = new JLabel[16];
private int[] board = new int[16];
private void genRandMole(){

Random rnd = new Random(System.currentTimeMillis()); //seeding rando


int moleID = rnd.nextInt(16);

Coding 4: Creating the holes

30

Whack A Java Mole


board[moleID] = 1;
holes[moleID].setIcon(loadImage("/moleOut.png"));
}
private ImageIcon loadImage(String path){

Image image = new ImageIcon(this.getClass().getResource(path)).getIm

Image scaledImage = image.getScaledInstance(132, 132, java.awt.Imag


return new ImageIcon(scaledImage);
}
public Game() {
setTitle("Whack A Mole");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 608, 720);
JPanel contentPane = new JPanel();
contentPane = new JPanel();
contentPane.setBackground(new Color(0, 51, 0));
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);
JLabel lblTitle = new JLabel("Whack A Mole");
lblTitle.setForeground(new Color(153, 204, 0));
lblTitle.setHorizontalAlignment(SwingConstants.CENTER);
lblTitle.setFont(new Font("Century Gothic", Font.BOLD, 20));
lblTitle.setBounds(0, 0, 602, 47);
contentPane.add(lblTitle);
panel = new JPanel();
panel.setBackground(new Color(0, 102, 0));
panel.setBounds(32, 105, 535, 546);
panel.setLayout(null);
contentPane.add(panel);
holes[0] = new JLabel("0");
holes[0].setName("0");
holes[0].setBounds(0, 396, 132, 132);
panel.add(holes[0]);

Coding 4: Creating the holes

31

Whack A Java Mole


holes[1] = new JLabel("1");
holes[1].setName("1");
holes[1].setBounds(132, 396, 132, 132);
panel.add(holes[1]);
holes[2] = new JLabel("2");
holes[2].setName("2");
holes[2].setBounds(264, 396, 132, 132);
panel.add(holes[2]);
holes[3] = new JLabel("3");
holes[3].setName("3");
holes[3].setBounds(396, 396, 132, 132);
panel.add(holes[3]);
holes[4] = new JLabel("4");
holes[4].setName("4");
holes[4].setBounds(0, 264, 132, 132);
panel.add(holes[4]);
holes[5] = new JLabel("5");
holes[5].setName("5");
holes[5].setBounds(132, 264, 132, 132);
panel.add(holes[5]);
holes[6] = new JLabel("6");
holes[6].setName("6");
holes[6].setBounds(264, 264, 132, 132);
panel.add(holes[6]);
holes[7] = new JLabel("7");
holes[7].setName("7");
holes[7].setBounds(396, 264, 132, 132);
panel.add(holes[7]);
holes[8] = new JLabel("8");
holes[8].setName("8");
holes[8].setBounds(0, 132, 132, 132);
panel.add(holes[8]);

Coding 4: Creating the holes

32

Whack A Java Mole


holes[9] = new JLabel("9");
holes[9].setName("9");
holes[9].setBounds(132, 132, 132, 132);
panel.add(holes[9]);
holes[10] = new JLabel("10");
holes[10].setName("10");
holes[10].setBounds(264, 132, 132, 132);
panel.add(holes[10]);
holes[11] = new JLabel("11");
holes[11].setName("11");
holes[11].setBounds(396, 132, 132, 132);
panel.add(holes[11]);
holes[12] = new JLabel("12");
holes[12].setName("12");
holes[12].setBounds(0, 0, 132, 132);
panel.add(holes[12]);
holes[13] = new JLabel("13");
holes[13].setName("13");
holes[13].setBounds(132, 0, 132, 132);
panel.add(holes[13]);
holes[14] = new JLabel("14");
holes[14].setName("14");
holes[14].setBounds(264, 0, 132, 132);
panel.add(holes[14]);
holes[15] = new JLabel("15");
holes[15].setName("15");
holes[15].setBounds(396, 0, 132, 132);
panel.add(holes[15]);
for(int i = 0; i < 16; i++){
holes[i].setIcon(loadImage("/moleIn.png"));
board[i] = 0;
}

Coding 4: Creating the holes

33

Whack A Java Mole


setContentPane(contentPane);
}
public static void main(String[] args) {
Game frame = new Game();
frame.setVisible(true);
}
}

Coding 4: Creating the holes

34

Whack A Java Mole

Coding 5: Hit the moles


Be prepared as this coding lesson will be a lot more challenging than the
previous ones.

Before diving into the next part, let's first organise


the code we have written so far.
We will group our code into separate functions (methods)
and call them when we need to use them.
Recall that in our constructor: public Game(){..} we he have the following lines of
code:
for(int i = 0; i < 16; i++){
holes[i].setIcon(loadImage("/moleIn.png"));
board[i] = 0;
}

which initialises the icons and board array to display empty holes on all 16 labels.
It is a better idea to create a separate function for this, as we may need to
use it more than once.
So go ahead and make a function and copy-paste the code in there like this:
private void clearBoard(){
for(int i = 0; i < 16; i++){
holes[i].setIcon(loadImage("/moleIn.png"));
board[i] = 0;
}
}

Let's also group all the code in the constructor that is related to initialising the
GUI (Swing components) and call the function: initGUI:

Coding 5: Hit the moles

35

Whack A Java Mole

private void initGUI(){


setTitle("Whack A Mole");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 608, 720);
JPanel contentPane = new JPanel();
contentPane = new JPanel();
contentPane.setBackground(new Color(0, 51, 0));
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);
JLabel lblTitle = new JLabel("Whack A Mole");
lblTitle.setForeground(new Color(153, 204, 0));
lblTitle.setHorizontalAlignment(SwingConstants.CENTER);
lblTitle.setFont(new Font("Century Gothic", Font.BOLD, 20));
lblTitle.setBounds(0, 0, 602, 47);
contentPane.add(lblTitle);
panel = new JPanel();
panel.setBackground(new Color(0, 102, 0));
panel.setBounds(32, 105, 535, 546);
panel.setLayout(null);
contentPane.add(panel);
holes[0] = new JLabel("0");
holes[0].setName("0");
holes[0].setBounds(0, 396, 132, 132);
panel.add(holes[0]);
holes[1] = new JLabel("1");
holes[1].setName("1");
holes[1].setBounds(132, 396, 132, 132);
panel.add(holes[1]);
holes[2] = new JLabel("2");
holes[2].setName("2");
holes[2].setBounds(264, 396, 132, 132);
panel.add(holes[2]);

Coding 5: Hit the moles

36

Whack A Java Mole


holes[3] = new JLabel("3");
holes[3].setName("3");
holes[3].setBounds(396, 396, 132, 132);
panel.add(holes[3]);
holes[4] = new JLabel("4");
holes[4].setName("4");
holes[4].setBounds(0, 264, 132, 132);
panel.add(holes[4]);
holes[5] = new JLabel("5");
holes[5].setName("5");
holes[5].setBounds(132, 264, 132, 132);
panel.add(holes[5]);
holes[6] = new JLabel("6");
holes[6].setName("6");
holes[6].setBounds(264, 264, 132, 132);
panel.add(holes[6]);
holes[7] = new JLabel("7");
holes[7].setName("7");
holes[7].setBounds(396, 264, 132, 132);
panel.add(holes[7]);
holes[8] = new JLabel("8");
holes[8].setName("8");
holes[8].setBounds(0, 132, 132, 132);
panel.add(holes[8]);
holes[9] = new JLabel("9");
holes[9].setName("9");
holes[9].setBounds(132, 132, 132, 132);
panel.add(holes[9]);
holes[10] = new JLabel("10");
holes[10].setName("10");
holes[10].setBounds(264, 132, 132, 132);
panel.add(holes[10]);

Coding 5: Hit the moles

37

Whack A Java Mole


holes[11] = new JLabel("11");
holes[11].setName("11");
holes[11].setBounds(396, 132, 132, 132);
panel.add(holes[11]);
holes[12] = new JLabel("12");
holes[12].setName("12");
holes[12].setBounds(0, 0, 132, 132);
panel.add(holes[12]);
holes[13] = new JLabel("13");
holes[13].setName("13");
holes[13].setBounds(132, 0, 132, 132);
panel.add(holes[13]);
holes[14] = new JLabel("14");
holes[14].setName("14");
holes[14].setBounds(264, 0, 132, 132);
panel.add(holes[14]);
holes[15] = new JLabel("15");
holes[15].setName("15");
holes[15].setBounds(396, 0, 132, 132);
panel.add(holes[15]);
setContentPane(contentPane);
}

Finally, in the constructor we can call the two functions we just created:
public Game() {
initGUI();
clearBoard();
}

Make sure to call: initGUI() first, so the label array is initialised. Then we can call
clearBoard() to set the values to 0 and set the imageicons to 'moleIn.png'

Coding 5: Hit the moles

38

Whack A Java Mole

Mouse Events - detecting mouse click on JLabel


For each label (representing a hole or mole) we need to add a Mouse Click Event
Listener, which basically executes certain code when the corresponding label
detects a mouse click.
To do this, we must first loop through each label in the array.
Then, add a mouse listener for each label.

As this is beyond the scope of this tutorial, how the Mouse Listener Event works
will not be explained in detail.
We can now create a function: initEvents() which will contain all the code that
adds event listeners. For now, let's add the mouse click event listener to each
label.
private void initEvents(){
for(int i = 0; i < holes.length; i++){
holes[i].addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e){
JLabel lbl = (JLabel)e.getSource();
int id = Integer.parseInt(lbl.getName());
pressedButton(id);
}
});
}
}

Don't forget to call this function in the constructor:


public Game() {
initGUI();
clearBoard();
initEvents();
}

Coding 5: Hit the moles

39

Whack A Java Mole


As you can see, we now need to implement the pressedButton() function..
This function should do the following:
(1) check whether the pressed button (label) is a mole or an empty hole
(2) if it is a mole, increase the score by 1
(3) if it is an empty hole, decrease the score by 1 (this is the penalty for missing)
(4) update the score label (5) clear the board (reset it)
(6) generate another random mole
So first, let's create a global variable to store the score:
private int score = 0;

Now we can create the pressedButton function..


private void pressedButton(int id){
int val = board[id];
//if val is 1 = mole
//if val is 0 = empty hole
if(val==1){
score++;
}else{ //val==0
score--;
}
lblScore.setText("Score: " + score); //update the score
clearBoard();
genRandMole();
}

Note that we are calling the functions: clearBoard() and genRandMole() which
we created earlier.

Now try running the game, you should be able to click on a


hole/mole, and see a random mole appear.
Coding 5: Hit the moles

40

Whack A Java Mole

Coding 5: Source Code


import java.awt.Color;
import java.awt.Font;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;

public class Game extends JFrame{


private JPanel panel;
private JLabel[] holes = new JLabel[16];
private int[] board = new int[16];
private int score = 0;
private void pressedButton(int id){
int val = board[id];
//if val is 1 = mole
//if val is 0 = empty hole
if(val==1){
score++;
}else{ //val==0
score--;
}
lblScore.setText("Score: " + score); //update the score
clearBoard();

Coding 5: Hit the moles

41

Whack A Java Mole

genRandMole();
}
private void initEvents(){
for(int i = 0; i < holes.length; i++){
holes[i].addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e){
JLabel lbl = (JLabel)e.getSource();
int id = Integer.parseInt(lbl.getName());
pressedButton(id);
}
});
}
}
private void initGUI(){
setTitle("Whack A Mole");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 608, 720);
JPanel contentPane = new JPanel();
contentPane = new JPanel();
contentPane.setBackground(new Color(0, 51, 0));
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);
JLabel lblTitle = new JLabel("Whack A Mole");
lblTitle.setForeground(new Color(153, 204, 0));
lblTitle.setHorizontalAlignment(SwingConstants.CENTER);
lblTitle.setFont(new Font("Century Gothic", Font.BOLD, 20));
lblTitle.setBounds(0, 0, 602, 47);
contentPane.add(lblTitle);
panel = new JPanel();
panel.setBackground(new Color(0, 102, 0));
panel.setBounds(32, 105, 535, 546);
panel.setLayout(null);
contentPane.add(panel);

Coding 5: Hit the moles

42

Whack A Java Mole

holes[0] = new JLabel("0");


holes[0].setName("0");
holes[0].setBounds(0, 396, 132, 132);
panel.add(holes[0]);
holes[1] = new JLabel("1");
holes[1].setName("1");
holes[1].setBounds(132, 396, 132, 132);
panel.add(holes[1]);
holes[2] = new JLabel("2");
holes[2].setName("2");
holes[2].setBounds(264, 396, 132, 132);
panel.add(holes[2]);
holes[3] = new JLabel("3");
holes[3].setName("3");
holes[3].setBounds(396, 396, 132, 132);
panel.add(holes[3]);
holes[4] = new JLabel("4");
holes[4].setName("4");
holes[4].setBounds(0, 264, 132, 132);
panel.add(holes[4]);
holes[5] = new JLabel("5");
holes[5].setName("5");
holes[5].setBounds(132, 264, 132, 132);
panel.add(holes[5]);
holes[6] = new JLabel("6");
holes[6].setName("6");
holes[6].setBounds(264, 264, 132, 132);
panel.add(holes[6]);
holes[7] = new JLabel("7");
holes[7].setName("7");
holes[7].setBounds(396, 264, 132, 132);
panel.add(holes[7]);

Coding 5: Hit the moles

43

Whack A Java Mole

holes[8] = new JLabel("8");


holes[8].setName("8");
holes[8].setBounds(0, 132, 132, 132);
panel.add(holes[8]);
holes[9] = new JLabel("9");
holes[9].setName("9");
holes[9].setBounds(132, 132, 132, 132);
panel.add(holes[9]);
holes[10] = new JLabel("10");
holes[10].setName("10");
holes[10].setBounds(264, 132, 132, 132);
panel.add(holes[10]);
holes[11] = new JLabel("11");
holes[11].setName("11");
holes[11].setBounds(396, 132, 132, 132);
panel.add(holes[11]);
holes[12] = new JLabel("12");
holes[12].setName("12");
holes[12].setBounds(0, 0, 132, 132);
panel.add(holes[12]);
holes[13] = new JLabel("13");
holes[13].setName("13");
holes[13].setBounds(132, 0, 132, 132);
panel.add(holes[13]);
holes[14] = new JLabel("14");
holes[14].setName("14");
holes[14].setBounds(264, 0, 132, 132);
panel.add(holes[14]);
holes[15] = new JLabel("15");
holes[15].setName("15");
holes[15].setBounds(396, 0, 132, 132);
panel.add(holes[15]);

Coding 5: Hit the moles

44

Whack A Java Mole

setContentPane(contentPane);
}
private void clearBoard(){
for(int i = 0; i < 16; i++){
holes[i].setIcon(loadImage("/moleIn.png"));
board[i] = 0;
}
}
private void genRandMole(){

Random rnd = new Random(System.currentTimeMillis()); //seeding rando


int moleID = rnd.nextInt(16);
board[moleID] = 1;
holes[moleID].setIcon(loadImage("/moleOut.png"));
}
private ImageIcon loadImage(String path){

Image image = new ImageIcon(this.getClass().getResource(path)).getIm

Image scaledImage = image.getScaledInstance(132, 132, java.awt.Imag


return new ImageIcon(scaledImage);
}
public Game() {
initGUI();
clearBoard();
initEvents();
}
public static void main(String[] args) {
Game frame = new Game();
frame.setVisible(true);
}
}

Coding 5: Hit the moles

45

Whack A Java Mole

Coding 6: Timer, Start Button, Labels


We will finally be implementing the timer which will
count down from 30 seconds
And we will also create the start button and a label
to display the score, highscore and time remaining
By now you should be familiar with creating a JLabel component.
The score label should be a global object, so we can access it from anywhere
inside the Game class.
So let's define the JLabel object in global space:
private JLabel lblScore;

Now go to the initGUI() function, and initialise the lblScore object.


lblScore = new JLabel("Score: 0");
lblScore.setHorizontalAlignment(SwingConstants.TRAILING);
lblScore.setFont(new Font("Cambria", Font.BOLD, 14));
lblScore.setForeground(new Color(135, 206, 250));
lblScore.setBounds(423, 54, 144, 33);
contentPane.add(lblScore);

The code above should be pretty self-explanatory.


Let's do the exact same thing for our high-score label and time-remaining
label:
private JLabel lblTimeLeft;
private JLabel lblHighscore;

Inside the initGUI() function:

Coding 6: Timer, Start Button, Labels

46

Whack A Java Mole

lblTimeLeft = new JLabel("30");


lblTimeLeft.setHorizontalAlignment(SwingConstants.CENTER);
lblTimeLeft.setForeground(new Color(240, 128, 128));
lblTimeLeft.setFont(new Font("Cambria Math", Font.BOLD, 24));
lblTimeLeft.setBounds(232, 54, 144, 33);
contentPane.add(lblTimeLeft);
lblHighscore = new JLabel("Highscore: 0");
lblHighscore.setHorizontalAlignment(SwingConstants.TRAILING);
lblHighscore.setForeground(new Color(255, 255, 0));
lblHighscore.setFont(new Font("Cambria", Font.BOLD, 14));
lblHighscore.setBounds(433, 18, 134, 33);
contentPane.add(lblHighscore);

Notice that the argument values in setBounds is different for each object as this
determines the size and location of the object in the window.
Before we carry on, let's also create the global variables that will store the
highscore and time remaining:
Add the following to global space:
private int timeLeft = 30;
private int highscore = 0;

Create a JButton object


We will now create a 'Start' button, in a similar way of creating the JLabels above.
Define the JButton in global space:
private JButton btnStart;

Next, initialise the JButton object in the initGUI() function:

Coding 6: Timer, Start Button, Labels

47

Whack A Java Mole

btnStart = new JButton("Start");


btnStart.setBackground(Color.WHITE);
btnStart.setBounds(32, 60, 110, 33);
contentPane.add(btnStart);

In order for the button to do something when it is clicked, we need to add an


Action Event Listener to it
Go to the initEvents() function and add the event listener:
btnStart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
btnStart.setEnabled(false);
clearBoard();
genRandMole();
timer.start();
}
});

When the button is clicked, the following actions will occur:


(1) The start button is disabled
(2) The board is cleared and reset (all the labels set to empty hole)
(3) A random mole is generated
(4) The timer is started
There should be an error if you try to run the program now, as we haven't
yet implemented the timer. So let's go ahead and do that now!
Define a timer object in global space:
private Timer timer;

Initialise the timer in the initEvents() function:

Coding 6: Timer, Start Button, Labels

48

Whack A Java Mole

timer = new Timer(1000, new ActionListener() {


public void actionPerformed(ActionEvent evt) {
if(timeLeft == 0){
lblTimeLeft.setText("" + timeLeft);
timer.stop();
gameOver();
}
lblTimeLeft.setText("" + timeLeft);
timeLeft--;
}
});

The code above performs the following steps:


(1) Initialise a timer and an action listener, which is triggered every 1000ms (1
second)
(2) First, check if there is any time left
(3) If the time has run out (timeLeft = 0), then update the label, stop the timer and
call the function: gameOver()
(4) Finally, update the label and decrease the timeLeft by 1 (this will essentially
function as a countdown timer)

Implementing the gameOver() function


What should happen when the game is over and the time remaining is 0?
(1) Re-enable the 'start' button
(2) Check whether the high score has been beaten, update the highscore variable
accordingly
(3) Display a messagebox to the user indicating that the game is over
(4) Reset all the variables: set score=0, timeLeft=30 (same with the corresponding
labels)
(5) Clear the board
Create the gameOver() function:

Coding 6: Timer, Start Button, Labels

49

Whack A Java Mole

private void gameOver(){


btnStart.setEnabled(true);
if(score > highscore){
highscore = score;
lblHighscore.setText("Highscore: " + highscore);

JOptionPane.showMessageDialog(this, "Your final score is: " + score,


}else{

JOptionPane.showMessageDialog(this, "Your final score is: " + score,


}
score = 0;
timeLeft = 30;
lblScore.setText("Score: 0");
lblTimeLeft.setText("30");
clearBoard();
}

JOptionPane is another Swing component which basically displays a message


box

If you have gotten this far, great job!


You should now have a fully functional Whack A Mole
game!

Coding 6: Timer, Start Button, Labels

50

Whack A Java Mole

Wait a second, we are not finished yet...


There are still a few extra stuff we need to implement:
In the next coding lesson, we will cover:
(1) Styling the cursor into a hammer icon (2) Saving the highscore to a text file (3)
Reading the highscore from the text file when the program is opened

Coding 6: Source Code


import java.awt.Color;
import java.awt.Font;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JButton;

Coding 6: Timer, Start Button, Labels

51

Whack A Java Mole


import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;

public class Game extends JFrame{


private JPanel panel;
private JLabel[] holes = new JLabel[16];
private int[] board = new int[16];
private int score = 0;
private int timeLeft = 30;
private int highscore = 0;
private JLabel lblScore;
private JLabel lblTimeLeft;
private JLabel lblHighscore;
private JButton btnStart;
private Timer timer;
private void gameOver(){
btnStart.setEnabled(true);
if(score > highscore){
highscore = score;
lblHighscore.setText("Highscore: " + highscore);

JOptionPane.showMessageDialog(this, "Your final score is: " + sc


}else{

JOptionPane.showMessageDialog(this, "Your final score is: " + sc


}
score = 0;
timeLeft = 30;
lblScore.setText("Score: 0");
lblTimeLeft.setText("30");

Coding 6: Timer, Start Button, Labels

52

Whack A Java Mole


clearBoard();
}
private void pressedButton(int id){
int val = board[id];
//if val is 1 = mole
//if val is 0 = empty hole
if(val==1){
score++;
}else{ //val==0
score--;
}
lblScore.setText("Score: " + score); //update the score
clearBoard();
genRandMole();
}
private void initEvents(){
for(int i = 0; i < holes.length; i++){
holes[i].addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e){
JLabel lbl = (JLabel)e.getSource();
int id = Integer.parseInt(lbl.getName());
pressedButton(id);
}
});
}
btnStart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
btnStart.setEnabled(false);
clearBoard();
genRandMole();
timer.start();
}
});

Coding 6: Timer, Start Button, Labels

53

Whack A Java Mole

timer = new Timer(1000, new ActionListener() {


public void actionPerformed(ActionEvent evt) {
if(timeLeft == 0){
lblTimeLeft.setText("" + timeLeft);
timer.stop();
gameOver();
}
lblTimeLeft.setText("" + timeLeft);
timeLeft--;
}
});
}
private void initGUI(){
setTitle("Whack A Mole");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 608, 720);
JPanel contentPane = new JPanel();
contentPane = new JPanel();
contentPane.setBackground(new Color(0, 51, 0));
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);
JLabel lblTitle = new JLabel("Whack A Mole");
lblTitle.setForeground(new Color(153, 204, 0));
lblTitle.setHorizontalAlignment(SwingConstants.CENTER);
lblTitle.setFont(new Font("Century Gothic", Font.BOLD, 20));
lblTitle.setBounds(0, 0, 602, 47);
contentPane.add(lblTitle);
panel = new JPanel();
panel.setBackground(new Color(0, 102, 0));
panel.setBounds(32, 105, 535, 546);
panel.setLayout(null);
contentPane.add(panel);
holes[0] = new JLabel("0");

Coding 6: Timer, Start Button, Labels

54

Whack A Java Mole


holes[0].setName("0");
holes[0].setBounds(0, 396, 132, 132);
panel.add(holes[0]);
holes[1] = new JLabel("1");
holes[1].setName("1");
holes[1].setBounds(132, 396, 132, 132);
panel.add(holes[1]);
holes[2] = new JLabel("2");
holes[2].setName("2");
holes[2].setBounds(264, 396, 132, 132);
panel.add(holes[2]);
holes[3] = new JLabel("3");
holes[3].setName("3");
holes[3].setBounds(396, 396, 132, 132);
panel.add(holes[3]);
holes[4] = new JLabel("4");
holes[4].setName("4");
holes[4].setBounds(0, 264, 132, 132);
panel.add(holes[4]);
holes[5] = new JLabel("5");
holes[5].setName("5");
holes[5].setBounds(132, 264, 132, 132);
panel.add(holes[5]);
holes[6] = new JLabel("6");
holes[6].setName("6");
holes[6].setBounds(264, 264, 132, 132);
panel.add(holes[6]);
holes[7] = new JLabel("7");
holes[7].setName("7");
holes[7].setBounds(396, 264, 132, 132);
panel.add(holes[7]);
holes[8] = new JLabel("8");

Coding 6: Timer, Start Button, Labels

55

Whack A Java Mole


holes[8].setName("8");
holes[8].setBounds(0, 132, 132, 132);
panel.add(holes[8]);
holes[9] = new JLabel("9");
holes[9].setName("9");
holes[9].setBounds(132, 132, 132, 132);
panel.add(holes[9]);
holes[10] = new JLabel("10");
holes[10].setName("10");
holes[10].setBounds(264, 132, 132, 132);
panel.add(holes[10]);
holes[11] = new JLabel("11");
holes[11].setName("11");
holes[11].setBounds(396, 132, 132, 132);
panel.add(holes[11]);
holes[12] = new JLabel("12");
holes[12].setName("12");
holes[12].setBounds(0, 0, 132, 132);
panel.add(holes[12]);
holes[13] = new JLabel("13");
holes[13].setName("13");
holes[13].setBounds(132, 0, 132, 132);
panel.add(holes[13]);
holes[14] = new JLabel("14");
holes[14].setName("14");
holes[14].setBounds(264, 0, 132, 132);
panel.add(holes[14]);
holes[15] = new JLabel("15");
holes[15].setName("15");
holes[15].setBounds(396, 0, 132, 132);
panel.add(holes[15]);
lblScore = new JLabel("Score: 0");

Coding 6: Timer, Start Button, Labels

56

Whack A Java Mole


lblScore.setHorizontalAlignment(SwingConstants.TRAILING);
lblScore.setFont(new Font("Cambria", Font.BOLD, 14));
lblScore.setForeground(new Color(135, 206, 250));
lblScore.setBounds(423, 54, 144, 33);
contentPane.add(lblScore);
lblTimeLeft = new JLabel("30");
lblTimeLeft.setHorizontalAlignment(SwingConstants.CENTER);
lblTimeLeft.setForeground(new Color(240, 128, 128));
lblTimeLeft.setFont(new Font("Cambria Math", Font.BOLD, 24));
lblTimeLeft.setBounds(232, 54, 144, 33);
contentPane.add(lblTimeLeft);
lblHighscore = new JLabel("Highscore: 0");
lblHighscore.setHorizontalAlignment(SwingConstants.TRAILING);
lblHighscore.setForeground(new Color(255, 255, 0));
lblHighscore.setFont(new Font("Cambria", Font.BOLD, 14));
lblHighscore.setBounds(433, 18, 134, 33);
contentPane.add(lblHighscore);
btnStart = new JButton("Start");
btnStart.setBackground(Color.WHITE);
btnStart.setBounds(32, 60, 110, 33);
contentPane.add(btnStart);
setContentPane(contentPane);
}
private void clearBoard(){
for(int i = 0; i < 16; i++){
holes[i].setIcon(loadImage("/moleIn.png"));
board[i] = 0;
}
}
private void genRandMole(){

Random rnd = new Random(System.currentTimeMillis()); //seeding rando


int moleID = rnd.nextInt(16);
board[moleID] = 1;
holes[moleID].setIcon(loadImage("/moleOut.png"));

Coding 6: Timer, Start Button, Labels

57

Whack A Java Mole


}
private ImageIcon loadImage(String path){

Image image = new ImageIcon(this.getClass().getResource(path)).getIm

Image scaledImage = image.getScaledInstance(132, 132, java.awt.Imag


return new ImageIcon(scaledImage);
}
public Game() {
initGUI();
clearBoard();
initEvents();
}
public static void main(String[] args) {
Game frame = new Game();
frame.setVisible(true);
}
}

Coding 6: Timer, Start Button, Labels

58

Whack A Java Mole

Coding 7: Wrapping up - Saving the


Highscore
This is the final coding lesson.
You are almost there, the Whack A Mole game is now 99% complete, so let's get it
to 100%.

Save highscore - write to text file


Create a function called: saveHighscore():
private void saveHighscore(){
}

Inside the function we need to:


(1) Create a BufferedWriter object
(2) Initialise the object, passing in a new FileWriter object specifying the path to
write to
(3) Write the highscore using the BufferedWriter object
(4) Flush and close the BufferedWriter
Which would look like this:

Coding 7: Wrapping up - saving the highscore

59

Whack A Java Mole

private void saveHighscore(){


BufferedWriter bw = null;
try {

bw = new BufferedWriter(new FileWriter(System.getProperty("user.dir"


bw.write("" + highscore);
bw.flush();
bw.close();
} catch (IOException e) {

JOptionPane.showMessageDialog(this, e.getMessage(), "Error while sav


}
}

The line: bw.write("" + highscore); is writing the highscore to the text file as a
String
The "" + highscore essentially converts the integer highscore into a string
System.getProperty("user.dir") - gets the path of the current directory the
program is running in

Load highscore - read from text file


Create a function called: loadHighscore():
private void loadHighscore(){
}

Inside the function we need to:


(1) Create a BufferedReader object
(2) Declare a String to store the lines read by the BufferedReader
(3) Initialise the object, passing in a new FileReader object specifying the path to
read from
(4) Read a line from the BufferedReader
(5) Close the BufferedReader object
(6) Check that the line read is not empty

Coding 7: Wrapping up - saving the highscore

60

Whack A Java Mole


(7) If it is not empty, parse the line (convert it into an integer) and update the
highscore
(8) Update the highscore label as well
Which would look like this:
private void loadHighscore(){
BufferedReader br = null;
String line = "";
try {

br = new BufferedReader(new FileReader(System.getProperty("user.


line = br.readLine();
br.close();
} catch (IOException e) {
line = "";
}
if(line != ""){
highscore = Integer.parseInt(line);
lblHighscore.setText("Highscore: " + highscore);
}
}
}

Go back to the gameOver() function


Inside the gameOver() function, call the 'saveHighscore()' function:
private void gameOver(){
...
...
saveHighscore();
}

This means that whenever a game ends, it will update the highscore and save it to
the text file.
Now go to the constructor
Inside the constructor, call the 'loadHighscore()' function:

Coding 7: Wrapping up - saving the highscore

61

Whack A Java Mole

public Game() {
...
...
loadHighscore();
}

Try running the program and play through the game once.
When the game finishes and you beat the highscore, try exiting the program and
restarting it. If you've done everything correctly, the highscore should appear
correctly.

Styling the cursor with a hammer icon


We want the standard cursor to be replaced with a hammer icon, when our mouse
is over the game panel.
So let's go to the initGUI() function, where we defined the panel, and add the
following code:
panel = new JPanel();
...
...
panel.setCursor(Toolkit.getDefaultToolkit().createCustomCursor(
loadImage("/hammer.png").getImage(),
new Point(0,0),"custom cursor1"));

Also, don't forget to save the following hammer image file as 'hammer.png'
and put it inside the 'res' folder as usual.

CONGRATULATIONS!

Coding 7: Wrapping up - saving the highscore

62

Whack A Java Mole

You have completed the coding lesson series


on creating a Whack A Mole game in Java.
Final Source Code
import java.awt.Color;
import java.awt.Font;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;

public class Game extends JFrame{


private JPanel panel;
private JLabel[] holes = new JLabel[16];
private int[] board = new int[16];

Coding 7: Wrapping up - saving the highscore

63

Whack A Java Mole

private int score = 0;


private int timeLeft = 30;
private int highscore = 0;
private JLabel lblScore;
private JLabel lblTimeLeft;
private JLabel lblHighscore;
private JButton btnStart;
private Timer timer;
private void loadHighscore(){
BufferedReader br = null;
String line = "";
try {

br = new BufferedReader(new FileReader(System.getProperty("user.


line = br.readLine();
br.close();
} catch (IOException e) {
line = "";
}
if(line != ""){
highscore = Integer.parseInt(line);
lblHighscore.setText("Highscore: " + highscore);
}
}
private void saveHighscore(){
BufferedWriter bw = null;
try {

bw = new BufferedWriter(new FileWriter(System.getProperty("user.


bw.write("" + highscore);
bw.flush();
bw.close();
} catch (IOException e) {

JOptionPane.showMessageDialog(this, e.getMessage(), "Error while


}
}

Coding 7: Wrapping up - saving the highscore

64

Whack A Java Mole

private void gameOver(){


btnStart.setEnabled(true);
if(score > highscore){
highscore = score;
lblHighscore.setText("Highscore: " + highscore);

JOptionPane.showMessageDialog(this, "Your final score is: " + sc


}else{

JOptionPane.showMessageDialog(this, "Your final score is: " + sc


}
score = 0;
timeLeft = 30;
lblScore.setText("Score: 0");
lblTimeLeft.setText("30");
clearBoard();
saveHighscore();
}
private void pressedButton(int id){
int val = board[id];
//if val is 1 = mole
//if val is 0 = empty hole
if(val==1){
score++;
}else{ //val==0
score--;
}
lblScore.setText("Score: " + score); //update the score
clearBoard();
genRandMole();
}
private void initEvents(){
for(int i = 0; i < holes.length; i++){

Coding 7: Wrapping up - saving the highscore

65

Whack A Java Mole


holes[i].addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e){
JLabel lbl = (JLabel)e.getSource();
int id = Integer.parseInt(lbl.getName());
pressedButton(id);
}
});
}
btnStart.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
btnStart.setEnabled(false);
clearBoard();
genRandMole();
timer.start();
}
});
timer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if(timeLeft == 0){
lblTimeLeft.setText("" + timeLeft);
timer.stop();
gameOver();
}
lblTimeLeft.setText("" + timeLeft);
timeLeft--;
}
});
}
private void initGUI(){
setTitle("Whack A Mole");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 608, 720);
JPanel contentPane = new JPanel();
contentPane = new JPanel();
contentPane.setBackground(new Color(0, 51, 0));

Coding 7: Wrapping up - saving the highscore

66

Whack A Java Mole


contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(null);
JLabel lblTitle = new JLabel("Whack A Mole");
lblTitle.setForeground(new Color(153, 204, 0));
lblTitle.setHorizontalAlignment(SwingConstants.CENTER);
lblTitle.setFont(new Font("Century Gothic", Font.BOLD, 20));
lblTitle.setBounds(0, 0, 602, 47);
contentPane.add(lblTitle);
panel = new JPanel();
panel.setBackground(new Color(0, 102, 0));
panel.setBounds(32, 105, 535, 546);
panel.setLayout(null);
panel.setCursor(Toolkit.getDefaultToolkit().createCustomCursor(
loadImage("/hammer.png").getImage(),
new Point(0,0),"custom cursor1"));
contentPane.add(panel);
holes[0] = new JLabel("0");
holes[0].setName("0");
holes[0].setBounds(0, 396, 132, 132);
panel.add(holes[0]);
holes[1] = new JLabel("1");
holes[1].setName("1");
holes[1].setBounds(132, 396, 132, 132);
panel.add(holes[1]);
holes[2] = new JLabel("2");
holes[2].setName("2");
holes[2].setBounds(264, 396, 132, 132);
panel.add(holes[2]);
holes[3] = new JLabel("3");
holes[3].setName("3");
holes[3].setBounds(396, 396, 132, 132);
panel.add(holes[3]);
holes[4] = new JLabel("4");

Coding 7: Wrapping up - saving the highscore

67

Whack A Java Mole


holes[4].setName("4");
holes[4].setBounds(0, 264, 132, 132);
panel.add(holes[4]);
holes[5] = new JLabel("5");
holes[5].setName("5");
holes[5].setBounds(132, 264, 132, 132);
panel.add(holes[5]);
holes[6] = new JLabel("6");
holes[6].setName("6");
holes[6].setBounds(264, 264, 132, 132);
panel.add(holes[6]);
holes[7] = new JLabel("7");
holes[7].setName("7");
holes[7].setBounds(396, 264, 132, 132);
panel.add(holes[7]);
holes[8] = new JLabel("8");
holes[8].setName("8");
holes[8].setBounds(0, 132, 132, 132);
panel.add(holes[8]);
holes[9] = new JLabel("9");
holes[9].setName("9");
holes[9].setBounds(132, 132, 132, 132);
panel.add(holes[9]);
holes[10] = new JLabel("10");
holes[10].setName("10");
holes[10].setBounds(264, 132, 132, 132);
panel.add(holes[10]);
holes[11] = new JLabel("11");
holes[11].setName("11");
holes[11].setBounds(396, 132, 132, 132);
panel.add(holes[11]);
holes[12] = new JLabel("12");

Coding 7: Wrapping up - saving the highscore

68

Whack A Java Mole


holes[12].setName("12");
holes[12].setBounds(0, 0, 132, 132);
panel.add(holes[12]);
holes[13] = new JLabel("13");
holes[13].setName("13");
holes[13].setBounds(132, 0, 132, 132);
panel.add(holes[13]);
holes[14] = new JLabel("14");
holes[14].setName("14");
holes[14].setBounds(264, 0, 132, 132);
panel.add(holes[14]);
holes[15] = new JLabel("15");
holes[15].setName("15");
holes[15].setBounds(396, 0, 132, 132);
panel.add(holes[15]);
lblScore = new JLabel("Score: 0");
lblScore.setHorizontalAlignment(SwingConstants.TRAILING);
lblScore.setFont(new Font("Cambria", Font.BOLD, 14));
lblScore.setForeground(new Color(135, 206, 250));
lblScore.setBounds(423, 54, 144, 33);
contentPane.add(lblScore);
lblTimeLeft = new JLabel("30");
lblTimeLeft.setHorizontalAlignment(SwingConstants.CENTER);
lblTimeLeft.setForeground(new Color(240, 128, 128));
lblTimeLeft.setFont(new Font("Cambria Math", Font.BOLD, 24));
lblTimeLeft.setBounds(232, 54, 144, 33);
contentPane.add(lblTimeLeft);
lblHighscore = new JLabel("Highscore: 0");
lblHighscore.setHorizontalAlignment(SwingConstants.TRAILING);
lblHighscore.setForeground(new Color(255, 255, 0));
lblHighscore.setFont(new Font("Cambria", Font.BOLD, 14));
lblHighscore.setBounds(433, 18, 134, 33);
contentPane.add(lblHighscore);

Coding 7: Wrapping up - saving the highscore

69

Whack A Java Mole


btnStart = new JButton("Start");
btnStart.setBackground(Color.WHITE);
btnStart.setBounds(32, 60, 110, 33);
contentPane.add(btnStart);
setContentPane(contentPane);
}
private void clearBoard(){
for(int i = 0; i < 16; i++){
holes[i].setIcon(loadImage("/moleIn.png"));
board[i] = 0;
}
}
private void genRandMole(){

Random rnd = new Random(System.currentTimeMillis()); //seeding rando


int moleID = rnd.nextInt(16);
board[moleID] = 1;
holes[moleID].setIcon(loadImage("/moleOut.png"));
}
private ImageIcon loadImage(String path){

Image image = new ImageIcon(this.getClass().getResource(path)).getIm

Image scaledImage = image.getScaledInstance(132, 132, java.awt.Imag


return new ImageIcon(scaledImage);
}
public Game() {
initGUI();
clearBoard();
initEvents();
loadHighscore();
}
public static void main(String[] args) {
Game frame = new Game();
frame.setVisible(true);
}
}

Coding 7: Wrapping up - saving the highscore

70

Whack A Java Mole

Coding 7: Wrapping up - saving the highscore

71

Whack A Java Mole

Lesson 1: Get started with Java


Java is a general-purpose computer programming language that is concurrent,
class-based, object-oriented. And it's specifically designed to have as few
implementation dependencies as possible, so it's platform-independent. Java
applications are compiled to bytecode that can run on any Java Virtual Machine,
or JVM, regardless of the underlying computer architecture. Java uses an
automatic garbage collector to automatically manage memory in the object life
cycle. The syntax of Java is heavily borrowed from C++. And It is important to
note that Java and JavaScript are two separate languages.

JVM, JRE, JDK and IDE


A Java virtual machine (JVM) is an abstract computing machine that enables a
computer to run a Java program.
Java Runtime Environment (JRE) is a software package that contains what is
required to run a Java program.
Java Development Kit (JDK) is a superset of a JRE and contains also tools for
Java programmers, e.g. a javac compiler.
An integrated development environment (IDE) is a software application that
provides comprehensive facilities to computer programmers for software
development. An IDE normally consists of a source code editor, build automation
tools and a debugger. Most modern IDEs have an intelligent code completion.

Install JDK and Eclipse IDE


There are many Java IDEs that you can download, but in this tutorial we will be
using Eclipse IDE which is one of the most common tools used to develop Java
applications.
Lesson 1: Getting started with Java

72

Whack A Java Mole


Before you download Eclipse IDE, you should first install the Java Development
Kit (JDK) by going to:
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads2133151.html
To download the JDK, simply tick the box to 'Accept License Agreement' and click
on the download link for your operating system.
Next we will install the Eclipse IDE.
To download Eclipse go to the following link: https://www.eclipse.org/downloads/
Make sure to download Eclipse for the correct operating system.
If you dont know whether your operating system is 32-bit or 64-bit:
1. Right click on 'My Computer'
2. Click on 'Properties'
3. This should open up a new window
4. Next to 'System type' you should see either 32-bit or 64-bit

Exploring the Eclipse IDE


Open up Eclipse and you should see a window asking you to choose a
workspace.
You can create a folder somewhere on your hard drive and select that path or just
use the default workspace created by Eclipse.
To create a new project.
Click: File -> New -> Java project
(img placeholder)
You can name the project whatever you want, but I will name it demo.
Right click on your project folder in the package explorer.
Then select: New -> Class
(img placeholder)
Name it 'Helloworld' and tick the 'public static void main(String[] args)' checkbox.
This will allow Eclipse to automatically generate a Main method.
The 'main' method is the first thing that is executed when the program starts.

Lesson 1: Getting started with Java

73

Whack A Java Mole


(img placeholder)
Inside the 'main' method, enter the following line of code:
System.out.println("Hello World!");

(img placeholder)
Now if you save the file (ctrl+s) and click on the green button (looks like a play
button), your 'Helloworld' program should execute.
You should now see 'Hello World!' printed to your console.
(img placeholder)
Congratulations! You have just created your first Java program!
Exercises:
1. Try printing out: I am 'yourname' in your console by editing the current code.
2. There is something wrong with the following lines of code, try fixing them:
System.out.println(What is your name?);
System.println("What is your name?");
System.out.println('What is your name?');

3. Print a list of numbers 1 to 5 (each number in a new line).

Lesson 1: Getting started with Java

74

Whack A Java Mole

Lesson 2: Java basics


Anatomy of a Java program
A Java program would consist of basic parts, for example the main method. Every
java program has to have it in order to get the program complied, but what do we
write in the java file?Basically, it is going to include:
Variables
Statements
Input/output
Loops (for and while)
Decision statements (if else)
File input and output
Comments and other methods

Here is an example:

Lesson 2: Java basics

75

Whack A Java Mole

/*

* To change this license header, choose License Headers in Project Properti


* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/ comments
package javaexample;
import java.util.Scanner; // import library
public class JavaExample {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
int num1,num2,sum; //variables
Scanner in=new Scanner(System.in);
System.out.println("Please input two integer numbers!");
num1=in.nextInt(); num2=in.nextInt(); //read two integer numbers
sum=num1+num2; //add them up

System.out.println("The sum of the two numbers you entered is "+ sum


}
}

Basically what this program does is taking two integer numbers in and add them
up to print out the sum of them.

Data Type
Every variable we define must be declared with a data type, as java is known as a
strict data typing language. And you can not change the type of the date stored in
the variable.
Primitive data type

Lesson 2: Java basics

76

Whack A Java Mole

Characters: char letter=B;


Boolean: isTrue=false; (isTrue can be true as well!)
Integers byte,short,int, and long;
Rational numbers: float, double;

Like the previous example, we define two variables as int(Integer) in order to find
the sum of them. You will get an error if you try to input rational numbers, but if
you define them as float, you wont get the error when you input two integers.

Exercise
1 Play with the previous example to see what happen if you try to input two
rational numbers.
2 Define the two variables as float or double, see what happen if you try to input
two integer numbers.
3 Create a simple calculator that enables you to do addition, subtraction,
multiplication and division between any two real numbers.

Strings
String is technically not a primitive data type.
A sequence/array characters can be stored in a string variable.
For instance, we can say
String aString=Hello World; but not char achar=Hello World

Remember that a char variable can only store one character.

Exercise

Lesson 2: Java basics

77

Whack A Java Mole


1 Instead of printing out Hello World directly, try to print out a string variable that
stores the value of Hello World.

Arrays
Imagining that you are shopping in a supermarket, and you want to write a
program that create a list of the goods. You have to store the name of the product
as well as the price in some variables. It is okay if you have only a few items when
you only need to create a few variables to store them. But what if you have
hundreds or thousands of items to deal with?
Then you need a array.
An array uses one variable name for multiple values, and this is how we define an
array.
data type[] variable name= new data type[size];
the data type on the left hand side has to be the same as the data type on the
right hand side.
For instance, you can create arrays like
String[] Name=new String[1000];
float[] price=new float[1000];

To store the names and prices of 1001(why?) items. Note that an array can only
store the data type that it is declared with.
Array must be declared with the size. And it is accessed with an index
value(Integers)starting from 0. As a array always has a fixed size, if you want to
access the array with an index value which is larger than the size of array, you will
get an out of bounds exception.
Here is an example(it is used to calculate the total price as well as the average of
the items in the shopping list, and this version is not good enough. You will learn a
better approach when you get to the loop part)

Lesson 2: Java basics

78

Whack A Java Mole

package shoppinglist;
import java.util.Scanner;
public class ShoppingList {
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
float[] price=new float[6];
float total,average;
System.out.println("Please input the prices of 6 items.");
price[0]=in.nextFloat();
price[1]=in.nextFloat();
price[2]=in.nextFloat();
price[3]=in.nextFloat();
price[4]=in.nextFloat();
price[5]=in.nextFloat();
total=price[0]+price[1]+price[2]+price[3]+price[4]+price[5];
average=total/6;
System.out.println("The total price of the items is "+total);

System.out.println("The average price of the items is "+average);


// System.out.println(price[11]);
}
}

I have also included a line that it is trying to print the element of index 11 in the
price array. You can uncomment it and see what it does when running.

Exercise
1. Amend the example and make it do the calculation for ten items.
2. Write a program that asks for your home address line by line then prints it out
in the same order as you enter your address.

Lesson 2: Java basics

79

Whack A Java Mole

Lesson 3: Loops
Loops are the best things in the world. Imagine yourself having to write "1" to the
console 1000 times. You will find the job tedious, and soon want to quit. This is
where our programs kick in. Through loops, they repeat things over and over, until
we tell them to stop.
In our case, we will ask our program to stop printing 1 when one thousand "1"
have been printed on console. It will be:
for(int i=0;i<1000;i++){
System.out.println(1);
}

"for" is one of the most common loop that we see, along with while. Lets talk about
"for" first.
There are three parts to the for loop. (1) Variable initialization(that's used for
condition) (2) Condition ( True or False ) (3) Action every loop(eg. increment the
variable in (1))
for( (1) ; (2) ; (3) );
To explain our code above, (1) we first introduce a variable called i, which is a
common variable when used to iterate(loops), and initialize it to 0. (2) our
condition is when i < 1000. if i = 1000, the condition will return false, and loop will
end. (3) for each iteration, we increase the value of i by 1.
int i=0;
while(i!=1000){
System.out.println(1);
i++;
}

Lesson 3: Loops

80

Whack A Java Mole


"while" is the other loop we commonly encounter. While(condition) is the syntax,
and this loop is used for repeated actions, while for loops are common for iterating
over arrays and other iterations. In our code above, our condition is when i is not
1000. This will return false when i = 1000. Similar syntax to our for loop, but
different in a way that it can be expressed like this:
Boolean isThousand = false;
int i =0;
while( !isThousand ) {
System.out.println(1);
i++;
if( i == 1000 ) {
isThousand = true;
}
}

While loops are pretty useful, but sometimes if the condition is false from the
beginning, the loop does not even execute. In such cases, we have "DO - WHILE"
loops, which will execute at least once.
Boolean insane = true;
do {
//something crazy
} while ( insane )

simply putting it, the condition is evaluated at the bottom of "do" section.
Therefore, whether insane is true or not, "something crazy" will happen at least
once.

Lesson 3: Loops

81

Whack A Java Mole

Lesson 4: Classes and Objects


Introduction:
In lesson 4, we will talk about one of the most important features of objectoriented programming and Java: Classes and Objects!
What is a class? In life, you can find many things which are of the same type classified by its similar behaviors. For example, BMW, Benz and many others cars
all have the same framework (wheels, car body, etc) and are hence part of the
same class: Car. In object-oriented language, we can define the brand of cars as
instance objects of the class: Car. In other words, a class is a blueprint from which
individual objects are created.

To clarify things and provide further insight into Classes and Objects, I quote
Steve Jobs (from a 1994 Rolling Stone interview):
"Objects are like people. They're living, breathing things that have knowledge
inside them about how to do things and have memory inside them so they can
remember things. And rather than interacting with them at a very low level, you
interact with them at a very high level of abstraction, like we're doing right now.
Here's an example: If Im your laundry object, you can give me your dirty clothes
and send me a message that says, Can you get my clothes laundered, please. I
Lesson 4: Classes and Objects

82

Whack A Java Mole


happen to know where the best laundry place in San Francisco is. And I speak
English, and I have dollars in my pockets. So I go out and hail a taxicab and tell
the driver to take me to this place in San Francisco. I go get your clothes
laundered, I jump back in the cab, I get back here. I give you your clean clothes
and say, Here are your clean clothes. You have no idea how I did that. You have
no knowledge of the laundry place. Maybe you speak French, and you cant even
hail a taxi. You cant pay for one, you dont have dollars in your pocket. Yet I knew
how to do all of that. And you didnt have to know any of it. All that complexity was
hidden inside of me, and we were able to interact at a very high level of
abstraction. Thats what objects are. They encapsulate complexity, and the
interfaces to that complexity are high level."
Now that you have a clearer understanding of what Classes and Objects are, let's
get started with Java.

4.1 Creating classes:


Now you may wonder: How do you create a class in Java? Have a look at the
example below:

Lesson 4: Classes and Objects

83

Whack A Java Mole

public class Car{


//All cars have these features, so we put instance variables here.
private int speed;
private string brand;
private int wheel_numbers;

//This is a constructor. When an object is instantiated, it must initial


//It will be explained further in 4.2.
public Car(int startSpeed, string brand, int wheels){
this.speed = startSpeed;
this.brand = brand;
this.wheel_numbers = wheels;
}

//a method used to change the value of an instance variable out of this
public setSpeed(int newSpeed){
speed = newSpeed;
}

//a method used to get the value of an instance variable out of this cla
public getSpeed(){
return speed;
}
public increaseSpeed(int increment){
speed += increment;
}
}

As shown in the example above, a class should include variables and methods
and I will explain it more particularly. Variable is a basic part of a class and it
includes static variables and instance variables. These variables can be equal to
the features of an object. For instance, if a class called people and it includes
following variables: eyes color, hair color and skin color, then each object of this
class will have different eyes color, hair color and skin color.
Lesson 4: Classes and Objects

84

Whack A Java Mole


private int speed; // this is a general variable

Instance variables should always be written at the top of a class and it should
include the modifier, data type (int, char, string, etc) and the name of the variable.
For methods, these are functions in a class and these can be explained to the
motions of a class. In above code, increaseSpeed is a general method and when
an object of this class is instantiated in the main function, this object can use this
method to change its instance variable speed. In addition, you can find that there
has a method that has the same name with the class, called Car. Actually,
constructor is a special method and it will be called when an object is created, to
assign instance variables of this object.
modifier dataType methodName(dataType parameter){
method body
}

If you have learned C language, you will find that the Java method is quite similar
to the function in C. Since Java is a objective-oriented language, its methods have
objective features. Therefore, a method can be called by different objects if the
method is public. So, how can we use our class in the main function?

4.2 Instantiating classes


An object is an instance of a class, and the process to create this object is called
instantiation. Instantiating classes will occur when you want to use methods of
class out of this class. For example, we have a transportation class and it includes
a method run, which can make a kind of transportation run. If you want to use
this method, you cant just say Hey! Transportation run! It will be vague since
computer doesnt know which transportation you want to run. Therefore, we need
a specific object to implement this method. You need to create an object car,
and use this object to call the run method. Then the car will run.
In Java, we always use a keyword new, to create an object and there are three
steps: declaration, instantiation and initialization.
Declaration: Declare an object; include object name and the type of this

Lesson 4: Classes and Objects

85

Whack A Java Mole


object.
Instantiation: Use the keyword new to create an object.
Initialization: when we use new to create an object, constructor will be called
to initial the object.
Person allen = new Person();

The code above is a simple instantiation of an object allen. Person is the type of
the object, allen is the object name and new Person() is the initialization. The
empty parenthesis: () means that there are no constructors in the class and the
instance variables in the class will all be set to its default value.
Take another example:
Car newCar = new Car(80, Benz, 4);

Car is the class I wrote above, and this code means I create a new object call
newCar and it has been initialized with speed 80, 4 wheels and its brand is Benz.
Why can this object initial with these parameters? That is because of constructor.
public Car(int startSpeed, string brand, int wheels){
this.speed = startSpeed;
this.brand = brand;
this.wheel_numbers = wheels;
}

This is a constructor and it must have the same name with the class. When we
use new Car(80, Benz, 4), these parameters will send to the constructor and the
startSpeed will be assigned 80, the brand will be assigned Benz and the wheels
will be assigned 4. Then these instance variables in the class: speed, brand and
wheel_numbers will be assigned. It is important to remember that if a class has a
constructor, we must initial instance variables when an object of this class be
created. If a class doesnt have a constructor we can just create an object and
leave the parameter brackets blank: Person allen = new Person();
After we created an object, we can access the method of the object:

Lesson 4: Classes and Objects

86

Whack A Java Mole

Car newCar = new Car(80, Benz, 4);


newCar.increaseSpeed(20);
newCar.getSpeed();
newCar.setSpeed();

It is quite simple since we just use dot to access these method and we can use
getSpeed and setSpeed to operate instance variables inside the class. Why cant
we just use newCar.speed to get the value of this instance variable? Because this
variable is private and we can only get the value of this private variable through
the getSpeed method.

4.3 Static and Instance methods/variables


Static and instance is an important part of Java, I will explain it by two parts: static
and instance variables and static and instance methods.
Static variables has a keyword static in the declaration of this variables:
public static dataType variableName;

When a static variable is declared, the program will allocate memory for this
variable and if this static variable changes in one object or in the class directly, this
static variable of all objects will be changed at the same time.
For instance: if we have an object personA and object personB and we also have
a static variable hairColor,
People personA = new Person();
People personB = new Person();
personA.hairColor = RED;
System.out.println(personB.hairColor);

From the code above, you will find that console will print RED on the screen.
Moreover, static variable can be used by class name directly in another class
without instantiating a new object.
People.hairColor = RED

Comparing with static variable, instance variable wont be allocated storage before
an object be created and it must be called after creating a object. In addition,
when this variable changed in an object, it wont affect others objects.

Lesson 4: Classes and Objects

87

Whack A Java Mole


Static methods features are similar to static variable and it also has a keyword
static before the datatype: modifier static dataType methodName(dataType
parameter) Static method can be called without instantiation from another class.
But instance method must be called with a object be created. Now I have a
question: Why can instance method calls instance variables and static variable,
yet static method cant calls instance variable? Thats because static method can
be used before an object be created, and at that time instance variable havent be
allocated storage. One last question: Why is the main method static?

4.4 Using encapsulation


One of the core features of Java is encapsulation. So what is encapusulation?
Generally, encapusulation means we need hide all of the member variables and
implementation details and do not allow the outside of this class to call directly.
And we should give the outside methods to let them call and operate member
variables safely.
What is the function of encapsulation? Firstly, users can only access data through
default methods and it can protect member variables from some unreasonable
call. Secondly, it will be easier for modification and improving the maintainability of
codes.
There are four common modifiers: private, default, protected and public. Private
only allow the call inside the class and default means we dont add any keyword
before the method or variables, and we can use default methods/variables free in
a package. Protected means this method/variable only availiable for the subclass
of the class this method/variable in. Public means you can use this
method/variable anywhere! Modifier can be used in class, method, variable and
also the constructor. Furthermore, most member variables should be modified by
private unless some member variables modified by static.

Exercise:

Lesson 4: Classes and Objects

88

Whack A Java Mole

In our final project, we will create a real whack-a-mole game. Therefore, Let's try
to make a simplest console whack-a-mole game with our knowledge first! It will
involves all we learnt in Chapter 4. There is the requirements:
a) The game should have 9 holes and arranged into 3*3 matrix.
b) Allow users to hit the moles in console.
c) Every time users hit a mole, a new mole will come out from a random hole.
d) Every time users hit a mole, users will get scores and at the end of this game,
the total score will be shown.
e) The game need a timer to limit the length of this game.
f) When users hit wrong hole, game over. When the time out, game over.
Hints:

Lesson 4: Classes and Objects

89

Whack A Java Mole

1. You may need multiple classes in this exercise.


2. You can use Scanner class to get users' input.
3. You may need ArrayList to manage your holes.

4. You can use System.currentTimeMillis() to get the total run time of th


5. Remember to use while and for loops in your program.

6. Tou can use Random class to get a random number between a range of num

(You can find the example in next page)

Lesson 4: Classes and Objects

90

Whack A Java Mole

Lesson 5: An exercise on Classes and


Objects
There are two classes in the example: Main and Holes. Holes.java:
//this class is used to describe every single hole in our game.
public class Holes {
//if mole = true, then this hole has a mole.
private boolean mole;
//A constructor used for initialization.
Holes(boolean m){
this.mole = m;
}
//Let external class change the state of hole.
public void setMole(boolean x){
mole = x;
}
//Let external class get the state of hole
public boolean getMole(){
return mole;
}
}

Main.java:
import java.util.ArrayList;
import java.util.Random;
import java.util.Scanner;
public class Main {

static ArrayList<Holes> holes = new ArrayList<Holes>(); //used for savin


static int totalScore = 0;
static int totalTime = 30; //the total time of the game
static long start = System.currentTimeMillis();

Lesson 5: An exercise on classes and objects

91

Whack A Java Mole

public static void main(String[] args) {


//instantiation of all 9 holes.
Holes hole1 = new Holes(false);
Holes hole2 = new Holes(false);
Holes hole3 = new Holes(false);
Holes hole4 = new Holes(false);
Holes hole5 = new Holes(false);
Holes hole6 = new Holes(false);
Holes hole7 = new Holes(false);
Holes hole8 = new Holes(false);
Holes hole9 = new Holes(false);
//add each holes into arraylist.
holes.add(hole1);
holes.add(hole2);
holes.add(hole3);
holes.add(hole4);
holes.add(hole5);
holes.add(hole6);
holes.add(hole7);
holes.add(hole8);
holes.add(hole9);
//set a random hole to have a mole.
holes.get(randomNumber()).setMole(true);
//the main loop for our game.
while (true){
//reminder of time

System.out.println("time remain" + ((totalTime - (System.curre


//if time less than 0, then the game over

if((totalTime - (System.currentTimeMillis()-start) / 1000) < 0){

System.out.printf("\nGame over! Your score: %d", totalScore)


return;
}
//setGraph() is used for display our game in console
setGraph();
System.out.printf("\nYour score: %d", totalScore);
System.out.printf("\nhit:");
//get users'input

Lesson 5: An exercise on classes and objects

92

Whack A Java Mole


Scanner input = new Scanner(System.in);
int whack;
whack = input.nextInt() - 1;
//the result when the user hits on a hole.
if (holes.get(whack).getMole() == true){
totalScore = totalScore + 100;
holes.get(whack).setMole(false);
holes.get(randomNumber()).setMole(true);
}else {

System.out.printf("\nGame over! Your score: %d", totalScore)


return;
}
}
}
//a method to create a random number
public static int randomNumber() {
int max=8;
int min=0;
Random random = new Random();
int randomHole = random.nextInt(max)%(max-min+1) + min;
return randomHole;
}
//display game in console
public static void setGraph(){
for (int i = 1; i <= 9; i++) {
if (i % 3 == 1) {
System.out.printf("\n");
}
if (!holes.get(i - 1).getMole()) {
System.out.printf("0");
} else {
System.out.printf("1");
}
}
}
}

Lesson 5: An exercise on classes and objects

93

Whack A Java Mole


What will this example looks like?

Lesson 5: An exercise on classes and objects

94

Whack A Java Mole

Lesson 5: An exercise on classes and objects

95

Whack A Java Mole

Lesson 6: File IO
Introduction
Its time to play with some files. In this lessons, we will learn how to read and write
to text files. Basically, instead of having you to copy and paste the content of text
whatever you want to play with into the program, you can just use one of the
classes to do that for you.
Basically, the class reads the file for you, and stores the content of the file, which
you can use.
Lets have an example below.
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

Here are the classes we will be using.


Java.io.BufferedReader: create buffer(temporary memory) for reader classes.
Java.io.FileReader: class that will actually read the file.
Java.io.IOException: we will deal with this later.
public class BufferedReaderExample {
public static void main(String[] arg) {
BufferedReader br = null;

First, we declare the class. Lets call it BufferedReaderExample. In the main, we


will first declare our bufferedreader, br(Buffered Reader) and equate it to null,
for the reasons we will discuss later.

Lesson 6: File IO

96

Whack A Java Mole

String sCurrentLine;
br = new BufferedReader(new FileReader("C://testing.txt"));
while((sCurrentLine = br.readLine()) != null){
System.out.println(sCurrentLine);
}

String sCurrentLine declares a string variable called sCurrentLine.


br remember the BufferedReader variable we created above? Now we will have
output of FileReader stored in it.
While -> readLine method moves to the next line, and condition of (!=null) checks
whether there is any more lines or not.
-However, here we face an important problem. Its exceptions (or errors). Lets say,
we want to use testing file.txt in C, as in the example. However, what if, there is
no such file as testing.txt in C? We will get an error, and we need to handle the
error somehow.
Remember IOException, one of the first three we imported in the beginning? The
error-handling class will be used in this case.
So, we first wrap our code using try {} phrase.

try (BufferedReader br = new BufferedReader(new FileReader("C:\\testing.tx


String sCurrentLine;
while((sCurrentLine = br.readLine()) != null){
System.out.println(sCurrentLine);
}
}

Lesson 6: File IO

97

Whack A Java Mole


then, if we failed to try, we catch whatever error there is. In this case, as we have
Input-Output-Exception error, we are using IOException
catch (IOException e) {
e.printStackTrace
}

printStackTrace is similar to console.log of errors. We are not going to do anything


but to print what happened, so the user knows.
Thus, the entire code will look like this, with extra brackets in the end.
package your.package.name;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class BufferedReaderExample {
public static void main(String[] args) {

try (BufferedReader br = new BufferedReader(new FileReader("C:\\test


{
String sCurrentLine;
while ((sCurrentLine = br.readLine()) != null) {
System.out.println(sCurrentLine);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

Lesson 6: File IO

98

Whack A Java Mole


Since we have learned how to read files, lets learn how to write to files.
Instead of
import java.io.BufferedReader; <br>
import java.io.FileReader;

We have
import java.io.File;<br>
import java.io.FileOutputStream;

This time. As the name suggests, they got to do with writing files. Let's begin with
creating the class called WrtieFileExample.
public class WriteFileExample {
public static void main(String[] args) {

Then, since we're writing to file, it exists or not does not matter.
File file = new File("c:/newfile.txt");
String content = "This is the text content";

What we're doing is pretty obvious in the syntax. We will use our try-catch we
learend previously, to prevent any malicious things happening.
try (FileOutputStream ops = new FileOutputStream(file)) {

if (!file.exists()) {
// if file doesn't exist, then we create it
file.createNewFile();
}

Lesson 6: File IO

99

Whack A Java Mole


Here, we created File Output Stream, just liked we created Buffered Reader(they
are the similar syntax) and we will create the file if it does not exist. This part is
very human-readable, I agree.
// get the content in bytes
byte[] contentInBytes = content.getBytes();
ops.write(contentInBytes);
ops.flush();
ops.close();
System.out.println("Done");
}

We close the loop, at the same time we wrtie the contents. We first convert our
string into bytes, and we write the content to the file. Then, we "flush" our stream,
as we clear(empty) the stream we have used. Finally, we close the stream,
implying no more outputs to the file.
As usual, if there's an error, we catch it!
catch (IOException e) {
e.printStackTrace();
}

This is how it looks in the end :

Lesson 6: File IO

100

Whack A Java Mole

package your.package.name;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
public class WriteFileExample {
public static void main(String[] args) {
File file = new File("c:/newfile.txt");
String content = "This is the text content";
try (FileOutputStream ops = new FileOutputStream(file)) {
// if file doesn't exists, then create it
if (!file.exists()) {
file.createNewFile();
}
// get the content in bytes
byte[] contentInBytes = content.getBytes();
ops.write(contentInBytes);
ops.flush();
ops.close();
System.out.println("Done");
} catch (IOException e) {
e.printStackTrace();
}
}
}

Lesson 6: File IO

101

Whack A Java Mole

Lesson 7: Graphical User Interface


So far, we have covered most of the basics of Java and Object-oriented
programming. We are now ready to learn how to code a GUI!
Java provides a rich set of libraries that can be used to create a platformindependent graphical user interface. So we can use the graphics classes
provided in JDK for constructing our own Graphical User Interface applications.
Writing your own graphics classes will take far too long to be a feasible option.
There are two sets of Java APIs for GUI programming: AWT and Swing. In this
tutorial we will be programming using Swing rather than AWT, as most of the AWT
components have become obsolete and Swing has a more comprehensive set of
graphics libraries.

Introduction to Swing
The main features of Swing are (Source: Swing website):
1. Swing is written in pure Java (except a few classes) and therefore is 100%
portable.
2. Swing components are lightweight.
3. Swing components (JComponents) are written in Java.
4. Swing components support pluggable look-and-feel. You can choose
between Java look-and-feel and the look-and-feel of the underlying OS (e.g.,
Windows, UNIX or Mac). If the later is chosen, a Swing button runs on the
Windows looks like a Windows' button and feels like a Window's button.
Similarly, a Swing button runs on the UNIX looks like a UNIX's button and
feels like a UNIX's button.
5. Swing supports mouse-less operation, i.e., it can operate entirely using
keyboard.
6. Swing components support "tool-tips".
7. Swing components are JavaBeans a Component-based Model used in
Visual Programming (like Visual Basic). You can drag-and-drop a Swing
component into a "design form" using a "GUI builder" and double-click to
attach an event handler.

Lesson 7: Graphical User Interface

102

Whack A Java Mole


8. Others can be found on the Swing website
Swing component classes (in package javax.swing) begin with a prefix "J", e.g.,
JButton, JTextField, JLabel, JPanel, JFrame, or JApplet.

Original Source: https://netbeans.org/images_www/v7/3/features/client-swingpalette-cut.png

Lesson 7: Graphical User Interface

103

Das könnte Ihnen auch gefallen