Java Graded Projects and one program

402943 final_graded_project
1.Solve graded projects of pages 133-139, 165-168 and 195-200 of file 402943 2.Graded project of other file final graded project

Save Time On Research and Writing
Hire a Pro to Write You a 100% Plagiarism-Free Paper.
Get My Paper

3.This program:(you can take help for it at 

http://stackoverflow.com/questions/18216716/java-abstract-classes-and-inheritance

)

Write an application named UseLoan that uses an abstract class named PersonalLoan and subclasses to display two different types of loans -home and car- and the cost per month for each. Each of the subclasses contains a constructor that sets the cost per month based on the loan type, after prompting the user for at least one data-entry item that is used in the cost-determining decision. (For example, with a car loan, you might ask the age of the car, or whether it is a sports car.) Include an abstract toString() method in the PersonalLoan class that constructs a String containing all the relevant data. Prompt the user for the type of insurance, and then create and display the appropriate object. Save the files as PersonalLoan.java, CarLoan.java, homeLoan.java, and UseLoan.java.

Save Time On Research and Writing
Hire a Pro to Write You a 100% Plagiarism-Free Paper.
Get My Paper

 

total 4 graded projects and one program

Price is final…and i want work asap… (do not ask me to raise the price)

Deliverables are mentioned in the graded projects

Study Guide

Programming in Java
By

Joshua Hester

About the Author

Joshua Hester is a content developer for Kaplan IT Learning and a
certified trainer for Microsoft and Certified Internet Webmaster pro-
grams. He has written, talked, taught, and breathed code for more
than 15 years. After mastering BASIC with a Commodore 64 and
pushing his website development on people throughout college, he
has now evolved into Java Structs, the Microsoft 4 Framework, and
other Web 2.0 technologies.

Mr. Hester is a certified Project Management Professional, Linux
Professional, and Microsoft Office Specialist; he also holds certifica-
tions for A+, Linux+, Network+, and i-Net+. He earned a bachelor
of arts in English from Colgate University and is currently pursuing
a masters of education in instructional technology from Kaplan
University. Besides looking for more certifications, he’s an avid
runner and gamer and enjoys biking, hiking, and solving the odd
logic puzzle.

Copyright © 2013 by Penn Foster, Inc.

All rights reserved. No part of the material protected by this copyright may be
reproduced or utilized in any form or by any means, electronic or mechanical,
including photocopying, recording, or by any information storage and retrieval
system, without permission in writing from the copyright owner.

Requests for permission to make copies of any part of the work should be
mailed to Copyright Permissions, Penn Foster, 925 Oak Street, Scranton,
Pennsylvania 18515.

Printed in the United States of America

All terms mentioned in this text that are known to be trademarks or service
marks have been appropriately capitalized. Use of a term in this text should not be
regarded as affecting the validity of any trademark or service mark.

INSTRUCTIONS TO STUDENTS

1

LESSON ASSIGNMENTS

5

LESSON 1: INTRODUCTION TO
THE JAVA LANGUAGE

7

GRADED PROJECT—LESSON 1

29

LESSON 2: DATA TYPES AND
PROGRAM CONTROL

33

GRADED PROJECT—LESSON 2

71

LESSON 3: OBJECT-
ORIENTED PROGRAMMING

79

GRADED PROJECT—LESSON 3

133

LESSON 4: ADVANCED PROGRAMMING LOGIC

141

GRADED PROJECT—LESSON 4 165

LESSON 5: GRAPHICAL USER
INTERFACE DESIGN 169

GRADED PROJECT—LESSON 5

195

SELF-CHECK ANSWERS

201

iii

C
o

n
t

e
n

t
s

C
o
n
t
e
n
t
s

1

I

n
s

tr
u

c
t

io

n
s

In
s

tr
u
c
tio
n
s

YOUR COURSE

Like watching a nimble artisan, you can’t learn Java by mere
observation. You must practice. This course will introduce
Java development by immersion. Each lesson builds upon
the previous one, layering concepts and growing skills—not
through passive interpretation, but by writing real-world
applications. The first few lessons will gently inch you into
the rich development world of Java, but by the end of the
course, you’ll have a fully functional application and the
associated skillset to create many more.

The textbook for the course is Java: A Beginner’s Guide, Fifth
Edition, by Herbert Schildt. This study guide accompanies the
textbook by providing reading assignments, additional
resources, insights and highlights, and step-by-step activities
and self-check questions to build skills and test your progress.
The answers to the self-check questions are at the end of the
study guide. The textbook also includes Try This activities
and Self-Test questions in each chapter to provide additional
practice.

The course is divided into five lessons, each with assignments
and a graded project. The first three lessons will provide a
foundation for using the Java language, while the last two
will move into specific Java frameworks. With the exception
of the first graded project, each subsequent graded project
will build upon the other. The final graded project is the
summary for the course, requiring you to apply your learned
Java knowledge and skills to an application built from the
ground up.

PREREQUISITES

This course assumes that you understand computer
components, are familiar with text editor applications, have
experience with programming languages other than Java, and
have had some exposure with object-oriented programming
and design. If these prerequisites are a bit rusty, then you
might find Oracle’s Java Tutorials (http://docs.oracle.com/
javase/tutorial/index.html) a helpful supplement to the
textbook and study guide.

When you complete this course, you’ll be able to

■ Write, compile, and run Java code

■ Implement common coding algorithms in Java

■ Create applications with object-oriented design principles

■ Use Java I/O and multithreading in applications

■ Create applets and Swing-based applications

YOUR TEXTBOOK

The textbook is Java: A Beginner’s Guide, Fifth Edition, by
Herbert Schildt. It contains a thorough introduction to Java
development and is a great preparation material for the Oracle
Java SE 7 Programmer certification. Java development is
divided into 16 chapters, starting with the runtime basics and
concluding with Swing. Answers to Self-Test questions are
found in the back of the book along with Java documentation
comments and an index.

COURSE MATERIALS

The main course materials are this study guide and the
textbook. The study guide consists of the following:

■ Reading assignments for each lesson

■ Lessons that emphasize and augment the reading

■ Activities to perform tasks and apply your learning

■ Self-check questions and answers to assess your learning

■ Graded projects for each lesson

Instructions to Students2

A STUDY PLAN

Everyone has his or her own style of learning. The object is
to find the method of learning that works best for you. What
follows is a suggested format for using this study guide.
Remember that it’s only a suggested plan. If you feel that
another method would help you learn more effectively, by
all means use that method.

This course divides the material to be covered into five lessons.
Each lesson is divided into multiple assignments to make your
learning more manageable. Each assignment includes a read-
ing from your textbook and a supplementary assignment in
this study guide. For most assignments, there are self-check
questions to check your understanding of what you’ve
learned. Be sure to complete all of the work in each lesson
before moving on to the next. You’ll find this easy to do if you
follow the plan of study outlined below.

1. Note the textbook pages for each assignment and read
the summary material in this study guide.

2. Quickly read the assigned pages in your textbook. This
is called skimming, and it’s a learning technique you
should use to get a general idea of the topics covered in
that part of the text.

3. Go back and slowly read the assigned textbook pages
again. Pay careful attention to what you’re reading. Keep
in mind the learning objectives and how the material
relates to them. Pay particular attention to definitions
and main concepts.

4. Answer the questions and problems provided in the self-
checks in the study guide. This will serve as a review of
the material covered. The self-checks are an integral part
of the assignment. Don’t move on to the next assignment
without taking the self-check. These questions are for
your use only—they aren’t graded. Don’t send your
answers to the school.

Instructions to Students 3

5. Once you’ve completed a self-check, turn to the answers
provided at the back of this study guide. The self-checks
are designed to show you how well you understand the
material, so test yourself honestly. Make every effort to
complete the questions before turning to the answers at
the back of this study guide. If you find any weak areas
in your knowledge, go back and review the relevant
material until you understand it.

6. Follow this procedure for the next assignments, until
you’ve completed the lesson.

7. When you’re confident that you understand all the assigned
material within a lesson, complete the examination or
graded project for that lesson. The examination is based
on both your textbook and this study guide.

8. Follow this procedure for all six lessons. If you have any
questions during your studies, e-mail your instructor for
assistance. You’re now ready to begin your study of Java
programming. Good luck!

Instructions to Students4

Remember to regularly check “My Courses” on your student homepage.
Your instructor may post additional resources that you can access to
enhance your learning experience.

Lesson 1: Introduction to the Java Language
For: Read in the Read in the

study guide: textbook:

Assignment 1 Pages 7–11 Pages 1–10

Assignment 2 Pages 13–18 Pages 10–11

Assignment 3 Pages 19–28 Pages 12–30

Graded Project 40259400 Material in Lesson 1

Lesson 2: Data Types and Program Control
For: Read in the Read in the

study guide: textbook:

Assignment 4 Pages 34–47 Chapter 2; Pages 158–164;
166–176

Assignment 5 Pages 48–59 Chapter 3; Pages 110–117;
176–177; 194–199

Assignment 6 Pages 60–65 Pages 136–158

Assignment 7 Pages 66–69 Chapter 9

Graded Project 40259500 Material in Lesson 2

Lesson 3: Object-Oriented Programming
For: Read in the Read in the

study guide: textbook:

Assignment 8 Pages 80–96 Pages 104–110; 124–134;
Chapter 6

Assignment 9 Pages 97–114 Chapter 7; Pages 268–278;
427–429

Assignment 10 Pages 115–123 Pages 278–292; 406–420

Assignment 11 Pages 125–131 Pages 420–426; Chapter 13

Graded Project 40259600 Material in Lesson 3

5

A
s

s
ig

n
m

e
n

t

s
A

s
s

ig
n

m
e

n
ts

Lesson 4: Advanced Programming Logic
For: Read in the Read in the

study guide: textbook:

Assignment 12 Pages 142–153 Chapter 10

Assignment 13 Pages 154–163 Chapter 11

Graded Project 40259700 Material in Lesson 4

Lesson 5: Graphical User Interface Design
For: Read in the Read in the

study guide: textbook:

Assignment 14 Pages 170–182 Pages 473–496; 536–537

Assignment 15 Pages 183–193 Chapter 15

Graded Project 40259800 Material in Lesson 5

Lesson Assignments6

Note: To access and complete any of the examinations for this study
guide, click on the appropriate Take Exam icon on your “My Courses”
page. You should not have to enter the examination numbers. These
numbers are for reference only if you have reason to contact Student
Services.

7

L
e

s
s

o
n

1
L

e
s

s
o

n
1

Introduction to the
Java Language

INTRODUCTION

There’s no better way to learn how to program in a new lan-
guage than to dive in! In this lesson, you’ll be introduced to
the Java language and runtime environment and you’ll tour
the NetBeans IDE. You’ll be writing, compiling, and running
your first Java application by its conclusion.

OBJECTIVES

When you complete this lesson, you’ll be able to

■ Explain how procedural languages differ from
object-oriented languages

■ Identify the main characteristics of Java technology

■ Install the Java Standard Edition 7
Runtime Environment

■ Identify language rules and common conventions in Java

■ Write, compile, and execute a simple Java program using
the NetBeans IDE

ASSIGNMENT 1: A BRIEF
OVERVIEW OF PROGRAMMING
Read Assignment 1 in this study guide. Then, read pages 1–10
in your textbook.

The Procedural Approach

This assignment is an overview of basic programming
approaches and introduces the Java language. The textbook
assignment recounts the history of Java and reviews important
concepts in high-level object-oriented programming (OOP).

Programming in Java8

The goal of programming is to solve problems. In the proce-
dural approach, the solution involves executing instructions
step by step. Each step may modify some data, but the data
and instructions are stored separately. Data can be stored in
structures such as arrays, sets, or records, while instructions
are grouped into procedures, and procedures are further
grouped into modules. Procedures and modules allow pro-
grammers to reuse code to reduce repetition and increase
manageability.

Take the example of making a fresh cup of coffee with a coffee
press. The data would include the amount of coffee beans
and boiling water, whether the beans were ground or whole,
and the time to boil the water and let the coffee brew. The
instructions would include the following steps:

■ Measure the amount of beans and water.

■ Place the beans in the grinder.

■ Grind the beans in the grinder.

■ Place the water to boil on the stove.

■ Place the ground beans in the coffee press.

You get the idea. These and other instructions could then
become simple procedures named Boil(), Measure(), Grind(),
Move(), Brew(), and Pour() in a module named Coffee. The
approach focuses on action and which data is required to
perform the actions.

A number of early languages, such as BASIC, COBOL, C,
and FORTRAN, implement this approach. The more modern
languages like Scala, Lisp, and F# implement a variation on
this approach, known as functional programming. Unlike
traditional procedural programming, functional programming
languages support additional built-in mathematical functions
and out-of-order execution for instructions.

The Object-Oriented Approach

The object-oriented approach is more abstract and less declar-
ative than the procedural approach. Data and instructions are
combined into entities that resemble real-world objects. The

Lesson 1 9

data is stored as attributes of the object, while instructions
are grouped into its methods. Objects can have complex rela-
tionships and interdependencies to optimize scalability and
reduce overall redundancy. In object-oriented design, a class
is a blueprint for objects, describing which attributes and
methods each object will support. Attributes are also known
as fields in Java.

Continuing with the coffee press example, an object-oriented
approach would first capture the real-world objects involved,
which include the beans, grinder, water, and coffee press.
The next step would be to determine which attributes each
object requires. Coffee beans can be either whole or ground,
so a field would need to represent that. Water can be either
boiling or not boiling, and a coffee press can be brewing coffee,
containing only beans, or empty. Like the procedural approach,
measurements are tracked, but in object-orientation, each
object tracks its own data. Finally, the methods need to be
determined for each object. The methods are very similar to
the procedures described previously, except they’re stored in
an object and usually require fewer arguments. For example,
the Grinder object would contain a method named grind()
that needs to know only how many beans to grind.

Most compiled languages and increasingly a number of
scripting languages as well, implement this approach. Unlike
C++ and Visual Basic, in which object-orientation was bolted
onto an existing procedural language, Java is built from the
ground up on object-oriented programming. As you’ll see,
even the simplest of programs requires a class and the
main() method to execute.

The Java Approach

One of the early slogans for Java was “write once, run anywhere.”
Java programs can run on diverse platforms—from standard
desktop and laptop computers to mobile phones and tablets.
The current high definition standard even supports Java running
from BluRay discs!

When Java was introduced in 1995, most programming languages
targeted a specific platform. Conversely, Java applications are
platform-agnostic, meaning the developer only needs to learn
Java, not keep track of the particulars of a specific CPU,

Programming in Java10

motherboard, chipset, or operating system. A developer also
doesn’t need to compile a program on each platform like C++,
because the source code is compiled into optimized Java
instructions, known as bytecode. Then, a specialized execu-
tion component known as the Java Virtual Machine (JVM)
takes that bytecode and runs it on any platform with the
JVM installed. The JVM is probably the reason why Java
hasn’t faded away and only grows in popularity as devices
and platforms become more diverse and powerful.

Note: The keyword,
native, allows for native
code to be integrated
into Java applications
to optimize certain
features for target
platforms. Overuse of
native code will nega-
tively affect the default
portability of a Java
application.

Lesson 1 11

Self-Check 1

At the end of each section of Programming in Java, you’ll be asked to pause and check your
understanding of what you’ve just read by completing a “Self-Check” exercise. Answering
these questions will help you review what you’ve studied so far. Please complete Self-
Check 1 now.

1. What is the fundamental difference between a procedural programming language and
an OOP language?

__________________________________________________________

2. What does the slogan “write once, run anywhere” mean for Java?

__________________________________________________________

Check your answers with those on page 201.

Programming in Java12

NOTES

Lesson 1 13

ASSIGNMENT 2: INSTALL THE
JAVA RUNTIME ENVIRONMENT
Read Assignment 2 in this study guide. Then, read pages 10–11
in your textbook.

The Java Runtime Environment (JRE) is a composite of the
JVM, runtime commands and applications, and essential
class libraries. The runtime commands include java and
javaw for running stand-alone programs, Java Web Start to
deploy applications through a browser, and Java Plug-in to
run applets within a browser. Essential class libraries include
classes for input/output (I/O), networking, database connections,
and user interface design.

Oracle offers three different flavors for the Java Runtime
Environment:

■ Standard Edition (SE)

■ Enterprise Edition (EE)

■ Micro Edition (ME)

Java EE provides additional support for servlets, Java
Server Pages (JSP), Java Server Faces (JSF), Enterprise
Java Beans (EJBs), and other technologies associated with
business applications. Think of Java SE as the client-side
runtime, while Java EE provides an additional framework
for server-side applications. Java ME is a configurable subset
of the Java SE for supporting small devices such as printers,
mobile phones, and smart cards. Java ME doesn’t contain all
class libraries found in SE, but does include Java for Mobile
Devices, Java Technology for Embedded, Java TV, and Java
Card.

Java Development Kit

To run a Java application, only the JRE is required. To develop
a Java application, you also need the Java Development Kit
(JDK). The JDK includes all components of the JRE, the com-
piler javac, and other developer tools. These tools provide
automated documentation with JavaDoc, a compression

Note: Web Start appli-
cations and applets are
now known as rich
internet applications
(RIAs) by Oracle.

Programming in Java14

formatter known as Java Archive (JAR), and even its own
relational database called Java DB. The JDK is also known
as the Java Software Development Kit (SDK), so don’t let the
name conflict confuse you. These two terms are synonymous
and used interchangeably in most documentation.

When downloading the JDK, you can choose to install the JDK
only or bundled with other Java technologies such as

JavaFX

or Java EE tools. The textbook uses the JDK only, but for this
course, you’ll download and install the JDK bundled with the
NetBeans Integrated Development Environment (IDE).

Activity 1: Install the JDK 7
with NetBeans Bundle

1. Download the JDK 7 with NetBeans Bundle from the
Oracle Java SE Download page (Figure1). The current
download URL is http://www.oracle.com/technetwork/
java/javase/downloads/jdk-7-netbeans-download-
432126.html

a. On the Web page, choose the Accept License
Agreement radio button.

b. Click on the file required for your platform. For
most students, this would be the link labeled
Windows x86.

c. Choose to save the file, so that you can re-run it
if necessary.

d. Once the download is complete, run the file. If you’re
prompted to allow the program to make changes to
your computer, click the Yes button.

2. Navigate through the Java SE Development Kit and
NetBeans IDE Installer wizard.

a. Click the Next button.

b. On the JUnit License Agreement page, choose I
accept the terms in the license agreement.
Install JUnit.

Lesson 1 15

c. You can change the JDK installation location if you
would like. Click the Next button.

d. You can change the NetBeans IDE and JDK for the
NetBeans IDE installation locations if you like. Click
the Next button.

e. Verify your configuration settings and then click the
Install button.

f. The installation will take several minutes. Click the
Finish button when it completes.

If you have any problems during the installation, please let
your instructor know.

FIGURE 1—NetBeans Download Page

Programming in Java16

NetBeans Projects

NetBeans is intended for developing and deploying Java
applications with many moving parts. To simplify manage-
ment, code is organized into projects and further subdivided
into packages. A project is a complete application, while each
related group of components in that project is a package.

NetBeans includes the following types of projects:

Java Application—Standard stand-alone application that’s
run using the java command. To simplify compilation, an
auto-generated build script handles all source code files.

JavaFX Application—A stand-alone application with JavaFX
enabled for a rich graphical user interface (GUI).

Java Class Library—Reusable code library with no
user interface.

NetBeans Module—Plug-in for the IDE itself. Since NetBeans
is a Java application, you can use Java to create plug-ins for it.

Activity 2: Create Your
First NetBeans Project

1. To launch NetBeans, click on the Start Menu and click
the All Programs section. Choose NetBeans IDE 7.2 in
the NetBeans folder.

2. In the File menu, choose New Project.

3. In the New Project wizard, choose the Java category and
Java Application project (Figure 2).

4. Click the Next button.

5. Type the name FirstJavaApp in the Project Name text
box at the top. Leave all other default settings (Figure 3).

6. Click the Finish button. It will take several seconds for
the new project to be created and saved.

Lesson 1 17

FIGURE 2—New Project

Figure 3—New Java Application Dialog

Programming in Java18

Self-Check 2

1. What is the primary difference between the Java SE and ME runtime environments?

__________________________________________________________

2. Why do you need to install the JDK to write Java applications? Is the JDK required to run
Java applications?

__________________________________________________________
Check your answers with those on page 201.

Lesson 1 19

ASSIGNMENT 3: WRITE, COMPILE,
AND EXECUTE JAVA PROGRAMS
Read Assignment 3 in this study guide. Then read pages 12–30
in your textbook.

As described on page 12 in the textbook, the basic development
process is three steps: enter, compile, and run. In real-world
development, you would first define what the application will do
and design the class structure and user interface prototypes.

Another important step is missing after compiling and running
a program: debugging! The compiler will catch syntax errors,
but semantic errors won’t be obvious until running the appli-
cation. Rarely will an application work perfectly as written,
especially when you’re writing in a new programming language.
Don’t be discouraged; making mistakes and learning how to
debug them is an integral part of becoming familiar with a
new language.

On page 13, the textbook describes how to compile and execute
a Java program using the command line. Because you’ll be
using NetBeans, the compile and execute steps are combined
into one. To run a Java application, simply click the Run
Project button (F6). The term building refers to the process of
compiling all classes within a project. Although NetBeans
automates the process somewhat, it’s important to remember
that Java source code files have the extension .java, and
compiled bytecode files have the extension .class. Also, mul-
tiple .class files can be combined into executable archive files
with the extension .jar.

Programming in Java20

The main() Method

In Java, a class is the primary container for code. Because
most applications consist of multiple classes, the class that
contains the main() method will be loaded first. The main()
method is the initial entry point, where JVM will start execution.
The main() method is declared in a class as follows:

class SomeClass {
public static void main ( String[] args ) {

//Starting code goes here

}

}

The code in bold is required by the JVM to see the main()
method. The public keyword ensures the main() method is
visible to the JVM, while the static keyword allows the JVM
to call the method without first creating a class object. The
void keyword indicates that there’s no return value. The
argument String[] args allows you to send arguments from
the command line when running an application. The variable
args can be named anything else, but common convention is
args. The following is an example of sending arguments:

java JavaApp1 “Argument 1” arg2 3

All arguments are treated as String objects (more about that
in the next lesson). The textbook describes command-line
arguments in more detail on pages 165–166 of Chapter 5.
With NetBeans, your applications won’t use command-line
arguments, because they’ll be launched through the IDE,
not via the command line.

Java Syntax and
Common Coding Conventions

Like C and C++, Java is case-sensitive and uses the semicolon ;
to terminate lines of code. Case-sensitivity can cause some
frustration to programmers who are familiar with more lenient
languages like Visual Basic. Don’t think of it as an arbitrary
convention—think of it as a way for the compiler to encourage
good programming practices.

Note: Your textbook
uses the argument
String args[] instead
of String[] args, but
either order is allowed.
String[] args is the pre-
ferred convention.

Lesson 1 21

Code Blocks and Comments

Java uses curly brackets { } to enclose blocks of code and
uses square brackets [ ] to define and access arrays (more
about that in the next lesson). Pages 24–26 in the textbook
go into more depth about how to create blocks of code and
good indentation practices when doing so.

The characters // specify an inline comment, while /* and

*/

are used for block comments. Developers use comments to
highlight important or complex algorithms, to provide book-
marks for future reference, or to remove code that may
contain errors during debugging. The compiler never reads
comments.

int i = 0; //This code initializes an integer to the default
value 0.

/*

* This is a longer comment

* set off from the code

* in multiple lines.

*/

Note: You can use
the Toggle Comment
option from the Source
menu or the keyboard
shortcut CTRL+/ in
NetBeans to hide code
during debugging.

Programming in Java22

There are also special comments using the characters /**
and */ for detailed documentation comments using JavaDoc.
The example below describes the loadImage method:

/**
* Returns an {@link Image} object based on an

absolution {@link URL

}

* and filename {@link String}.
* This method returns null if no compatible image

files exist.
* @param url an absolute URL
* @param name the image filename
* @return An Image object
* @see Image

*/
public Image loadImage(URL url, String name) {

//Imagine some code here
}

JavaDoc can then pull out the comments into HTML, XML, or
any other standard documentation format to share them with
other developers. JavaDoc will even generate missing com-
ments for parameters, return types, and other details. For
more details on JavaDoc, you can visit the Oracle Website at
http://docs.oracle.com/javase/7/docs/technotes/guides/
javadoc/.

Identifiers

When defining a class, method, variable, or custom data type,
you must follow Java naming rules. The first character of an
identifier can be a letter, an underscore _, or, a dollar sign $.
All subsequent characters can also include digits. As in other
languages, Java keywords are those that have special mean-
ing and aren’t allowed when you define your own identifiers.
See page 29 in the textbook for the complete list of Java key-
words and examples of allowable identifiers.

Lesson 1 23

When following syntax rules, you should also consider com-
mon programming conventions, especially those implemented
in the language. There are two casing schemes used in most
programming languages: camel and Pascal. Camel casing
keeps the first letter of the name lowercase, but then uses
uppercase for the first letter of each logical word or abbrevia-
tion. A competing standard is known as Pascal casing, where
even the first letter is uppercase. In Java, variables, methods,
and package names use camel casing, whereas Pascal casing
is used for class names and custom data types. This conven-
tion makes it easier to eyeball whether something is a class
or method without combing through lengthy documentation.

Cameo of Two Data Types
and Control Statements

Textbook pages 16–24 briefly mention two numerical data
types, and the control statements if and for. The data type
int represents whole numbers, while double represents frac-
tional values. The if statement executes code only once when
a condition is met, while a for statement executes code
repeatedly if the condition is met. Although you’ve been
exposed to these constructs before in other languages, you’ll
revisit this topic within the larger context of program control
in the next lesson and further along in the textbook.

Brief Tour of the NetBeans IDE

Similar to other development environments, the NetBeans
IDE uses toolbars, panels, and windows to provide access
to information and tools on the same screen (Figure 4). The
amount of information can seem overwhelming at first, but
over time, you’ll value having it at your fingertips.

Programming in Java24

Panels

For projects in this course, you need to be concerned only
with the following panels:

Projects. The Projects panel contains the logical structure
of all of your files associated with each NetBeans project. You
can add files to your project using the File menu or by right-
clicking in the Projects panel.

Files. The Files panel contains the physical structure of all
files associated with each NetBeans project. You can open
documents by double-clicking in the Solution Explorer panel
or using the File menu.

Documents. The Documents tabbed panel contains all
source code files opened in the IDE. A bolded file name in
the tab indicates whether a file has been modified since it
was last saved.

Navigator. The Navigator contains a logical breakdown of
the current document. Each method and field is displayed
and can be double-clicked to go directly to that member.

Output. The Output displays compiler information and out-
put for command-line applications with no GUI. You can also
used it for standard keyboard input.

Figure 4—NetBeans
IDE Window

Lesson 1 25

Main Toolbar

The main toolbar in NetBeans is broken into three groups
(Figure 5). The first group is used for file operations, such as
creating new files and folders, opening projects, and saving
all open files. The second group is used for performing undo
and redo edit operations. The last group contains buttons for
building, cleaning, and then re-building, executing, and
debugging projects. The green triangle button and its key-
board shortcut F6 builds a project and executes the
bytecode.

Activity 3: Enter, Compile, and Run

You’ll enter, compile, and run a simple Java application
using NetBeans. Be sure to read pages 12–28 in the textbook
carefully before attempting this activity.

1. If you’ve closed out of the FirstJavaApp project and
NetBeans, then launch NetBeans. (See Step 1 in
Activity 2).

2. The FirstJavaApp.java file should be open in
Documents. If not, double-click the FirstJavaApp.java
file in Projects. You should see the following default
code provided:

/*
* To change this template, choose Tools |

Templates
* and open the template in the editor.
*/

package firstjavaapp;

/**
*
* @author jhester
*/

public class FirstJavaApp {

Figure 5—NetBeans Main Toolbar

Programming in Java26

/**
* @param args the command line arguments
*/

public static void main(String[] args) {

// TODO code application logic here

}
}

