 |
Discover Java with Beginning Java 2 JDK 5
|
by: Jeff Friesen
Java's continuing evolution has fostered a growing assortment of books that educate developers about all things Java. Many of
these books introduce Java technology to beginners. One of the better books in this category is Murach's beginning
Java 2 JDK 5. Even if you are not a Java beginner, this book deserves a place in your programming library.
This article reviews beginning
Java 2 JDK 5 by taking you on a chapter-by-chapter tour, which gives you a high-level
overview of book content. During this review, caution boxes that point out book flaws and provide corrections are presented.
The article also presents a bonus topic that teaches you how to work with mouse events, and use them with a custom component
to improve a business application's GUI.
Book tour
Murach's beginning Java 2 JDK 5 is a 21-chapter and one appendix book (approximately 800 pages cover to cover). These
21 chapters are organized into five sections: essential Java skills, object-oriented programming with Java, more Java
essentials, GUI programming with Java, and data access programming with Java. The appendix shows you how to download and
install the book's accompanying files.
Each chapter presents tutorial and reference content using Murach's paired-pages format. The tutorial content appears on each
left page and refers to reference material -- essential syntax, guidelines, and examples -- on the appropriate right page.
Each chapter concludes by summarizing key topics and presenting business-oriented exercises -- modify a future value
calculator application, for example.
Essential Java skills
Chapter 1 introduces you to Java. It next shows you how to download, install, and configure your environment for version 5 of
the Java Development Kit (JDK). You discover the GUI-based TextPad text editor and command-line-based JDK tools for
developing Java programs, and learn how to install and navigate the JDK's documentation. This chapter wraps up by discussing
the Eclipse and BlueJ IDEs.
Chapter 2 teaches you Java programming fundamentals. Basic coding skills (like creating identifiers) are first presented. You
then learn how to work with numeric and string variables. Moving on, you learn how to import classes, create objects and call
methods, and use the API documentation to research classes. You also discover console input and output. And you are taught
how to code simple control statements.
Chapter 3 focuses on working with data. You learn basic skills, such as how to code arithmetic expressions and how to
initialize variables. You next discover Java's NumberFormat, Math, Double and
Integer classes. After using some of this knowledge in a formatted invoice application, this chapter introduces
Java's BigDecimal class and applies it to the application.
Chapter 4 looks at how to code control statements. It first explains how to code Boolean expressions, which are used by most
control statements. It next explains how to code if/else and switch, various loop, and the break and continue statements.
This chapter closes by showing you how to work with static methods, which allows you to divide your applications into
manageable parts.
Chapter 5's study of exception handling and data validation ends this section. You discover exception-handling concepts,
which are illustrated by a future value application. You then learn about data validation in the context of Java's
Scanner class (which early chapters use to simplify console input). The chapter then presents static methods for
data validation, and applies these methods to the future value application.
Object-oriented programming with Java
Chapter 6 introduces you to object-oriented programming by exploring classes. You learn how classes organize an application
and support the concept of encapsulation. You then learn how to code classes, instantiate objects from classes, and code and
use static fields, methods, and initialization blocks. A line item application that demonstrates many of these concepts
rounds out this chapter.
|
Caution
|
Figure 6-9's return currency.format(this.getPrice); is wrong. The correct statement is
return currency.format(this.getPrice());.
|
I really liked this
chapter's discussion of three-tiered architecture and its application to business
programs. I also
liked the chapter's use of the Unified Modeling Language to describe classes
and class relationships. However, I didn't like page
208's "call static fields and methods" terminology. In my opinion, a program
calls methods and accesses fields -- it doesn't
call fields.
Chapter 7 focuses on inheritance. You learn how inheritance works, how the Java API uses inheritance, and other fundamentals.
You then receive basic skills in working with inheritance -- how polymorphism works, for example. A product application is
next presented to demonstrate inheritance. You also learn more inheritance skills (like casting objects), and how to work
with keywords abstract and final.
Chapter 8 investigates interfaces. Your introduction to interfaces includes a comparison with abstract classes, and an
introduction to Java's Cloneable and Comparable interfaces. You next learn how to code and
implement interfaces, inherit interfaces from other interfaces, and more. A product maintenance application that uses
interfaces to hide the implementation of its database tier concludes this chapter.
|
Caution
|
Page 276 refers to Figure 8-8's ProductDAO, ProductReader and ProductWriter as
classes. However, they are interfaces -- not classes.
|
Chapter 9 completes this section by discussing additional object-oriented programming concepts. Specifically, you learn about
packages and how to organize your classes and interfaces into packages, about using the JDK's javadoc tool to document your
packages and their contents, about nesting classes within other classes, and about enumerations and static imports.
|
Caution
|
|
In its discussion of Java's enum language feature, page 312 states that "the constants in the enumeration are assigned
integer values." Also, Figure 9-9 specifies: "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."
These assertions are wrong. The JDK documentation states that an "enum declaration defines a full-fledged class", which leads
to an enum constant being a class instance. Consider enum declaration
enum Directions { north, south, east, west };. You can invoke methods on north and the other
constants. Example: System.out.println (Direction.north.toString ());.
|
More Java essentials
Chapter 10 presents arrays. You learn how to create a simple array, assign values to its elements, and use both the regular
for loop and the enhanced for loop to iterate over these elements. You next learn about the methods in Java's
Arrays class for searching, sorting, filling, and comparing arrays. After learning how to copy one array to
another (and perform other operations), you discover tabular and jagged arrays.
Chapter 11 introduces you to collections (where you learn how they compare with arrays, and more) and generics. You then
discover Java's ArrayList and LinkedList classes, which are demonstrated via two versions of an
invoice application. You next learn about maps, specifically hash and tree maps. Finally, you learn how to work with legacy
collections -- collections that pre-date JDK 5.
|
Caution
|
The second example's int number = (Integer)numbers.get(i); statement in Figure 11-18 is flawed because
it will not compile under pre-JDK 5 versions, where a wrapper object cannot be assigned to a primitive type. Although this
statement compiles under JDK 5 because of autoboxing, I consider it to be flawed because this example belongs to a section
focused on legacy collections.
|
Chapter 12 looks at dates and strings. You study Java's GregorianCalendar, Calendar,
Date, and DateFormat classes. You then study a DateUtils class whose utility methods
return the number of days between two dates (and more). This chapter next presents Java's String class, and
finishes with a presentation of Java's StringBuilder class.
Chapter 13 extends Chapter 5's exception-handling introduction. You are shown Java's exception class hierarchy and the way
exceptions propagate up the method call stack. You then learn how to work with exceptions via the try and throw statements,
and various clauses. Moving on, you are taught how to create your own exception classes, and how to chain exceptions
together. Finally, you discover assertions.
This section finishes with Chapter 14's focus on threads. To begin, you learn how threads work, find out about a thread's
life cycle, and more. You next learn how to create threads as objects that either subclass Java's Thread class
or implement its Runnable interface. Thread sleep, priority change, and thread interruption are discussed next.
Finally, you learn how to synchronize and communicate between threads.
|
Caution
|
Figure 14-10 presents a synchronized calculateFutureValue() method. Page 456 states that this method must be
synchronized to prevent multiple threads that simultaneously access this method from interfering with each other's
calculations. But this method doesn't need to be synchronized. Each thread receives its own stack, which holds a copy of the
local variables. Interference cannot occur.
|
GUI programming with Java
Chapter 15 transitions you from creating text-based console user interfaces to creating Swing-based graphical user
interfaces. This transition takes place in the context of a future value calculator application. You learn how to work with
frames, including how to center a frame on the screen. You also learn about Swing's panel, button, label, and text field
components; button events; and the flow and border layout managers.
Chapter 16 continues to explore Swing by introducing you to Swing's text area, scroll pane, check box, radio button, combo
box (you learn how to use event listeners with a combo box), and list (you learn how to support multiple selections in a
list) components. You also find out how to establish a component's border. I really liked this chapter's simplified
introduction to the Grid Bag layout manager.
Chapter 17 digs deeper into event handling. You learn about Java's event model, semantic versus low-level events, how to
structure event-handling code, and more. You also learn how to work with the low-level focus and keyboard events, and
adapter classes. The chapter then switches to validating Swing input data, where you discover Java's JOptionPane
class and a useful SwingValidator class.
|
Caution
|
Page 550 states that most of the classes and interfaces in Figure 17-2 are stored in packages java.awt and
java.awt.event. However, none of these classes and interfaces are stored in java.awt. Also, page
578 refers to the code in Figure 17-16's first example as using a series of nested if statements. However, these if
statements are not nested.
|
In contrast to previous chapters, which focused on applications, Chapter 18 wraps up this section by focusing on applets. You
are shown the former future value calculator application as an applet, learn applet history, examine security issues, study
applet inheritance, and learn about an applet's lifecycle methods. You next learn how to develop and test applets, and
explore packaging applets in JAR files for easy deployment.
Data access programming with java
Chapter 19 introduces you to Java's support for text and binary files. You discover Java's File class for
performing basic file-oriented tasks, and the streams mechanism for inputting data from and outputting data to files. You
next learn to use character streams with text files and byte-oriented streams with binary files. Chapter 19 closes with a
discussion of random-access files.
Chapter 20 presents the XML alternative to text and binary files. After introducing fundamental XML concepts (tags, elements,
and attributes, for example), this chapter introduces you to Java's SAX and DOM (Document Object Model) APIs. The chapter
then emphasizes DOM, where you learn how to build, read, and write DOM trees. Finally, the chapter presents a utility class
for working with XML files.
|
Caution
|
Page 708 refers to an addTextNodeElement() method. However, the method shown in Figure 20-15 is
addTextNode().
|
The previous chapters presented two alternatives for storing a business application's data. A third alternative is presented
in this section's final chapter. Chapter 21 introduces the fundamental concepts of relational databases, tables, fields, and
SQL (Structured Query Language) to you. You then learn about database drivers, using the JDBC API to read business data from
and write it to database tables, and metadata.
|
Caution
|
Page 748 refers to a DBUtil class. However, the class shown in Figure 21-15 is DBStringUtil.
|
One of the things I really like about this book is its practical example of interfaces. Chapter 8 introduces this example,
whereby a group of interfaces allows a product maintenance application to access products from storage independent of the
storage mechanism. Chapters 19 through 21 extend this example by implementing these interfaces to support text/binary files,
XML files, and JDBC-accessible databases.
Bonus topic
Chapter 17 summarizes keyboard, mouse, and other low-level events. Unlike keyboard events, however, this chapter doesn't
discuss working with mouse events, leading one to assume that mouse events are not as useful as keyboard events in business
applications. However, mouse events can be just as useful, as you will see. After showing you how to work with mouse events,
this section presents a useful example.
How to work with mouse events
Java provides several interfaces and classes for working with mouse events that result from a mouse button being
pressed or released, the mouse pointer being moved across the screen, or the mouse wheel being moved. For business
applications, the MouseListener interface, the MouseAdapter class, and the MouseEvent
class are the most useful.
The MouseListener interface provides five methods for detecting a mouse button being clicked (that is, pressed
and then released), the mouse pointer entering or exiting a component's GUI region, and a mouse button being pressed or
released. The MouseAdapter class trivially implements all of these methods so that you only need to override (in
a subclass) the methods that you need:
-
void mouseClicked(MouseEvent e) is invoked when a mouse button is clicked over a component.
-
void mouseEntered(MouseEvent e) is invoked when the mouse pointer enters a component.
-
void mouseExited(MouseEvent e) is invoked when the mouse pointer exits a component.
-
void mousePressed(MouseEvent e) is invoked when a mouse button is pressed over a component.
-
void mouseReleased(MouseEvent e) is invoked when a mouse button is released over a component.
Each of the previous methods takes a MouseEvent object whose methods identify the mouse button that was pressed,
released, or clicked; identify the mouse pointer's position (relative to the origin of the component under the mouse
pointer); identify whether the event is a trigger for displaying a popup menu, and provide other kinds of information.
I'm not going to list any MouseEvent methods because they aren't relevant to this section's useful example.
Furthermore, you probably won't need them in most business applications. However, I've chosen to demonstrate the
mouseClicked() method. When you click the label in the code fragment below, the label component's text is
replaced with Your salary has been doubled!:
private JLabel lblSurprise = new JLabel ("Click me for a big surprise!");
// Later in the source code ...
lblSurprise.addMouseListener (new MouseAdapter ()
{
public void mouseClicked (MouseEvent e)
{
lblSurprise.setText ("Your salary has doubled!");
}
});
Mouse events and a helpful status bar
The book's Figure 17-11 presents two examples that demonstrate responding to and listening for keyboard events. The examples
restrict those characters that can be entered into a text field to digits and a few numeric-related symbols. This capability
simplifies data validation and demonstrates the usefulness of keyboard events in business applications. But mouse events can
also be useful. Check out Figure 1.
Figure 1: A suitable help message appears in the status bar when the mouse pointer moves over the check box or text
field.
Someone new to a business application's GUI may not understand how to enter some of the data. Figure 1 reveals how a GUI can
assist the user, by presenting a status bar, and by displaying a line of component-specific help text in the status bar when
the user moves the mouse pointer over the component. When the mouse pointer exits the component, some kind of default text
appears in the status bar.
A status bar can be implemented by a class that extends the JLabel class. As shown below, this subclass
specifies a private field for storing default status bar text; specifies a constructor that saves this default text in the
field, places the text in the status bar, and creates a nice border to highlight the status bar in the GUI; and specifies a
method for setting the default text:
class StatusBar extends JLabel
{
private String defaultText;
StatusBar (String defaultText)
{
this.defaultText = defaultText;
setDefaultText ();
setBorder (BorderFactory.createBevelBorder (BevelBorder.LOWERED));
}
void setDefaultText ()
{
setText (defaultText);
}
}
The following code fragment shows you how to create a status bar from the above class. It assumes that Grid Bag layout is the
current layout manager. The status bar's constraints are specified to begin the status bar in the left-most cell on row 6,
have the status bar occupy three horizontal cells, and align the status bar's left edge with the west side of the left-most
cell:
private StatusBar sb;
// Later in the source code ...
sb = new StatusBar ("Payment Application 1.0");
GridBagConstraints gbc;
gbc = getConstraints (0, 6, 3, 1, GridBagConstraints.WEST);
gbc.fill = GridBagConstraints.HORIZONTAL;
add (sb, gbc);
The gbc.fill = GridBagConstraints.HORIZONTAL; assignment tells Grid Bag layout to display the status bar label
across all three cells. Without this assignment, the status bar would begin at the west edge of the left-most cell, but not
extend over the entire GUI's width. This has to do with the status bar's preferred size, which depends upon the length of the
text to be displayed and the status bar's current font.
A status bar is not useful until it can display text as the mouse pointer enters and exits a component. This can be
accomplished by creating a class that extends MouseAdapter and overrides the mouseEntered() and
mouseExited() methods to present the appropriate text. It is then a simple matter to create a class instance
with appropriate status bar text and attach it to the component:
class StatusBarHelp extends MouseAdapter
{
private String msg;
StatusBarHelp (String msg)
{
this.msg = msg;
}
public void mouseEntered (MouseEvent e)
{
sb.setText (msg);
}
public void mouseExited (MouseEvent e)
{
sb.setDefaultText ();
}
}
// Later in the source code ...
String msg = "Use format xxxx xxxx xxxx xxxx";
txtCardNumber.addMouseListener (new StatusBarHelp (msg));
I excerpted the previous code fragments from a PaymentApp application that I wrote to demonstrate using mouse
events with a helpful status bar. This application is similar to the application that appears in the book's Figure 16-15.
Unlike the book's version, however, my version doesn't handle events -- apart from the status bar's mouse events. Check out
Listing 1.
Listing 1: PaymentApp.java
// PaymentApp.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class PaymentApp
{
public static void main (String [] args)
{
new PaymentFrame ("Payment Application").setVisible (true);
}
}
class PaymentFrame extends JFrame
{
PaymentFrame (String title)
{
super (title);
setDefaultCloseOperation (EXIT_ON_CLOSE);
add (new PaymentPanel ());
pack ();
// Center the frame.
Toolkit tk = Toolkit.getDefaultToolkit ();
Dimension dim = tk.getScreenSize ();
setLocation ((dim.width-getWidth ())/2, (dim.height-getHeight ())/2);
}
}
class PaymentPanel extends JPanel
{
private JRadioButton rbCreditCard, rbBillCustomer;
private JList lstCardType;
private JTextField txtCardNumber;
private JComboBox cbMonth, cbYear;
private JCheckBox ckbVerified;
private JButton btnAccept, btnExit;
private JLabel lblCardType, lblCardNumber, lblExpirationDate;
private StatusBar sb;
PaymentPanel ()
{
setLayout (new GridBagLayout ());
// Declare a local class that is used to simplify status bar help for
// various GUI components.
class StatusBarHelp extends MouseAdapter
{
private String msg;
StatusBarHelp (String msg)
{
this.msg = msg;
}
public void mouseEntered (MouseEvent e)
{
sb.setText (msg);
}
public void mouseExited (MouseEvent e)
{
sb.setDefaultText ();
}
}
// Establish GUI's billing choice section.
JPanel pnlRadio = new JPanel ();
ButtonGroup bgBilling = new ButtonGroup ();
pnlRadio.setLayout (new FlowLayout (FlowLayout.LEFT));
Border bdLowered;
bdLowered = BorderFactory.createBevelBorder (BevelBorder.LOWERED);
Border bdRadio;
bdRadio = BorderFactory.createTitledBorder (bdLowered, "Billing:");
pnlRadio.setBorder (bdRadio);
rbCreditCard = new JRadioButton ("Credit card", true);
bgBilling.add (rbCreditCard);
pnlRadio.add (rbCreditCard);
rbBillCustomer = new JRadioButton ("Bill customer");
bgBilling.add (rbBillCustomer);
pnlRadio.add (rbBillCustomer);
add (pnlRadio, getConstraints (0, 0, 3, 1, GridBagConstraints.WEST));
// Establish GUI's credit card section.
lblCardType = new JLabel ("Card type:");
add (lblCardType, getConstraints (0, 1, 1, 1, GridBagConstraints.EAST));
String [] cardNames =
{
"Visa", "Master Card", "American Express", "Other"
};
lstCardType = new JList (cardNames);
lstCardType.setFixedCellWidth (170);
lstCardType.setVisibleRowCount (3);
JScrollPane sp = new JScrollPane (lstCardType);
add (sp, getConstraints (1, 1, 2, 1, GridBagConstraints.WEST));
lblCardNumber = new JLabel ("Card number:");
add (lblCardNumber, getConstraints (0, 2, 1, 1, GridBagConstraints.EAST));
txtCardNumber = new JTextField (15);
add (txtCardNumber, getConstraints (1, 2, 2, 1, GridBagConstraints.WEST));
String msg = "Use format xxxx xxxx xxxx xxxx";
txtCardNumber.addMouseListener (new StatusBarHelp (msg));
lblExpirationDate = new JLabel ("Expiration date:");
add (lblExpirationDate, getConstraints (0, 3, 1, 1,
GridBagConstraints.EAST));
String [] months =
{
"January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"
};
cbMonth = new JComboBox (months);
add (cbMonth, getConstraints (1, 3, 1, 1, GridBagConstraints.WEST));
String [] years =
{
"2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012"
};
cbYear = new JComboBox (years);
add (cbYear, getConstraints (2, 3, 1, 1, GridBagConstraints.WEST));
ckbVerified = new JCheckBox ("Verified");
add (ckbVerified, getConstraints (1, 4, 1, 1, GridBagConstraints.WEST));
msg = "Check this box to indicate a verified card.";
ckbVerified.addMouseListener (new StatusBarHelp (msg));
// Establish GUI's command section.
btnAccept = new JButton ("Accept");
add (btnAccept, getConstraints (1, 5, 1, 1, GridBagConstraints.EAST));
btnExit = new JButton ("Exit");
add (btnExit, getConstraints (2, 5, 1, 1, GridBagConstraints.CENTER));
// Establish GUI's status bar.
sb = new StatusBar ("Payment Application 1.0");
GridBagConstraints gbc;
gbc = getConstraints (0, 6, 3, 1, GridBagConstraints.WEST);
gbc.fill = GridBagConstraints.HORIZONTAL;
add (sb, gbc);
}
private GridBagConstraints getConstraints (int gridx, int gridy,
int gridwidth, int gridheight,
int anchor)
{
GridBagConstraints gbc = new GridBagConstraints ();
gbc.insets = new Insets (5, 5, 5, 5);
gbc.gridx = gridx;
gbc.gridy = gridy;
gbc.gridwidth = gridwidth;
gbc.gridheight = gridheight;
gbc.anchor = anchor;
return gbc;
}
}
class StatusBar extends JLabel
{
private String defaultText;
StatusBar (String defaultText)
{
this.defaultText = defaultText;
setDefaultText ();
setBorder (BorderFactory.createBevelBorder (BevelBorder.LOWERED));
}
void setDefaultText ()
{
setText (defaultText);
}
}
Conclusion
After reading Murach's beginning Java 2 JDK 5 cover to cover, I can confidently say that this book is an excellent
choice for learning (and teaching) Java. In spite of flaws (whose corrections can be recorded on the relevant pages), this
book accomplishes its three core objectives: it lets you get off to a fast start learning Java, it helps you master the core
Java features, and it teaches you how to build real-world applications.
Resources
-
Download this article's code.
-
Download beginning Java 2 JDK 5's code.
Author Bio
Jeff
Friesen is a freelance software developer and educator specializing in Java technology.
|