Murach's Java Programming
Murach's Java Programming
mu rach's
programming
4™ EDITION
JOEL MURACH
AN OBJECT-ORIENTED BOOK
that shows you how ro use business classes,
inheritance, and interfaces the way they’re
used in the real world
murach's
programming
4th EDITION
Joel Murach
10 9 8 7 6 5 4 3 2 1
ISBN: 978-1-890774-65-3
Contents
Introduction XV
A ppendixes
Appendix A How to set up your PC for this book 771
Appendix B How to set up your Mac for this book 111
E x p a n d e d c o n te n ts
As you work with Java SE 7, please keep in mind that all Java versions are
backwards-compatible. That means that everything in this book will also work
with future versions of the JDK.
Introduction to Java
In 1996, Sun Microsystems released a new programming language called
Java. Although Oracle bought Sun in 2010, Java remains one of the most widely
used object-oriented programming languages.
Java timeline
Year Month Event
1996 January Sun releases Java Development Kit 1.0 (JDK 1.0).
1997 February Sun releases Java Development Kit 1.1 (JDK 1.1).
1998 December Sun releases the Java 2 Platform with version 1.2
of the Software Development Kit (SDK 1.2).
1999 August Sun releases Java 2 Platform, Standard Edition (J2SE).
December Sun releases Java 2 Platform, Enterprise Edition (J2EE).
2000 May Sun releases J2SE with version 1.3 of the SDK.
2002 February Sun releases J2SE with version 1.4 of the SDK.
2004 September Sun releases J2SE 5.0 with version 1.5 of the JDK.
2006 December Sun releases Java SE 6 with version 1.6 of the JDK.
2010 April Oracle buys Sun.
2011 July Oracle releases Java SE 7 with version 1.7 of the JDK.
Description
• Versions 1.2 through 1.4 of Java are called the Software Development Kit (SDK).
• Versions 1.5 through 1.7 of Java are called the Java Development Kit (JDK).
Note
• Java SE 8 with version 1.8 of the JDK is expected to be released late in 2012.
C:Smurach\jaua\classes>java Futurellalueflpp
Monthly Payment: 1100
Continue? <y/n>:
Calculate Exit
An applet
M ike Murach and Associates - Publisher o f Professional Program m ing Books - M ozilla Firefox
r
File Edit View
- c
H isto ry .Bookmarks
& □
Tools Help
□ Mil
M ike Murach and Associates - Publish...
_L·
A servlet
M ike Murach and Associates - Publisher o f Professional Program m ing Books - M ozilla Firefox
e ’ G & □ http://w w w .m urach .com /servlet/m u ra ch.fv.F utu re V a lu eS e ivle t * | |ÎJ ’ Google P
while (choice.equalsIgnoreCase(■y"))
{
// get the input from the user
System.out.print("Enter monthly investment: ");
double monthlylnvestment = sc.nextDouble();
System.out.print("Enter yearly interest rate: ");
double interestRate = sc.nextDouble();
System.out.print("Enter number of years: ");
int years = sc.nextlnt();
Figure 1-3 The code for the console version of the Future Value application
Section 1 Essential Java skills
Java IDE
W source code
Text editor (*.java files)
Java c<>mpiler |
1r
Description
• When you develop a Java application, you develop one or more classes.
• You can use a Java IDE or any text editor to create, edit, and save the source code
for a Java class. Source code files have the java extension.
• The Java compiler translates Java source code into a platform-independent format
known as Java bytecodes. Files that contain Java bytecodes have the class exten
sion.
• The Java interpreter executes Java bytecodes. Since Java interpreters exist for all
major operating systems, Java bytecodes can be run on most platforms. A Java
interpreter is an implementation of a Java virtual machine (JVM).
• Most modem web browsers can be Java enabled. This lets applets run within these
browsers. Oracle provides a tool known as the Java Plug-in that allows you to
specify the version of the Java interpreter that you want to use.
Description
• To develop Java applications, you typically use an Integrated Development Envi
ronment (IDE) like those listed above. All of these IDEs are either free or have free
editions.
File Edit View Navigate Source Refactor Run Debug P rofile Team Tools W ind ow Help C V Search (Ctrl+1)
f i ‘p I |Γ- ί 1 ; [<defaultconfig>
• Ϊ 1 0 S & '® -
1Projects <3 S InvoiceApp.java 3t| 111__IlzJlüH
B ~ & di02_Invoice 1m ® - a Ί ^ ^ ^ (D l ψ f» 1a ^ I « □ Im ^
Θ ·· 1jg Source Packages 1 H i m p o r t j a v a . u t i l .S c a n n e r,· *■
ß 'b L i <default package >
3 p u b l i c c l a s s I n v o ic e A p p
É)· g Libraries 4 f
S JDK 1,7 (Default) 5 p u b l i c s t a t i c v o id m a in ( S tr in g [ j arg s)
6 i
7 U. w elc o m e t i e u s e r t o t h e p r o g r a n , =
S S y s te m , o u t . p r i n t l n ( "W elcom e t o t h e I n v o i c e T o t a l C a l c u l a t o r " } ,·
9 S y s te m , o u t . p r i n t I n () ; rr · .:.· a tls r .ic l i
10
11 i f c r e a t e a S c a n n e r o b j e c t n a m e d 3C
12 S c a n n e r s c = new S c a n n e r ( S y s t e m . i n ) ;
13
14 /! p e rfo rm , i n v o i c e c a l c u l a t i o n s u n t i l c h o i c e i s n ' t e q u a l t o "y "
IS S t r i n g c h o ic e = " y" ;
16 w h i l e ( c h o i c e . e q u a ls T g n o r e C a s e ( !; ) )
17
IS f ! g e t th e i n v o i c e s u b t o t a l fro m t h e u s e r
19 S y s te m , o u t . p r i n t ( ' ' i n t e r s u b t o t a l : ") ;
20 d o u b l e s u b t o t a l = s c . r.e x tD o u b le ( ) ;
21
22 / / c a l c u l a t e th e d is c o u n t am ount and t o t a l
23 d o u b le d is c o u n t F e r c e n t= 0 .0 ;
24 i f ( s u b t o t a l >= 200}
25 d is c o u n tP e rc e n t = .2 ;
26 e l s e i f ( s u b t o t a l >= 100} *
05 111 INS
Description
• A NetBeans project consists of a top-level folder that contains the subfolders and
files for an application.
• The Source Packages subfolder contains the .java files that make up the project.
These files define classes that are later compiled into .class files.
• By default, a project consists of a single class that contains the main method. The
main method is the starting point for the application, and the class that contains it is
called the main class.
• The .java files that make up a project can be organized into one or more packages.
If you don’t specify a package for the main class when you create a project, it’s
stored in the default package.
• The Libraries subfolder contains the libraries that are available to your project.
These libraries contain the Java classes that you can use in your projects. By
default, you can use the classes in the JDK libraries.
• The folders, files, and libraries that make up a Java project are listed in the Projects
window. If this window isn’t visible, you can display it by using the
Window->Projects command. Then, you can expand and collapse the nodes in this
window by clicking on the plus and minus signs.
• You can display and work with the source code in a .java file in the code editor
window. For details, see figure 1-11.
Mac OS X note
• To enable right-clicking with Mac OS X, you can edit the system preferences for the
mouse.
An application that uses the Output window for input and output
Q ch02Jnvoîee - NetBeans IDE 7.0 l.°i® ba<J
File Edit View Navigate Source Refactor Run Debug P rofile Team Tools W ind ow Help Q .* Search (Ctrl+1)
‘p ~| I,—
! 1
f i ; [<defâulto)nfïg>
' ] Ï 1 0 S & '® -
: Projects , InvoiceApp.java Sä | (ZHJB®
IQ
Ξ ~® ch02_Invoice
ü - q H^ ^ <5® ^ a a Γ%» □ I& j
φ - £§ Source Packages
1 ( 3 i m p o r t j a v a . u c i l .S c a n n e r,·
Ô 'Ë t l <default package > 2
InvoiceADo.jsva 3 p u b l i c c l a s s I n v o ic e A p p
Θ·· g Libraries 4 {
§ JDK 1,7 (Default) 5 p u b l i c s t a t i c v o i d m a i n ( S t r i n g [] a r g s )
6Π {
71 ί ΐ welcome ·.·.= user το tie prograir,
S y s t e m . c r j c . p r i n t I n ( "W elcom e t o t h e I n v o i c e T o t a l C a l c u l a t o r " ) ;
S y s te m , o u t . p r i n t I n () ; ’ i r i s .-.ic 1 :.“ ?
©
I t c r e a t e a S c a n n e r o b j e c t n a m e d 3C
S c a n n e r s c = r.ew S c a n n e r ( S y s te m , in ) ;
: O u tp u t - ch 0 2 _ln v o ice (r u n )
w
Welcome tc the Invoice Total Calculator
Continue? {y/n): |
Description
• When you run an application that prints data to the console, that data is displayed
in the Output window.
• When you run an application that requests input from the console, the Output
window pauses to accept the input. Then, you can click in the Output window, type
the input, and press the Enter key.
• In addition to displaying output and accepting input, the Output window can
display other information. For example, it can display messages when the applica
tion is compiled, and it can display errors that are encountered when an application
is run.
Figure 1-8 How to use the Output window with a console application
Section 1 Essential Java skills
File Edit View Navigate Source Refactor Run Debug Profile Team Tools W in d o w H elp (V Search (Ctrl+1) Ί
fh Θ Q l % l * D 0 1 '■ i<£tefeultronfig> Ί ^ ! I t ® ’
1 ill J N s jl
Description
• NetBeans lets you open and work with two or more projects at the same time.
• When you work with two or more projects, you can set one project as the main
project. To do that, right-click on the project and select Set as Main Project. Or,
when you open the project, select the Open as Main Project option.
• After you set a main project, you can run that project by pressing F6, by using the
Run->Run Main Project command, or by clicking the Run Main Project button in
the toolbar. The Run Main Project command and toolbar button replace the Run
Project command and toolbar button when a main project is set.
• To run a project other than the main project, right-click on the project and select the
Run command, or right-click on the file that contains the main method you want to
run and select the Run File command.
• If you don’t set a main project, you can run any project by selecting that project in
the Projects window and then using standard techniques.
description:
C re a te s a n e w J a v a SE a p p lic a tio n in a standard IDE project, You can also aenerate a main class
in the project. Standard p rojects use a n ID F g e n e r a te d A n t build s c rip t to build, run, and debug
your project,
S teps N a m e an d Location
Description
• To create a new project, use the File->New Project command or click the New
Project button in the toolbar to display the New Project dialog box. Then, select a
project type, click the Next button and complete the dialog box that’s displayed.
• To create a Java Application project, enter the project name and location and the
name you want to use for the main class. You can also enter the name of the
package that will contain the main class, but that’s not necessary.
Categories:
,-■· 0 Sources Java Platform: JDK 1.6 T Manage Platforms...
i... 0 Libraries
Libraries Folder : Browse,..
a -® Build
s Compiling
Compile Processor | Run | Compile Tests | Run Testsj
0 Packaging
9 Documenting Compile-time Libraries:
I...o Run
Add Project...
a·· o Application
0 Web Start Add Library...
:..0 Formatting
Add JAR/Folder
I Q Project Properties - ch O l.T e st
Categories:
Move Up
Encoding: UTF-6
Cancel Help
Description
• The Project Properties dialog box lets you set various properties that affect the
project. To display this dialog box, right-click on the project in the Projects window
and select the Properties command.
• To set the version of the Java language and compiled bytecodes the project uses,
select the version from the Source/Binary Format drop-down list in the Sources
category. Then, the compiled bytecodes for the project will run under this version
of Java and later. In addition, the project can only use language features for the
specified version of Java.
• To set the version of the JDK libraries that are available to the project, select the
version from the Java Platform drop-down list in the Libraries category. Then, your
project can only use the features that are available from that version of the JDK
libraries. For this to work, the version of the JDK you want to use must be installed
on your system.
• To be sure that the JDK libraries are compatible with the language features and
bytecodes, select the same version of the JDK from the Java Platform and the
Source/Binary Format drop-down lists.
Figure 1-11 How to set the Java version for a project
Section 1 Essential Java skills
Net Bean’s code editor with the starting source code for a project
Çjjjc h O l J e s t - NetBeans IDE 7,0 I 1
File Edit View Navigate Source Refactor Run Debug Profile Team Tools W ind ow H elp Q ? Search {Ctrl+1)
B l® j
a -0 chQl_Test »
1 □ -
©· I £3 Source Packages * To c h a n g e t h i s t e i r p l a t e , c h o o e e T o o l s 1 T e m p la te s -
2
! B - M <default package > 3 • a n d a c e r. t h e t e m p l a t e i n t i e e d i t o r .
I ·"■|cSft TestApp.java 4
(3- g Libraries 5
É - @ ] JDK 1.7 (Default) 6 Ξ /**
7 *
8 ■ 0 - a o th o r A n c e
9 *!
10 p u b lic c la s s T e s tA p p {
11
12 □ / -
13 * S p a re rn a r g s t h e CBMmana l i n e a r g u m e n ts
14 L *!
15 3 p u b l i c s t a t i c v o i d m a i n ( S t r i n g [] a r g s ) ί
16 ! ! TODC c o d e a p p l i c a t i o n l o a x c h e r e
17 L >
IS }
19
111 INS
Description
• To open a .java file in the code editor, double-click on it in the Projects window. Then,
you can use normal editing techniques to work with the source code.
• To collapse the code for a method or comment, click the minus sign (-) to its left. Then,
a plus sign (+) appears to the left of the method or comment, and you can click the plus
sign to display the code again.
• To save the source code for a file, use the File->Save command (Ctrl+S) or click the
Save All Files button in the toolbar. This automatically compiles the file so it doesn’t
have to be compiled when the project is run.
• To rename a file, right-click on it, select the Refactor-^ Rename command, and enter the
new name in the resulting dialog box.
• To delete a file, you can right-click on it, select the Delete command, and confirm the
deletion in the resulting dialog box.
Figure 1-12 How to work with Java source code and files
Section 1 Essential Java skills
G p r i n t l n ( b o o le a n x) v o id
G p r i n t l n (c h a r x ) v o id
G p r i n t l n (c h a r [] x ) v o id
îava.io.PrintStream
p u b l i c v o i d p r i n t l n ( S tr in g , x)
Prints a S tring and then term in ate the line. T h is m ethod behaves as though it invokes INS
P r in t s t r e a m . p r i n t ( S t r i n j ] and then P ri n tS t re am. p r i n t I n 1) ■
P a ra m e te rs :
x - T he s t r i n g to be printed.
Description
• You can use the code completion feature to help you enter the names of classes and
objects and select from the methods and fields that are available for a class or
object.
• To activate the code completion feature for entering a class or object name, press
Ctrl+Spacebar after entering one or more letters of the class or object name. Then,
a list of all the classes and objects that start with those letters is displayed.
• To activate the code completion feature for a method or field of a class or object,
enter a period after a class or object name. Then, a list of all the methods and fields
for that class or object is displayed.
• To insert an item from a code completion list, select the item and then press the
Enter key. If the item requires parentheses, they’re added automatically. If the item
requires one or more arguments, default values are added for those arguments and
the first argument is highlighted so you can enter its value. Then, you can press the
Tab key and enter the values for any remaining arguments.
• If you enter the opening quote for a string value, the code completion feature
automatically adds the closing quote and places the cursor between the two quotes
so you can enter a value.
Description
• NetBeans often detects syntax errors as you enter code into the code editor.
• When NetBeans detects a syntax error, it displays a red error icon to the left of the
statement in error and it places a red wavy line under the statement.
• To get more information about a syntax error, you can position the mouse pointer
over the error icon. Or, you can move the cursor to the line that contains the error
and press Alt+Enter.
Perspective
In this chapter, you were introduced to Java, and you learned how to use
NetBeans to create and run a Java application. With that as background, you’re
ready to learn how to write your own Java applications. But first, I recommend
that you familiarize yourself with NetBeans by doing the exercises at the end
of this chapter.
Summary
• You use the Java Development Kit (JDK) to develop Java applications. This used
to be called the Software Development Kit (SDK) for Java.
• As of version 6, the Standard Edition (SE) of Java is called Java SE. In older
versions, it was called the Java 2 Platform, Standard Edition (J2SE).
• You can use Java SE to create applications (also known as desktop applications)
that run on your computer and a special type of Internet-based application known
as an applet.
• A desktop application can use a graphical user interface (GUI) or a console to
display output and get user input. Applications that use a console to interact with
the user are known as console applications.
• You can use the Enterprise Edition (EE) of Java, which is known as Java EE, to
create server-side applications using servlets and JavaServer Pages (JSPs).
• The Java compiler translates source code into a platform-independent format
known as Java bytecodes.
• Any machine that has a Java interpreter installed on it can be considered an
implementation of a Java virtual machine (JVM).
• An Integrated Development Environment (IDE) such as NetBeans can make
working with Java easier.
• In NetBeans, a project is a folder that contains all of the files that make up an
application.
• Java code is stored in classes. To organize multiple classes, you can store them in
packages.
• The main class of an application is the class that contains the main method, which
is the starting point of the application.
• If an application prints text to the console, NetBeans displays the text in the Output
window. NetBeans also allows you to enter input into the Output window.
• When multiple projects are open, NetBeans identifies the main project by
boldfacing its name in the Projects window.
• You can use the NetBeans code editor to enter and edit code. As you enter code,
you can use the code completion feature to help you enter the names of classes and
objects and select from fields and methods.
Chapter 1 How to get started with Java and NetBeans
3. Modify the generated code for the TestApp class so it looks like this (type
carefully and use the same capitalization):
public class TestApp
{
public static void main(String[] args)
{
System.out.println(
"This Java application has run successfully.");
}
}
4. Press F6 to compile and run the application. This should display “This Java
application has run successfully.” in the Output window.
Use the code completion feature
5. Enter the statement that starts with System, out again, right after the first
statement. This time, type “sys” and then press Ctrl+Spacebar. Then, use the
code completion feature to select the System class, and complete the
statement.
6. Enter this statement a third time, right after the second statement. This time,
type System, enter a period, and select out from the list that’s displayed. Then,
enter another period, select println(String x), and complete the statement. You
should now have the same statement three times in a row.
7. Run the application again to see that the message is displayed three times in a
row in the Output window.
Introduce and correct a syntax error
8. In the code editor window, delete the semicolon at the end of the first println
statement, and NetBeans will display an error icon to the left of the statement.
9. Correct the error, and NetBeans will remove the error icon.
10. Use the File->Save command (Ctrl+S) to save the changes.
2
Introduction
to Java programming
Now that you know the basic skills for using NetBeans to work with Java
projects, the quickest and best way to learn Java programming is to do Java
programming. That’s why this chapter shows you how to write complete Java
programs that get input from a user, make calculations, and display output.
When you finish this chapter, you should be able to write comparable programs
of your own.
Description
• Java statements direct the operations of a program, while comments are used to help
document what the program does.
• You can start a statement at any point in a line and continue the statement from one
line to the next. To make a program easier to read, you should use indentation and
extra spaces to align statements and parts of statements.
• Most statements end with a semicolon. But when a statement requires a set of braces
{ }, the statement ends with the right brace. Then, the code within the braces can be
referred to as a block of code.
• To code a single-line comment, type // followed by the comment. You can code a
single-line comment on a line by itself or after a statement. A comment that’s coded
after a statement is sometimes called an end-of-line comment.
• To code a block comment, type /* at the start of the block and */ at the end. You can
also code asterisks to identify the lines in the block, but that isn’t necessary.
Valid identifiers
InvolceApp $orderTotal 1
Invoice _orderTotal X
InvolceApp2 inputstring TITLE
subtotal gettotal MONTHS PER YEAR
di scountPercent $ 64 Valid
Keywords
boolean if interface class true
char else package volatile false
byte final swi tch while throws
float private case return native
void protected break throw implements
short public default try import
double static for catch synchronized
int new continue finally const
long this do transient goto
abstract super extends instanceof null
Description
• An identifier is any name that you create in a Java program. These can be the
names of classes, methods, variables, and so on.
• A keyword is a word that’s reserved by the Java language. As a result, you can’t use
keywords as identifiers.
• When you refer to an identifier, be sure to use the correct uppercase and lowercase
letters because Java is a case-sensitive language.
}
The rules for naming a class
• Start the name with a capital letter.
• Use letters and digits only.
• Follow the other rules for naming an identifier.
Description
• A Java application consists of one or more classes that start with a class declaration. You
write the code for the class within the opening and closing braces of the declaration.
• The public and private keywords are access modifiers that control what parts of the
program can use the class. Most classes are declared public, which means that the class
can be used by all parts of the program.
• The file name for a class is the same as the class name with java as the extension.
• A method is a block of code that performs a task.
• Every Java application contains one main method that you can declare exactly as shown
above. This is called the main method declaration.
• The statements between the braces in a main method declaration are run when the pro
gram is executed.
Examples
int scoreCounter = 1; // initialize an integer variable
double unitPrice = 14.95; // initialize a double variable
Description
• A variable stores a value that can change as a program executes.
• Java provides for eight primitive data types that you can use for storing values in
memory. The two that you’ll use the most are the int and double data types. In the
next chapter, you’ll learn how to use the other primitive data types.
• The int data type is used for storing integers (whole numbers). The double data
type is used for storing numbers that can have one or more decimal places.
• Before you can use a variable, you must declare its data type and assign an initial
value to the variable. It’s common to initialize integer variables to 0 and double
variables to 0.0.
• An assignment statement assigns a value to a variable. This value can be a literal
value, another variable, or an expression like the arithmetic expressions that you’ll
learn how to code in the next figure. If a variable has already been declared, the
assignment statement doesn’t include the data type of the variable.
// double arithmetic
double a = 8.5;
double b = 3.4;
double result5 = a + b; // results 11.9
double result6 = a - b; // résulte = 5.1
double result7 = a * b; // result7 = 28.9
double résulte = a / b; // résulte = 2.5
Description
• An arithmetic expression consists of one or more operands and arithmetic
operators.
• When an expression mixes the use of int and double variables, Java automatically
casts the int types to double types. To retain the decimal places, the variable that
receives the result must be a double.
• In the next chapter, you’ll learn how to code expressions that contain two or more
operators.
Description
• A string can consist of any characters in the character set including letters, num
bers, and special characters like *, &, and #.
• In Java, a string is actually a String object that’s created from the String class that’s
part of the Java API (.Application Programming Interface). The API provides all the
classes that are included as part of the JDK.
• To specify the value of a string, you can enclose text in double quotation marks.
This is known as a string literal.
• To assign a null value to a string, you can use the null keyword. This means that the
value of the string is unknown.
• To assign an empty string to a String object, you can code a set of quotation marks
with nothing between them. This means that the string doesn’t contain any
characters.
• To join (or concatenate) a string with another string or a data type, use a plus sign.
Whenever possible, Java will automatically convert the data type so it can be used
as part of the string.
• When you append one string to another, you add one string to the end of another.
To do that, you can use assignment statements.
• The += operator is a shortcut for appending a string expression to a string variable.
Result
Code : JSPS
Price: $49.50
Result
Joe Smith
Kate Lewis
Result
Type "x" to exit
Example 4: Backslash
String
"C:\\j ava\\files"
Result
C:\java\files
Description
• Within a string, you can use escape sequences to include certain types of special
characters.
Examples
double subtotal = sc.nextDouble(); // get a double entry from the console
String currentDate = now.toString(); // convert the date to a string
Examples
String sPrice = Double.toString(price); // convert a double to a string
double total = Double.parseDouble(userEntry); // convert a string to a double
Description
• When you create an object from a Java class, you are creating an instance of the
class. Then, you can use the methods of the class by calling them from the object.
• Some Java classes contain static methods. These methods can be called directly
from the class without creating an object.
• When you create an object from a class, the constructor may require one or more
arguments. These arguments must have the required data types, and they must be
coded in the correct sequence separated by commas.
• When you call a method from an object or a class, the method may require one or
more arguments. Here again, these arguments must have the required data types
and they must be coded in the correct sequence separated by commas.
• Although you can use the syntax shown in this figure to create a String object, the
syntax in figure 2-6 is the preferred way to do that. Once a String object is created,
though, you call its methods from the object as shown above.
• In this book, you’ll leam how to use dozens of the Java classes and methods. You
will also leam how to create your own classes and methods.
Incidentally, you can also use the syntax shown in this figure to create a
String object. However, the preferred way to create a String object is to use the
syntax shown in figure 2-6. Once a String object is created, though, you use the
syntax in this figure to call one of its methods. You’ll see examples of this later
in this chapter.
In the pages and chapters that follow, you’ll learn how to use dozens of
classes and methods. For now, though, you just need to focus on the syntax for
creating an object from a class, for calling a method from an object, and for
calling a static method from a class. Once you understand that, you’re ready to
learn how to import the Java classes you need for your programs.
Common packages
Package name Description
java.lang Provides classes fundamental to Java, including classes that work with
primitive data types, strings, and math functions.
java.text Provides classes to handle text, dates, and numbers.
java.util Provides various utility classes including those for working with collections.
java.io Provides classes to read data from files and to write data to files.
java.sgl Provides classes to read data from databases and to write data to databases.
java.applet An older package that provides classes to create an applet.
java.awt An older package called the Abstract Window Toolkit (AWT) that provides
classes to create graphical user interfaces.
java.awt.event A package that provides classes necessary to handle events.
javax.swing A newer package called Swing that provides classes to create graphical user
interfaces and applets.
Examples
import java.text.NumberFormat;
import java.uti1.Scanner;
import java.util.*;
import javax.swing.*;
Description
• The API for the Java SE provides a large library of classes that are organized into
packages.
• All classes stored in the java.lang package are automatically available to all Java
programs.
• To use classes that aren’t in the java.lang package, you can code an import state
ment as shown above. To import one class from a package, specify the package
name followed by the class name. To import all classes in a package, specify the
package name followed by an asterisk (*).
• If you don’t code an import statement for a class, you must qualify the class name
with the name of the package that contains it each time you refer to the class.
W S c a n n e r (Java P la tfo rm SE 7 )
Random java.lang.Object
ResourceBundle java.util.Scanner
Res oureeBunci e.ControI All Implemented Interfaces:
jScannen
ServiceLoader CloseaBle, AutoCloseable, lterator<S1ring*
SimpleTimeZone
Stack
StringTokencer p u b lic f in a l c la s s S can n er
Timer e x te n d s O b je c t
TimerTask iir.p ie rp .e n t3 I t e r a t o r < S t r i n g > , C lo s e a fc le
TimeZone
TreeMap A simple text scanner which can parse primitive types and strings using regular expressions.
TreeSet
UUID A S canner breaks its input into tokens using a delimiter pattern, which by default matches whitespace. The resulting
Vector tokens may then ce converted into values of different types using the various n e x t methods.
WeaKHashMap
For example, this code allows a userto read a number from S y ste m , in :
Enums
S c a n n e r s o = n ew S c a n n e r ( S y s t e m . i n ) ;
FormatterBigDecimalLayo i n c i = 3 C . nextlnc();
Locale.Category
E xcep tio n s As another example, this code allows lo n g types to be assigned from entries in a fileiryiiiurtoers:
ConcurrentModificationExc . S c a n n e r sc = new S c a n n e r (n ew F i l e ( ',rr.yNurr±;·er3', ) ) ;
Description
• The Java SE API contains thousands of classes and methods that can help you do
most of the tasks that your applications require.
• You can use a browser to view the Java SE API on the Internet by going to this
address:
http i//download.oracle.com/javaae/7/docs/api/index.html
• You can select the name of the package in the top left frame to display information
about the package and the classes it contains. Then, you can select a class in the
lower left frame to display the documentation for that class in the right frame.
• Once you display the documentation for a class, you can scroll through it or click
on a hyperlink to get more information.
• To make it easier to access the API documentation, you should bookmark the index
page. Then, you can easily redisplay this page whenever you need it.
Figure 2-10 How to use the API documentation to research Java classes
Section 1 Essential Java skills
}
The console output
f- ----- *
Welcome to the Invoice Total Calculator
Subtotal: 100.0
Discount percent: 0.2
Discount amount: 20.0
Total: 80.0
W- --------- J
Description
• Although the appearance of a console may differ from one system to another, you
can always use the print and println methods to print data to the console.
Figure 2-11 How to use the System.out object to print output to the console
Section 1 Essential Java skills
Description
• To create a Scanner object that gets input from the console, specify System.in in the
parentheses.
• When one of the next methods of the Scanner class is run, the application waits for
the user to enter data with the keyboard. To complete the entry, the user presses the
Enter key.
• Each entry that a user makes is called a token. A user can enter two or more tokens
by separating them with whitespace, which consists of one or more spaces, tab
characters, or return characters.
• The entries end when the user presses the Enter key. Then, the first next, nextlnt, or
nextDouble method gets the first token; the second next, nextlnt, or nextDouble
method gets the second token; and so on. In contrast, the nextLine method gets all
of the input or remaining input on the current line.
• If the user doesn’t enter the type of data that the next method expects, an error
occurs and the program ends. In Java, this type of error is called an exception.
You’ll leam more about this in chapter 5.
• Since the Scanner class is in the java.util package, you’ll want to include an import
statement whenever you use this class.
Note
• The Scanner class was introduced in version 1.5 of the JDK.
Figure 2-12 How to use the Scanner class to read input from the console
Section 1 Essential Java skills
// read a string
System.out.print("Enter product code: ");
String productCode = sc.nextO;
( Average: 93
Relational operators
Operator Name Description
== Equality Returns a true value if both operands are equal.
1- Inequality Returns a true value if the left and right operands
are not equal.
> Greater Than Returns a true value if the left operand is greater
than the right operand.
< Less Than Returns a true value if the left operand is less
than the right operand.
>= Greater Than Or Equal Returns a true value if the left operand is greater
than or equal to the right operand.
<= Less Than Or Equal Returns a true value if the left operand is less
than or equal to the right operand.
Examples
userEntry.equals("Y") // equal to a string literal
userEntry.equalsIgnoreCase("Y") // equal to a string literal
(llastName.equals("Jones")) // not equal to a string literal
code.equalsIgnoreCase(productCode) // equal to another string variable
Description
• You can use the relational operators to compare two numeric operands and return a
Boolean value that is either true or false.
• To compare two numeric operands for equality, make sure to use two equals signs.
If you only use one equals sign, you’ll code an assignment statement, and your
code won’t compile.
• If you compare an int with a double, Java will cast the int to a double.
• To test two strings for equality, you must call one of the methods of the String
object. If you use the equality operator, you will get unpredictable results (more
about this in chapter 4).
Description
• An if/else statement, or just if statement, always contains an if clause. In addition, it
can contain one or more else if clauses, and a final else clause.
• If a clause requires just one statement, you don’t have to enclose the statement in
braces.
• If a clause requires more than one statement, you enclose the block of statements in
braces.
• Any variables that are declared within a block have block scope so they can only be
used within that block.
Description
• A while statement executes the block of statements within its braces as long as the
Boolean expression is true. When the expression becomes false, the while state
ment skips its block of statements so the program continues with the next statement
in sequence.
• The statements within a while statement can be referred to as a while loop.
• Any variables that are declared in the block of a while statement have block scope.
• If the Boolean expression in a while statement never becomes false, the statement
never ends. Then, the program goes into an infinite loop. In NetBeans, you can
cancel an infinite loop by clicking on the Stop button in the Output window.
Continue? (y/n):
V --------- 1
The code for the application
import java.util.Scanner;
Enter score: 90
Enter score: 80
Enter score: 75
Enter score: 999
Score count: 3
Score total: 245.0
Average score: 81.66666666666667
V — 1
u> run.:
Welcome to the Invoice Total Calculator
H> ru n : >
Description
• A syntax or compile-time error occurs when a statement can’t be compiled. Before
you can test an application, you must fix the syntax errors.
• To test an application, you run it to make sure that it works properly no matter what
combinations of valid and invalid data you enter. The goal of testing is to find the
errors (or bugs) in the application.
• To debug an application, you find the causes of the bugs and fix them.
• One type of bug leads to a runtime error (also known as a runtime exception) that
causes the program to end prematurely. This type of bug must be fixed before
testing can continue.
• Even if an application runs to completion, the results may be incorrect due to logic
errors. These bugs must also be fixed.
Debugging tips
• For a runtime error, go to the line in the source code that was running when the
program crashed. In NetBeans, you can do that by clicking on the link to the line of
source code. That should give you a strong indication of what caused the error.
• For a logical error, first figure out how the source code produced that output. Then,
fix the code and test the application again.
Perspective
The goal of this chapter has been to get you started with Java program
ming and to get you started fast. Now, if you understand how the Invoice and
Test Score applications in figures 2-17 and 2-18 work, you’ve come a long
way. You should also be able to write comparable programs of your own.
Keep in mind, though, that this chapter is just an introduction to Java
programming. So in the next chapter, you’ll learn the details about working
with data. In chapter 4, you’ll learn the details about using control statements.
And in chapter 5, you’ll learn how to prevent and handle runtime exceptions.
Summary
• The statements in a Java program direct the operation of the program. The com
ments document what the program does.
• You must code at least one public class for every Java program that you write. The
main method of this class is executed when you run the class.
• Variables are used to store data that changes as a program runs, and you use
assignment statements to assign values to variables. Two of the most common data
types for numeric variables are the int and double types.
• A string is an object that’s created from the String class, and it can contain any
characters in the character set. You can use the plus sign to join a string with
another string or a data type, and you can use assignment statements to append one
string to another. To include special characters in strings, you can use escape
sequences.
• When you use a constructor to create an object from a Java class, you are creating
an instance of the class. There may be more than one constructor for a class, and a
constructor may require one or more arguments.
• You call a method from an object and you call a static method from a class. A
method may require one or more arguments.
• Before you use many of the classes in the Java API, you should code an import
statement for the class or for the package that contains it.
• You can use the methods of a Scanner object to read data from the console, and
you can use the print and println methods of the System.out object to print data to
the console.
• You can code if statements to control the logic of a program based on the true or
false values of Boolean expressions. You can code while statements to repeat a
series of statements until a Boolean expression becomes false.
• Testing is the process of finding the errors or bugs in an application. Debugging is
the process of locating and fixing the bugs.
Chapter 2 Introduction to Java Programming
2. Open the file named InvoiceApp.java. Review the code for this file and note
that NetBeans doesn’t display any errors.
3. Test this application with valid subtotal entries like 50,150,250, and 1000 so
it’s easy to see whether or not the calculations are correct.
4. Test the application with a subtotal value like 233.33. This will show that the
application doesn’t round the results to two decimal places. But in the next
chapter, you’ll learn how to do that.
5. Test the application with an invalid subtotal value like $1000. This time, the
application should crash. Study the error message that’s displayed and
determine which line of source code in the InvoiceApp class was running
when the error occurred. Then, jump to this line by clicking on the link to it.
6. Restart the application, enter a valid subtotal, and enter 20 when the program
asks you whether you want to continue. What happens and why?
7. Restart the application and enter two values separated by whitespace (like
1000 20) before pressing the Enter key. What happens and why?
3. Open the file named TestScoreApp.java and modify the while statement so
the program only ends when you enter 999. Then, test the program to see how
this works.
4. Modify the if statement so it displays an error message like “Invalid entry, not
counted” if the user enters a score that’s greater than 100 but isn’t 999. Then,
test this change.
Continue? (y/n): y
Continue? (y/n): n
Number of invoices: 2
Average invoice: 232.5
Average discount: 67.5
^
1. Open the project named ch02_ex3_Invoice that’s in the ex_starts directory.
Then, open the file named InvoiceApp.java.
2. Modify the code so the application ends only when the user enters “n” or “N”.
As it is now, the application ends when the user enters anything other than “y”
or “Y”. To do this, you need to use a not operator (!) with the
equalsIgnoreCase method. This is illustrated by the third example in figure
2-14. Then, compile this class and test this change by entering 0 at the
Continue prompt.
3. Modify the code so it provides a discount of 25 percent when the subtotal is
greater than or equal to 500. Then, test this change.
4. Modify the code so it displays the number of invoices, the average invoice
amount, and the average discount amount when the user ends the program.
Then, test this change.
Chapter 2 Introduction to Java Programming
Description
• A bit is a binary digit that can have a value of one or zero. A byte is a group of eight
bits. As a result, the number of bits for each data type is the number of bytes multi
plied by 8.
• Integers are whole numbers, and the first four data types above provide for integers of
various sizes.
• Floating-point numbers provide for very large and very small numbers that require
decimal positions, but with a limited number of significant digits. A single-precision
number provides for numbers with up to 7 significant digits. A double-precision
number provides for numbers with up to 16 significant digits.
• The double data type is commonly used for business programs because it provides
the precision (number of significant digits) that those programs require.
• The Unicode character set provides for over 65,000 characters with two bytes used
for each character.
• The older ASCII character set that’s used by most operating systems provides for 256
characters with one byte used for each character. In the Unicode character set, the
first 256 characters correspond to the 256 ASCII characters.
• A boolean data type holds a true or false value.
Technical notes
• To express the value of a floating-point number, you can use scientific notation like
2.382E+5, which means 2.382 times 105 (a value of 238,200), or 3.25E-8, which
means 3.25 times 10'8 (a value of .0000000325). Java will sometimes use this nota
tion to display the value of a float or double data type.
• Because of the way floating-point numbers are stored internally, they can’t represent
the exact value of the decimal places in some numbers. This can cause a rounding
problem in some business applications. Later in this chapter, you’ll learn how to use
the BigDecimal class to solve these rounding problems.
Example
int counter; // declaration statement
counter = 1 ; // assignment statement
Examples
int counter = 1; // initialize an int variable
double price = 14.95; // initialize a double variable
float interestRate = 8.125F; // F indicates a floating-point value
long numberOfBytes = 20000L; // L indicates a long integer
int population = 1734323; // initialize an int variable
int population = 1 7 3 4 3 2 3 ; // underscores improve readability
double distance = 3.65e+9; // scientific notation
char letter = Ά 1; // stored as a two-digit Unicode character
char letter = 65; // integer value for a Unicode character
boolean valid = false; // where false is a keyword
int x = 0, y = 0; // initialize 2 variables with 1 statement
Description
• A variable stores a value that can change as a program executes.
• Before you can use a variable, you must declare its data type and initialize it by
assigning a value to it. As default values, it’s common to initialize integer variables
to 0, floating-point variables to 0.0, and boolean variables to false.
• To declare and initialize more than one variable for a single data type in a single
statement, use commas to separate the assignments.
• To identify float values, you must type a n /o r F after the number. To identify long
values, you must type an I or L after the number.
Naming conventions
• Start variable names with a lowercase letter and capitalize the first letter in all
words after the first word.
• Try to use meaningful names that are easy to remember as you code.
Note
• The use of underscores in numeric literals was introduced in version 1.7 of the
JDK.
Examples
final int D A Y S I N N O V E M B E R = 30;
final float S A L E S T A X = .075F;
final double L I G H T Y E A R M I L E S = 5.879e+12
Description
• A constant stores a value that cannot change as a program executes.
• The skills for initializing variables also apply to constants.
Naming conventions
• Capitalize all of the letters in constants and separate words with underscores.
• Try to use meaningful names that are easy to remember.
Arithmetic operators
Operator Name Description
+ Addition Adds two operands.
- Subtraction Subtracts the right operand from the left operand.
* Multiplication Multiplies the right operand and the left operand.
/ Division Divides the right operand into the left operand. If both
operands are integers, then the result is an integer.
% Modulus Returns the value that is left over after dividing the right
operand into the left operand.
++ Increment Adds 1 to the operand (x = x + 1).
-- Decrement Subtracts 1 from the operand (x = x -1).
+ Positive sign Indicates that the value is positive.
- Negative sign Changes a positive value to negative, and vice versa.
double a = 8.5;
double b = 3.4;
double result9 = a + b; // result9 = 11.9
double resultlO = a - b; // resultlO = 5.1
double resultll = a * b; // resultll = 28.
double resultl2 = a / b; // resultl2 = 2.5
double resultl3 = a % b; // resultl3 = 1.7
double resultl4 = -a + b; // resultl4 = -5.
double resultl5 = --a; // resultl5 = 7.5
double resultl6 = ++b; // resultl6 = 4.4
// character arithmetic
char letterl = 'C1; // letterl = 'C' Unicode integer is 67
char letter2 = ++letterl; // letter2 = 1D 1 Unicode integer is 68
Description
• An arithmetic expression consists of operands and arithmetic operators. The first
five operators above are called binary operators because they operate on two
operands. The next four are called unary operators because they operate on just
one operand.
• An assignment statement consists of a variable, an equals sign, and an expression.
When the assignment statement is executed, the value of the expression is deter
mined and the result is stored in the variable.
Figure 3-4 How to code assignment statements and arithmetic expressions
Section 1 Essential Java skills
Assignment operators
Operator Name Description
= Assignment Assigns a new value to the variable.
+= Addition Adds the operand to the starting value of the variable
and assigns the result to the variable.
-= Subtraction Subtracts the operand from the starting value of the
variable and assigns the result to the variable.
*= Multiplication Multiplies the operand by the starting value of the
variable and assigns the result to the variable.
/= Division Divides the starting value of the variable by the
operand and assigns the result to the variable. If the
operand and the value of the variable are both
integers, the result is an integer.
%= Modulus Derives the value that is left over after dividing the
right operand by the value in the variable, and then
assigns this value to the variable.
Statements that use the same variable on both sides of the equals sign
count = count + 1 ; // count Is increased by 1
count = count - 1; // count is decreased by 1
total = total + 100.0; // total is increased by 100.0
total = total - 100.0; // total is decreased by 100.0
price = price * .8; // price is multiplied by .8
sum = sum + nextNumber; // sum is increased by value ofnextNumber
Statements that use the shortcut operators to get the same results
count + = 1 ; // count is increased by 1
count -= 1; // count is decreased by 1
total += 100.0; // total is increased by 100.0
total -= 100.0; // total is decreased by 100.0
price *= .8; // price is multipled by .8
sum += nextNumber; // sum is increased by the value of nextNumber
Description
• Besides the equals sign, Java provides for the five other assignment operators
shown above. These operators provide a shorthand way to code common assign
ment operations.
Description
• Unless parentheses are used, the operations in an expression take place from left to
right in the order o f precedence.
• To specify the sequence of operations, you can use parentheses. Then, the opera
tions in the innermost sets of parentheses are done first, followed by the operations
in the next sets, and so on.
• When you use an increment or decrement operator as a prefix to a variable, the
variable is incremented or decremented and then the result is assigned. But when
you use an increment or decrement operator as a postfix to a variable, the result is
assigned and then the variable is incremented or decremented.
double d = 95.0;
int i = 86, j = 91;
double average = (d+i+j)/3; // convert i and j to double values
// average = 90.666666...
Examples
int grade = (int) 93.75; // convert double to int (grade = 93)
double d = 95.0;
int i = 86, j = 91;
double average = ( (int)d+i+j)/3; // convert d to int value (average = 90)
Description
• If you assign a less precise data type to a more precise data type, Java automatically
converts the less precise data type to the more precise data type. This can be
referred to as an implicit cast or a widening conversion.
• When you code an arithmetic expression, Java implicitly casts the less precise data
types to the most precise data type.
• To code an assignment statement that assigns a more precise data type to a less
precise data type, you must use parentheses to specify the less precise data type.
This can be referred to as an explicit cast or a narrowing conversion.
• You can also use an explicit cast in an arithmetic expression. Then, the casting is
done before the arithmetic operations.
• Since each char value has a corresponding int value, you can implicitly or explicitly
cast between these types.
Description
• You can use one of the three static methods of the NumberFormat class to create a
NumberFormat object. Then, you can use the methods of that object to format one
or more numbers.
• When you use the format method, the result is automatically rounded by using a
rounding technique called half-even. This means that the number is rounded up if
the preceding digit is odd, but the extra decimal places are truncated if the preced
ing digit is even.
• Since the NumberFormat class is in the java.text package, you’ll want to include an
import statement when you use this class.
Figure 3-8 How to use the NumberFormat class
Section 1 Essential Java skills
When you use the format method of a NumberFormat object, the numbers
are automatically rounded using a technique called half-even. This technique
rounds up if the preceding digit is odd, but rounds down if the preceding digit is
even. If, for example, the currency format is used for a value of 123.455, the
formatted result is $123.46, which is what you would expect. But if the value is
123.445, the result is $123.44. Although this is okay for many applications, it
can cause problems in others. You’ll learn more about this later in this chapter.
Description
• You can use the static methods of the Math class to perform common arithmetic
operations. This figure summarizes the methods that are the most useful for busi
ness applications.
• When a method requires one or more arguments, you code them between the
parentheses, separating multiple arguments with commas.
• In some cases, you need to cast the result to the data type that you want.
Description
• The Integer and Double classes are known as wrapper classes since they can be
used to construct Integer and Double objects that contain (wrap around) int and
double values. This can be useful when you need to pass an int or double value to a
method that only accepts objects, not primitive data types.
• The Integer and Double classes also provide static methods that you can use for
converting values from these data types to strings and vice versa.
• If the parselnt and parseDouble methods can’t successfully parse the string, they
will cause an error to occur. In Java terminology, this is known as throwing an
exception. You’ll leam how to handle or catch exceptions in chapter 5.
• Every primitive type has a wrapper class that works like the Integer and Double
classes.
Continue? (y/n):
V --------------------- A
The code for the formatted Invoice application
import java.util.Scanner;
import java.text.NumberFormat;
Continue? (y/n):
V- ------------ J
UNFORMATTED RESULTS
Discount percent: 0.1
Discount amount: 10.005
Total before tax: 90.045
Sales tax: 4.50225
Invoice total: 94.54725
FORMATTED RESULTS
Discount percent: 10%
Discount amount: $10.00
Total before tax: $90.04
Sales tax: $4.50
Invoice total: $94.55
Continue? (y/n):
1
Description
• The BigDecimal class provides a way to perform accurate decimal calculations in
Java. It also provides a way to store numbers with more than 16 significant digits.
Figure 3-13 The constructors and methods for the BigDecimal class
106 Section 1 Essential Java skills
Continue? (y/n):
V --------------------- ό
Description
• With this code, all of the result values are stored in BigDecimal objects, and all of
the results have two decimal places that have been rounded correctly when needed.
• Once the results have been calculated, you can use the NumberFormat methods to
format the values in the BigDecimal objects without any fear of rounding prob
lems. However, the methods of the NumberFormat object limits the results to 16
significant digits.
Perspective
If this chapter has succeeded, you should now be able to work with
whatever primitive data types you need in your applications. You should be
able to use the NumberFormat, Math, Double, and Integer classes whenever
you need them. And you should be able to use the BigDecimal class to solve
the problems that are associated with floating-point numbers.
Summary
• Java provides eight primitive data types to store integer, floating-point, character,
and boolean values.
• Variables store data that changes as a program runs. Constants store data that
doesn’t change as a program runs. You use assignment statements to assign values
to variables.
• You can use arithmetic operators to form arithmetic expressions, and you can use
some assignment operators as a shorthand for some types of arithmetic expres
sions.
• Java can implicitly cast a less precise data type to a more precise data type. Java
also lets you explicitly cast a more precise data type to a less precise data type.
• You can use the NumberFormat class to apply standard currency, percent, and
number formats to any of the primitive numeric types.
• You can use the static methods of the Math class to perform mathematical opera
tions such as rounding numbers and calculating square roots.
• You can use the constructors of the Double and Integer wrapper classes to create
objects that wrap double and int values. You can also use the static methods of
these classes to convert strings to numbers and vice versa.
• You can use the constructors of the BigDecimal class to create objects that store
decimal values that aren’t limited to 16 significant digits. Then, you can use the
methods of these objects to do the calculations that your programs require.
Chapter 3 How to work with data 109
Relational operators
Operator Name Description
== Equality Returns a true value if both operands
are equal.
1= Inequality Returns a true value if the left and right
operands are not equal.
> Greater Than Returns a true value if the left operand
is greater than the right operand.
< Less Than Returns a true value if the left operand
is less than the right operand.
>= Greater Than Or Equal Returns a true value if the left operand
is greater than or equal to the right operand.
<= Less Than Or Equal Returns a true value if the left operand
is less than or equal to the right operand.
Description
• You can use the relational operators to create a Boolean expression that compares
two operands and returns a boolean value that is either true or false.
• If you compare two numeric operands that are not of the same type, Java will
convert the less precise operand to the type of the more precise operand before
doing the comparison.
• By definition, a boolean variable evaluates to a boolean value of true or false.
Code that tests whether two strings refer to the same object
Scanner sc = new Scanner(System.in);
System.out.print("Enter stringl: ");
String stringl = sc.nextO;
System.out.print("Enter string2: ") ;
String string2 = sc.nextO;
Description
• To test two strings to see whether they contain the same string values, you must call
one of the methods of the String object.
• To test whether a string is null, you can use the equality operator (==) or the in
equality operator (!=) with the null keyword.
• A string object is a reference type, not a primitive data type. That means that a string
variable doesn’t contain the data like a primitive type does. Instead, a string variable
refers to (or points to) the data, which is in another location of computer memory.
• If you use the equality or inequality operator to compare two string variables, Java
tests to see whether the two strings refer to the same String object. If they do, the
expression is true. If they don’t, it’s false.
Technical note
• Because Java stores string literals in pools to reduce duplication, the equality and
inequality tests for strings may not work as shown above when two String objects
are assigned the same literal value.
Logical operators
Operator Name Description
&& And Returns a true value if both expressions are
true. This operator only evaluates the second
expression if necessary.
Or Returns a true value if either expression is
" true. This operator only evaluates the second
expression if necessary.
& And Returns a true value if both expressions are
true. This operator always evaluates both
expressions.
1 Or Returns a true value if either expression is
true. This operator always evaluates both
expressions.
1 Not Reverses the value of the expression.
Examples
subtotal >= 250 && subtotal < 500
timelnService < = 4 || timelnService >= 12
Description
• You can use the logical operators to create a Boolean expression that combines two
or more Boolean expressions.
• Since the && and II operators only evaluate the second expression if necessary,
they’re sometimes referred to as short-circuit operators and are slightly more
efficient than the & and I operators.
• By default, Not operations are performed first, followed by And operations, and
then Or operations. These operations are performed after arithmetic operations and
relational operations.
• You can use parentheses to change the sequence in which the operations will be
performed or to clarify the sequence of operations.
Description
• If a clause in an if/else statement contains just one statement, you don’t have to
enclose the statement in braces. You can just end the clause with a semicolon.
However, this statement can’t declare a variable or it won’t compile.
• If a clause requires more than one statement, you must enclose the block of state
ments in braces. Then, any variable that is declared within the block has block
scope so it can only be used within that block.
Description
• Prior to version 1.7 of Java, the switch statement could only be used with an
expression that evaluated to one of these integer types: char, byte, short, or int.
• Starting with version 1.7 of Java, the switch statement can also be used with string
expressions. Then, the switch statement uses the equals method of the String object
to compare the strings. As a result, the strings in switch statements are case-
sensitive.
• The switch statement transfers control to the appropriate case label. If control isn’t
transferred to one of the case labels, the optional default label is executed.
The third example in figure 4-5 shows how to code a switch statement that
sets a day variable to “weekday” or “weekend” depending on the value of the
integer in the variable named dayOfWeek. Here, the case labels for 2, 3, 4, and
5 don’t contain any statements, so execution falls through to the case label for 6.
As a result, day is set to “weekday” for any of those values. Similarly, whenever
dayOfWeek equals 1 or 7, day is set to “weekend”.
Although a break statement is coded at the end of the last case label in this
example, you should know that it isn’t required. If you omit this break state
ment, program execution automatically falls through to the statement that
follows the switch statement. However, it’s generally considered a good pro
gramming practice to code a break statement at the end of the last case label.
That way, if you add a new case label after the last case label, your switch
statement still works correctly. Similarly, if you move the last case label so it
occurs earlier in the switch statement, it still works correctly.
When you code switch statements, you can nest one statement within
another. You can also nest if/else statements within switch statements and
switch statements within if/else statements. Here again, you should try to code
the statements with a logical structure that is relatively easy to understand. If
necessary, you can also add comments that clarify the logic of your code.
Chapter 4 How to code control statements 123
Description
• If a case label doesn’t contain a break statement, code execution will fall through to
the next label. Otherwise, the break statement ends the switch statement.
• The case labels can be coded in any sequence.
The console
(?- ----------- «
Enter customer type (r/c): r
Enter subtotal: 100
Discount percent: 10%
Discount amount: $10.00
Total: $90.00
Continue? (y/n):
V ------------------ à
The code
import java.text.NumberFormat;
import java.util.Scanner;
while (Ichoice.equalsIgnoreCase("n"))
{
// get the input from the user
System.out.print("Enter customer type (r/c): ");
String customerType = sc.nextO;
System.out.print("Enter subtotal: ");
double subtotal = sc.nextDouble();
Description
• In a while loop, the condition is tested before the loop is executed. In a do-while
loop, the condition is tested after the loop is executed.
• A while or do-while loop executes the block of statements within the loop as long
as its Boolean expression is true.
• If a loop requires more than one statement, you must enclose the statements in
braces. This identifies the block of statements that are executed by the loop, and
any variables or constants that are declared in that block have block scope.
• If a loop requires just one statement, you don’t have to enclose the statement in
braces. However, that statement can’t declare a variable or it won’t compile.
• If the condition at the start of a while statement or at the end of a do-while state
ment never becomes false, the statement never ends. Then, the program goes into
an infinite loop. In NetBeans, you can cancel an infinite loop by clicking on the
Stop button in the Output window.
Description
• A for loop is useful when you need to increment or decrement a counter that
determines how many times the loop is executed.
• Within the parentheses of a for loop, you code an initialization expression that
gives the starting value for the counter, a Boolean expression that determines when
the loop ends, and an increment expression that increments or decrements the
counter.
• The loop ends when the Boolean expression is false.
• If necessary, you can declare the counter variable before the for loop. Then, this
variable will be in scope after the loop finishes executing.
The console
f- ------
Enter monthly investment: 100
Enter yearly interest rate: 3
Enter number of years: 3
Future value: $3,771.46
Continue? (y/n): y
W- ---------- λ
The code
import java.util.Scanner;
import java.text.NumberFormat;
The console
/h- ------ Λ
Monthly Payment: 100.0
}
}
The syntax of the labeled break statement
break labelName;
The syntax for calling a static method that’s in the same class
methodName([argumentList] )
Description
• To allow other classes to access a method, use the public access modifier. To
prevent other classes from accessing a method, use the private modifier.
• To code a method that returns data, code a return type in the method declaration
and code a return statement in the body of the method. The return statement ends
the execution of the method and returns the specified value to the calling method.
• Within the parentheses of a method, you can code an optional parameter list that
contains one or more parameters that consist of a data type and name. These are
the values that must be passed to the method when it is called.
• The name of a method along with its parameter list form the signature of the
method, which must be unique.
• When you call a method, the arguments in the argument list must be in the same
order as the parameters in the parameter list defined by the method, and they must
have compatible data types. However, the names of the arguments and the param
eters don’t need to be the same.
have compatible data types. That means that an argument and parameter must
have the same data type, or the parameter must have a more precise data type
than the argument so the argument can be implicitly cast to that type. To refresh
your memory on implicit casting, you can refer back to figure 3-7 in chapter 3.
In practice, the terms parameter and argument are often used interchange
ably. In this book, however, we’ll use the term parameter to refer to the vari
ables of a method declaration, and we’ll use the term argument to refer to the
variables that are passed to a method.
The code
import java.util.Scanner;
import java.text.NumberFormat;
Perspective
If this chapter has succeeded, you should now be able to use if, switch,
while, do-while, and for statements. These are the Java statements that imple
ment the selection, case, and iteration structures, and they provide the logic of
an application. You should also be able to code and call your own static
methods, which will help you divide your programs into manageable parts.
Summary
• You can use the relational operators to create Boolean expressions that compare
primitive data types and return true or false values, and you can use the logical
operators to connect two or more Boolean expressions.
• To determine whether two strings are equal, you can call the equals and
equalsIgnoreCase methods from a String object.
• You can use if/else statements and switch statements to control the logic of an
application, and you can nest these statements whenever necessary.
• You can use while, do-while, and for loops to repeatedly execute one or more
statements until a Boolean expression evaluates to false, and you can nest these
statements whenever necessary.
• You can use break statements to jump to the end of the current loop or a labeled
loop, and you can use continue statements to jump to the start of the current loop
or a labeled loop.
• To code a static method, you code an access modifier, the static keyword, its return
type, its name, and a parameter list. Then, to return a value, you code a return
statement within the method.
• To call a static method that’s in the same class as the main method, you code the
method name followed by an argument list.
Chapter 4 How to code control statements 143
Enter score 1: 75
Enter score 2 : 80
Enter score 3 : 75
Enter score 4 : 880
Invalid entry. not counted
Enter score 4 : 80
Enter score 5: 95
Score count : 5
Score total: 405
Average score: 81
Minimum score: 75
Maximum score: 95
Enter score 1: 85
Enter score 2 : 95
Enter score 3 : 100
Score count : 3
Score total: 280
Average score: 93.3
Minimum score: 85
Maximum score: 100
Description
• An exception is an object that contains information about an error that has oc
curred. When an error occurs in a method, the method throws an exception.
• If an exception is thrown when you’re testing a console application, some informa
tion about the exception, including its name and stack trace, is displayed at the
console.
• A stack trace is a list of the methods that were called before the exception oc
curred. The list appears in reverse order, from the last method called to the first
method called.
• All exceptions are subclasses of the Exception class. The Exception class repre
sents the most general type of exception. Each successive layer of subclasses
represents more specific exceptions.
• The class for an exception is usually stored in the same package as the class whose
methods throw that type of exception. For instance, the InputMismatchException
class is stored in the java.util package along with the Scanner class.
converted to another data type. This exception can be thrown by the parseDouble
method of the Double class or the parselnt method of the Integer class.
The class for an exception is usually stored in the same package as the class
that has the methods that throw that type of exception. For instance, the
InputMismatchException is thrown by the Scanner class, so the class for this
exception is stored in the java.util package along with the Scanner class. As a
result, if your application is going to use this exception object, it should import
java.util.InputMismatchException or all of the classes in the java.util package.
Console output
Enter subtotal: $100
Error! Invalid number. Try again.
Enter subtotal:
Description
• In a try statement (or try/catch statement), you code any statements that may throw
an exception in a try block. Then, you can code a catch block that will handle any
exceptions that may occur in the try block.
• When an exception occurs, any remaining statements in the try block are skipped
and the statements in the catch block are executed.
• Any variables or objects that are used in both the try and catch blocks must be
declared before the try and catch blocks so both the try and catch blocks can access
them.
• If you use a catch block to catch a specific type of exception, you should also
import the package that contains that exception class.
Enter subtotal:
v J
Description
• The hasXxx methods of the Scanner class let you check whether additional data is
available at the console and whether that data can be converted to a specific data
type. You can use these methods to prevent an exception from being thrown when
one of the next methods is called.
• You can use the nextLine method to retrieve and discard any additional data that
the user enters on a line that isn’t required by the application.
• When your code prevents an exception from being thrown, it runs faster than code
that catches and then handles the exception.
Description
• When a user enters data, that data usually needs to be checked to make sure that it
is valid. This is known as data validation.
• When an entry is invalid, the program needs to display an error message and give
the user another chance to enter valid data. This needs to be repeated until the entry
is valid. One way to code this type of validation routine is to use a while loop.
• Two common types of validity checking for a numeric entry are (1) to make sure
that the entry has a valid numeric format, and (2) to make sure that the entry is
within a valid range (known as range checking).
Description
• Because most applications need to check more than one type of entry for validity, it
often makes sense to create and use generic methods for data validation.
The console
Figure 5-7 shows the console display when the user enters invalid data for
the improved version of the Future Value application. Here, the error messages
have been highlighted so you can see them more easily. For example, the first
error message is displayed if the user doesn’t enter a valid double value for the
monthly investment. The second error message is displayed if the user enters a
value that’s out of range for the interest rate. And the third error message is
displayed if the user doesn’t enter a valid integer value for the years.
The Data Entry section in this figure uses descriptive error messages to
identify the problems to the user, and it doesn’t require that the user re-enter
values that have already been successfully entered. In addition, it only uses the
first value the user enters on a line, which is usually what you want. All other
values are discarded.
After the user completes the Data Entry section, the Future Value applica
tion calculates the future value and displays it along with the user’s entries in
the Formatted Results section. This makes it easy to see what valid values the
user entered, which is useful if the user has entered one or more invalid entries
in the Data Entry section.
Chapter 5 How to validate input data 159
DATA ENTRY
Enter monthly Investment: $100
Error! Invalid decimal value. Try again.
Enter monthly Investment: 100 dollars
Enter yearly Interest rate: 120
Error! Number must be less than 30.0.
Enter yearly Interest rate: 12.0
Enter number of years: one
Error! Invalid Integer value. Try again.
Enter number of years: 1
FORMATTED RESULTS
Monthly investment: $100.00
Yearly interest rate: 12.0%
Number of years : 1
Future value: $1,280.93
Continue? (y/n):
Description
• The Data Entry section gets input from the user and displays an appropriate error
message if the user enters an invalid numeric format or a number that’s outside the
valid range.
• The Formatted Results section displays the data that was entered by the user along
with the future value in a format that’s easy to read.
Figure 5-7 The console for the Future Value application with data validation
160 Section 1 Essential Java skills
The code
Figure 5-8 shows the code for this version of the Future Value application.
On page 1, you can see the code for the main method. Because this code is
similar to code you’ve already seen, you shouldn’t have any trouble understand
ing how it works. The biggest difference is that it uses methods named
getDoubleWithinRange and getlntWithinRange to validate the data entered by
the user. In this case, the monthly investment must be a double that’s greater
than 0 and less than 1000, the yearly interest rate must be a double that’s greater
than 0 and less than 30, and the number of years must be an int that’s greater
than 0 and less than 100. Then, the application will be able to calculate the
future value for any values within these ranges.
The getDouble and getDoubleWithinRange methods shown on page 2 of
this listing are the ones presented in figure 5-6. As a result, if you have any
trouble understanding how these methods work, you may want to review that
figure. The getlnt and getlntWithinRange methods on page 3 work like the
getDouble and getDoubleWithinRange methods except that they validate an int
value instead of a double value. Note that all four of these methods, as well as
the calculateFutureValue method, are coded with the public access modifier so
they can be accessed from other classes.
As you review this code, notice how each method performs a specific task.
For example, the getDouble and getlnt methods prompt the user for an entry,
validate the entry, and return the valid entry. Similarly, the calculateFutureValue
method performs a calculation and returns the result. This is a good design
because it leads to code that’s reusable and easy to maintain. For example, you
can use the getDouble and getlnt methods with any console application that gets
double or int values from the user. Although you can copy these methods from
one application to another, you can also store them in classes that you can
access from any application. You’ll learn how to do that in chapter 7.
Chapter 5 How to validate input data
The code for the Future Value application with data validation Page 1
import java.util.*;
import j ava.text.* ;
String results =
"Monthly investment :\t"
+ currency.format(monthlylnvestment) + "\n"
+ "Yearly interest rate:\t"
+ percent.format(interestRate/100) + "\n"
+ "Number of years:\t"
+ years + 11\n"
+ "Future value:\t\t"
+ currency.format(futureValue) + "\n";
System.out.printlnO ;
System.out.println("FORMATTED RESULTS");
System.out.println(results);
Figure 5-8 The code for the Future Value application with data validation (part 1 of 3)
162 Section 1 Essential Java skills
The code for the Future Value application with data validation Page 2
public static double getDoubleWithinRange(Scanner sc. String prompt,
double min, double max)
{
double d = 0.0;
boolean isValid = false;
while (isValid == false)
{
d = getDouble(sc, prompt);
if (d <= min)
System.out.println(
"Error! Number must be greater than " + min +
else if (d >= max)
System.out.println(
"Error! Number must be less than " + max + ".");
else
isValid = true;
}
return d;
}
public static double getDouble(Scanner sc. String prompt)
{
double d = 0.0;
boolean isValid = false;
while (isValid == false)
{
System.out.print(prompt);
if (sc.hasNextDouble())
{
d = sc.nextDouble();
isValid = true;
}
else
{
System.out.println(
"Error! Invalid decimal value. Try again.");
}
sc.nextLine(); // discard any other data entered on the line
}
return d;
}
Figure 5-8 The code for the Future Value application with data validation (part 2 of 3)
Chapter 5 How to validate input data 163
The code for the Future Value application with data validation Page 3
public static int getlntWithinRange(Scanner sc. String prompt,
int min, int max)
{
int i = 0;
boolean isValid = false;
while (isValid == false)
{
i = getlnt(sc, prompt);
if (i <= min)
System.out.println(
"Error! Number must be greater than " + min + ".");
else if (i >= max)
System.out.println(
"Error! Number must be less than " + max + ".");
else
isValid = true;
}
return i ;
}
public static int getlnt(Scanner sc. String prompt)
{
int i = 0;
boolean isValid = false;
while (isValid == false)
{
System.out.print(prompt);
if (sc.hasNextlnt())
{
i = sc.nextlnt();
isValid = true;
}
else
{
System.out.println(
"Error! Invalid integer value. Try again.");
}
sc.nextLine(); // discard any other data entered on the line
}
return i ;
}
public static double calculateFutureValue(double monthlylnvestment,
double monthlylnterestRate, int months)
{
double futureValue = 0;
for (int i = 1; i <= months; i++)
{
futureValue =
(futureValue + monthlylnvestment) *
(1 + monthlylnterestRate);
}
return futureValue;
}
}
Figure 5-8 The code for the Future Value application with data validation (part 3 of 3)
164 Section 1 Essential Java skills
Perspective
Now that you’ve completed this chapter, you should be able to write
console applications that validate the input data that’s entered by the users and
catch any exceptions that occur. As a result, the applications should never
crash. That, of course, is the way professional applications should work.
At this point, you’ve learned a complete subset of Java, and you know how
to use some of the methods in a few of the classes in the Java API. But there’s
a lot more to Java programming than that. In particular, you need to leam how
to create your own classes that have their own methods. That’s the essence of
object-oriented programming, and that’s what you’ll leam in the next section
of this book. But first, you’ll leam how to test and debug an application.
Summary
• An exception is an object that’s created from the Exception class or one of its
subclasses. This object contains information about an error that has occurred.
• The stack trace is a list of methods that were called before an exception occurred.
• You can code a try statement to create an exception handler that will catch and
handle any exceptions that are thrown. This is known as exception handling.
• Data validation refers to the process of checking input data to make sure that it’s
valid.
• Range checking refers to the process of checking an entry to make sure that it falls
within a certain range of values.
In this exercise, you’ll add code to the Invoice application that validates the data
the user enters. That includes exception handling code as well as specific data
validation methods.
1. Open the project named ch05_exl_Invoice in the ex_starts directory. Then,
test the application to see how it works.
2. As you test the application, enter an invalid customer type code to see what
happens. Then, enter an invalid subtotal entry like $1000 to see what happens
when the application crashes.
Validate the customer type code
3. Modify the application so it will only accept customer type codes r and c. It
should also discard any extra entries on the customer type line. If the user
enters an invalid code, the application should display an error message and
Chapter 5 How to validate input data 165
ask the user to enter a valid code. This should be done before the user enters a
subtotal. Then, test this enhancement.
4. Code a static method named getYalidCustomerType that does the validation
of step 3. This method should include one parameter that receives a Scanner
object, and it should return a valid customer type code. The method should
get an entry from the user, check it for validity, display an error message if it’s
invalid, and discard any other user entries whether or not the entry is valid.
This method should continue getting user entries until one is valid. The
easiest way to add the code for this method is to copy the code you wrote in
step 3.
5. Modify the application so it uses this method. Then, test this enhancement.
Validate the subtotal
6. Add a try statement that catches any InputMismatchException that the
nextDouble method of the Scanner class might throw. The catch block should
display an error message and issue a continue statement to jump to the
beginning of the while loop. It should also discard the invalid entry and any
other entries on the line. For this to work, you’ll need to import the
InputMismatchException class, and you’ll need to declare the subtotal
variable before the try statement so it can be used outside that statement. Test
this enhancement.
7. Code a static method named getValidSubtotal that uses the hasDouble method
of the Scanner class to validate the subtotal entry so the
InputMismatchException won’t occur. This method should require one
parameter that receives a Scanner object, and it should return a valid subtotal.
This method should get an entry from the user, check that it’s a valid double
value, check that it’s greater than zero and less than 10000, display
appropriate error messages if it isn’t valid, and discard any other user entries
whether or not the entry is valid. This should continue until the method gets a
valid subtotal entry.
8. Modify the code within the try statement so it uses this method. Then, test this
enhancement so you can see that an InputMismatchException is no longer
caught by the catch block.
Discard any extra entries for the Continue prompt
9. Run the application again. When the Continue prompt is displayed, enter two
or more values to see what happens.
10. Modify the code so the application works right even if the user enters two or
more values when asked if he wants to continue. To do that, you need to
discard any extra entries. Then, test this enhancement.
At this point, the application should be bulletproof. It should only accept valid
entries for customer type and subtotal, and it should work even if the user
makes two or more entries for a single prompt.
166 Section 1 Essential Java skills
In this exercise, you’ll add data validation to a variation of the Test Score
application that you worked on in previous chapters. To do that, you’ll use
generic methods that you can copy from the Future Value application. This will
show you that generic validation methods can be used in a wide range of
applications.
1. Open the project named ch05_ex2_TestScore in the ex_starts directory. Then,
run the application to see how it works. Note that it crashes if you enter an
invalid integer for a score or if you enter “y” followed by another value at the
prompt that asks if you want to enter another score. Note also that it allows
invalid scores such as 150.
2. Open the ch05_FutureValueValidation project in the book_apps directory.
Then, copy the generic getlnt and getlntWithinRange methods from that
application and paste them into the TestScoreApp class.
3. Use the getlnt and getlntWithinRange methods to validate that each score
ranges from 1 through 100. Then, test this enhancement.
4. Add code that discards any extra entries at the prompt that asks if you want to
enter another score. Then, test the application to make sure that it is
bulletproof.
6
How to test and debug
an application
As you develop a Java application, you need to test it to make sure that it
performs as expected. Then, if you encounter any problems, you need to debug
the application to locate the cause of the problems. This chapter shows how to
do both.
DATA ENTRY
Enter monthly Investment: 100
Enter yearly interest rate: 3
Enter number of years : 3
FORMATTED RESULTS
Monthly investment: $100.00
Yearly interest rate: 3.0%
Number of years: 3
Future value: $6,517.42
Continue? (y/n):
V ---------------------
Description
• To test a Java application, you run it to make sure that it works properly no matter
what combinations of valid or invalid data you enter.
• When you debug an application, you find and fix all of the errors (bugs) that you
find when you test the application.
Description
• A simple way to trace the execution of an application is to insert println statements
at key points in the code that print messages to the console.
• The messages that are printed to the console can indicate what code is being
executed, or they can display the values of variables.
• When you see an incorrect value displayed, there is a good chance that the
application contains a logic error between the current println statement and the
previous one.
File Edit View Navigate Source Refactor Run Debug P rofile Team Tools W ind ow Help Q ·· Search (Ctrl+I)
; O utput
147 1 1 INS
Description
• A breakpoint causes program execution to stop before the line that contains the
breakpoint is executed.
• To set a breakpoint for a line, open the code editor for the class and click on the
line number. The breakpoint is identified by a small red square that’s placed to the
left of the line of code.
• To remove a breakpoint, click on the breakpoint icon.
• You can set and remove breakpoints either before you start debugging or while
you’re debugging. In most cases, you’ll set at least one breakpoint before you start
debugging.
• To start debugging for the main project, click the Debug Main Project button on the
toolbar. If a single project is open and it’s not set as the main project, the name of
this button is Debug Project.
• You can also start debugging by right-clicking on a project and selecting the Debug
command or by right-clicking on the file that contains the main method you want to
run and selecting the Debug File command.
A debugging session
Q NetBeans IDE 7,0 |siks«|
F ile E d it V ie w N a v ig a te S o u rc e R e fa c to r Run D ebug P r o f ile T eam Took W in d o w H e lp j Q ," Search (Ctrl+!)
Name Type
<QrfutureValue y 503.7625234609472
Q
% G 1D Ü b Ü td ❖i
O B re ak p oin ts
chQ6_FutureValue (debug) | 14 5 I 1 IN S
Description
• When a breakpoint is reached, program execution is stopped before the line is executed.
• The arrow in the bar at the left side of the code editor window shows the line that will
be executed next.
• The Variables window shows the values of the variables that are in scope for the current
method. This window is displayed by default when you start a debugging session. If
you close it, you can open it again using the Wmdow->Debugging->Variables
command.
• If a variable in the Variables window refers to an object, you can view the values for
that object by clicking the plus sign to the left of the object name to expand it.
• You can use the buttons on the Debug toolbar to control the execution of an application.
I I FutureValueApp .main : 27
* III
lb m ti
□ Breakpoints
Description
• A stack trace is a list of the methods that have been called in the reverse order in
which they were called.
• By default, NetBeans displays a stack trace in the Debugging window that’s
included in the group of windows at the left side of the IDE.
• You can also display a stack trace in the Call Stack window, which appears in the
group of windows below the code editor. You can display this window by selecting
the Window->Debugging-> Call Stack command.
• To jump to a line of code in the code editor that’s displayed in the stack trace,
double-click on that line in the stack trace.
Perspective
Before you put an application into production, you should test and debug it
thoroughly. That way, no unexpected errors will occur as the application is
being used. Now that you’ve completed this chapter, you should have the skills
you need to test an application to identify any bugs it may contain. Then, you
should be able to use the NetBeans debugger to locate the cause of those bugs.
The skills presented in this chapter should give you a solid foundation for
testing and debugging any application that you develop. However, you should
know that NetBeans provides some additional features that you can use to test
and debug your applications. For example, you can use the Watches window to
list the values of variables and expressions you specify, and you can use the
Breakpoints window to manage the breakpoints in an application. After
reading this chapter, you shouldn’t have any trouble learning how to use these
windows as well as other NetBeans features on your own.
As you begin to develop more complex applications, you may also want to
leam about unit testing. Unit testing is a way of creating tests for individual
units of source code such as methods to make sure that they work correctly.
As you test an application, you may also run into memory or performance-
related problems. To help identify the source of these problems, you can use
the NetBeans Profiler. This tool lets you monitor the performance of an
application. Then, you can use the data it provides to locate code in your
application that can be optimized so the application will run more efficiently.
Summary
• To test an application, you run it to make sure that it works properly no matter
what combinations of valid or invalid data you enter.
• When you debug an application, you find and fix all of the errors (bugs) that you
find when you test the application.
• Syntax errors violate the rules for how Java statements must be written. These
errors are detected by the NetBeans IDE or the Java compiler before you can run
the application.
• Runtime errors occur after you run an application. These types of errors throw
exceptions that stop the execution of the application.
• Logic errors don’t cause the application to crash, but they prevent it from working
correctly.
• A simple way to trace the execution of an application is to insert println statements
at key points in the code.
• NetBeans includes a powerful tool known as a debugger that can help you find and
fix these errors.
Chapter 6 How to test and debug an application
You can set a breakpoint on a line of code to stop code execution just before that
line of code. Then, you can step through the code and view the values of the vari
ables as the code executes.
A stack trace is a list of methods in the reverse order in which they were called.
This exercise guides you through the process of using NetBeans to test and debug
an application.
10. Display the Variables window again and inspect the values of the variables.
11. Click the Step Over button in the toolbar repeatedly to step through the
application one statement at a time. After each step, review the values in the
Variables window to see how they have changed.
12. When you’re done inspecting the variables, click the Finish Debugger Session
button to end the application. This should give you some idea of how useful
the NetBeans debugging tools can be.
In this exercise, you’ll use NetBeans to find and fix syntax errors and a logic
error in the Future Value application.
Object-oriented programming
with Java
In the first section of this book, you learned how to use classes that are
provided as part of the Java API. For instance, you learned how to use the
Math class to perform common arithmetic operations, and you learned
how to use the NumberFormat class to format numeric values. That’s one
part of object-oriented programming.
Besides the classes provided by the API, though, you can create your
own classes. That’s the other part of object-oriented programming, and
that’s what the four chapters in this section teach you to do. Specifically,
chapter 7 shows you how to create your own classes. Chapter 8 shows you
how to use inheritance, one of the most important features of object-
oriented programming. Chapter 9 shows you how to use interfaces. And
chapter 10 presents other object-oriented skills.
Because each of the chapters in this section builds on the previous
chapters, you should read these chapters in sequence. In addition, you
should read all of the chapters in this section before going on to sections 3,
4, or 5. That’s because many of the chapters in these sections rely on your
knowledge of inheritance and interfaces.
7
How to define
and use classes
This chapter shows you how to create and use your own classes in Java
applications. Here, you’ll learn how to create classes that include regular fields
and methods as well as classes that contain static fields and methods. In
addition, you’ll see two complete applications that use several user-defined
classes.
When you complete this chapter, you’ll start to see how creating your
own classes can help simplify the development of an application. As a bonus,
you’ll have a better understanding of how the Java API works.
An introduction to classes
The topics that follow introduce you to the concepts that you need to know
before you create your own classes. That includes how you’ll use classes in a
typical business application, how the fields and methods of a class can be
encapsulated within the class, and how a class relates to its objects.
Presentation Presentation
layer classes
Middle Business
layer classes
Database
layer Database
Description
• To simplify development and maintenance, many applications use a three-tiered
architecture to separate the application’s user interface, business rules, and data
base processing. Classes are used to implement the functions performed at each
layer of the architecture.
• The classes in the presentation layer control the application’s user interface. For a
console application, the presentation layer typically consists of a class with a main
method and any other classes related to console input and output. For a GUI
application, the user interface typically consists of one class for each window
(called a frame in Java) that makes up the GUI.
• The classes in the database layer handle all of the application’s data processing.
• The classes in the middle layer, which is sometimes called the business rules layer,
act as an interface between the classes in the presentation and database layers.
Sometimes, these classes correspond to business entities, such as customers or
products, and sometimes these classes implement business rules, such as discount
or credit policies. Often, the classes in this layer are referred to as business classes,
and the objects created from them are called business objects.
• The classes that make up each layer are often stored in packages that can be shared
among applications. For more information, see chapter 10.
+setCode(String)
+getCode(): String
+setDescription(String)
+getDescription(): String > Methods
+setPrice(double)
+getPrice(): double
+getFormattedPrice(): String
Description
• The fields of a class store the data of a class.
• The methods of a class define the tasks that a class can perform. Often, these
methods provide a way to work with the fields of a class.
• Encapsulation is one of the fundamental concepts of object-oriented programming.
This means that the class controls which of its fields and methods can be accessed
by other classes. As a result, the fields in the class can be hidden from other classes,
and the methods in a class can be modified or improved without changing the way
that other classes use them.
i V
Droductl
-code = "java"
-description = "Murach1s Beginning Java"
-price = 49.50 1f
prod uct2
-code = "mcb2n
-description = "Murach1s Mainframe COBOL"
-price = 59.50
Description
• A class can be thought of as a template from which objects are made.
• An object diagram provides the name of the object and the values of the fields.
• Once an instance of a class is created, it has an identity (a unique address) and a
state (the values that it holds). Although an object’s state may change throughout a
program, its identity never does.
Project: ;ch07_Product
Package:
! . Warning: I t is highly recommended that you do NOT place Java dasses in the default package.
Description
• To create a new class, right-click on the package where you want to add the class,
select the New->Java Class command, and respond to the resulting dialog box. At
the least, you should enter a name for the class in the Class Name text box.
• Although this dialog box encourages you to select a package for the class, this isn’t
required. If you don’t select a package for the class, NetBeans will store the class in
the default package. To leam how to create and use packages, see chapter 10.
• You can change a NetBeans option so the opening brace for a class is on its own
line rather than on the same line as the class declaration. To do that, use the
Tools-^Options command, click the Editor button at the top of the Options dialog
box that’s displayed, display the Formatting tab, select Java from the Language
drop-down list, and select Braces from the Category drop-down list. Then, select
New Line from the Class Declaration drop-down list.
// the constructor
public Product()
{
code = 1111;
description = "";
price = 0 ;
}
// the set and get methods for the code variable
public void setCode(String code)
{
this.code = code;
}
public String getCodeO
{
return code;
}
// the set and get methods for the description variable
public void setDescription(String description)
{
this.description = description;
}
public String getDescription()
{
return description;
}
// the set and get methods for the price variable
public void setPrice(double price)
{
this.price = price;
}
public double getPriceO
{
return price;
}
// a custom get method for the price variable
public String getFormattedPrice()
{
NumberFormat currency = NumberFormat.getCurrencylnstance();
return currency.format(price);
}
Examples
private double price;
private int quantity;
private String code;
private Product product;
Description
• An instance variable may be a primitive data type, an object created from a Java
class such as the String class, or an object created from a user-defined class such as
the Product class.
• To prevent other classes from accessing instance variables, use the private keyword
to declare them as private.
• You can declare the instance variables for a class anywhere outside the constructors
and methods of the class.
Description
• The constructor must use the same name and capitalization as the name of the class.
• If you don’t code a constructor, Java will create a default constructor that initializes
all numeric types to zero, all boolean types to false, and all objects to null.
• To code a constructor that has parameters, code a data type and name for each
parameter within the parentheses that follow the class name.
• The name of the class combined with the parameter list forms the signature of the
constructor. Although you can code more than one constructor per class, each
constructor must have a unique signature.
• In the second and fourth examples above, the this keyword is used to refer to an
instance variable of the current object.
your own constructors. That way, it’s easy to see which constructors are avail
able to a class, and it’s easy to check the values that each constructor uses to
initialize the instance variables.
p.printToConsole() ;
p .printToConsole(" ", true);
p.printToConsole(" 11) ;
The console
f/-- ;--- ;------------- ;-- .---------- :------------- ------ Λ
j ava jMurach1s Beginning Java 2 |4 9.5
java Murach's Beginning Java 49.5
Description
• When you create two or more methods with the same name but with different
parameter lists, the methods are overloaded. It’s common to use overloaded meth
ods to provide two or more versions of a method that work with different data types
or that supply default values for omitted parameters.
Description
• Since Java implicitly uses the this keyword for instance variables and methods, you
don’t need to explicitly code it unless a parameter has the same name as an instance
variable.
• If you use the this keyword to call another constructor, the statement must be the
first statement in the constructor.
0 '
: P ro je c ts 1Product.java 28 ’ ProductApp.java ; Pr&ductOB.java S8
g f di07_Product
IQ φ jg Source Packages
El iit.p o r t j a v a . t e x t , Huir.be rF o rit,a t;
h ä ! 2 1 1 và
ά - β - Ι <default package>
fa^frroduct.java P*obl±c c l a s s P r o d u c t
.java {
p r iv a te S tr in g code;
•to Libraries p r iv a te S tr in g d e s c r ip tio n ;
p r i v a t e d o u b le p r i c e ;
5
J public P r o d u c t (J
: Product.java - Navigator 10Π
co d e = ;
£ Product d e s c r i p t i o n = ,,r';
f O ProductO
p r i c e = 0;
Î
O getCodeO : String
■■■ Q getDescription{) : String
p u b l i c v o id s e tC o d e ( S tr in g ' c c d e f
;·-··
Q getformattedPriceO : String
Q getPriceO : double
{
t h i s . co d e = c o d e ;
Q setCode{String code)
>■·· ( j setDescripSon(5tring description)
}
f-· Q setPricefdciuble price)
Output
-t^j] code : String
-% ] desCTlption : String
-% ] price : double
& QXIGEDGSDQIJ «
111 INS
Description
• To generate g e t an d se t m ethods fo r one o r m ore field , select th e
R efactor-> E ncapsulate F ield s com m and an d resp o n d to th e resu ltin g dialo g box.
• T he N avigator w indow lists a ll th e m em bers o f th e cu rren tly selected class. To
d isp lay th is w indow , c lic k on its tab a t th e le ft sid e o f th e ID E , o r u se th e
W indow -^N avigating -^N avigator com m and. To ju m p to a m em ber, d o uble-click
on it in th e N avigator w indow .
Example 1: No arguments
Product product = new Product();
Description
• To create an object, you use the new keyword to create a new instance of a class.
Each time the new keyword creates an object, Java calls the constructor for the
object, which initializes the instance variables for the object.
• After you create an object, you assign it to a variable. When you do, a reference to
the object is stored in the variable. Then, you can use the variable to refer to the
object.
• To send arguments to the constructor, code the arguments between the parentheses
that follow the class name. To send more than one argument, separate the argu
ments with commas.
• When you send arguments to the constructor, the arguments must be in the se
quence called for by the constructor and they must have data types that are compat
ible with the data types of the parameters for the constructor.
Description
• To call a method that doesn’t accept arguments, type an empty set of parentheses
after the method name.
• To call a method that accepts arguments, enter the arguments between the parenthe
ses that follow the method name. Here, the data type of each argument must be
compatible with the data type that’s specified by the method’s parameters.
• To code more than one argument, separate the arguments with commas.
• If a method returns a value, you can code an assignment statement to assign the
return value to a variable. Here, the data type of the variable must be compatible
with the data type of the return value.
Result
price: 54.45
Result
product.getPrice(): 49.5
product.getPrice(): 54.45
Description
• When a primitive type is passed to a method, the method receives the value of the
variable. That means the method can’t change the value of the variable directly.
Instead, the method must return a new value that gets stored in the variable.
• When a reference type (an object) is passed to a method, the method also receives
the value of the variable. Because an object variable contains a pointer to the
object, though, the method can change the data in the object. That means that a new
value doesn’t need to be returned by the method.
Figure 7-14 How primitive types and reference types are passed to a method
214 Section 2 Object-oriented programming with Java
The console
f- ------- *
Welcome to the Product Selector
SELECTED PRODUCT
Description: Murach·s Beginning Java
Price: $49.50
Continue? (y/n):
V -------
Note
• This class contains the main method that provides the entry point for the Product
application. In this book, we’ve used the suffix “App” to identify this type of class.
public Product()
{
code = "";
description = "" ;
price = 0;
objectCount++; // update the static variable
}
public static int getObjectCount() // get the static variable
{
return objectCount;
}
Description
• You can use the static keyword to code static fields and static methods. Since static
fields and static methods belong to the class, not to an object created from the class,
they are sometimes called class fields and class methods.
• When you code a static method, you can only use static fields and fields that are
defined in the method. You can’t use instance variables in a static method because
they belong to an instance of the class, not to the class as a whole.
Description
• To call a static field, type the name of the class, followed by the dot operator,
followed by the name of the static field.
• To call a static method, type the name of the class, followed by the dot operator,
followed by the name of the static method, followed by a set of parentheses. If the
method requires arguments, code the arguments within the parentheses, separating
multiple arguments with commas.
static
{
// any initialization statements for static fields
}
// the rest of the class
Description
• To initialize the static variables of a class, you typically code the values in the
declarations. If, however, a variable can’t be initialized in a single statement, you
can code a static initialization block.
• When a class is loaded, Java initializes all static variables and constants of the
class. Then, it executes all static initialization blocks in the order in which they
appear. (A class is loaded when one of its constructors or static methods is called.)
The console
Figure 7-20 shows the console for the Line Item application. This applica
tion starts by prompting the user to enter a product code. Then, it prompts the
user to enter a quantity for that product. Finally, it displays the data for the line
item that’s retrieved and calculated by the application.
The console
f- ------- ^
Welcome to the Line Item Calculator
LINE ITEM
Code : java
Description: Murach s Beginning Java
Price: $49.50
Quantity: 2
Total: $99.00
Continue? (y/n):
------ 4
+setCode(String) +setProduct(Product)
+getCode(): String <------ +getProduct(): Product
+setDescription(String) +setQuantity(int)
+getDescription(): String +getQuantity(): int
+setPrice(double) +getTotal(): double
+getPrice(): double -calculateTotal()
+getFormattedPrice(): String +getFormattedTotal(): String
Validator
+getString(Scanner,
ProductDB String): String
+getProduct(String): Product +getint(Scanner, String): int
+getint(Scanner, String,
int, int): int
+getDouble(Scanner,
String): double
+getDouble(Scanner, String,
double, double): double
Description
• The Line Item application accepts a product code and quantity from the user,
creates a line item using that information, and displays the result to the user.
• The Validator class is used to validate the data the user enters.
• The three instance variables of the Lineltem class are used to store a Product
object, the quantity, and the line item total. The get and set methods are used to get
and set the values of these variables. The calculateTotal method is used to calculate
the line item total, and the getFormattedTotal method is used to format the total as a
currency value.
Figure 7-20 The console and the class diagrams for the Line Item application
226 Section 2 Object-oriented programming with Java
Description
• After the user enters a valid product code and quantity, the getProduct method of
the ProductDB class is called to get a Product object for the product with that code.
Then, a new line item object is created with that product and quantity.
• The getCode, getDescription, and getFormattedPrice methods of the Product object
are used to get the code, description, and price fields so they can be displayed at the
console. The getQuantity and getFormattedTotal methods of the Lineltem class are
used to get the quantity and total.
Figure 7-23 shows the Lineltem class that defines a line item for an invoice.
Like the Product class, the Lineltem class defines a business object in the
application’s middle tier. If you review the code for this object, you shouldn’t
have any trouble understanding how it works.
As you can see, this class contains a constructor that initializes the instance
variables to default values. Notice here that the product variable is initialized to
a new Product object with default values. Although you could also assign a null
value to the product variable, we don’t recommend that. If you do assign a null,
you’ll get a NullPointerException if you try to use the variable before you
assign an object to it.
After the constructor, the next five methods provide get and set methods for
the three instance variables. These methods simply set or return the value of the
corresponding instance variable. Note that the getTotal method calls the
calculateTotal method to calculate the line item total. This method calls the
getPrice method of the Product object to get the price of the product, multiplies
the price by the quantity, and assigns the result to the total instance variable.
The last method, getFormattedTotal, returns the line item total formatted as
currency. To do that, it calls the getTotal method to calculate and return the
total.
Chapter 7 How to define and use classes 231
public Lineltem()
{
this.product = new Product();
this.quantity = 0 ;
this.total = 0 ;
}
public void setProduct(Product product)
{
this.product = product;
}
public Product getProduct()
{
return product;
}
public void setQuantity(int quantity)
{
this.quantity = quantity;
}
public int getQuantity()
{
return quantity;
}
public double getTotalO
{
this.calculateTotal();
return total;
}
private void calculateTotal()
{
total = quantity * product.getPrice();
}
public String getFormattedTotal()
{
NümberFormat currency = NumberFormat.getCurrencylnstance();
return currency.format(this.getTotal());
}
}
Perspective
Now that you’ve completed this chapter, you may be wondering why you
should go to the extra effort of dividing an application into classes. The answer
is twofold. First, dividing the code into classes makes it easier to use the
classes in two or more applications. For example, any application that needs to
work with product data can use the Product class. Second, using classes helps
you separate the business logic and database processing of an application from
the presentation elements. That can simplify the development of the applica
tion and make the application easier to maintain and enhance later on.
In this chapter, though, you’ve just learned the basic skills for creating and
using classes. As you will soon see, there’s a lot more to creating classes than
what’s presented here. And that’s what the next three chapters are going to
show you.
Summary
• In a three-tiered architecture, an application is separated into three layers. The
presentation layer consists of the user interface. The database layer consists of the
database and the database classes that work with it. And the middle layer provides
an interface between the presentation layer and the database layer. Its classes are
often referred to as business classes.
• The Unified Modeling Language (UML) is the standard modeling language for
working with object-oriented applications. You can use UML class diagrams to
identify the, fields and methods of a class.
• Encapsulation lets you control which fields and methods within a class are ex
posed to other classes. When fields are encapsulated within a class, it’s called data
hiding.
• Multiple objects can be created from a single class. Each object can be referred to
as an instance of the class.
• The data that makes up an object can be referred to as its state. Each object is a
separate entity with its own state.
• A field is a variable or constant that’s defined at the class level. An instance
variable is a field that’s allocated when an object is instantiated. Each object has a
separate copy of each instance variable.
• Every class that contains instance variables has a constructor that initializes those
variables.
• When you code the methods of a class, you often code public get and set methods,
called accessors, that provide access to the fields of the class.
• If you want to code a method or constructor that accepts arguments, you code a list
of parameters between the parentheses for the constructor or method. For each
parameter, you must include a data type and a name.
Chapter 7 How to define and use classes 233
• When coding a class, you can use the this keyword to refer to the current object.
• When Java passes a primitive type to a method, it passes the value of the variable
so the variable can’t be changed directly. When Java passes an object (a reference
type) to a method, the value it passes is a reference to the object so the method can
change the values of the object’s variables.
• The name of a method or constructor combined with the list of parameter types is
known as the signature of the method or constructor. You can overload a method
or constructor by coding different parameter lists for constructors or methods that
have the same name.
• When you use a class that contains only static fields, static methods, and static
initialization blocks, you don’t create an object from the class. Instead, you call
these fields and methods directly from the class.
This exercise guides you through the process of modifying the Future Value
application so it uses classes that provide static methods.
1. Open the project named ch07_ex2_FutureValue that’s stored in the ex_starts
directory. Then, review the code for the FutureValueApp class.
2. Start a new class named Validator in the same package as the FutureValueApp
class. Then, move the getDouble, getDoubleWithinRange, getlnt, and
getlntWithinRange methods from the FutureValueApp class to the Validator
class. For this to work, you will also need to add an import statement for the
Scanner class to the Validator class.
3. Change the name of the getDoubleWithinRange method to getDouble, and
change the name of the getlntWithinRange method to getlnt. This overloads
the getDouble and getlnt methods.
4. Modify the FutureValueApp class so it uses the methods in the Validator
class. Then, run the application to make sure that it still works correctly.
5. Start a new class named FinancialCalculations and save it in the same
package as the other classes. Then, move the calculateFutureValue method
from the FutureValueApp class to the FinancialCalculations class, and make
sure that the method is public.
6. Modify the FutureValueApp class so it uses the static calculateFutureValue
method that’s stored in the FinancialCalculations class. Then, run the
application to make sure that it still works properly.
Chapter 7 How to define and use classes 235
In this exercise, you’ll create an Invoice class and construct objects from it as
you convert the Invoice application to an object-oriented application.
1. Open the project named ch07_ex3_Invoice that’s in the ex_starts directory.
Then, review the code for the InvoiceApp and Validator classes, and run the
project to see how this application works.
2. Start a new class named Invoice and save it in the same package as the other
classes. Then, write the code for this class as described here, copying the code
from the InvoiceApp class whenever that makes sense:
• Include two private fields for the customer type and subtotal entered
by the user.
• Include a single constructor that accepts the customer type and subtotal as
parameters.
• Include a get method that returns the subtotal as a double value. In
addition, include get methods that calculate and return double values for
the discount percent, discount amount, and total.
• Include get methods that return formatted string values for the subtotal,
discount percent, discount amount, and total. These methods should call
the other get methods to get the values to be formatted.
• Include a get method that returns a string that contains the full name for a
customer type.
3. Modify the code in the InvoiceApp class so it creates an Invoice object. Then,
call the methods of the Invoice object to display the formatted values for the
Invoice, and delete any code that is no longer needed. That should simplify
the InvoiceApp class considerably.
4. Test this application to make sure that it works the way it did in step 1.
g
How to work
with inheritance
In h e rita n ce is o n e o f th e k ey co n cep ts o f o b ject-o rien ted p ro g ram m in g . It lets
y o u c reate a class th a t’s b a se d o n a n o th er class. A s y o u ’ll see in th is chapter,
in h eritan c e is u se d th ro u g h o u t th e classes o f th e Jav a A P I. In ad d itio n , y o u can
u se it in th e classes th a t y o u create.
An introduction to inheritance
Inheritance allows you to create a class that’s based on another class. When
used correctly, inheritance can simplify the overall design of an application. The
following topics present an introduction to the basic concepts of inheritance.
murach.presentation.ProductFrame
setTitleC'Product") ;
setLocation(10, 10); Code that uses
Subclass setSize(200, 200); y inherited fields and
setResizable(false); methods
setDefaultCloseOperation(EXIT_0N_CL0SE)
void actionPerformed(ActionEvent e)
void keyPressed(KeyEvent e)
} New methods
Description
• Inheritance lets you create a new class based on an existing class. Then, the new
class inherits the fields, constructors, and methods of the existing class.
• A class that inherits from an existing class is called a derived class, child class, or
subclass. A class that another class inherits is called a base class, parent class, or
superclass.
• A subclass can extend the superclass by adding new fields, constructors, and
methods to the superclass. It can also override a method from the superclass with
its own version of the method.
• To create a new window (called a frame in Java), you can code a class that inherits
the JFrame class that’s in the javax.swing package. Then, your frame will inherit all
the fields and methods that are available to this class. Once you inherit the JFrame
class, you can write code that uses the inherited fields and methods, you can add
controls to the frame, and you can extend the frame by coding new fields and
methods.
Description
• The Java API uses inheritance extensively in its own classes, so you often need to
know what the inheritance hierarchy is as you use these classes. For example, you
need to know that all classes ultimately inherit the Object class in the java.lang
package.
• All Swing classes, which are stored in the javax.swing package, inherit the Compo
nent and Container classes in the java.awt package. This package contains the
Abstract Window Toolkit (AWT) classes.
• A class can use the fields and methods of any of its superclasses. For example, the
JFrame class can use the fields and methods provided by the Frame, Window,
Container, Component, and Object classes.
Description
• The Object class in the java.lang package is the superclass for all classes. In other
words, every class inherits the Object class or some other class that ultimately
inherits the Object class. As a result, the methods defined by the Object class are
available to all classes.
• When creating classes, it’s a common practice to override the toString and equals
methods so they work appropriately for each class. For example, the toString
method might return a value that uniquely identifies an object. And the equals
method might compare two objects to see if their instance variables are equal.
• The hash code for an object is a hexadecimal number that identifies the object’s
location in memory.
• In general, you don’t need to override the finalize method for an object, even
though its default implementation doesn’t do anything. That’s because the garbage
collector automatically reclaims the memory of an object whenever it needs to.
Before it does that, though, it calls the finalize method of the object.
Description
• You can use inheritance in your applications to create generic superclasses that
implement common elements of related subclasses. For example, if you need
separate classes to represent distinct types of products, you can create a Product
superclass. Then, you can create a separate subclass for each type of product that
inherits the Product class.
• It’s also common to create classes that inherit from classes that are defined by the
Java API. For example, you might create a ProductFrame class that inherits the
JFrame class as shown in figure 8-1.
• When you inherit a class, you can use the subclass whenever an instance of the
superclass is called for. For example, if the Book class inherits the Product class as
shown above, a Book object can be used whenever a Product object is called for.
Access modifiers
Keyword Description
private Available within the current class.
public Available to classes in all packages.
protected Available to classes in the same package and to subclasses.
no keyword coded Available to classes in the same package.
public Product()
{
code = 1111;
description = 1111;
price = 0 ;
}
// get and set accessors for the code, description, and price
// instance variables
@Override
public String toString()
{
return "Code: " + code + n\n" +
"Description: " + description + "\n" +
"Price: " + this.getFormattedPrice() + "\n";
}
public static int getCountO // create public access for the
{ // count variable
return count;
}
}
Description
• Access modifiers specify the accessibility of the members declared by a class.
Protected members are accessible to the current class, to other classes in the same
package, and to subclasses.
• An annotation is a standard way to provide information about your code. When
you override a method, you can add the @Override annotation to the method.
overrides the toString method in the superclass. If it doesn’t, the compiler can
generate an error. Second, other programmers can use this information to easily
see that this method overrides a method in the superclass.
public Book()
{
super(); // call constructor of Product superclass
author = "";
count++; // update the count variable In the Product superclass
}
public void setAuthor(String author)
{
this.author = author;
}
public String getAuthorO
{
return author;
}
©Override
public String toString() // override the toString method
{
return super.toString() + // call method of Product superclass
"Author: " + author + "\n";
}
}
Description
• You can directly access fields that have public or protected access in the superclass
from the subclass.
• You can extend the superclass by adding new fields, constructors, and methods to
the subclass.
• You can override methods in the superclass by coding methods in the subclass that
have the same signatures as methods in the superclass.
• You use the super keyword to call a constructor or method of the superclass. If
necessary, you can call constructors or methods that pass arguments to the super
class.
Product p;
P = b;
System.out.println(p.toStringO); // calls toString from the Book class
p = s;
System.out.println(p.toStringO); // calls toString from the Software class
Description
• Polymorphism is a feature of inheritance that lets you treat objects of different
subclasses that are derived from the same superclass as if they had the type of the
superclass. If, for example, Book is a subclass of Product, you can treat a Book
object as if it were a Product object.
• If you access a method of a superclass object and the method is overridden in the
subclasses of that class, polymorphism determines which method is executed based
on the object’s type. For example, if you call the toString method of a Product
object, the toString method of the Book class is executed if the object is a Book
object.
The console
Figure 8-8 shows the console for this version of the Product application. As
you can see, this application works much like the one you saw in chapter 7.
However, there are three main differences. First, this application displays an
additional piece of information about each product, which varies depending on
whether the product is a book or software. In particular, it displays an author for
a book and a version number for software. Second, this application displays a
count of the total number of objects it has created. Third, if the user enters an
invalid product code, the application displays an appropriate error message.
Chapter 8 How to work with inheritance 253
Code : java
Description: Murach ■s Beginning Java
Price: $49.50
Author: Andrea Steelman
Product count: 1
Continue? (y/n): y
Code : txtp
Description: TextPad
Price: $27.00
Version: 4.7.3
Product count: 2
Continue? (y/n): y
Product count: 2
Continue? (y/n):
-------------- J
Description
• This version of the Product application handles two types of products: books and
software.
• If you enter the product code for a book, the information about the product includes
an author.
• If you enter the product code for software, the information about the product
includes a version number.
public Product() {}
public Book()
{
super();
author = "";
count++;
}
public void setAuthor(String author)
{
this.author = author;
}
public String getAuthorO
{
return author;
}
©Override
public String toString()
{
return super.toString() + "Author: ■ + author + "\n";
}
}
public Software()
{
super();
version =
count++;
}
public void setVersion(String version)
{
this.version = version;
}
public String getVersionO
{
return version;
}
©Override
public String toString()
{
return super.toString() + "Version: ■ + version + "\n";
}
}
Figure 8-11 The code for the Book and Software classes
Chapter 8 How to work with inheritance 259
Product p = null;
if (productCode.equalsIgnoreCase("java") ||
productCode.equalsIgnoreCase("jsps") ||
productCode.equalsIgnoreCase("mcb2"))
{
Book b = new B o o k ();
if (productCode.equalsIgnoreCase("java"))
{
b.setCode(productCode);
b.setDescription("Murach1s Beginning Java");
b.setPrice(49.50);
b.setAuthor("Andrea Steelman");
}
else if (productCode.equalsIgnoreCase("jsps"))
{
b.setCode(productCode);
b.setDescription("Murach1s Java Servlets and JSP");
b.setPrice(49.50);
b.setAuthor("Andrea Steelman");
}
else if (productCode.equalsIgnoreCase("mcb2"))
{
b.setCode(productCode);
b.setDescription("Murach1s Mainframe COBOL");
b.setPrice(59.50);
b .setAuthor("Mike Murach");
}
p = b; // set Product variable equal to the Book object
}
else if (productCode.equalsIgnoreCase("txtp"))
{
Software s = new SoftwareO;
s .setCode("txtp");
s .setDescription("TextPad");
s .setPrice(27.00);
s .setVersion("4.7.3");
p = s; // set Product variable equal to the Software object
}
return p;
}
}
Common method
Method Description
getName () Returns a String object for the name of this Class object.
The console
Class name: Book
The console
I This is a Book object
The console
I This is a Book object
Description
• Every object has a getClass method that returns a Class object that corresponds to
the object’s type.
• You can use the methods of the Class class to obtain information about any object,
such as its name.
• The method shown above is only one of the more than 90 properties and methods
of the Class class.
• You can use the instanceof operator to check if an object is an instance of a particu
lar class.
Instead of using a class object to test an object’s type, you can use the
instanceof keyword. This is illustrated in the third example in figure 8-13. If you
compare this code with the code in the second example, I think you’ll agree that
this is a much easier way to check if an object is an instance of a particular
class.
Description
• Java can implicitly cast a subclass to a superclass. As a result, you can use a
subclass whenever a reference to its superclass is called for. For example, you can
specify a Book object whenever a Product object is expected because Book is a
subclass of Product.
• You must explicitly cast a superclass object when a reference to one of its sub
classes is required. For example, you must explicitly cast a Product object to Book
if a Book object is expected. This only works if the Product object is a valid Book
object. Otherwise, a ClassCastException will be thrown.
• Casting affects the methods that are available from an object. For example, if you
store a Book object in a Product variable, you can’t call the setAuthor method
because it’s defined by the Book class, not the Product class.
Example 2: Both variables refer to different objects that store the same data
Product productl = new Product();
Product product2 = new Product();
if (productl.equals(product2 )) // expression returns false
Description
• To test if two objects point to the same location in memory, you can use the equals
method of the Object class.
• To test if two objects store the same data, you can override the equals method in the
subclass so it tests whether all instance variables in the two objects are equal.
©Override
public String toString()
{
return "Code: " + code + n\n" +
"Description: " + description + "\n" +
"Price: " + this.getFormattedPrice() + "\n";
}
abstract String getDisplayText() ; // an abstract method
}
©Override
public String getDisplayText() // implement the abstract method
{
return super.toString() +
"Author: " + author + "\n";
}
}
Description
• An abstract class is a class that can be inherited by other classes but that you can’t
use to create an object. To declare an abstract class, code the abstract keyword in
the class declaration.
• An abstract class can contain fields, constructors, and methods just like other
superclasses. In addition, an abstract class can contain abstract methods.
• To create an abstract method, you code the abstract keyword in the method declara
tion and you omit the method body. Abstract methods cannot have private access.
However, they may have protected or default access (no access modifier).
• When a subclass inherits an abstract class, all abstract methods in the abstract class
must be overridden in the subclass.
• An abstract class doesn’t have to contain abstract methods. However, any class that
contains an abstract method must be declared as abstract.
Description
• To prevent a class from being inherited, you can create a final class by coding the
final keyword in the class declaration.
• To prevent subclasses from overriding a method of a superclass, you can create a
final method by coding the final keyword in the method declaration. In addition, all
methods in a final class are automatically final methods.
• To prevent a method from assigning a new value to a parameter, you can code the
final keyword in the parameter declaration to create a final parameter. Then, if a
statement in the method tries to assign a new value to the parameter, the compiler
will report an error.
• Coding the final keyword for classes and methods can result in a minor perfor
mance improvement for your application because the compiler doesn’t have to
allow for inheritance and polymorphism. As a result, it can generate more efficient
code.
Perspective
Conceptually, this is one of the most difficult chapters in this book.
Although the basic idea of inheritance isn’t that difficult to understand, the
complications of polymorphism, overriding, casting, and abstract and final
classes are enough to make inheritance a difficult topic. So if you find yourself
a bit confused right now, don’t be disheartened. It will become clearer as you
actually use the techniques you’ve learned here and see them used in the Java
API.
The good news is that you don’t have to understand every nuance of how
inheritance works to use it. In fact, since all classes automatically inherit the
Object class, you’ve already been using inheritance without even knowing it.
Now that you’ve completed this chapter, though, you should have a better
understanding of how the Java API works. In addition, you should have a
better idea of how you can use inheritance to improve the design of your own
classes.
Summary
• Inheritance lets you create a new class based on an existing class. The existing
class is called the superclass, base class, or parent class, and the new class is
called the subclass, derived class, or child class.
• A subclass inherits all of the fields and methods of its superclass. The subclass can
extend the superclass by adding its own fields and methods, and it can override a
method with a new version of the method.
• All classes inherit the java.lang.Object class, which provides methods such as
toString, equals, and getClass.
• You can use access modifiers to limit the accessibility of the fields and methods
declared by a class. Protected members can be accessed only by classes in the
same package or by subclasses.
• An annotation is a standard way to provide information about your code to other
software tools and developers. When you override a method, it’s generally consid
ered a good practice to add the @Override annotation to the method.
• In a subclass, you can use the super keyword to access the fields, constructors, and
methods of the superclass.
• Polymorphism is a feature of inheritance that lets you treat subclasses as though
they were their superclass.
• You can call the getClass method from any object to get a Class object that con
tains information about that object.
• You can use the instanceof operator to check if an object is an instance of a
particular class.
Chapter 8 How to work with inheritance
Java can implicitly cast a subclass type to its superclass type, but you must use
explicit casting to cast a superclass type to a subclass type.
Abstract classes can be inherited by other classes but can’t be used to create an
object. Abstract classes can include abstract methods that must be implemented by
subclasses.
You can use the final keyword to declare final classes, final methods, and final
parameters. No class can inherit a final class, no method can override a final
method, and no statement can assign a new value to a final parameter.
This exercise lets you view and run a class that inherits the javax.swing.JFrame
class.
1. Open the project named ch08_exl_ProductFrame that’s stored in the ex_starts
directory. Review the code in the ProductFrame class, and notice how it
inherits the JFrame class and calls methods inherited from this class. In
addition, note that this class contains a main method that creates an instance
of the ProductFrame class and displays that instance.
2. Run this project. This should display a frame. When you click on its close
button, the frame should close. In section 4, you’ll learn more about working
with frames like this one. In particular, you’ll learn how to add components
such as buttons, labels, and text boxes.
3. Use the documentation from the Java API documentation to research the
methods of the JFrame class that are called by this code. Then, add comments
to the code to indicate which class the method is inherited from.
4. Use your research from step 3 to determine which class inherited by the
JFrame class declares the setVisible method. Then, import that class and
modify the code in the main method so the frame variable is declared as that
type rather than as a JFrame type. Run the application to verify that it still
works properly.
272 Section 2 Object-oriented programming with Java
In this exercise, you’ll change the Product class in the Product application to an
abstract class to see how that works, and you’ll add an abstract method and
implement it in the Book, Software, and CompactDisc subclasses. Then, you’ll
change the Book class to a final class to see that a final class can’t be inherited,
and you’ll create a final method to see that it can’t be overridden.
3. Open the ProductApp class, and add this statement before the statement that
calls the getProduct method:
Product pTest = new Product();
4. If you’re using NetBeans, a syntax error should be displayed indicating that
the Product class is declared as abstract and cannot be instantiated. If this
error isn’t displayed, save or compile the ProductApp class so it is displayed.
5. Delete the statement you just added. Then, run the application to make sure it
works.
Add an abstract method to the Product class
6. Add an abstract method named getDisplayText to the Product class. This
method should accept no parameters, and it should return a String object.
Then, compile this class.
7. Rename the toString methods in the Book and Software classes to
getDisplayText.
8. Modify the ProductApp class so it calls the getDisplayText method of a
product instead of the toString method. Then, run the application to be sure it
works correctly.
Change the Book class to a final class
9. Add the final keyword to the Book class declaration.
10. Create a class named UsedBook that inherits the Book class. You don’t need
to include any code in the body of this class. If you’re using NetBeans, a
syntax error should be displayed indicating that the Book class can’t be
inherited because that class is final. If this error isn’t displayed, save or
compile the Book and UsedBook classes so it is displayed.
Add a final method
11. Remove the final keyword from the Book class declaration. Then, add the
final keyword to the getDisplayText method of the Book class.
12. Add a getDisplayText method to the UsedBook class to override the
getDisplayText method of the Book class. Code this method so it returns an
empty string. If you’re using NetBeans, a syntax error should be displayed
indicating that the getDisplayText method can’t be overridden because that
method is final. If this message isn’t displayed, save or compile the Book and
UsedBook classes so it is displayed.
13. Remove the final keyword from the getDisplayText method of the Book class.
Now, no syntax errors should be displayed. If you get a warning about the
@Override annotation, though, add this annotation to the getDisplayText
method of the UsedBook class.
274 Section 2 Object-oriented programming with Java
An introduction to interfaces
In some object-oriented programming languages, such as C++, a class can
inherit more than one class. This is known as multiple inheritance. Although
Java doesn’t support multiple inheritance, it does support a special type of
coding element known as an interface. An interface provides many of the
advantages of multiple inheritance without some of the problems that are
associated with it.
A simple interface
Figure 9-1 illustrates how you create and use an interface. Here, the first
example shows the code for a simple interface named Printable. This code is
similar to the code that defines a class and would be stored in a file named
Printable.java. However, the code for an interface uses the interface keyword
instead of the class keyword and contains only abstract methods.
The second example shows a Product class that implements the Printable
interface. To implement the Printable interface, the declaration for the Product
class uses the implements keyword followed by the name of the interface. Then,
the body of the Product class implements the print method that’s specified by
the Printable interface.
The third example shows that a Product object that implements the Printable
interface can be stored in a variable of the Printable type. In other words, an
object created from a Product class that implements the Printable interface is
both a Product object and a Printable object. As a result, you can use this object
anywhere a Printable object is expected. You’ll leam more about how this works
later in this chapter.
Chapter 9 How to work with interfaces 277
Example 3: Code that uses the print method of the Product class
Printable product =
new Product("java", "Murach's Beginning Java", 49.50);
product.print();
Resulting output
(f- ------ «
Code: 3 ava
Description: Murach's Beginning Java
Price: $49.50
----------ά
Description
• An interface defines a set of public methods that can be implemented by a class.
The interface itself doesn’t provide any code to implement the methods. Instead, it
provides the method signatures.
• A class that implements an interface must provide an implementation for each
method defined by the interface.
• An interface can also define public constants. Then, those constants are available to
any class that implements the interface.
Advantages of an interface
• A class can only directly inherit one other class, but it can directly implement
multiple interfaces.
• Any object created from a class that implements an interface can be used wherever
the interface is accepted.
Description
• The Java API defines many interfaces that you can implement in your classes. In
this chapter, you’ll see an example of a class that implements the Cloneable
interface.
• Since the Cloneable interface doesn’t contain any methods and is primarily used to
identify an interface as being safe for cloning, it’s known as a tagging interface.
Similarly, the EventListener interface is a tagging interface that identifies an
interface as a type of EventListener.
• The WindowListener and ActionListener interfaces inherit the EventListener
interface.
• This table only lists the most important members of each interface. For a complete
description of these interfaces and a list of their members, see the documentation
for the Java API.
Description
• Declaring an interface is similar to declaring a class except that you use the inter
face keyword instead of the class keyword.
• In an interface, all methods are automatically declared public and abstract, and all
fields are automatically declared public, static, and final. Although you can code
the public, abstract, and final keywords, they’re optional.
• Interface methods can’t be static.
System.out.printlnCDept:\t" + dept) ;
}
}
Description
• To declare a class that implements an interface, you use the implements keyword.
Then, you provide an implementation for each method defined by the interface.
• If you forget to implement a method that’s defined by an interface that you’re
implementing, the compiler will issue an error message.
• A class that implements an interface can use any constant defined by that interface.
Description
• A class can inherit another class and also implement one or more interfaces.
• If a class inherits another class that implements an interface, the subclass automati
cally implements the interface. However, you can code the implements keyword in
the subclass for clarity.
• If a class inherits another class that implements an interface, the subclass has
access to any methods of the interface that are implemented by the superclass and
can override those methods.
Resulting output
----- *
Code: java
Description: Murach's Beginning Java
Price: $49.50
Code: java
Description: Murach's Beginning Java
Price: $49.50
---------J
Resulting output
// Code : java
----- Λ
Description: Murach's Beginning Java
Price: $49.50
Code: java
Description: Murach's Beginning Java
Price: $49.50
v— ---------4
Description
• You can declare a parameter that’s used by a method as an interface type. Then,
you can pass any object that implements the interface to the parameter.
• You can also declare a variable as an interface type. Then, you can assign an
instance of any object that implements the interface to the variable, and you can
pass the variable as an argument to a method that accepts the interface type.
Description
• An interface can inherit one or more other interfaces by specifying the inherited
interfaces in an extends clause.
• An interface can’t inherit a class.
• A class that implements an interface must implement all the methods declared by
the interface as well as all the methods declared by any inherited interfaces unless
the class is defined as abstract.
• A class that implements an interface can use any of the constants declared in the
interface as well as any constants declared by any inherited interfaces.
ja v a
[d] ^roductConstants.;
'.java
lûïl^ProductDB.java
©Override
public Product getProduct(String code) {
throw new UnsupportedOperationException("Not supported y e t .");
}
©Override
public String getProductsStringQ {
throw new UnsupportedOperationException("Not supported y e t ."};
}
©Override
public boolean addProduct(Product p) {
throw new UnsupportedOperationException("Not supported y e t ."};
}
©Override
public boolean updateProduct(Product p) {
throw new UnsupportedOperationException("Not supported y e t . " ) t
}
©Override
public boolean deleteProduct(Product p) {
throw new UnsupportedOperationException("Not supported y e t ."};
}
}
Description
• To ad d an in terface to a p ro ject, rig h t-c lic k o n th e package y o u w an t to add th e
in terface to , select th e N ew -> Java In terface com m and, an d u se th e resu ltin g dialog
b o x to e n te r a nam e fo r th e interface.
• W hen co ding a class th a t im plem ents an in terface, you can autom atically generate
a ll th e m ethod declarations fo r th e interface. To do th at, create a new class as
described in ch ap ter 7 , use th e im plem ents keyw ord to id en tify th e in terface, click
on th e lig h t bulb ico n in th e le ft m argin, and select th e "Im plem ent a ll ab stract
m ethods” com m and.
Product <-■
<-
<-
« in te r f a c e » « in te r f a c e » « in te r f a c e »
ProductConstants ProductWriter ProductReader
Ί7\ “ /<r
\ I /
DAOFactory ' I /
N\ I /'
\ I /
____ I______ i_
l ____________________________________ « i n t e r f a c e »
--------------------------------------------------- > ProductDAO
ProductTextFile
->
Figure 9-10 The class diagram for the Product Maintenance application
296 Section 2 Object-oriented programming with Java
The console
Figure 9-11 shows the console for the Product Maintenance application. To
start, this application displays a welcome message and a list of five commands
that are recognized by the application (list, add, del, help, and exit). When the
user enters one of these commands, this application performs the appropriate
action.
If the user enters the list command, the application displays a list of all the
products that are currently stored in the file. A user might use this command
after the add or del command to verify that a product has been added or deleted
from the file.
If the user enters the add command, the application prompts the user to
enter a code, description, and price for the product. Once the user makes these
entries, the application adds the product to the file and displays an appropriate
message to the user.
If the user enters the del command, the application prompts the user for the
product’s code. Once the user enters a code for a product that exists in the file,
the application deletes the product and displays an appropriate message. How
ever, if the user enters an invalid code, the application displays a message that
indicates that the product couldn’t be found.
If the user enters the help command, the application displays the menu of
commands again. This command may come in handy if the menu has scrolled
off the screen.
Although it’s not shown here, alternate commands are provided for the
delete and help commands. For example, the user can enter either “del” or
“delete” to delete a product. Similarly, the user can enter either “help” or
“menu” to display the menu of commands.
To exit from this application, the user enters the exit command. Then, the
application displays a goodbye message and ends.
Chapter 9 How to work with interfaces 297
COMMAND MENU
list - List all products
add - Add a product
del - Delete a product
help - Show this menu
exit - Exit this application
PRODUCT LIST
java Murach's Beginning Java $49.50
jsps Murach's Java Servlets and JSP $49.50
cshp Murach's C# $49.50
mcb2 Murach's Mainframe COBOL $59.50
PRODUCT LIST
java Murach's Beginning Java $49.50
jsps Murach's Java Servlets and JSP $49.50
mcb2 Murach's Mainframe COBOL $59.50
txtp TextPad 7.4 $2 0 . 0 0
Bye.
λ
Description
• When this application first starts, it displays a menu of the commands the user can
enter. When the user enters one of these commands, the appropriate processing is
performed. Otherwise, an error message is displayed.
public ProductTextFile()
{
// code that initializes the fields
}
//*************************************************
// Implement the ProductReader interface
//*************************************************
public Product getProduct(String code)
{
// code that returns a Product
}
public String getProductsString()
{
// code that returns a String that lists all products
if (action.equalsIgnoreCaseC'list"))
displayAHProducts () ;
else if (action.equalsIgnoreCase("add"))
addProduct();
else if (action.equalsIgnoreCase("del") ||
action.equalsIgnoreCase("delete"))
deleteProduct();
else if (action.equalsIgnoreCase("help") ||
action.equalsIgnoreCase("menu"))
displayMenu();
else if (action.equalsIgnoreCase("exit"))
System.out.println("Bye.\n");
else
System.out.println("Error! Not a valid command.\n");
}
}
System.out.printlnO ;
System.out.println(description + " has been added.\n");
}
public static void deleteProduct()
{
String code = Validator.getString(sc,
"Enter product code to delete: ");
Product p = productDAO.getProduct(code);
System.out.printlnO ;
if (p != null)
{
productDAO.deleteProduct(p);
System.out.println(p.getDescription()
+ " has been deleted.\n");
}
else
{
System.out.printlnCNo product matches that product code.\n");
}
}
How to implement
the Cloneable interface
Occasionally, you may need to clone an object. When you clone an object,
you create a new instance of the object that contains all the same data as the first
object. To do that, you can call the clone method of the Object class. But first,
you must implement the Cloneable interface that’s in the java.lang package to
tell the compiler that it’s safe to use this method.
©Override
public Object clone() throws CloneNotSupportedException
{
return super.clone();
}
}
The result
(?- ------- *
Code: j ava
Description: Murach1s Beginning Java
Price: $49.50
Code: java
Description: Murach1s Beginning Java
Price: $44.50
V- ----------- J
Description
• You can use the clone method of the Object class to clone a user-defined class only
if the user-defined class implements the Cloneable interface.
• Since the clone method in the Object class has protected access, it is only available
to subclasses and other classes in the same package. To make this method available
to all classes, you can override the clone method of the Object class with a clone
method that has public access.
• The clone method returns an Object type.
• The clone method of the Object class throws a CloneNotSupportedException.
©Override
public Object clone() throws CloneNotSupportedException
{
Lineltem li = (Lineltem) super.clone();
Product p = (Product) product.clone();
li.setProduct(p);
return li;
}
}
The result
Code : java
Description: Murach's Beginning Java
Price: $49.50
Quantity: 3
Total: $148.50
Code : java
Description: Murach's Beginning Java
Price: $44.50
Quantity: 2
Total: $89.00
Description
• To clone an object that contains an instance variable for a mutable object, you need
to override the clone method and manually clone that object.
Perspective
In this chapter, you’ve learned how to use interfaces and how they can be
used to improve the design of an application. That means that you should now
be able to implement all types of classes that are commonly used in business
applications. In the next chapter, though, you’ll leam some additional object-
oriented skills that will round out your knowledge of object-oriented program
ming.
Summary
• An interface is a special type of coding element that can contain static constants
and abstract methods. Although a class can only inherit one other class, it can
implement more than one interface.
• To implement an interface, a class must implement all the abstract methods
defined by the interface. An interface can also inherit other interfaces, in which
case the implementing class must also implement all the methods of the inherited
interfaces.
• An interface defines a Java type. Because of that, you can use an object that’s
created from a class that implements an interface anywhere that interface is
expected.
• When you clone an object, you make an identical copy of the object.
• Before you can use the clone method of the Object class, you need to implement
the Cloneable interface. Then, you can override the clone method so it is public
and so it works correctly with mutable objects.
5. The updateProduct method should start by getting a valid product code from
the user. Then, it should ask the user if he wants to update the product’s
description or price. Depending on the user’s response, it should then accept a
new description or price from the user. Finally, it should call the
updateProduct method of the ProductDAO object to update the product and
print a line that indicates the update operation that was performed.
6. Run the ProductMaintApp class to make sure it works correctly.
An introduction to packages
Figure 10-1 shows the directories and files of the Line Item application
presented in chapter 7 after packages have been used to organize the classes in
that application. Here, the chlO_LineItem\src directory contains the
subdirectories for each package. Then, each subdirectory contains the classes
for a package. For example, the murach\business directory stores the Product
and Lineltem classes that define the business objects for this application.
When you name a package, you can use any name you want. However, if
you want to make sure that the name of your package is unique, it’s considered
a good practice to start the name with your Internet domain name in reverse. For
example, since our Internet domain name is murach.com, all packages created
by our company would begin with com.murach.
Even if you don’t follow this convention, you should avoid using a generic
name that might be used by someone else. For example, a package name of
business is too generic. However, murach.business is specific enough that it’s
unlikely to conflict with any other package names. For this book, I decided to
use just murach as the first level of the package name to clearly identify the
company that created these packages. Then, you can use the second level to
organize the packages within the first level.
Once you store a class in the correct directory, you must code a package
statement at the beginning of the class. This statement consists of the package
keyword followed by the name of the package. In this figure, for example, the
Lineltem, Product, and ProductDB classes each begin with a package statement
that corresponds with the directory that contains the class. Although you can
code comments before the package statement, that’s not usually necessary.
If a class is stored in a package, it can’t be accessed from classes in other
packages without qualifying it with the package name. As a result, you typically
import the class to make it easier to refer to. This works the same for the
packages and classes that you create as it does for the classes of the Java API. In
this figure, for example, the ProductDB class imports all the classes in the
murach.business package. As a result, the ProductDB class can use the Product
class, which is a member of this package, without qualification.
Chapter 10 Other object-oriented programming skills 313
import java.text.NumberFormat;
import java.text.NumberFormat;
import murach.business.*;
Description
• A package can store one or more classes. A package can also store interfaces,
although we’ll just focus on classes in this chapter.
• Each package name corresponds with a directory that has the same name. The
names you use should be unique to prevent conflicts with other packages.
• When you organize an application into packages, it’s common to store all the
classes in packages other than the default package. That includes the class that
contains the main method for the application, which is often stored in a directory
with a name that’s similar to the application name.
• When you store a class in a package, the first statement of the class must be a
package statement that specifies the name of the package.
• After the package statement, you can code the import statements for the class.
These statements work the same for the packages and classes that you create as
they do for the packages and classes of the Java API.
File Edit View Navigate Source Refactor Run Debug Profile Team Tools W in d o w Help Q » Search (Ctrl+I)
P ro jects ’ ProductDB,java s? | G T D 0 (ä
IQ
B· g j chlQ _L ineItem
•kiassi o b \m j
B - I £3 S o u r c e P a c k a g e s
έ ΐ-ÉFl m u ra c h .b u s in e s s
1 p a c k a g e m u r a c h .d a ta b a s e ;
2
ij L in e lte m , ja v a im p o r t m u r a c h . b u s i n e s s . * ;
3Ξ
i 5| P r o d u c t .ja v a
4
m u r a c h .d a ta b a s e p u b l i c c l a s s P ro d u c tD B
iH ^ProductDBjava {
Θ t± j m u ra c h .lin e ite m p u b lic s t a t i c P ro d u c t g e t P r o d u c t ( S t r i n g p ro d u c tC o d e )
- - |afe L in e lte m A p p .ja v a i
B - 't jf c J m u r a c h .p r e s e n ta tio n II I n a m o re r e a l i s t i c a p p l i c a t i o n , t h i s c o d e w o u ld
L - g V a lid a to r .ja v a // g e t th e d a t a f o r th e p r o d u c t fro m a f i l e o r d a ta b a s e
B - § L ib ra rie s
II F o r now , t h i s co d e j u s t u s e s i f r 'e l s e s ta te m e n ts
É - & JDK 1 . 7 ( D e fa u lt)
P r o d u c t p r o d u c t =■ new P r o d u c t ) ) ;
p r o d u c t . a e tC G d e ( p r o d u c tC o d e ) ;
if (p ro d u c tC o d e . e q u a l s I g n o r e C a s e a v a " ))
{
p r o d u c t . s e t D e s c r i p t i o n ( " M u r a c h 's s e g i n n i r . c J a v a " ) ;
p r o d u c t . s e t F n c e ( 4 9 .5 0 ) ;
)
e ls e i f ( p r o d u c t C o d e . e q u a l s I g n o r e C a s e ( 1: s p s " ) )
{
p r o d u c t . s e t D e s c r i p t i o n .v a c -. ' = J a v a S e r v l e t s ar.S J 3 P )
p r o d u c t . s e t P r i c e ( 4 2 .5 0 ) ;
I»
111 INS
Description
• To navigate th ro u g h ex istin g pack ag es, u se th e P ro jects w indow to expand o r
collapse th e packages w ith in a project.
• To ad d a new package to a p ro ject, rig h t-c lic k o n th e p ro ject nam e o r th e Source
Packages fo ld er in th e P ro jects w indow , select th e N ew -> Java P ackage com m and,
and en ter th e nam e o f th e package in th e resu ltin g dialo g box. T h is creates a
directory, i f necessary, as w ell as a subdirectory w ith in th a t directory.
• I f you specify a pack ag e w hen y o u add a new class and th a t package d o e sn 't
alread y ex ist, it’s autom atically created fo r you.
• To rem ove a package fro m a p ro ject, rig h t-click on th e pack ag e and select th e
D elete com m and fro m th e resu ltin g m enu. T h is deletes th e d irecto ry fo r th e pack
age and a ll subdirectories and files w ith in th a t directory.
• I f you add a new class to a package, N etB eans autom atically adds th e necessary
package statem ent to th e class.
• To renam e a package, u se th e R efactor-> R enam e com m and. T hen, N etB eans
autom atically m odifies th e pack ag e statem ent.
• To m ove a class fro m one pack ag e to another, d rag it in th e P rojects w indow . T hen,
click th e R efactor bu tto n in th e M ove C lass dialo g b o x th at’s displayed so
N etB eans m odifies th e package statem ent.
© B - H - l murach.product 9 p u b l i c c l a s s P r o d u c tA p p
■■ ProductApp.java 10 {
Θ '- g Libraries 11 p u b l i c s t a t i c v o i d m a in ( S t r i n g a r g s } ] )
f f l- β chlO_MurachLib.jar 12 R t
i t d i s p l a y a w elc o m e ir .s s s a a e
a -8 JDK 1 ,7 [Default)
S y s te m . p r i n t l n ( "W eclom e t o th e P ro d u c t S e le c to r" )
O u tp u t - c h 10 _P ro d uct(run )
SïLïCTïD PRODUCT
Description: Murach'9 Beginning Java
Price : $43.5ΰ
Continue? (y/n): n
Description
• A library can sto re one o r m ore p ackages th a t each contains one o r m ore classes.
• W hen you create a lib rary u sin g N etB eans, th e lib rary is sto red in a Java Archive
(JAR) file.
• A fter you create a library, you can m ake it av ailable to o th er program m ers b y
storing it in a cen tral lo cation.
import java.text.NumberFormat;
/***********************************************************
* Creates a new Product with default values.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * j
public Product()
{
code = 1111;
description = "" ;
price = 0 ;
}
/ * * * * * * * .......* * * * * ......... * * * * * * ........ * * * * * * ....... * * * * * ........ * * * * *
* Sets the product code to the specified String.
***********************************************************/
public void setCode(String code)
{
this.code = code;
}
/ * * * * * * * .......* * * * * ......... * * * * * * ........ * * * * * * ....... * * * * * ........ * * * * *
* Returns a String that represents the product code.
***********************************************************/
public String getCodeO
{
return code;
}
Description
• A javadoc comment begins with /** and ends with */, and asterisks within the
comment are ignored. You can use javadoc comments to describe a class and its
public and protected fields, constructors, and methods.
• A comment should be placed immediately above the class or member it describes.
For a class, that means that the comment must be placed after any import state
ments.
• If you enter a slash (/) followed by two or more asterisks on a blank line before the
code for a class, field, constructor, or method in NetBeans, NetBeans generates
beginning javadoc comments. That includes comments with some of the javadoc
tags you’ll leam about in the next figure.
Figure 10-4 How to add javadoc comments to a class
320 Section 2 Object-oriented programming with Java
The Product class with comments that use HTML and javadoc tags
package murach.business;
/******************************************************************
* The <code>Product</code> class represents a product and is used
* by the <code>LineItem</code> and <code>ProductDB</code> classes.
* ©author Joel Murach
* ©version 1 .0 . 0
....... * * * * * * ....... * * * * * ....... * * * * * * ........ * * * * * * ....... * * * * * .........* * * * * * * * /
public class Product {
private String code;
private String description;
private double price;
/**************************************************************
* Creates a <code>Product</code> with default values.
* * * * * * * ....... * * * * * ....... * * * * * * ........ * * * * * * ....... * * * * * .........* * * * * * * * /
public Product(){
code = "";
description =
price = 0 ;
}
/**************************************************************
* Sets the product code to the specified <code>String</code>.
* @param code A <code>String</code> for the product code.
*************************************************************/
public void setCode(String code){
this.code = code;
}
/**************************************************************
* Returns a <code>String</code> that represents the product code.
* ©return A <code>String</code> for the product code.
*************************************************************/
public String getCode(){
return code;
}
Figure 10-5 How to use HTML and javadoc tags in javadoc comments
322 Section 2 Object-oriented programming with Java
& i |J file:///C:/murach/java/netbeans/bot>k_apps/chlO_Lineltern/dist/jayadoc/Tndex.t ^ - |
P ro du ct
Packages
Prev Class Next Class Frames No Frames
murach.cusiness S u m m a ry : N e s t e d 1 F ie ld | C o n s tr : M e th o d D e ta il: F ie ld i C o n s tr | M e th o d
murach. dataoase
murach. lineitem murach.business
murach.presentation
Class Product
java.lang.Object
murach. cusiness.Product
p u b lic c la s s P ro d u ct
Classes e x te n d s j a v a . l a n g . O b je c t
Line lte m The Product class represents a product and is used Cythe Lineltem class.
iProducI
Constructor Summary
Method Summary
f iIe / / / C :/m u rach/java/ n etb ea n s/bo o k_a pps''c hlO J_in eltem /dist/j ava do c/m u rach/b u siness/P ro d uct.htm I
Description
• To generate o r view th e docum entation fo r a p ro je c t from N etB eans, you can rig h t-
click o n th e p ro ject in th e P rojects w indow an d select th e “G enerate Javadoc”
com m and. W hen you do , N etB eans generates th e Jav a docum entation fo r th e
p ro ject and d isplays it in th e d efau lt w eb brow ser.
• B y d efau lt, N etB eans stores th e docum entation fo r a p ro ject in a subdirectory
nam ed distVjavadoc th a t’s subordinate to th e p ro ject’s ro o t directory.
• I f th e p ro ject alread y contains docum entation, N etB eans overw rites ex istin g files
w ithout any w arning.
• Y ou can view th e g en erated docum entation b y startin g a w eb b ro w ser and navigat
in g to th e in dex.htm l file th a t’s created in th e distVjavadoc directory.
Figure 10-6 How to generate and view the documentation for a package
324 Section 2 Object-oriented programming with Java
}
class Product
{
// body of Product class
}
The class files that are generated when the code above is compiled
Lineltem.class
Product.class
Description
• When you code two or more classes in the same file, you can only have one public
class in the file, and that class should be declared first.
• The name of a file that contains two or more classes must be the same as the name
of the public class.
Figure 10-7 How to code more than one class per file
326 Section 2 Object-oriented programming with Java
Description
• A nested class is a class that’s coded within the block of code for another class.
• When you nest classes, the outer class must be declared public and must have the
same name as the file name of the class.
• Within an outer class, you can nest inner classes and static inner classes. Since the
inner classes are members of the outer class, they are sometimes called member
classes.
• A class can also be nested inside a method or any other type of block. These types
of classes are sometimes called local classes.
Description
• An enumeration contains a set of related constants. The constants are defined with
the int type and are assigned values from 0 to the number of constants in the
enumeration minus 1.
• An enumeration defines a type. Because of that, you can’t specify another type
where an enumeration type is expected. That means that enumerations are type-
safe.
• To add an enumeration to a project using NetBeans, right-click on the package you
want to add the enumeration to and select the New->Other command. Select Java
Enum as the file type from the dialog box that’s displayed, click the Next button,
and use the resulting dialog box to enter a name for the enumeration.
©Override
public String toString()
{
String s = "" ;
if (this.ordinal() == 0)
s = "UPS Next Day (1 business day)";
else if (this.ordinal() == 1)
s = "UPS Second Day (2 business days)";
else if (this.ordinal() == 2)
s = "UPS Ground (5 to 7 business days)";
return s;
}
}
Code that uses the toString method
ShippingType ground = ShippingType.UPSGROUND;
System.out.println("toString: " + ground.toString() + "\n");
Resulting output
[ toString; UPS Ground (5 to 7 business days) ]
Description
• All enumerations inherit the java.lang.Object and java.lang.Enum classes and can
use or override the methods of those classes or add new methods.
• By default, the toString method of an enumeration constant returns the same string
as the name method.
• You can use a static import to import all of the constants of an enumeration or all of
the static fields and methods of a class.
Figure 10-10 How to enhance an enumeration and work with static imports
332 Section 2 Object-oriented programming with Java
Perspective
Now that you’ve finished this chapter, you should be able to package and
document your classes so other programmers can use them. You should also be
able to apply the appropriate technique for coding classes that are closely
related, and you should be able to create and work with enumerations. With
these skills, you’ll be able to implement the classes, interfaces, and enumera
tions that are commonly used in business applications.
Summary
• You can use packages to organize the classes in your application. Then, you can
use import statements to make the classes in that package available to other
classes.
• You can use a library to make packages and classes available to other applications.
When you use NetBeans to create a library, it’s stored in a Java Archive (JAR) file.
• You can use javadoc comments to document a class and its fields, constructors,
and methods. Then, you can generate HTML-based documentation for your class.
• When two or more classes are closely related, it sometimes makes sense to store
them all in one file or to nest them.
• You can use an enumeration to define a set of related constants as a type. Then,
you can use the constants in the enumeration anywhere the enumeration is al
lowed.
• You can use static imports to import the constants of an enumeration or the static
fields and methods of a class. Then, you can refer to the constants, fields, and
methods without qualification.
4. Compile the Customer class. Then, view the files in the build\classes
subdirectory of the project. This subdirectory should contain .class files for
both the Customer and Address classes. This shows that the Customer.java file
now stores two classes.
Other examples
An array of String objects
String[] titles = new String[3];
Description
• An array can store more than one primitive type or object. An element is one of the
items in an array.
• To create an array, you must declare a variable of the correct type and instantiate an
array object that the variable refers to. You can declare and instantiate the array in
separate statements, or you can combine the declaration and instantiation into a
single statement.
• To declare an array variable, you code a set of empty brackets after the type or the
variable name. Most programmers prefer coding the brackets after the array type.
• To instantiate an array, you use the new keyword and specify the length, or size, of
the array in brackets following the array type. You can specify the length by coding
a literal value or by using a constant or variable of type int.
• When you instantiate an array of primitive types, numeric types are set to zeros and
boolean types to false. When you create an array of objects, they are set to nulls.
The syntax for creating an array and assigning values in one statement
type [] arrayName = (valuel, value2, value3, ...};
Description
• To refer to the elements in an array, you use an index that ranges from zero (the
first element in the array) to one less than the number of elements in the array.
• If you specify an index that’s less than zero or greater than the upper bound of the
array, an ArraylndexOutOfBoundsException will be thrown when the statement is
executed.
• You can instantiate an array and provide initial values in a single statement by
listing the values in braces. The number of values you provide determines the size
of the array.
Description
• You can use the length field of an array to determine how many elements are
defined for the array.
• For loops are often used to process each element in an array.
Description
• Version 1.5 of the JDK introduced a new form of the for loop called an enhanced
fo r loop. The enhanced for loop simplifies the code required to loop through arrays.
The enhanced for loop is sometimes called a foreach loop because it lets you
process each element of an array.
• Within the parentheses of an enhanced for loop, you declare a variable with the
same type as the array followed by a colon and the name of the array.
• With each iteration of the loop, the variable that’s declared by the for loop is
assigned the value of the next element in the array.
Note
• You can also use foreach loops to work with collections. See chapter 12 for details.
Description
• All of these methods accept arrays of primitive data types and arrays of objects for
the arrayName argument, and they all accept primitive types and objects for the
value argument.
• All of the index arguments for these methods must be int types. If an index argu
ment is less than zero or greater than one less than the length of the array, the
method will throw an ArraylndexOutOfBoundsException.
• If you use the sort method on an array of objects created from a user-defined class,
such as the Product class, the class must implement the Comparable interface as
shown in figure 11-7.
• The copyOf and copyOfRange methods were introduced with JDK 1.6. As a result,
they won’t work with older versions of the JDK.
Example 2: Code that uses the fill method to fill 3 elements in an array
int[] quantities = new i n t [5];
Arrays.fill(quantities, 1, 4, 100); // elements 1, 2, and 3 are set to 100
if (titlesl == titles2 )
System.out.println("titlesl == titles2 is true");
else
System.out.println("titlesl == titles2 is false");
if (Arrays.equals(titlesl, titles2))
System.out.println("Arrays.equals(titlesl, titles2) is true");
else
System.out.println("Arrays.equals(titlesl, titles2) is false");
Description
• You can use the sort method of the Arrays class to sort an array of objects only if the class
that defines those objects implements the Comparable interface. To implement this inter
face, a class must define the compareTo method.
• The compareTo method must return -1 if the current object is less than the passed object, 0
if the objects are equal, and 1 if the current object is greater than the passed object.
Figure 11-7 How to implement the Comparable interface
354 Section 3 More Java essentials
Example 4: Code that copies part of one array into another array
double[] grades = {92.3, 88.0, 95.2, 90.5};
Arrays.sort(grades) ;
doublet] lowestGrades = Arrays.copyOfRange(grades, 0, 2);
doublet] highestGrades = Arrays.copyOfRange(grades, 2, 4);
Example 6: Code that copies part of one array into another array
double[] grades = {92.3, 88.0, 95.2, 90.5};
Arrays.sort(grades) ;
doublet] lowestGrades = new double[2];
System.arraycopy(grades, 0, lowestGrades, 0, 2) ;
double[] highestGrades = new double[2];
System.arraycopy(grades, 2, highestGrades, 0, 2) ;
Description
• To create a reference to an existing array, code an assignment statement like the one
shown in the first example. Then, two variables will point to the same array
in memory.
• To copy the elements of one array into another with JDK 1.6 or later, use the
copyOf or copyOfRange methods of the Arrays class. Prior to JDK 1.6, use the
arraycopy method of the System class.
• When you copy an array, the new array must be the same type as the source array.
How to work
with two-dimensional arrays
So far, this chapter has shown how to work with an array that uses one
index to store a single set of elements. You can think of that as a one-dimen-
sional array. Now, you’ll learn how to work with two-dimensional arrays that
use two indexes to store data. You can think of a two-dimensional array as a
table made up of rows and columns where each element in the array is at the
intersection of a row and column.
If you’re familiar with array processing in other languages such as C++ or
even Visual Basic, you may be surprised to discover that Java doesn’t directly
support two-dimensional arrays in the same way those languages do. Instead,
Java implements a two-dimensional array as an array o f arrays where each
element of the first array is itself an array. Although the syntax is different, the
effect is nearly the same.
Description
• Two-dimensional arrays use two indexes and allow data to be stored in a table that
consists of rows and columns. This can also be thought of as an array o f arrays
where each row is a separate array of columns.
• A rectangular array is a two-dimensional array whose rows all have the same
number of columns.
• Although it’s rarely necessary, you can extend this two-dimensional syntax to work
with arrays that have more than two dimensions.
Although it’s not shown in figure 11-9, you should realize that you can also
use nested foreach loops to work with rectangular arrays. To do that, you
declare an array variable in the outer for loop that you can use to refer to the
rows in the array. Then, you declare a variable in the inner for loop that you can
use to refer to the columns in each row. For example, figure 11-10 uses nested
foreach loops to work with another type of two-dimensional array called a
jagged array.
Example 4: Code that prints the contents of the jagged array of integers
for (int i = 0 ; i < pyramid.length; i++)
{
for (int j = 0 ; j < pyramid[i].length; j++)
System.out.print(pyramid[i] [j] + " ■) ;
System.out.print("\n") ;
}
The console output
Description
• A jagged array is a two-dimensional array whose rows have different numbers of
columns. When you create a jagged array, you specify the number of rows in the
array, but you leave the size of each column array unspecified and set it later.
Perspective
Now that you’ve finished this chapter, you should know how to work with
one-dimensional and two-dimensional arrays. Although you’ll use arrays in
many applications, they may not always provide the functionality you need. In
that case, you can use a more advanced data structure called a collection.
You’ll learn how to work with collections in the next chapter.
Summary
• An array is a special type of object that can store more than one primitive data type
or object. The length (or size) of an array is the number of elements that are stored
in the array. The index is the number that is used to identify any element in the
array.
• For loops are often used to process arrays. Version 1.5 of the JDK introduced a new
type of for loop, called an enhanced for loop or a foreach loop, that lets you process
each element of an array without using indexes.
• You can use the Arrays class to fill, compare, copy, sort, and search arrays. You can
use an assignment statement to create a second reference to the same array.
• To provide for sorting a user-defined class, that class must implement the Compa
rable interface.
• A one-dimensional array provides for a single list or column of elements so just one
index value is required to identify each element. In contrast, a two-dimensional
array, or an array o f arrays, can be used to organize data in a table that has rows
and columns. As a result, two index values are required to identify each element.
• A two-dimensional array can be rectangular, in which case each row has the same
number of columns, or jagged, in which case each row has a different number of
columns.
4. Use the sort method of the Arrays class to sort the values in the array, and print
the median value (the 50th value) on the console followed by a blank line. Then,
test this enhancement.
5. Print the 9th value of the array on the console and every 9th value after that.
Then, test this enhancement.
the string it’s executed on with the string that’s passed to it as an argument. If
the first string is less than the second string, this method returns a negative
integer. If the first string is greater than the second string, it returns a positive
integer. And if the two strings are equal, it returns 0.
3. Add code to the SortedCustomersApp class that creates an array of Customer
objects that can hold 3 elements, and create and assign Customer objects to
those elements. Be sure that the email values you assign to the objects aren’t in
alphabetical order. Sort the array.
4. Code a foreach loop that prints the email, firstName, and lastName fields of each
Customer object on a separate line.
5. Test the program until you’re sure it works correctly.
Description
• A collection is an object that can hold other objects. Collections are similar to
arrays, but are more flexible to use and are more efficient than arrays for many
applications.
Collection interfaces
Interface Description
Collection Defines the basic methods available for all collections.
Set Defines a type of collection in which no duplicate elements are allowed.
List Defines a type of collection that maintains the order in which elements were added to
the list.
Map Defines a map, which is similar to a collection but holds one or more key value pairs
instead of simple elements. Each key-value pair consists of a key that uniquely
dentifies an entry and a value that provides data associated with a particular key.
Description
• The Java collection framework is interface based, which means that each class in the
collection implements one of the interfaces defined by the collection framework.
• The collection framework consists of two class hierarchies: Collection and Map.
Collections store individual objects as elements. Maps store pairs of key objects and
value objects in a way that lets you retrieve a value object based on its key.
• Although there are many classes in the Java collection framework, the most commonly
used classes are the ArrayList, LinkedList, HashSet, HashMap, and TreeMap classes.
However, you’ll also learn the basic skills for working with the HashMap and
TreeMap classes. If you want to learn more about these classes, though, or you
want to learn about the HashSet class, you shouldn’t have any trouble doing that
using the Java API documentation.
An introduction to generics
Prior to Java 1.5, the elements of a collection were defined as type Object. As
a result, you could store any type of object as an element in a collection. At first,
this flexibility might seem like an advantage. But with it comes two disadvantages.
First, there’s no way to guarantee that only objects of a certain type are added to a
collection. For example, you can’t limit an ArrayList so it can hold only Product
objects. Second, you must use casting whenever you retrieve an object from a
collection. That’s because an element can be any type of object. For example, to
retrieve a Product object from a collection, you must cast the object to a Product.
Java 1.5 introduced a new feature called generics that addresses these two
problems. The generics feature lets you specify the element type for a collection.
Then, Java can ensure that only objects of the specified type are added to the
collection. And any objects you retrieve from the collection are automatically cast
to the correct type.
Figure 12-3 shows how the generics feature works. To specify a type when you
declare a collection, you code the type in angle brackets immediately following the
name of the collection class (such as ArrayList or LinkedList). Prior to Java 1.7,
you had to do this twice: once when you use the collection class to declare the
collection, and again when you use the constructor of the collection class to create
an instance of the collection. As I’ll explain in a moment, though, Java 1.7 intro
duced a feature that lets you simplify this code.
The first example shows a statement that declares and instantiates an instance
of an array list collection named codes that will hold String objects. Here,
<String> is specified following the ArrayList class name to indicate that the
elements of the array list must be String objects. The second and third examples
are similar, but they create collections that can hold integers and Product objects.
In the second example, a wrapper class is specified as the type instead of the
primitive type. That’s necessary because a collection can only hold objects, not
primitive types. But if you declare a collection with a wrapper type, you can store
values of the related primitive type in that collection.
If you’re using Java 1.7 or later, you can omit the type from the brackets that
follow the constructor as long as the compiler can infer the type from the context.
This is illustrated in the fourth example in this figure, which works the same as the
first example. Because this feature simplifies your code, I’ll use it in most of the
remaining examples in this chapter.
You can also create your own classes that use generics. To do that, you specify
one or more type variables in angle brackets following the class name as shown in
the fifth example. Here, the type variable is specified as E. Then, you can use this
variable within the class anywhere you would normally specify a type. You’ll learn
more about how this works later in this chapter.
Chapter 12 How to work with collections and generics 369
The syntax for using type inference with JDK 1.7 or later
CollectionClass<Type> collectionName = new CollectionClasso();
Description
• Generics refers to a feature introduced with Java 1.5 that lets you create typed collec
tions. A typed collection is a collection that can hold only objects of a certain type.
• To declare a variable that refers to a typed collection, you list the type in angle brack
ets (<>) following the name of the collection class.
• When you use a constructor for a typed collection, you can specify the type variable
in angle brackets following the constructor name. The type variable can’t be a primi
tive type such as int or double, but it can be a wrapper class such as Integer or Double.
It can also be a user-defined class.
• Beginning with Java 1.7, you can omit the type from within the brackets that follow
the constructor if the compiler can infer the type from the context. This empty set of
brackets is known as the diamond operator.
• If you do not specify a type for a collection, the collection can hold any type of object.
However, the Java compiler will issue warning messages whenever you access the
collection to warn you that type checking can’t be performed for the collection.
• To create a generic class that lets you specify type information, specify one or more
type variables in angle brackets following the class name on the class statement.
Then, you can use the type variable within the class anywhere you would normally
specify a type.
Description
• An array list is a collection that’s similar to an array, but can change its capacity as
elements are added or removed. The ArrayList class uses an array to store the
elements it contains.
• You can specify the type of elements to be stored in the array list by naming a type
in angle brackets.
• You can specify the size of an array list when you create it, or you can let the array
list default to an initial capacity of 10 elements.
• The capacity of an array list automatically increases whenever necessary.
Resulting output
[warp, mbdk, citr]
Resulting output
[wuth]
Resulting output
[ [1, 2, 3] 1
Description
• When you use generics to create a collection that holds a wrapper type, the com
piler automatically converts the primitive type to its wrapper type and vice versa
using a technique called autoboxing.
Method Description
void addltem(Lineltem lineltem) Adds the specified line item to the invoice.
ArrayList getLineltems() Returns an ArrayList object that contains
the line items for the invoice.
double getlnvoiceTotal() Returns a double that contains the sum of
the totals for the line items in the invoice.
String getFormattedTotal() Returns a String that contains the invoice
total formatted as currency.
Description
• The user enters a product code and quantity for each line item to be added to the
invoice. When the user indicates that all of the line items have been entered, the appli
cation displays each line item on a separate line along with the total for the invoice.
• The Product, ProductDB, Validator, and Lineltem classes are described in chapter 7.
// the constructor
public Invoice()
{
lineltems = new A r r a y L i s t o () ;
}
// a method that adds a line item
public void addltem(Lineltem lineltem)
{
this.lineltems.add(lineltem);
}
// the get accessor for the line item collection
public ArrayList<LineItem> getLinelterns()
{
return lineltems;
}
// a method that gets the invoice total
public double getlnvoiceTotal()
{
double invoiceTotal = 0;
for (Lineltem lineltem : this.lineltems)
{
invoiceTotal += lineltem.getTotal();
}
return invoiceTotal;
}
// a method that returns the invoice total in currency format
public String getFormattedTotal()
{
NUmberFormat currency = NumberFormat.getCurrencylnstance();
return currency.format(this.getlnvoiceTotal());
}
}
Description
• A linked list is a collection that’s similar to an array list. However, the LinkedList
class doesn’t use an array to store its elements. Instead, each element in the list
contains pointers that are used to refer to adjacent elements.
• You can specify the type of elements the linked list can contain by listing the type
in angle brackets.
• The LinkedList class contains methods that let you perform more advanced opera
tions than the ArrayList class.
Figure 12-9 The LinkedList class
382 Section 3 More Java essentials
System.out.println(codes) ;
Resulting output
[warp, mbdk, citr]
Example 2: Code that adds elements to the beginning and end of the list
codes.addFirst("wuth");
codes.addLast("wooz") ;
System.out.println(codes) ;
Resulting output
[wuth, warp, mbdk, citr, wooz]
Example 3: Code that uses an enhanced for loop to process the list
for (String s : codes)
System.out.println(s);
Resulting output
/f-----
wuth;------------------------ ------------------------
warp
mbdk
citr
wooz
Example 4: Code that retrieves the first and last elements of the list
String firstString = codes.removeFirst();
String lastString = codes.removeLast();
System.out.println(firstString) ;
System.out.println(lastString);
System.out.println(codes) ;
Resulting output
-----------------*
wuth
wooz
[warp, mbdk, citr]
--------------- 4
Resulting output
(f- ---------- «
The queue contains 3 items
Item One
Item Two
Item Three
The queue now contains 0 items
V- ---------- è
Description
• A queue is a first-in, first-out collection. To implement a queue, you can use a
linked list as shown above.
• A class that implements a queue is typically declared with a type variable that’s
used to specify the type of objects the queue will hold.
Figure 12-11 A class that uses a linked list to implement a generic queue
386 Section 3 More Java essentials
An enhanced version
of the Invoice application
The following topics present an enhanced version of the Invoice application
that was presented earlier in this chapter. This version illustrates one way to use
a linked list in an application.
Number Total
1 $49.50
2 $99.00
Total for all invoices: $148.50
V ----
Description
• This version of the Invoice application lets the user enter more than one invoice.
The invoices are stored in a queue created from the GenericQueue class that was
presented in figure 12-11.
• When the user has finished entering invoices, the application displays the invoice
number and total for each invoice. Then, the application displays the total for all the
invoices that were entered.
• The Invoice application assigns an invoice number to each invoice, starting with 1
for the first invoice entered. However, the invoice number isn’t stored as a part of
the Invoice object.
When the user indicates there are no more invoices to enter, control returns
to the main method. Then, this method calls the displaylnvoices method to
display information for each invoice. This method uses a while loop that ex
ecutes as long as the size method of the invoices collection indicates that there
is at least one more invoice in the queue. Variables named invoiceNumber and
batchTotal are used to keep track of the invoice numbers and totals for the
invoices that were entered. Within the loop, the pull method is called to retrieve
each Invoice object from the queue. Next, the println method is called to display
the invoice number and the total for the invoice, the invoice number is
incremented, and the invoice total is added to the batchTotal variable. After all
of the invoices have been displayed, the batchTotal value is formatted and
displayed.
Chapter 12 How to work with collections and generics
Description
• A map is a collection that contains values that are associated with keys. The two most
commonly used classes that implement maps are HashMap and TreeMap.
• The main difference between a hash map and a tree map is that a tree map automatically
maintains entries in order based on the key values. In contrast, a hash map doesn’t main
tain its entries in sorted order. If an application doesn’t require that the entries be kept in
order, a hash map is often more efficient than a tree map.
• Each entry of a map implements the Map.Entry interface in the java.util.Map package. You
can use two of the methods provided by this interface to get the key and value for an entry.
Note
• You can use a custom class for the key objects of a hash map. To do that, the class
must override the hashCode and equals methods inherited from Object. For more
information, see the Java documentation.
Resulting output
/r~ wuth: Wuthering Heights -------------- Λ
mbdk: Moby Dick
wooz: Wizard of Oz
Resulting output
----------------------- *
f mbdk: Moby Dick
wooz: Wizard of Oz
wuth: Wuthering Heights
Figure 12-15 Code examples that work with hash maps and tree maps
396 Section 3 More Java essentials
Resulting output
f - warp ------------------------ *
mbdk
citr --------------------------------------- i
Description
• The collection hierarchy was introduced with Java 1.2. For compatibility reasons,
Java still supports older collection classes such as Vector, HashTable, and Stack.
However, you should avoid using these classes for new program development.
• The classes listed in this figure aren’t deprecated. They are still fully supported as
part of the Java API.
• The Vector class was the most commonly used legacy collection class. Because the
newer ArrayList class is an improved version of the Vector class, the code used to
work with a vector is similar to the code used to work with an array list.
Resulting output
(r- ---------- ^
dctp Duct Tape $4.95
blwr Bailing Wire $14.95
cgum Chewing Gum $0.95
V- ----------------- 4
Description
• Code written before Java 1.5 uses untyped collections, which don’t use generics to
specify the element type.
• Untyped collections hold elements of type Object. No special coding is required to
add objects to an untyped collection. However, you must typically use a cast to
retrieve objects from an untyped collection.
• Versions 1.5 and later of the Java compiler generate a warning message whenever
you add an element to an untyped collection.
numbers.add(new Integer(1));
numbers.add(new Integer(2 ));
numbers.add(new Integer(3));
Description
• Because untyped collections hold elements of type Object, they can’t hold primi
tive types. As a result, you must use wrapper classes to store primitive types in a
collection.
• To add a primitive type to an untyped collection, create an instance of the appropri
ate wrapper class and pass the value you want it to hold to the constructor of that
class.
• To retrieve an element that holds a primitive type, cast the element to the wrapper
type. Because wrapper types can automatically be converted to their corresponding
primitive types, you can assign the wrapper type to a primitive type variable
without any explicit casting.
Perspective
Now that you’ve finished this chapter, you should know how to work with
array lists and linked lists, the two most commonly used Java collections. You
should also know how to use hash maps and tree maps to work with collec
tions that store key-value pairs. Finally, you should know how to work with
legacy collections in case you ever come across older programs that use them.
However, you should also understand that the interfaces and classes for
working with collections that were presented in this chapter only begin to
scratch the surface of what’s available from the Java API. Many other classes
for working with collections have become available with versions 1.5 and 1.6
of Java, and each of these classes provides functionality that’s useful in certain
situations. As a result, if the collections presented in this chapter don’t provide
the functionality that your program requires, there’s a good chance that the
Java API already includes a collection that provides this functionality. To find
the collection that you need and to learn how it works, you can start by looking
in the documentation for the java.util package. Then, you can use many of the
same skills that were presented in this chapter to work with the collection.
Summary
• A collection is an object that’s designed to store other objects.
• The two most commonly used collection classes are ArrayList and LinkedList. An
array list uses an array internally to store its data. A linked list uses a data structure
with next and previous pointers.
• The generics feature, which became available with Java 1.5, lets you specify the
type of elements a collection can store. This feature also lets you create generic
classes that work with variable data types.
• The diamond operator, which became available with Java 1.7, allows you to code
an empty set of brackets (<>) in the constructor of a typed collection instead of
having to code the type within those brackets.
• A map is a collection that contains key-value pairs.
• The two most commonly used map classes are HashMap and TreeMap. The main
difference between these two types of maps is that a tree map maintains its entries
in key sequence and a hash map does not.
• Code that was written before Java 1.5 used untyped collections, which hold
elements of type Object. To retrieve an element from an untyped collection, you
typically have to use casting. To store primitive types in an untyped collection, you
have to use wrapper classes.
Chapter 12 How to work with collections and generics 403
8. Run the project. If it works correctly, your output should look something like this:
0 - -------------- Λ
Push: Apples
Push: Oranges
Push: Bananas
The stack contains 3 items
Peek: Bananas
The stack contains 3 items
Pop: Bananas
Pop: Oranges
Pop: Apples
The stack contains 0 items
V- ------------ J
13
How to work with
dates and strings
In section 1 of this book, you learned some basic skills for working with
strings. In this chapter, you’ll learn more about working with strings, and you’ll
learn how to work with dates. Because you’ll use dates and strings in many of
the applications that you develop, you should know how to use all of the skills
presented in this chapter.
Description
• Year must be a four-digit integer.
• Month must be an integer from 0 to 11 with 0 being January and 11 being December.
• Day must be an integer from 1 to 31.
• Hour must be an integer from 0 to 23, with 0 being 12 AM (midnight) and 23 being
11PM.
• Minute and second must be integers from 0 to 59.
Figure 13-1 How to use the GregorianCalendar class to set dates and times
408 Section 3 More Java essentials
Note
• For more information about these and other fields and methods, look up the Calen
dar and GregorianCalendar classes in the documentation for the Java API.
Figure 13-2 How to use the Calendar and GregorianCalendar fields and methods
410 Section 3 More Java essentials
Common constructors
Constructor Description
Date () Creates a Date object for the current date and time based
on your computer’s internal clock.
D a t e ( l o n g M i l li s e c o n d s ) Creates a Date object based on the number of milliseconds
that is passed to it.
Common methods
Method Description
getTime () Returns a long value that represents the number of milliseconds for the date.
toString () Returns a String object that contains the date and time formatted like this:
Wed Aug 04 08:31:25 PDT 2009.
Example 2: A statement that gets a Date object for the current date/time
Date now = new D a t eO ;
Example 4: Code that calculates the number of days between two dates
Date startDate = gregStartDate.getTime();
Date endDate = gregEndDate.getTime();
long startDateMS = startDate.getTime();
long endDateMS = endDate.getTime();
long elapsedMS = endDateMS - startDateMS;
long elapsedDays = elapsedMS / (24 * 60 * 60 * 1000) ;
Description
• A Date object stores a date and time as the number of milliseconds since January 1,
1970 00:00:00 GMT (Greenwich Mean Time).
• You need to convert GregorianCalendar objects to Date objects when you want to
use the DateFormat class to format them as shown in the next figure.
• Date objects are also useful when you want to calculate the number of milliseconds
(or days) between two dates.
Common fields
Style Date example Time example
SHORT 12/31/10 12:00 AM
MEDIUM Dec 31, 2010 7:30:00 PM
LONG December 31, 2010 7:30:00 AM PST
FULL Saturday, December 31, 2010 7:30:00 AM PST
Common method
Method Description
format (Date) Returns a String object of the Date object with the
format that’s specified by the DateFormat object.
Example 3: Code that overrides the default date and time formats
DateFormat shortDate = DateFormat.getDatelnstance(DateFormat.SHORT);
DateFormat shortTime = DateFormat.getTimelnstance(DateFormat.SHORT);
DateFormat shortDateTime =
DateFormat.getDateTimelnstance(DateFormat.SHORT, DateFormat.SHORT);
Description
• You can use the DateFormat class to format Date objects in various ways.
Figure 13-4 How to use the DateFormat class to format dates and times
414 Section 3 More Java essentials
Resulting output
f( Today is July 11, 2011 ^
II There are 166 days until Christmas. J
Figure 13-5 A DateUtils class that provides methods for handling dates
416 Section 3 More Java essentials
public Invoice()
{
lineltems = new A r r a y L i s t o () ;
invoiceDate = DateUtils.getCurrentDate();
}
public ArrayList<LineItem> getLinelterns()
{
return lineltems;
}
public void addltem(Lineltem lineltem)
{
this.lineltems.add(lineltem);
}
public double getlnvoiceTotal()
{
double invoiceTotal = 0 ;
for (Lineltem lineltem : this.lineltems)
{
invoiceTotal += lineltem.getTotal();
}
return invoiceTotal;
}
public String getFormattedTotal()
{
NUmberFormat currency = NumberFormat.getCurrencylnstance();
return currency.format(this.getlnvoiceTotal());
}
public Date getlnvoiceDate()
{
return invoiceDate;
}
public String getFormattedDate()
{
DateFormat shortDate = DateFormat.getDatelnstance(DateFormat.SHORT);
return shortDate.format(invoiceDate);
}
}
Notes
• For the third constructor shown above, the characters referred to by the intOffset
and intLength arguments must fall within the array. Otherwise, the constructor will
throw an IndexOutOfBoundsException.
• A char data type contains a single Unicode character, which is stored in two bytes.
When you use the second and third constructors above, you can construct a String
object from an array of char types. To code a literal char value, you use single
quotes instead of double quotes as shown in the third example.
• Because a byte data type can hold the Unicode value for every character in the
ASCII character set, you can also construct a String object from an array of bytes
as shown in the fourth example.
• Since String objects are immutable, they can’t grow or shrink. Later in this chapter,
you’ll learn how to work with StringBuilder objects that can grow and shrink.
Description
• StringBuilder objects are mutable, which means you can modify the characters in the
string. The capacity of a StringBuilder object is automatically increased if necessary.
• The append and insert methods accept primitive types, objects, and arrays of characters.
• The StringBuilder class was introduced with Java 1.5. It’s designed to replace the older
StringBuffer class, which has identical constructors and methods but isn’t as efficient.
Figure 13-11 Code examples that work with the StringBuilder class
428 Section 3 More Java essentials
Perspective
Now that you’ve finished this chapter, you should be able to use the
classes provided by the Java API to work with dates, and you should be able to
use the String and StringBuilder classes to work with strings. These are skills
that you will use often as you develop Java applications.
Summary
• You can use the GregorianCalendar, Calendar, Date, and DateFormat classes to
create, manipulate, and format dates and times.
• You can use methods of the String class to locate a string within another string,
return parts of a string, and compare all or part of a string. However, String objects
are immutable, so you can’t add, delete, or modify individual characters in a string.
• StringBuilder objects are mutable, so you can use the StringBuilder methods to
add, delete, or modify characters in a StringBuilder object. Whenever necessary,
Java automatically increases the capacity of a StringBuilder object.
For this exercise, you’ll modify the Invoice class that’s shown in figure 13-6 so
it contains methods that return a due date, calculated as 30 days after the invoice
date. Then, you’ll modify the Invoice application that was shown in chapter 12
to display the invoice date and due date for a batch of invoices.
1. Open the project named chl3_exl_Invoice that’s in the ex_starts directory.
Then, review the code in the Invoice and InvoiceApp classes.
2. Add two methods named getDueDate and getFormattedDueDate to the
Invoice class. The getDueDate method should calculate and return a Date
object that’s 30 days after the invoice date. The getFormattedDueDate method
should return the due date in the short date format.
3. Modify the displaylnvoices method in the InvoiceApp class so that the invoice
display includes columns for the invoice date and the due date in addition to
the invoice number and total. Then, run the application to make sure it works.
Chapter 13 How to work with dates and strings 429
3. Display each word of the name on a separate line. If the user enters fewer
than two words or more than three words, display an error message. Also,
make sure the application works even if the user enters one or more spaces
before or after the name.
4. Test the project to make sure it works correctly.
An introduction to exceptions
All applications encounter runtime errors. For example, a user may enter
data that’s not appropriate for the program, or a file that your program needs
may get moved or deleted. These types of errors may cause a poorly-coded
program to crash and cause the user to lose data. In contrast, when an error
occurs in a well-coded program, the program will notify the user, save as much
data as possible, clean up resources, and exit the program as smoothly as
possible.
To help you handle errors, Java uses a mechanism known as exception
handling. Before you learn how to handle errors, though, you need to learn
about the exception hierarchy and the exception handling mechanism.
TheThrowable hierarchy
Description
• An exception is an object of the Exception class or any of its subclasses. It represents a
condition that prevents a method from successfully completing.
• The Exception class is derived from a class named Throwable. Two types of exceptions are
derived from the Exception class: checked exceptions and unchecked exceptions.
• Checked exceptions are checked by the compiler. As a result, you must write code that
handles all checked exceptions before you can compile your code.
• Unchecked exceptions are not checked by the compiler, but they can occur at runtime. It’s
generally considered a good practice to write code that handles unchecked exceptions. If an
unchecked exception occurs and isn’t handled by your code, your program will terminate.
• Like the Exception class, the Error class is also derived from the Throwable class. However,
the Error class identifies internal errors that are rare and can’t usually be recovered from.
As a result, you can usually ignore the Error class.
Description
• When a method encounters a condition it can’t handle, that method should throw an
exception. This allows users of the method to handle the exception in a way that’s
appropriate for their programs. Many methods in the Java API throw exceptions.
• When a method calls another method that throws a checked exception, the method
must either throw the exception to its caller or catch the exception and handle it
directly. Code that catches an exception is known as an exception handler.
• When an exception occurs, the runtime system looks for the appropriate exception
handler. To do that, it looks through the stack trace, or call stack, which lists the
methods that have been called until it finds a method that catches the exception.
A method that catches two types of exceptions and uses a finally clause
public static String readFirstLine(String path)
{
RandomAccessFile in = null;
try
{
in = new RandomAccessFile(path, "r"); // may throw FileNotFound
String line = in.readLine(); // may throw IOException
return line;
}
catch (FileNotFoundException e)
{
System.out.println("File not found.");
return null;
}
catch(IOException e)
{
System.out.println("I/O error occurred.");
return null;
}
finally
{
try
{
if (in 1= null)
in.close(); // may throw IOException
}
catch (Exception e)
{
System.out.println("Unable to close file.");
}
}
}
Description
• You can code a try block around any statements that may throw an exception.
• You can code one catch block for each type of exception that may be thrown in the
try block. You should code the catch clauses in sequence from the most specific
class in the Throwable hierarchy to the least specific class.
• You can code a finally block to free any system resources that are used by objects
created in the try block. The code in the finally block is always executed.
Description
• The try-with-resources statement is a special type of try statement that declares and
instantiates one or more objects that use system resources and automatically closes
those objects and releases the resources after the try statement finishes executing.
• The try-with-resources statement was introduced with version 1.7 of Java.
• Any object that implements the java.lang. AutoCloseable interface can be created
on the try-with-resources statement.
• As of version 1.7 of Java, most of the classes in the Java API that use system
resources have been retrofitted to implement the AutoCloseable interface.
java.io.FileNotFoundException: c:\murach\java\files\produx.txt
(The system cannot find the file specified)
java.io.FileNotFoundException: c:\murach\java\files\produx.txt
(The system cannot find the file specified)
at java.io.RandomAccessFile.open(Native Method)
at java.io.RandomAccessFile.<init>(RandomAccessFile.java:233)
at java.i o .RandomAccessFile.<init>(RandomAccessFile.java:118)
at ProductApp.readFirstLine(ProductApp.java:70)
at ProductApp.main(ProductApp.java:10)
Description
• The Throwable class provides methods that are available to all exceptions.
• The System.err object works like the System.out object, but it prints data to the
standard error output stream instead of the standard output stream.
• It’s generally considered a good practice to remove the printStackTrace method
from production applications or replace it with a better way of logging exceptions.
Description
• The multi-catch block allows you to use a single catch block for multiple excep
tions that are at the same level in the inheritance hierarchy.
• The multi-catch block was introduced with version 1.7 of Java.
Description
• Any method that calls a method that throws a checked exception must either catch
the exception or throw the exception. Otherwise, the program won’t compile.
• To throw a checked exception, you code a throws clause in the method declaration.
The throws clause must name each checked exception that’s thrown up to the
calling method.
• Although you can specify unchecked exceptions in the throws clause, the compiler
doesn’t force you to handle unchecked exceptions.
if (true)
throw new IOException("I/O exception test");
return firstLine;
}
catch (IOException e)
{
// code to handle IOException goes here
}
Example 3: Code that rethrows an exception
try
{
// code that throws IOException goes here
}
catch (IOException e)
{
System.out.println("IOException thrown in getFileLength method.");
throw e;
}
Description
• You use the throw statement to throw an exception. You can throw any object that’s
created from a subclass of the Throwable class.
• You can use the constructors of the Throwable class to create a new exception. Then,
you can throw that exception. To throw an existing exception, you must first catch it.
Description
• To define a checked exception, inherit the Exception class or any of its subclasses.
• To define an unchecked exception, inherit the RuntimeException class or any of its
subclasses.
• By convention, each exception class should contain a default constructor that doesn’t
accept any arguments and another constructor that accepts a string argument.
Figure 14-9 How to create your own exception class
450 Section 3 More Java essentials
creating a custom DAOException for the getProduct method, you can hide the
details of how the getProduct method works from methods that call it. So even
if the application is changed to use a database, the getProduct method can still
throw DAOException if an error occurs while retrieving a product object.
Method Description
getCause() Returns the exception object that represents this exception’s
cause.
initCause (c a u s e ) Sets the exception’s cause to the specified exception. Note that
this method can be called only once. If you initialize the cause
via the constructor, you can’t call this method at all.
Description
• Exception chaining lets you maintain exception information for exceptions that are
caught when new exceptions are thrown. Exception chaining uses the cause field,
which represents the original exception that caused the current exception to be
thrown.
NetBean’s Project Properties dialog box with the -ea switch set
Q Project Properties - ch06_FutureValue
Categories:
■O Sources
Configuration: <default config > New., Delete
i.. o Libraries
0· o Build
ö Compiling Main Class: FutureValueApp
o Packaging
0 Documenting Arguments:
o Run
Working Directory: Browse..
0 - O Application
L o Web Start VM Options: Customize
Q Formatting (e.g. -XmslOm)
Cancel Help
Description
• The assert statement was introduced with Java 1.4. You can use this statement to code an
assertion, which is a condition that should be true at a particular point in your application.
• Assertions are disabled by default. To enable assertions from NetBeans, right-click
on the project, choose the Properties command, select the Run group, and enter -ea
in the VM Options text box.
• If assertions are enabled, the JRE evaluates assert statements and throws an
AssertionError if the condition specified by the assert statement is false. If the
assert statement specifies a message, the message is included in the AssertionError.
• An assert statement shouldn’t include any code that performs a task. If it does, the
program will run differently depending on whether assertions are enabled or disabled.
Perspective
In this chapter, you learned the most important techniques for handling
exceptions in Java. Unfortunately, exception handling is one of the more trouble
some aspects of any serious application development. The essential problem of
exception handling is that exceptions are usually thrown at the lowest levels of
an application, but should be handled at the highest levels. For example, a
getProduct method that retrieves Product objects probably has no idea what
should be done if an 10 error occurs. So this low-level method throws an excep
tion that’s handled by a higher-level method, which can write the exception to an
error log, display an error message, or even terminate the application. In short,
exception handling usually affects every level of an application’s design.
Summary
·· In Java, an exception is an object that’s created from a class that’s derived from the
Exception class or one of its subclasses. When an exception occurs, a well-coded
program notifies its users of the exception and minimizes any disruptions or data
loss that may result from the exception.
• Exceptions derived from the RuntimeException class and its subclasses are
unchecked exceptions because they aren’t checked by the compiler. All other
exceptions are checked exceptions.
• Any method that calls a method that throws a checked exception must either throw
the exception by coding a throws clause or catch it by coding try/catch/finally
blocks as an exception handler.
• The try-with-resources statement is a special type of try statement that declares and
instantiates one or more objects that use system resources and automatically closes
the objects and releases the resources after the try statement finishes executing.
• The multi-catch block allows you to use a single catch block for multiple excep
tions that are at the same level in the inheritance hierarchy.
• When coding your own methods, if you encounter a potential error that can’t be
handled within that method, you can code a throw statement that throws the
exception to another method. If you can’t find an appropriate exception class in the
Java API, you can code your own exception class.
• You can create custom exception classes to represent exceptions your methods
might throw. This is often useful to hide the details of how a method is imple
mented.
• When you create custom exceptions, you can use exception chaining to save
information about the cause of an exception.
• An assertion lets you test that a condition is true at a specific point in an
application.
Chapter 14 How to handle exceptions 455
An introduction to Swing
In this chapter, you’ll leam how to create graphical user interfaces using
classes from the javax.swing package. These classes are known as Swing, or the
Swing set.
Title bar
f x
I j FutureValue Calculator I
Label
Description
• The window that contains the GUI is called a frame, or form.
• The form in this figure contains ten controls: four labels, four text fields, and two
buttons.
• The last text field in this figure is not editable. As a result, this text field can display
output, but the user can’t enter data into it.
• To calculate a future value, the user enters or changes the monthly payment
amount, the yearly interest rate, and the number of years. Then, the user selects the
Calculate button.
• To exit the program, the user selects the Exit button.
• To select a button, the user can click on the button, press the Alt key and the
shortcut key for the button at the same time, or use the Tab key to move the focus to
the button and then press the spacebar.
Figure 15-1 The user interface for the Future Value Calculator application
462 Section 4 GUI programming with Swing
Description
• The Abstract Window Toolkit (AWT) is an older technology for creating GUIs that
look and act a little different on different platforms. The AWT classes are stored in
the java.awt package.
• Swing is a newer technology that creates GUIs that are consistent from platform to
platform. The Swing classes are stored in the javax.swing package. All Swing
classes begin with the letter J.
• The Standard Widget Toolkit (SWT) is another GUI library that isn’t used as often
as Swing and isn’t described in this chapter.
Project: chl5_FutureValue
Package: murach. ui
Description
• Before you add the first form to a project, you should create a package to hold the
forms for the application.
• To add a form to a package, right-click on the package and select the New->JFrame
Form command. Then, enter a class name in the resulting dialog box.
Notes
• When you create a project for a GUI application, you should create it without a
main class. Then, you can use the class that defines the first form of the application
as the main class.
• If the JFrame Form command isn’t available from the New menu, the GUI Builder
plugin may not be activated. To activate this plugin, select the Tools-^Plugins
command and display the Installed tab of the resulting dialog box. Then, locate the
GUI Builder plugin, select the check box for this plugin, and click the Activate
button.
□
Swing C ontainers
Panel Q Tabbed Pane
j φ- S m urach.business Ç The Preview Design button {in the toolbar) enables yo u to test the design o f the form.
J\_ Split Pane y SaollPane
I 0 -"S murach.ui
fc T Tool Bar ^ 3 Desktop Pane
I'··" l^ j^Fu tu reV alu e F ram e .ja va
© la Libraries Label 1 jTe xtFie ld l
Π Internal Frame 1*1 Layered Pane
B Swing Controls
(Label2
eta Label 2*1 Button
la b e ls IS lT o g g le Button H - Check Box
Ö -Q [JFrame]
i - iitei (Label 1 [JLabel]
□ [240.240.2+0] Q
( ■ iiM jLabel2 [JLabel]
Tahoma 11 Plain
[·■·■» e i jLabel3 [JLabel]
j.... ute jLabeM [JLabel]
■ [0.0,0]
■■ ί I jTextFieldl [JTextField]
ï—I I jT s x tF ie k ß [JTextField] jButton2 [JButton] &
j -O jTextField3 [JTextField]
:- I I jTextField4 [JTextField]
I f f l jButton 1 [JButton]
: O utput - m urach_web4 (run)
j -IB c l )Button2 [JButton]
IP
ai
Description
• To open a form, double-click on the .java file for the form in the Projects window.
• You can display a form in two views in NetBeans. Design view shows a graphical
representation of the form, and Source view shows the source code for the form.
• To switch between Design view and Source view, click on the Design and Source
buttons in the toolbar at the top of the form window.
• To add a control to a form, select the control in the Palette window and then click
on the form where you want to place the control. If the Palette window isn’t
displayed, you can display it by using the Window->Palette command.
• To select a control, click on it. To move a control, drag it. To size a control, select it
and drag one of its handles. To change the size of the form, drag its edges.
• To select a group of controls, hold down the Ctrl key as you click on each control.
Or, click on a blank spot in the form and drag an outline around the controls.
• To move a group of controls, drag one of them. To align a group of controls, use the
buttons in the toolbar at the top of the form window.
□ chl5_FutureValue ~ S w in g C o n ta in e rs >
Source [ Design Γ Ö I SJ U i I? ï i ·« 1 «> 0
0 -l.îà Source Packages 1__ 1Panel Γ Ί Tabbed Pane
j E th -ffi muradi.business ί Use the Connection Mode button On the toolbar) to establish a connection between compon
J L Split Pane Q Scroll Pane
I B ~ @ 3 murach.ui
P5~ Tool Ear S5
- [Ëfe^HjtureValueFrame.java
Ë H s> Libraries j__ j Internal Frame f » | Layered Pane
Monthly Payment:
S w in g C o n tro ls
fearlv InterestRate:
βω Label [ôKj Button
133 I 1
Description
• To set a property for a control, select the control and then use the Properties
window to change the property.
• You can also change the text property for a control by right-clicking the control,
selecting the Edit Text command, and entering new text for the control.
• To set a property for more than one control at the same time, select the controls and
use the Properties window to change the property.
• To set a property for a form, click outside the controls to select the JFrame object.
• The properties that have been changed from their default values are displayed in
bold in the Properties window.
• To sort the properties of a control by category or name, right-click in the Properties
window and select the Sort by Category or Sort by Name command.
• To search for a specific property when the focus is in the Properties window, type
the starting letter or letters of the property. This starts the Quick Search feature.
• A description of the currently selected property is normally displayed at the bottom
of the properties window. If this description isn’t shown, right-click in the Proper
ties window and select Show Description Area.
Description
• To leam about the properties that are available for a control, you can select the
control, use the Properties window to scroll through its properties, and read the
descriptions for each property.
A form after the variable names have been set for the controls
Q c h !5 _ F u tu re V a lu e - N e tB e a n s IDE 7 .0
H S R g B !- x · 1
»
51 133 11
Description
• When you add controls to a form, default variable names are given to the controls.
If you’re going to refer to a control in your Java code, you should change its name
so it’s easier to remember and use.
• To change the name of the variable that’s used for a control, select the control, click
the Code button in the Properties window, and then change the Variable Name
property.
Swing C ontrols
B -ls Libraries
Btai Label IgiJ Button 1oiil Toagle Button
Yearly Interest Rate:
Button Group
Number o f Years: [ Ξ Combo Box 3 List
S B exitButton [JButton]
CO
H>
& ! 139 1 1
The code that’s generated for the actionPerformed event of the Exit button
private void exitButtonActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
}
The generated code that wires the event handler to the event
exitButton.addActionLi s tener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
exitButtonActionPerformed(evt);
}
})l
Description
• To create an event handler for the default event of a control, double-click on the control.
• To create an event handler for other events, select the control, click the Events
button in the Properties window, and select the name for the event handler from the
combo box list.
• To create an event handler with a custom name, select the control, click the Events
button in the Properties window, click in the combo box for the event that you want
to handle, enter a custom name for the event handler, and press the Enter key.
• To wire an event to an existing event handler, enter the name of the event in the
combo box for the event that you want to handle.
can’t edit it manually. In addition, you can’t manually rename or remove the
method declaration for an event handler. Instead, if you need to rename or
remove an event handler, you must use the Handlers dialog box shown in the
next figure.
Handlers
exitßuttonArtionPerfbrmed Add...
Remove
Rename.
OK Cancel
Description
• Since an event handler includes wiring code that’s automatically generated and
stored in a different location than the event handler code, you should always use the
Handlers dialog box if you need to rename or remove an event handler. That way,
both the event handler and its wiring are updated or removed in a single operation.
• To rename or remove an event handler, select the control, click on the Events
button in the Properties window, and click on the ellipsis button to the right of the
event that you want to work with. Then, use the Handlers dialog box to remove or
rename the event handler.
The source code after two event handlers have been coded
Q c h l5 _ F u tu re V a lu e - N e tB e a n s IDE 7.0 1= 1O \m & m \
m m
private void c a l c u l a t e B u t t o n A c t i o n P e r f o r m e d ( j a v a .a w t .e v e n t .A c t i o n E v e n t
double p = D o u b l e . p a r s e D o u b l e ( m o n t h l y P a y r a e n t T e x t F i e l d . g e t T e x t () ) ;
double r = D o u b l e . p a r s e D o u b l e ( y e a r l y R a t e T e x t F i e l d . g e t T e x t ());
int y = I n t e g e r . p a r s e l n t (y e a r s ! e x t F i e l d .g e t T e x t ());
double fv = F i n a n c i a l C a l c u l a t i o n s . c a l c u l a b e F i z t u r e ' / a l ü e ( p r r, y) ;
e xitB utton A ctio n P e rfo rm e d - Navigator
Number Format currency = N u m b e r F o r m a t . g e t C i i r r e n c y l n s tail c e () ;
Members View
futureValueTextField.s e t l e x t ( c u r r e n c y . f o r m a t ( fv ) ) ;
[V FutureValueFrame : : JFrame
Q FutureValueFrameO
calculateButtonActimPerformedCActioriEvent
private void e x i t B u t t o n A c t i o n P e r f o r m e d (jc .a w t .e v e n t .A c t i o n E v e n t evt} {
ί^_ · exitButtonAcbonPerformedf - > : e vt)
System,, e x i t (0> ;
initC omponentsO
(flj mainCStringO args)
}
caleulateButton : JButton
exitButton : JButton ■* S p a r a m a r g e
i ^ J futureValueTextField : JTextField
φ ] jL a b e ll; JLabel
% ] jLabel2 : JLabel
Output - chfS_FutureValue (run)
131 I 24 INS
Description
• Y ou can u se th e code e d ito r to e n te r th e co d e fo r an event h an d ler ju s t a s you w ould
en ter any o th er code.
• To refe r to th e controls on th e form , you u se th e variab le nam es th a t you assigned
to th e controls. Y ou can review th ese variab le nam es in th e N avigator w indow fo r
th e fram e. Y ou can also review th e declarations fo r th ese variables a t th e end o f th e
source co d e fo r th e form .
• To im port a class th a t w ill b e u sed b y th e form , co d e an im p o rt statem ent a fte r th e
package statem ent th a t’s a t th e sta rt o f th e fo rm class ju s t lik e you w ould fo r any
o th er class.
• I f you n eed to in itia liz e a co n tro l, you can add code to th e co n stru cto r fo r th e class
a fte r th e call to th e initC om ponents m ethod.
• You can also add m ethods o th er th an event handlers to a form . W hen you do th at,
you ty p ically p lace th e m ethods follow ing th e event handlers th a t c a ll them .
• N etB eans shades a ll gen erated code, and you can ’t m anually e d it th is code. I f you
need to change th is code, use D esign view as described in previous topics.
Description
• To leam more about the methods that are available for a control, refer to the API
documentation for the control.
• The getText, setText, setEditable, and selectAll methods are defined by the
JTextComponent class. The setEnabled and requestFocusInWindow methods are
defined by the JComponent class. And the setFocusable method is defined by the
Component class.
A main method for a form that displays and centers the form
public static void main(String a rgs[] ){
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
FutureValueFrame frame = new FutureValueFrame();
frame.setVisible(true) ;
frame.setLocationRelativeTo(null);
}
});
}
Description
• By default, NetBeans generates a main method for a form that creates the form and
displays it in the upper left comer of the user’s screen.
• You can modify this code to display the form in the center of the screen as shown
in the second example above.
Notes
• The code that’s generated by NetBeans for a form creates a new thread for the
form, which is a single flow of execution through the program. To create this
thread, the code creates a new class that implements the Runnable interface. This
interface has a single method named run. For more information about working with
threads, see chapter 22.
• The class that implements the Runnable interface is coded within the invokeLater
method of the EventQueue class. As a result, this class is a type of inner class as
described in chapter 10. Since this inner class doesn’t have a name, it’s known as
an anonymous class.
• The invokeLater method of the EventQueue class puts the thread for the form in a
queue. Then, it runs the thread when the thread reaches the front of the queue.
import java.text.NumberFormat;
import murach.business.FinancialCalculations;
public FutureValueFrame() {
initComponents();
}
private void initComponents() {
// Generated code - do not modify
}
private void calculateButtonActionPerformed(
java.awt.event.ActionEvent evt) {
double p = Double.parseDouble(monthlyPaymentTextField.getText());
double r = Double.parseDouble(yearlylnterestRateTextField.getText());
int y = Integer.parselnt(yearsTextField.getText());
double futureValue = FinancialCalculations.calculateFutureValue(
p, r, y ) ;
NumberFormat currency = NumberFormat.getCurrencylnstance();
futureValueTextField.setText(currency.format(futureValue));
}
private void exitButtonActionPerformed(java.awt.event.ActionEvent evt) {
System.exit(0);
}
/**
* ©param args the command line arguments
*/
public static void main(String a r g s []) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
FutureValueFrame frame = new FutureValueFrame();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}
// Variables declaration - do not modify
private javax.swing.JButton calculateButton;
private javax.swing.JButton exitButton;
private javax.swing.JTextField futureValueTextField;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JTextField monthlyPaymentTextField;
private javax.swing.JTextField yearlylnterestRateTextField;
private javax.swing.JTextField yearsTextField;
OK
Arguments
Argument Description
parent An object representing the component that’s the parent of the dialog box.
If you specify null, the dialog box will appear in the center of the screen.
message A string representing the message to be displayed in the dialog box.
title A string representing the title of the dialog box.
messageType An int that indicates the type of icon that will be used for the dialog box.
You can use the fields of the JOptionPane class for this argument.
0 INFORMÄnON_MESSAGE
A WARNING_MESSAGE
Θ ERROR_MESSAGE
S QUESTION_MESSAGE
Description
• The showMessageDialog method is a static method of the JOptionPane class that is
commonly used to display dialog boxes with error messages for data validation.
• To close a dialog box, the user can click the OK button or the close button in the
upper right comer of the dialog box.
• You can also use the JOptionPane class to accept input from the user. For more
information, see the API documentation for this class.
Figure 15-14 How to display error messages
488 Section 4 GUI programming with Swing
Description
• Like console applications, GUI applications should validate all data entered by the
user before processing the data.
• When an entry is invalid, the application can display an error message and give the
user another chance to enter valid data.
• To test whether a value has been entered into a text field, you can use the getText
method of the text field to get a string that contains the text the user entered. Then,
you can check whether the length of that string is zero by using its length method.
• To test whether a text field contains valid numeric data, you can code the statement
that converts the data in a try block and use a catch block to catch a
NumberFormatException.
Figure 15-15 How to validate the data entered into a text field
490 Section 4 GUI programming with Swing
import j avax.swing.* ;
import j avax.swing.text.JTextComponent;
return true;
}
Description
• When more than one field needs to be validated, it is best to put all the validation
logic in a separate method that returns a boolean value to indicate whether or not
the data is valid.
• The first and second examples above show two alternatives for validating multiple
entries. Both use the non-static methods of the SwingValidator class.
The code
Figure 15-19 shows the code for the Future Value application. Since this
code is similar to the code for the FutureValueFrame class presented earlier in
this chapter, you shouldn’t have much trouble understanding it. The main
difference is that this code uses the SwingValidator class shown in figure 15-16
to validate the input. Also, for the sake of completeness, this code listing shows
the code for the FinancialCalculations class that contains the static method that
calculates the future value.
Chapter 15 How to develop a form 495
Number of Years:
FutureValue: $3,771.46
Calculate Exit
I OK OK I
Description
• When the Future Value application starts, it displays the Future Value Calculator
form.
• To perform a calculation, the user enters a monthly payment, yearly interest rate,
and number of years and then clicks on the Calculate button or presses Alt+C. If
the data is valid, the future value is formatted and displayed.
• If the user enters invalid data, the application displays a dialog box that describes
the error. Then, after the user clicks the OK button, the application moves the focus
to the text field that contains the invalid data.
• To exit the application, the user clicks on the Exit button or presses Alt+X.
Figure 15-18 The user interface for the Future Value application
496 Section 4 GUI programming with Swing
import j ava.text.NumberFormat;
import murach.business.FinancialCalculations;
double fv = FinancialCalculations.calculateFutureValue(p, r, y ) ;
Figure 15-19 The code for the Future Value application (part 1 of 2)
Chapter 15 How to develop a form 497
Figure 15-19 The code for the Future Value application (part 2 of 2)
498 Section 4 GUI programming with Swing
Perspective
In this chapter, you learned how to use the Swing GUI builder that comes
with NetBeans to build a GUI version of the Future Value application. This
application uses some of the most common controls that are available from the
Swing library including labels, text fields, and buttons. In the next chapter,
you’ll leam how to use more of the controls that are available from this library.
Summary
• A GUI builder is a graphical tool that a developer can use to generate the code
that’s used to display a graphical user interface and to write the code that makes
the GUI work.
• The Swing GUI builder is one of the most popular GUI builders for Java develop
ers, and it is available from the NetBeans IDE.
• The window that contains the GUI is called a frame, or form. Within a form, you
add GUI controls such as labels, text fields, and buttons.
• The Abstract Window Toolkit (AWT) is an old technology for creating GUIs. Swing
is a newer technology for creating GUIs. All Swing classes begin with the letter J
and are stored in the javax.swing package.
• Properties are the values that determine how a form and its controls will look and
work when the form is displayed.
• An event handler is a special type of method that responds to an event that’s
triggered when a user interacts with a form. NetBeans automatically generates the
code that wires the method for an event handler to an event.
This exercise guides you through the process of using NetBeans to develop the
GUI version of the Future Value application presented in this chapter.
5. Change any of the other properties for the form or controls so they will look
and act the way you want.
6. Preview the form by clicking on the Preview Design button in the toolbar at
the top of the form window. This shows that NetBeans has many features that
aren’t mentioned in this introductory chapter. Close the form by clicking on
the Close button in its upper right comer.
7. Make any changes necessary to get the form to look the way it should, and
then preview it again.
Review the code that was generated for the form
8. Switch to Source view, and review the code for the constructor of the
FutureValueForm class. Note that it calls a method named InitComponents.
9. Click on the plus sign to the left of the Generated Code region to display the
InitComponents method within this region. Then, scroll through this method
and review its code. As you do, take a moment to consider how much work
NetBeans has done for you.
10. View the main method near the end of the code, and note that it creates an
instance of the FutureValueForm class, which in turn causes the constmctor
near the start of the class to be executed.
11. Review the declarations for the control variables at the end of the code.
Add code to the form class
12. Add import statements for the java.text.NumberFormat and
murach.business.FinancialCalculations classes.
13. Switch back to Design view, and then double-click on the Exit button to
generate the starting code and wiring for an event handler that handles the
actionPerformed event of that button. Then, add code to this event handler
that exits the application.
14. Use the Properties window to generate the starting code and wiring for an
event handler that handles the actionPerformed event of the Calculate button.
Then, add code to this event handler that gets the values the user entered in
the form, calculates the future value using the calculateFutureValue method of
the FinancialCalculations class, formats the result, and displays it in the
Future Value text field.
15. Modify the code in the main method so it displays the form in the center of
the screen.
16. Run the form by right-clicking on the .java file for the form in the Projects
window and selecting Run File. Test the form to be sure it works with valid
data. When you’re done, click the form’s Exit button.
Add validation to the form class
17. Add a private method named isValidData that uses the methods of the
SwingValidator class to validate the data that’s entered by the user.
18. Modify the code in the event handler for the actionPerformed event of the
Calculate button so it only executes if the data is valid.
500 Section 4 GUI programming with Swing
19. Run the form again. Test it to make sure it handles invalid entries in an
appropriate way.
In this exercise, you’ll use NetBeans to develop a GUI version of the Invoice
application you saw earlier in this book. When you’re done, the user interface
for this application should look something like this:
I j..| Invoice Total Calculator I α I B ^ — P
DiscountAmount $50.00
Total: $200.00
Calculate Exit
Save
Li' - -
Description
• In contrast to a text field, a text area can be used to enter and display more than one
line of text.
• By default, the GUI builder adds a text area to a scroll pane. A scroll pane can
provide scroll bars for the text area.
Address:
Uoel M u ra c h
611 Guerroro St.
San Francisco. CA94110|
Accept
L___ J
Method Description
isSelected() Returns a true value if the check box is selected.
setSelected (b o o le a n ) Checks or unchecks the check box depending on
the boolean value.
Description
• A check box lets the user choose to turn an option on or off.
• To select or deselect a check box, the user can click on the check box, press the Alt
key plus the shortcut key for the check box, or move the focus to the check box and
then press the spacebar.
Carrier
® USPS OUPS O FedEx
Accept
Description
• Radio buttons let the user choose one option from among several options. Selecting a
radio button automatically deselects all other radio buttons in the same button group.
• A panel is a control that can contain other controls. A panel can have a border
that’s used to visually group controls such as radio buttons or to enhance the
appearance of controls.
• Because a panel only groups controls visually, you must still use the buttonGroup
property to group radio buttons logically. Before you can set the buttonGroup
property, you must create a button group using the Button Group control in the
Palette window.
• To select a radio button, the user can click on the button, press the Alt key plus the
shortcut key for the button, or move the focus to the button and then press the spacebar.
Price: 52.50
OK
Description
• A combo box lets the user choose one of several items from a drop-down list.
• If a combo box will contain just a few items that won’t change, you can use the
Properties window to enter those items for the model property. Otherwise, you
should use code to add items to the combo box as shown above.
example could have added the Product objects directly to the combo box. In that
case, the combo box would call each product’s toString method to get the text to
display for the object.
Products:
OK
Method Description
getSelectedValuesList() Returns a L i s t o type that contains the selected items.
getSelectedlndices() Returns an array of int values for the indices of the
selected items.
getSelectedValue() Returns the selected item as an Object type.
getSelectedlndex() Returns an int value for the index of the selected item.
IsSelectedlndex(lnt) Returns a true value if the item at the specified index is
selected.
setSelectedlndex ( i n t ) Selects the item at the specified index.
setModel ( l i s t M o d e l ) Sets the model for the list that’s defined by the
DefaultListModel class.
Description
• A list allows the user to select zero or more items from a list of items.
• If a list will contain just a few items that won’t change, you can use the Properties
window to enter those items for the model property. Otherwise, you should use
code to add items to the list as shown in the next figure.
The code examples in part 2 of figure 16-5 illustrate how you work with a
list. The first example declares a variable that stores an array list of Product
objects. This variable is used by the next two examples.
The second example shows how to initialize a list. Here, the constructor for
the frame begins by calling the initComponents method to initialize all of the
components for the frame. Then, the next group of statements calls the
getProducts method of the ProductDB class to get an array list of Product
objects.
The third group of statements within the constructor creates and populates a
DefaultListModel object. This object provides a conceptual model for managing
the items in the list. As a result, it’s known as a list model. The table at the top
of this figure presents some of the methods for working with a list model.
After creating the list model, an enhanced for loop populates the model with
the product descriptions. To do that, it uses the addElement method of the list
model object. Then, the setModel method of the list is used to associate the list
model with the list. Finally, the setSelectedlndex method is used to set the initial
selection to the first item in the list. That’s necessary because the first item isn’t
selected by default like it is in a combo box.
The third example shows how to access the item or items that have been
selected by the user. Here, the getS electedValuesList method retrieves a list of
selected values. Then, an enhanced for loop displays these values. Note that you
can also use the getSelectedlndexes method to return the indexes of the selected
items too if necessary. Similarly, if the list box only allows a single selection,
you can use the getSelectedlndex or getSelectedValue method to get the se
lected index or value for the selected item.
Chapter 16 How to work with controls and handle events 513
products = ProductDB.getProducts();
productList.setModel(model) ;
productList.setSelectedlndex(0 );
}
Example 3: Code that gets the selected items from the list
List<String> selections = productList.getSelectedValuesList();
Description
• To modify the contents of a list using code, you must first create a list model that
defines the data displayed by the list. The list model can be any object that imple
ments the ListModel interface. The most commonly used model is the
DefaultListModel class.
• When you use a list model, you should include an import statement for its class.
The list model classes are in the javax.swing package.
The code
Figure 16-7 shows the code for the Payment application. To start, after the
constructor for the frame calls the initComponents method, it initializes the
combo box that stores the list of years. To do that, this code gets the current year
and then uses a for loop to add the current year and the next seven years to the
combo box list. Notice that I didn’t use code to initialize the items in the Card
Type list or the combo box list that stores the list of months. Instead, I used the
model property since these lists are short and unlikely to change.
In the event handler for the actionPerformed event of the radio button group,
the first line of code checks if the “Credit card” radio button is selected. If so, this
code passes a true value to the enableCreditCardControls method to enable the
controls for entering the credit card data. On the other hand, if the “Bill cus
tomer” radio button is selected, this code disables the credit card controls.
In the event handler for the actionPerformed event of the Accept button, the
first statement defines a variable that stores the message that’s displayed. Then,
this code gets the data entered by the user and formats it in a message. To do
that, this code uses some of the methods described in this chapter. For example,
it uses the getSelectedValue method of the list box. This works because this list
box only allows the user to select a single item. Similarly, it uses the
getSelectedltem method of the two combo boxes to get the selected expiration
date. Since this method returns an Object type, this code casts the return values
to String types.
After storing the appropriate message in the variable, this code displays the
message in a dialog box. Then, it sets all of the controls to their default state. To
do that, this code uses some of the methods described in this chapter. In particu
lar, it uses the setSelectedlndex method of the list and combo boxes to select the
first item in those controls. In addition, it passes a false value to the setSelected
method of the check box to deselect that check box.
Chapter 16 How to work with controls and handle events 515
Billing Billing
□ Verified
t---------------------------
Bill Visa
(T> Number ♦ 1234123412341234
Message
OK OK
k------------------- J
Description
• The Payment application uses some of the controls shown in this chapter to allow
the user to enter information regarding a payment.
• To enter a credit card payment, the user selects the “Credit card” radio button,
selects a card type from the list, enters a card number in the text field, and selects
an expiration month and year from the combo boxes. If the credit card has been
verified, the user can also select the check box. When the user clicks the Accept
button, the application displays the credit card data that was entered in a dialog box.
• To send a bill to the customer, the user selects the “Bill customer” radio button.
This disables the controls for entering credit card data. If the user clicks the Accept
button, the application displays a dialog box with a message that indicates that the
customer will be billed.
• To exit the application, the user clicks the Exit button.
import javax.swing.JOptionPane;
import java.util.Calendar;
import j ava.util.GregorianCalendar;
Description
• A semantic event is an event that’s related to a specific component like clicking on a
button. In contrast, a low-level event is a less specific event like clicking the mouse.
• Every event class has a corresponding listener interface that defines the names of
the events that can be handled.
• The classes for the events and their corresponding listeners are stored in the
java.awt.event package.
Focus events
Event name Description
focusGained Invoked when a component gains the focus.
focusLost Invoked when a component loses the focus.
Description
• A focus event occurs when the focus moves to or from a component.
Keyboard events
Event Description
keyPressed Invoked when a key is pressed.
keyReleased Invoked when a key is released.
keyTyped Invoked when a key is pressed and released.
{
evt.consume() ;
}
}
Description
• A keyboard event occurs when a user presses, releases, or presses and releases a key.
ProductCode: mcsp
Description: Murach's C#
Exit
OK OK
v >
Description
• The Product Maintenance application lets the user add, edit, or delete products. It is
similar to the Product Maintenance application that was presented in chapter 9, but
it is a GUI application rather than a console application.
• To add a new product, the user clicks the Add button. This enables the Product
Code, Description, and Unit Price text fields as well as the Accept and Cancel
buttons. Then, the user enters the data for the new product and clicks the Accept
button to accept the new product or the Cancel button to cancel the entry.
• To edit a product, the user selects the product from the combo box. This displays
the data for the selected product in the text fields. Then, the user clicks the Edit
button to enable the Description and Unit Price text fields. Finally, the user can
enter any necessary changes and click the Accept button to accept the changes or
the Cancel button to cancel the changes.
• To delete a product, the user selects the product from the combo box and then
clicks the Delete button.
• When the user moves the focus into an enabled text field, the text within that field
is automatically selected.
Figure 16-11 The user interface for the Product Maintenance application
526 Section 4 GUI programming with Swing
The code
Figure 16-12 presents the code for the Product Maintenance application.
Although it’s five pages long, all of the coding techniques it uses have already
been presented in this book. Because of that, I’ll just describe the highlights here.
The ProductMaintFrame class begins by declaring instance variables for a
data access object named productDAO, an array list named products that will be
used to store all the products, a Product object named newProduct that will be
used to store a new product, and a boolean variable named filling that indicates
whether the combo box is currently being filled. Then, the constructor of this
class calls the initComponents method to initialize the controls on the form,
uses the data access object to populate the array list, calls the fillComboBox
method to add the products to it, and calls the showProduct method to display
the data for the first product.
The fillComboBox method starts by setting the filling variable to true. That
way, when the code that follows causes the actionPerformed event of the combo
box to be invoked, the code in the event handler for this event won’t be executed.
You can look ahead to page 3 of this listing to see how this works. Then, the last
statement in the fillComboBox method sets the filling variable to false. Note that
this method is called each time the product list changes. That’s why all of the
items are removed from the combo box before the current items are added.
The fillComboBox method is followed by a series of methods that are used
by the event handlers of the frame. The selectProduct method selects an item in
the combo box. The getCurrentProduct method gets a product from the combo
box. And the showProduct method displays the code, description, and price for
a specified product in the text fields.
Chapter 16 How to work with controls and handle events 527
import javax.swing.JTextField;
import java.util.ArrayList;
import murach.business.Product;
import murach.db.*;
Figure 16-12 The code for the Product Maintenance application (part 1 of 5)
528 Section 4 GUI programming with Swing
// return a new Product object with the data in the text fields
private Product getProduct() {
Product p = new Product();
p.setCode(codeTextField.getText());
p.setDescription(descriptionTextField.getText());
p.setFormattedPrice(priceTextField.getText());
return p;
}
private void setAddMode() {
codeTextField.setEditable(true);
codeTextField.setFocusable(true);
codeTextField.reguestFocusInWindowO;
descriptionTextField.setEditable(true);
descriptionTextField.setFocusable(true);
priceTextField.setEditable(true);
priceTextField.setFocusable(true);
}
private void setEditMode() {
descriptionTextField.setEditable(true);
descriptionTextField.setFocusable(true);
descriptionTextField.requestFocusInWindowO;
priceTextField.setEditable(true);
priceTextField.setFocusable(true);
}
private void setDisplayMode() {
codeTextField.setEditable(false);
codeTextField.setFocusable(false);
descriptionTextField.setEditable(false);
descriptionTextField.setFocusable(false);
priceTextField.setEditable(false);
priceTextField.setFocusable(false);
}
private void setAddEditMode(boolean e) {
addButton.setEnabled(Ie);
editButton.setEnabled(!e);
deleteButton.setEnabled(!e);
productComboBox.setEnabled(!e);
acceptButton.setEnabled(e);
cancelButton.setEnabled(e);
}
Figure 16-12 The code for the Product Maintenance application (part 2 of 5)
530 Section 4 GUI programming with Swing
item from the list. Then, this event handler gets the current product from the
combo box and displays the data for that product in the text fields.
The event handler for the actionPerformed event of the Add button starts by
creating a new Product object and clearing the data entry fields. Then, it calls
the setAddEditMode method so the appropriate controls are enabled, and it calls
the setAddMode method so the user can enter data for a new product. Note that
this event handler doesn’t actually add a new product. That’s done after the user
enters the data for the product and clicks the Accept button.
The event handler for the actionPerformed event of the Edit button also calls
the setAddEditMode method. Then, it calls the setEditMode method so the user
can edit the product. Like the event handler for the actionPerformed event of the
Add button, this event handler doesn’t actually update the product. That’s done
when the user clicks the Accept button.
In contrast, the event handler for the actionPerformed event of the Delete
button actually deletes the selected product. To do that, it starts by getting the
current product. Then, it deletes the product from the data store, and it removes
the product from the products array list. Next, it reloads the combo box so it
doesn’t contain the deleted product, it selects the first product in the combo box
and displays the data for that product in the text fields, and it moves the focus to
the combo box.
The event handler for the actionPerformed event of the Accept button begins
by calling the isValidData method to validate the input data. Note that this
method, shown on page 4 of this listing, checks the newProduct variable for a
null value to determine if a product is being added or updated. If a product is
being added, the product code field is validated. Otherwise, it isn’t.
If the data is valid, this event handler either adds a new product or updates
an existing product depending on whether newProduct is null. To add a new
product, it starts by getting a product with the values the user entered. Then, it
adds the object to the data store and the products array list, it refreshes the
combo box so it includes the new product, and it selects that product. Finally, it
sets newProduct to null to prepare for the next user action.
To update an existing product, this event handler gets the current product as
well as a new product with the values the user entered. Then, it assigns the new
description and price values to the existing product, updates the product in the
data store, and updates the display. Finally, this event handler resets the controls
on the form so the user can perform another operation.
The event handler for the actionPerformed event of the Cancel button starts
by setting the newProduct variable to null. Then, it sets the controls to display
mode, calls the showProduct method to redisplay the data for the current
product, sets add/edit mode to false, and moves the focus to the combo box.
This effectively discards any changes made by the user.
The event handler for the focusGained event is wired to all three text fields.
As a result, if these fields are enabled and the user moves the focus into one of
them, this event handler selects all of the existing text in that field.
Chapter 16 How to work with controls and handle events
Figure 16-12 The code for the Product Maintenance application (part 3 of 5)
532 Section 4 GUI programming with Swing
Figure 16-12 The code for the Product Maintenance application (part 4 of 5)
Chapter 16 How to work with controls and handle events 533
Figure 16-12 The code for the Product Maintenance application (part 5 of 5)
534 Section 4 GUI programming with Swing
Perspective
In this chapter, you learned how to work with some new components, and
you learned how to handle low-level events such as focus events and keyboard
events. If you understand the Product Maintenance application that’s presented
at the end of this chapter, you’ve come a long way. Once you master the data
access skills that are presented in the next section, you’ll have a solid set of
skills for developing Java applications at a professional level.
Summary
• A text area lets the user enter one or more lines of text. You can use many of the
same techniques to work with text fields and text areas.
• A scroll pane can provide scroll bars for controls. By default, NetBeans automati
cally adds a text area to a scroll pane since text areas often need scroll bars.
• Radio buttons let the user select one option from a group of options in a button
group. A check box lets the user select or deselect a single option.
• When working with radio buttons and other related controls, you can visually
group them by adding them to a panel that has a border.
• A combo box lets a user select one item from a drop-down list of items, and a list
lets a user select one or more items from a list of items.
• A semantic event is an event that’s related to a specific component like selecting a
button. In contrast, a low-level event is a less specific event.
• Two types of low-level events are focus events such as moving the focus to a
control and keyboard events such as pressing or releasing a key.
Number of Years:
Calculate Exit
Chapter 16 How to work with controls and handle events 535
S iz e
Toppings
0 Sausage □ Olives
0 Pepperoni 0 Mushrooms
□ Salami □ Anchovies
Price: $12.96
Calculate Exit
Item Price
Small pizza $6.99
Medium pizza $8.99
Large pizza $10.99
Sausage $1.49
Pepperoni $1.49
Salami $1.49
Olives $0.99
Mushrooms $0.99
Anchovies $0.99
An introduction to applets..................................................538
The Future Value Calculator applet............................................................. 538
A brief history of applets..............................................................................538
Applet security issues...................................................................................540
The inheritance hierarchy for applets.......................................................... 542
Four methods of an applet............................................................................542
How to develop applets......................................................544
How to develop a panel for an applet.........................................................544-
How to code an applet................................................................................ 546
How to test an applet with the Applet Viewer............................................546
How to deploy applets........................................................548
A procedure for deploying an applet........................................................... 548
How to create an HTML document for an applet...................................... 550
How to run an applet within a web browser...............................................552
Perspective........................................................................... 554
538 Section 4 GUI programming with Swing
An introduction to applets
This topic begins by showing a simple applet. Then, it discusses some
security issues that apply to applets. Finally, it gives an overview of the classes
and methods that you use to work with applets.
File E dit V ie w H is to ry B o o k m a rk s T o o ls H e lp
© - C ^ □ http://www.murach.com/fv/applet7/fiiture_value.html * [ | *· Google fi
Number o f Y e a rs: |3
C alculate
Done
Description
• An applet is a special type of application that can be downloaded from an Internet
or intranet server and run on the client’s computer within a web browser.
• The Java Plug-in is a browser plug-in that allows a web browser to use the Java
Runtime Environment to run an applet.
• The Java Runtime Environment (JRE) is the Java interpreter that lets you run
compiled programs in Java. The Java plug-in is included as part of the JRE.
• For a client machine to run applets, a current version of the JRE and Java Plug-in
must be installed on the client.
• When you install the current version of the JDK, the current version of the JRE is
automatically installed on your machine.
• If a user attempts to run an applet without first installing the required version of the
JRE, the JRE will be downloaded automatically, and the user will be prompted to
install it.
• The JRE and Java Plug-in can be downloaded from www.java.com. If necessary,
you can provide a link to this site from your web page.
Description
• To prevent applets from damaging a client system or from making it possible to
damage a client system, security restrictions limit what an applet can do.
• To overcome these security restrictions, you can create a signed applet. This
indicates that the applet comes from a trusted source. Then, you can add rights to
the signed applet.
Description
• To create a Swing applet, you define a class that extends the JApplet class. This
class is stored in the javax.swing package, and it inherits the Applet class in the
java.applet package.
• Once you define a class that extends the JApplet class, you can override any of the
four methods of the Applet class. These methods are called automatically by the
browser as indicated above, and they control the execution of the applet.
• The JApplet class also inherits the Component, Container, and Panel classes. As a
result, you can call methods of these classes when you code an applet.
: K ) Ç I j [«default config>
Name FutureValuePanel
Navigator : Inspector ja v a
Extension
Ë5] Form FutureValuePanel
A ll Files Citoiurach^avaY.. Q
E
(+!■· Components
File Size 6934
É -D [JPanel] A ug 10, 2011 1:56:...
Modification Time
]■■■■utei jLabel 1 [JLabel] Ξ Classpaths
jLabel2 [JLabel]
Compile Classpath □
\—Kiel jLabel3 [JLabel] ' *
} ·- - □ yearsTextField [JTextField]
O u tp u t-c h 1 7 _ F u t u r e V a lu e (c le a n ja r)
I- I I futureValueTextField [JTextField]
i~ IB B calculateButton [JButton]
&! Ill
Description
• To create a class th a t defines a p an el, rig h t-c lic k o n th e package w here you w an t to
add th e panel. T hen, select th e N ew -> JPanel F orm com m and an d u se th e resu ltin g
dialo g b o x to e n te r a nam e fo r th e class.
• Y ou can u se th e sam e sk ills fo r developing a JP anel class fo r a fo rm as you do fo r
developing a JF ram e class for a form .
• T he fo rm fo r an ap p licatio n o ften includes an E x it b utton. S ince an ap p let runs
w ith in a brow ser, th e fo rm fo r an ap p let should n o t include an E x it button.
Number of Years:
FutureValue: $3,771.46
Calculate
Applet started.
import javax.swing.JApplet;
Description
• To create a class that defines an applet, right-click on the package where you want
to add the applet and select the N e w O th e r command to display the New File
dialog box. Then, select the Java category, select the JApplet file type, and click the
Next button. Finally, enter a class name for the applet in the New JApplet dialog
box that’s displayed.
• Most of the code for an applet is generated by NetBeans when you create the class
for the applet. Then, you can add code to the init method of the applet class that
adds the appropriate panel to the applet.
• The Applet Viewer lets you test an applet before you deploy it. The Applet Viewer
is included in the JDK.
• To run an applet in the Applet Viewer, right-click on the java file for the applet and
select the Run File command. If necessary, resize the Applet Viewer window so it’s
the correct size for the applet.
Description
• To display the Source/Binary Format option in NetBeans, right-click on the project,
select the Properties command, and then select the Sources category in the resulting
dialog box. See chapter 1 for more information on this option.
• By default, NetBeans stores the JAR file for a project in the project’s dist subfolder
when you build the project.
• To place the JAR and HTML files in the same folder, you can copy the HTML file
to the project’s dist subfolder. Or, you can create a new folder and then copy both
files into that folder. The folder does not have to be part of the project.
• Because a JAR file stores the files it contains in a compressed format, storing the
files for an applet in a JAR file can dramatically improve the download time for the
applet.
• Before you can display an applet in a web browser, you must create a web page for
the applet. Then, when you display the web page in a browser, the applet is down
loaded and displayed.
• If you will be deploying an applet to an intranet, you can simply copy the JAR and
HTML files to the web server. If you will be deploying an applet to the Internet,
you can use an FTP program to copy the files to the web server. See chapter 23 for
more information on using an FTP program.
Description
• The Hypertext Markup Language (HTML) is the language that’s used to create web
pages. An HTML document contains HTML elements that define the content and
structure of the web page.
• Most HTML elements have three parts: an opening tag that includes the tag name,
a closing tag that includes the tag name preceded by a forward slash, and the
content between the opening and closing tags.
• Within an opening tag, you can code attributes to provide optional values. To code
an attribute, you code the name of the attribute, an equals sign, and the value for the
attribute enclosed in quotes.
• The <head> element of a document contains information about the web page. For
example, the <title> element specifies the text that’s displayed in the browser’s title bar.
• The <body> element of a document defines the content of the web page. Within
this element, you can code <script> elements to run the applet.
• The first <script> element loads the JavaScript Deployment Toolkit. Then, the
second <script> element calls a JavaScript function that’s stored in this toolkit.
• To create an HTML document in NetBeans, use the New->HTML File command.
;/murach/java/netbeans/tests/chl7_FutureValue/dist/future_value.html ^ j1 τ | ^ Googie
Number of Years: [J J a v a P l u g - i n 1 0 .0 .0 .1 4 7
U sin g JRE v e r s i o n 1 .7 .0 - Ü 1 4 7 J a v a H o ts p o t (Til) C l i e n t VM
FutureValue: $3.771.46
O se r home d i r e c t o r y = C :V ü s e rs \A n n e .m u ra ch
c l e a r c o n s o le window
finalize objects on finalization queue
garbage collect
dump c l a s s l o a d e r l i s t
p r i n t memory u s a g e
t r i g g e r lo g g in g
h id e c o n s o le
r e lo a d p o lic y c o n fig u ra tio n
dump s y s te m a n d d e p lo y m e n t p r o p e r t i e s
dump thread list
s e t t r a c e l e v e l t o <n>
D e te c te d fro m b o o t c l a s s p a t h : C : \ \ P R O G R R ~ l \ \ J a v a \ \ j r e 7 \ \ l i t A \ d e p l o y . j a r
Copy
Description
• To ru n an ap p let in a w eb brow ser, sta rt th e brow ser and th en en ter th e address o f
th e H T M L p ag e th a t contains th e ap plet. W hen th e H T M L file is processed, th e
ap p let is dow nloaded and displayed.
• If you’re using In tern et E xplorer, it m ay d isplay its In form ation B ar and prevent th e
ap p let fro m running. To co n tin u e, you can c lic k o n th e Inform ation B ar and select
th e A llow B locked C ontent com m and.
• O nce th e ap p let is disp lay ed in th e brow ser, you can te st it to b e su re it w orks
correctly.
Perspective
In this chapter, you learned how to develop applets. You also learned about
some of the limitations of applets that have led web programmers to use other
methods for developing web applications. As a result, before you begin
developing a project that relies heavily on applets, you should review this
technology to make sure that it’s appropriate for your project.
In particular, if you want to develop web applications that store data in a
file or database on the server, you should consider using servlets and Java
Server Pages (JSP). Then, all processing is done on the server and the server
returns standard HTML to the browser. The second book in this series,
Murach’s Java Servlets and JSP, shows how to use servlets and JSP to create
web applications.
Summary
• An applet is a special type of application that’s stored on a web server and runs
within a web browser on a client machine.
• To view an applet, the client computer must have the appropriate version of the
Java Runtime Environment (JRE) and the Java Plug-in installed. The Java Plug-in
is part of the JRE.
• Since applets are downloaded from remote servers and run on client machines,
they have stricter security restrictions than applications. To get around these
restrictions, it’s possible to create a signed applet.
• You can use the JApplet class to create an applet from a panel that contains the
Swing controls and code for the applet.
• You can use the Applet Viewer to test an applet before you deploy it.
• You can use a Java Archive (JAR) file to store all of the Java classes and resources
for an applet.
• You can create a Hypertext Markup Language (HTML) document that displays an
applet. Within the HTML file, you can use a JavaScript library to start the applet.
• To test an applet after it has been deployed, you view the HTML page in a web
browser.
Chapter 1 7 How to develop and deploy applets 555
Description
• To work with a directory or file, you use a Path object. A Path object can include a
root component as well as directory names and a file name.
Figure 18-1 A package for working with directories and files
562 Section 5 Data access programming with Java
Resulting output
0 - ----------- Λ
File name: products.txt
Absolute path: c :\murach\java\files\products.txt
Is writable: true
V- ------------------ i
Description
• Java SE 7 introduced the java.nio.file package (also known as NIO.2). This package
provides an improved way to access the default file system and is designed to
replace the functionality that was available from the java.io.File class.
• The java.nio.file package provides support for many features that aren’t provided
by the java.io.File class.
• When coding paths, you can use a front slash to separate directory names. This
works equally well for Windows and other operating systems.
• To identify the name and location of a file, you can use an absolute path name to
specify the entire path for a file. You can also use a relative path name to specify
the path of the file relative to the directory that contains the class that identifies the
path.
Figure 18-2 Code examples that work with directories and files
564 Section 5 Data access programming with Java
File Edit Search View Encoding Language Settings M acro Run Plugins W indo w ?
File Edit Search View Encoding Language Settings M acro Run Plugins W in d o w ? X
•j dà I * tL i Γϋ I 3 e I ä I * * ·
a products bin |
Description
• An input file is a file that is read by a program; an output file is a file that is written
by a program. Input and output operations are often referred to as I/O operations or
file I/O.
• A stream is the flow of data from one location to another. To write data to a file
from internal storage, you use an output stream. To read from a file into internal
storage, you use an input stream.
• To read and write text files, you use character streams. To read and write binary
files, you use binary streams.
• Streams are not only used with disk devices, but also with input devices like
keyboards and network connections and output devices like PC monitors and
network connections.
Description
• The java.io package contains dozens of classes that can be used to work with
different types of streams that have different functionality.
• To get the functionality you need for a stream, you often need to combine, or layer,
two or more streams. You’ll leam more about how this works as you progress
through this chapter.
• To make disk processing more efficient, you can use a buffered stream that adds a
block of internal memory called a buffer to the stream.
• When working with buffers, you often need to flush the buffer. This sends all data
in the buffer to the I/O device. One way to do that is to use a try-with-resources
statement to automatically close the I/O stream after you use it.
input stream for the products file. Within the try block, the two statements read
the first line of that file and print that line to the console. Finally, once the try-
with-resources statement finishes executing, it automatically closes the input
stream, which flushes the buffer and frees all system resources associated with
the input stream.
Because this figure is only intended to give you an idea of how file I/O
works, you shouldn’t worry if you don’t understand it completely. As you
progress through this chapter, you’ll learn about all of the classes and methods
shown here in more detail.
while(line 1= null)
{
System.out.println(line);
line = in.readLine();
}
}
catch (IOException e)
{
System.out.println(e) ;
}
}
else
{
System.out.println(
productsPath.toAbsolutePathO + " doesn't exist");
}
Description
• The Writer class is an abstract class that’s inherited by all of the classes in the Writer
hierarchy. To learn more about the Writer hierarchy, see the Java API documentation.
• If the output file doesn’t exist when the FileWriter object is created, it’s created auto
matically. If it does exist, it’s overwritten by default. If that’s not what you want, you
can specify true for the second argument of the constructor to append data to the file.
• If you specify true for the second argument of the PrintWriter constructor, the
autoflush feature flushes the buffer each time the println method is called.
Description
• To write a character representation of a data type to an output stream, you use the
print and println methods of the PrintWriter class. If you supply an object as an
argument, these methods will call the toString method of the object.
• To create a delimited text file, you delimit the records in the file with one delimiter,
such as a new line character, and you delimit the fields of each record with another
delimiter, such as a tab character.
• To flush all data to the file, you can use a try-with-resources statement to automati
cally close the stream when you’re done using it.You can also use the flush or close
methods of the stream to manually flush all data to the file.
Description
• The Reader class is an abstract class that’s inherited by all of the classes in the
Reader hierarchy. To leam more about the Reader hierarchy, check the documenta
tion for the Java API. All classes in the java.io package that end with Reader are
members of the Reader hierarchy.
• Although you can read files with the FileReader class alone, the BufferedReader
class improves efficiency and provides better methods for reading character input
streams.
Sample output
------- *
This application was run on Mon Oct 19 09:21:42 PDT 2009
This application was run on Tue Oct 20 10:14:12 PDT 2009
V- ----------J
Example 2: Code that reads a Product object from a delimited text file
// read the next line of the file
String line = in.readLine();
Sample output
/?--------------- ------- Λ
Code : java
Description: Murach's Beginning Java
Price: $49.50
V ------------------------ ----------- 4
public ProductTextFile()
{
productsPath = Paths.get("products.txt");
productsFile = productsPath.toFile();
products = this.getProducts();
}
public ArrayList<Product> getProducts()
{
// if the products file has already been read, don't read it again
if (products 1= null)
return products;
products = new A r r a y L i s t o () ;
line = in.readLine();
}
}
catch(IOException e)
{
System.out.println(e) ;
return null;
}
}
return products;
}
Figure 18-11 A class that works with a text file (part 1 of 2)
582 Section 5 Data access programming with Java
change the way that exceptions are handled. For example, you might want to
write an error message to a log file. Or, you might want to throw a custom
exception that indicates that a generic access error has occurred. For more
information on how to create a custom exception, see chapter 14.
The getProduct method returns a Product object for a product that matches
the specified product code. To search for the product, this method loops through
each product in the products array list until it finds one with the specified
product code. Finally, it returns that product. If no product is found with the
specified code, this method returns a null.
The saveProducts method accepts an ArrayList object that contains Product
objects, and it writes all of these Product objects to the file. If this operation is
successful, it returns a true value. If an IOException is thrown, this method
returns a false value to indicate that the save operation wasn’t successful.
The saveProducts method starts by creating a buffered output stream that
connects to the products file. Then, this method uses a loop to write each
product in the array list to the file. To do that, it uses the FIELD_SEP constant
to separate each field in a product record, and it uses the println method to insert
a new line character at the end of each product record.
The addProduct method starts by calling the add method of the ArrayList
class to add the product to the array list. Then, it calls the saveProducts method to
save the modified array list to the products file so that the array list and the file
contain the same data. Notice that the addProduct method returns the boolean
value that’s returned by the saveProducts method. That way, if the saveProducts
method returns a true value, the addProduct method will also return true.
The deleteProduct method is similar. It starts by calling the getProducts
method to return a products array list. Then, it calls the remove method of the
ArrayList class to remove the product from the array list. Finally, it calls the
saveProducts method to save the array list to the products file, and it returns the
boolean value that’s returned by that method.
The updateProduct method works a little differently. This method updates
the data for an existing product with the data in a new Product object. To start,
this method uses the getProduct method to get the old Product object with the
same product code as the new Product object. Then, it gets the index for the old
product, and it removes that product from the array list. Next, it inserts the new
product into the array list where the old product used to be. Finally, it calls the
saveProducts method to save the array list to the products file, and it returns a
value that indicates whether the save operation was successful.
As you review this code, you should realize that this class won’t work
correctly for multiple users. For example, suppose that both user A and user B
read the products file, and user A modifies that file. Then, suppose user B also
modifies the file. At this point, user B’s changes overwrite user A’s changes.
This is known as a concurrency problem.
One way to reduce concurrency problems would be to read the data from
the file each time the getProducts, getProduct, addProduct, updateProduct, and
deleteProduct methods are called. That way, the data is more likely to be
current. However, this would be inefficient, particularly if the file contained
thousands of records. That’s why developers typically use databases to store
data that’s going to be accessed by multiple users.
Chapter 18 How to work with text and binary files 583
return this.saveProducts();
}
}
Figure 18-11 A class that works with a text file (part 2 of 2)
584 Section 5 Data access programming with Java
Description
• The OutputStream class is an abstract class that’s inherited by all of the classes in
the OutputStream hierarchy. To leam more about the OutputStream hierarchy,
check the documentation for the Java API.
• All classes in the java.io and java.util.zip packages that end with OutputStream are
members of the OutputStream hierarchy.
• The FilterOutputStream class is a superclass of all classes that filter binary output
streams.
• If the output file doesn’t exist when the FlleOutputStream object is created, it’s
created automatically. If it does exist, it’s overwritten by default. If that’s not what
you want, you can specify true for the second argument of the constructor to
append data to the file.
• Although a buffer isn’t required, it makes output operations more efficient.
Description
• Since the DataOutputStream class implements the DataOutput interface, you can
call any of the methods shown above from a DataOutputStream object.
• The writeUTF method writes a two-byte number that indicates the number of bytes
in the string. Then, it writes the characters using the Universal Text Format (UTF).
For most strings, UTF uses one byte per character.
Description
• The InputStream class is an abstract class that’s inherited by all of the classes in the
InputStream hierarchy. To learn more about the InputStream hierarchy, check the
documentation for the Java API.
• All classes in the java.io and java.util.zip packages that end with InputStream are
members of the InputStream hierarchy.
• The FllterlnputStream class is a superclass of all classes that filter binary input
streams.
• Although a buffer isn’t required, it makes input operations more efficient.
Description
• Since the DatalnputStream class implements the Datalnput interface, you can call
any of the methods shown above from an object of this class.
• The readUTF method reads characters that were written with the Universal Text
Format.
out.close();
Resulting output
writeUTF writes 25 bytes. Ί
writeChars writes 46 bytes.______________________ J
File Edit Search View Encoding Language Settings Macro Run Plugins Window ? X
a J@ 1 s a t2 l I “à Î 3 111 ! ü C I® I * * 1- - ' 1 | @ ΐ 1 E I @ | S v g
3 test .bin
WHWIJIHtaThi i i s a t e s t s t r i n g .
PBHTB M h M l i liimis RUB BHDi Omis BOB SH BaSnn fitfH- lÎtfl'He lifflWa KflHlt fJili* Biiill·; liili* IJilin· |}IWL· IJiliH: lining f ilm . lip
Resulting output
readUTF reads 25 bytes. Ί
readChar reads 46 bytes.________________________ j
Description
• You can use the classes in the OutputStream and InputStream hierarchies to read
and write files sequentially. A file you access sequentially is called a sequential-
access file. When you work with a sequential-access file, you read from the begin
ning of the file to the end of the file, and you can add data only at the end of the file.
• You can use the RandomAccessFile class to read and write files randomly. A file
you access randomly is called a random-access file. When you work with a ran
dom-access file, you can move a pointer to any point in the file. Then, you can read
and write data starting at that point. This lets you modify part of a file without
affecting the rest of the file.
• If you use one of the synchronized read-write modes, only one user at a time can
update the file. Since the rwd mode doesn’t update the metadata with each operation,
it reduces the number of IO operations and runs slightly faster than the rws mode.
• The metadata for a file includes information about the file such as its size, the date
it was last modified, and so on.
productsFile.close() ;
Description
• When writing to a random-access file, it’s a common coding practice to write each
record with the same number of bytes. This makes it possible to move the file
pointer to the start of each record in the file.
Figure 18-18 How to read to and write from a random access file
598 Section 5 Data access programming with Java
Description
• When you write strings to a random-access file, you need to write fixed-length
strings. That way, the length of the strings won’t vary from one record to another,
and all of the record lengths in the file will be the same.
• You can create a class like the IOStringUtils class shown above that contains static
methods to write and read fixed-length strings.
• The writeFixedString method writes the characters of an input string to an output
file followed by Unicode zeros for any unused positions in the fixed-length output
string.
• The readFixedString method reads a string written by the writeFixedString method,
but stops appending characters to the StringBuilder object when the first Unicode
zero is read.
public ProductRandomFile()
{
try
{
productsFile = new RandomAccessFile("products.ran", "rw");
productCodes = this.getCodes();
}
catch(IOException e)
{
System.out.println(e);
}
}
//*************************************************
// Private methods for reading products
//*************************************************
The getRecord method accepts an int value that specifies the record number
for a record and returns a Product object for that record. To start, this method
checks if the record number is greater than or equal to zero and less than the
total number of records. If so, the record number is valid and the method
continues by creating a Product object from the data that’s stored in the record
and returning it to the calling method. Otherwise, the method returns a null to
indicate that no product exists for that record number.
To create the Product object, the getRecord method uses the seek method to
position the pointer at the beginning of the specified record. Then, the
readFixedString method of the IOStringUtils class is used to read the product’s
code and description, and the readDouble method is used to read the product’s
price. Finally, these values are passed to the constructor of the Product class to
create a Product object.
The getCodes method creates an array list that contains every product code
that’s stored in the file. To start, this method declares an array list of strings.
Then, it uses a loop to read each product code from the file into the array. To do
that, this method uses the getRecordCount method to return the number of
records in the file, it uses the seek method to skip to the beginning of each
record, and it uses the static readFixedString method of the IOStringUtils class
to read the string for the product code. When the loop completes, the array list is
returned to the calling method. If an exception is encountered as the product
codes are read, however, the exception is printed to the console and a null is
returned to indicate that the getCodes method did not complete successfully.
Chapter 18 How to work with text and binary files 603
The next two methods in this class are public methods that return Product
objects. Both of these methods catch any IOException that might be thrown.
This prevents any of the implementation details of this class (such as the type of
exceptions) from being exposed to other classes, and it makes it easier for
programmers to use these methods since they don’t have to handle these
exceptions.
If either of these methods encounter an IOException, its catch clause
executes two statements. The first statement prints the exception to the console,
which can help the programmer who is coding this class determine the cause of
the error during the testing and debugging phase. Then, the second statement
returns a null. This indicates to the programmer who is using this class that the
operation wasn’t completed successfully.
The getProducts method returns an array list that contains all the Product
objects in the file that haven’t been marked for deletion. To do that, this method
begins by creating an ArrayList object named products that can store Product
objects. Then, it uses a loop to create a Product object for each record. Within
the loop, an if statement checks if the product code for the record is equal to the
DELETION_CODE constant. If not, the product has not been marked for
deletion. Then, the getRecord method is called to get the Product object for the
record, and the Product object is added to the array list.
The getProduct method accepts a product code. If the random-access file
contains a record with this product code, this method returns a Product object
that contains the data that’s stored in that record. To do that, it calls the
getRecordNumber method to get the record number of the record with the
specified product code. Then, it calls the getRecord method to get the record
with that number, and it creates a Product object from the data in that record.
Note that if a record with the specified product code isn’t found, the
getRecordNumber method returns -1. Then, the getRecord method returns a
null because -1 is an invalid record number. In that case, the Product object
that’s returned to the calling method is null.
Chapter 18 How to work with text and binary files 605
The next method in this class is a private method named writeProduct that’s
used to write the data for a product to the file. This method accepts a Product
object and a record number. It uses the record number to move the pointer to the
position in the file where the record is to be written. Then, it writes the data in
the Product object to the file. To write the product code and description fields, it
uses the writeFixedString method of the IOStringUtils. To write the price field,
it uses the writeDouble method. If an exception is thrown by any of these
statements, this method prints the exception and returns a false value.
The next three methods are public methods that can be used to add, update,
and delete the products stored in the products file. All three of these methods
accept a Product object as an argument.
The addProduct method writes the data in the Product object that’s passed
to it to the end of the random-access file. To do that, it adds the product code to
the productCodes array list. Then, it calls the getRecordNumber method to get
the record number of the new product. Finally, it calls the writeProduct method
to write the new product at the position indicated by the record number, which
should be at the end of the file. If the writeProduct method executes success
fully, it returns a true value. That value is then returned to the method that called
the addProduct method.
The updateProduct method writes the data that’s stored in the Product object
that’s passed to it over the record that has the same product code. To do that, it
starts by calling the getRecordNumber method to get the record number for the
product. If this record number isn’t equal to -1, which indicates that the product
was found, this method calls the writeProduct method to write the data for the
specified Product object over the data for the current record. However, if the
product code isn’t found, this method returns a false value and doesn’t update
the record.
The deleteProduct method marks the specified Product object for deletion. To
do that, the first statement gets the record number for the Product by calling the
getRecordNumber method. If this method returns a value other than -1, indicat
ing that the product was found, the set method of the productCodes array list is
used to set the product code of the specified product to the value that’s stored in
the DELETION_CODE constant. Then, the product code for the product is set to
the DELETION_CODE constant. Finally, the deleteProduct method calls the
writeProduct method to write the Product object to the file. If this write operation
is successful, this method returns a true value. If this operation isn’t successful,
or if the product wasn’t found, this method returns a false value.
Since the deleteProduct method doesn’t actually delete the record from the
file, you may want to include another method in this class that deletes all the
records that have been marked for deletion. Then, you can run that method
periodically to remove unnecessary data from the file. To do that, this method
could use the getProducts method to read all the products that haven’t been
marked for deletion. Then, it could write all of these products to the file, over
writing any existing records. Finally, it could use the setLength method of the
RandomAccessFile class to set the length of the file based on the number of
records that remain, which would truncate any leftover data at the end of the file.
Chapter 18 How to work with text and binary files 607
Perspective
In this chapter, you learned how to read and write text files sequentially,
and you learned how to read and write binary files sequentially and randomly.
If you’ve already read the chapters in section 4, this means that now at last you
can see how all of the classes and methods in a business application work
together. That includes presentation classes like JFrame and JPanel classes,
business classes like Product and Invoice classes, and data access classes like
the ProductTextFile and ProductRandomFile classes.
Now that you’ve seen how to work with text files and binary files, you
might want to take a moment to consider the advantages and disadvantages of
each. For example, since you don’t need to convert int and double values to
strings and back, binary files make it easier to work with numbers. However,
text files often make it easier to share data with other programs. For example,
the data in a text file can be viewed in a text editor or a web browser.
As you work with files, remember that they are only one option for storing
data. Another option is to store data in a database. Because databases provide
sophisticated features for organizing and managing data, they’re used for most
serious applications. You’ll leam how to work with databases in chapter 20.
But first, the next chapter will show you how to work with data using XML.
Summary
• A text file stores data as characters. A binary file stores data in a binary format.
• In a delimited text file, delimiters are used to separate thc fields and records of the
file.
• You use character streams to read and write text files and binary streams to read
and write binary files. To get the functionality you need, you can layer two or more
streams.
• A buffer is a block of memory that is used to store the data in a stream before it is
written to or after it is read from an I/O device. When an output buffer is full, its
data is flushed to the I/O device.
• When you work with I/O operations, you’ll need to catch or throw three types of
checked exceptions: IOException, FileNotFoundException, and EOFException.
• To identify a file when you create a File object, you can use an absolute path name
or a relative path name.
• The java.nio.file package provides classes and interfaces that you can use to check
whether a file or directory exists, to get information about a path, to create or
delete directories and files, and to create a File object.
• You can use the classes in the Writer and Reader hierarchies to work with a text
file. You can use the classes in the OutputStream and InputStream hierarchies to
Chapter 18 How to work with text and binary files 609
work with a binary file. You can also use the methods of the DataOutput and
Datalnput interfaces to work with binary files.
• You can use the RandomAccessFile class to access a binary file randomly rather
than sequentially. When you use a random-access file, you can position a pointer
to any location in the file.
• When you work with random-access files, you store string values as fixed-length
strings. That way, the files have the same number of bytes for each field within
each record.
when the output stream is opened, print the exception to the console and
return false to the calling method.
6. Run the application, and test the list, add, and delete functions to be sure they
work.
IOException occurs, it should return -1.) To do that, you can load the
products array with all the records that haven’t been deleted, write all the
products in the products array list to the file, and use the setLength method to
set the file to the appropriate length. To make this code work, you’ll need to
close the RandomAccessFile object so the new file length is applied. Also, be
sure to reopen the file for random access, and reinitialize the productCodes
array so it contains only the current products.
7. Display the ProductMaintApp class and add a commit command to the menu.
When the user enters this command, a method named commitDeletions
should be executed. Add the code for this method so it creates a new
ProductRandomFile object and then calls the commitDeletions method of this
object. If the commit operation is successful, it should display the number of
records that were deleted. Otherwise, it should display an appropriate error
message.
8. Test this code to be sure it works correctly. To do that, start by deleting one or
more records. Then, commit the deletions.
19
How to work with XML
XML provides a standard way of storing data. Although XML is often used to
exchange data between applications, particularly web-based applications, it can
also be used to store structured data in a file. In this chapter, you’ll learn the
basics of creating XML documents, and you’ll learn how to store those
documents in a file. Because the class that’s presented at the end of this chapter
uses an array list, you may want to review chapters 11 and 12 before you read
this chapter.
Introduction to XML
The topics that follow introduce you to the basics of XML. Here, you’ll
leam what XML is, how it is used, and the rules you must follow to create a
simple XML document.
An XML document
XML (Extensible Markup Language) provides a standard way to structure
data by using tags that identify each data element. In some ways, XML is
similar to HTML, the markup language that’s used to format HTML documents
on the web. As a result, if you’re familiar with HTML, you’ll have no trouble
learning how to create XML documents.
Figure 19-1 shows a simple XML document that contains data for three
products. Each product has a code, description, and price. In the next two
figures, you’ll leam how the tags in this XML document work. But even without
knowing those details, you can pick out the code, description, and price for each
of the three products represented by this XML document.
You can also use XML files as an alternative to the text and binary files
described in chapter 18. Later in this chapter, for example, you’ll see a
ProductXMLFile class that uses an XML file. You can use this class with the
Product Maintenance application you first saw in chapter 9.
Chapter 19 How to work with XML 615
Description
• XML, which stands for Extensible Markup Language, is a method of structuring
data using special tags.
• The XML document in this figure contains data for three products. Each product has
an attribute named Code and elements named Description and Price. You’ll learn
more about attributes and elements in the next two figures.
• XML can be used to exchange data between different systems, especially via the
Internet.
• XML documents that are stored in a file can be used as an alternative to binary
files, text files, or even database systems for storing data.
• When XML is stored in a file, the file name usually has an extension of xml.
XML elements
Elements are the building blocks of XML. Each element in an XML docu
ment represents a single data item and is identified by two tags: a start tag and
an end tag. The start tag marks the beginning of the element and provides the
element’s name. The end tag marks the end of the element and repeats the
name, prefixed by a slash. For example, <Description> is the start tag for an
element named Description, and </Description> is the corresponding end tag.
It’s important to realize that XML does not provide a pre-defined set of
element names the way HTML does. Instead, you create your own element
names to describe the contents of each element. Also, since XML names are
case-sensitive, <Product> and <product> are not the same.
A complete element consists of the element’s start tag, its end tag, and the
content between the tags. For example, <Price>49.50</Price> indicates that the
content of the Price element is 49.50. And <Description>Murach’s Beginning
Java</Description> indicates that the content of the Description element is
Murach’s Beginning Java.
Besides content, elements can contain other elements, known as child
elements. This lets you add structure to a parent element. For example, a parent
product element can have child elements that provide details about each prod
uct, such as the product’s description and price. In this figure, for example, you
can see that the start tag, end tag, and values for the Description and Price
elements are contained between the start and end tags for the Product element.
As a result, Description and Price are children of the Product element, and the
Product element is the parent of both the Description and Price elements.
Chapter 19 How to work with XML 617
An XML document
<?xml versions111 .0 " encodings"utf-8 "?>
Description element
<!--Product data-->
<Products>
<Product Code="java11>
<Description>Murachls Beginning Java</Description>
z
<Price>49.50</Price> Product element
</Product>
</Products>
Price element
Elements
• An element is a unit of XML data that begins with a start tag and ends with an end
tag. The start tag provides the name of the element and contains any attributes
assigned to the element (see figure 19-3 for details on attributes). The end tag
repeats the name, prefixed with a slash (/). You can use any name you want for an
XML element.
• The text between an element’s start and end tags is called the element’s content.
For example, <Description>Murach’s Beginning Java</Description> indicates that
the content of the Description element is the string Murach’s Beginning Java.
• Elements can contain other elements. An element that’s contained within another
element is known as a child element. The element that contains a child element is
known as the child’s parent element.
• Child elements can repeat within a parent element. For instance, in the example
above, the Products element can contain more than one Product element. Similarly,
each Product element could contain repeating child elements.
• The highest-level parent element in an XML document is known as the root
element. An XML document can have only one root element.
As the XML document in figure 19-1 shows, an element can occur more
than once within an XML document. In this case, the document has three
Product elements, each representing a product. Since each of these Product
elements contains Description and Price elements, these elements also appear
three times in the document.
Although this example doesn’t show it, a given child element can also occur
more than once within a parent. For example, suppose you want to provide for
products that have more than one category. You could do this by using a Cat
egory child element to indicate the category of a product. Then, for a product
that belongs to multiple categories, you simply include multiple Category child
elements within the Product element for that product.
The highest-level parent element in an XML document is known as the wot
element, and an XML document can have only one root element. In the ex
amples in figures 19-1 and 19-2, the root element is Products. For XML docu
ments that contain repeating data, it is common to use a plural name for the root
element to indicate that it contains multiple child elements.
XML attributes
As shown in figure 19-3, attributes are a concise way to provide data for
XML elements. In the products XML document, for example, each Product
element has a Code attribute that provides an identifying code for the product.
Thus, <Product Code="java"> contains an attribute named Code whose value is
java.
Here again, XML doesn’t provide a set of pre-defined attributes. Instead,
you create attributes as you need them, using names that describe the content of
the attributes. If an element has more than one attribute, you can list the at
tributes in any order you wish. However, you must separate the attributes from
each other with one or more spaces. In addition, each attribute can appear only
once within an element.
When you plan the layout of an XML document, you will often need to
decide whether to use elements or attributes to represent each data item. In
many cases, either one will work. In the products document, for example, I
could have used a child element named Code rather than an attribute to repre
sent each product’s code. Likewise, I could have used an attribute named
Description rather than a child element for the product’s description.
Because attributes are more concise than child elements, it’s often tempting
to use attributes rather than child elements. Keep in mind, though, that an
element with more than a few attributes soon becomes unwieldy. As a result,
most designers limit their use of attributes to certain types of data, such as
identifiers like product codes or customer numbers.
Chapter 19 How to work with XML 619
An XML document
<?xml versions111 .0 " encodings"utf-8 " ?>
< !- -Product data- -> ^ C()de attribute
<Products>
<Product Code="java"
<Description>Murach's Beginning Java</Description>
<Price>49.50</Price>
</Product>
</Products>
Description
• You can include one or more attributes in the start tag for an element. An attribute
typically consists of an attribute name, an equal sign, and a string value in quotes.
• If an element has more than one attribute, the order in which the attributes appear
doesn’t matter, but the attributes must be separated by one or more spaces.
An introduction to DTDs
By now, you can begin to see that XML provides a flexible way to store
structured data. However, the XML standard provides for other tools that you
can use to work with an XML document. One of the most useful is a schema,
which you can use to define a list of conditions that an XML document must
follow. For example, figure 19-4 shows how to use a Document Type Definition
{DTD) to define the conditions for the products.xml document shown in figure
19-1.
Although a DTD is optional, you can use a DTD to make sure that various
XML documents use the same format. For example, if various suppliers were
sending you information about their products, you could supply them with a
DTD to make sure that they all used a compatible format. This provides a way
to create a standard set of tags for a certain application.
In a DTD, each XML element is declared in an ELEMENT declaration. If
an element has children, that element must declare the children by listing the
names in order, separated by commas. For example, the Product element DTD
in this figure contains Description and Price elements in that order.
To specify that a child element may occur zero or one time, you can code a
question mark after the element name. To specify that a child element may
occur zero or more times, you can code an asterisk after the element name. And
to specify that an element must occur one or more times, you can code a plus
sign after the element name. If you don’t code any of these characters after an
element name, the element must occur one and only one time.
If an element contains text, you code the #PCDATA (parsed character data)
keyword for that element. In this figure, for example, you can see that this
keyword is coded for both the Description and Price elements.
To specify the attributes for an element, you use the ATTLIST declaration.
This declaration specifies the element to which the attribute belongs, the name
of the attribute, and the attribute type. If an attribute contains character data, you
code the CDATA keyword. (Notice that you don’t prefix this keyword with the #
character.) In addition, an attribute declaration can include the #REQUIRED
keyword to show that the attribute is required. In this figure, the Code attribute
of the Product element is required, and it can store character data.
This figure also shows an XML document that uses a DOCTYPE declara
tion to refer to a DTD that’s stored in an external file. Here, the DOCTYPE
declaration is coded after the XML declaration but before the start tag of the
root element, and this declaration points to a DTD file named products.dtd.
(Because a path isn’t specified for this file, it must be stored in the same direc
tory as the products.xml file.) That way, you can easily validate this XML
document against the specified DTD.
Chapter 19 How to work with XML
Description
• XML allows you to set conditions that must be enforced on an XML document. To
define these conditions, you use a schema language to create a schema. Document
Type Definition (DTD) is a schema language that’s part of standard XML.
• You use the ELEMENT declaration in a DTD to define the names of the elements
and the types of data they will contain. You use the ATTLIST declaration to define
the names of the attributes and the types of data they will contain.
• By default, each child element must occur one time. To specify that a child element
can occur zero or one time, code a question mark after the name of a child element
on the parent element declaration. To specify that the child element can occur zero
or more times, code an asterisk. And to specify that a child element can occur one
or more times, code a plus sign.
• In an XML document, you can use a DOCTYPE declaration to refer to a DTD
that’s stored in a DTD file.
<£■ ί D file :///C :i, m u r a c h /ja v a /file s /p r o d u c ts.x m l - C i l ' Google p II*
M o s t V isited ' S . G ettin g S ta rte d L a te s t H e a d lin e s I f l B o o k m a rk s
This X M L file does not a p p ear to have any style information associated with it- The document tree is show n below.
—< P ro d u c ts>
—< P ro d u c t Code="java">
< D escription> M u rach 's Beginning J a v a< D escriptions·
< P ric e > 4 9 .5 < P ric e >
< /P roduct>
—< P ro d u c t C ode="jsps">
<D escriptioB >M urach's Java Servlets and J S P < D e sc rip tio n >
< P ric e > 4 9 .5 <<Pric e>
< /P roduct>
- < P r o d u c t C o d e = ”mcb2">
< D escription> M u rach 's Mainframe C O B O L < 'D e sc rip tio n >
< P ric e > f 9.5 < P r i c e>
P r o d u c t?
< P r o d « c ts >
E l-g S c h l9 _ P ro d u c lN a in t
a a »aI
(i?xml ver3ion="1.0"?>
I V a lid a te X M L ( A lt* Shift-*- F9) |
<! DOCTYPE P ro d u c ts SYSTEM pr0ducc3.dcG
<Products>
< P r o d u c t : C a d e = " ; a T/a" >
<Descxiption>Murach1 Beginning Java</Descxiption>
< Price> 4 9 .5</Pxice>
</Product>
8 .( 3 <Produce C o d e ^ j 3p5''>
11 </Product>
Filters; Ο ®
S I Hi
Description
• You can d isp lay an X M L docum ent in a brow ser. You can e d it an X M L docum ent
in a tex t e d ito r lik e th e one th a t com es w ith N etB eans.
DOM
DOM stands for Document Object Model. This XML standard was devel
oped by the World Wide Web Consortium (www.w3c.org). When working with
DOM, the entire XML document is stored in memory as a collection of objects.
As a result, DOM isn’t appropriate for working with large XML documents.
SAX
SAX is the Simple API for XML. Originally, this XML API was a Java-only
API, but versions are now available for other languages too. With SAX, the
programmer writes code that handles events that are fired when the XML parser
reads the XML document. Since the programmer must respond to data that is
pushed to the application by the XML parser, this is known as a push
technology. Although this approach allows SAX to read large XML documents
quickly and to use memory efficiently, SAX doesn’t provide a mechanism for
writing documents.
StAX
StAX is the Streaming API for XML. Like DOM, StAX can be used to read
or write XML. Like SAX, StAX is fast and memory efficient when working
with small or large files. In addition, many programmers feel that the StAX API
is designed better than DOM or SAX, which makes it easier for the programmer
to use. With StAX, the programmer writes code that controls when and how the
XML parser reads and writes the XML document. Since the programmer can
pull data from the XML parser, this is known as a pull technology, and it gives
the programmer more flexibility for working with XML.
Chapter 19 How to work with XML 625
DOM is
• Memory intensive
• Read-write
• Typically used for working with documents smaller than 10 megabytes
SAX is
• Memory efficient
• Read-only
• Typically used for working with documents larger than 10 megabytes
StAX is
• Memory efficient
• Read-write
• Appropriate for documents of all sizes.
• Easier to use than DOM or SAX
Description
• The Document Object Model (DOM) and the Simple API for XML (SAX) are two
older XML APIs. Both of these APIs have been supported since JDK 1.4.
• The Streaming API for XML (StAX) is a newer API that was introduced with JDK
1.6 .
• When you use DOM, the entire XML document structure is read into memory.
• When you use SAX or StAX, you can read only the parts of the XML document
that you need.
• With SAX, the programmer writes code that handles events that are fired when the
XML parser reads the elements of the XML document. This is known as a push
technology.
• With StAX, the programmer writes code that controls when and how the XML
parser reads and writes the XML document. This is known as a pull technology.
try
{
// create XMLStreamWriter object
FileWriter fileWriter =
new FileWriter("products.xml");
XMLStreamWriter writer =
outputFactory.createXMLStreamWriter(fileWriter);
Description
• You can use the XMLOutputFactory class to create an XMLStreamWriter object.
Then, you can use the XMLStreamWriter object to write an XML document to a
stream as described in the next figure.
• To write XML to a file, you can supply a FileWriter object as the argument for the
createXMLStreamWriter method. For more information about the FileWriter
object, please see chapter 18.
• To write XML to an output stream, such as the console, you can supply any stream
that implements the abstract OutputStream class as the argument for the
createXMLStreamWriter method.
writer.writeStartElement("Description");
writer.writeCharacters(p.getDescription());
writer.writeEndElement() ;
writer.writeStartElement("Price");
double price = p.getPrice();
writer.writeCharacters(Double.toString(price));
writer.writeEndElement();
Description
• Since these methods throw an XMLStreamException, you must handle this excep
tion when working with these methods.
Description
• You can use the XMLInputFactory class to create an XMLStreamReader object.
Then, you can use the XMLStreamReader object to read an XML document from a
stream as described in figure 19-10.
• To read XML from a file, you can supply a FileReader object as the argument for
the createXMLStreamReader method. For more information about the FileReader
object, please see chapter 18.
Description
• If the called method isn’t valid for the current event, an XMLStreamException is
thrown. As a result, you must handle the XMLStreamException when you work
with these methods.
• If the called method isn’t valid for the event, an IllegalStateException is thrown.
Since an IllegalStateException is an unchecked exception, you don’t have to handle
it. If possible, though, it’s a good practice to write your code so it prevents this type
of exception from being thrown.
Code that reads all Product elements into a products array list
ArrayList<Product> products = new A r r a y L i s t o ();
Product p = null;
while (reader.hasNext())
{
Int eventType = reader.getEventType();
switch (eventType)
{
case XMLStreamConstants.START_ELEMENT:
String elementName = reader.getLocalName();
if (elementName.equals("Product"))
{
p = new Product();
String code = reader.getAttributeValue(0);
p .setCode(code);
}
if (elementName.equals("Description"))
{
String description = reader.getElementText();
p.setDescription(description);
}
if (elementName.equals("Price") )
{
String priceString = reader.getElementText();
double price = Double.parseDouble(priceString);
p.setPrice(price);
}
break;
case XMLStreamConstants.ENDELEMENT:
elementName = reader.getLocalName();
if (elementName.equals("Product"))
{
products.add(p) ;
}
break;
default:
break;
}
reader.n e x t () ;
}
public ProductXMLFile()
{
productsPath = Paths.get("products.xml");
products = this.getProducts();
}
private boolean saveProducts()
{
// create the XMLOutputFactory object
XMLOutputFactory outputFactory = XMLOutputFactory.newFactory()
try
{
// create XMLStreamWriter object
FileWriter fileWriter =
new FileWriter(productsPath.toFile());
XMLStreamWriter writer =
outputFactory.createXMLStreamWriter(fileWriter);
products = new A r r a y L i s t o () ;
Product p = null;
if (Files.exists(productsPath)) // prevent the FileNotFoundException
{
// create the XMLInputFactory object
XMLInputFactory inputFactory = XMLInputFactory.newFactoryO;
try
{
// create a XMLStreamReader object
FileReader fileReader =
new FileReader(productsPath.toFile());
XMLStreamReader reader =
inputFactory.createXMLStreamReader(fileReader);
return this.saveProducts();
}
}
Perspective
In this chapter, you learned the basic concepts and terms for working with
XML. In addition, you learned how to use the XMLStreamReader and
XMLStreamWriter interfaces to read and write XML documents. With that as
background, you should be able to read and write XML documents of all types
and sizes.
However, the StAX API provides two other interfaces that can also be used
to read and write XML documents: the XMLEventReader and
XMLEventWriter interfaces. You can use the XMLEventFactory class to
create objects that implement these interfaces. Since this works similarly to the
techniques presented in this chapter, you shouldn’t have too much trouble
using these interfaces if necessary. The main advantage is that the
XMLEventReader interface includes a peek method that allows you to look at
the next XML event without reading it from the stream.
Finally, if you want or need to learn how to work with the DOM, SAX, or
other XML API, you can find more information on the Java web site.
Summary
• XML provides a standard way to structure data by using tags that identify data
items.
• An element begins with a start tag and ends with an end tag. An element can
contain data in the form of content that appears between the tags. It can also
contain child elements.
• An attribute consists of a name and value that appear within an element’s start tag.
• A DTD (Documentation Type Definition) is a schema that defines the structure of
an XML document. This schema can be enforced when a document is read or
written.
• You can use a web browser to view XML data, and you can use any text editor to
edit an XML file, but it’s helpful to use a text editor that’s designed for working
with XML.
• DOM (the Document Object Model) is an API that can be used to build a DOM
tree, work with the nodes of a tree, read an XML document from a file, and write
an XML document to a file.
• SAX (the Simple API for XML) can be used to read an XML document.
• StAX (the Streaming API for XML) is appropriate for reading or writing XML
documents of all sizes.
Chapter 19 How to work with XML 643
Products list:
java Murach's Beginning Java $49.50
jsps Murach's Java Servlets and JSP $49.50
test XML Tester $77.77
Products list:
java Murach's Beginning Java $49.50
jsps Murach's Java Servlets and JSP $49.50
V- --- 4
1. Use a web browser to view the products.xml file in the
ex_starts\chl9_exl_XMLTester directory. Then, collapse and expand some of
the elements.
2. Open the project named chl9_exl_XMLTester that’s stored in the ex_starts
directory. Then, open the XMLTesterApp class and review its code. Finally,
run this project to see how it works. At this point, it prints three messages to
the console, but it doesn’t work with the XML file.
3. Add code to the readProducts method that reads an XML document from the
products.xml file and stores it in an array list. Be sure to catch any exceptions
that may be thrown. Then, test the class. At this point, the application should
print three identical product lists, and those lists should match the data that’s
stored in the products.xml file.
4. Add code to the writeProducts method that writes the XML document to the
products.xml file. Then, remove the comments from the code in the main
method that adds and removes a product from the list. Finally, test the
application again. When you do, it should display the messages shown above.
20
How to work
with a Derby database
Since Java SE 6, Java has included an open-source, all-Java database
known as Derby that provides the features of a true relational database
management system (RDMS). Since this database is already installed on your
computer, it’s a convenient way to leam about how relational database
management systems work. In addition, if you need to embed a database in a
client application, Derby might be exactly what you need.
To start, this chapter teaches you some basic concepts for working with a
relational database. Then, it shows you some specific skills for working with
a Derby database.
Description
• A relational database uses tables to store and manipulate data. Each table contains
one or more records, or rows, that contain the data for a single entry. Each row
contains one or more fields, or columns, with each column representing a single
item of data.
• Most tables contain a primary key that uniquely identifies each row in the table.
• The software that manages a relational database is called a database management
system (DBMS). Four popular database management systems today are Oracle,
Microsoft’s SQL Server, IBM’s DB2, and MySQL.
Primary key
2 1 jsps 5
3 2 mcb2 1
4 4 cshp 1
8 4 zjcl 2
9 6 sqls 1
10 iqvq 1
11 7 mcb2 5
1
Foreign key
Description
• The tables in a relational database are related to each other through their key
columns. For example, the ProductCode column is used to relate the Products and
Lineltems tables. The ProductCode column in the Lineltems table is called a
foreign key because it identifies a related row in the Products table.
• Three types of relationships can exist between tables. The most common type is a
one-to-many relationship as illustrated above. However, two tables can also have a
one-to-one relationship or a many-to-many relationship.
Description
• A database management system requires a name and data type for each column in a
table. Depending on the data type, the column definition can include other proper
ties such as the column’s size.
• Each column definition also indicates whether or not the column can contain null
values. A null value indicates that the value of the column is not known.
• A column can be defined with a default value. Then, that value is used for the
column if another value isn’t provided when a row is added to the table.
Description
• The SELECT statement is used to perform a query that retrieves rows and columns
from a database.
• The result set (or result table) is the set of rows that are retrieved by a query.
• The current row pointer, or cursor, identifies the current row in a result set. You can
use this pointer to identify the row you want to update or delete from a result set.
Any change to the result set is reflected in the table that the result set is based on.
• To select all of the columns in a table, you can code an asterisk (*) instead of
coding column names.
• For efficiency, you should code your queries so the result set has as few rows and
columns as possible.
Description
• A join lets you combine data from two or more tables into a single result set.
• An inner join, or equi-join, returns rows from both tables only if their related
columns match. An outer join returns rows from one table in the join (the LEFT or
RIGHT table) even if the rows aren’t matched by rows in the other table.
identifies the join by using the AND keyword to connect all of the selection
criteria that must be satisfied. This is an older syntax for joins that is still used
by some database management systems.
H o w to update rows
UPDATE syntax
UPDATE table-name
SET expression-1 [, expression-2] ...
[WHERE selection-criteria]
H o w to delete rows
D E LE TE syntax
DELETE FROM table-name
[WHERE selection-criteria]
An introduction to Derby
Apache Derby is an open-source, Java-based relational database manage
ment system (RDBMS) that can be embedded in Java applications that run on a
client machine or run as the database server for a networked client/server
system. Oracle has distributed this database as part of the JDK ever since Java
SE 6. This distribution of Derby is marketed as Java DB. Although the Java DB
distribution is used throughout this chapter, the Derby name is still used by the
JAR files and classes. As a result, I’ll use the Derby name to refer to this
database throughout this chapter.
An overview of Derby
Figure 20-7 lists some of the advantages and disadvantages of using Derby.
To start, since Derby is open-source, it’s free. Since Derby is written in Java, it
runs on all modem operating systems. Since Derby is based on established
JDBC (Java Database Connectivity) and SQL standards, it works well with any
other applications that rely on these standards. Since Derby only requires about
2.8 MB of memory, it can easily be run on most computers, including client
machines. And finally, since Derby can be embedded within a client application
or run on a server in a client/server system, it can be used for a wide range of
applications.
When Derby is embedded in a client application, it’s known as an embedded
database, and it runs in the same process as the client application. On the other
hand, when Derby is run in a separate process on a server and accessed by
multiple client applications, it’s known as a networked database. Other popular
databases that are typically run as networked databases include Oracle, MySQL,
DB2, and SQL Server. Although versions of these databases can also run on the
client, the database runs in a process separate from the applications that use it. If
you want the database to run in the same process as the client application, you
have to use an embedded database like Derby.
So, what’s the downside of working with Derby? To start, unlike the other
database systems mentioned previously in this chapter, Derby doesn’t provide a
GUI tool for viewing and working with the database. Instead, you must use a
command-line tool that you’ll leam about in this chapter. In addition, Derby
isn’t designed to work with large, enterprise databases. Nevertheless, Derby can
be a good choice if you’re working with a small- to medium-sized database,
especially if you want to use an embedded database.
Chapter 20 How to work with a Derby database 659
Pros
• Is inexpensive (free).
• Is platform-independent.
• Is based on the Java, JDBC, and SQL standards.
• Is included as part of the JDK.
• Doesn’t use much memory (about 2.6 MB).
• Can be run on the client and embedded in a Java application.
• Can be run on a server and accessed by multiple clients.
Cons
• Doesn’t provide easy-to-use GUI tools.
• Not designed for large, enterprise databases.
Description
• Apache Derby is an open-source, Java-based relational database management
system (RDBMS) that can be embedded in Java applications or run in a networked
client/server system.
• Starting with JDK 6, Java includes Oracle’s distribution of the Derby database. This
distribution of Derby is known as Java DB.
• When a database runs in the same process as the application, it’s known as an
embedded database. When a database runs on a server and is accessed by clients,
it’s known as a networked database.
• A Derby database that’s embedded in a client application can be completely
transparent to the user of the application.
• JDBC (Java Database Connectivity) is a Java API that provides for querying and
updating the data in a database. See chapter 21 for details on using JDBC.
Mac OS X note
• Derby isn’t included as part of the JDK for Mac OS X, so you have to install it
separately. For more information, see appendix B.
A class path that contains the current directory and four Derby JAR files
•/
C:\Program Files\Java\jdkl.7.0\db\lib\derby.jar;
C:\Program Files\Java\jdkl.7.0\db\lib\derbytools.jar;
C:\Program Files\Java\jdkl.7.0\db\lib\derbynet.jar;
C:\Program Files\Java\jdkl.7.0\db\lib\derbyclient.jar;
Description
• The class path tells the JRE where to find the .class files needed to run a program.
To allow your application to work with Derby, you must include the necessary JAR
files in the class path.
• To include the current directory in the class path, just code a period for the direc
tory followed by a semicolon at the start of the list of paths as shown above.
• After you change the class path, you may need to close and reopen the command
prompt before the new class path takes effect. Or, in some cases, you may need to
reboot your computer.
Figure 20-8 How to configure your system to work with a Derby database
662 Section 5 Data access programming with Java
^ C:\murach\java\db>
------- J)
C :\murach\java\db>java org.apache.derby.tools.ij
ij version 1 0 . 8
ij> connect 'jdbc:derby:MurachDB;create=true';
ij> disconnect;
ij> exit;
C :\murach\java\db>
Description
• You can use the ij (interactive JDBC) tool to interactively work with a Derby
database.
• By default, the ij tool looks for the Derby database within the current directory. As
a result, it usually makes sense to use the cd command to change the current
directory to the directory that contains the database.
• To start the ij tool, use the java command to run the ij class that’s stored in the
derbytools.jar file.
• To stop the ij tool, enter the exit command.
• To connect to a database, enter the connect command followed by the connection
string enclosed in single quotes. The connection string should specify the protocol
(jdbc), the subprotocol (derby), and a URL that specifies the name and location of
the database.
• To disconnect from a database, enter the disconnect command.
• To create a database, append “;create=true” to the end of theconnection string.
• You must enter a semicolon at the end of each command.
Figure 20-9 How to use the ij tool to create and connect to a database
664 Section 5 Data access programming with Java
database. In figure 20-9, for instance, the first example uses the jdbc:derby
protocol to connect to the database named MurachDB that’s stored in the
current directory.
If you try to connect to a database and the database isn’t found, Derby will
display an error message like the one shown in the second example in figure
20-9. In this case, you may need to exit the ij tool, use the cd command to
change the current directory, and start the ij tool again. Or, you may need to
create the database as described in the next topic. When you’re done working
with a database, you can use the disconnect command to free any resources that
are used by the connection to the database.
ProductCode VARCHAR(IO),
Description VARCHAR(40),
Price DOUBLE
);
0 rows inserted/updated/deleted
ij>
1 row selected
ij> exit;
C :\murach\java\db>
Description
• To run a SQL statement, enter the statement at the ij prompt followed by a semi
colon. When you do, the ij tool will display a message that shows the result of the
SQL statement.
• To quickly reenter a previous statement, you can use the up and down arrows to
scroll through previously entered statements. Then, you can edit the statement and
run it again.
• You can use capitalization, line breaks, and spacing to make the SQL statement
easy to read.
• When you use the ij tool to run a SELECT statement, the data in the returned rows
and columns are displayed in a table that uses the column names as the column
headers. If a column name has more characters than the column has, the column
header is truncated and ends with the & character.
• If the table you’re working with is stored in a schema, you have to identify that
schema to access the table using the ij tool. To do that, you can use this command:
ij> set schema AppUser;
Or, you can qualify the name of the table with the schema like this:
ij> SELECT * FROM AppUser.Products;
When you use the ij tool, you should realize that a table can be stored in a
schema, which is a container that stores tables and other database objects. If a
table is stored in a schema, you have to identify that schema to work with the
table using the ij tool. You can do that using one of the two techniques shown in
figure 20-10. First, you can use the set schema command to identify the schema.
In this figure, this command is used to set the schema to AppUser. Then, the ij
tool will assume that any tables you refer to in any SQL statements you enter
are stored in that schema. Second, you can qualify the name of a table in a SQL
statement with the schema. Then, the ij tool only uses the schema for that
statement.
ProductCode VARCHAR(IO),
Description VARCHAR(40),
Price DOUBLE
);
0 rows inserted/updated/deleted
ij> run 'ProductsTablelnsert.sql';
ij> INSERT INTO Products
VALUES ('java', 'Murach,,s Beginning Java', 49.50);
1 row inserted/updated/deleted
ij> INSERT INTO Products
VALUES ('jsps', 'Murach,,s Java Servlets and JSP', 49.50);
1 row inserted/updated/deleted
ij> disconnect;
ij> exit;
Description
• To run a SQL script from the ij prompt, you can start the ij tool, connect to the
database, and use the run command to run the script. Here, you must enclose the
name of the script in single quotes.
• If the script is in the root directory for the database, you don’t need to enter a path
for the script. Otherwise, you need to enter the full path for the script.
Description
• To run a SQL script from the command prompt, you can enter the name of the
script after you use the java command to run the ij class that’s stored in the
derbytools.jar file. For this to work, the script must begin with a connect command
that connects to the database.
• If the script is in the root directory for the database, you don’t need to enter a path
for the script. Otherwise, you need to enter the full path for the script.
• To run a DOS batch file that executes a SQL script, you can use Windows Explorer
to locate the batch file and double-click on it. Or, you can enter the name of the
batch file at the command prompt.
Figure 20-12 How to run SQL scripts from the command prompt
670 Section 5 Data access programming with Java
:\UsersNJoe1>
Description
• To start the Derby network server, use the java command to pass the start argument
to the NetworkServerControl class that’s stored in the derbynet.jar file. For this to
work, the derbynet.jar file must be included in the class path.
• Once you start the server, you can use the ij tool to connect to a database and run
SQL statements and scripts. For this to work, the derbyclient.jar file must be
included in the class path.
• To stop the Derby network server, use the java command to pass the shutdown
argument to the NetworkServerControl class that’s stored in the derbynet.jar file.
Figure 20-13 How to start and stop the Derby server
672 Section 5 Data access programming with Java
\ r e f d e r b y .p d f (application/pdf Object]
□ Comment S h are
0 □ Statements
T his se ctio n pro v id es m an ua l p a ge s fo r Doth liigh-lewel l a n gu ag e co n stru cts a n d part3
th e re o f. F o r exa m p le , th e C R E A T E IN D E X s ta te m e n t is a hig h-leve l s ta te m e n t th a t y o u
corr e x e cu te d ire c tly v ia th e JD B C interface- T his se ctio n a ls o in c lu d e s clauses., w tiic h
a re n o t hig h-leve l sta te m e n ts a n d w h ich y o u ca n n o t e xe cu te d ire ctly tun. o n ly as part
L? table-Name o f a hig h -le ve l sta te m e n t. T h e O R D E R B Y an d W H E R E cla u s e s are exa m p le s o f th is
# 0s view-Name
kind o f cla u se . F inally, th is se ctio n a ls o inclu de s s o m e syn ta c tic a lly co m p le x po rtio n s o f
sta tem e nts calle d exp ression s, fo r e xa m ple SelectExpressbn a n d T&MeSubquery/. T he se
cla u se s a n d exp re s s io n s re ce ive th e ir ow n m a n u a l p a g e s fo r e a se o f reference.
CP index-Name U nle ss it is exp licitfy s ta le d othenM se, y o u can e x e c u te o r p re p a re 3 n d th e n e xe cute
all W e hig h -le ve l s ta te m e n ts, w h ich a re ail m arked w ith th e w o rd srafe nie nf, via th e
CP constraint-Name in te rla c e s pro vid ed B y J D B C . T h is m a n u a l in d ica te s w h e th e r an exp re ssio n can be
exe cuted a s a hig h -le ve l sta tem e nt.
L? cursor-Name
T h e se c tio n s prw i-S e g e ne ral in fo rm a tio n a b o u t s ta te m e n t use. a n d de scrip tio n s o f the
CP TriggerName sp e cific sta tem e nts.
Description
• To view the Derby documentation, go to the Derby website and use your web
browser to navigate to the PDF file for the documentation. If you want to, you can
save the PDF file to your computer so you can view it without connecting to the
Internet.
• To navigate through the documentation, you can expand, collapse, or select the
topics in the table of contents in the left panel of the window. Or, you can use the
search feature to search the documentation for a word or phrase.
Perspective
Now that you’ve finished this chapter, you have some basic skills for
working with a Derby database. Please note, however, that this chapter is only
an introduction to the use of Derby databases. To leam more, you can refer to
the extensive documentation that’s available from the Derby web site.
If you want to create an application that allows multiple clients to access a
database that’s running on a server, you might consider using a database such
as MySQL that’s specifically designed to work in a client-server environment.
Like Derby, MySQL is open-source and available for free. However, MySQL
provides more features than Derby, including GUI tools that make it easier to
work with your databases.
Summary
• A relational database uses tables to store and manipulate data. Each table contains
one or more rows, or records, while each row contains one or more columns, or
fields.
• A primary key is used to identify each row in a table. A foreign key is a key in one
table that is used to relate rows to another table.
• Each database is managed by a database management system (DBMS) that sup
ports the use of the Structured Query Language (SQL). To manipulate the data in a
database, you use the SQL SELECT, INSERT, UPDATE, and DELETE statements.
• The SELECT statement is used to return data from one or more tables in a result
set. To return data from two or more tables, you join the data based on the data in
related fields. An inner join returns a result set that includes data only if the related
fields match.
• Apache Derby is an open-source, Java-based relational database management
system (RDBMS) that can be embedded in Java applications or run in a networked
client/server environment.
• An embedded Derby database runs in the same process in which the application
that uses the database runs.
• A networked Derby database runs on a network server so the database can be
accessed by two or more clients.
• The JDK includes a distribution of Derby known as Java DB. This is the version of
Derby that’s included in the db directory of Java SE.
• To work with a Derby database, you can use the ij tool (interactive JDBC tool) to
connect to a database and execute SQL statements.
• SQL statements that have been saved in files are known as SQL scripts. You can
run these scripts from the ij prompt or the command prompt.
Chapter 20 How to work with a Derby database 675
Middleware
translates
net protocol
to native
DBMS protocol
,______ ’ F---------------- ^
Notes
• To get information about the drivers that are currently available, search the database
vendor’s web site or the Internet.
• Since type-1 and type-2 drivers require some client-side installation, they’re not a
good solution for most applications, especially Internet applications.
Fite Edit View Navigate Source Refactor Run Debug Profile Team Tools Window Help__________________________________________ K^JjearchJCW+!^
7 {
8 Connection connection = null;
9 try
10 ί
11 Π if necessary, set· t h e home directory for Derby
12 String dbDirectory = " c :/ m u r a c h / ; : a v a / d b " ;
13 S y s t e m . s e t P r o p e r t y (" d e r t v .s y s t e m .h o m e " ,dbDirectory);
i-T
1 4-
1d e rby .jar - N avigator <0 S3 15 // set the db url string
s r
'!/UBUILD SUCCESSFUL ( t o t a l t im e : 5 sara=nds>
i
@ ! I ll INS
Description
• A database driver is a class that’s typically stored in a JAR file.
• To add a database driver to a NetBeans project, right-click on the Libraries folder
for the project, select the Add JAR/Folder command, and use the resulting dialog
box to select the JAR file that contains the driver.
• After you add the JAR file that contains a database driver to a project, the JRE can
find and run the class for the driver.
• To remove a database driver from a project, right-click on the JAR file that contains
the driver and select the Remove command.
Description
• Prior to JDBC 4.0 (JDK 1.6), you needed to use the forName method of the Class
class to load the driver.
• With JDBC 4.0 (JDK 1.6) and later, the database driver is loaded automatically.
This feature is known as automatic driver loading.
Description
• All of the interfaces, classes, and exceptions for using JDBC that are presented in
this chapter are stored in the java.sql package.
• By default, Derby looks for the specified database in the directory where the Java class
is stored. If the database is stored in another directory, you can use the setProperty
method of the System class to set the derby.system.home property to that directory.
• To connect to an embedded Derby database, you can call the getConnection
method of the DriverManager class to pass a database URL that indicates the
protocol to be used and the name of the database. You can also pass the username
and password that are used to connect to the database.
• The getConnection method uses automatic driver loading to load the right driver
for the database. In this example, that driver is the embedded Derby JDBC driver.
• The getConnection method throws a SQLException if the connection fails. With
JDBC 4.0 (JDK 1.6) and later, the SQLException class implements the Iterable
interface. As a result, you can use an enhanced for statement to loop through any
chained exceptions.
• If necessary, you can use the getProperty method of the System class to get the
default directory for the database or to get the username for the current user.
Figure 21 -4 How to connect to an embedded database
686 Section 5 Data access programming with Java
How to disconnect from all databases and shut down the database engine
public boolean disconnect()
{
try
{
// On a successful shutdown, this throws an exception
String shutdownURL = 11jdbc:derbyshutdown=true";
DriverManager.getConnection(shutdownURL);
}
catch (SQLException e)
{
if (e.getMessage().equals("Derby system shutdown."))
return true;
}
return false;
}
Description
• To disconnect from all databases and shut down the Derby database engine, you
can call the getConnection method of the DriverManager class with a parameter
that indicates the protocol to be used and that the database engine should be shut
down.
• To disconnect from a specific database, you can call the getConnection method of
the DriverManager class with a parameter that indicates the protocol to be used, the
name of the database, and that one database should be shut down.
• When you disconnect from a specific database, the Derby database engine isn’t
shut down since other databases could be connected to it. If an application works
with a single database, you should use the technique for disconnecting from all
databases so the database engine is shut down.
• Since a successful shutdown throws a SQLException, you need to handle this
exception.
URL syntax
jdbc:subprotocolName:databasePath
Description
• By default, the Derby client attempts to connect to the database that’s in the
directory where the NetworkServerControl class is stored. To connect to a database
in a different directory, include that directory in the database path.
• To connect to a database server that’s running on the client, use the localhost
keyword followed by the port number.
• To connect to a database server that’s running on a network server, specify the
server name followed by the port number.
• By default, the Derby database uses port number 1527. In contrast, MySQL uses
port number 3306, and Oracle uses port number 1521.
• The database server for a networked database is always running. As a result, there’s
no need to shut down the server when you disconnect from the database.
ResultSet rs = statement.executeQuery(query);
Description
• The createStatement method of a Connection object creates a Statement object.
Then, the executeQuery method of the Statement object executes a SELECT
statement that returns a ResultSet object.
• By default, the createStatement method creates a forward-only, read-only result set.
However, you can set the type and concurrency of a Statement object by coding the
fields above for the two arguments of the createStatement method.
• Both the createStatement and executeQuery methods throw an exception of the
SQLException type. As a result, any code that returns a result set needs to catch or
throw this exception.
if (rs.isFirst() == false)
rs.previous();
if (rs.isLast() == false)
rs.next();
rs.absolute(4);
rs.relative(-2 );
rs.relative(3);
Description
• When you create a result set, the cursor is positioned before the first row. As a result,
the first time you call the next method, it moves to the first row in the result set.
• The first, previous, next, last, absolute, and relative methods all return a true value
if the new row exists and a false value if the new row doesn’t exist or the result set
is empty.
• All of the methods in this figure throw an exception of the SQLException type.
Code that uses column indexes to return fields from the Products result set
String code = rs.getString(1);
String description = rs.getString(2);
double price = rs.getDouble(3);
Description
• The get methods of a ResultSet object can be used to return all eight primitive
types. For example, the getlnt method returns the int type and the getLong method
returns the long type.
• The get methods of a ResultSet object can also be used to return some objects such
as dates and times. For example, the getDate, getTime, and getTimestamp methods
return objects of the Date, Time, and Timestamp classes of the java.sql package.
• The getBlob and getClob methods can be used to return BLOB objects (Binary
Large Objects) and CLOB objects (Character Large Objects).
• The get methods accept an argument that specifies the number or name of the
column in the result set. The column numbers begin with 1.
How to use methods from JDBC 2.0 (JDK 1.4) and later to modify data
How to add a record
rs.moveToInsertRowO ;
rs.updatestring("ProductCode", p.getCode());
rs.updateString("Description", p.getDescription());
rs.updateDouble("Price", p.getPrice());
r s .insertRow();
rs.moveToCurrentRowO ;
Description
• The executeUpdate method returns an int value that identifies the number of
records that were affected by the update.
• The executeUpdate method works with most JDBC drivers. The other methods
shown in this figure may not work properly with all JDBC drivers.
• In some cases, you may need to refresh the result set after a modification by
closing it and reopening it.
To update a record
String updateProduct =
"UPDATE Products " +
"SET Description = ?, Price = ? " +
"WHERE ProductCode = ?";
PreparedStatement ps = connection.preparestatement(updateProduct);
p s .setString(1, p .getDescription());
p s .setDouble(2, p.getPrice());
ps.setString(3, p .getCode());
int count = p s .executeUpdate();
To insert a record
String insertProduct =
"INSERT INTO Products (ProductCode, Description, Price) " +
"VALUES (?, ?, ?)";
PreparedStatement ps = connection.preparestatement(insertProduct);
p s .setString(1, p .getCode());
ps.setString(2, p.getDescription());
ps.setDouble(3, p.getPrice());
int count = p s .executeUpdate();
To delete a record
String deleteProduct =
"DELETE FROM Products " +
"WHERE ProductCode = ?";
PreparedStatement ps = connection.preparestatement(deleteProduct);
ps.setString(1, p .getCode());
int count = p s .executeUpdate();
Description
• To specify a placeholder for a parameter in the SQL statement, type a question
mark (?).
• To supply values for the parameters in a prepared statement, use the set methods of
the PreparedStatement interface. For a complete list of set methods, look up the
PreparedStatement interface of the java. sql package in the documentation for the
Java API.
• To execute a SELECT statement, use the executeQuery method. To execute an
INSERT, UPDATE, or DELETE statement, use the executeUpdate method.
Description
• SQL uses single quotes to indicate the beginning and end of the value of a column.
If you need to store a single quote in a column value, you have to code two con
secutive single quotes if you’re using a Statement object. Alternately, you can use a
prepared statement to store a single quote in a column value.
The getProduct method returns a Product object for a product that matches
the specified product code. To do that, it uses a prepared SQL statement to
return a result set. Then, it calls the next method of the result set to attempt to
move the cursor to the first row in the result set. If successful, this method
continues by reading the description and price fields from the row and creating
a Product object from these fields. Then, it closes the result set and returns the
Product object.
Note that, unlike the getProducts method, the result set used by the
getProduct method can’t be created in the try-with-resources statement. That’s
because before the result set can be opened, the value of the parameter in the
prepared statement must be set. However, the connection and prepared state
ment can still be created in the try-with-resources statement, which means that
they don’t have to be closed explicitly.
If no product record contains a product code that matches the specified
code, this method returns a null to indicate that the product couldn’t be found.
In addition, if a SQLException is thrown anywhere in this method, this method
returns a null to indicate that it was not successful.
As you review the getProduct method, note that if the try block throws a
SQLException, the result set isn’t explicitly closed. In most cases, that’s not a
problem because the result set will be automatically closed when the prepared
statement that was used to create the result set is closed. If you wanted to close
the result set explicitly, though, you could do that by adding a finally clause to
the try statement.
The addProduct method begins by creating a prepared statement that can be
used to insert values into the three columns of the Products table. Then, it sets
the values of the three parameters in the prepared statement to the values stored
in the Product object that’s passed to it. Finally, it executes the executeUpdate
method of the prepared statement. If this update is successful, the addProduct
method returns a true value. However, if a SQLException is thrown anywhere in
this method, it returns a false value to indicate that it was not successful.
Chapter 21 How to use JDBC to work with databases 705
An introduction to working
with metadata
When you work with a result set, you can get data about the definition of
the result set. This type of information is known as metadata. For example, the
metadata of a result set includes the number of columns, names of the columns,
and the data type that’s stored in each column. Although working with metadata
is an advanced skill that you don’t need for normal business applications, this
topic gives you a taste of what you can do with it.
Description
• You can use the fields of the Types class of the java.sql package to specify an int
value for a SQL data type.
Figure 21-14 How to work with metadata
710 Section 5 Data access programming with Java
Description
• To get the SQL data type that’s used in the column of a result set, you can use the
getColumnType and getColumnTypeName methods of the ResultSetMetaData
class.
Figure 21-15 How SQL data types map to Java data types
712 Section 5 Data access programming with Java
Perspective
Now that you’ve finished this chapter, you should understand how to use
JDBC to store data in a database and to retrieve data from a database. Al
though there’s much more to leam about working with databases, those are the
essential skills. To enhance your database skills, you can leam more about
SQL, database management systems like MySQL or Oracle, and other JDBC
features.
Summary
• With JDBC 4.0 (JDK 1.6) and later, the database driver that’s used to connect the
application to a database is loaded automatically. This is known as automatic
driver loading. With JDBC 4.0 and later, you can also loop through any exceptions
that are nested within the SQLException object.
• A Java program can use one of four driver types to access a database. Type-1 and
type-2 drivers run on the client’s machine, while type-3 and type-4 drivers can run
on a server machine.
• If you connect to a Derby database with a username and create a table in a data
base, that table is stored in a schema that corresponds to the username. Then, to
access that table, you need to connect to the database with the same username or
qualify any reference to that table with the username.
• You can use JDBC to execute SQL statements that select, add, update, or delete
one or more records in a database. You can also control the location of the cursor
in the result set.
• You can use prepared statements to supply parameters to SQL statements. Since
prepared statements provide better performance and security than regular state
ments, you should use them whenever possible.
• You can return a list of the column names and types in a result set by using
metadata. To do this, you may need to convert SQL data types to Java data types.
3. Write the code for the printFirstProduct method. Use column names to
retrieve the column values. Then, test the project. You can tell if this method
is working correctly if it prints the first product in the list of products that’s
printed by the printProducts method.
4. Write the code for the printLastProduct method. To move to the last product
in the result set, you can use a scrollable result set. Then, test the project.
5. Write the code for the printProductByCode method. Use a prepared statement
to create the result set, and use indexes to retrieve the column values. Then,
test the project.
6. Write the code for the insertProduct method. This method should begin by
checking if a product with the specified product code exists in the database. If
so, this method should display an error message. Otherwise, it should add the
product to the database and print the product that was added to the console.
7. Test the insertProduct method. To do that, you need to run the project twice.
The first time, the product should be added to the database. The second time,
the product should appear in the list of products, but then an error message
should be displayed indicating that the product already exists.
8. Write the code for the deleteProduct method. This method should delete the
product that was added by the insertProduct method. Then, test the project.
This exercise has you enhance a Product Maintenance application that uses the
Derby database described in chapter 20 to store the product data. To work with
that data, this application uses the ProductDB class that’s presented in this
chapter.
down the Derby database engine and returns a boolean value that indicates if
the shutdown was successful.
6. Switch to the ProductMaintApp class and try to add a statement that calls the
disconnect method from the ProductDB class when the application ends. Note
that you can’t access this method because it’s being called from a static
context.
7. Now, try to call the disconnect method from the ProductDAO object. This
time, you won’t be able to access this method because it isn’t available from
the ProductDAO interface.
8. Create an interface named EmbeddedDB and add a method named disconnect
to it.
9. Modify the ProductDAO interface so it inherits the EmbeddedDB interface.
10. Modify the ProductMaintApp class so it calls the disconnect method from the
ProductDAO object when the application ends. Then, test the application to
make sure it works correctly.
Section 6
An introduction to threads
Before you leam how to develop applications that use two or more threads,
you need to understand how threads work and when you would typically use
them. You also need to be familiar with the classes and interfaces you use when
you work with threads, and you need to understand the life cycle of a thread.
That’s what you’ll leam in the topics that follow
One thread
thread 1 task 1 (wail for I/O) task 1 (wait for I/O) task 2
Two threads
Description
• A thread is a single sequential flow of control within a program. A thread often
completes a specific task.
• By default, a Java application uses a single thread, called the main thread. How
ever, some programs can benefit by using two or more threads to allow different
parts of the program to execute simultaneously.
• On a computer that has just one central processing unit, or CPU, the threads don’t
actually execute simultaneously. Instead, a part of the Java virtual machine called
the thread scheduler alternately lets portions of each thread execute. This gives the
appearance that all of the tasks are running at the same time, and this can make an
application work more efficiently.
To give you some perspective on this, you should realize that the actual
amount of time that the CPU spends waiting for I/O to complete is much greater
than what’s indicated in figure 22-1. In fact, since each of the blocks that show
task 1 executing are about one half of an inch long, the blocks that show the
CPU waiting for I/O would probably need to be about the length of a football
field to show the wait time accurately. That’s about how much slower disk
operations are than CPU operations.
The second reason for using threads is to improve the responsiveness of
programs that use graphical user interfaces. For example, when a user clicks a
toolbar button, he or she expects the program to respond immediately, even if
the program is busy doing something else. A GUI application that uses Swing as
described in section 4 automatically runs in a thread that handles the events that
are fired by the user and updates the GUI accordingly. However, if the applica
tion needs to perform a task that may take a long time, this task should be
performed in a second thread.
The final reason for using multithreading is to allow two or more users to
run server-based applications simultaneously. For example, Java servlets
automatically create one thread for each user. You learned a little bit about
servlets in chapter 1, and you can leam more about them in our book, Murach’s
Java Servlets and JSP. For now, you should just realize that each person who
uses a servlet runs it in a separate thread. As a result, when you write servlet
code, you must make sure that the code is thread-safe.
Key methods of the Thread class, Runnable interface, and Object class
Method Class/Interface Description
start Thread Registers this thread with the thread scheduler so it’s
available for execution.
run Runnable, Thread An abstract method that’s declared by the Runnable interface
and implemented by the Thread class. The thread scheduler
calls this method to run the thread.
sleep Thread Causes the current thread to wait (sleep) for a specified
period of time so the CPU can run other threads.
wait Object Causes the current thread to wait until another thread calls
the notify or notifyAll method for the current object.
notify Object Notifies one arbitrary thread that’s waiting on this object that
it can resume execution.
notifyAll Object Notifies all the threads that are waiting on this object that
they can resume execution.
Description
• After you create a Thread object, you can call its start method so the thread scheduler can
run the thread. Then, you can use the other methods shown above to manage the thread.
Blocked
Thread states
State Description
New The thread has been created (its constructor has been called), but not yet started.
Runnable The thread’s start method has been called and the thread is available to be run by the
thread scheduler. A thread in Runnable state may actually be running, or it may be
waiting in the thread queue for an opportunity to run.
Blocked The thread has been temporarily removed from the Runnable state so it can’t be
executed. This can happen if the thread’s sleep method is called, if the thread is waiting
on I/O, or if the thread requests a lock on an object that’s already locked. When the
condition changes (for example, the I/O operation completes), the thread is returned to
the Runnable state.
Waiting The thread has called its wait method so that other threads can access an object. The
thread remains in the Waiting state until another thread calls the notify or notifyAli
method.
Terminated The thread’s run method has ended.
Description
• All threads have a life cycle that can include five states: New, Runnable, Blocked,
Waiting, and Terminated.
Description
• By default, the threads that you create explicitly are named numerically. If that’s
not what you want, you can specify the name on the constructor of the thread.
• By default, a thread is independent of the thread that created it. This is called a user
thread. Or, you can use the setDaemon method to create a daemon thread.
• The sleep method throws InterruptedException. Because this is a checked excep
tion, you must throw or catch this exception when you use the sleep method.
try
{
Thread.sleep(2000); // Sleep for 2 seconds to simulate
// an IO task that takes a long time
}
catch(InterruptedException e) {}
Sample output
(? - -------------------
main started.
main starts Thread-0.
main finished.
Thread-0 started.
Thread-0 finished.
V ------------------ J'
try
{
Thread.sleep(2000); // Sleep for 2 seconds to simulate
// an IO task that takes a long time
}
catch(InterruptedException e) {}
}
}
Description
• By default, every thread is given the priority of the thread that created it. If a thread
is created from the main thread, it’s given a priority of 5 by default.
• Since thread scheduling relies on the underlying system, the result of setting a
thread’s priority may vary depending on the platform.
Sample output
---------- Λ
Press the Enter key to stop counting.
Thread-0 count 1
Thread-0 count 2
Thread-0 count 3
Thread-0 interrupted.
W- --------- i
Description
• If a thread is interrupted while it is sleeping, InterruptedException is thrown. In this
case, the islnterrupted method won’t indicate that the thread has been interrupted.
Description
• Whenever two or more threads can access an object, concurrency is an important
issue. Concurrency problems can result because a thread running a method may be
interrupted in the middle of the method so control can be given to another thread
that runs the same method. When that happens, the intermediate results from the
first thread can affect the accuracy of the second thread.
• The synchronized keyword assures that only one thread at a time is allowed to
execute any synchronized method of an object by locking the object. Any other
thread that attempts to run any synchronized method for the object is blocked until
the first thread releases the lock by exiting the synchronized method.
• A thread can run an unsynchronized method of an object even if the object is
locked. That’s because the object isn’t checked for a lock unless a synchronized
method is executed.
• You should use synchronized methods whenever two or more threads might
execute the same method. Even methods with just one line of code typically need
to be synchronized.
Example 2: Code that satisfies the condition and notifies other threads
orderQueue.add(order); // add an order to the queue
notifyAli(); // notify other threads
Description
• In some multithreaded applications, it’s important for threads to inform one another
when certain events have occurred or conditions have been met. The wait, notify,
and notifyAli methods provide for this type of communication.
• The wait method releases the lock on the current object so other threads can
execute synchronized methods. The effect of the wait method is to interrupt the
current thread until another thread calls the notify or notifyAli method.
• The notifyAli method restores all the threads that are waiting for the current
object’s lock to the Runnable state. The Java thread scheduler then selects one of
the threads for execution.
• The notify method is similar to the notifyAli method, but it restores only one
arbitrarily selected thread to the Runnable state. Since this thread may not be able
to perform its function, the notifyAli method is typically used instead.
• The wait, notify, and notifyAli methods can only be used in synchronized methods.
If you call one of these methods from an unsynchronized method,
DlegalMonitorStateException is thrown.
The operation
Figure 22-11 presents the operation of the Order Queue application. The
diagram at the top of this figure shows how the application uses multiple
OrderTaker threads to create orders and add them to the queue and multiple
OrderHandler threads to remove orders from the queue and process them. The
queue itself is managed by a class named OrderQueue that runs in its own
thread (the main thread).
So you can focus on the threading aspects of this application, each order is
represented by an Order object that consists of just an order number. Obviously,
a more realistic Order object would include additional details, such as customer,
product, and payment information.
The OrderTaker and OrderHandler classes are also simplified. In this
application, the OrderTaker class simply creates a specified number of orders at
one-second intervals, displaying a message on the console as each order is
created. Similarly, the OrderHandler class retrieves an order from the queue,
displays it on the console, and then waits two seconds before retrieving another
order. In a more realistic application, the OrderTaker class would get input from
a user about each order, and the OrderHandler class would print invoices,
update customer information, and so on.
If you study the console output shown in this figure, you’ll see that the
Order Queue application begins by displaying information about the OrderTaker
and OrderHandler threads. The number of OrderTaker and OrderHandler
threads can easily be changed, as can the number of orders to be created by each
OrderTaker thread. For this example, the application creates three OrderTaker
threads, each of which creates three orders. As a result, a total of nine orders are
created. In addition, the application creates two OrderHandler threads.
After displaying this initial information, the application starts the
OrderTaker and OrderHandler threads. Each OrderTaker thread displays a
message when it creates an order, and each OrderHandler thread displays a
message when it processes an order. As you can see, nine orders are created by
the three OrderTaker threads, and nine orders are eventually processed by the
two OrderHandler threads.
Incidentally, the design of the Order Queue application is based on a
commonly-used design pattern called the producer/consumer pattern. This
design pattern uses a queue to coordinate producers—objects that create items
that need to be processed—with consumers—objects that process the items
created by the producers.
Chapter 22 How to work with threads 739
Description
• This application simulates a multithreaded ordering application in which multiple
order takers, each running the application in a separate thread, generate orders that
are added to a queue that runs in the application’s main thread. The orders are then
handled by multiple order-handling threads, which remove orders from the queue
and display them on the console.
• This application is an example of a common design pattern called producer/
consumer. With this pattern, threads that produce objects place them in a queue so
the objects can later be retrieved by threads that consume them.
The classes
Figure 22-12 describes the four classes used by the Order Queue applica
tion. The first class is the Order class, which represents an individual order. To
keep this application simple, the only information about an order that an Order
object stores is the order number. The order number is passed to an order via its
constructor. Then, this number can be retrieved by calling the toString method,
which returns the order number in a formatted string (for example, “Order #1”).
The OrderQueue class represents the queue used to store orders. This class
uses a linked list internally to store the Order objects. It has two methods, both
of which are synchronized. The pushOrder method adds an order to the queue,
and the pullOrder method retrieves an order from the queue.
The OrderTaker class creates orders by adding them to the queue. It sleeps
for one second between each order it creates. This class is designed to be run as
a thread, so it extends the Thread class and implements the run method. Unlike
the other thread classes you’ve seen, the OrderTaker class includes a constructor
that accepts two parameters. The first parameter indicates how many orders the
thread should create before ending. The second parameter holds a reference to
the OrderQueue object that the orders should be added to.
The OrderHandler class retrieves orders from the order queue. It too is
designed to run as a thread, so it extends the Thread class and defines its opera
tions in the run method. It also includes a constructor that accepts a parameter
that refers to the OrderQueue object that the orders should be retrieved from.
Chapter 22 How to work with threads
Method Description
toString() Returns a string in the form “Order #n,” where n is the order number.
Method Description
run () Retrieves orders from the queue specified by the
constructor. A message is displayed on the console
for each order retrieved, and the thread sleeps for
two seconds between orders.
Description
• An Order object represents an order.
• An OrderQueue object uses a linked list to store orders created by the OrderTaker
threads so they can be retrieved by the OrderHandler threads.
• An OrderTaker object runs in a separate thread, creates orders at one-second
intervals, and adds them to a queue. The constructor lets you specify how many
orders to create before the thread terminates.
• An OrderHandler object runs in a separate thread and removes orders from the
queue at two-second intervals.
Figure 22-12 The classes used by the Order Queue application
742 Section 6 Advanced Java skills
String s
= " OrderTaker threads OrderHandler threads \n"
+ " = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = " ;
System.out.println(s);
Figure 22-13 The code for the Order Queue application (part 1 of 3)
744 Section 6 Advanced Java skills
Order order;
while (count < maxOrders)
// ignore interruptions
}
}
return orderNumber++;
}
}
Figure 22-13 The code for the Order Queue application (part 2 of 3)
746 Section 6 Advanced Java skills
Figure 22-13 The code for the Order Queue application (part 3 of 3)
748 Section 6 Advanced Java skills
Perspective
In this chapter, you learned the essential skills for working with threads.
Frankly, threading is one of the most challenging topics in this book. So don’t
be too worried if you don’t understand every detail of how it works. The best
way to leam how to work with threads is to develop multithreaded applica
tions. You’ll get a chance to do that in the exercises that follow.
You should be aware that several threading features were introduced with
JDK 1.4 and 1.5. We didn’t cover those features in this chapter, though,
because they’re used for more advanced aspects of multithreaded program
ming. For example, JDK 1.4 introduced a new variable modifier called volatile
that lets you share access to variables in unsynchronized methods. And JDK
1.5 introduced a set of classes (java.util.concurrent,
java.util.concurrent.atomic, and java.util.concurrent.locks) that provide more
advanced threading features. You can refer to the Java documentation if you
want to find out more about these features.
Summary
• A thread is a single sequential flow of control within a program that often com
pletes a specific task.
• A multithreaded application consists of two or more threads whose execution can
overlap.
• Since a processor can only execute one thread at a time, the thread scheduler
determines which thread to execute.
• Multithreading is typically used to improve the performance of applications with
I/O operations, to improve the responsiveness of GUI operations, and to allow two
or more users to run server-based applications simultaneously.
• You can create a thread by extending the Thread class and then instantiating the
new class. Or, you can implement the Runnable interface and then pass a reference
to the Runnable object to the constructor of the Thread class.
• You can use the methods of the Thread class to start a thread, to control when a
thread runs, and to control when other threads are allowed to run.
• Asynchronous threads execute independently of each other.
• Synchronized methods can be used to ensure that two threads don’t run the same
method of an object simultaneously. When a thread calls a synchronized method,
the object that contains that method is locked so other threads can’t access it.
Chapter 22 How to work with threads 749
5. Modify the Finder class so its run method uses the sleep method to cause the
thread to sleep for 1 millisecond every ten times through the loop. If an
InterruptedException occurs, display the exception at the console.
6. Test the application to be sure it still works correctly.
An introduction to deployment..........................................752
How executable JAR files work................................................................... 752
How Java Web Start works...........................................................................752
How an installer program w orks................................................................. 752
How to use an executable JAR file ....................................754
How to create an executable JAR file.......................................................... 754
How to deploy a GUI application................................................................ 756
How to deploy a console application........................................................... 758
How to use Java Web Start.................................................760
A procedure for using Java Web S tart......................................................... 760
How to create a JNLP file.............................................................................762
How to create an HTML document that launches an application.............. 764
How to deploy an application to a remote web server................................766
How to launch an application...................................................................... 768
How to fix a common problem.................................................................... 768
Perspective........................................................................... 770
752 Section 6 Advanced Java skills
An introduction to deployment
Figure 23-1 lists three techniques you can use to deploy a Java application.
Each of these techniques has its advantages and disadvantages.
Web Start
Java Web Start (JWS) allows users to download an application from the web, cache
the application locally, and start it.
Pros
• The correct version of Java is automatically installed.
• The code is automatically updated.
Cons
• There are some significant security restrictions.
Installer program
An installer program allows you to create an install file for every operating system
that you want your application to run on. Then, users can use the install file for
their operating system to install the application just as they would install any other
application.
Pros
• The application installs and runs like a professional desktop application.
• The correct version of Java can be installed as part of the installation process.
• There are no significant security restrictions.
Cons
• The code is not automatically updated after the program is installed.
• Most installer programs are expensive commercial products.
• This approach requires more work to set up and configure.
Description
• When you build a project, NetBeans creates an executable JAR file and stores it in
the project’s dist directory by default.
• The executable JAR file contains all of the files necessary to run the application,
including any Java libraries that are needed by the application.
• The executable JAR file also contains a manifest file that stores information about
the files that the JAR file contains, including which .class file contains the main
method for the application.
• Because a JAR file uses a compressed format, it can dramatically improve the
download time for an application that’s deployed to the web.
Description
• Once you’ve created an executable JAR file for a GUI application, you can deploy
it by making the JAR file available to your users.
• To run an executable JAR file, the user can double-click on it.
• The JRE has to be installed on the user’s computer for the user to run an executable
JAR file.
• To install the JRE on a system other than one running Mac OS X, the user can go to
www.java.com.
• The JRE is installed on systems running Mac OS X by default. To install a newer
version, the user can use the Software Update feature that’s available from the
Apple menu.
• For an operating system to run an executable JAR file, it must associate the .jar
extension with the Java Platform SE binary program that’s included as part of the
JRE.
Figure 23-3 How to deploy an executable JAR file for a GUI application
758 Section 6 Advanced Java skills
2 : SU s e r s \ Jo e 1>c d \ m u r a c h \ j a u a S d ist
:\murach\javaSdist>jawa -jar ch23_FutureUalueConsole .jar
elcome to the Future Ualue Calculator
)ATA ENTRV
inter monthly investment: 100
nter yearly interest rate: 3
nter nunber of years : 3
ORMATTED RESULTS
onthly inuestnent: $100.00
early interest rate: 3.0κ
umber of years : 3
uture ualue: $3,771.46
Continue? (y/n):
Description
• Once you’ve created an executable JAR file for a console application, you can
deploy it by making the JAR file available to your users.
• To run an executable JAR file, the user starts a console and then uses the java
command. This command is case-sensitive.
• For Windows, you can create a batch (.bat) file to start the console and execute the
java command. For Mac OS X or Linux, you can create a bash (.sh) file.
• If a system can’t find the java command, you can specify an absolute path to the
command. For Windows, for example, the path will look like this:
11C:\Program Files\Java\jre7\bin\java"
Or, you can modify the system’s Path variable so it includes the bin directory for the JRE.
Figure 23-4 How to deploy an executable JAR file for a console application
760 Section 6 Advanced Java skills
Description
• The Java Network Launch Protocol (JNLP) can be used to launch Java applications
that have been deployed on a network such as an intranet or the Internet.
• Hypertext Markup Language (HTML) can be used to create a web page that in
cludes a link to a JNLP file.
• If you are deploying an application to an intranet, you can copy the JAR, JNLP, and
HTML files to the appropriate directory on the server.
• If you are deploying an application to the Internet, you can use an FTP program to
copy the files to the web server. See figure 23-8 for details.
Description
• A JNLP file is a type of XML file that specifies all the information that Web Start
needs to launch an application across a network such as the Internet.
• To create a JNLP file, copy an existing JNLP file and modify its elements and
attributes so they’re appropriate for your application.
• To test a JNLP file, double-click on the file. If your JNLP file is coded correctly,
this should launch your application.
to include it if the default settings aren’t working adequately. In that case, you
can experiment with the various options until you get the updating to work the
way you want it to work.
Once you finish coding your JNLP file, you can test it by double-clicking
on it. If your JNLP file is coded correctly and stored in the correct directory, this
should launch your application. Otherwise, you’ll get an error message that may
provide some details to help you troubleshoot the problem.
Keep in mind that this figure only covers a starting set of JNLP elements
and attributes. Other elements and attributes are available that let you provide an
icon for the application, control how shortcuts are created, remove security
restrictions, and so on. For more information about JNLP, you can search the
Internet for its documentation.
Description
• The Hypertext Markup Language (HTML) is the language that’s used to create web
pages.
• An HTML document contains HTML elements that define the content and structure
of the web page. This works similarly to an XML file, except that the names of the
HTML elements as well as any attributes they contain are predefined.
• The <head> element of a document provides information about the document, such
as the text that’s displayed in the browser’s title bar.
• The <body> element of a document defines the content of the web page. Within
this element, you can code an <a> element with an href attribute that defines a link
to the JNLP file for the application. The content of this element determines what’s
displayed for the link on the page. When the user clicks on this link, the application
is launched.
Description
• To deploy files to a remote web server, you can use an FTP program such as
FileZilla, which is free and open-source. After you start FileZilla, you can use it to
connect to your web server.
• The top left pane of the main FileZilla window shows the directory structure of the
local system, and the top right pane shows the directory structure of the remote system.
• If you select a directory in either directory tree, the subdirectories and files in that
directory are displayed in the lower pane of the main window. Then, you can use
that pane to navigate through the directories.
• The directory that’s identified by two dots at the top of each lower pane represents
the parent directory.
• To upload a file or directory to the remote site, right-click on the file or directory in
the local site and select the Upload command from the resulting menu.
• To download a file or directory from the remote site, right-click on the file or direc
tory in the remote site and select the Download command from the resulting menu.
• You can also upload or download multiple files and directories by selecting them
and then using the Upload or Download command.
Perspective
You’ll probably spend a surprising amount of time developing procedures
for deploying even relatively small applications. So, for a large application, I
recommend that you develop a procedure early in the application’s development
cycle. Then, you can use this procedure to deploy the application during testing,
and you can use that experience to fine-tune the procedure as you go along. As a
side benefit, you may discover deployment issues that affect the application’s
design.
Summary
• An executable JAR (Java Archive) file stores all classes and resources needed by
your application. You can manually distribute this file to your users and show them
how to run it.
• Java Web Start (JWS) allows users to download a Java GUI application from the
web, cache the application locally, and start it.
• An installer program allows you to create an install file for every operating system
that you want your application to run on.
• An executable JAR file contains a manifest file that stores information about the
files that are stored within the JAR file, including the file that contains the main
method for the application.
• The Java Network Launch Protocol (JNLP) can be used to launch Java applica
tions that have been deployed on a network such as an intranet or the Internet.
• Hypertext Markup Language (HTML) can be used to create a web page that
includes a link to a JNLP file.
Appendix A
How to set up your PC
for this book
This appendix shows how to install and configure the software that we
recommend for developing Java applications on a PC. This software includes
the Java Development Kit (JDK) and the NetBeans IDE. This appendix also
shows how to install the source code and create the databases for this book.
Please note that this appendix is designed for a PC that’s running the
Windows operating system. For directions on setting up a Mac, see
appendix B.
As you read this appendix, please remember that most web sites are
continually updated. As a result, some of the procedures in this appendix may
have changed since this book was published. Nevertheless, these procedures
should still be good guides to installing the software. And if there are
significant changes to these setup instructions, we will post updates on our
web site (www.murach.coin).
Notes
• For more information about installing the JDK, you can refer to the Oracle web site.
• For more information about installing NetBeans, you can refer to the NetBeans
web site.
Figure A-2 How to install the source code for this book
Appendix B
How to set up your Mac
for this book
This appendix shows how to install and configure the software that we
recommend for developing Java applications on a Mac. This software includes
the Java Development Kit (JDK), the NetBeans IDE, and the Apache Derby
database. This appendix also shows how to install the source code for this
book. This includes the files and databases that are used by the applications
presented in this book.
Please note that this appendix is designed for a Mac that’s running the
OS X operating system. For directions on setting up a PC, see appendix A.
As you read this appendix, please remember that most web sites are
continually updated. As a result, some of the procedures in this appendix may
have changed since this book was published. Nevertheless, these procedures
should still be good guides to installing the software. And if there are
significant changes to these setup instructions, we will post updates on our
web site (www.murach.com).
Notes
• When Apple makes an official version of JDK 1.7 available for the Mac, you can
install it by using the Software Update feature. Until then, you can install an
unofficial build of OpenJDK 1.7.
• For more information about installing the JDK on Mac OS X, you can search the
Internet.
Notes
• The JDK for the Mac doesn’t include Derby. As a result, if you want to use Derby
as described in chapters 20 and 21, you must install it separately.
• For more information about installing Netfieans or Derby on Mac OS X, you can
search the Internet.
Figure B-3 How to install the source code for this book
Arithmetic operators 785
Formatting dates and times, 412, 413 getColumnType method (ResultSetMetaData interface),
forName method (Class class), 682,683 708-711
Forward-only result set, 692, 693 getColumnTypeName method (ResultSetMetaData
Forward-only, read-only result set, 690, 691 interface), 708-711
Frame, see Form getComponent method (FocusEvent class), 520, 521
Frame class (java.awt), 462,463 getConnection method (DriverManager class), 684, 685
FRIDAY field (Calendar class), 409 getCurrencylnstance method (NumberFormat class), 94, 95
FROM clause (SELECT statement), 652, 653 getDatelnstance method (DateFormat class), 412,413
FTP program, 766,767 getDateTimelnstance method (DateFormat class), 412, 413
FULL field (DateFormat class), 412, 413 getDouble method (ResultSet interface), 694,695
Function, see Method getElementText method (XMLStreamReader class), 632
Future Value applet 635
HTML page, 550, 551 getEventType method (XMLStreamReader class), 632-635
interface, 538, 539 getFileName method (Path interface), 560-563
Future Value application, 130,131 getFirst method (LinkedList class), 380, 381
with data validation, 158-163 getltemCount method (combo box), 508,509
with exception handling, 150,151 getKey method (Map.Entry interface), 392-395
with GUI, 494-497 getKeyChar method (KeyEvent class), 522, 523
with nested for loops, 130,131 getKeyCode method (KeyEvent class), 522, 523
with static method, 140,141 getLast method (LinkedList class), 380, 381
getLocalName method (XMLStreamReader class), 632
635
G getMessage method (Throwable class), 440, 441
getMetaData method (ResultSet interface), 708, 709
Garbage collector, 242, 243 getName method (Class class), 260,261
Generate methods (NetBeans), 206, 207 getName method (Path interface), 560, 561
Generated code region (form), 478, 479 getName method (Thread class), 725
Generic class, 368, 369 getNameCount method (Path interface), 560, 561
Generic methods for validating an entry, 156,157 getNumberlnstance method (NumberFormat class), 94,95
Generic queue, 384, 385 getOppositeComponent method (FocusEvent class), 520,
GenericQueue class, 384, 385 521
Generics, 368, 369 getParent method (Path interface), 560, 561
get method (ArrayList class), 370-373 getPercentlnstance method (NumberFormat class), 94, 95
get method (Calendar class), 408,409 getRoot method (Path interface), 560, 561
get method (HashMap class), 392, 393 getRow method (ResultSet interface), 692,693
get method (LinkedList class), 380, 381 getSelectedlndex method (combo box), 508, 509
get method (list model), 512,513 getSelectedlndex method (list), 511
get method (Paths class), 560-563 getSelectedlndices method (list), 511
get method (TreeMap class), 392, 393 getSelectedltem method (combo box), 508, 509
get methods, 194,195, 200, 201 getSelectedValue method (list), 511
getAttributeCount method (XMLStreamReader class), getSelectedValuesList method (list), 511-513
632-635 getString method (ResultSet interface), 694, 695
getAttributeLocalName method (XMLStreamReader getText method (control), 480,481
class), 632-635 getText method (text area), 502,503
getAttributeValue method (XMLStreamReader class), getText method (XMLStreamReader class), 632, 633
632-635 getTime method (Calendar class), 408-411
getCause method (Throwable class), 450,451 getTime method (Date class), 410,411
getClass method (Object class), 242, 243, 260, 261 getTimelnstance method (DateFormat class), 412,413
getColumnCount method (ResultSetMetaData interface), getValue method (Map.Entry interface), 392-395
708.709 Greater Than operator, 63,112, 113
getColumnLabel method (ResultSetMetaData interface), Greater Than Or Equal operator, 63,112,113
708.709 GregorianCalendar class (java.util), 406,407
getColumnName method (ResultSetMetaData interface), GUI (graphical user interface), 6,7,459
708.709
GUI application (deployment), 756,757
792 HALF_EVEN field Instantiation
JNLP (Java Network Launch Protocol), 760-763 Life cycle of a thread, 722,723
elements and attributes, 762,763 Lightweight components, 462
Join (database), 654, 655 Line Item application, 224-231
Joining strings, 46,47 lineWrap property (text area), 502, 503
JOptionPane class (javax.swing), 486, 487 Linked list, 366, 367, 380-385
JPanel class (javax.swing), 462,463 using to create a queue, 384, 385
JRE (Java Runtime Environment), 538, 539, 756,757 LinkedList class (java.util), 366, 367, 380-385
JSP (Java Server Page), 6 List, 366, 367, 510-513
JTextComponent class, 520,521 List interface (java.util), 366, 367
JTextField class (javax.swing), 462,463 List model, 512, 513
JULY field (Calendar class), 409 Listener interfaces, 518, 519
JUNE field (Calendar class), 409 Literal value, 42,43
JVM (Java virtual machine), 10,11 Local class, 326, 327
JWS (Java Web Start), 753, 754,760-769 Locking objects, 734,735
Logic error, 72,73,168,169
Logical operators, 116,117
K LONG field (DateFormat class), 412,413
long type, 80, 81
Key-value pair, 366, 367 LONGVARBINARY data type (SQL), 710, 711
Keyboard event, 522, 523 LONGVARCHAR data type (SQL), 710, 711
KeyEvent class (java.awt.event), 522, 523 Loops, 126-133
keyPressed method (KeyListener interface), 522, 523 with arrays, 344-347
keyReleased method (KeyListener interface), 522, 523 with linked lists, 382, 383
keyTyped method (KeyListener interface), 522, 523 with maps, 394, 395
Keywords (Java), 38, 39 Low-level events, 518,519
L M
Label, 460,461 Main class, 14,15,40,41
Labeled break statement, 134,135 Main method, 8, 9, 40,41
Labeled continue statement, 136,137 Main project (NetBeans), 20,21
last method (ResultSet interface), 692, 693 Main thread, 718, 719
lastlndexOf method (String class), 420,421 Manifest file (executable JAR), 754, 755
Late binding, 250 Manipulating strings, 420,421
Layering input streams Many-to-many relationship, 648, 649
binary, 588, 589 Map, 366, 367, 392, 393
character, 574, 575 Map.Entry interface (java.util.Map), 392, 393
Layering output streams MARCH field (Calendar class), 409
binary, 584, 585 Math class, 96,97
character, 570, 571 Matisse GUI builder, 459
Layering streams, 566, 567 max method (Math class), 96,97
Left outer join, 654 MAX_PRIORTTY field (Thread class), 730, 731
Legacy collection classes, 396, 397 MAY field (Calendar class), 409
length field (array), 344,345 MEDIUM field (DateFormat class), 413
length method (RandomAccessFile class), 596, 597 Member class, 326, 327
length method (String class), 420-423 Members of a class, 194,195
length method (StringBuilder class), 424-427 Metadata
Length of an array, 340, 341 of a file, 594, 595
Less Than operator, 63,112,113 of a result set, 708-711
Less Than Or Equal operator, 63,112,113 Metal look and feel, 460
Library, 14,15, 316, 317 Method, 8, 9,40,41,188,189
adding to a project, 680, 681 calling, 50,51,210,211
making available, 316, 317
M ethod (continued) Num eric variables 795
Product application with inheritance, 252-259 readLine method (BufferedReader class), 576, 577
Product class diagram, 188,189 readUTF method (Datalnput interface), 590-593
Product Maintenance application REAL data type (SQL), 710, 711
with GUI, 524-533 Record
with interfaces, 294-303 database, 646,647
ProductConstants interface, 578, 579 file, 572, 573
ProductDAO interface, 294, 295 Rectangular arrays, 356, 357
file I/O version, 578, 579 Red-black tree, 392
ProductReader interface, 578, 579 Reference to an array, 354, 355
ProductWriter interface, 578, 579 Reference type, 114,115
Project (NetBeans), 14,15 passing to method, 212, 213
Properties for forms and controls, 470,471 Regular expression, 420,421
protected keyword in superclass, 246, 247 Relational database, 646,647
public keyword, 138,139 Relational operators, 62, 63,112,113
class declaration, 40,41 Relationships (between tables), 648, 649
instance variable, 196 relative method (ResultSet interface), 692, 693
method, 200, 201 Relative path, 562, 563
superclass, 246, 247 Remote web server (deploying to), 766,767
Pull operation, 384, 385 remove method (ArrayList class), 370-373
Push operation, 384, 385 remove method (HashMap class), 392, 393
put method (HashMap class), 392-395 remove method (LinkedList class), 380, 381
put method (TreeMap class), 392-395 remove method (TreeMap class), 392, 393
removeElementAt method (list model), 512, 513
removeFirst method (LinkedList class), 380-383
Q removeltem method (combo box), 508, 509
removeltemAt method (combo box), 508, 509
Query, 652-655 removeLast method (LinkedList class), 380-383
QUESTION_MESSAGE field (JOptionPane class), 486, replace method (String class), 420,421
487
replace method (StringBuilder class), 424, 425
Queue, 384, 385
requestFocusInWindow method (control), 480,481
resizable property (form), 471
Result (returning), 690, 691
R Result set, 652-655
Radio buttons, 506, 507 moving through, 692, 693
random method (Math class), 96,97 returning data, 694, 695
Random-access files, 594-599 Result table, 652-655
RandomAccessFile class (java.io), 594-597 ResultSet object, 690-695
Range checking, 154,155 ResultSetMetaData interface (java.sql), 708,709
RDBMS (relational database management system), 646 return statement, 138,139, 200, 201
read method (BufferedReader class), 576, 577 Return type, 138,139
read-only field, 194,195 of a method, 200, 201
readBoolean method (Datalnput interface), 590, 591 Return value of a method, 210,211
readChar method (Datalnput interface), 590-593 Right outer join, 654
readDouble method (Datalnput interface), 590,591 roll method (Calendar class), 408, 409
Reader class (java.io), 574, 575 roll method (GregorianCalendar class), 408,409
Reader hierarchy, 574, 575 Root element (XML), 617, 618
Reading round method (Math class), 96, 97
binary files, 590, 591 Rounding, 94, 95
fixed-length strings, 598, 599 RoundingMode enumeration, 104, 105
input from the console, 58, 59 Row
random-access files, 596, 597 database, 646,647
text files, 576, 577 file, 572, 573
readlnt method (Datalnput interface), 590, 591 Rl'I'l (runtime type identification), 260
798 run m ethod (Runnable interface) SQ L (Structured Query Language)
run method (Runnable interface), 720, 721 setEnabled method (control), 480,481
run method (Thread class), 720,721, 725 setFocusable method (control), 480,481
Runnable interface (java.lang), 720,721 setLength method (RandomAccessFile class), 596, 597
implementing, 728,729 setLength method (StringBuilder class), 424, 425
Runnable state (thread), 722,723,736,737 setLocationRelativeTo method (form), 482, 483
Running projects, 16,17 setMaximumFractionDigits method (NumberFormat
Running executable JAR files, 758, 759 object), 94, 95
Running SQL scripts (Derby database), 666-669 setMinimumFractionDigits method (NumberFormat
Runtime error, 72, 73,168,169 object), 94, 95
Runtime exception, 72, 73,168,169 setModel method (list), 511-513
RuntimeException (java.lang), 146,147,432, 433 setPriority method (Thread class), 730,731
setProperty method (System class), 684, 685
setScale method (BigDecimal class), 104,105
s setSelected method (check box), 504,505
setSelectedlndex method (combo box), 508,509
SATURDAY field (Calendar class), 409 setSelectedlndex method (list), 511, 512, 513
SAX (Simple API for XML), 624, 625 setString method (PreparedStatement interface), 698, 699
Scale, 104,105 setText method (control), 480, 481
Scanner class, 58-61,152,153 setText method (text area), 502, 503
Schema (database), 684 setTime method (Calendar class), 408,409
Schema language (XML), 620, 621 Setting dates and times, 406,407
Scientific notation, 80, 81 setVisible method (form), 482,483
Script file, 758,759 SHORT field (DateFormat class), 412,413
Scroll bars, 502, 503 short type, 80, 81
Scroll pane, 502,503 Short-circuit operators, 116,117
Scrollable result set, 690-693 showMessageDialog method (JOptionPane class), 486, 487
SDK (Software Development Kit), 4, 5 Signature
SE (Standard Edition), 4,5 constructor, 198,199
SECOND field (Calendar class), 409 method, 138,139,202, 203
Security issues (applets), 540, 541 Signed applet, 540, 541
seek method (RandomAccessFile class), 596,597 Significant digits, 80, 81
SELECT statement (SQL), 652-655 Single-line comment, 36, 37
joining tables, 654,655 Single-precision number, 80, 81
selectAll method (control), 480, 481 size method (ArrayList class), 370-373
selectAll method (JTextComponent class), 520, 521 size method (DataOutputStream class), 586, 587
selected property (check box), 504, 505 size method (Files class), 560, 561
selected property (radio button), 506, 507 size method (HashMap class), 392, 393
Selection structure, 64,118,119 size method (LinkedList class), 380, 381
selectionMode property (list), 510, 511 size method (list model), 512, 513
Semantic events, 518, 519 size method (TreeMap class), 392, 393
SEPTEMBER field (Calendar class), 409 Size of an array, 340,341
Sequential-access file, 594,595 skip method (BufferedReader class), 576, 577
Servlet, 6,7 skipBytes method (Datalnput interface), 590, 591
Set, 366, 367 sleep method (Thread class), 720,721,725-729
Set interface (java.util), 366, 367 SMALLINT data type (SQL), 710,711
set method (ArrayList class), 370-373 Software class, 256, 258
set method (Calendar class), 408,409 sort method (Arrays class), 348-351
set method (LinkedList class), 380, 381 Source code, 10,11
set methods, 194,195, 200,201 SPACE constant (XMLStreamConstants interface), 632,
setCharAt method (StringBuilder class), 424,425 633
setDaemon method (Thread class), 724, 725 Special characters, 48, 49
setDouble method (PreparedStatement interface), 698, 699 split method (String class), 420-423
setEditable method (control), 480, 481 SQL (Structured Query Language), 652
SQL data types Testing applications 799
Testing exception handlers, 446,447 toString method (Object class), 242, 243
Text area, 502,503 toString method (StringBuilder class), 424, 425
Text field, 460, 461 toString method (Throwable class), 440, 441
validating, 488,489 Trace execution, 172,173
Text files, 564, 565,570-577 Tree map, 392, 393
delimited, 572, 573 TreeMap class (java.util), 366, 367, 392, 393
reading, 576, 577 trim method (String class), 420-423
writing, 572, 573 try statement, 148,149,436, 437
text property (check box), 504, 505 try-with-resources statement, 438,439
text property (control), 470,471 TUESDAY field (Calendar class), 409
text property (radio button), 506, 507 Two-dimensional arrays, 356-359
text property (text area), 502, 503 Type variable, 368, 369
this keyword, 198,199,204, 205 TYPE_FORWARD_ONLY field (ResultSet interface), 690,
Thread class (java.lang), 720,721,724, 725 691
extending, 726,727 TYPE_SCROLL_INSENSmVE field (ResultSet
Thread scheduler, 718,719,722,723 interface), 690, 691
Thread states, 722, 723 TYPE_SCROLL_SENSITIVE field (ResultSet interface),
Threads, 483,718,719 690, 691
communicating among, 736,737 Type-safe enumerations, 328, 329
creating, 724-729 Typed collection, 368,369
interrupting, 732,733 Types class (java.sql), 708,709
life cycle, 722,723
manipulating, 730-733
Order Queue application, 738-747 u
putting to sleep, 725-729
UML (Unified Modeling Language), 188, 189
setting priority, 730, 731
Unary operator, 86, 87
synchronizing, 734-737
Unchecked exception, 432, 433
uses for, 718,719,720
Unicode character set, 80, 81
ways to create, 720,721
Untyped collection, 398-401
Three-tiered architecture, 186,187 UPDATE statement (SQL), 656, 657
Throw an exception, 98, 99,146,147,434, 435
Updateable result set, 690,691
throw statement, 446,447
updateDouble method (ResultSet interface), 696, 697
Throwable class (java.lang), 432,433, 440,441
updateRow method (ResultSet interface), 696, 697
Throwable hierarchy, 432, 433
updateString method (ResultSet interface), 696, 697
Throwing a checked exception, 444, 445
Updating records in a database
throws clause, 444,445
JDBC, 696, 697
THURSDAY field (Calendar class), 409
SQL, 656,657
TIME data type (SQL), 710,711
Upload to a remote server, 766,767
Times (formatting), 412, 413
User thread, 724,725
TIMESTAMP data type (SQL), 710,711
UTF (Universal Text Format), 586, 587
TINYBIT data type (SQL), 710,711
Title bar, 460, 461
title property (form), 471 V
Titled border (panel), 506, 507
toAbsolutePath method (Path interface), 560-563 Validating a single entry, 154,155
toArray method (ArrayList class), 370, 371 Validating Swing input data, 486-493
toArray method (LinkedList class), 380, 381 Validator class, 226, 229-230
toFile method (Path interface), 560, 561 VARBINARY data type (SQL), 710,711
Token, 58, 59 VARCHAR data type (SQL), 710,711
toString method (BigDecimal class), 104,105 Variable Name property (control), 472,473
toString method (Date class), 410, 411 Variables, 42,43
toString method (Double class), 98, 99 array, 340, 341
toString method (Integer class), 98,99 initializing, 42,43, 82, 83
Variables (continued) yie ld m ethod (Thread class)
Call toll-free:
1-800-221-5528
(Weekdays, 8 am to 4 pm Pacific Time)
To comment by
E-mail: murachbooks® murach.com Fax: 1-559-440-0963
Web: www.murach.com
Postal mail: Mike Murach & Associates, Inc.
4340 North Knoll Ave. Mike Murach & Associates, Inc.
Fresno, California 93722-7825 Professional programming books
What software you need for this book
• Java SE 7 (JDK 1.7) or later. You can download this software for free and install
it as described in appendix A (PC) or appendix B (Mac).
• NetBeans IDE 7.0 or later. You can download this software for free from
netbeans.org and install it as described in appendix A (PC) or appendix B
(Mac).
• Apache Derby 10.8 or later. This software is included as part of Java SE 7 on a
PC. On a Mac, you can download it for free and install it as described in
appendix B.
w w w .m urach.com
Corrections to the sec o n d printing
Chapter 20, page 661
The second heading should say “Four im portant JA R files” (not “Three im portant JA R files”).
Corrections to the third printing
Chapter 1, page 33
In step 5, the project should be ch01_ex1_TestScore (not ch01_ex2_TestScore).
Chapter 2, page 45
U nder the “Statem ents that m ix int and double variables” heading, the first line should be:
int result9 = (int) invoiceTotal / invoiceCount // result9 = 125
Not:
int result9 = invoiceTotal / invoiceCount // result9 = 125
GUI programming m ade easy “ Murach's Java is n o w my go-to source fo r reference and
• Use Sw ing an d N etB eans to develop graphical user interfaces that learning and brushinq up, w e ll above and beyond the
o th e r books in my collection."
han d le events, validate data, an d w ork w ith business objects
Je ff Salter, Sacram ento Java User? Group { S a d DG)
• Apply y our n ew skills t o a special type o f G U I application know n as
an applet " If I'd seen this book first, I w o u ld n o t have wasted money
(and tim e) on 6 o th e r books! This one is highly organized,
Data access programming the professional way clear, and very effective as a learning to o l."
• W rite d a ta access classes th a t m ap business objects to text, binary, o r Posted a t Am azon.com
X M L files
"The style is clean, very user friendly, and simple. The
• Use the StAX A P I t o w ork w ith X M L files
narrative is to ta lly accurate and focuses on im p o rta n t
• L ea m h o w to em b ed an A pache D erb y database w ithin a desktop issues; it is n o t dum bed dow n. This book is a w in n e r!"
application Dr. Richard Wiener, Editor-in-Chief, Journal o f Cfcjecf Technology
• M aster the latest JD B C features for w orking w ith any database
• D evelop 3-tier, object-oriented, database applications th e way the
pros develop th em
ISBN 978-1-890774-65-3
Downloadable files m ake learning easier 55750
(see the last page o f this book for details)