3. Select the comment //TODO code application logic
here and replace it with the following code:

System.out.println(“Welcome to the World of
Java!”

);

4. Build and run the project by clicking the Run Project
button in the main toolbar or using the F6 keyboard
shortcut.

5. The Output panel should display the following result:

run:
Welcome to the World of Java!
BUILD SUCCESSFUL (total time: 1 second)

In the next part, you’ll make an intentional syntax error and
observe how NetBeans handles it.

6. In the main() method, add the following line of code:

This isn’t valid syntax;

Notice how the NetBeans editor underscores the code with a
red squiggly line. NetBeans is warning you that this part of
the code will fail compilation.

7. Try to build and run the project
anyway. Click the Run Project
button in the main toolbar or
use the F6 keyboard shortcut.

8. NetBeans should display the
warning in Figure 6.

9. Click the Run Anyway button.
The Output panel should dis-
play an error message in red.

Figure 6—Compilation Error

Lesson 1 27

In the last part, you’ll make an intentional semantic error
that won’t be detected until after the code is executed. This
code uses the for loop introduced on page 23 of the textbook.

10. Select the error-prone code This isn’t valid syntax; and
replace it with the following code:

/*
* This code will behave normally at first,
* but then grow too big and become large
* negative values.
*/

for (int i = Integer.MAX_VALUE – 10000; ; i++ )
{

System.out.println(“i: “ + i);
}

11. Run and build the project. Notice when the numerical
value gets too large for the int data type, the number
becomes negative. Because there’s no exit condition
specified in the for statement, the code will run in an
infinite loop.

12. In the Output panel, click the red stop button to end
execution.

Finally, you’ll correct the error and run the code again. The
process of running your code and verifying output is debug-
ging. The more time you spend on designing and debugging,
the less time you’ll spend on programming frustrations.

13. Modify the code in the for statement to stop once i
becomes negative as follows:

for (int i = Integer.MAX_VALUE – 10000; i > -1;
i++ ) {

14. Run and build the project. Notice how execution ends
before the max value is exceeded.

Programming in Java28

Self-Check 3

1. What is the extension of a source code file and which command do you use to compile it?

__________________________________________________________

2. What is the extension of a bytecode file and which command do you use to run it?

__________________________________________________________
Check your answers with those on page 201.

29

G
ra

d
e

d
P

ro
je

c
t

G
ra
d
e
d
P
ro
je
c
t

OVERVIEW

You’re ready to work on your first Java application. This proj-
ect will assess your understanding of writing, compiling, and
running a Java program.

Make sure that you follow all directions completely and verify
your results before submitting the project. Remember to
include all required components in your solution or you won’t
receive full credit.

Your Project

For your first project, you’ll create a simple number guessing
game. The game will use a for statement to ask for three
guesses and an if statement to determine if the answer is
right.

Instructions

1. In NetBeans, create a new Java Application project
named NumberGuess. Review Activity 2 for details.

2. In the main() method, add the code to generate a
random number:

Graded Project 130

int randNum = 0, guessNum = 0;
//Generates a random number from 1 to 10
randNum = new java.util.Random().nextInt(10) + 1;
System.out.println(“I am thinking of a number from
1 to 10”);

3. Using a for loop, ask for three guesses. See pages 23–24
in the textbook for more details. You can use the following
code to ask for a guess:

System.out.print(“Guess? “);
//Wraps the default input in a simple parser
called Scanner

java.util.Scanner scan = new
java.util.Scanner(System.in);

guessNum = scan.nextInt(); //Reads the next
command-line int
System.out.println(“You guessed “ + guessNum);

4. Using an if statement in the for block, determine
whether randNum and guessNum are equal. See pages
21–23 for in the textbook for more details. You can use the
following code if randNum and guessNum are equal:

System.out.println(“You guessed it!”);

break;

5. When you’re finished, the contents of the main() method
should resemble the following:

int randNum = 0, guessNum = 0;
//Generates a random number from 1 to 10
randNum = new java.util.Random().nextInt(10) + 1;
System.out.println(“I am thinking of random number
from 1 to 10”);
for (/* Figure this part out yourself */) {

System.out.print(“Guess? “);
java.util.Scanner scan = new

java.util.Scanner(System.in);
guessNum = scan.nextInt();
System.out.println(“You guessed “ +

guessNum);
if (/* Figure this part out yourself */) {

System.out.println(“You guessed it!”);
break;

}
}

Note: The input/output
code will be explained
in the last lesson. Don’t
worry about under-
standing all of it now.

Note: The break state-
ment will be explained
in the next lesson.

Graded Project 1 31

6. Compile and run the project to ensure it works as
expected. To type input, make sure you click in the
Output panel; otherwise, you’ll modify code.

Submission Guidelines

To submit your project, you must provide the following
two files:

■ NumberGuess.java

■ NumberGuess.class

To find these files within NetBeans, go to the NumberGuess
project folder. To determine this folder, right-click on
NumberGuess project in the Projects panel. Copy the value for
the Project Folder textbox using the keyboard shortcut
CTRL+C. In Windows Explorer, paste the project folder path
and hit the ENTER key. Copy both the NumberGuess.java
file from the src\numberguess folder and the
NumberGuess.class file from the build\numberguess folder
to your desktop or any other temporary location.

Follow this procedure to submit your project online:

1. Log on to the Penn Foster website and go to My Courses.

2. Click Take Exam next to the lesson you’re working on.

3. Attach your files as follows:

a. Click on the Browse box.

b. Locate the file you wish to attach.

c. Double-click on the file.

d. Click Upload File.

e. Since you have more than one file to attach, click on
the Browse box again, and repeat steps b, c, and d
for each file.

4. Enter your e-mail address in the box provided. (Note:
This information is required for online submissions.)

5. If you wish to tell your instructor anything specific
regarding this assignment, enter it in the Message box.

6. Click Submit File.

Graded Project 132

Grading Criteria

Your instructor will use the following guidelines to grade your
project.

The source code file includes
the provided code: 20 points

The for statement loops
only three times: 30 points

The if statement checks for equality
between the required variables: 30 points

Both source and compiled code
files are included: 20 points

TOTAL 100 points

33
L
e
s
s
o
n

2
L

e
s
s
o

n
2

Data Types and
Program Control

INTRODUCTION

As with all languages, you’ll need to learn the basics of how
to store and perform operations on data and control applica-
tion flow. This lesson will introduce you to using data types,
operators, and expressions and handling program flow using
control statements and blocks in Java. In addition, you’ll learn
about how to logically group values and statements using
arrays and methods, respectively.

OBJECTIVES
When you complete this lesson, you’ll be able to

■ Declare variables for values and choose the appropriate
primitive data type

■ Use literal values, typecasting, and standard operators

■ Use methods associated with String objects

■ Explain how different expressions are evaluated

■ Define application logic using appropriate
control statements

■ Define and use methods

■ Declare and use arrays to handle multiple related values

■ Discuss multidimensional arrays

■ Handle runtime exceptions

Programming in Java34

ASSIGNMENT 4: USE DATA TYPES,
VARIABLES, AND OPERATORS
Read Assignment 4 in this study guide. Then read Chapter 2,
as well as pages 158–164 and 166–176 in your textbook.

In Assignment 4, you’ll be introduced to how to use variables
to perform operations. Be sure to complete the Try This activ-
ities in Chapter 2. They’ll acquaint you with any unfamiliar
data types in the lesson. The selected pages in Chapter 5
introduce how strings are used in Java and some bitwise
arithmetic operations.

Primitive Data Types

As you may remember from the previous lesson, all programming
languages rely on data to perform their work. Each individual
piece of data (known as a datum) can represent different things
and may require different storage considerations. Water
measurement will require more precision than the number of
beans, for example. This data is very different than determin-
ing whether the water is boiling. The water is either boiling or
isn’t boiling; there’s no in-between value.

The built-in data types in Java are known as primitive types.
Their storage model is remarkably simple compared to objects.
The value for a primitive type has a fixed size and is stored
on the default memory stack. Whether an int type stores the
number 4 or 4,000,000, an int will always be 16 bits (2 bytes)
in size. If two int types have the same value, they’ll still be
stored separately in memory. Primitive types are both fixed
in size and unique.

In terms of complexity and storage, Boolean is the simplest
primitive. The only literal values valid for a Boolean are true
and false. Storage is a single bit that is either 0 or 1.

For numeric values, you can choose from integer or floating-
point data types. In Java, all numbers are signed, meaning
that a sign bit is required for every number to indicate
whether it’s positive or negative. Integers are whole numbers
without fractional amounts, while floating-point numbers
support decimal points. Floating-point numbers store only

Lesson 2 35

the significant digits of numbers, ignoring leading and trailing
zeroes, and use a base and exponent to represent the num-
ber’s magnitude. The number of significant digits is known as
its precision, while the magnitude is known as its scale. For
example, the value 15,050,000 is stored as 15050000 in the
integer primitive int, but stored as 1.505E7 in the floating-point
primitive double.

Integer primitives differ only in storage size. A byte uses 8 bits,
while a long stores numbers with 64 bits or 8 bytes. The most
commonly used integer primitive is int and for most programs,
its size will be adequate. You’ll find a complete table of integer
data types and their sizes and number ranges at the bottom
of page 33 in the textbook.

The primitives float and double also differ by storage, but
because they use a floating-point representation, the differ-
ence is in precision and scale, not an actual value range. A
float devotes 23 bits to represent the precision and 8 bits for
the scale. Together with the sign bit, a float is 32 bits in size.
A double is twice that size—64 bits.

The final primitive is char. This data type represents a 16-bit
Unicode character (UTF-16), meaning that Java supports a
majority of known languages in the world. A value for a char
can be specified as an integer, literal character, or hexadeci-
mal character code. Character codes are specified using the
\u suffix. You can find a complete list of character codes at
http://www.fileformat.info/info/charset/UTF-16/list.htm.

Variable Declaration and Scope

To reuse a value stored in memory, you must first reserve
and identify it using a variable. In Java, all variables must be
declared with a specified data type and name before they can
be used. The data type can be a primitive or object type and
the name must be a valid identifier. See the Identifiers section
in the previous lesson for Java rules when using identifiers.

Programming in Java36

The following code demonstrates how to declare variables:

Notice that the second and fourth lines declare multiple vari-
ables using commas. The third, fourth, and last lines also
use the assignment operator (=) to declare a variable and ini-
tialize its value in the same statement. In Java, variables
must be initialized to a value before they’re used in other
statements. The last line uses the final keyword to declare a
constant. Constants can be used like variables, but they
must be initialized when declared and their values can’t be
modified after their assignment.

Variables don’t persist forever; they have a limited lifetime,
known as scope. Scope is fairly straightforward: a variable
is available only within the code block in which it’s declared.
Although the same identifier can’t reference different values
in the same scope, identifiers at different levels of scope can
have the same name. This can cause some serious confusion,
so you should avoid using the same name for variables at
different scopes.

The following simplified code demonstrates scoping:

{
int x = 10;
{
//x is available here
}
}
//x is out of scope here
int x = 10; //this is x at a different scope

Pages 43–46 in the textbook describe scoping issues in
more depth.

int num; //One uninitialized integer
double num1, num2, num3; //Three uninitialized floating-point
short num4 = 1000; //One initialized integer
float num5, num6 = 10; //One initialized and other not
final char SPECIAL_CHAR = ‘Y’; //Constant value that can’t be changed

Lesson 2 37

Using Literal Values

Unlike variables, literal values are used once and then discarded.
Like most languages, Java has some conventions for writing
literal values in code. Characters use single quotes while
multicharacter strings use double quotes. Whole numbers
are treated as int, byte, or short (depending on the literal
size), while numbers with decimal points are treated as double
types. If you want Java to treat whole numbers as long, then
you can use the suffixes L in the literal for long. If you want
Java to treat a number with a decimal point as a float, then
use the suffix f. This is the one situation where Java isn’t
case-sensitive. Oracle recommends using an uppercase suffix
for long and lowercase suffix for float.

The following are some literals with suffixes:

long num1 = 943543511234533145L; //Number was too
big for int, so must use suffix

float num2 = 453232234.52124f; //Loss of
precision error if suffix was not used

By default, local variables aren’t set to a value. However,
fields declared at the class level are set to a default value
automatically. Table 1 lists the default values for data types
when declared at the class level. Notice that all reference
types or objects default to the value null. Think of null as an
empty variable with no reference. The next lesson will pick up
this topic again when discussing reference types.

Java 7 also supports other means of formatting and repre-
senting literal numbers. Although the comma can’t be used
for grouping digits in a number, the underscore character is
supported. The underscore can be placed only between digits
and can’t be at the end or beginning of a number. The follow-
ing code demonstrates using the underscore in a literal
number:

int largeNumber = 36_997_000_145;

Although the default representation for numbers is traditional
decimal notation, you can specify literals using scientific
notation, hexadecimal, or binary. Scientific notation is sup-
ported only for the floating point types float and double, but
can use an uppercase or lowercase E to indicate the expo-
nent. Hexadecimal requires the prefix 0x, while the prefix 0b

Programming in Java38

indicates binary. Be aware that these alternative representa-
tions are provided for convenience, but aren’t stored any
differently than other numerical values.

The following are some literals specified in other notations:

double d1 = 5_100_000;

double d2 = 5.1E6; //Same value as d1 in scientific
notation

byte b1 = 127;

byte b2 = 0b0111_1111; //Same value as b1 in binary

byte b3 = 0x7F; //Same value as b1 and b2 in hexa-
decimal

Type Casting

Normally, Java will handle conversions between primitive
types automatically. For example, assigning an int value
to a double is an automatic conversion that you need not
worry about it. But you’ll run into situations where there’s
a conflict between data types. Take the following example:

int i = 256;

byte b = i;

Data Type Default

Boolean False

byte, short, int 0

long 0L

float 0.0f

double 0.0

char ‘\u0000’

Object Null

Table 1—Data Type defaults

Lesson 2 39

The assignment of a variable to another variable isn’t at issue,
because this is common. Assigning a variable to another sim-
ply copies the original value and assigns it to the second
variable. The conflict isn’t in the assignment, but the value
itself. The value 256 falls within the range of legal values for
int, but well outside the valid range for byte. A byte can’t be
more than 127. Serious consequences will result when trying
to push too large a value into a smaller space. In Activity 4,
you’ll explore these consequences firsthand.

In order to accept the conversion operation, you need to use
explicit conversion known as casting. Casting syntax specifies
the desired data type in parentheses on the right side of the
assignment operation. Using casting, the example can now be
compiled with the following modification:

int i = 256;

byte b = (byte) i;

In the next lesson, you’ll also use casting to perform reference
type conversions as well.

Common Operators

An expression is a group of data that must be calculated at
runtime. Expressions can contain literal values, variables,
constants, and/or methods. Operators are special symbols
that affect one or more values within an expression. The val-
ues that are provided as input to an operator are known as
operands. Determining the overall value for an expression is
known as evaluation.

As the table on page 46 in the textbook demonstrates, Java
provides standard arithmetic operators required for numeric
expressions.

Note: All operators in Java are dependent on the operands you
provide, especially the case when using the division operator
with two integers. The result will not be a fractional amount,
but an unrounded integer. You’ll need to use casting to get
the decimal value. Instead of using 4 / 5, use (double) (4 / 5).

There are also single-argument operators, known as unary
operators. Table 2 describes the unary operators.

Programming in Java40

As indicated by the increment and decrement operators ++
and – –, shorthand arithmetic assignment is supported by
Java. To perform other arithmetic operations like division and
multiplication, you would use the arithmetic operator and
assignment operator together. For example, to double the
variable x, you could use the expression x *= 2. Actually, the
following statements are equivalent:

i++;

i += 1;

i = i + 1;

Numeric expressions must evaluate to a number like int or
double, while conditional expressions must evaluate to a
boolean. The two tables on page 48 in the textbook list the
relational and logical operators available in Java. Note that =
is used for assignment and == tests equality. Another impor-
tant difference is between the default operators & and |, and
the short-circuit operators && and ||. If the first operand is
false when using the && operator or true when using the ||
operator, then the second part isn’t evaluated, because the
hole expression will evaluate to false or true, respectively.
Such behavior reduces computation time, but can create
some unexpected results if you don’t know about it.

Unary Operator Description Code Example

+ Makes a number positive(default value) int i = +286;

– Makes a number negative float f = –120.7;

~ Reverses each binary bit of a number
byte b = ~0b011;
//Becomes 100

++ Increments a variable by 1 i++;

– – Decrements a variable by 1 x– – ;

! Reverses a boolean value boolean b1 = false; boolean b2 = !b1;

Table 2—Unary Operators

Lesson 2 41

Operator Precedence

Normally, operations are performed in order from left to right.
Some operations have higher priority than others and are eval-
uated first. This is known as operator precedence. You’ve seen
this in many arithmetic operations before. Take the following
example:

6 + 10 / 2 – 4

Without operator precedence, you would go from left to right,
adding 6 to 10, then dividing it by 2, and finally subtracting 4.
The result of 4 is incorrect, because multiplication and divi-
sion occur before addition and subtraction. Using operator
precedence, you should first divide 10 by 2, then add 6, sub-
tract 4, and get the result of 7. Java is the same way, but there
are more than arithmetic operations to consider! Table 2-3 on
page 56 of the textbook lists precedence from highest to lowest.
As in arithmetic, you can use the parentheses to perform
operations out of their normal order.

Also confusing is the placement of ++ and – – operators. The
following two expressions will increment x by 1, but will perform
the operation at different times:

++x //Prefix increment

x++ //Postfix increment

In the first expression, x is incremented immediately and the
new value for x will be used for any other operations. In the
second expression, x is incremented later and the current
value for x will be used for other expressions. Prefix opera-
tions occur before evaluation, while postfix operations occur
after evaluation. In the next activity, you’ll use postfix and
prefix operations in expressions.

Activity 4:
Using Operators in Expressions

1. Launch NetBeans if it’s not already open. To launch
NetBeans, click on the Start Menu and click the All
Programs section. Choose NetBeans IDE 7.2 in the
NetBeans folder.

Programming in Java42

2. Create a new Java project named Lesson2Activity4. To
create a new Java project, follow these steps:

a. In the File menu, choose New Project. In the New
Project wizard, choose the Java category and Java
Application project.

b. Click the Next button.

c. Type the name Lesson2Activity4 in the Project
Name text box at the top. Leave all other default set-
tings.

d. Click the Finish button. It will take several seconds
for the new project to be created and saved.

3. Select the comment //TODO code application logic here
and replace it with the following code:

//Activity 4
byte b1 = 0b0111_1111;
int i1 = 127, i2 = -1;
boolean isb1i1Equal = b1 == i1;
boolean isb1i2Equal = b1 == i2;

System.out.println(“Is b1 equal to i1? “ +
isb1i1Equal);
System.out.println(“Is b1 equal to i2? “ +
isb1i2Equal);

4. Before you run this code, take time to consider what you
think the output will be.

5. Build and run the project by clicking the Run Project
button in the main toolbar or using the F6 keyboard
shortcut.

6. Remember that literals that begin with the 0b prefix are
using a binary representation. Did the output meet your
expectations?

7. Modify the byte declaration line as follows:

byte b1 = 0b1111_1111;

Lesson 2 43

8. Notice there’s a compilation error indicated by the red
squiggly line under the code. Move your cursor over the
highlighted statement. What does “possible loss of preci-
sion” mean?

9. To make this code compile, we need to explicitly cast the
value to a byte. Modify the byte declaration line as fol-
lows:

byte b1 = (byte) 0b1111_1111;

10. Build and run the project again. Why is the
result different?

11. Under the previous code, add the following code:

double result1 = 10.2 – 5 * 10 + i1++;
double result2 = (10.2 – 5) * 10 + ++i1;

System.out.println(“result1 = “ + result1);
System.out.println(“result2 = “ + result2);

12. Before you run the code, take time to consider what you
think the output will be.

13. Build and run the project by clicking the Run Project
button in the main toolbar or using the F6 keyboard
shortcut.

14. Remember order precedence and the difference between
the prefix and postfix increment operators. Also, notice
that i1 starts as 127 and then is incremented to 128
after result1. Did the output meet your expectations?

You’ll use this same project in Activity 5, so you can keep it
open.

Note: Remember that a
byte can’t be more
than 127 positive, but
you tried to push into
that small size the
value 255. Don’t forget
that one bit is reserved
for its sign.

Programming in Java44

The String Object

In Java, variable-length text is stored in a specialized object
known as String. String literals are enclosed using double
quotes, rather than the single quotes used by char. Table 2-2
on page 40 lists some common escape characters you can
use in String literals for spacing and other special charac-
ters.

Because a String is an object, it has methods you can use to
manipulate it. Page 160 in the textbook lists some common
String methods you’ll use. Like arrays, Strings use zero-based
indexes, so the first character is at position 0, not 1. Also,
notice that you use the equals method to see if two String
values have the same characters, not the equals operator ==.
The most common operation you’ll perform with a String is
concatenation. Concatenation is combining Strings using the
addition operator +.

String values are immutable, meaning they can’t be modified
after being initialized. In other words, a String value is actually
read-only.

Take the following code:

String name = “Joshua, “;
name += “welcome to”;
name += “ Java”;
name += “.”;

Although only the name variable is declared and used, there
are technically four String objects stored in memory. The
concatenation is actually creating a new String object, rather
than modifying the existing one. If the String values are lengthy,
then you should consider using the StringBuilder class
instead.

The StringBuilder class limits the number of String objects
and provides additional manipulation methods. When you’re
done using the StringBuilder class, you need only invoke the
toString() method to get the underlying String object. You
can learn more about the StringBuilder class by visiting the
Oracle website at http://docs.oracle.com/javase/tutorial/
java/data/buffers.html.

Lesson 2 45

Activity 5: Perform String Operations

1. Launch NetBeans and open the Lesson2Activity4 project
if you’ve closed out of the NetBeans.

2. The Lesson2Activity4.java file should be open in
Documents. If not, then double-click the file in the
Projects panel.

3. So that you can keep the code used in Activity 4 for fur-
ther reference without affecting this activity’s code, you’ll
comment out the current code. To do this, highlight the
current code in the main() method and then choose the
Toggle Comment option from the Source menu or the
keyboard shortcut CTRL+/.

4. Add the following code to the main() method:

5. Read through the code before building and running the
code. Can you predict the output?

6. Build and run the project. Does it work as expected?

7. Modify the value for the msg variable and see if you can
predict how the output changes.

//Activity 5
String msg = “Java is Fun to Write and Drink!”;
System.out.println(msg);
System.out.println(msg.toLowerCase());
System.out.println(msg.toUpperCase());
System.out.println(“Length: “ + msg.length());
System.out.println(“First char: “ + msg.charAt(0));
System.out.println(“Last char: “ + msg.charAt(msg.length()-1));
System.out.println(“First i: “ + msg.indexOf(“i”));
System.out.println(“Last i: “ + msg.lastIndexOf(“i”));

Programming in Java46

Bitwise and Shift Operations

As you may recall from earlier programming courses, all numbers
and instructions are stored using a binary representation.
When creating low-level classes, you may need to manipulate
these representations. Java provides the bitwise and shift
operators for just this purpose. Pages 166–176 in the text-
book provide a thorough introduction to bitwise and shift
operators if you want to learn more. Don’t feel too intimi-
dated; most Java programmers use binary representations
sparingly.

Lesson 2 47

Self-Check 4

1. What are primitive data types?

__________________________________________________________

2. What is the difference between integer numbers and floating-point numbers?

__________________________________________________________

3. When should you use explicit casting?

__________________________________________________________

4. What is the value of the variable result after the following statement?

double result = (5 – 10) + 15 % 7 * 10 ^ 2;

__________________________________________________________

5. What is the value of the variable charVal after the following statement?

char charVal = “Strings of Java”.toUpperCase().charAt(2);

__________________________________________________________

Check your answers with those on page 202.

Programming in Java48

ASSIGNMENT 5: EXECUTE WITH
PROGRAM CONTROL STATEMENTS
AND METHODS
Read Assignment 5 in this study guide. Then read Chapter 3,
Chapter 4 pages 110–117, Chapter 5 pages 176–177, as well as
Chapter 6 pages 194–199 in your textbook.

Assignment 5 introduces the syntax for control statements
and methods. Be sure to complete the Try This activities in
Chapter 3. They’ll acquaint you with any unfamiliar data
types in the lesson. The selected sections in Chapters 4–6
describe basic and overloaded methods, and the ? operator.

Conditional Statements

It’s not uncommon that a statement or block of statements
should execute only if a specific condition is true. One of the
primary mechanisms of control in Java is the if statement.
The if statement can be accompanied by the else for any
statement(s) that must execute if the condition isn’t true.
The general syntax is as follows:

if ( conditional_expression ) {
//statements that execute if true

} else {

//statements that execute if false

}

The syntax shown above is the long-hand form when more
than one statement must execute. You could also use the
short-hand syntax if only a single statement need execute.
The following code is an example:

if (msg1.equals(msg2))
System.out.println(“EQUAL”);
else System.out.println(“NOT EQUAL”);

Typical of Java, there’s also a shorter syntax. If only a single
value needs to be returned, then you can use the ? operator.
The ? operator uses the following syntax:

conditional_expression ? value_if_true :
value_if_false

Lesson 2 49

The previous example could use the ? operator as follows:

System.out.println( msg1.equals(msg2) ? “EQUAL” :
“NOT EQUAL”);

Although you can use logical operators to combine conditional
expressions, you may want to perform separate checks. You
can use the else-if statement to do this as follows:

if (guess == number) {
System.out.println(“Good job!”);
} else if (guess > number – 5 && guess < number + 5) { System.out.println(“Very close!”); } else if (guess > number) {
System.out.println(“Way too high!”);
} else if (guess < number) { System.out.println(“Way too low!”); }

Notice that the conditional expression in the else-if state-
ment is evaluated only when the condition is false in the
previous if or else-if statement.

Using else-if statements can be useful for complex conditions
and value ranges, but not for testing discrete values. Java
provides the switch statement for those situations. The fol-
lowing code demonstrates usage of the switch statement:

switch (state) {
case “TX”:
shippingCost = 4.59;
break;
case “GA”:
shippingCost = 2.85;
break;
case “NY”:
case “LA”:
shippingCost = 3.65;
break;
default:
shippingCost = 5.00;
}

Programming in Java50

Note the following about this code. The variable or expression
can be a byte, int, char, String, or enumeration (more about
that in the next lesson). The first two case labels for TX and
GA specify only one condition, but the third label for NY falls
through to the fourth label for LA. Any case label that doesn’t
contain a break statement will fall through. The break state-
ments exit the switch statement, so that no other code in the
switch block is executed. Finally, the default label is exe-
cuted if there’s no match in the previous case labels.

Iterative Statements

Whereas conditional statements will execute statement(s) only
once if a condition is true, iterative statements can execute
multiple times while the condition is true. The two simplest
iterative statements are while and do-while. The only differ-
ence between the two statements is when the condition is
evaluated. Because the condition in the do-while statement
is evaluated at the end of each iteration, the statements in
the do-while block will execute at least once.

In both the while and do-while statements, the number of
iterations is dependent on the conditional expression and
not necessarily on a counter. Java provides the for statement
specifically for handling counters. The general syntax for the
for statement is as follows:

for (initializer_statement; conditional_expres-
sion; iteration_statement) {

//statements to run here
}

The initializer statement runs once before the for block starts
its first iteration. The conditional expression is evaluated before
each iteration, while the iteration statement is executed after
each iteration. The following code demonstrates using the for
statement:

for (int count = 10; count >= 0; count—) {
System.out.print(count + “…”);
}

System.out.println(“BLAST OFF!”);

Besides using a counter, you can also use the break and
continue statements to control the number of iterations. The
break statement will exit a code block, while the continue

Lesson 2 51

statement will skip the remaining code in the block and move
onto the next iteration. As you saw for the switch statement,
the break statement can be unlabeled to exit out of the
innermost code block. You can also create labels and specify
which code block to exit as follows:

outer: for (int x = 0; x < 100; x++) { inner: while (!isFound) { if (x == codeValue ) { System.out.println(“FOUND IT!”); break outer; } } }

Activity 6: Create a Simple Countdown

In this activity, you’ll use nested loops with a continue
statement.

1. Create a new Java Application project named
Lesson2Activity6. Review steps 1 and 2 of Activity 4
if you need help on performing this action.

2. Select the comment //TODO code application logic
here and replace it with the following code:

char promptChar = ‘\u0000’; //null
character
//Remember this line from the first graded
project?
java.util.Scanner scan = new
java.util.Scanner(System.in);
int counter = 100, block = 10; //Total count
and block

do {
for (int i = block; i > 0; i— ) {
System.out.print(counter + “…”);
counter—;
}
System.out.print(“\nContinue countdown?(y/n):
“);
promptChar = (char) scan.next().charAt(0);
} while (promptChar != ‘n’);

Programming in Java52

3. Before you run the code, take time to consider what you
think the output will be. The code will count from 100 in
decrements of 10, until the n character is pressed.

4. Build and run the project by clicking the Run Project
button in the main toolbar or using the F6 keyboard
shortcut. Remember: Click in the Output panel to type
input. You have to type in a character other than n and
hit the ENTER key to continue. Type n and hit the
ENTER key to stop the application.

5. Think about how you could modify this code to print
only even numbers in the countdown. Hint: The modulus
operator % is commonly used to find even and odd numbers.

6. Replace the code in the for block with the following:

if (counter— % 2 != 0) continue;
System.out.print(counter + “…”);

7. Build and run the project. Does it work as expected?

8. Notice that every tenth value is omitted. This is because
the counter variable is now decremented at the beginning
of each iteration. It would be easier if the for statement
could handle both variables i and counter. Luckily, for
loops can have multiple expressions in the iteration
statement!

9. Modify the for block as follows:

for (int i = block; i > 0; i—, counter— ) {
if (counter % 2 != 0) continue;
System.out.print(counter + “…”);
}

10. Build and run the project. It should now work as
expected. How would you modify the code to exit before
reaching 50? Hint: You could use the break statement.

You’ll use this same project in Activity 7, so you can keep
it open.

Lesson 2 53

Declaring Methods

Methods are useful in hiding complexity and reusing common
code. Two methods you’ve been using so far are main() and
println(). The main() method is where you placed code to run
when the application starts, while println() writes output to
the command line. You also learned about methods used with
String objects, such as toUpperCase() and charAt(). Some of
these methods accept input data known as arguments and
when they finish, send back output known as a return value.

To declare your own methods, you should use the following
syntax:

return_type MethodName (list_of_parameter_types) {
//definition here
}

The return type specifies what data type the method will
return or the keyword void if no value is returned. To return
a value in a method, you use the return statement. Java is
very strict about return values—if the method specifies a
return type, then all code paths in the method must return
that data type or compilation will fail. You can also specify a
return statement with no value to exit a method prematurely.

The parameter list is comma-delimited and order-dependent.
When invoking a method, the Java runtime determines the
values for the parameters based on the order of arguments.

Take the following method:

double drink(double sipAmount, double totalSize )
{

return totalSize – sipAmount;
}

Because this method specifies two double parameters, you
must provide two double arguments to invoke it. You don’t
need to handle the return value, but the order in which you
place the arguments will affect the return value. If you invoke
the drink() method with drink(10, 20), then the argument 10
will be the value for the sipAmount parameter, 20 will be the
value for the totalSize variable, and the return value will be 2.0.

Programming in Java54

Java also allows a variable number of arguments, known as
varargs. Unlike normal parameters, a varargs parameter is
optional and can have more than one value. The following
method uses the ellipse to specify a varargs parameter:

void printArgs(Object… objs) {
for (int i = 0; i < objs.length; i++) { System.out.println(“Argument#” + i + “: “ +

objs[i]);
}
}

This should look similar to how main() method arguments
were handled in the first lesson. This is because the varargs
parameter is treated like an array. Arrays will be discussed in
the next section.

The code printArgs(“Testing”, 5, 10.5f, ‘c’, false); will produce
the following output:

Argument0: Testing

Argument1: 5

Argument2: 10.5

Argument3: c

Argument4: false

A varargs parameter can appear as the only or last parameter
for a method. Otherwise, the runtime would be unable to dif-
ferentiate between normal and varargs parameters.

Note: Like class variables, methods can also include modifiers
such as public and static. These modifiers will appear before
the return type. In the next lesson, the meaning of these
modifiers will be discussed. For now, just understand that
static is a required modifier when invoking a method directly
from the main() method. Remember the main() method is
also declared with the static keyword.

Overloading

Recall that the Java runtime determines the values for the
parameters based on the order of arguments when invoking
methods. The name of a method and its order of parameter
data types is known as a method signature. The method

Lesson 2 55

signature is how the runtime figures out which method
should be invoked. When you invoke a method named
doSomething with the arguments 3, 4, 5, and 6, then the
Java runtime is looking for a method with the signature
doSomething(int,int,int,int). Because of automatic type
conversions, other compatible signatures could also include
doSomething(double,double,double,double) or even
doSomething(int,double,int,double).

Why is this somewhat obvious point worth mentioning?
It’s because Java supports a feature known as overloading.
Overloading occurs when two or more methods have the
same name, but specify a different order or data types for
parameters. Overloading enables a single method name to be
reused, so that it can be specialized for different situations.
Take the drink() method from before. You could expand it to
accept an additional argument to handle more than one con-
tainer. The following code overloads the drink() method:

Again, the Java runtime knows which version of the drink()
method you want based on the arguments you provide. If you
provide two double arguments, then the first drink() method
is invoked. If you provide that additional int argument, then
this second drink() method is invoked. Pages 194–199 in
Chapter 6 of the textbook provide further examples of method
overloading. In the next activity, you’ll use overloaded meth-
ods to modify the countdown application.

Activity 7: Create Countdown Methods

1. Open the Lesson2Activity6.java file in NetBeans.

2. Cut the following code from the main() method:

for (int i = block; i > 0; i—, counter — ) {
if (counter % 2 != 0) continue;
System.out.print(counter + “…”);

}

double drink(double sipAmount, double totalSize, int numContainers) {
return numContainers * (totalSize – sipAmount);

}

Programming in Java56

To cut the code, highlight the code lines and use the
keyboard shortcut CTRL+X. You can also right-click on
the selected code and choose the Cut option from the
context menu.

3. Declare the following methods in the Lesson2Activity6
class (make sure you place your cursor before the final
closing curly brace):

4. Notice these are overloaded countdown methods. The
first countdown method will take three arguments so
that the countdown occurs in blocks and skips certain
numbers. The second countdown method will work only
countdown in blocks and not skip numbers. The third
countdown method will simply count down without
using blocks or skipping numbers. The first two count-
down methods return an int, so that the program can
continue the countdown after the method returns. The
last countdown will keep going until it reaches 1, so it
returns no value.

5. Paste the cut code into the first countdown method. You
can use the keyboard shortcut CTRL+V or right-click in
the method and choose the Paste option from the con-
text menu. Don’t worry if the paste operation failed; you
can always retype the code from step 2.

static int countdown (int counter, int block, int skip) {

}
static int countdown (int counter, int block) {

}
static void countdown (int counter) {

}

Lesson 2 57

6. Modify the code in the first countdown method as follows:

7. As you might imagine, the code for the second count-
down method will be very similar. So why should you
rewrite all of that code? The second countdown method
could just call the first version, using the value of 1 for
the skip argument. This is informally called piggybacking.

8. Add the following code to the second countdown
method:

return countdown(counter, block, 1);

9. You can do the same thing with the third countdown
method as follows:

countdown(counter, counter);

Notice that there’s no return statement, because the
third countdown method doesn’t return a value. By
specifying the counter argument for both the counter
and block parameters, you’re allowing the countdown to
go completely to 1.

10. Go back to the main() method and in the do-while block,
invoke the first countdown method as follows:

counter = countdown(counter, block, 2);

11. Build and run the project. The output should match as it
did at the end of Activity 6.

12. Now, replace the code and invoke the second countdown
method as follows:

counter = countdown(counter, block);

13. Build and run the project. The output should now match
as it did at step 4 of Activity 6.

static int countdown (int counter, int block, int skip)
{
for (int i = block; i > 0; i—, counter — ) {
if (counter % skip != 0) continue;
System.out.print(counter + “…”);
}
return counter;
}

Programming in Java58

14. Finally, replace the code and invoke the third count-
down method as follows:

countdown(counter);

15. Build and run the project. The output should now count
all the way down to 1. Feel free to modify your arguments
to see how the output changes.

Lesson 2 59

Self-Check 5

1. Which iterative statement executes at least once?

__________________________________________________________

2. Which iterative statement uses an explicit counter?

__________________________________________________________

3. Which two statements control iterations within an iterative code block?

__________________________________________________________

4. How many return values can a method return?

__________________________________________________________

5. How many arguments are required for varargs parameter?

__________________________________________________________
Check your answers with those on page 202.

Programming in Java60

ASSIGNMENT 6: USE ARRAYS
FOR MULTIPLE VALUES
Read Assignment 6 in this study guide. Then read Chapter 5,
pages 136–158 in your textbook.

Assignment 6 introduces a new data type to handle multiple
values. Be sure to complete the Try This activities 5-1 and 5-2
in Chapter 5 to reinforce general use of arrays. Chapter 5
also covers irregular arrays, which aren’t addressed in this
assignment.

Declare Arrays

An array is a zero-based index of common elements. In Java,
arrays must meet the following criteria:

1. Each element must be the same data type.

2. Its length must be set to an int value.

3. Its length is fixed and can’t be modified.

When using arrays it’s also useful to remember that the last
index is always one less than its length. For example, an array
with a length of 10 elements will have elements at index posi-
tions 0 through 9.

An array declaration is the same as any other variable
declaration, but also includes square brackets. You may
remember that the main() method declares an array parameter
to handle command-line arguments as follows:

public static void main(String[] args)

You can also declare an array by placing the square brackets
after the variable name, but this isn’t common convention.
Because arrays are objects, they must be initialized before
they’re accessed. To initialize an array, you must use the new
keyword and specify its length in a pair of square brackets. In
the next lesson, you’ll use the new keyword for other objects
as well.

Lesson 2 61

The following code declares and initializes an int array with
five elements:

int[] intArray = new int[5];

Notice the data type is repeated after the new keyword.
Because an array is an object, the value for each element is
set to its default. In this example, each int element is set to 0.

Using Arrays

To access elements in an array, you’ll use the square brack-
ets as well. The following code sets each element in the array
initialized in the previous example:

intArray[0] = 1;
intArray[1] = 2;
intArray[2] = 3;
intArray[3] = 4;
intArray[4] = 5;

Of course, this code is very tedious, especially as arrays get
larger in size. You already learned about a better technique.
Instead of manual code repetition, you can use a cleaner
algorithm to do the same thing with a for statement:

for (int i = 0; i < intArray.length; i++) { intArray[i] = i + 1; }

Notice the length field is used to retrieve the number of ele-
ments in the array. If you need to initialize an array with
values, you can also use another short-hand notation with
curly braces. The following code declares and initializes an
array with values using this notation:

String[] names = {“Joshua”, “Chelsea”, “April”,
“Alisha”};

Java understands the number of elements based upon the
number of provided arguments. The arguments have to
match the data type of the array declaration, of course.

Programming in Java62

Enhanced For Statement

When using arrays, you can choose a special type of for state-
ment known as the enhanced for. The enhanced for statement
will automatically iterate across an array and retrieve each
element without requiring an explicit index. The syntax for
the enhanced for is as follows:

for ( data_type variable_name : array_name) {
//access each element in array

}

The following code will output each value in intArray using
the enhanced for statement:

for (int intElement : intArray) {
System.out.println(intElement);
}

The enhanced for statement makes sense only when an
index is needed to access elements. If the index is required
for another purpose such as modifying element values or
performing a calculation, the enhanced for statement isn’t
very helpful.

Activity 8: Create a Simple Calculator

1. Create a new Java Application project named
Lesson2Activity8.

2. Select the comment //TODO code application logic
here and replace it with the following code:
java.util.Scanner scan = new
java.util.Scanner(System.in);

System.out.print(“Number of operands? “);
double[] operands = new double[scan.nextInt()];
for (int i = 0; i < operands.length; i++) { System.out.print(“\nValue “ + i + “ : “); operands[i] = scan.nextDouble(); }

System.out.print(“\nOperation? “);
String operation = scan.next();

Lesson 2 63

3. Before you run this code, take time to consider how you
think the application will behave. This code will ask for a
number of values, ask for an operation, and then return
the result.

4. Build and run the project. Remember: Click in the Output
panel to type input. Try doing an operation you can check
easily to verify that it works. Test both operations.

5. Consider how you would add another operation such as
subtraction or division. How would the for statement differ?

Multidimensional Arrays

Java also supports arrays with more than one index, which are
known as multidimensional arrays. Multidimensional arrays
are used to represent matrices, tables, flat and 3D shapes,
and image coordinates. For each dimension in a multidimen-
sional array, another pair of square brackets is required. These
extra pairs of square brackets set the length of each dimen-
sion during initialization and specify the other index of each
dimension during access.

double result = 0;

switch (operation.toUpperCase()) {
case “ADD”:

result = 0; //Required for addition
for (double num : operands) result += num;
break;

case “MULTIPLY”:
result = 1; //Required for
multiplication
for (double num : operands) result *= num;
break;

default:
System.err.println(“\nNo such operation defined.”);

}
System.out.println(“\nThe result is “ + result);

Programming in Java64

The following code initializes a two-dimensional array and
sets its first and last elements:

String[][] matrix = new String[4][5];
matrix[0][0] = “first”;
matrix[3][4] = “last”;

The total number of elements in a multidimensional array is
the product of elements in each dimension. If you access the
length field from a single dimension, then it will return only
the number of elements in that single dimension. For example,
matrix.length will return 4, representing the number of
dimensions, while matrix[0].length will return 5, indicating
the number of elements in that dimension. The total number
of elements for a matrix is 20, because there are 4 dimensions
with 5 elements in each dimension.

Lesson 2 65

Self-Check 6

1. What are the three restrictions for arrays in Java?

__________________________________________________________

2. Which field returns the number of elements in an array?

__________________________________________________________

3. Which index value will retrieve the first element in an array?

__________________________________________________________

Check your answers with those on page 203.

Programming in Java66

ASSIGNMENT 7:
EXCEPTION HANDLING
Read Assignment 7 in this study guide. Then read Chapter 9 in
your textbook.

Assignment 7 describes how to deal with runtime errors in
code.

Runtime Exceptions

An exception is an abnormal condition that occurs while an
application is running. Most often, an exception is an error,
but in some cases, the exception isn’t fatal and the applica-
tion can recover. When an exception occurs, it’s thrown. As
a programmer, you can also throw exceptions manually.

If you don’t design an application to handle exceptions,
then the operating system will have no choice but to termi-
nate the application prematurely. Although you can avoid
many exceptions by performing simple checks, you can’t pre-
dict all exceptions. Also, some methods in Java require you
to plan for exceptions in order to invoke them. These types of
exceptions are known as checked and must be dealt with for
the code to compile. Exception handling is the mechanism of
listening for exceptions and dealing with them when they occur.

Exception classes take advantage of all object-oriented design
principles. Exception objects are recoverable situations that
usually are within the control of a user or programmer, whereas
Error objects are system issues that aren’t recoverable and
shouldn’t be handled. Both the Exception and Error class
inherit core methods from the Throwable class. This means
that all exceptions have a user-friendly message available
from the getMessage() method and a complete path from
which the exception originated with the printStackTrace()
method. Java has both generalized Exception classes, such
as IOException and IllegalArgumentException, and more
specific Exception classes, such as FileNotFoundException
and PrintException. Tables 9-2 and 9-3 on pages 315 and
316 in Chapter 9 of the textbook document the most com-
mon exceptions.

Lesson 2 67

Exception Handling

There are four ways to deal with exceptions in a method:

1. Declare the exception thrown by the method (required if
checked by compiler).

2. Handle the exception and continue execution.

3. Handle the exception and throw the exception again
(known as re-throwing).

4. Handle the exception and throw another exception.

To declare a method throws an exception, you should use the
throws keyword as in the following example:

void couldDoSomethingVeryBad() throws Exception

The throws clause on a method means that to invoke the
method, the declared exception must be handled or also
declared unhandled by the invoking method. To handle the
exception, you should use the try/catch blocks. The
try/catch blocks use the following syntax:

try {

//statements that might throw an exception

} catch ( exception_types exception_variable) {
//handle the exceptions

}

The catch parameter can include more than one type of
exception or you can use multiple catch blocks for each type
of exception. To declare multiple exceptions in the catch
parameter, use the bitwise OR operator |.

If you use more than one catch block, then be careful that
they’re in order of specific to general or some catch blocks
may be unreachable. Every try block must have at least one
accompanying catch block, but that catch block can be empty.
To manually throw an exception, you should use the throw
statement. There’s also an optional finally block if you need
to have any code run whether or not an exception is thrown.

Programming in Java68

The following code handles any divide by zero exceptions that
are thrown and throws another exception:

A simple check for num1 so that it isn’t zero is a better
approach than using exception handling. In a future lesson,
you’ll see better uses for exception handling when performing
input/output operations.

double divide(double num1, double num2) {

double result = 0;
try {

result = num1 / num2; //num1 should not be zero

} catch (ArithmeticException ex) {

throw new IllegalArgumentException(“num2 parameter must not be 0!”);

} finally {

return result;

}
}

Lesson 2 69

Self-Check 7

1. What is an exception?

__________________________________________________________

2. Which blocks should you use to handle exceptions?

__________________________________________________________

3. How are the keywords throw and throws used in Java?

__________________________________________________________
Check your answers with those on page 203.

Programming in Java70

NOTES

71
G
ra
d
e
d
P
ro
je
c
t
G
ra
d
e
d
P
ro
je
c
t
Data Types and
Program Control
OVERVIEW

After reading selected sections of Chapters 2, 5, and 9 in the
textbook and completing Lesson 2, you’re now ready to use
data types and control structures. This project will assess
your understanding of using variables, constants, operators,
arrays, statements, methods, and exceptions.

Make sure to follow all directions completely and verify your
results before submitting the project for grading. Remember
to include all required components in your solution.

Your Project

In this project, you’ll create a text-based Tic-Tac-Toe game in
which each player places either an X or O mark on a nine-
grid square. An X mark is known as a cross, while an O is
called a nought. The winner is the first player to place their
mark on three contiguous squares vertically, horizontally or
diagonally across. You can read about it in more detail on
Wikipedia (http://en.wikipedia.org/wiki/Tic-tac-toe).

The output of this project will be referenced in the subsequent
graded projects for this course.

Graded Project72

Instructions

1. In NetBeans, create a new Java Application project
named TicTacToeGame.

2. Add the following variable and constant declarations to
the TicTacToeGame class:

static int[][] gameboard;
static final int EMPTY = 0;
static final int NOUGHT = -1;
static final int CROSS = 1;

Note: The variable gameboard is a two-dimensional int array.
Think of it as a table with rows and columns, where a cell
can be empty (0) or contain a nought (–1) or cross (1) . The
constants EMPTY, NOUGHT, and CROSS will simplify your
code.

3. Add the following utility methods to the TicTacToeGame
class:

static void set(int val, int row, int col) throws
IllegalArgumentException {
if (gameboard[row][col] == EMPTY) gameboard[row][col] = val;
else throw new IllegalArgumentException(“Player already there!”);
}

static void displayBoard() {
for( int r = 0; r < gameboard.length; r++ ) { System.out.print(“|”); for (int c = 0; c < gameboard[r].length; c++) { switch(gameboard[r][c]) {

case NOUGHT:

System.out.print(“O”);
break;

case CROSS:

System.out.print(“X”);
break;
default: //Empty
System.out.print(“ “);

Graded Project 73

}
System.out.print(“|”);
}
System.out.println(“\n———-\n”);
}
}

4. Add the following method signatures to the
TicTacToeGame class:

5. Define the createBoard method.

6. Define the winOrTie method. Check first for a win with
rows and columns and then diagonally. Finally, check to
see if there are any empty cells without a cross or naught.

Note: Review the sections “Initializing Multidimensional Arrays”
on pages 144–145 and “Iterating Over Multidimensional
Arrays” on pages 156–158 for how to initialize and iterate
through a multidimensional array. A player wins if all the
cells in a row or column are the same mark or diagonally
through the center. The players tie if all cells have a cross or
nought, but no player has three marks horizontally, verti-
cally, or diagonally. Return NOUGHT if nought wins, CROSS
if cross wins, 0 if there’s a tie, and another value (like –2, for
example) if there are empty cells on the board.

7. In the main() method, perform the following actions:

a. Create the board and initialize a turn counter, player
value, and game outcome. For nought, the value is
–1, while 1 is the value for cross.

b. While there’s no winner or tie, display the board and
prompt for a row and column for the current player.

static void createBoard(int rows, int cols) {
//Initialize the gameboard

}
static boolean winOrTie() {

//Determine whether X or 0 won or there is a tie
}

Graded Project74

c. Use a try/catch block to handle the exception from
the set method. You can use the System.err.println
method rather than the System.out.println method
to output the exception. This will display the message
in red.

d. Display the final board and a message on which
player won or if there’s a tie.

8. When completed, the contents of the main() method
should resemble the following:

createBoard(3,3);
int turn = 0;
int playerVal;
int outcome;
java.util.Scanner scan = new java.util.Scanner(System.in);
do {
displayBoard();
playerVal = (turn % 2 == 0)? NOUGHT : CROSS;
if (playerVal == NOUGHT) System.out.println(“\n—O’s turn—”);
else System.out.println(“\n—X’s turn—”);
System.out.print(“Enter row and column:”);
try {
set(playerVal, scan.nextInt(), scan.nextInt());
} catch (Exception ex) {System.err.println(ex);}
turn ++;
outcome = winOrTie();
} while ( outcome == -2 );
displayBoard();
switch (outcome) {
case NOUGHT:
System.out.println(“O wins!”);
break;
case CROSS:
System.out.println(“X wins!”);
break;
case 0:
System.out.println(“Tie.”);
break;
}

Graded Project 75

9. Compile and run the project to ensure it works as
expected. Try a few games to verify all wins and ties
are correctly detected.

The application should behave as follows in the Output window:

| | | |
______
| | | |
______
| | | |
______
—O’s turn—
Enter row and column:0 0
|O| | |
______
| | | |
______
| | | |
______
—X’s turn—
Enter row and column:0 1
|O|X| |
______
| | | |
______
| | | |
______
—O’s turn—
Enter row and column:1 1
|O|X| |
______
| |O| |
______
| | | |
______

—X’s turn—
Enter row and column:2 0
|O|X| |
______
| |O| |
______
|X| | |

______
—O’s turn—
Enter row and column: 2 2.
|O|X| |
______
| |O| |
______
|X| |O|

O wins!

SUBMISSION GUIDELINES

To submit your project, you must provide the following
two files:

■ TicTacToeGame.java

■ TicTacToeGame.class

To find these files within NetBeans, go to the TicTacToeGame
project folder. To determine this folder, right-click on
TicTacToeGame project in the Projects panel. Copy the
value for the Project Folder textbox using the keyboard
shortcut CTRL+C. In Windows Explorer, paste the project
folder path and hit the ENTER key. Copy both the
TicTacToeGame.java file from the src\tictactoegame folder
and the TicTacToeGame.class file from the build\tictac-
toegame folder to your desktop or any other temporary
location.

Follow this procedure to submit your project online:
1. Log on to the Penn Foster website and go to My Courses.

2. Click Take Exam.

3. Attach your files as follows:
a. Click on the Browse box.
b. Locate the file you wish to attach.
c. Double-click on the file.
d. Click Upload File.

Graded Project76

Graded Project 77

e. Since you have more than one file to attach, click on
the Browse box again, and repeat steps b, c, and d
for each file.
4. Enter your e-mail address in the box provided. (Note:
This information is required for online submissions.)
5. If you wish to tell your instructor anything specific
regarding this assignment, enter it in the Message box.

6. Click Submit File.

Grading Criteria

Your instructor will use the following guidelines to grade
your project.

The createBoard method
works as required: 25 points

The winOrTie method
works as required: 30 points

The application plays a standard
Tic-Tac-Toe game 25 points

Both source and compiled code
files are included: 20 points

TOTAL 100 points

Graded Project78

NOTES

79
L
e
s
s
o
n

3
L

e
s
s
o

n
3

Object-Oriented
Programming

INTRODUCTION

Because Java is an object-oriented language, learning its
structures will provide a review of object-oriented program-
ming (OOP). Java was built with good object-oriented design
principles in mind, making it easier to do the right thing, but
more restrictive than other languages you’ve learned. In this
lesson, you’ll define classes, interfaces, and enumerations and
revisit important OOP concepts such as inheritance and poly-
morphism. You’ll also learn how to use Java’s packaging
scheme and generics.

OBJECTIVES
When you complete this lesson, you’ll be able to

■ Define and instantiate classes

■ Describe reference variables and the object lifetime

■ Use inheritance and polymorphism

■ Differentiate between abstract and concrete classes

■ Use Java packages and the application programming
interface (API) documentation

■ Differentiate between interfaces and classes

■ Create interfaces and enumerations

■ Discuss autoboxing and generics

Programming in Java80

ASSIGNMENT 8:
CREATE OBJECTS AND CLASSES
Read Assignment 8 in this study guide. Then read Chapter 4,
pages 104–110 and 124–134, as well as Chapter 6 in your
textbook.

Create Objects and Classes

The focus of Assignment 8 is using OOP with Java syntax.
This assignment assumes you have a good grasp of general
object-oriented design principles. If you need a refresher on
object-oriented design, you can read the Java tutorial on the
Oracle website at http://docs.oracle.com/javase/tutorial/
java/concepts/index.html. Be sure to complete the Try This
activities in both Chapters 4 and 6; they’ll help to reinforce
the syntax and concepts.

Object Fundamentals

As you’ve learned in previous lessons, an object is a unique
representation of variable-sized data in memory. This data
consists of two things: state and behavior. State describes the
object, while behavior defines what that object can do. The
word unique means one object is stored separately from
another, even if they have the same state. In Java, state is
defined by variable fields, while behavior is defined by methods.

A class is a user-defined type that describes objects.
Although a class is loaded into memory like objects, a class
doesn’t have a unique state or behavior. Only static fields
and methods are available through a class. Any changes to
the class will affect all objects based on that class, however.
Think of a class as a group and objects as members of that
group. A class is merely a classification for a type of object.

An important object-oriented design principle is encapsulation.
Encapsulation is designing a class, so that fields are pro-
tected from direct access and all interaction with an object
requires methods. A method that retrieves a field’s value is
known as an accessor. A mutator is a method that modifies
a field’s value.

Lesson 3 81

Class Definition in Java

The following code defines the Robot class in a two-dimensional
maze application:

class Robot {
//fields (state)
String name;
int x,y;
int direction;
double speed;
//methods (behavior)
void turn(int direction) {}
void move(double time) {}
void move(double time, int direction) {}
void setSpeed(double speed) {}

}

Note the use of the class keyword to specify the new data
type. The fields are merely variables declared directly in the
class body. It’s worth mentioning that the methods don’t use
the static keyword as you were using in the previous lesson
because the methods will affect a single object. If you invoke
the move() on a Robot object, another Robot object won’t
have its x and y fields change.

The process of creating an object from a class is known as
instantiation. As with arrays, you need to use the new key-
word to instantiate a class. You’ll use parentheses instead of
square brackets, however. The following code instantiates the
Robot class twice to create two Robot objects and then sets
each of their fields:

Robot robo1 = new Robot();

robo1.name = “Marvin”;
robo1.speed = 4.2;

Robot robo2 = new Robot();

robo2.name = “Chip”;
robo2.speed = 12.8;

robo1.move(10);
robo2.move(5);

Notice that dot notation is used to access object fields and
methods. Also, notice that the robo1 and robo2 objects have
separate field values and methods. When the move() method

Programming in Java82

is invoked on robo1, robo2 remains in its current state.
While the move method is invoked for robo2, the state for
robo1 is unaffected.

Another important point is the default state of the Robot
objects. All fields will start with their default values. Because
the x, y and direction fields aren’t set, their current state is
0, 0 and 0.0, respectively.

Object References

As you’ll recall from the first assignment in the previous lesson,
assigning a variable to another simply copies the original value
and assigns it to the second variable. The following code
demonstrates this concept:

Values for primitive data types are stored on the default
memory stack. The only data stored for a primitive variable
is its value.

Because the size of object data isn’t fixed, objects are stored
in the memory heap. The size of an object is determined when
it’s instantiated, not using a size predefined by the JVM. If
object data is stored in the memory heap, then what’s stored
in the memory stack?

A reference to the object is stored on the memory stack.
Think of a reference as a pointer to that object’s data. This
means that a simple assignment operation for primitive data
types is actually a powerful reference mechanism for objects.

Note: Java provides
the transient keyword
for fields to indicate
they don’t need to be
stored with an object
because their values
don’t affect that object’s
state. The result of the
transient keyword is
apparent only when
using serialization.

int i1 = 10;
int i2 = i1; //now i2 is 10
i2++; //i2 is now 11, but i1 is still 10

Lesson 3 83

Look at the following modified code that uses the Robot objects:

Robot robo1 = new Robot();
Robot robo2 = robo1;

robo1.name = “Marvin”;
robo1.speed = 4.2;
robo2.name = “Chip”;
robo2.speed = 12.8;

System.out.println(robo1.name + “ “ +
robo1.speed);
System.out.println(robo2.name + “ “ +
robo2.speed);

The output would be the following:

Chip 12.8
Chip 12.8

This output may seem surprising until you realize that the
variables robo1 and robo2 reference the same object. The
assignment operation between objects doesn’t merely copy
field values, but copies the pointer to the object from one
to another.

The same principle applies to passing arguments to parameters.
When passing an object as an argument, any modifications to
the object will persist after the method returns. Unless this is
the desired effect, you may prefer to copy the object’s values and
specify a copy of the original object as an argument instead.

Class Members

By default, all fields and methods declared in a class will
affect only a single object. These constructs are known as
instance members. To access instance members, you must
instantiate that class first and then access those members
through the object reference using dot notation. The previous
code examples demonstrate this type of access.

If you declare a field or method with the static keyword, then
that field or method is now a class member. Setting class
fields or invoking class methods will affect every object of the
class. To access class members, you need only reference the

Programming in Java84

class itself in dot notation. As you may recall from the first
lesson, the reason the main() method uses the static key-
word is so that the Java runtime isn’t required to instantiate
the class first. Only the class is loaded, not any of its objects.

Continuing our Robot class example, the following class
members could be added:

static int totalRobots;
static void stopAllRobots() {}
To access these class members, you can use the class or an
object of the class. For clarity, the preferred convention is to
access class members using the class and not its objects. The
following code accesses class members of Robot using both
techniques:

Robot.stopAllRobots(); //preferred
new Robot().stopAllRobots();

Access Modifiers

Access modifiers are keywords that determine the visibility
of members to other classes. The two most common access
modifiers are public and private. A member declared with
the public keyword is available to all other classes, while a
member declared with the private keyword is available only
in that class.

Access modifiers are important tools for good encapsulation.
Most fields should be declared as private, while associated
accessor and mutator methods should be declared as public.
By limiting availability to fields, you’re ensuring that other
classes must use methods, rather than direct access. This
limitation ensures that an object’s state is consistent and
hidden from unnecessary modifications by other classes. The
only exception to using private on fields is constants or other
values that are required by other classes and don’t affect an
object’s internal state.

Lesson 3 85

You would modify members of the Robot class to use good
encapsulation as follows:

private String name;
private int x,y;
private int direction;
private double speed;
private static int totalRobots;

//accessors
public String getName() {

return name;
}
public Point getCoordinates() {

return new Point(x,y);
}
public double getSpeed() {

return speed;
}
public int getTotalRobots() {

return totalRobots;
}
//mutators
public void setName(String name) {
this.name = name;
}
public void setSpeed(double speed) {

this.speed = speed;
}

//functional methods
public void turn (int direction) {}
public void move(double time) {}
public void move(double time, int direction) {}
public static void stopAllRobots() {}
The keyword this is used to reference the current running
instance. When using a mutator, it’s common to name the
parameter the same name as the field. To differentiate
between the two variables, use the this keyword to reference
the field and not the parameter. Pages 132–134 in Chapter 4
of the textbook detail this usage.

Note: The keyword this
is used to reference the
current running
instance.

Programming in Java86

The previous example code that instantiates Robot objects
will now need to be rewritten as follows:

Robot robo1 = new Robot();
Robot robo2 = new Robot();
robo1.setName(“Marvin”);
robo1.setSpeed(4.2);
robo2.setName(“Chip”);
robo2.setSpeed(12.8);
Notice the impact of accessor and mutator methods on
how fields are used outside the class. If you provide a public
accessor method for a private field, then the field becomes
effectively read-only outside of the class. If both public muta-
tor and accessor methods are provided, then the field is
effectively read/write outside of the class. If no accessor or
mutator method is provided, then the field is completely
internal and unavailable outside the class.

Any calculation methods that are used only internally should
also be declared private. Only those functional methods that
must be exposed to other classes should be declared public.
Java also provides two other access levels to provide granu-
larity between private and public. The protected keyword is
the same as using private, but with the addition of visibility
to subclasses. If no access modifier is specified, then the
default access is package level. With package level, the mem-
ber is visible only to those classes within the same package.
Inheritance and packages will be discussed in the next
assignment.

Classes can also control their own visibility, but the language
restricts access to only two levels: package level and public. By
default, NetBeans declares all classes with the public keyword.
Only nested classes can also use the private and protected
keywords.

Note: You can define more than one class or other data type
within a single source file. But only one of those types can
be declared with the public keyword, and the filename must
match the name of that public data type. Using an IDE like
NetBeans that organizes applications into projects makes it
easier to use different source code files for each data type. It’s
a common practice to define more than one data type in a
source file if only a text editor like Notepad or TextPad is used.

Lesson 3 87

Construction and Finalization

Within its lifetime, an object undergoes the following phases:

■ Referenced

■ Instantiated

■ Initialized

■ Used

■ Dereferenced

■ Finalized

■ Deleted

In the referenced phase, a variable is either declared or
understood by the runtime to store a class pointer to the
object. The class must be loaded to determine the reference
type. The instantiated phase begins when the new keyword
is used. In this phase, the space in the memory heap is
reserved for the object.

The next phase is initialized. When an object is initialized,
its default values are set on its fields. During the initialized
phase, a specialized method called a constructor is invoked.
A constructor method uses the same name as the class and
implicitly returns an object of that class. If you’re confused
why you haven’t seen a constructor yet, it’s because the com-
piler automatically provides a default constructor to a class if
no constructors are found. The default constructor has no
parameters and an empty body.

For example, the Robot class has the following default
constructor:

Robot() { }

You can do so much more with a constructor. Constructors
can accept user-defined default values for an object’s fields
and perform initial calculations or actions during object cre-
ation. Like methods, constructors can also be overloaded. To
reference another overloaded constructor, use the this key-
word as you would when referencing instance fields.

Note: The access modi-
fier for the default
constructor matches
the access modifier of
the class. If the Robot
class was declared
public, then the default
constructor would
include the public
keyword.

Programming in Java88

The following code demonstrates overloaded constructors for
the Robots class:

Note: Most constructors are public or package level. Some
constructors are private to prevent instantiation by other
classes. The Math class is a good example of this. Although
the Math class provides useful constants and methods, this
functionality isn’t dependent on instance fields or methods.
Because instantiation isn’t required to use the class, the
class prevents instantiation.

Although this may seem like a lot of work when writing a class,
it greatly simplifies object creation down the road. Instead of
manually initializing fields or using mutator methods, you
can now create an object with all of the values you need with
a single line of code:

Robot robo1 = new Robot(“Marvin”, 4.2);
Robot robo2 = new Robot(“Chip”, 12.8);

You might be wondering if there’s a way to perform initialization
on class fields when a class is loaded, similar to how instance
fields are initialized using constructors. Pages 209–213 of
Chapter 6 in the textbook describe how to use the static
block for this purpose.

public Robot() {//invokes 2nd constructor
this(“Unnamed”);
}
public Robot(String name) {//invokes 3rd constructor
this(name,0);
}
public Robot (String name, double speed) {//invokes 4th constructor
this(name,speed,0,0);
}
public Robot (String name, double speed, int x, int y) {//workhorse
this.name = name;
this.x = x; this.y = y;
this.speed = speed;
totalRobots++;
}

Lesson 3 89

An object is in the used phase until the last variable that ref-
erences it goes out of scope. When that happens, the object is
now dereferenced. Dereferenced means that there are no live
pointers to the object, and the space it occupies in memory
could be used for other data.

In some runtime environments, you would then need to per-
form the operations to delete the object from memory and
reclaim it for usage with other objects. Provided by the JVM,
an automated service known as the garbage collector performs
this deletion and reclamation for you. The garbage collector
“takes out the garbage” only when there’s a significant
amount of memory being consumed by dereferenced objects.
This is especially the case when available system memory is
below what’s required for Java applications.

Because you can’t plan for when the garbage collector performs
its work, you can use the finalize() method for any opera-
tions that must be done before the object is removed. When
the finalize() method is executed by the garbage collector,
the object is now in the finalized phase immediately before dele-
tion. Once an object is in the deleted phase, its memory can
be reclaimed for other objects.

Activity 9: Create a Class
and Use Constructors

1. Create a new Java Application project named
Lesson3Activity9 in NetBeans.

2. Create a new public class named Polygon in the project.

a. You can either right-click on the Lesson3Activity9
project or choose New > JavaClass … in the context
menu by right-clicking the Lesson3activity9 pack-
age in Projects or use the CTRL+N keyboard
shortcut and choose Java Class in the File Types
pane and click the Next button (Figure 7).

b. In the Class Name text box, type Polygon and in the
Package drop-down list, choose lesson3activity9.

c. Click the Finish button.

Programming in Java90

3. First, create a non-encapsulated class. Inside the
Polygon class add the following code:

4. Open the Lesson3Activity9.java file. You can do this
either by clicking its tab at the top of Documents
because it should be open or by double-clicking the
Lesson3Activity9.java file in the Projects pane.

String id;
int numSides, lenSides;
void printInfo() {

System.out.print(id + “: “);

System.out.println(numSides + “ sides with length of “ + lenSides);

}

FIGURE 7—Create a New Class

Lesson 3 91

5. In the main() method of the Lesson3Activity9 class,
add the following code and consider what the output
should be for this code.

Polygon triangle = new Polygon();
Polygon square = new Polygon();
Polygon octagon = new Polygon();
triangle.id = “triangle1”;
triangle.numSides = 3;
triangle.lenSides = 5;
square.id = “square1”;
square.numSides = 4;
square.lenSides = 3;
octagon.id = “octagon1”;
octagon.numSides = 8;
octagon.lenSides = 10;

triangle.printInfo();

square.printInfo();

octagon.printInfo();

6. Build and run the project. Did the output match
your expectations?

Notice how the code in the main() method is lengthy and
requires significant understanding of the Polygon class. Also,
the Polygon class doesn’t provide much functionality or cal-
culations that could be helpful when using polygons. In the
next section, you’ll modify the Polygon class to use proper
encapsulation and store a polygon’s perimeter and area.

7. Open the Polygon.java file. You can open the file either
by clicking its tab at the top of Documents because it
should be open or by double-clicking the Polygon.java
file in the Projects pane.

8. Modify the code in the Polygon class as follows:

private String id;
private int numSides, lenSides;

//calculated fields
private int perimeter;
private double area;

//internal calculations

Programming in Java92

private void calculatePerimeter() {

perimeter = numSides * lenSides;

}

private void calculateArea() {//Uses the Math class

double numerator, denominator;

numerator = Math.pow(lenSides, 2) * numSides;

denominator = 4 * Math.tan(Math.toRadians(180/numSides));

this.area = numerator / denominator;

}

//accessor/mutators

public String getID() { return id; }

public void setID (String id) { this.id = id; }

public int getSides() { return numSides; }

public int getSideLengths() { return lenSides; }

public int getPerimeter() { return perimeter; }

public double getArea() { return area; }

public Polygon(String id, int numSides) {

this(id, numSides, 1);

}

public Polygon(String id, int numSides, int lenSides ) {

this.id = id;

if (numSides < 3)

throw new IllegalArgumentException(“Polygon must have at least 3 sides!”);

this.numSides = numSides;

if (lenSides < 1)

throw new IllegalArgumentException(“Polygon must have sides greater than 0!”);

this.lenSides = lenSides;

//perform calculations

calculatePerimeter(); calculateArea();

}

public void printInfo() {

System.out.print(id + “: “);
System.out.println(numSides + “ sides with length of “ + lenSides);

System.out.println(perimeter + “ perimeter with area of “ + area);

}

Lesson 3 93

Now your code in the main() method would be significantly
simplified and more information is available from the
Polygon class. In the next section, you’ll replace the main()
method code to use the improved Polygon class.

9. Open the Lesson3Activity9.java file. You can do this
either by clicking its tab at the top of Documents
because it should be open or by double-clicking the
Lesson3Activity9.java file in the Projects pane.

10. Notice all of the red squiggly lines in the main() method!
Because Polygon no longer has a default constructor
and its fields are now hidden from other classes, there
are a significant number of compilation errors!

11. Modify the code in the main() method as follows:

Polygon triangle = new Polygon(“triangle1”, 3, 5);
Polygon square = new Polygon(“square1”, 4, 3);
Polygon octagon = new Polygon(“octagon1”, 8, 10);

//all other main() code is deleted

triangle.printInfo();
square.printInfo();
octagon.printInfo();

12. Build and run the project. The output should now
include the perimeter and area of each polygon. Feel
free to build some more Polygon objects in the main()
method, so that you can become more familiar with
instantiating and using well-encapsulated classes.

Nested Classes

Although sparingly used, Java allows you to define a class
within another class. The inner class is known as a nested
class. This capability is intended for the rare circumstance
where a class is completely dependent on another class and
increased encapsulation could reduce complexity. When
using AWT and Swing, you’ll see some examples of nested
classes, even anonymous ones!

Programming in Java94

Sometimes a nested class indicates that an object contains
another object. In other scenarios, a nested class is simply
a class placed within another because it needs access to
unavailable fields or methods. The first situation describes
non-static nested classes, while the second describes a static
nested class. As you might expect, a static nested class is
declared using the static keyword.

Here is an example of a non-static nested class:

public class Polygon {
Side[] sides;
public class Side {

int length, angle;
}

}

Note: Although nested classes are often intended to provide
further encapsulation, the code above is a poor example of
good encapsulation. The example is intended to simplify the
syntax. If this were encapsulated better, then the fields would
be private, and public accessors and mutators would be
defined in both the outer and inner classes.

In this example code, the class Polygon has an inner class
named Side. Notice that the Polygon class references the
Side class using an array. The nested class then represents
the relationship that a polygon contains many sides.

How do you access an inner non-static class? Because the
inner class is dependent on objects of the outer class, you
must first instantiate the outer class and then instantiate
the inner class. As you might imagine, this situation creates
some unusual-looking code when using dot notation.

This code creates a Side object:

Polygon.Side side1 = new Polygon().new Side();

The declaration of the side1 variable makes sense, because a
Side object is nested within the Polygon class. But the portion
on the right side of the assignment seems very bizarre. It’s
for good reason. Java initially didn’t support inner classes, so
the existing instantiation syntax was reused to accommodate
the new feature.

Lesson 3 95

If the Side class was declared as a static nested class of
Polygon by adding the static keyword, the syntax is more
logical and easier to read:

Polygon.Side side1 = new Polygon.Side();

If you’re unsure when you’ll define nested classes, the answer
is probably rarely if ever. But you’ll find yourself using nested
classes when handling GUI elements and events.

Programming in Java96

Self-Check 8

1. What is the difference between object references and primitive types?

__________________________________________________________

2. What is object encapsulation?

__________________________________________________________

3. What is the difference between instance and class members?

__________________________________________________________

4. When is a class instantiated? When is an object finalized?

__________________________________________________________

Check your answers with those on page 204.

Lesson 3 97

ASSIGNMENT 9: CREATE CLASS
INHERITANCE AND PACKAGES
Read Assignment 9 in this study guide. Then read Chapter 7,
Chapter 8, pages 268–278, and Chapter 12, pages 427–429, in
your textbook.

Assignment 9 addresses how to inherit code from classes,
class hierarchies, and Java packages. Be sure to complete
the Try This activities in Chapters 7 and 8; they’ll help rein-
force the syntax and concepts.

Classes and Subclasses

As described in the previous assignment, classes can be
thought of as ways of classifying like objects. As with most
classification schemes, objects can become more and more
specialized based upon the class in which they belong.
Extending the previous example of a Robot class, you could
have specific types of robots based on algorithm such as a
BinarySearchRobot, on function such as a CarDriverRobot,
or on built-in capabilities such as a CameraRobot. Although
all of these classes are different and represent unique sets of
objects, they also share state and behavior mechanisms. For
example, all of these robots can move at a certain speed and
can be tracked using x and y coordinates.

Inheritance describes how subclasses can reuse code from
the same class. The subclass is the one that’s specialized,
while the superclass is the generalization. To take advantage
of inheritance in Java, you use the extends keyword when
declaring the subclass. Only single inheritance is supported in
Java, so that a subclass can have only one direct superclass.

The following code declares a subclass of the Robot class:

public class CameraRobot extends Robot {
private boolean pathBlocked;
private int cameraDirection;
public boolean isPathBlocked() {
return pathBlocked;
}
public int getCameraDirection() {

Programming in Java98

return cameraDirection;
}
public void turnCamera(int cameraDirection) {
this.cameraDirection = cameraDirection;
}
}

You may not see it, but code inside the Robot class is now
automatically part of the CameraRobot class because of the
extends keyword. The CameraRobot class only needs to con-
tain code that specializes it as a subclass.

There’s also a wider implication when considering object
references. Any CameraRobot objects are now typed not only
by the CameraRobot class, but also by the Robot class. The
compiler will allow you to declare variables of type Robot and
they can reference both Robot and CameraRobot objects!

The following code demonstrates the specialization principle
of subclasses:

CameraRobot cbot1 = new CameraRobot();
Robot cbot2 = new CameraRobot();

The difference between these two object references will be
discussed in the Polymorphism section.

What Is Inherited?

When defining a subclass, it’s important to realize that not
everything is inherited. All fields and methods, both class
and instance members are inherited. Constructors, however,
aren’t inherited from the superclass. When a subclass construc-
tor is invoked, an associated superclass is invoked implicitly.
Since a subclass is a specialized type of its superclass,
instantiation of a subclass must, by definition, instantiate the
superclass as well. Therefore, you’ll need to copy the same
constructors over to the subclass if you wish to offer the
same initialization functionality provided by the superclass.
Although superclass instantiation occurs automatically, you
should use the super keyword to invoke superclass construc-
tors and increase code reuse. To access fields, and methods
located in the superclass, you can also use the super keyword
in place of the this keyword.

Note: An explicit invo-
cation to superclass
constructor must be
the first line within a
subclass constructor
because the superclass
must be instantiated
before the subclass.

Lesson 3 99

The following code contains the constructors for the
CameraRobot subclass:

Of the items that are inherited, not every one is available
to the subclass. Availability depends on access modifiers. If
access is the default package level, then only subclasses in
the same package will have access to those members. If the
keyword protected was used, then subclasses in whichever
packages they’re located will have access to those members.
Even in subclasses, members declared with the private key-
word aren’t accessible.

It may seem odd to inherit members that are inaccessible,
but this is actually very common among real-world objects.
Although you may inherit traits from your mother or father,
many of those traits aren’t available for modification. For
better or worse, you’re stuck with them!

Overriding Methods

Subclasses can do more than overload superclass methods;
they can override them. As you recall from the previous lesson,
the method signature is how the runtime figures out which
method should be invoked. In overloading, more than one
method has the same name, but specifies a different order

public CameraRobot() {
this(“Unnamed”);

}
public CameraRobot(String name) {

this(name,0);
}
public CameraRobot (String name, double speed) {

this(name,speed,0,0);
}
public CameraRobot (String name, double speed, int x, int y) {

this(name, speed, x, y, 0);
}
public CameraRobot (String name, double speed, int x, int y, int
cameraDirection) {

super(name,speed,x,y);
pathBlocked = false;
this.cameraDirection = cameraDirection;

}

Programming in Java100

of data types for parameters. In overriding, a subclass can
use the same name and order of parameter data types as a
method in the superclass. This means that the subclass ver-
sion of the method effectively replaces the method version in
the superclass.

The following method in the CameraRobot class overrides
the move() method in the Robot class:

@Override
public void move(double time) {
//check if the path is blocked
}

Note: The previous code uses the @Override annotation, which
is used by the compiler to check that the method signature
matches a method in the superclass. Not all annotations
are useful during development, but the @Override annotation
is essential to making sure you override instead of overload
a superclass method. Annotations are introduced on
pages 430–432 in Chapter 12 of the textbook.

How does the runtime know which version of the move() method
is intended? Not surprisingly, the runtime chooses the version
based on which class the object instantiated. If you invoke
move() on a Robot object, then its version is executed. If you
invoke the move() on a CameraRobot object, then the
move() method defined in that class is executed.

As you recall from the previous lesson, the final keyword
is used in Java to declare constants. The final keyword can
also be used in inheritance. A method declared with the
final keyword can’t be overridden by subclasses. If a class is
declared with the final keyword, then it can’t have subclasses
at all. Some built-in classes provided by Java are declared as
final, because all or most of their methods are so complex,
that inheritance isn’t recommended.

Although not recommended at all, you can use subclass hiding
to replace fields and methods inherited from a superclass.
Hiding is the process of using syntactic loopholes to prevent
the side effects of normal inheritance. To hide a field, simply
declare a field in the subclass as it’s named in the superclass.
Because static methods can be accessible from instances as
you learned in the previous assignment, you can also hide a

Lesson 3 101

superclass method by using the same method signature with
the static keyword in the subclass. Polymorphism, as described
in the next section, doesn’t apply to hidden class methods,
only overridden instance methods.

It makes sense in the Robot example scenario to use method
overriding. A regular Robot object has no sensors to detect
its surroundings, while a CameraRobot object can actually see
and verify whether its path is blocked. But if you find your-
self overriding a majority of methods, you may want to
reconsider whether inheritance is a good idea. If most of the
inherited code is being replaced, then why inherit it in the
first place? A better choice might be an interface, as you’ll
learn in the next assignment.

Object References and Polymorphism

Now, revisit the following example code:

CameraRobot cbot1 = new CameraRobot();
Robot cbot2 = new CameraRobot();

Although both lines of code instantiate a CameraRobot object,
the first line uses a CameraRobot object reference and the
second line uses a Robot object reference. Using the cbot1
variable will provide access to the members in the
CameraRobot and Robot classes. This makes sense because
the CameraRobot class is a subclass of Robot and it inherits
its members.

The cbot2 variable is more limited, however. Because this
variable is a Robot object reference, only those members in
the Robot class are accessible. The cbot2 variable does point
to a CameraRobot object, so you could use casting to get
access to CameraRobot members. The following code
demonstrates the technique:

CameraRobot cbo2AsCameraRobot = (CameraRobot) cbot2;

Now, take the following example code:

Robot bot1 = new Robot();
Robot bot2 = new CameraRobot();

Programming in Java102

Unlike the previous example, bot1 and bot2 use the same
object reference type, but point to different types of objects.
The variable bot1 references an object of the superclass
Robot, while variable bot2 references an object of the sub-
class CameraRobot. Because both variables are using the
Robot class as the object reference, only those members in
the Robot class are accessible.

With what you’ve learned so far about object references, what
do you think will happen when the following code is run?

bot1.move(2.8);
bot2.move(5.4);

Surprisingly, when dealing with overridden methods, the ref-
erence type of the variable has no effect on which version of
the move() method is executed. The move() method defined
in the Robot class is executed for bot1, while the version in
the CameraRobot class is executed for bot2. This result is
known as polymorphism. In polymorphism, the actual
method that’s executed depends on the type of the object, not
the reference type of its variable.

The Object Class

In Java, even if you don’t use inheritance, every class is a
subclass of the Object class. What this means is that every
class has built-in functionality inherited from the Object
class. Thus, you can invoke the getClass() on any object and
it will return a reference to its class. The table on page 265 of
Chapter 7 in the textbook lists all methods inherited from the
Object class.

There are three methods that you’ll commonly override in your
classes: toString(), equals(), and hashCode(). The toString()
method is intended to provide a text representation of an
object for quick output. You’ve used the equals() method
before with String objects. The equals() method returns a
boolean value indicating whether the current object and an
object argument are equivalent. If you choose to override
the equals() method, you must also override the hashCode()
method. The hashCode() method returns an int value that
should be the same if two objects are equivalent.

Note: You can use the
instanceof operator to
verify whether an
object is an instance
of a specified class.
This is preferred before
performing a reference
type cast.

Lesson 3 103

The following code overrides the toString() method for the
Robot class:

Remember: Because it’s a subclass of Robot, the CameraRobot
class also inherits the overridden toString() method.

Abstract Classes

There will be some situations where a class is intended only for
generalizing a group of classes and instantiation doesn’t make
sense. Although there are many methods in the superclass
that won’t be overridden, some methods may be overridden
by every subclass. In other words, these method signatures
may be the same across classes, but the actual code defined
in each method will be different.

One solution to this problem is an abstract class. An abstract
class is one that can’t be instantiated and can include methods
without definition code. The class is declared with the abstract
keyword and each method that isn’t defined must also include
the abstract keyword. Although an abstract class can’t be
instantiated, it can include constructors that subclasses
can invoke.

The following code defines an abstract class named
MovableMachine:

public abstract class MovableMachine {
private int x,y;
private int direction;
private double speed;
public Point getCoordinates() {

return new Point(x,y);
}
public double getSpeed() {

return speed;
}
public void setSpeed(double speed) {

this.speed = speed;
}

@Override
public String toString() {

return name + “at “ + x + “, “ + y + “ with speed of “ + speed;
}

Programming in Java104

//abstract methods
public abstract void turn (int direction);

public abstract void move(double time);
}

Because an abstract class can’t be instantiated, subclasses
are required for actual usability. Subclasses of an abstract
superclass are known as concrete classes, because they must
provide the definition of all abstract methods. This require-
ment to provide definition for abstract methods is known as a
contract. If a subclass doesn’t provide definition for abstract
methods, then that subclass also must be declared abstract
and rely on its own subclasses to provide those definitions.

Activity 10: Create an
Abstract Class and Subclasses

1. Launch NetBeans and open the Lesson3Activity9 proj-
ect if you’ve closed out of the NetBeans.

2. Create a new public class named Shape in the project.
Review step 2 of Activity 9 if you need help performing
this action.

3. The Shape class should be defined as follows:

public abstract class Shape {
private String id;
//calculated fields
protected int perimeter;
protected double area;
public Shape(String id) {
this.id = id;
}
//accessor/mutators
public String getID() { return id; }
public void setID (String id) { this.id = id; }
public int getPerimeter() { return perimeter; }
public double getArea() { return area; }
//internal abstract calculations
protected abstract void calculatePerimeter();
protected abstract void calculateArea();
public void printInfo() {System.out.print(id + “: “);}
}

Lesson 3 105

Notice the area and perimeter fields and calculatePerimeter()
and calculateArea() methods are now declared with the
protected keyword. Why is that required?

4. Open the Polygon.java file either by clicking its tab at
the top of Documents because it should be open or by
double-clicking the Polygon.java file in the Projects
pane.

5. Modify the Polygon class declaration to inherit from the
Shape class as follows:

public class Polygon extends Shape

6. Because the Polygon class now inherits code from the
Shape class, you need to remove the id, perimeter, and
area fields and getID(), setID(), getPerimeter(), and
getArea() methods.

7. Because the calculatePerimeter() and calculateArea()
methods are declared with the protected keyword in the
Shape class, you need to change the private keyword to
protected on these methods in the Polygon class.

8. Replace the statement this.id = id; in the second
Polygon constructor with the statement super(id);

9. Replace the statement System.out.print(id + “: “); in the
printInfo() method with the statement super.printInfo();

10. Open the Lesson3Activity10.java file and modify the
first four lines in the main() method as follows:

Shape triangle = new Polygon(“triangle1”, 3, 5);
Shape square = new Polygon(“square1”, 4, 3);
Shape octagon = new Polygon(“octagon1”, 8, 10);
Shape hexagon = new Polygon(“hexagon1”, 6, 5 );

11. Build and run the project. The output should match the
output at the end of Activity 9.

The reason this code works is because of polymorphism.
In the next section, you’ll add another subclass of Shape
named Circle.

12. Create a new public class named Circle in the project.

Note: You could copy
and paste the code
from the Polygon.java
file and modify it,
rather than retyping it
all. Remember the key-
board shortcuts are
CTRL+C for copy and
CTRL+V for paste.

Programming in Java106

13. The Circle class should be defined as follows:

14. Open the Lesson3Activity9.java file and add the follow-
ing code to the main() method:

Shape circle = new Circle(“circle1”, 5);

circle.printInfo();

15. Build and run the project. You should now have both
Polygon and Circle objects using the Shape class and
through polymorphism displaying the correct results!

public class Circle extends Shape {
private int radius;
protected double perimeter; //hides Shape field
public Circle(String id, int radius) {

super(id);
this.radius = radius;
calculatePerimeter();
calculateArea();

}
//accessors/mutators
public int getRadius() { return radius; }
public int getDiameter() { return 2 * radius; }
//calculations
protected void calculatePerimeter() {

perimeter = 2 * Math.PI * radius;
}
protected void calculateArea() {

area = Math.PI * Math.pow(radius, 2);
}
public void printInfo() {

super.printInfo();
System.out.println(“radius of “+ radius);
System.out.println(perimeter + “ perimeter with area of “ + area);

}
}

Lesson 3 107

Define a Package

To avoid naming conflicts between classes and other types,
Java uses a unit of organization known as a package. A
package groups related types into a logical namespace. Each
package can in turn have sub-packages, so that the result is
an organized hierarchy of data types.

Rather than requiring a complex name for a class such as
PokerGamePlayingCardDeck, you could create a package
with the name games.poker.cards and simply rename the
class Deck. In the package games.poker.cards, you would
expect to find other card-related classes used in a poker
game, such as Card, PlayerHand, DealerHand, and River.
Because the dot-notation includes other packages (games,
games.poker), you would expect to find a more general
Player class in the games package and perhaps a Bet class
in the games.poker class.

To define a package, you must perform two actions:

1. Use the package statement in all related source code files.

2. Place the source code files in the same folder structure
required for the package.

All source code files in the same package should include a
package statement with that name. The following is an example
package statement for the Robot and CameraRobot classes:

package games2d.maze;

The package statement must be the first line of executable
code. This means that comments and annotations can pre-
cede the package statement, but no other elements. Common
convention is to use all lowercase letters for package names,
but all other characters allowed in Java identifiers can also
be used.

If no package statement is included in a source code file,
then the data type(s) in the source code file are placed in the
default package. The default package is global level, meaning
that no package name is required to access the data type(s).
If a package statement is included, then the package name is
automatically prepended to the data type name(s). With the

Programming in Java108

package statement above, the full names of the Robot and
CameraRobot classes are now games2d.maze.Robot and
games2d.maze.CameraRobot.

Finally, you must place the source code files in the package in
the same folder structure as indicated in the package state-
ment. That means for the Deck class in the
games.poker.cards package, you need to move the
Deck.java file into the \games\poker\cards folder. For the
files Robot.java and CameraRobot.java, you need to move
them into the \games2d\maze folder. After compiling the
files, the compiled files (.class) should also remain in this
folder structure or be compressed into a self-contained JAR
file. Remember: Java package names are case-sensitive, so
you should make sure the folder names are all lowercase as
well.

The location of these package folders must be specified in the
CLASSPATH environmental variable if running the files man-
ually on the command-line using the java executable. This
development environment can be tedious and error-prone.

Luckily, the NetBeans IDE automates the creation, compila-
tion, and running of packages. Each project you’ve developed
in NetBeans is part of a package with the same name as your
project, but in all lowercase. To create a new package, either
choose New > Java Package … in the context menu when
right-clicking on the Source Packages folder in Projects or
use the CTRL+N keyboard shortcut and choose Java Package
in the File Types pane and click the Next button. You can
create a dot-notated sub-package such as pack.subpack or
manually create a package named pack and then right-click on
the pack package and create a new package named subpack.

Lesson 3 109

Using a Package

As described in the last section, data types inside packages
now have longer names and these longer names are required
to access those data types. Now that Robot and CameraRobot
are in the games2d.maze package, their full name is required
when accessing them outside that package. The following
example demonstrates this.

games2d.maze.Robot bot1 = new
games2d.maze.CameraRobot();

Although the compiler or runtime has no problem with longer
names for data types, some programmers do. To resolve this
issue, you can use the import statement. The import state-
ment allows you to use shortened names for the data type(s)
in the package you import. You can import either one data
type at a time (preferred by NetBeans) or all data types in a
package using * as a wild card.

The following import statements will allow you to use the
Robot and CameraRobot with their shortened names:

These import statements will be stripped out after compilation,
so they’re only intended to reduce the number of keystrokes
when using data types from other packages. So don’t worry
about having too many import statements affecting runtime
performance. The import statement must come after the
package statement if it exists and before any other executable
code.

Note: Declaring explicit import statements is good programming
practice, but NetBeans provides a lazy import as needed. If a
data type isn’t recognized in your code, NetBeans will place a
red squiggly line below the data type with the message can’t
find symbol. Simply right-click on the source code file and
choose the Fix Imports option from the contextual menu. A
dialog box will then appear allowing you to choose which
packages you need to import if there’s a conflict. After click-
ing the OK button in the Fix All Imports dialog, NetBeans will
automatically add the required import statements for you
(Figure 8).

Note: As you recall from
the graded projects,
you used the Scanner
class to handle user
input. Because the
Scanner class was
located in the java.util
package, you had to
use the full name
java.util.Scanner in
that code.

Note: Only types within a
package are imported,
not sub-packages.

import games2d.maze.*; //imports both Robot and CameraRobot
import games2d.maze.Robot;
import games2d.maze.CameraRobot;

Programming in Java110

One word of caution when using
import statements: conflicts. If you
import too many packages, then
possibly conflicting data types will
require long names anyway. For
example, there’s a Robot class
in both the games2d.maze and
java.awt packages. In the scenario
where there’s a conflict between
classes, you’ll need to choose which
package to import and which class(es)
you’ll need to use the longer name.

Finally, you can also use a special type of import statement
known as static import. For classes that contain class mem-
ber exclusively, that static import statement can be used to
omit the class when using its members. The best example of
doing this is the Math class. The Math class contains no
instance members, only class constants and methods. Rather
than typing Math.PI to use this constant, you can use a
static import statement to abbreviate the reference to PI.

The following code example uses a static import statement
for the Square class:

import static java.lang.Math.pow;

public class Square {
private int sideLength;
private double calculateArea() {

return pow(sideLength, 2);
}

}

In this example, the code can reference the class method
pow() without the package or class name. You can also use
the * as a wildcard character to import all class members.
Oracle recommends using static import statements spar-
ingly, because they can create some very confusing and
disorganized code if used all the time.

In the following activity, you’ll create a new package for
the Shape, Circle, and Polygon classes and then import
that package.

Figure 8—Fix All Imports Dialog

Lesson 3 111

Activity 11: Create and
Import a Package in NetBeans

1. Launch NetBeans and open the Lesson3Activity10
project if you’ve closed out of the NetBeans.

2. Create a new java package named geometry.shapes2d.
To create a new package, either choose New > Java
Package … in the context menu when right-clicking on
the Source Packages folder in Projects or use the
CTRL+N keyboard shortcut and choose Java Package in
the File Types pane and click the Next button. Then,
type geometry.shapes2d in the Package Name textbox
and click the Finish button.

3. Move the Circle.java, Polygon.java, and Shape.java files
into the geometry.shapes.2d package. To do this, you
should click and drag each file from the lesson3activity10
package on top of the geometry.shapes2d package in
the Projects pane.

Note: For each package move, you’ll be prompted by the
Move Class dialog for verification. By default, NetBeans
will refactor, meaning that each moved file will have the
package statement automatically added to the top and
any file that referred to the old package will now have
an import statement referring to the new one. Click the
Refactor button on this dialog to continue.

4. Open the Circle.java, Polygon.java, and Shape.java
files one at a time. Notice the new package statement at
the top added by NetBeans.

5. Open the Lesson3Activity10.java file. Notice the new
import statement at the top added by NetBeans.

6. Build and run the project. The output should be the
same as that at the end of the previous activity.

Programming in Java112

Common Packages

The Java SE 7 platform comes with existing packages you
can use. The documentation of these data types is known as
the application programming interface (API) specification. The
API specification describes an overview of each data type, its
superclasses and subclasses, and fields and methods. You
can either download this documentation or access the API
specification remotely on Oracle’s website at
http://docs.oracle.com/javase/7/docs/api/.

Note: In NetBeans, you can view the API documentation for a
built-in class or one of its methods very easily. Either right-
click on the class or its member and choose the Show
JavaDoc option from the context menu or use the ALT+F1
keyboard shortcut. JavaDoc is the older name associated
with Java API documentation.

Page 278 in Chapter 8 includes the top-level packages
originally found in java. The java.lang package contains
the fundamental types required by the Java language, so it’s
always imported implicitly. Not surprisingly, the basic input
and output types are found in the java.io and java.nio pack-
ages, while networking-related features are in java.net. The
java.applet package is used to create applets, while graphics
and painting uses the java.awt and javax.swing packages.

One important package omitted from the textbook is the
java.util package. This package contains the collections
framework and other utility classes like the Scanner class.
The collections framework contains powerful list structures
that offer more flexibility and generally better performance
than arrays. Unlike arrays, collections aren’t fixed in size
and provide built-in sorting and searching capabilities.

Table 3 contains common collection classes you might find
useful. Because most collections use generics to handle dif-
ferent types, usage of a collection will be delayed until that
section in the lesson.

Lesson 3 113

Class Description

ArrayList A resizable list of index-ordered elements with next/back iteration

HashMap A resizable set of unordered elements retrievable by key

LinkedList A resizable list of index-ordered elements with next/backiteration and stack/queue functionality.

TreeMap A resizable set of elements ordered in hierarchical sortingalgorithm and retrievable by key.

Table 3—Common Collection Classes

Programming in Java114

Self-Check 9

1. What is inheritance? Which class is the superclass and which is the subclass?

__________________________________________________________

2. Given the following code, what is the output?

public class SuperClass {

public void print() {System.out.println(“Super print()”);

}

class SubClass extends SuperClass {

public void print() {System.out.println(“Sub print()”);}

public static void main(String[] args) {

SuperClass obj = new SubClass();

obj.print();

}
}
__________________________________________________________

3. What is the difference between abstract and concrete classes?

__________________________________________________________

4. Which two purposes does a package serve in Java?

__________________________________________________________
Check your answers with those on page 204.

Lesson 3 115

ASSIGNMENT 10: CREATE
INTERFACES AND ENUMERATIONS
Read Assignment 10 in this study guide. Then read Chapter 8,
pages 278–292, and Chapter 12, pages 406–420, in your textbook.

Assignment 10 adds two other reference types used in Java:
interfaces and enumerations. This study guide will introduce
you to the selected sections in Chapter 8 and Chapter 12. Be
sure to complete the Try This activities in both chapters. They’ll
help reinforce the syntax and concepts.

Interface and Implementation

When considering a class, it’s important to differentiate
between a class’s interface and its implementation. An inter-
face is the declaration of each method, including the method
name, parameter list, and return value. The implementation
is code that defines how the method uses the arguments as
input and returns the result as output. The implementation
is the code between the opening and closing curly braces.

For the following method in the Square class, the interface is
bolded and the implementation is italicized:

public double getArea() {

return Math.pow(sideLength, 2);

}

The interface describes what an object can do, while the
implementation defines how the object does it.

Inheritance without the Side Effects

Although inheritance provides reuse and encapsulation among
subclasses, it also creates tight-coupling between these classes.
This means that any implementation changes in the superclass
will affect all subclasses and their implementation. Although
the subclasses share the same interface, their implementation
may be unrelated and doesn’t require inheritance.

Programming in Java116

In many situations, inheritance doesn’t make sense. Classes
may share the same interface, but inherit code from different
superclasses. Take the following class as an example:

public class Mouse {
public void eat () {}
public void sleep() {}
public void turn (int direction) {}
public void move(double time) {}
public void move(double time, int direction) {}

}

The Robot and Mouse classes both share some methods,
namely move() and turn(), but in all other ways they’re dis-
similar. A Robot object can’t eat or sleep, while a Mouse
object can’t be tracked using x and y coordinates. It wouldn’t
make sense to create some superclass named Movable just for
a single method!

Not only that, but because Java supports only single inheritance,
the Robot and Mouse classes couldn’t share one superclass
and be subclasses of another. It would make logical sense for
Robot to have a superclass like Machine and Mouse to have
a superclass like Animal. Neither the Robot nor Animal
class can be subclasses, unless they give up inheritance with
their other superclasses.

To overcome these design issues, Java provides the interface
keyword to separate out just the interface portion from a class.
Unlike abstract classes, interfaces can contain no private
fields or method implementations, only constants, initialized
fields, and method declarations. A class can have only one
immediate superclass, but it can implement zero or more
interfaces.

To resolve the issue with the Robot and Mouse classes, you
could declare a new interface called Movable that contains
only shared methods between the two classes. The following
code demonstrates one way to define the Movable interface:

public interface Movable {
public void turn (int direction);
public void move(double time);
public void move(double time, int direction);

}

Lesson 3 117

The Robot and Mouse classes would use the implements
keyword in their class declarations as follows:

Similar to inheriting an abstract class, classes that imple-
ment an interface must define all methods of that interface.
Interfaces are also treated as powerful reference types and
support polymorphism. Implementing an interface is known
as “inheritance without the side effects.” This is because only
the interface is inherited, not the implementation details that
are bound to change from class to class. The interface is less
likely to change, so that classes that communicate using
interfaces are known as loosely-coupled.

How powerful is an interface? Take the following method as
an example:

The moveInMaze() method will move a Mouse, Robot, or
any other object that implements the Movable interface. The
implementation of the moveInMaze() method doesn’t need to
be concerned with implementation details, but only how to
use the interface. Even though a Mouse object can eat and
sleep, using an interface allows other classes to focus on what
they need to do with the object, not be concerned with all of
the class details that aren’t important with the task at hand.

Activity 12: Create and Use an Interface

1. Launch NetBeans and open the Lesson3Activity11
project if you’ve closed out of the NetBeans.

2. Add a new interface named Nameable.

public class Mouse extends Animal implements Movable {/*implementation
omitted*/}

public abstract class Robot extends Machine implements Movable
{/*implementation omitted*/}

Note: In abstract
classes, methods with
no definition must use
the keyword abstract.
The keyword abstract
isn’t required in this
code, because all meth-
ods in an interface
contain no definition.

public void moveInMaze( Movable m, double time, int direction) {
m.move(time, direction);

}

Programming in Java118

You can either right-click on the Lesson3Activity11
project and choose New > Java Interface … in the con-
text menu by right-clicking the lesson3activity11
package in Projects or use the CTRL+N keyboard short-
cut and choose Java Interface in the File Types pane
and click the Next button.

In the Class Name text box, type Polygon and in the
Package drop-down list, choose lesson3activity11.

3. The Nameable interface will contain three methods for
objects with names and descriptions. The code for the
Nameable interface should be as follows:

public interface Nameable {
public String getID();
public void setID (String id);
public void printInfo();
}

4. Open the Shape.java file in the geometry.shapes2d
package.

5. Modify the Shape class declaration to implement the
Nameable class as follows:

public abstract class Shape implements
Nameable

6. Right-click somewhere in the source code file and
choose the Fix Imports option from the contextual
menu. This will add the import statement for the
interface automatically.

Now that you’ve created an interface for objects with
names and descriptions, you’ll create another class
unrelated to two-dimensional shapes. This new class
represents a geometric proof that contains a name and
description, but has no other similarity with the Polygon
and Circle classes.

Note: The interface
contains very little
code. Because classes
that implement an
interface must provide
implementation for all
methods declared in an
interface, most inter-
faces are specialized
and brief.

Lesson 3 119

7. Create another class named Proof to the geometry
package.

■ You can either right-click on the Lesson3Activity
project in Projects and choose New > Java Class …
in the context menu or use the CTRL+N keyboard
shortcut and choose Java Class in the File Types
pane and click the Next button.

■ In the Class Name text box, type Proof and in the
Package drop-down list, type geometry.

8. The Proof class should be defined as follows:

9. Right-click somewhere in the source code file and
choose the Fix Imports option from the contextual
menu. This will add the import statement for the
interface automatically.

public class Proof implements Nameable {
private String id;
private String prove;
private String[] given;
public Proof(String id, String prove, String… given) {

this.id = id;
this.prove = prove;
this.given = given;

}
//Nameable implementation

public String getID() { return id; }
public void setID(String id) { this.id = id; }
public void printInfo() {

System.out.print(id + “: “);
System.out.print(“\nProve: “ + prove);
System.out.print(“\nGiven: “ +

Arrays.toString(given));
}
}

Programming in Java120

10. Open the Lesson3Activity11.java file and modify the
following code in the main() method:

11. Right-click somewhere in the source code file and
choose the Fix Imports option from the contextual
menu. This will add the import statement for the
Proof class automatically.

12. Build and run the project. You should now have all three
objects, Polygon, Circle, and Proof objects using the
Nameable interface and through polymorphism
displaying the correct results.

Creating Basic Enumerations

Using names for values rather than literal values themselves
makes code more readable. This is especially the case for
numerical values. It’s easier to remember that a number is
the width of a box if it’s named with the variable boxWidth,
than it’s simply as its value of 8.5.

Nameable triangle = new Polygon(“triangle1”, 3, 5);

Nameable square = new Polygon(“square1”, 4, 3);

Nameable octagon = new Polygon(“octagon1”, 8, 10);

Nameable hexagon = new Polygon(“hexagon1”, 6, 5 );

triangle.printInfo();
square.printInfo();
octagon.printInfo();

hexagon.printInfo();

Nameable circle = new Circle(“circle1”, 5);

circle.printInfo();

Nameable proof = new Proof(“Congruent triangles”, “ABM and DCM are congruent”,

“AD bisects BC”, “BC bisects AD”);

proof.printInfo();

Lesson 3 121

Simply described, an enumeration is a custom data type that
contains a limited set of named values. An enumeration is
described in Java using the enum keyword. The following
code defines an enumeration for e-mail messages:

public enum MailPriority {
REQUIRED_RESPONSE, REQUIRED_ACKNOWLEDGEMENT,
OPTIONAL_RESPONSE, OPTIONAL_ACKNOWLEDGEMENT
}

Like constants, enumeration values are by convention in all
uppercase. To use an enumeration, you would declare a vari-
able with that enumeration type and set the value as in the
following code:

MailPriority p = MailPriority.REQUIRED_RESPONSE;

Enumerations are much more powerful in Java than in
other languages. Although the new keyword isn’t required to
instantiate enumerations, they support fields, methods, and
constructors. The following code declares the MailPriority
enumeration using preset int values:
public enum MailPriority {

REQUIRED_RESPONSE (10), REQUIRED_ACKNOWLEDGEMENT(8),
OPTIONAL_RESPONSE (4), OPTIONAL_ACKNOWLEDGEMENT (2);
//preset value
private int relValue;
public int getValue() {return relValue;}
//constructor
public MailPriority (int relValue) {this.relValue = relValue;}

}

Programming in Java122

Built-In Methods for Enumerations

Although enumerations can’t be subclassed, they’re subclasses
of the superclass Enum. This means that enumerations include
the built-in methods shown in Table 4.

The following code demonstrates how to use these methods:

for(MailPriority p : MailPriority.values()) {
System.out.print(“\n” + p.name());
System.out.print(“(“ + p.ordinal() + “) – “);
System.out.print(“\”“ + p.toString() + “\”“);

}

The output of the code is as follows:

REQUIRED_RESPONSE(0) – “REQUIRED_RESPONSE”

REQUIRED_ACKNOWLEDGEMENT(1) – “REQUIRED_ACKNOWLEDGEMENT”

OPTIONAL_RESPONSE(2) – “OPTIONAL_RESPONSE”

OPTIONAL_ACKNOWLEDGEMENT(3) – “OPTIONAL_ACKNOWLEDGEMENT”

Note: Because enumer-
ations contain discrete
values, they can be used
in switch statements.

Table 4

Method Description

name() Returns the name of an enumeration constant.

ordinal() Returns the order of an enumeration constant as it was declared.

values() Returns an array of enumeration constants.

Table 4—Built-in Methods

Note: The toString()
method is overridden in
the Enum class to pro-
vide the same value as
the name() method.

Lesson 3 123

Self-Check 10

1. What does the phrase “inheritance without the side effects” mean?

__________________________________________________________

2. What are two key differences between abstract classes and interfaces?

__________________________________________________________

3. What is the simple definition of an enumeration?

__________________________________________________________

Check your answers with those on page 205.

Programming in Java124

NOTES

Lesson 3 125

ASSIGNMENT 11:
BOXING AND GENERICS
Read Assignment 11 in this study guide. Then read Chapter 12,
pages 420–426, as well as Chapter 13 in your textbook.

Assignment 11 introduces two important reference type
mechanisms: boxing and generics. This study guide covers
the selected section in Chapter 12 and Chapter 13. Be sure
to complete the Try This activities in Chapter 13, which are
invaluable in gaining a more in-depth study of generics.

Type Wrappers

Although primitive types over significant memory and per-
formance advantages over objects, you’ll find that certain
methods will require an object or you need a primitive value
to be modified by a method. The Java language provides spe-
cial classes known as type wrappers to allow primitive types
to be stored, used, and passed as objects. The following table
lists the type wrapper classes and their associated primitive
types.

Table 5

Type Wrapper Class Supported Primitive Type

boolean boolean

Byte byte

Short short

Integer int

Long long

Float float

Double double

Character char

Table 5—Type Wrapper Classes

Programming in Java126

All numeric type wrappers are subclasses of the abstract
Number class. The Number class provides xxxValue() meth-
ods to retrieve a primitive value of any numerical value,
whether it’s wrapped by a Byte or Float class. Other features
provided by numeric type wrappers include parsing, convert-
ing, bitwise manipulation, and display in other representations
such as hexadecimal, octal, and binary.

To manually wrap a primitive type, you need only specify the
value in the class constructor. The following code demonstrates
using a primitive type variable and a literal value:

int primVal = 10;
Integer i1 = new Integer(primVal);
Integer i2 = new Integer(10);

This process of placing a primitive value into its type wrapper
class is known as boxing. The reverse, removing a primitive
type from its type wrapper is known as unboxing. The follow-
ing code manually unboxes the wrapper objects i1 and i2:

int p1 = i1.intValue();
int p2 = i2.intValue();

Autoboxing

Although you could manually box and unbox primitive types,
the runtime does this automatically for you. Any time an
operation or method requires an object, the primitive value is
boxed. Whenever a primitive value is required by an operation
or method, it’s unboxed.

The following code demonstrates this automatic unboxing
and boxing for operations:

int result1 = i1 + i2 + 5; //Auto
unboxed
Integer result2 = p1 + p2 + 5; //Auto boxed

This, of course, works with methods just as easily. If a method
requires a subclass of the Object class, for example, then the
runtime boxes the primitive value and then automatically
unboxes it whenever needed.

Note: As you learned
in the previous graded
project, the Character
class is useful for
checking for types of
characters, including
valid characters for
Java identifiers! The
Character class also
provides methods for
offsetting characters
and modifying them
using character codes.

Lesson 3 127

Note: Autoboxing may seem to be modifying wrapper objects,
but like the String object, wrapper objects are immutable.
This means that autoboxing can have an impact on performance
similar to reassignment with a multitude of String objects. The
recommendation is to group together and perform operations
with primitive types before assigning the primitive result to a
wrapper object.

Generic Objects and Generics

So far you’ve learned how to group objects by either a direct
class or superclass. You also know that every object is a sub-
class of the Object class. With that knowledge in mind, you
want to generalize methods to handle any object by using the
Object class. For example, you may want to create a general-
ized method for outputting an object’s string representation:

public static void print(Object obj) {
System.out.println(obj.toString());

}

This method isn’t necessarily a bad idea, because every class
inherits the toString() method. Even if that class doesn’t
override the toString() method to display state data, the
method will output the class name by default. You might
start feeling over-confident and then try something like the
following method:

This method is much more problematic. Although all classes
inherit the equals() method from the Object class, its default
implementation will return true only if both variables reference
the same object, not when they’re equivalent. This means the
method will work for some pairs of object arguments, but not
others.

public static boolean isEqual(Object obj1, Object obj2) {
return obj1.equals(obj2);

}

Programming in Java128

Now, another example of over-generalization. You have a
method that accepts an array of Object types. Instead of
checking first to see what actual types they are, you perform

a cast and then invoke a method not inherited from the
Object class. The following code demonstrates this tech-
nique:

This is a problem, because some objects may not implement
the Movable interface and can’t be casted as such. The com-
piler doesn’t know that the cast is invalid, because the actual
value for the obj variable isn’t known until runtime. This code
will compile, even though it’s possible there will be serious
runtime errors. Runtime debugging can consume significantly
more time than checking the cast when the code compiles.

The solution is generics. Generics is a category of classes and
interfaces that can handle specific parameter types without
using the Object class. Because these specific parameter
types are checked at compile time, generics provide type
safety. Type safety prevents runtime errors when casting.

Generic Methods

When using generics in methods, you can think of them as
extra parameters for a method. The only difference is a generic
parameter can represent any type and is specified in angle
brackets before the return type, not in the parameter list.

public static void moveObjects(Object[] objArray, double time) {
for (Object obj : objArray) {

Movable m = (Movable) obj;

m.move(time);

}
}

public static void moveObjects(T[] genArray, double time) {

for (T generic : genArray) {

Movable m = (Movable) generic;

m.move(time);
}
}

Lesson 3 129

The following is a generic version of the moveObjects() method:

Now the compiler can track the data type sent to the
moveObjects() method using the generic parameter T.
Because there are no restrictions on which type T can be,
this isn’t altogether helpful. The following modification can
restrict T to only those objects that implement the Movable
interface:

This modification will now cause the following code to fail
compilation before the runtime throws an exception:

String[] strings = {“we”, “do”, “not”, “move!”};
moveObjects(strings, 2.8);

Notice that the code above doesn’t have to specify a generic
argument, because the generic argument can be implied by
the data type of the first method argument genArray. Since
the genArray argument is String array and String objects
don’t implement the Movable interface, the code fails compi-
lation.

Of course generic types are uncommon, because there’s often
an interface or specific class in which objects must implement
or extend. In this scenario, we could just as easily support
an array of Movable objects which would provide type-safety
without generics.

public static void moveObjects(T[] genArray, double time)
{

for (T generic : genArray) {
Movable m = (Movable) generic;
m.move(time);
}
}

Programming in Java130

For a more in-depth exploration of generics, please read
through all of Chapter 13 in the textbook. Because most
often you’ll use generic types and not define them, the next
activity will have you use the generic collection ArrayList.

Activity 13: Use a Generic Collection

1. Open the Lesson3Activity12.java file of the
Lesson3Activity project in NetBeans.

2. Replace the code in the main() method with the following:

3. Build and run the project. The output should match the
output at the end of Activity 12.

The big difference between non-generic and generic col-
lections is that the programmer isn’t required to perform
many casting operations and deal with possible issues at
runtime. Using a non-generic ArrayList where every ele-
ment was stored as an Object type, was painful in
previous versions of Java. Look at the following code for
an example of this pain:

ArrayList list = new ArrayList();
list.add(new CameraRobot());
list.add(new Mouse());

for (Object obj : list) ((Movable)
obj).printInfo();

Using generic collections, you can be assured that all ele-
ments are stored using the data type you need. Although
they may seem rather complex at first, generics are a
simplification tool.

Note: The diamond
operator <> is used
when instantiating
generic classes that
have the generic type
already specified in the
variable data type. In
Java, you don’t need
to provide the generic
argument twice.

java.util.ArrayList list = new java.util.ArrayList<>();

list.add(new Polygon(“triangle1”, 3, 5));

list.add(new Polygon(“square1”, 4, 3));

list.add(new Polygon(“octagon1”, 8, 10));

list.add(new Polygon(“hexagon1”, 6, 5 ));

list.add(new Circle(“circle1”, 5));

list.add(new Proof(“Congruent triangles”, “ABM and DCM are congruent”,

“AD bisects BC”, “BC bisects AD”));

for (Nameable n : list) n.printInfo();

Lesson 3 131

Self-Check 11

1. How are type wrappers used in Java?

__________________________________________________________

2. What is autoboxing?

__________________________________________________________

3. Given the following method declaration, which type of objects are allowed for the array
and elem parameters?

> void sortArray (T[] array, T elem)

__________________________________________________________
__________________________________________________________
Check your answers with those on page 205.

Programming in Java132

NOTES

133
G
ra
d
e
d
P
ro
je
c
t
G
ra
d
e
d
P
ro
je
c
t
Object-Oriented
Programming
OVERVIEW

After reading selected sections of Chapters 4, 6, 7, 8, 12, and 13
in the textbook and completing Lesson 3, you’re ready to begin
object-oriented programming. This project will assess your
understanding of creating a class hierarchy in a package and
writing code for classes and enumerations.

Make sure that you follow all directions completely and verify
your results before submitting the project. Remember to include
all required components in your solution.

YOUR PROJECT

In this project, you’ll create data types in a class structure for
cell-based board games similar to Tic-Tac-Toe. Games like
Connect Four and Mastermind also use boards divided by
rows and columns. The Board and Cell classes represent the
board, while the Player, Mark, and Outcome enumerations
track the game.

You’ll use the classes and enumerations created in this project
in future graded projects. You use the NetBeans project in
the next lesson.

INSTRUCTIONS

1. In NetBeans, create a new Java Application project
named BoardGameTester.

2. Create a new package named games and a sub-package of
games named board. The easiest way is simply to create
a package named games.board.

Graded Project134

3. Add an enumeration named Player to the games.board
package. You could add Empty Java File or choose
Java Enum as the file type. This enumeration represents
the current player in a turn-based game. Use the follow-
ing code:

public enum Player {FIRST,SECOND}

Note: Although Tic-Tac-Toe and Mastermind allow only
two players, Connect Four can be played with up to four
players. For simplicity, our code will handle only two
players.

4. Add an enumeration named Outcome to the
games.board package. This enumeration represents the
result when the turn is completed. Use the following
code:

5. Add an enumeration named Mark to the games.board
package. This enumeration represents the result when
the game is completed. Use the following code:

Note: Yellow and red are used in Connect Four, while
Mastermind uses all six colors.

6. Add the Cell class to the games.board package. It
should have the private variables content, row, and
column, and the public methods getContent,
setContent, getRow, and getColumn. Use the following
code as a guide:

public class Cell {
private Mark content;
private int row, column;

public Cell(int row, int column) {
this.row = row;
this.column = column;

content = Mark.EMPTY;
}
public Mark getContent() { return content; }

public enum Outcome {PLAYER1_WIN, PLAYER2_WIN, CONTINUE, TIE}

public enum Mark {EMPTY, NOUGHT, CROSS, YELLOW, RED, BLUE, GREEN, MAGENTA, ORANGE}

Graded Project 135

Note: All classes that support direct instantiation should
have a constructor. In this case, the constructor will be
used by the Board class to create each of its cells.

7. Add the Board class to the games.board package. It should
have a two-dimensional array of Cell objects. The Board
class should initialize a board with a specified number
of columns and rows, provide access to Cell objects, and
display all of its cells correctly. Use the following code as
a guide:

public class Board {
private Cell[][] cells;

public Board(int rows, int columns) {
cells = new Cell[rows][columns];
for( int r = 0; r < cells[0].length; r++ ) {

for (int c = 0; c < cells[1].length; c++) { cells[r][c] = new Cell(r,c);

}
}

}
public void setCell(Mark mark, int row, int column) throws
IllegalArgumentException {

if (cells[row][column].getContent() == Mark.EMPTY)
cells[row][column].setContent(mark);

else throw new IllegalArgumentException(“Player already there!”);
}
public Cell getCell(int row, int column) {
return cells[row][column];

}
public String toString() {

StringBuilder str = new StringBuilder();

for( int r = 0; r < cells.length; r++ ) { str.append(“|”); for (int c = 0; c < cells[r].length; c++) {

switch(cells[r][c].getContent()) {

public void setContent(Mark content) { this.content = content; }
public int getRow() { return row; }

public int getColumn() { return column; }
}

Graded Project136

case NOUGHT:
str.append(“O”);
break;

case CROSS:
str.append(“X”);
break;

case YELLOW:
str.append(“Y”);
break;

case RED:
str.append(“R”);
break;

case BLUE:
str.append(“B”);
break;

case GREEN:
str.append(“G”);
break;

case MAGENTA:
str.append(“M”);
break;

case ORANGE:
str.append(“M”);
break;

default: //Empty
str.append(“ “);

}
str.append(“|”);

}
str.append(“\n”);

}
return str.toString();

}
}

Note: This code should seem familiar to you. The meth-
ods in the TicTacToeGame class are similar to those in
the Board class. The StringBuilder class was used
instead of the String class for better performance. You
can learn more about the StringBuilder class by visiting
the Oracle Website at http://docs.oracle.com/javase/
tutorial/java/data/buffers.html.

Graded Project 137

8. Add the following import statement to the
BoardGameTester class:

import games.boards.*;

9. In the main() method of BoardGameTester, perform the
following actions:

a. Create a 3 × 3 board for a Tic-Tac-Toe game.

b. Create a 6 × 7 board for a Connect Four game.

c. Create a 5 × 8 board for a game of Mastermind.

d. Set a cell to a nought or cross on the
Tic-Tac-Toe board.

e. Set a cell to yellow or red on the
Connect Four board.

f. Set a cell to yellow, red, green, blue, magenta, or
orange on the Mastermind board.

g. Display the boards for Tic-Tac-Toe, Connect Four,
and Mastermind.

10. Compile and run the project to ensure it works
as expected.

SUBMISSION GUIDELINES

To submit your project, you must provide the following
source code files in a ZIP file:

■ BoardGameTester.java

■ Board.java

■ Cell.java

■ Mark.java

■ Outcome.java

■ Player.java

Graded Project138

To find these files within NetBeans, go to the
BoardGameTester project folder. To determine this folder,
right-click on BoardGameTester project in the Projects
panel. Copy the value for the Project Folder textbox using
the keyboard shortcut CTRL+C. In Windows Explorer, paste
the project folder path and hit the ENTER key. Right-click on
the src folder and choose the Send to… > Compressed
(zipped) folder option from the context menu. Rename the file
to BoardGameTester_Lesson3.zip and copy it to your desk-
top
or any other temporary location.

Follow this procedure to submit your project online:
1. Log on to the Penn Foster website and go to My Courses.
2. Click Take Exam.

3. Attach your Zip file as follows:

a. Click on the Browse box.
b. Locate the file you wish to attach.
c. Double-click on the file.
d. Click Upload File.
4. Enter your e-mail address in the box provided. (Note:
This information is required for online submissions.)
5. If you wish to tell your instructor anything specific
regarding this assignment, enter it in the Message box.
6. Click Submit File.

Grading Criteria
Your instructor will use the following guidelines to grade
your project.

All types are organized in correct
package hierarchy 10 points

Mark enumeration correctly defined 5 points

Outcome enumeration correctly defined 5 points

Player enumeration correctly defined 5 points

Cell class correctly defined 10 points

Board class correctly defined 10 points

BoardGameTester class correctly defined 20 points

The application returns expected output 25 points

All source code files are included: 10 points

TOTAL 100 points

Graded Project 139

NOTES

Graded Project140

141
L
e
s
s
o
n

4
L

e
s
s
o

n
4

Advanced
Programming Logic

INTRODUCTION

So far the applications you’ve designed are transient and
unoptimized. They’re effective as long as a user keeps the
program running and performs one action at a time. Well-
built applications usually take advantage of a user’s local
storage and memory/CPU utilization. In this lesson, you’ll
learn how to load and save data to files and use multithread-
ing techniques to improve the consistency and performance
of your applications.

OBJECTIVES

When you complete this lesson, you’ll be able to

■ Differentiate between the I/O classes provided by Java

■ Write data from an application to a file

■ Read data from a file back into an application

■ Access the local user’s file system using the
java.nio package

■ Create a custom thread using the Thread class and
Runnable interface

■ Control a running thread’s lifetime and priority

■ Use thread synchronization and notification techniques

■ Use the java.util.concurrency package

Programming in Java142

ASSIGNMENT 12:
USE I/O CLASSES
Read Assignment 12 in this study guide. Then read Chapter 10
in your textbook.

Assignment 12 introduces basic input/output programming
in Java and addresses the new I/O classes provided by Java 7
in the java.nio package. Be sure to complete the Try This
activities in Chapter 10.

Standard Stream Classes

A stream is a sequential flow of data from a source to a
destination. Sources can include files, network hosts, or
even local String objects. Data sent through a stream can be
raw bytes, individual characters, sequences of characters, or
entire objects. Input streams read data from a stream, while
output streams write data to a stream.

There are many stream classes located in the java.io pack-
age, each specialized for certain types of streams, sources,
and destinations. In the textbook, Table 10-1 on page 328
lists all of the byte stream classes, while Table 10-2 on page
329 lists all of the character stream classes. The fundamental
difference between byte and character streams is that character
streams convert bytes into characters. Byte streams don’t
assume a character set and are intended for images, object
serializations, and other binary data.

Byte Streams

Byte input and output streams are subclasses of the abstract
classes InputStream and OutputStream, respectively. The
core method of the InputStream class is read(). The read()
method can retrieve a single byte or an array of bytes. When
the end of the stream is reached, read() will return -1. The
core method of the OutputStream class is write() and can
also handle a single byte or array of bytes. The OutputStream
class includes the flush() method to push buffered data into
the stream. Both InputStream and OutputStream provide a
close() method to end the stream and release all system
resources used by that stream.

Lesson 4 143

The following code demonstrates a common algorithm used
in reading byte streams:

while ( (byteRead = inputStream.read() ) != -1) {
//do something with the bytes here

}

As you can see from this example code, the while and do-
while statements are prominent in I/O programming. Notice
also from this example that the read() method is invoked,
then immediately assigned, and compared to -1. This condi-
tion will ensure the block ends once the end of the stream is
reached.

Character and Buffered Streams

Character input and output streams are subclasses of
the abstract classes Reader and Writer, respectively. The
Reader class also provides the read() method, but unlike the
InputStream class, the Reader retrieves converted char values
from the stream. The Writer class provides a write() method
for characters, but also includes the append() method for
adding characters to the end of a stream. The flush() method
pushes buffered characters into the stream. Like InputStream
and OutputStream, the Reader and Writer classes provide a
close() method.

Because character streams merely convert between bytes and
characters, character stream classes accept byte streams for
their constructors. By wrapping a byte stream in a character
stream, you can take advantage of sources and destinations
that don’t natively support character conversion. The follow-
ing code wraps the standard input byte stream with a
character stream:

Reader reader = new InputStreamReader( System.in );

Often, you’ll need to read characters, not one at a time,
but entire lines at a time. BufferedReader is a wrapper for
Reader objects to provide the additional readLine() method.
The PrintWriter is a wrapper for Writer objects to provide
the additional println() and printf() methods. The printf()
method is intended for formatting an array of objects in a

Note: Both byte and
character stream
classes can throw
an IOException. If a
method throws an
IOException, then you
must either handle the
exception in a
try/catch block within
the method or declare
that method throws an
IOException.

Programming in Java144

String. You can read more about formatting string syntax in
the Java 7 API Documentation at http://docs.oracle.com/
javase/7/docs/ api/java/util/Formatter.html#syntax

System Streams

In using the command line for I/O operations, you’ve already
been exposed to predefined streams provided by the System
class:

■ System.in—Standard keyboard entry using the
InputStream class

■ System.out—Standard text-based output using the
PrintStream class

■ System.err—Standard text-based output formatted for
errors using the PrintStream class

Another technique for using the command line is to use the
Console class. If you develop command-line applications, you
should use the Console class rather than the System streams.
Unfortunately, the Console class isn’t compatible with the
Output pane in the NetBeans IDE.

Opening and Closing Streams

To open a stream for reading or writing in Java, you need only
instantiate the stream class. The available() method in the
InputStream class will return the number of bytes available
for reading. The ready() method returns a boolean indicating
whether the stream is available for reading with the Reader
class.

Note: Byte streams
have a class similar
to PrintWriter. The
PrintStream class also
provides the println()
and printfs() methods.

Lesson 4 145

When reading or writing with the stream is complete, that
stream should be closed and its pointer dereferenced. The
following code performs this action manually:

Note: The finally block will execute whether or not an excep-
tion is thrown. However, if the close() method throws an
exception, then any exceptions thrown from the try block
will be effectively suppressed. The Throwable class provides
getSuppressed() and initCause() to access suppressed excep-
tions in these situations.

Java 7 introduces a new construct to handle this logic
seamlessly. The try-with-resources statement will automati-
cally close and dereference resources that implement the
AutoCloseable interface. All stream classes implement this
interface, so this construct can definitely simplify your code.

The previous example could be rewritten using the try-with-
resource statement:

try ( FileWriter fs = new FileWriter(“output”) ) {
//perform write operations

} catch (IOException ex) {

//handle exception

}

try {
FileWriter fs = new FileWriter(“output.txt”);
//perform write operations
} catch (IOException ex) {

//handle exception
} finally {

if (fs != null ) { // <- instantiation may have failed fs.close(); // <- close the stream fs = null; // <- dereference the stream pointer

}
}

Programming in Java146

Reading and Writing to Files

To read from a file, you can use the byte stream
FileInputStream or character stream FileReader. To write
to a file, you can use the byte stream FileOutputStream or
character stream FileWriter. The constructors for these
classes can accept a path name or legacy File object. These
constructors can throw FileNotFoundException if the loca-
tion is invalid or SecurityException if the current user
doesn’t have permission to read or write to it.

The following code copies a file byte into another file:

In the next activity, you’ll use the ObjectInputStream and
ObjectOutputStream classes to write and read an object and
use the FileInputStream and FileOutputStream classes to
read and write that object to a file.

Activity 14: Read and
Write Objects with a File

1. Create a new Java Application project named
Lesson4Activity14 in NetBeans.

2. Create a new public class named Employee to the
Lesson4Activity14 package.

3. Inside the Employee class, add the following code:

Note: For an object to be written to a stream, it must
implement the Serializable interface. All fields, including
those declared as private, are written to the stream.

Note: The readObject()
method throws a
ClassNotFoundException,
because the object may
represent a class that’s
unavailable to the
application.

try (

FileInputStream fsIn = new FileInputStream(“input.txt”);
FileOutputStream fsOut = new FileOutputStream(“output.txt”)

) {
int b;
while ( (b = fsIn.read()) != -1 )

fsOut.write(b);
} catch (IOException ex) {

System.err.println(ex.toString());
}

Lesson 4 147

4. Open the Lesson4Activity14.java file. You can do
this by either clicking its tab at the top of Documents
because it should be open or by double-clicking the
Lesson4Activity14.java file in the Projects pane.

5. Make sure you add import the java.io package in the
Lesson4Activity14.java file using the following statement:

import java.io.*;

6. Add the following code in the main() method:

7. Build and run the project. The output should be as
follows:

Employee object written to file.
Employee object read from file.
999-99-9999 (Joshua Hester) – Developer.

//Activity 14
Employee emp =
new Employee(“Joshua Hester”, “999-99-9999”, “Developer”);

//save employee to file
try (FileOutputStream fout = new FileOutputStream(“emp.data”);

ObjectOutputStream objout = new ObjectOutputStream(fout);) {
objout.writeObject(emp);
objout.flush();
System.out.println(“Employee object written to file.”);
} catch (IOException ex) {

System.err.println(ex);

}

emp = null; //clear employee

//read back employee from file
try (FileInputStream fin = new FileInputStream(“emp.data”);
ObjectInputStream objin = new ObjectInputStream(fin);) {
emp = (Employee) objin.readObject();
System.out.println(“Employee object read from file.”);
} catch (IOException | ClassNotFoundException ex) {
System.err.println(ex);
}
System.out.println(emp);

Programming in Java148

New I/O Classes

Although the system.io package provides classes, enumera-
tions, and interfaces to handle local file system viewing and
manipulation, Java 7 introduced a new file I/O mechanism
in the java.nio package. The java.nio package offers signifi-
cant advantages over the older java.io package. Not only are
file I/O operations with java.nio greatly simplified, but this
mechanism utilizes memory buffers, read/write channels,
and multiple threads.

Table 6 lists common I/O classes and interfaces in the
java.nio package and java.nio.file and ava.nio.file.attribute
subpackages.

Note: Many of these
classes are abstract,
because the JVM
provides the implemen-
tation optimized for the
target file system at
runtime. This means
that file I/O operations
should work regardless
of which operating sys-
tem is installed.

Table 6

Class Description

Buffer Abstract sequence of primitive elements storedfor an underlying stream

MappedByteBuffer An abstract byte-portion of a file mapped to memory

FileChannel An abstract channel for file reading/writing and manipulation

NetworkChannel An interface for channels using network protocols

SocketChannel, ServerSocketChannel Abstract network channels that represent clientsenders and server listeners, respectively

Path
Interface that represents a file/directory location
on the file system. To get a Path object, use the
Paths class.

DirectoryStream Interface used to iterate through entries in a directory

Files A class that provides static methods for opening,
Table 6—Java.nio classes

Lesson 4 149

You’ll use a Path object to reference a file or directory loca-
tion. The Paths class provides the static method get(), which
can accept one or more String arguments. The following code
demonstrates how to access a File using the Paths class:

Path p1 = Paths.get(“file.txt”);
//relative
Path p2 = Paths.get(“C:\\Java\\file.txt”);
//absolute
Path p3 = Paths.get(“C:”, “Java”, “file.txt”);
//same as p2
boolean isSameFile = Files.isSameFile(p2, p3);
//set to true

Assuming the current compiled class is in the same location
as file.txt, all three of these Path objects would reference the
same file. When using absolute locations, the last code state-
ment is the preferred convention. This is because the JVM
automatically adds the path separator (\ for Windows; / for
Linux, Unix, and Mac) for the target OS. It’s always prefer-
able to be agnostic in terms of the OS, so that your Java
application will run on any platform.

A Path object doesn’t map to an actual file or directory location,
because a path may not exist on the local file system. This is
helpful for creating new files, but can complicate matters when
reading from or appending to an existing file. Before using a
Path object for input, you should invoke either the exists() or
notExists() method on the Files class. If the file system can’t
confirm its existence because of a hardware or driver issue,
then it may return false for both methods.

The Files class also provides methods to verify the capabili-
ties of the file. The isReadable() and isWritable() methods are
important to check before attempting to open a file. The
StandardOpenOptions enumeration specifies how the file
should be opened when performing write operations. This
enumeration includes the following fields:

1. WRITE—Write access.

2. APPEND, TRUNCATE_EXISTING—Add data to the end of
the file or overwrite existing data, respectively.

Note: You can use the
getPath() method on
the default FileSystem
object to retrieve a
Path object. Also,
the FileSystem object
provides helpful OS-
specific methods to
ensure that your file
I/O code remains
agnostic of the OS.
These methods include
getSeparater() and
getRootDirectories().

Note: The
StandardOpenOptions
enumeration fields use
the bitwise OR operator
| to combine values.

Programming in Java150

3. CREATE, CREATE_NEW—Create a new file. CREATE
will open the file if it already exists, while CREATE_NEW
will throw an exception if the file already exists.

4. DELETE_ON_CLOSE—Deletes the temporary file after
I/O operations are complete.

When handling files, you’ll most often use Files and/or Path
to access a file for reading or writing. The simplest method
is to use the self-explanatory methods readAllBytes() or
readAllLines() or write(). This is appropriate for small files
less than a megabyte in size. Larger text files can retrieve
buffered streams using the newBufferedReader() and
newBufferedWriter() methods. For backwards compatibility,
the methods newInputStream() and newOutputStream() are
provided, but the newByteChannel() method is intended for
larger data files. Finally, the most robust and complex mech-
anism for accessing files is using FileChannel, which offers
file-locking features, file bytes to memory mapping, and
advanced reading and writing controls.

The following code reads all bytes from one file and copies
those bytes into another:

In Activity 15, you’ll use buffered streams to write and then
read back contents of a file.

Path srcFile = Paths.get(“original.txt”);
Path destFile = Paths.get(“copy.txt”);
try {

byte[] readBytes = Files.readAllBytes(srcFile); //read
Files.write(destFile, readBytes); //write

} catch (IOException ex ) {
System.err.println(ex.toString());

}

Lesson 4 151

Activity 15: Use New I/O
Classes to Read and Write Files

1. Open the Lesson4Activity14 project in NetBeans.

2. Open the Lesson4Activity13.java file.

3. Make sure to add the following statements to the
Lesson4Activity13.java file:

import java.nio.*;
import java.nio.file.*;
[program font ends here]

4. So that you can keep the code used in Activity 13 for fur-
ther reference without affecting this activity’s code, you’ll
comment the current code. To do this, highlight the cur-
rent code in the main() method and then choose the
Toggle Comment option from the Source menu or the
keyboard shortcut CTRL+/.

5. Add the following code to the main() method as follows:

//Activity 15

Path file = Paths.get(“activity.txt”);

Charset cset = Charset.forName(“UTF-16”);

if (Files.notExists(file)) { //Check for file

System.out.println(“Enter text for new file. Hit ENTER on a blank line to end.”);

try (BufferedReader stdin = new BufferedReader( new

InputStreamReader(System.in));

BufferedWriter fout = Files.newBufferedWriter(file, cset);) {

String line = ““;

while ((line = stdin.readLine()) != null && line.length() != 0 ) {

fout.write(line);

fout.newLine();

}

fout.flush();

} catch (IOException ex) {
System.err.println(ex);
}

System.out.println(“File written.”);

} else {

System.out.println(“Reading file ….”);

try (BufferedReader fin = Files.newBufferedReader(file, cset);) {

String line = ““;

Programming in Java152

This code checks to see if a file doesn’t exist. If the file
doesn’t exist, then it creates the file by reading each line
from the command line and writing it to the file. If the
file does exist, then the contents of the file are read line-
by-line and printed as output.

6. Build and run the project. You should be prompted to
write the contents of the file. You can write as many lines
of text as you like. When you’re done, hit the ENTER key
on a blank line to finish writing to the new file.

7. Run the project again. Because the file was already written,
the contents of the file should be displayed.

while ((line = fin.readLine()) != null) {

System.out.println(line);

}
} catch (IOException ex) {
System.err.println(ex);
}
}

Lesson 4 153

Self-Check 12

1. What are the differences between byte, character, and buffered streams?

__________________________________________________________

2. Which standard method is used to retrieve data from a stream? Which standard method is
used to modify data in a stream?

__________________________________________________________

3. Which three predefined streams accept standard input and generate output and errors?

__________________________________________________________

4. How does the try-with-resources statement handle resource objects?

__________________________________________________________

5. Which interface in the java.nio package represents the location of a file or directory?

__________________________________________________________
Check your answers with those on page 205.

Programming in Java154

ASSIGNMENT 13:
USE MULTIPLE THREADS
Read Assignment 13 in this study guide. Then read Chapter 11
in your textbook.

Assignment 13 introduces multithreading concepts and how
to use threads in Java as well as high-level threading classes.
Be sure to complete the Try This activities in Chapter 11. It’s
highly recommended that you read the Concurrency lesson
in the Oracle Java Tutorials at http://docs.oracle.com/
javase/tutorial/essential/concurrency/ before implementing
multithreading in any professional applications.

Threading Basics

A process is a unique runtime environment for a running
application. Each process contains its own state, memory
address, and set of resources. Processes can communicate
with each other, but not through direct memory access.
These communication mechanisms are controlled by the
operating system, not the programmer.

A thread is a distinct task performed by an application.
Threads can share state and memory, because they’re exe-
cuted within the same process. Whereas multiple processor
cores dictate how many concurrent processes can execute,
application code dictates how many concurrent threads can
execute in a process.

It’s important to note that neither multiprocessing operating
systems nor multithreaded applications execute their units
exactly at the same time. There’s a system of scheduling
required, where each execution unit, whether a thread or
process, is assigned a slice of time in which to be active. The
execution is active until the time expires; it completes or a
higher priority unit requires access. In the case of processes,
the operating system controls access to hardware resources. In
the case of Java threads, it’s the JVM that controls execution
scheduling and execution.

Lesson 4 155

Creating Threads

By default, all Java applications have a single user thread
known as main. As you recall, the main() method is the first
point of entry for a Java application. All execution in the
main() method is executed on the main thread. Even when
code outside the main() method is executed, the main thread
is used, because the invocations originate from within the
main() method. Thus, all applications you’ve developed so far
are single-threaded.

To create custom threads, you can either implement the
Runnable interface or extend the Thread class because the
Thread class implements the Runnable interface. Explicitly
implementing the Runnable interface is preferred, but you’ll
still use the Thread class to start and control the thread. The
table at the bottom of page 369 in Chapter 11 of the textbook
lists the most common Thread methods. The body for a
thread is defined within its run() method. The run() method
often performs long-running calculations or complex iterative
algorithms. The run() method must match the following
signature:

public void run()

The following code creates a thread class by implementing
the Runnable interface:

public class ThreadWithRunnable implements
Runnable {

public void run() {

//perform work

}
}

Note: Because the run()
method can’t accept
arguments or return
values, input and out-
put is handled by
sharing fields between
threads. The Callable
interface is more flexible
with its call() method,
which can return a
value.

Programming in Java156

The following code creates a thread class by extending the
Thread class:

public class ThreadWithThreadClass extends Thread
{

public void run() {
//perform work

}
}

The real difference between these two techniques is overhead
and how the thread is started. To start a thread, you must
use the start() method of the Thread class. If the custom
thread class extends Thread, then you need to instantiate
only the Thread class and invoke start(). If the custom
thread class implements Runnable, then you need to instan-
tiate the custom thread class, specify the thread object in the
Thread class constructor, and then invoke the start()
method.

The following code demonstrates how to start threads using
both techniques:

//thread instantiation
Thread thRunnable = new Thread(new
ThreadWithRunnable());
Thread thThreadClass = new
ThreadWithThreadClass();
//start the threads
thRunnable.start();
thRunnable.start();

Thread Lifetime

Figure 9 depicts the states in a thread’s lifetime.

As indicated in the lifetime, the start() method doesn’t actu-
ally run the thread, but places it in the runnable queue. For
most threads, the majority of their lifetime is spent in the
runnable state. When a thread actually runs is determined
by the scheduler based on its priority and position in the
queue. A higher priority thread is more likely to receive exe-
cution time than a lower priority thread. In many cases, a
high-priority thread can dominate execution if other threads

Note: Although the
run() method contains
the main body of a
thread, it’s actually the
start() method that
executes the body on a
separate thread.

Lesson 4 157

in the runnable queue are low-priority. To set a thread’s pri-
ority, you can use the setPriority() method. The default
priority level is NORM_PRIORITY, with both MIN_PRIORITY
and MAX_PRIORITY as the other options.

A thread can move from running back into the runnable state
by using the yield() method. The yield() method notifies the
scheduler that a thread is willing to give up execution time for
other runnable threads. Unfortunately, the exact implemen-
tation differs by operating system. In Windows, the thread
is forced to wait a specified amount of time, but then can
immediately resume its execution later. In Linux, the thread
is forced to wait until all other threads in the queue execute
at least once.

From the running state, a thread can also move into the blocked
and dead state. A thread in the blocked state is effectively
paused, waiting in memory for immediate execution. Like
runnable, the blocked state uses a queue for waiting threads.
The operating system can interrupt a thread if a runtime
exception occurs or a higher priority thread requires execution.
The sleep() method moves a thread into the blocked state for
a predetermined number of milliseconds. After the time has
elapsed, the thread is pushed into the wait queue for immediate
execution.

FIGURE 9—A Thread’s Lifetime

Programming in Java158

The join() method is a bit more complex. When Thread1
invokes the join() method on Thread2, Thread1 will be
blocked until Thread2 is dead. A thread is considered dead if
that thread completes its work or is stopped manually by the
programmer or operating system. The isAlive() method indi-
cates whether a thread is in any other state than dead.
Remember that a thread is alive when it’s in the runnable
queue or blocked.

Activity 16: Create and
Control a Custom Thread

1. Create a new Java Application project named
Lesson4Activity16 in NetBeans.

2. Create a new public class named Timer to the
lesson4Activity16 package.

3. Inside the Timer class, add the following code:

public class Timer implements Runnable {
private boolean stopped;
private long delay;

public Timer (long delay) {
this.delay = delay;

}
public void stop() { stopped = true; }
public void run() {
while (! stopped ) {

java.util.Date time = new java.util.Date();
System.out.println(time);
for (long i = 0; i < delay; i++);

}
}
}

This class is a simple timer that outputs the current
time in a thread. The stop() method ends the timer.

4. Open the Lesson4Activity16.java file. You can do this
either by clicking its tab at the top of Documents
because it should be open or by double-clicking the
Lesson4Activity16.java file in the Projects pane.

Lesson 4 159

5. Add the following code in the main() method:

6. Build and run the project. The timer should display until
you hit the S key and ENTER. The only reason this works
is because the timer is displaying output on a separate
thread from the main thread, which is listening for input.

Code Synchronization

For threads to communicate, they must share fields and object
references with each other. When multiple threads share data
like this, error conditions such as thread interference and
memory inconsistency can occur. In thread interference, two
or more operations running in different threads act on the
same data and overlap their sequence of execution. Thread
interference errors are difficult to detect, because the results
are unpredictable. Memory inconsistency occurs when multi-
ple threads see the same data differently. For example, while
Thread1 is incrementing a counter variable, Thread2 may be
reading the previous value and assuming it’s the current value.

To prevent these error conditions, you can use the synchro-
nized keyword. The synchronized keyword can lock a block
of statements or entire method, so that only one thread at a
time can execute. When using the synchronized keyword

Timer tmr = new Timer(1_000_000_000);
System.out.println(“Timer started. \’s\’ to stop”);
new Thread(tmr).start();

while (true) {
try {
if (System.in.read() == ‘s’) {

tmr.stop();
break;

}
} catch (java.io.IOException ex) {
System.err.println(ex);
}
}

System.out.println(“Timer stopped.”);

Note: By default, each
thread stores a copied
value from a shared
field. A field declared
with the volatile key-
word will allow all
threads to use a master
copy of value. If a field
is bound to change
often in multithreaded
situations, you may
find more consistent
results by using the
volatile keyword.

Programming in Java160

with a block of statements, you choose an object that repre-
sents the lock. This usage of the synchronized keyword is
known as a synchronized statement. In most cases, the lock
is the current object modified by the group of statements.

The following code demonstrates a synchronized statement:

synchronized(this) {
this.counter++;

}

When using the synchronized keyword with a method, only
a single thread can execute the method at a time. This means
that method invocations by other threads are blocked until
the current thread returns from the method. This type of
method is known as a synchronized method.

The following code demonstrates a synchronized method:

public synchronized void increment(int value) {
this.counter += value;

}

When using synchronized statements and methods, you can
take advantage of thread-related methods provided by the
Object class. An overloaded version of the wait() method
takes no argument and will move a thread into the blocked
state until it’s notified to resume. By default, this will move
the thread directly into the wait queue rather than having a
timeout. The notify() method will resume a single thread
from the wait queue. The resumed thread will be the first
thread in the queue. The notifyAll() method will attempt to
resume all threads in the queue, so that the highest priority
thread will resume first.

A simple threading model that utilizes these methods is
producer/consumer. The producer provides a resource
that’s used by the consumer. A consumer thread invokes a
wait() on itself to allow the producer to prepare access to the
resource. When the resource is available, the producer thread
then invokes the notify() or notifyAll() methods. When the
consumer thread completes, it can then wait again until
resources are made available by the producer thread.

Lesson 4 161

High-Level Concurrency

If manual threading seems too complex to implement large-scale,
don’t worry. Java offers high-level locking, thread pools, and
concurrent-safe collections to simplify multithreaded applications.
These types are found in the java.util.concurrent package.

Table 7 lists these high-level concurrency types.

Table 7

Class Description

Lock An interface that allows explicit control for tryingto acquire and releasing a single-thread lock

ReadWriteLock
An interface that allows one lock to be shared by
reader threads and another exclusive lock for
writer methods

Callable An interface implemented by threads which canreturn a value

RecursiveTask Abstract class that represents a task that can bedivided into recursive invocations

Future This interface represents the result from anasynchronous invocation

ExecutorService An interface for executing threads within automated thread pools

ScheduledExecutorService An interface for executing threads at set delayand/or repeated period

BlockingQueue, ConcurrentMap,
ConcurrentMap

Interfaces implemented by collections that
protect elements when multiple threads
access those elements concurrently

Table 7—High-level Concurrent Classes

Programming in Java162

The following code demonstrates usages of high-level concur-
rency classes and interfaces:

This code generates a random number after a 10-second delay.

public class CalcThread implements Callable {
//Callable implementation
public Integer call() throws Exception {

//Get number from 1 to 10
return ThreadLocalRandom.current().nextInt(1,11);

}
public static void main(String[] args) {

ScheduledExecutorService ex =
Executors.newScheduledThreadPool(1);

Callable c = new CalcThread();
Future f = ex.schedule(c, 10, TimeUnit.SECONDS);
while (!f.isDone()) {} //waiting
try {

System.out.println(f.get());
ex.shutdown();

} catch (Exception e) {
System.err.println(“Error: “ + e.toString());

}
}
}

Lesson 4 163

Self-Check 13

1. How does a thread differ from a process?

__________________________________________________________

2. What are the two techniques for creating a custom thread class?

__________________________________________________________

3. How do the Runnable and Callable interfaces differ?

__________________________________________________________

4. What is the initial state of a thread after the start() method is invoked?

__________________________________________________________

5. What does the synchronized keyword allow?

__________________________________________________________

Check your answers with those on page 206

.

Programming in Java164

NOTES

Lesson 4 165

Advanced
Programming Logic
OVERVIEW

Now you’re ready to add file I/O to your board game applica-
tion. This project will assess your understanding of writing a
file and using multithreading.

Make sure to follow all directions completely and verify your
results before submitting the project for grading. Remember
to include all required components in your solution.
YOUR PROJECT

In this project, you’ll modify the BoardGameTester application
to save the gameboard to a file. You’ll perform the file writing
process on a separate thread.

INSTRUCTIONS

1. In NetBeans, open the BoardGameTester project.

2. Create a new package named games.utilities.

3. Add a public class named FileManager that contains the
following methods:

public static void writeToFile(String saveState, String

fileName) {

//TODO: Write a string to a new file synchronously

}

public static void writeToFileAsync(final String saveState,

final String fileName) {

//TODO: Write a string to a new file asynchronously

}
G
ra
d
e
d
P
ro
je
c
t
G
ra
d
e
d
P
ro
je
c
t

Programming in Java166

4. Implement the writeToFile method using the new file
I/O classes in a try-with-resources statement.

Note: Use the code in Activity 15 as a guide for the
writeToFile method. Remember to import the java.io,
java.nio, java.nio.charset, and java.nio.file packages.

5. Implement the writeToFileAsync method using a sepa-
rate thread. Use the following code as a guide:

new Thread() {
public void run() {
writeToFile(saveState, fileName);
}
}.start();

Note: This code uses an anonymous inner class to declare
and instantiate a Thread class. Unlike a traditional inner
class, anonymous inner classes are available only within
the statement they’re declared. You’ll see more examples
of anonymous classes with Swing in the next lesson. To
ensure that local variables are unchanged by the inner
class, the parameters saveState and fileName must be
declared with the final keyword.

6. In the main() method of the BoardGameTester project,
add the following code:

Note: Remember to import the games.utilities package!

7. Compile and run the project to create three files, one for
each saved board game. Open the files to ensure they
contain the correct game board display.

Note: Notepad won’t display the line returns in the file.
You may need to open the text files using Microsoft Word
or Wordpad instead.

These three game board files will be required for submission.

FileManager.writeToFileAsync(ticTacToe.toString(), “ttt.txt”);
FileManager.writeToFileAsync(connectFour.toString(), “c4.txt”);
FileManager.writeToFileAsync(mastermind.toString(), “mm.txt”);

Lesson 4 167

SUBMISSION GUIDELINES
To submit your project, you must provide the following
source code files in a ZIP file:
■ BoardGameTester.java

■ FileManager.java

■ ttt.txt

■ c4.txt

■ mm.txt

To find the Java source files within NetBeans, go to the
BoardGameTester project folder. To determine this folder,
right-click on BoardGameTester project in the Projects
panel. Copy the value for the Project Folder textbox using
the keyboard shortcut CTRL+C. In Windows Explorer, paste
the project folder path and hit the ENTER key. Copy both the
BoardGameTester.java file from the src\boardgametester
folder and the FileManager.java file from the
src\games\utilities folder to your desktop or any other tem-
porary location. The three game board files will be located at
the root of the project folder.

Follow this procedure to submit your project online:
1. Log on to the Penn Foster website and go to My Courses.
2. Click Take Exam.

3. Attach your zip file as follows:

a. Click on the Browse box.
b. Locate the file you wish to attach.
c. Double-click on the file.
d. Click Upload File.
4. Enter your e-mail address in the box provided. (Note:
This information is required for online submissions.)
5. If you wish to tell your instructor anything specific
regarding this assignment, enter it in the Message box.
6. Click Submit File.

Programming in Java168

GRADING CRITERIA

Your instructor will use the following guidelines to grade your
project.

FileManager class correctly defined 40 points

BoardGameTester class correctly modified 20 points

All three game board files are correct 20 points

All source code and files are included: 20 points

TOTAL 100 points

Lesson 4 169

Graphical User
Interface Design

INTRODUCTION

So far you’ve focused on developing command-line applications
that strictly control text-based input/output. Most modern
applications use a graphical user interface (GUI) for input/
output and rely on user events to perform their operations. In
this lesson, you’ll be introduced to the APIs for the abstract
windowing toolkit (AWT), Swing, and JavaFX. After completing
this lesson, you’ll be prepared to create robust and user-
friendly applications in Java!

OBJECTIVES
When you complete this lesson, you’ll be able to

■ Discuss Java applet technology and life cycle

■ Create and use a Java applet

■ Use the Graphics class to paint text and basic shapes

■ Register and handle standard events

■ Differentiate Swing from the abstract windowing toolkit
(AWT)

■ Explain the model-view-controller pattern

■ Use layout managers to organize Swing components

■ Create and add standard Swing components

■ Create an applet with Swing

■ Describe JavaFX technology

L
e
s
s
o
n

5
L

e
s
s
o

n
5

Programming in Java170

ASSIGNMENT 14: CREATE
APPLETS AND HANDLE EVENTS
Read Assignment 14 in this study guide. Then read Chapter 14,
pages 473–496, as well as Chapter 15, pages 536–537, in your
textbook.

Create Applets and Handle Events

Assignment 14 introduces applets and event handling using
AWT, and covers anonymous inner classes, which are presented
in Chapter 15. Be sure to complete the Try This activities in
Chapter 14.

Applet Basics

An applet is a small GUI application embedded in a Web
page. Applets are often built as executable Java archive (JAR)
files and are executed by the JVM associated with a brower’s
plug-in manager. Because applets are automatically loaded
by the browser, Java applets run in security sandbox to pro-
tect the client OS from malicious code. Unsigned applets are
those that aren’t signed with a valid certificate from a trusted
certificate authority (CA). They can’t access the local file sys-
tem or other remote Web servers. Signed applets can run in
standalone mode and are limited only by general OS security.

Applets are embedded in Web pages in the same way as other
multimedia is. In earlier versions of HTML, you would use the
element, while the element is preferred for
HTML5. The following HTML embeds an applet in a Web page:

Applet failed to run. Please install the

Java plug-in.

The type attribute specifies the Multipurpose Internet Mail
Extensions (MIME), so that the browser knows to use the
Java plug-in. The code parameter specifies the applet class,

while the archive parameter contains the location of the JAR
file. If the JVM isn’t installed or not configured correctly in
the browser, the text in the element is displayed in
the Web page.

AWT-based applets extend the Applet class and override the
paint() method. The paint() method receives a Graphics
object from the JVM to draw text, shapes, and components
in the applet.

The Graphics Context

One of the first aspects in GUI programming that you’ll need
to get used to is how methods are used. Although you’ll con-
tinue to write and invoke your own methods, more often than
not, the JVM environment will call methods automatically for
you. It’s your responsibility to implement or override certain
methods to execute custom code in response.

The paint() method is a good example of how this works.
Because Applet is a subclass of Component and Container,
it inherits the paint() method. In AWT, any time a component
or its container is resized or redisplayed in any way, the
paint() method is invoked. Rather than being concerned about
the complexity of painting graphics for each OS, the JVM pro-
vides a concrete implementation of the abstract class
Graphics to the paint() method. The Graphics object is also
known as the Graphics context, because the JVM with native
OS-specific code provides the concrete class. As a program-
mer, you need write only code in the paint() method that tells
the Graphics context what to do.

The Graphics class contains many different methods for creat-
ing simple and complex shapes, and drawing lines and text.
One-dimensional segments and shape outlines are created by
using the drawXXX() methods, while filled shapes is created
by the fillXXX() methods. The setColor() method indicates
the Color object used for painting colors, while setFont()
specifies the Font object used for painting text. The following
methods are common when painting shapes and text:

■ drawString()—Paints text using the specified x/y coordi-
nate as the top-left corner of the text block.

Lesson 4 171

Graded Project172

■ drawLine()—Paints a line from one x/y coordinate
to another.

■ drawArc() and fillArc()—Paints a line or filled area from an
x/y coordinate within a rectangular block at specified
start and end angles.

■ drawRect(), fillRect(), draw3DRect(), and fill3DRect()—
Paints closed rectangle outline, fill with or without a
3-dimensional highlight starting at an x/y coordinate
with a specified width and height.

■ drawOval() and fillOval()—Paints a closed circular shape
within a rectangular block starting from a top-left x/y
coordinate.

■ drawPolygon() and fillPolygon()—Paints a closed shape
using an array of x/y coordinates or a Polygon object.

■ drawPolyline()—Paints an open shape using an array of
x/y coordinates.

To designate where something is painted, you must specify
the x/y coordinates of where it will appear in the component.
The top-left corner is 0,0, while moving to the right increases
the x value and moving down decreases the y value (Figure 10).

Take the following code:

Font font = new Font(“Arial”, Font.BOLD, 18 );
String text = “Have a nice day!”;
g.setColor(Color.YELLOW);
g.fillOval(100,100,200,200);
g.setColor(Color.BLACK);
g.fillOval(150, 150, 25, 25);
g.fillOval(225, 150, 25, 25);
g.drawArc(150, 180, 100, 75, -180, 180);
//Measure text
FontMetrics measure = g.getFontMetrics(font);
int txtWidth = measure.stringWidth(text);
g.setColor(Color.RED);
g.setFont(font);
g.drawString(text, 100 + 200/2 – txtWidth/2, 325);

This code will generate an applet that paints the graphic in
Figure 11.

Graded Project 173

Applet Life Cycle

Before the paint() method is called, the init() and start()
methods are invoked by the JVM. The init() method is invoked
only once, while the start() method is invoked every time the
applet is restarted. The stop() is invoked whenever the applet
is suspended. The final method invoked is destroy(). This
occurs only once when the applet is shut down. Unlike
paint(), the init(), start(), stop(), and destroy() methods
accept no arguments.

A common action to take in the init() method is to retrieve
custom parameters from the Web page. The following HTML
specifies a custom parameter for an applet:

Figure 10—x/y Coordinates Figure 11—Graphic Code Output

Applet failed to run. Please install the Java plug-in.

Graded Project174

The following code retrieves the custom parameter username:

String username = getParameter(“username”);

Code in the init() method could also start other user threads,
so that the code in destroy() would terminate those threads.
Think of the start() and stop() methods as the methods that
are invoked when an applet is paused and then resumed.
Rather than consume resources indefinitely, use the stop()
method to stop painting and calculations, until the start()
method is invoked.

To change what’s displayed in the applet after fields have
been updated to new values, you should invoke the repaint()
method. This is because iteration within the paint() method
would make the applet unresponsive to user events. The JVM
will then invoke the paint() method again with the updated
values. An overloaded version of repaint() accepts a bounding
rectangle with x/y coordinates and width and height, so that
only a portion of the applet is repainted.

Of course, applets can do more than simply paint graphics.
They can play audio clips, display images, and even resize
themselves. Table 14-1 on pages 488–489 in the textbook
lists all of the methods provided by the Applet class. Because
an Applet is a direct subclass of Panel, it inherits methods
from the AWT classes Panel, Container, and Component
as well.

Activity 17: Create a Basic Java Applet

1. Create a new Java Application project named
Lesson5Activity17 in NetBeans.

2. Replace the Lesson5Activity17.java with the
following code:

3. Run the file by right-clicking on the
Lesson5Activity17.java file in Projects and choosing the
Run File option in the contextual menu or using the
SHIFT+F6 keyboard shortcut. This technique will auto-
matically compile and run the class in the default
appletviewer.

4. The applet should display a target with concentric black
and red circles.

Event Delegation Model
Applets, like any application with a GUI, are event driven. This
means that rather than pushing the user through a predefined
algorithm and prompting for input whenever it’s needed, a
GUI application is primarily concerned with responding to
user interactions whenever they occur. Such user interac-
tions occur when a user clicks on a button, clicks and drags
across the screen, or touches a tablet screen. These user
interactions are called events.

import java.awt.*;
import java.applet.*;
public class Lesson5Activity17 extends Applet {
public void init() { System.out.println(“Applet initialized!”); }
public void start() { System.out.println(“Applet started!”); }
public void stop() { System.out.println(“Applet stopped!”); }
public void destroy() { System.out.println(“Applet destroyed!”); }
public void paint (Graphics g) {
for (int circles = 0; circles < 6; circles ++) {

g.setColor((circles % 2 == 0)? Color.BLACK : Color.RED);
int size = 30 * circles;
int align = size /2;
g.fillOval(0 + align, 0 + align, 180 – size, 180 – size);

}
}
}

Graded Project 175

Programming in Java176

Events are divided by source and type. If a user clicks on a
button, then that button will generate an ActionEvent. If a
user changes the value in a textbox, then that textbox will
generate a TextEvent. Hardware devices like keyboards and
mice also generate events. Table 14-2 on page 491 in the
textbook lists commonly used event classes.

Event Listening and Registration

To respond to an event, you need to use an event listener. An
event listener is registered with one or more sources and is
notified when that event occurs. Event listeners are interfaces
in Java, so you must implement an interface to receive and
respond to event notifications. The listener interface contains
one or more methods that are invoked with the event type.
Table 14-3 on page 492 in the textbook lists commonly used
listener interfaces.

The following code implements the MouseListener and
MouseMotionListener interfaces for a simple line drawing
application:

public class MouseHandler
implements MouseListener, MouseMotionListener {

int prevX, prevY, curX, curY;
public void mouseClicked(MouseEvent me) {/*do nothing */}
public void mouseMoved(MouseEvent me) {/*do nothing*/}
public void mouseEntered(MouseEvent me) {

System.out.println(“Listening for mouse events!”);
}
public void mouseExited(MouseEvent me) {

System.out.println(“Ignoring mouse events!”);
}
public void mousePressed(MouseEvent me) {

prevX = me.getX(); prevY = me.getY();
}
public void mouseDragged(MouseEvent me) {

curX = me.getX(); curY = me.getY();

}
public void mouseReleased(MouseEvent me) {

//draw line from prevX,prevY to curX,curY
}

}

Lesson 5 177

Most listener interfaces are restricted to one or two methods,
but not so for low-level events involving keyboards, mice, focus,
and windows. Unfortunately, you’ll notice that implementing
an interface is all or nothing. You can’t implement a few
methods of an interface—you must implement all methods,
even if your application doesn’t need to listen for those events.
Java provides listener adapter classes as a workaround for this
issue. For example, instead of implementing the MouseListener,
MouseMotionListener, and MouseWheelListener interfaces,
you could simply subclass MouseAdapter. Java provides
adapter classes that combine many related listener interfaces.
These adapter classes include MouseAdapter,
MouseMotionAdapter, FocusAdapter, KeyAdapter, and
WindowAdapter.

The previous class could be briefer using the MouseAdapter
class:

public class MouseHandler extends MouseAdapter {
int prevX, prevY, curX, curY;
public void mousePressed(MouseEvent me) {

prevX = me.getX(); prevY = me.getY();
}
public void mouseDragged(MouseEvent me) {
curX = me.getX(); curY = me.getY();
}
public void mouseReleased(MouseEvent me) {

//draw line
}

}

To ensure that the listener is notified when an event occurs,
you must register that listener with the event source. Java
provides addXXXListener() and removeXXXListener() meth-
ods to allow components to provide or withhold notifications,
respectively.

Programming in Java178

The following code will instantiate the MouseHandler class
to handle events associated with the MouseListener and
MouseMotionListener interfaces:

MouseHandler mouseHandler = new MouseHandler();
addMouseListener(mouseHandler);
addMouseMotionListener(mouseHandler);

It’s common to register listeners within the start() method of
an applet and then remove those listeners in the stop() method.
By doing this, you’re reducing the resource consumption while
the user isn’t actively using the applet.

The following code removes notification of mouse-related events:

removeMouseListener(mouseHandler);
removeMouseMotionListener(mouseHandler);

Anonymous Inner Classes

Often, listener classes are declared as inner classes within their
components. This is because listener classes usually require
access to the same Graphics context as the component and
may need to share important fields and methods within the
class. This is the preferred technique in most cases.

The following code declares the MouseHandler class within
an applet class:

public class DrawApplet extends Applet {
MouseHandler mh;
public void init() {

mh = new MouseHandler();
}
public void start() {

addMouseListener(mh);
addMouseMotionListener(mh);

}
public void paint(Graphics g) {

g.drawLine(mh.prevX, mh.prevY, mh.curX, mh.curY);
}
public void stop() {

removeMouseListener(mh);
removeMouseMotionListener(mh);

}

Lesson 5 179

Because the listener object is referenced multiple times in the
init(), start(), paint(), stop(), and destroy() methods, this
code makes sense as a formally named class. But what if you
wanted to declare a listener class, but used it only once and
never needed to reference the class again?

Welcome to anonymous inner classes. An anonymous inner
class is one that’s defined when it’s instantiated or “on-the-fly.”
As you might guess, because the class is anonymous, you
can’t refer to the class again and can access its methods only
through the object. Thus, anonymous classes can contain only
instance members. The following code defines an anonymous
inner class for a listener to keyboard events:

addKeyListener(
new KeyAdapter() {

public void keyTyped(KeyEvent ke) {
if(ke.getKeyChar() == ‘s’) {

saveToFile();
}

}
}
);

public void destroy () {
mh = null; //dereferenced

}
//inner listener class
class MouseHandler extends MouseAdapter {

int prevX, prevY, curX, curY;
public void mousePressed(MouseEvent me)

{
prevX = me.getX(); prevY = me.getY();

}
public void mouseDragged(MouseEvent me)

{
curX = me.getX(); curY = me.getY();

}
public void mouseReleased(MouseEvent me) {

repaint(); //in the Applet class
}

}
}

Programming in Java180

The class has no name, so you need only specify an interface
or superclass name. An anonymous inner class can’t imple-
ment more than one interface or extend a superclass and
implement an interface. You must choose only one way of
inheriting interface or implementation.

As you’ll notice, the convenience of anonymous inner classes
is overwhelmed by the increased complexity it introduces into
your code. Anonymous inner classes are often used for event
handling, so you should be aware of them even if you choose
not to use them often in your applications.

Activity 18: Create an Interactive Applet

1. Open the Lesson5Activity18 project in NetBeans.

2. In the Lesson5Activity18.java file, add the following
import statement:

import java.awt.event.*;

3. In the Lesson5Activity18.java file, add the members to
the Lesson5Activity18 class:

private StringBuilder input = new
StringBuilder();
private KeyHandler kh = new KeyHandler();
private class KeyHandler extends KeyAdapter {
public void keyTyped (KeyEvent ke) {
input.append(ke.getKeyChar());
repaint();
}

This listener class will allow you to type text in the
applet.

4. In the start() and stop() methods, make the following
modifications:

public void start() {
System.out.println(“Applet started!”);

this.addKeyListener(kh);

}

public void stop() {
System.out.println(“Applet stopped!”);

Lesson 5 181

this.removeKeyListener(kh);

}

5. Add the following code to the paint() method:

g.setFont(new Font(“Arial”, Font.PLAIN, 14));
g.setColor(Color.GREEN);
g.drawString(input.toString(), 50, 50);

6. Run the file in the appletviewer by right-clicking on the
Lesson5Activity18.java file in Projects and choosing
the Run File option in the contextual menu or using the
SHIFT+F6 keyboard shortcut.

7. When you type keys on the keyboard, you should see
them written to the applet.

Programming in Java182

Self-Check 14

1. What is an applet? How does it differ from a traditional stand-alone application?

__________________________________________________________
__________________________________________________________

2. Which method should you override to create the visual elements of an AWT-based applet?

__________________________________________________________

3. Which Graphics method should you use to paint the outline of a circle? Which Graphics
method should use to paint an open shape?

__________________________________________________________
__________________________________________________________

4. What is the role of the source and listener in the event delegation model?

__________________________________________________________

5. What is an anonymous inner class?

__________________________________________________________
Check your answers with those on page 206

Lesson 5 183

ASSIGNMENT 15: USE SWING
Read Assignment 15 in this study guide. Then read Chapter 15
in your textbook.

Assignment 15 continues GUI development by introducing
Swing. This assignment also mentions the current evolution
of GUI development with JavaFX. Be sure to complete the
Try This activities in Chapter 15.

AWT and Swing

The difference between the abstract windowing toolkit (AWT)
and Swing is stark. With AWT, the focus was on having GUI
applications rely heavily on native code, so that an application
developed in Java would look and feel similar to non-Java
applications developed for that platform. With Swing, compo-
nents have a unique look and feel that’s consistent across
Java applications and platforms. In AWT, two components
represented every visual element: a native implementation
and a Java abstract class. In Swing, all visual elements are
pure Java. For this reason, AWT components are known as
heavyweight, while Swing components are considered light-
weight. Although Swing still uses AWT for much of its
plumbing, specifically events and graphics, its components
are much more robust and customizable than those directly
provided by AWT.

Swing is highly customizable, because its components implement
a modified model-view-controller (MVC) pattern. In MVC,
implementation is separated into three different elements: a
model that represents the underlying object state, a view that
displays that state, and a controller which modifies that state.
The view is responsible for output only, while the controller
accepts the input. The model is invoked by the view to be read
and invoked by the controller to be modified. This means that
a single object could have different views and be modified by
more than one type of input. In Swing, the model and view
are combined into a single thing known as the UI delegate.

Programming in Java184

In other words, a button doesn’t have to resemble a standard
rectangle or behave in the same way as every other button. A
button could be circular, transparent, or accept input via a
mouse drag rather than a mouse click. In Swing, the only
limitations are your imagination and the expectations of
your users!

Containers and Layout Managers

Swing takes advantage of the concept of containership.
Components aren’t lone elements, but placed within other
elements, similar to placing smaller boxes within larger
boxes. Top-level containers are at the top of the hierarchy
and can’t be placed into other containers. The JWindow,
JDialog, and JFrame containers are used for stand-alone
applications, while the JApplet container is intended for
Swing-based applets. The JFrame container is a standard
application window, but JWindow and JDialog are intended for
customized windows and dialogs that don’t contain standard
interface elements.

Each top-level container defines a set of dividers known as
panes. The top pane in the hierarchy is the JRootPane. You
can manually divide the interface further by using the JPanel
class. A layout manager controls how components and sub-
panes are arranged in a pane. To specify a layout manager,
you use the setLayout() method. You can choose from many
different layout manager classes.

The simplest layout manager is FlowLayout (Figure 12).
Components are laid out from left to right or right to left and
top to bottom, based upon the available size in the container.
Components can be aligned horizontally by center, left or
right. A pixel amount can be specified for the horizontal and
vertical gap between components. This is the default layout
manager for JPanel objects.

Figure 12—FlowLayout
Example

Lesson 5 185

The next layout manager is GridLayout (Figure 13).
Components are laid out by row and column, where each
component expands to fit its destination cell. Like
FlowLayout, you can also specify a horizontal and vertical
gap between cells.

Another simple layout manager is BorderLayout (Figure 14).
With this layout manager, the panel is divided into five different
regions: PAGE_START, PAGE_END, LINE_START,
LINE_END, and CENTER. Components inserted into the
PAGE_START and PAGE_END regions will have the preferred
height, but expand to fit the width of the panel. Components
inserted into the LINE_START and LINE_END regions will
have the preferred width, but expand to fit the height of the
panel. Components in the CENTER region will expand to fill
any empty regions. You can also specify a horizontal and ver-
tical gap between cells.

A more complex layout manager is GridBagLayout (Figure 15).
Like GridLayout, the panel is divided into rows and columns.
Unlike GridLayout, rows and columns can be different sizes
and cells can span more than a single row or column. Also,
you can ensure components use preferred widths and heights
by specifying sizing constraints.

Figure 13—GridLayout
Example

Figure 14—
BorderLayout
Example

Figure 15—GridBagLayout

Programming in Java186

BoxLayout (Figure 16) is a more flexi-
ble version of FlowLayout. Like
FlowLayout, controls are either
stacked vertically or lined up horizon-
tally. The Box class provides custom
fillers known as struts to provide hori-
zontal gaps between components and
glue to create automatic space that
grows vertically or horizontally. Rigid
areas are fixed elements that can fill
space both vertically and horizontally.

CardLayout is a layout manager that allows you to stack
groups of components on top of each other. Because
CardLayout only allows switching between groups using a
combo box, the JTabbedPane component is the preferred
technique for organizing groups of controls. To use the
JTabbedPane component, you add components to a JPanel
and then add that JPanel as a tab (Figure 17).

The other layout managers like GroupLayout and
SpringLayout are intended for IDEs with visual designers. If
you add a Swing GUI Form such as JDialog, JFrame,
JPanel, or JApplet to a NetBeans project, then you can use
either of these layout managers to click and drag components
from a toolbox onto a visual designer (Figure 18). You can
also place components using absolute positioning as well.

Figure 16—BoxLayout Example

Figure 17—JTabbedPane
Example

Lesson 5 187

Swing Components

All Swing components are derived from the JComponent
class, including JFrame. The table on page 507 of the text-
book lists common Swing components, some of which are
containers themselves. To add a component to a container,
you need only invoke its add() method; to remove it, you use
the remove() method. If using a layout manager that requires
additional information on where to place the component,
such as BorderLayout and GridLayout, you should specify
those arguments as well.

The following code adds a button to a JFrame using
BorderLayout:

frame.add( new JButton(“Button 1”),
BorderLayout.PAGE_START);

Figure 18—NetBeans Visual Designer

Note: You’re not expected
to use the NetBeans
visual designer for proj-
ects or activities. If
you’re familiar with
GUI-based interface
design, then you’re wel-
come to use the visual
designers in NetBeans
to reduce the amount
of code you type.

Programming in Java188

As for JFrame properties, its constructor can accept a String
for its window title and GraphicsConfiguration for the device
screen. The setSize() method will set the width and height of
the window in pixels, while the setVisible() method is
required to display the window. By default, closing a JFrame
won’t stop the application from running. To change this
behavior, invoke the setDefaultCloseOperation() method
with the EXIT_ON_CLOSE constant.

Event handlers in Swing use a special thread known as the
event dispatcher. To launch a JFrame object from the main()
method so that it uses the event dispatcher thread, rather
than the main thread, you should use the invokeLater() or
invokeAndWait() methods from the SwingUtilities class. The
invokeLater() method is intended for the initial load in
standalone applications, while the invokeAndWait() is used
for UI updates when outside the event dispatcher thread and
is intended for applets.

The following code uses an anonymous inner class that
implements Runnable to instantiate JFrame:

SwingUtilities.invokeLater( new Runnable () {
public void run() { new CustomJFrame(); }

});

Read through pages 515–530 in your textbook for an intro-
duction to the JButton, JTextField, JCheckBox, and JList
components. Other common Swing components you’ll probably
use include JTextArea, JComboBox, JMenuBar, JSpinner,
and JSlider. You can visit the Java tutorials on Oracle’s web-
site for usage details on other important Swing components:
http://tinyurl.com/cu69r87

Notice that Swing components use the same event delegation
model you learned for AWT-based applets.

Activity 19: Create a Line
Drawing Application with Swing

1. Create a new Java Application project named
Lesson5Activity19 in NetBeans.

2. Replace the contents of Lesson5Activity19.java with the
following code:

Lesson 5 189

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class Lesson5Activity19 extends JFrame {
ArrayList drawPoints = new ArrayList<>();
Color penColor = Color.BLACK;
private Lesson5Activity19() {
//initialize
PaintComponent comPaint = new PaintComponent();
comPaint.setBackground(Color.WHITE);
comPaint.setSize(300, 300);
JPanel panButton = new JPanel();
panButton.setLayout(new GridLayout(4,0));
//create buttons
JButton btnBlack = new JButton(“Black”);
btnBlack.setForeground(Color.WHITE);
btnBlack.setBackground(Color.BLACK);
panButton.add(btnBlack);
JButton btnRed = new JButton(“Red”);
btnRed.setForeground(Color.BLACK);
btnRed.setBackground(Color.RED);
panButton.add(btnRed);
JButton btnGreen = new JButton(“Green”);
btnGreen.setForeground(Color.BLACK);
btnGreen.setBackground(Color.GREEN);
panButton.add(btnGreen);
JButton btnBlue = new JButton(“Blue”);
btnBlue.setForeground(Color.BLACK);
btnBlue.setBackground(Color.BLUE);
panButton.add(btnBlue);
//add listeners
MouseHandler mh = new MouseHandler();
comPaint.addMouseListener(mh);
ActionHandler ah = new ActionHandler();
btnBlack.addActionListener(ah);
btnRed.addActionListener(ah);
btnGreen.addActionListener(ah);
btnBlue.addActionListener(ah);
this.setLayout(new BorderLayout());
this.add(comPaint, BorderLayout.CENTER);

Programming in Java190

this.add(panButton, BorderLayout.LINE_END);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setTitle(“Lines with Swing”);
this.setSize(350, 300);
this.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater( new Runnable () {

public void run() { new Lesson5Activity19(); }
});
}
//inner classes
private class PaintComponent extends JComponent {
public void paint(Graphics g) {

g.setColor(penColor);
for (int i = 1; i < drawPoints.size(); i ++) {

g.drawLine(drawPoints.get(i-1).x, drawPoints.get(i-1).y,
drawPoints.get(i).x, drawPoints.get(i).y);

}
}
}
private class MouseHandler extends MouseAdapter {
public void mousePressed(MouseEvent me) {

drawPoints.add(new Point(me.getX(), me.getY()));
}
public void mouseReleased(MouseEvent me) {

drawPoints.add(new Point(me.getX(), me.getY()));
repaint();

}
}
private class ActionHandler implements ActionListener {
public void actionPerformed(ActionEvent ae) {

JButton button = (JButton) ae.getSource();
penColor = button.getBackground(); //Set to button back-

ground color
}
}
}

Lesson 5 191

Look carefully at this code. It uses a two-panel layout to
display a custom component for drawing and a panel for
color buttons. When you click on two different places in
the drawing panel, a line is drawn between the two points,
connecting any previous points as well. The buttons
change the color of these lines.

3. Build and run the project. Once you get the hang of it,
try customizing the application to draw other shapes.

Applets with Swing

How different is it to create a Swing-based applet than an
AWT-based applet? Only two main differences exist. First,
the Swing-based applet must be a subclass of JApplet,
rather than Applet. Second, the UI is built on the event dis-
patcher thread by invoking the
SwingUtilities.invokeAndWait() method. Because JApplet is
a subclass of Applet, the lifetime methods init(), start(),
stop(), and destroy() are the same.

The example code on pages 537–538 demonstrates a Swing-
based applet. It should look very recognizable to you, combining
what you learned about applets and Swing in one place.

JavaFX

Although Swing-based applications are still very common, the
next generation of Java GUI applications is using JavaFX
(Figure 19). JavaFX provides rich graphics and robust anima-
tion support for applications that are designed to run across
traditional desktop, mobile, and embedded platforms. The API
for JavaFX is very similar to Swing in many respects, but it
provides a greater range of visual customization and multi-
media support. All UI classes and interfaces for JavaFX are
located in the javafx package, and no implementation is
reused from AWT or Swing.

Programming in Java192

JavaFX applications extend the Application class and use their
start() method as the main entry point. Content is stored on
a stage, divided by scenes and further by frames. JavaFX also
supports standard Web technologies such as HTML and CSS
(Cascading Style Sheets) for content and styling.

Although a more thorough discussion on JavaFX is outside
this course, the NetBeans IDE contains a few samples for
JavaFX applications that you can run and modify to become
more familiar. You can also visit the JavaFX documentation
provided by the Oracle website at http://docs.oracle.com/
javafx/index.html for detailed tutorials and step-by-step
exercises.

Figure 19—Colorful Circles
Sample Project for JavaFX

Lesson 5 193

Self-Check 15

1. How does Swing differ from AWT?

__________________________________________________________

2. What is the MVC pattern and how does Swing modify it?

__________________________________________________________

3. Which layout manager is optimal for a table-like layout that allows components to expand
more than one column or row?

__________________________________________________________

4. Which method must you use to instantiate a JFrame object? Which method must you
invoke on a JFrame object for it to display?

__________________________________________________________
__________________________________________________________

5. How does JavaFX differ from Swing?

__________________________________________________________

Check your answers with those on page 207.

Programming in Java194

NOTES

Graphical User Interface

OVERVIEW

Now you’ll develop a graphical user interface for the
TicTacToe game. This project will assess your understanding
of AWT, Swing, and event handling.

Make sure that you follow all directions completely and verify
your results before submitting the project. Remember to include
all required components in your solution.
YOUR PROJECT

In this project, you’ll create the GUI front-end for the TicTacToe
game. This application will leverage the classes you wrote in
the graded project for Lesson 3. You’ll copy code from Graded
Project 3 for this project.

Figure 20 is a guide for the completed user interface.

195
G
ra
d
e
d
P
ro
je
c
t
G
ra
d
e
d
P
ro
je
c
t

FIGURE 20—The Completed
Tic Tac Toe Game

Graded Project196

INSTRUCTIONS

1. In NetBeans, create a new Java Application project
named TicTacToeGUIGame.

2. Copy the games.board package from the Lesson 3 proj-
ect named BoardGameTester.

■ Right-click on the game.board package in the
BoardGameTester project of the Projects pane
panel.

■ Choose the Copy option from the context menu or
use the keyboard shortcut CTRL+C.

■ Paste it in the TicTacToeGUIGame project using the
Paste option in the context menu or the keyboard
shortcut CTRL+V.

Make sure to copy and paste the package in the Source
Packages folder.

3. In the Cell.java file, have the Cell class extend the
JButton class. This action will ensure that each cell on
the board has the look and feel of a standard Java button.

4. Override the paintComponent method in the Cell class
as follows:

public void paintComponent(Graphics g) {

//paint the basic button first

super.paintComponent(g);

int offset = 5;

Graphics2D g2 = (Graphics2D) g;

g2.setStroke(new BasicStroke(5));

switch(content) {

case NOUGHT:

g2.setColor(Color.RED);

//Draw O

g2.drawOval(offset, offset, this.getWidth() – offset * 2, this.getHeight() – offset * 2);

break;
case CROSS:

g2.setColor(Color.BLACK);

//Draw X

Graded Project 197

Note: This code uses the enhanced Graphics2D class
to set the stroke thickness to more than one pixel. The
Oracle documentation provides more guidance on creat-
ing complex geometric shapes using the Graphics2D
class at http://docs.oracle.com/javase/tutorial/2d/
geometry/index.html. Remember to import the
java.awt and javax.swing packages!

5. In the Board.java file, have the Board class extend the
JPanel class. This action will ensure that the board can
lay out each cell and process its UI events.

6. Make the following modifications to the Board constructor:

These changes will add each cell to the UI and assign an
ActionListener object to each cell.

Note: Remember to import the java.awt, java.awt.event,
and javax.swing packages.

7. In the TicTacToeGUIGame.java file, have the
TicTacToeGUIGame class extend JFrame. This action
will ensure that the game is hosted in a Java window.

8. Import the games.board, java.awt, and javax.swing
packages.

g2.drawLine(offset, offset, this.getWidth() – offset , this.getHeight() – offset );

g2.drawLine(this.getWidth() – offset, offset , offset, this.getHeight()- offset);

break;
}
}

public Board(int rows, int columns, ActionListener ah) {
cells = new Cell[rows][columns];
this.setLayout(new GridLayout());
for( int r = 0; r < cells.length; r++ ) {

for (int c = 0; c < cells[r].length; c++) { cells[r][c] = new Cell(r,c); this.add(cells[r][c]); cells[r][c].addActionListener(ah);

}
}
}

Graded Project198

9. Add the following code to the main method:

SwingUtilities.invokeLater( new Runnable () {
public void run() { new TicTacToeGUIGame(); }
});

10. Declare the following instance variables in
TicTacToeGUIGame:

private Board gb;
private int turn;

11. Add the following method to handle each turn:

private void takeTurn(Cell c) {
Mark curMark = (turn++ % 2 == 0)? Mark.NOUGHT
: Mark.CROSS;
gb.setCell(curMark, c.getRow(), c.getColumn());
}

12. Define the following constructor to create the board,
provide the event listener, and display the board in
the window:

private TicTacToeGUIGame() {
gb = new Board(3, 3, new ActionListener() {
public void actionPerformed(ActionEvent ae) {
Cell c = (Cell) ae.getSource();
takeTurn(c);
}
});
this.add(gb);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setTitle(“TIC-TAC-TOE”);
this.setSize(300, 300);
this.setVisible(true);
}

13. Compile and run the project. Test to make sure each
button displays a nought or cross when clicked.

Graded Project 199

SUBMISSION GUIDELINES

To submit your project, you should submit the final JAR file:

TicTacToeGUIGame.jar

To ensure the JAR file is built, you should click the Build
button or hit the F11 key.

To find the JAR file with NetBeans, go to the
TicTacToeGUIGame project folder. To determine this folder,
right-click on TicTacToeGUIGame project in the Projects
panel. Copy the value for the Project Folder textbox using
the keyboard shortcut CTRL+C. In Windows Explorer, paste
the project folder path and hit the ENTER key. Copy the
TicTacToeGUIGame.jar file from the dist folder to your desktop
or any other temporary location.

Follow this procedure to submit your project online:
1. Log on to the Penn Foster website and go to My Courses.
2. Click Take Exam.

3. Attach your file as follows:

a. Click on the Browse box.
b. Locate the file you wish to attach.
c. Double-click on the file.
d. Click Upload File.

4. Enter your e-mail address in the box provided. (Note: This
information is required for online submissions.)

5. If you wish to tell your instructor anything specific
regarding this assignment, enter it in the Message box.
6. Click Submit File.

Graded Project200

Grading Criteria
Your instructor will use the following guidelines to grade
your project.

Cell class is modified correctly 20 points

Board class is modified correctly 20 points

The game window displays correctly 20 points

The buttons behave correctly when clicked 20 points

JAR file is provided: 20 points

TOTAL 100 points

201

A
n

s
w

e
r

s
A
n
s

w
e

r
s

Self-Check 1
1. Procedural programming languages use step-by-step

instructions, while object-oriented programming (OOP)
languages model real-world structures and relationships.
Procedural programming languages separate data and
instructions, but object-oriented languages combine
them into fields and methods of objects.

2. A Java application that’s written and compiled can run
on any platform with the Java Virtual Machine (JVM)
installed. The developer doesn’t need to write code for a
specific CPU, motherboard, chipset, or operating system.

Self-Check 2
1. Java Micro Edition (ME) is a configurable subset of Java

SE (Standard Edition), because it must support smaller,
embedded devices that can’t store all class libraries
found in SE.

2. The JDK (Java Development Kit) is required to write
applications, because it includes the compiler and
other developer tools. The JDK isn’t required to run Java
applications—only the JRE (Java Runtime Environment)
is needed. The JRE includes the JVM (Java Virtual
Machine), runtime commands and applications, and
essential class libraries.

Self-Check 3
1. The extension of a source code file is .java and the

command that compiles it is javac.

2. The extension of a bytecode file is .class and the com-
mand that runs it is java or javaw.

Self-Check 4
1. Primitive data types are built-in data types that are fixed

in size and stored only in the default memory stack.

2. Integers are whole numbers, while floating-point numbers
support fractional values. Floating-point numbers use
scale and precision to represent values, while integers
only reserve a dedicated sign bit.

3. You should use explicit casting for a data type when
moving values from a larger container into a smaller one.
The conversion could result in a loss of precision, so you
must use explicit casting.

4. The value of the result is 7.0. According to operator prece-
dence, the parenthetical subtraction will occur first
(5 – 10) to yield –5. Then, the modulus operator will be
used (15 % 7) to yield a remainder of 1. Next, the multi-
plication operation will be performed (1 * 10) to yield 10.
Remember the ^ operator is used for bitwise XOR opera-
tions, so it will be performed last. The addition operation
occurs next (–5 + 10) and yields 5. Finally, the XOR
operation compares 5 (0b101) to 2 (0b010) and yields 7
(0b111). The final result will be 7.0 because the result
variable is a double. For more on bitwise and shift oper-
ators, read pages 166–171 in Chapter 5 of the textbook.

5. The value of charVal is R. The toUpperCase() method
returns the String value as STRINGS OF JAVA. The
charAt() method with the 2 argument will return the
third character R.

Self-Check 5
1. The do-while statement executes at least once, because

the while expression isn’t evaluated until after the first
iteration.

2. The for statement uses an explicit counter to loop.

3. The break and continue statements. The break state-
ment exits out of an iterative loop, while the continue
statement skips to the next iteration.

Self-Check Answers202

Self-Check Answers 203

4. A method can return only one value. A method may not
return a value if its return type is void.

5. No arguments are required for a varargs parameter. Zero
or more arguments can be specified for a varargs parameter.

Self-Check 6
1. In Java, elements in an array must be the same data

type, the length of an array must be an int, and its
length is fixed and can’t be modified.

2. The length field returns the number of elements in the
array.

3. The index value 0 will return the first element in the
array, because arrays use zero-based indexing.

Self-Check 7
1. An exception is simply an abnormal condition that

occurs in a program. Some exceptions are errors from
which an application can’t recover, while others can be
handled by users or programmers to continue running
the application.

2. The try/catch blocks handle exceptions. The try block
contains code that might throw an exception, while the
catch block performs an action when the exception is
actually thrown.

3. The throws keyword is used in method declarations to
indicate that invoking the method will require dealing
with a specific exception, while the throw keyword is
used to manually throw an exception within a method.

Self-Check Answers204

Self-Check 8
1. Object references are stored in the memory heap and are

actually pointers to that object’s data, whereas primitive
types are stored on the memory stack and only contain
a value.

2. Encapsulation is designing an object so that its state
(fields) is protected from direct access and all interac-
tions with the object involve its behaviors (methods).

3. Instance members are unique to each object, whereas
class members affect all objects of a class.

4. A class is instantiated when the new keyword is used
and memory in the heap is reserved. An object is final-
ized when the garbage collector prepares to delete the
object from memory and invokes the finalize() method.

Self-Check 9
1. Inheritance is when one or more classes inherit code

from another class. The superclass contains the inher-
ited code, while its subclasses are those that receive the
inherited code.

2. The output is Sub print() because the print() method
is overridden in Subclass. Polymorphism dictates that
the actual method invoked depends on the type of the
object, not the reference type of its variable. Although the
variable obj is of type SuperClass, the actual object is of
type SubClass.

3. Abstract classes are those that can’t be instantiated but
can contain methods without definition code. Concrete
classes are subclasses that provide the definition for
abstract methods.

4. In Java, a package prevents naming conflicts between
classes and other types and provides an organized hier-
archy for data types.

Self-Check 10
1. The phrase “inheritance without the side effects” describes

how using interfaces ensures only the method declarations,
not the implementation details of each method, are
inherited by each class. Also, in class inheritance, there’s
tight coupling and only a single class can be inherited. In
interface implementation, there’s loose coupling and
multiple interfaces that can be implemented by a single
class.

2. Abstract classes can contain implementation and only
support single inheritance. Interfaces can’t contain
implementation, but support multiple inheritance.

3. An enumeration is a custom data type that contains a
limited set of named values.

Self-Check 11
1. Type wrappers are special classes that represent primi-

tive values, so that they can be stored, used, and passed
as objects.

2. Autoboxing is the automatic boxing of primitive types
into objects and unboxing of objects into primitive types.
This is provided by the runtime without requiring manual
boxing or unboxing with type wrapper methods.

3. Only those object types that implement the generic
Comparable interface are allowed for both the array
and elem parameters.

Self-Check 12
1. A byte stream reads/writes un-encoded data bytes, while

a character stream code/encodes that data. Buffered
streams wrap character streams so that characters can
read/write line by line, rather than character by character.

2. The read() method is standard for input streams which
retrieve data from a stream. The write() method is stan-
dard for output streams which modify data in a stream.

Self-Check Answers 205

3. System.in is the standard method for retrieving data using
the keyboard. System.out and System.err are used to
generate output for all-purpose and error text, respec-
tively.

4. Resource objects are automatically closed and derefer-
enced at the end of a try-with-resources block. If the
close() method throws an exception, then any other
exceptions thrown in the try-with-resources block will
be suppressed.

5. The Path interface represents the location of a file or
directory in the java.nio package.

Self-Check 13
1. A thread is a task performed by an application and can

be controlled by the programmer. A process is a unique
runtime environment for a running application that is
controlled by the OS.

2. You can either implement the Runnable interface
directly or extend the Thread class, which also imple-
ments the Runnable interface.

3. The Runnable interface provides a run() method that
can’t return a value, while the Callable interface provides
a call() method that can return a value.

4. The initial state is runnable after the start() method is
invoked for a thread.

5. The synchronized keyword allows access to a code block
or method by only one thread at a time.

Self-Check 14
1. An applet is a small GUI application embedded in a Web

page. Unlike stand-alone applications, applets can’t run
outside the browser and are placed in a security sandbox.

2. The paint() method should be overridden to create visual
elements for an AWT-based applet. The repaint() method
is invoked to update those visual elements.

Self-Check Answers206

3. The drawOval() method is used to paint the outline of a
circle, while the drawPolyline() is used to paint an open
shape.

4. The event source is the visual component or input device
on which an action occurs. The event listener is an object
that’s notified by the source when a type of action occurs
by receiving an event object.

5. An anonymous inner class is one that’s defined “on-the-fly”
without a name. The class definition is provided when an
object is instantiated, so that the class can’t be referenced
outside the object.

Self-Check 15
1. AWT relies heavily on native code for the visual elements,

while Swing uses pure Java components. Swing still uses
AWT for events and graphics, however.

2. In MVC, a model represents the underlying object state,
while the controller and view provide the input and out-
put for that state, respectively. Swing modifies the MVC
pattern by combining the controller and view into the UI
delegate.

3. The optimal layout manager would be GridBagLayout.
Cells can span more than a single row or column in this
layout manager.

4. To instantiate a JFrame object on the event dispatcher
thread, you should use the invokeLater() method. To
display the JFrame object, you should invoke the
setVisible() method, specifying true.

5. JavaFX provides a greater range of visual customization
and multimedia support and doesn’t rely on AWT imple-
mentations.

Self-Check Answers 207

Graded Project

Final Graded Project

OVERVIEW

1

YOUR PROJECT 1

SUBMISSION GUIDELINES 2

iii

C
o
n
t
e
n
t
s

C
o
n
t
e
n
t
s

1

OVERVIEW

Now that you’ve completed the study guide and required
textbook reading, you’re ready to finish the TicTacToe game
in the final project. You’ll add the application logic to handle
each turn and determine the outcome of the game.

Make sure that you follow all directions completely and verify
your results before submitting the project. Remember to include
all required components in your solution.

YOUR PROJECT

In this project, you’ll finish the GUI version of the Tic-Tac-Toe
game. This project will require you to rewrite the application
logic found in the graded project for Lesson 2, but using object
orientation this time. In the instructions, code will be refer-
enced from the previous graded projects.

Instructions

1. In NetBeans, open the TicTacToeGUIGame project.

2. In the TicTacToeGUIGame.java file, make the following
changes to the TicTacToeGUIGame class:

a. Add a new method named getOutcome that returns
an Outcome enumeration. Use the winOrTie
method in the Lesson 2 graded project as a guide.

b. In the takeTurn method, use the getOutcome
method to determine whether to continue the game.

Final Graded Project

c. In the takeTurn method, display a dialog message
that displays the winner or tie when the game ends.
Optionally, you can clear the board and start a new
game after it ends.

Note: You can use the following method to display a
dialog message in the current window:

JOptionPane.showMessageDialog (this, “Both players tie.”);

3. Build and run the project. Verify it works as expected.
Don’t be discouraged if it doesn’t run as expected right
away. Try tracing your steps and using System.out.write
statements to figure out where you went wrong.

SUBMISSION GUIDELINES

For your project, you should submit the final JAR file:

TicTacToeGUIGame.jar

To ensure the JAR file is built, you should click the Build
button or hit the F11 key.

To find the JAR file with NetBeans, you need to go to the
TicTacToeGUIGame project folder. To determine this folder,
right-click on TicTacToeGUIGame project in the Projects
panel. Copy the value for the Project Folder textbox using
the keyboard shortcut CTRL+C. In Windows Explorer, paste
the project folder path and hit the ENTER key. Copy the
TicTacToeGUIGame.jar file from the dist folder to your
desktop or any other temporary location.

Follow this procedure to submit your project online:

1. Log on to the Penn Foster website and go to My Courses.

2. Click Take Exam.

3. Attach your file as follows:

a. Click on the Browse box.

b. Locate the file you wish to attach.

c. Double-click on the file.

d. Click Upload File.

Graded Project Title2

4. Enter your e-mail address in the box provided. (Note:
This information is required for online submissions.)

5. If you wish to tell your instructor anything specific
regarding this assignment, enter it in the Message box.

6. Click Submit File.

Grading Criteria

Your instructor will use the following guidelines to grade
your project.

Application behaves as expected 40 points

GUI meets the requirements 30 points

File contains no syntax errors 30 points

TOTAL 100 points

Congratulations! You’ve completed a simple application
with a GUI. You could expand on this game by adding more
graphics or animation or develop a new game like Connect
Four or Mastermind.

Now, you are ready to take on the larger world of Java
development!

Graded Project # 3

Still stressed from student homework?
Get quality assistance from academic writers!

Order your essay today and save 25% with the discount code LAVENDER