Você está na página 1de 226

SUN TECHNOLOGIES: JAVA

STANDARD EDITION (SCJP)

Loc ROBERT, SUN

http://www.supinfo.com

SUN TECHNOLOGIES: JAVA STANDARD EDITION (SCJP)


by Loc ROBERT
DESCRIPTION_CURSUS
Discovery of Java language

http://www.supinfo.com

PREFACE
Learn how to develop applications with Java

Using Eclipse IDE in an JSE programing environment

Prepare yourself for the SCJP certification


Java is a programation languague which has built its reputation in the field of application development. The
course covers the basics of Java language by studying each parts of JSE (Java Standard Edition),such as objectoriented
programming,
management
of
exception,
design,
etc..

iii
http://www.supinfo.com

Chapter 1. Introduction to Java


Programming
This chapter will describe :

History of the Java programing language

Overview of Java Platform

Glossary of main Java concepts

1. Course
1.1. Introduction

In this part we will present you the Java history in a way that you understand :

why, how and by who it as been created

4
http://www.supinfo.com

which are the main improvement features from one version to another (giving you an easy-look time
guideline for features).

which are the policies used to add new features inside or around the Java Platform

what is making the strength of Java

An overview of the main features

1.1.1. History
Java (which means coffee in slang English) was created in the 90's by Sun Microsystems Incorporation. The
Java platform and language began as an internal project of Sun Microsystems in the end of 1990. Computer
engineer Patrick Naughton frustrated by Sun C and C++ API and tools decided to create an alternative to them.
The Stealth Project was borned, soon renamed as Green Project while Mike Sheridan and James Gosling (the
main Java architect) joining Naughton. After a lot of brainstorming they decided to make a language close from
cpp (which means close syntax from cpp and Object Oriented Programming support) but with main differences :
memory had not to be managed any more by the programmer but automatically by a garbage collector, the
portability, the threading had to be easier and it had to provide a improvement in secure computing, there is also
not multiple inheritance. Finally in the end of 1992 they presented a new platform including the Green OS, the
Oak language, the libraries and the hardware. The concrete implementation was building on a PDA named Star7
which had a GUI and a smart agent called "Duke" to assist the user which will become later the Java mascot.
However the platform failed to interest the other companies. In the 1994 year, they decided to re-targeted the
platform for the World Wide Web, and rename the Oak language, Java and the platform became Java platform.
In 1995 Sun made the first released of Java and Hot Java (a Sun web browser) which it main aim was to develop
some portable applets. They also announced that the Netscape browser (at this time it was the main Internet
browser) would be including Java support. In January 1996 the JavaSoft group was formed by Sun
Microsystems in order to develop the technology. Since this year there was a lot of new versions of the Java
Platform which added a lot of new features as we will see forward in the Java versions part. Since J2SE 1.4 the
evolution of Java is made by the Java Community Process (JPC created in 1998) which work is looking for all
the Java Specification Request (JSR) and vote which can been added to the Java Environment (Java language,
Java Platform, and all which is officially linked to them).

1.1.2. Java Versions


Since its creation, Java language has evolved considerably. It has improved with years. Here are the principal
steps of its evolution (don't scary if some features means nothing for you at this time, you will be able to use this
time-line guide latter as a quick easy look to understand versions improvements and changes, when you will
have see a lot of the forward listed features) :

JDK 1.0 alias "Oak" :

250 classes

slow

fun to use

lots of bugs

use to make applets.

5
http://www.supinfo.com

JDK 1.1 alias "Sparkler" :

Java Beans

500 classes

little faster

much more convenient

much more used

easy code for GUI (Graphic User Interface)

inner class

JDBC

RMI

Java 2 : Sun decided to change the change the codename for any Java Platform in Java 2 (from J2SE 1.2 to
1.5 and J2EE 1.2 to J2EE 1.5) and the version name in J2SE (Java 2 Standard Edition) replace JDK version
name in order to distinguish it with the new J2EE Platform (Java Enterprise Edition) and the new J2ME
Platform (Java Mobile Edition)

J2SE 1.2 alias "Playground" and "Merlin" :

Collections framework

2300 classes

Faster and powerful

Can be used in native execution

strictfp Java Keyword

Swing GUI API integrated in the core classes

Sun's JVM provides a JIT (Just in Time) compiler for the first time

6
http://www.supinfo.com

Java IDL, an IDL implementation for Corba interoperability

J2EE 1.2 :

Enterprise Java Beans (EJB), version 1.1

JavaServer Pages (JSP), version 1.1

Java Servlet, version 2.2

JDBC API, version 2.0

Java Naming and Directory Interface (JNDI), version 1.2

Java Message Service (JMS), version 1.0

Java Transaction API (JTA), version 1.0

Java Transaction Service (JTS), version 0.95

JavaMail API, version 1.1

JavaBeans Activation Framework (JAF), version 1.0

J2SE 1.3 :

RMI modified to support optional compatibility with CORBA

Java Naming and Director Interface (JNDI) included in core libraries

Java Platform Debugger Architecture (JDPA)

J2EE 1.3 :

Enterprise Java Beans (EJB), version 2.0

JavaServer Pages (JSP), version 1.2

Java Servlet, version 2.3


7
http://www.supinfo.com

JDBC API, version 2.1

Java Naming and Directory Interface (JNDI), version 1.2

Java Message Service (JMS), version 1.0

Java Transaction API (JTA), version 1.0

Java Transaction Service (JTS), version 1.0

JavaMail API, version 1.1

JavaBeans Activation Framework (JAF), version 1.0

J2EE Connector Architecture, version 1.0

Java API for XML Processing (JAXP), version 1.0

Java Authentication and Authorization Service (JAAS), version 1.0

J2SE 1.4. First release of the Java Platform under the Java Community Process :

assert Java Keyword

regular expressions

exception chaining allows an exception to encapsulate original lower-level exception

IPv6 support

non-blocking NIO (New Input/Output)

logging API

image I/O API for reading and writing images in format like JPEG and PNG

integrated XML parser and XSLT processor (JAXP)

integrated security and cryptography extensions (JCE, JSSE, JAAS)


8
http://www.supinfo.com

J2EE 1.4 :

Java 2 Platform, Enterprise Deployment Specification, version 1.0

Enterprise Java Beans (EJB), version 2.1

JavaServer Pages (JSP), version 2.0

Java Servlet, version 2.4

JDBC API, version 3.0

Java Naming and Directory Interface (JNDI), version 1.2

Java Message Service (JMS), version 1.1

Java Transaction API (JTA), version 1.0

Java Transaction Service (JTS), version 1.0

JavaMail API, version 1.2

JavaBeans Activation Framework (JAF), version 1.0

J2EE Connector Architecture, version 1.5

Java API for XML Processing (JAXP), version 1.2

Java Authentication and Authorization Service (JAAS), version 1.0

Java Authorization Service Provider Contract for Containers (JACC), version 1.0

Web Services for J2EE, version 1.0

Java API for XML-based RPC (JAX-RPC), version 1.0

Java API for XML Registries (JAXR), version 1.0

Java Management Extensions (JMX), version 1.1


9
http://www.supinfo.com

Java 2 Platform, Enterprise Edition Management Specification, version 1.0

J2SE 5.0 alias "Tiger" :

3500 classes

Faster, easier and powerful to developer

Generics : provide compile-time type safety for collections and eliminates the need for most typecasts

Annotations : allows language constructs such as classes and methods to be tagged with additional data,
which can then be processed by meta data-aware utilities.

Autoboxing/unboxing : Automatic conversions between primitive types (such as int) and primitive wrapper
classes

Enumerations: The enum keyword creates a type safe, ordered list of values (such as Day.MONDAY,
Day.TUESDAY, etc.).

Swing: New skinnable look and feel, called synth.

Varargs

Enhanced for loop

Automatic stub generation for RMI objects.

static import

J2EE 1.5 :

Java Persistence API (JPA), version 1.0

JavaServer Pages (JSP), version 2.1

Java Servlet, version 2.5

JavaServer Faces (JSF), version 1.2

JavaServer Pages Standard Tag Library (JSTL), version 1.2

10
http://www.supinfo.com

JDBC API, version 3.0

Java Naming and Directory Interface (JNDI), version 1.2

Java Message Service (JMS), version 1.1

Java Transaction API (JTA), version 1.0

Java Transaction Service (JTS), version 1.0

JavaMail API, version 1.4

JavaBeans Activation Framework (JAF), version 1.1

J2EE Connector Architecture, version 1.5

Java API for XML Processing (JAXP), version 1.3

Java Authentication and Authorization Service (JAAS), version 1.0

Java Authorization Service Provider Contract for Containers (JACC), version 1.1

Web Services for J2EE, version 1.2

Java API for XML-based RPC (JAX-RPC), version 1.1

Java API for XML Registries (JAXR), version 1.0

Java Management Extensions (JMX), version 1.2

Java 2 Platform, Enterprise Edition Management Specification, version 1.1

Java 2 Platform, Enterprise Deployment Specification, version 1.1

Java API for XML-based Web Services (JAX-WS), version 2.0

Java Architecture for XML Binding (JAXB), version 2.0

SOAP with Attachment API for Java (SAAJ), version 1.3


11
http://www.supinfo.com

Web Services Metadata for the Java Platform, version 2.0

Streaming API for XML (StAX), version 1.0

Enterprise Java Beans (EJB), version 3.0

Java SE 6 alias "Tiger" :

over 4000 class

about 30% faster

Improved Web Service support through JAX-WS

Dramatic performance improvements for the core platform and Swing

JDBC 4.0 support

Upgrade of JAXB to version 2.0

1.1.3. Advantages
Here are the main stengths of the Java programming language

Mobile :

Java language can be executed on any platform, Indeed it is semi compiled and semi interpreted.

Java code source is compiled into simple binary instructions : bytecode. Then the bytecode is interpreted
by the Java Virtual Machine into binary code adapted to the implementation.
The JVM (Java Virtual Machine) is free and available on the Suns web site, for any platform (UNIX,
Windows, Mac).

(Byte Code = Instructions generated by the compiler that an abstract computer can execute). So Bytecode
is independent of the environment where it is executed.
Primitives type size is independent of the platform.

Java supports source code written in Unicode.

12
http://www.supinfo.com

Easy developing :

syntax close from c and cpp

No compilation guideline like "#define", "typedef ", and no need for files headers, because Java permits the
definition of other classes and their methods.

No pointers

No multiple inheritances

No overloading of operators

Garbage collecting is managing memory allocation and deallocation

Javadoc is a rich standardized documentation

Java provides a lot of core libraries, to create easily network, multi thread, I/O, GUI

The developer don't need to be scared about the mobility

The developer benefit from a management system for exceptions which provides easily highest security

Robust and Sure :

No pointers

Memory is managed by Garbage Collector (Collects Crumbs) that allows you to have a better security
solving problems of allowances and explicit liberation of memory.

An exception management system was implemented. Treatment of lot of casual exceptions is obligatory.

Very strict compiler which provides for example good initialization for values, strict typing, ...

Object Oriented Programming language :

Quite almost is object in Java, Java is conceived to implement OOP applications, and to do OOP. You can't
do non object oriented application like in cpp

You can do encapsulation OOP concept

13
http://www.supinfo.com

You can do inheritance OOP concept (and in some way specify a contract for multiple inheritance through
interfaces)

You can do polymorphisms OOP concept

You can do overloading OOP concept

You can do composition OOP concept

So a Java application well designed can benefit from all the power of OOP : exentability, scale ability,
group development

1.1.4. Main features


Everything is Object :
In Java everything is an object, except the following Primary types : boolean, byte, char, short, int, long, float,
double but they also have their equivalent as object called wrappers class

All classes inherit from the java.lang.Object class :


which means all classes can benefit from it almost protected methods.

Multiple inheritances does not exist in Java, but we can implement multiple interfaces :
abstract class where all methods are abstract and public and that must be override in the class that implements
the interface.

Everything is passed by value in Java :

for the primitives the identifier contains the primitive value, and a copy of this value is passed throw the
method (so you can't modify directly a primitive value inside the scope of the method)

for the objects the identifier contains the value of the reference to the object, and this reference is passed
throw the method (so you can modify directly the object in the scope of the method)

The syntax and the semantics of the Java language are very close to those used in C++

Semi compiled and semi interpreted language :

The Java language is first compiled in an intermediate code, the bytecode (a language which can be
interpreted by any JVM), before being interpreted by a JVM , which translate it into a binary executable
code.

You have to understand that the bytecode is not supposed to be execute directly on any system, it only
14
http://www.supinfo.com

represent a code (of low level) which can be interpreted by any Java Virtual Machine. And the JVM is
making the interpretation of this bytecode to the specific concrete binary code of the implementation on
which it is installed. So if you think of the JVM as a layer it is always waiting for a bytecode input and
have to interpret it into an adapted binary output code. The bytecode is universal, any JVM is waiting for
bytecode as input, but each JVM provides a special adapted binary output code.

In a way bytecode provides a contract between Java source code and every JVM

In a way JVM provides a contract between bytecode and a specific implementation

Memory management is automated by the "Garbage Collector" :


The allowance as well as the liberation of memory is a mechanism which developers dont have to worry
about, contrary to the C or CPP developer

Exceptions implemented in Java prevent various errors that appear in the execution of the program (Division
by zero).

The creation of multi task applications and their synchronizations can be easily implemented in Java with the
help of Threads.

is also network oriented :

with the simple creation of sockets.

more powerful it aims distributed applications with RMI/IIOP or JAVA/CORBA

the packages naming should respect the reverse of the Domain Name System (DNS), so everyone which
have a domain name could easily and safely isolate it own package

with the creation of applets

with the creation of servlets, JSP


... and a lot of other features you will discover later.

1.2. Java Platforms


1.2.1. Java SE Platform
This platform of Java, also known under the name of platforms Java 2, makes it possible to develop and deploy
applications on microcomputers. One finds there functionalities like the graphic interfaces, the management of
the network, the management of the processes, etc.

15
http://www.supinfo.com

Overview of the Java SE 1.6 platform

JRE (Java Runtime Environment) :


JRE (Java Runtime Environment) is the container of the environment of Java execution that must be installed
on all machines to launch Java applications.

JDK (Java Development Kit) :


javadoc: Its a very powerful tool that constructs, from the commentaries inserted in Java sources, of the
files HTML about the classes, methods, and data members... define in these sources.

JDK (Java Development Kit) contains the JRE. It is an indispensable environment to create Java programs.
It includes a compiler, an interpreter, and an environment which contains development tools used for
programming.

javac: Java compiler. It translates a file source (.java file) in an executable (.class file).

java: Executes file or files compiled by javac. It is Java interpreter that means an implementation of the
Java virtual machine (JVM).

Java to interpret: "light" version of the Java interpreter that executes a program compiled by Javac without
having to install the JDK.
AppletViewer: This program executes an Applet Java without having to use a web navigator. Its a graphic
interface.

16
http://www.supinfo.com

Jdb: Java debugger detects programming errors.

1.2.2. Java EE Platform


The platform Java EE is the industrial standard for all server side applications. It is built on the solid bases of
java SE.

Above a first example of Java EE application :

Above a second example of Java EE application :

17
http://www.supinfo.com

Above a third example of Java EE application


As a first look you see some redundant things for Java EE application :

the application use multiple layouts

portability as for J2SE application

can work with thin (Web Browser) , heavy (SWING) or handled device (J2ME) client

the use of a Java EE server

concepts of : persistence, business logic, presentation, connector.

18
http://www.supinfo.com

technologies : EJB, Servlet, JSP, JMS, JavaMail, ...

1.2.3. Java ME Platform


This platform is omnipresent for the mobile devices. It provides a robust and flexible environment for portable
telephones, PDAs, remote controls, and printers. Java ME includes flexible user interfaces, a robust model of
safety, a broad range of the protocols of integrated networks, and applications managed in network and remote
which can be downloaded dynamically. The great advantage of ME, it is that all its applications are portable
through a vast range of device (the platform is deployed on billion devices).

Overview of the Java Micro Edition Platform :

Overview of the Connected Limited Device Configuration for small devices :

19
http://www.supinfo.com

Overview of the Connected Device Configuration for More Capable Devices and smart phones:

1.2.4. Eclipse IDE


Eclipse is an open source software framework written primarily in Java. In its default form it is a Java IDE,
consisting of the Java Development Tools (JDT) and compiler (ECJ). Users can extend its capabilities by
installing plugins written for the Eclipse software framework, such as development toolkits for other
programming languages, and can write and contribute their own plugin modules.

History :
Eclipse began as an IBM Canada project. It was developed by OTI (Object Technology International) as a
replacement for VisualAge, which itself had been developed by OTI. In November 2001, a consortium was
formed to further the development of Eclipse as open source. In 2003, the Eclipse Foundation was created.
Eclipse 3.0 (released in 2004) selected the OSGi Service Platform specifications as the runtime architecture.
Eclipse was originally released under the Common Public License, but was later relicensed under the Eclipse
Public License. The Free Software Foundation has said that both licenses are free software licenses, but are
incompatible with the GNU General Public License (GPL). Mike Milinkovich, of the Eclipse Foundation has
commented that moving to the GPL will be considered when version 3 of the GPL is released.

Get Eclipse :
You can get eclipse at http://www.eclipse.org/downloads/

1.2.5. Netbeans IDE


NetBeans refers to both a platform for the development of Java desktop applications, and an integrated
development environment (IDE) developed using the NetBeans Platform. The NetBeans Platform allows
applications to be developed from a set of modular software components called modules. A module is a Java
archive file that contains Java classes written to interact with the NetBeans Open APIs and a manifest file that
identifies it as a module. Applications built on modules can be extended by adding new modules. Since modules
can be developed independently, applications based on the NetBeans platform can be easily and powerfully
extended by third party developers.

History
NetBeans began in 1997 as Xelfi, a student project under the guidance of the Faculty of Mathematics and
Physics at Charles University in Prague. A company was later formed around the project and produced
commercial versions of the NetBeans IDE until it was bought by Sun Microsystems in 1999. Sun open source
the NetBeans IDE in June of the following year. The NetBeans community has since continued to grow,
thanks to individuals and companies using and contributing to the project.

Get Netbeans :
You can get NetBeans at http://www.netbeans.info/downloads/index.php

1.2.6. Duke
Duke is the mascot of the Java programming language. When Sun announced that Java SE and Java ME would
be released under a free software license (the GNU General Public License), they released the Duke graphics
under the free BSD license at the same time. If you want more information about Duke you can go at :
http://www.java.com/en/dukeszone/

1.3. Glossary
API Application programmers interface :
20
http://www.supinfo.com

This term refers to a set of related classes and methods that work together to provide a particular capability.
The API represents the parts of a class that are exposed (through access controls) to code written by others.

Class :
A class is the definition of a type. It is the blueprint used to construct objects of that type.

Encapsulation :
Encapsulation is the process of grouping methods and data together and hiding them behind a public
interface. A class demonstrates good encapsulation by protecting variables with private or protected access,
while providing more publicly accessible setter and/or getter methods.

Exception :
Exception has two common meanings in Java. First, an Exception is an object type. Second, an exception is
shorthand for exceptional condition, which is an occurrence that alters the normal flow of an application.

Extensibility :
Extensibility is a term that describes a design or code that can easily be enhanced without being rewritten.

Garbage collection :
The process by which memory allocated to an object that is no longer reachable from a live thread is
reclaimed by the Java VM.

Identifiers :
Identifiers are names that we assign to classes, methods, and variables.

Java Virtual Machine (JVM) :


A program that interprets and executes Java bytecode (in most cases, the bytecode that was generated by a
Java compiler). The Java VM provides a variety of resources to the applications it is executing, including
memory management, network access, hardware abstraction, and so on. Because it provides a consistent
environment for Java applications to run in, the Java VM is the heart of the write once run anywhere
strategy that has made Java so popular.

Java source file :


A file that contains computer instructions written in the Java programming language. A Java source file must
meet strict requirements; otherwise, the Java compiler will generate errors. Source files must end with a .java
extension, and there may be only one public class per source code file.

javac :
Javac is the name of the java compiler program. This Java compiler processes the source file to produce a
bytecode
file.

21
http://www.supinfo.com

Chapter 2. Syntax
At the end of this module, you will :

Know the syntax of the language

Know the keywords

Write a simple application

1. Course
Java is a programming language developed in the early 90s. It is inspired by the C language syntax, but some
aspects have been simplified (automatic memory management).
The foundations we are going to see allowed you to understand what makes the wealth of Java:

its object orientation (see the classes course)

the numerous libraries (Java Mobile Edition, Java Enterprise Edition, etc.).
We are going to see how to compile and execute a java program, the different variable types, methods,
instructions (if, switch, for, etc), operators (+, , /, *, <, etc), arrays, and we will finish with some specificities of
the java platform.

1.1. Compilation and execution


1.1.1. Reminder
As you know it, computers cannot understand source code you write. Before the processor of the computer can
execute your instructions, they must be translated into machine language that is under binary shape. In certain
programming languages as C or C ++, a compiler translates the source code into machine language, this
compiled code is called feasible code.
However, in Java, the compiler translates the source code (.java ) into bytecode (.class ) which is not a feasible
code. The bytecode is situated between the source code and the feasible code. This last one is interpreted by the
Java Virtual Machine (JVM) when you execute the program.
Java allows us to be independent in front of the platform by introducing the principle of virtual machine. If you
want to execute your application on a new platform, you only have to have a JVM for this platform.
Here is a schema of the cycle of development of an application Java:

22
Created by XMLmind

XSL-FO Converter.

1.1.2. Compilation of a Java program


First of all, you have to create a file which contains the source code of your program. Then you must use the
javac compiler via the command line interface to produce a file containing the bytecode.
Example:
This is an example of source file, MyFirstJavaProgram.java: This program displays This is my first Java
program!!! on the screen.
[CODE:java]
public class MyFirstJavaProgram{
public static void main(String[] args){
System.out.println("This is my first Java program!!!");
System.exit(0);
}
}

Open a command line interface and go to the folder which contains your source file then, execute the following
command:
[CODE:java]
javac MyFirstJavaProgram.java

If your source file doesnt contain syntax errors, you will see a new file named MyFirstJavaProgram.class, if
this file doesnt appear, the errors held by file will be displayed in the command line interface.

1.1.3. Execution of a Java program


Once your program compiled, you want to execute it. Open a command line interface et go to the folder which
contains your class file then, execute the following command:
[CODE:java]
java MyFirstJavaProgram

Your program is launched.


23
Created by XMLmind

XSL-FO Converter.

1.2. Data Types


In programming, we will have to use some variables in order to handle and to store some important data of our
program. We can imagine a variable as a symbol which represents a value stored in memory; this is not the
value itself. In other words, the represented value by the variable can be modified anytime and thats why its
called variable.
With the Java language, variables will have a defined type, in opposition to PHP for example, where variables
can store any data type. When you specify the data type you can reduce the amount of data in memory. We can
find two families of data type in Java:

Primitive types: simple values with functions integrated into the system (constant, numerical expression). The
allocated memory contains the associated value with the identifier.

Reference types: The data is passed thanks to their reference. These are the types of classes. They include
arrays and objects. The allocated memory for the identifier contains a hexadecimal representing the memory
address of the object.

1.2.1. Primitive types


Java supports primitive data types, such as int to represents integers, float to represent decimal values, and so
on.
All primitive data types are written lower case.
The Java programming language has the following primitive types:

We can see that except boolean and char types, all data types in Java are signed.
1.2.1.1. Integers
When a digital type is used as part of an assignment, it may be extended to a larger type. On the other hand a
numerical value can never be assigned to a lower type without conversion.
[CODE:java]
short x = 2;
int i = x;
[CODE:java]
int i = 2;
short x = (short)i;

24
Created by XMLmind

XSL-FO Converter.

In this second case, the conversion avoids an error at compilation time, this conversion is called the casting.
1.2.1.2. Characters
Specifying a value of type character framed by simple quotes ( 'a'), the escaped character (\), or a Unicode
character number with a hexadecimal format \ uXXXX.
[CODE:java]
char x = 'x'; // x
char x = '\''; //
char x = '\u004A'; // j

1.2.1.3. Floating numbers


They are always from type double unless they are followed by the letter 'f' or 'F' which indicates the float type.
[CODE:java]
double x = 5.23;
float y = 5.125F;

1.2.2. Reference types (Classes)


By convention, the names of classes have both upper and lower case letters, the first letter of each word is
written in capital letters.
1.2.2.1. The classes provided by the Java environment
For an overview of these classes, for example, you can refer to the documentation on the Java package
java.lang, and the documentation provided with your IDE (Integrated Development Environment) Java (eg:
Eclipse, Netbeans, and so on.). The documentation for Java is located at the following address:
http://java.sun.com/javase/6/docs/. Notice that the standard version (Java SE) contains several thousand
of classes, and this number has grown steadily since the early versions.
1.2.2.2. Data types defined by user
With Java, users often need to define one or more new types of data. It can be done via the keyword class. For
example, to create a program that behaves like a person, you can define a class that represents a person:
[CODE:java]
class Person
{
public void sayHello()
{
System.out.println("Hello !");
}
}

This type of userdefined data starts with the keyword class, followed by the name for the type of data, in this
case Person; followed by a string of properties and methods between the opening and closing braces. This
simple example provides only a single behavior, represented by the method sayHello().
1.2.2.3. Wrappers
We saw that there were primitive types in Java. But it is sometimes useful "encapsulating" his primitive types
for instance to pass them by reference. Java has therefore scheduled classes say "wrapper with these primitives.
Here is a synopsis of wrappers available and their relationship with the primitive types:

25
Created by XMLmind

XSL-FO Converter.

If you wish to parse a string to an integer for instance you will need to use the wrapper: Integer. These wrappers
have also many utilities, thanks to their many methods.
Example:
[CODE:java]
int entier = Integer.parse("10");

1.2.3. Manipulation of a property


1.2.3.1. Defining a property
To set a property, you must specify the data type and an identifier, and optionally, an initial value:
[CODE:java]
<datatype> <variable>;
<datatype> <variable1>, <variable2>, ..., <variablen>;
<datatype> <variable> = <value>;

Examples:
[CODE:java]
// primitive properties
int x;
int x = 6;
boolean fini = false;
// property by reference
String person = new String();

The identifier (handler) is the name we chose to call a variable. These identifiers must begin with a Unicode
letter, an underscore "_" or a dollar sign "$".
It is not possible to re-use as an identifier keyword language, which are listed below:

26
Created by XMLmind

XSL-FO Converter.

1.2.3.2. Instances of classes


Consider the following program:
[CODE:java]
public class MyFirstJavaProgram
{
public static void main(String[] args){
String myString = new String("Hello");
System.out.println(myString);
System.exit(0);
}
}

The main() method creates an instance of String called myString (case is important in Java).
In Java, as in other languages, a program allocates objects dynamically. The operator of memory allocation is
new:
[CODE:java]
new <datatype>(<arguments>...);
<datatype> <variable> = new <datatype>(<arguments>...);

The new operator asks the execution environment to create an instance of a data type defined by the user, for
27
Created by XMLmind

XSL-FO Converter.

example, new String(), and we do the same with most of the classes (there are some exceptions).
1.2.3.3. Assigning a variable
An assignment operation can occur in the following contexts:
[CODE:java]
<datatype> <variable> = <value>;
<datatype> <variable>;
<otherinstructions>...
<variable> = <value>;

Examples :
[CODE:java]
int x = 12;
x = 17;
double rate = 3.5;
String pers = new String();

1.2.3.4. Instance variables


Suppose you add a variable to reflect instituting a unique way to greet a person: an instance of string can
represent each greeting to a person:
[CODE:java]
class Person
{
int age;
String greeting = new String("Hello !");
void sayHello()
{
System.out.println(greeting);
}
}

The definition of Person now includes the instance variable greeting. In fact, every time a new instance of
person is created, this instance will include a variable reference to an instance of String representing this unique
way of greeting. This instance variable is initialized to the default value "Hello!".
In the case of instance variable "age'" if there is no explicit initialization, the Java Runtime Environment
automatically initializes the variable to zero or equivalent. This table summarizes the default type value
depending on the type of data:

1.2.3.5. Conclusion

28
Created by XMLmind

XSL-FO Converter.

Here are two patterns that will help you remember the difference between primitive type and reference type
inside memory:

The primitive types are stored on the stack so that the references are stored on the heap.

1.3. Methods
A method is the object-oriented equivalent of a function in procedural languages. This means that a method is a
bit of a program that provides the mechanism (method) for doing an act.

29
Created by XMLmind

XSL-FO Converter.

Using methods offers several advantages, a method can be executed (called) several times at different places in
the program. Without method, you would have to repeat your code, which increases the size of your program
and the risk of errors. Moreover, the methods allow easy maintenance, because if you need to make a change to
your code, you will only have to do so in your method.

1.3.1. Definition (declaration) of a method


A method is a block of code that executes a process on the data. A method consists of the following elements:

A name : The name and identifies the method and is used to call the method. The rules for naming a method
are identical to those for identifiers variable (see Chapter 3).

Parameter(s) : A method can have zero, one or more parameters defined in parentheses immediately after the
name of the method.

Argument(s) : The value of parameter passed during the call of the method are called arguments and
correspond to the parameters specified in the statement of the method.

Return type : A method can optionally return a value. The returned type(eg int) is declared in the declaration
of the method.

Access modifiers : Each method has an access modifier, as public or private, which determines the
accessibility of the method.
To declare a method:
[CODE:java]
<accessmodifier> <return-type> <name-of-the-method>(<parameter>...)
{
<instructions>...
}

1.3.1.1. Method without return type


[CODE:java]
public void sayHello()
{
System.out.println("Hello");
}

In this case, the method sayHello () must be called from the instance of a class. You can use the keyword static
so that the method is accessible directly from the class (see the method public static void main (String [] args),
you can find more details at the end of this chapter). Notice that the keyword void shows that the method returns
no value.
1.3.1.2. Method with return type
[CODE:java]
public int square(int number)
{
return number * number ;
}

Instead using the void return type, square(int number) provides a return type, in this case, int. The method must
provide a return instruction to return a value. In this example the square method returns the square of the
number passed as a parameter.
A return instruction has the following syntax :
[CODE:java]

30
Created by XMLmind

XSL-FO Converter.

return <value>;

... where <value> is an expression from the correct type , int in the case of the square method.

1.3.2. Calling a method


For a given instance of a class, the syntax of invocation of a method is :
[CODE:java]
<instance>.<method>();
<proprit> = <instance>.<method>(<arguments>...);

If you want a person to greet someone, use the following syntax:


[CODE:java]
Person olivier = new Person() ;
olivier.sayHello();

1.3.3. Overloading
Historically, the combination of the name of the method, its return type and the list of its arguments is called the
signature of the method. With modern objectoriented languages, a class can be defined several ways with the
same name, as long as they are distinguishable by their signatures (number and types of parameters). This
practice is called overloading a method. However, in the Java programming language, the type of return does
not contribute to the signature of the method, and thus, having two methods with the same names and
arguments, but with different types of return is not possible.
[CODE:java]
void sayHello(){
sayHello("Hello");
}
void sayHello(String greeting){
System.out.println(greeting);
}

In this example, we have two methods called sayHello returning no value (void), one does not accept
parameters, and the other accepts a parameter of type String.

1.3.4. Static methods


The static methods are shared by all instances of a class, they are declared in the class using the keyword static.
They can access only static members of the class. Such methods can be called before a instance of the class is
created. For example, each program has a main () method which is executed without even instantiate the class in
which it is written. We will return to the main () method further in the course.
Example:
Example of how to declare a static method, called sayHello which belongs to a class Person.
[CODE:java]
static void sayHello(String message){
System.out.println(message);
}

Example of how to use a static method :


[CODE:java]
Person.sayHello("Hello");

As you can see, there is no instantiate object of the Person class; however, we can access to the method named
sayHello(String).

1.3.5. Getters and Setters


The value of an instance variable varies over time, you need to allow a method to change this value. Such an
approach is called an access method. By convention, it starts with the word set:
31
Created by XMLmind

XSL-FO Converter.

[CODE:java]
...
String greeting;
void setGreeting(String greeting)
{
this.greeting = greeting;
}
...

Sometimes it is necessary to get the value of an instance variable. For each set methods, you should have a get
method:.
[CODE:java]
...
String getGreeting(){
return greeting;
}
...

Note that in the case of instituting Boolean variables such as nice, some programmers prefer the naming
convention with the style is to get more style, and others choose to provide both:
[CODE:java]
...
boolean nice;
boolean isNice()
{
return nice;
}
...

1.4. Instructions
1.4.1. Simple instructions
The simple instructions always end with a semicolon:
[CODE:java]
float weight; // declaration of a variable
int length = 10; // declaration and initialization
Not

Note that the variable is limited to the block of instructions (multiple instructions grouped between brackets).
See the Classes course.

1.4.2. Conditionnal expressions


In the preceding paragraphs, each method was running only in a sequential manner, carrying out an instruction
after another. Like other languages, the Java programming language allows the execution of conditional
instructions.
1.4.2.1. If instruction
Generally, if has the following syntax:
[CODE:java]
if (<boolean-expression>)
<instructions>...

... where <Boolean-expression> is any expression which is checked as a boolean value (true / false), and
<instructions> ...
An instruction can be single or multiple grouped between brackets (code block). If the boolean expression is
evaluated to true, the instruction (or block of instructions) following the if clause is executed.
Java also supports optional clause else. The syntax is:

32
Created by XMLmind

XSL-FO Converter.

[CODE:java]
if (<Booleanexpression>)
<instructions>...
else
<instructions>...

If the Boolean expression is evaluated to true, the instruction (or block of instructions) following the if clause is
executed. Otherwise, the instruction (or block of instructions) after the else clause is executed.
Example:
[CODE:java]
boolean x = true ;
if(x == true){
System.out.println("x == true") ;
}

In the previous code, the string "x == true" is displayed in the console.
1.4.2.2. Switch instruction
The operator switch has the following syntax:
[CODE:java]
switch (<variable>)
{
case (<value>) : <instructions>...
break;
case (<value>) : <instructions>...
break;
...
default : <instructions>...
}

This instruction will only work with primitive types. The default option is launched when there is no matching
possibility.
Example:
[CODE:java]
int i = 5;
switch(i){
case(1):{
System.out.println(1);
break;
}
case(5):{
System.out.println(5);
break;
}
case(6):{
System.out.println(6);
break;
}
default:{
System.out.println("default");
break;
}
}

This example prints 5 in the console. If we had remove the break keyword, it would have print 5 6 default.

1.4.3. The iterative expressions


1.4.3.1. The while loop
The syntax of the while loop is:
[CODE:java]

33
Created by XMLmind

XSL-FO Converter.

while (<booleanexpression>)
<instructions>...

The condition (boolean expression) is first evaluated. If it is true, the instructions are then executed, and repeat
until the condition becomes false.
Example:
[CODE:java]
int i=0;
while(i<5){
System.out.println("i=" + i);
i = i + 1;
}

The following lines are printed in the console:


[CODE:java]
i=0
i=1
i=2
i=3
i=4

1.4.3.2. The do while loop


The syntax of the do while loop is:
[CODE:java]
do
<instructions>...
while (<Booleanexpression>)

First, the instructions are executed, then the (boolean expression) is evaluated. If it is true, instructions are
executed again, and repeat until the condition becomes false.
Warning ! Instructions are always executed at least once in a do while loop.
Example:
[CODE:java]
int i=0;
do{
System.out.println("i=" + i);
i = i + 1;
}while(i<5)

The following lines are printed:


[CODE:java]
i=0
i=1
i=2
i=3
i=4

1.4.3.3. The for loop


The syntax of the for loop is:
[CODE:java]
for (<initializations>; <conditiontostop>; <incrementation>)
<instructions>...

The for loop is composed of 3 instructions separated by semicolons. The first component <initializations> is one
or more initialization delimited by comas. The second component is the condition for stopping the loop. The
third component is one or more expressions delimited by comas, executed after each iteration.
Ex ample :
34
Created by XMLmind

XSL-FO Converter.

[CODE:java]
for (int i=0; i<10; i++)
{
System.out.println(i);
}

Prints numbers from 0 to 9.


To make an infinite loop, simply omit the expressions, as follows:
[CODE:java]
for (;;)
<instructions>...

1.4.3.4. Another use of the for loop


Since version 1.5, there is a new syntax for the for loop:
[CODE:java]
for (<type> <variable> : <arrayorcollection>)
<instructions>...

For each variable <type> in <array-or-collection>, instructions are executed.


This instruction is called foreach.

1.5. Operators
In the previous chapter we saw that the variables are used to store data. However, in a computer program you
will be forced to change the value of a variable, for example, adding two data and store the result in another
variable. The variables on which we conduct operations are called operands.
For example in the instruction below, the variable x and y are operands and the equal sign is an operator:
[CODE:java]
x = y;

The execution of this line assigns the value of y to x.


Operators allow, in general, to manipulate the value of properties. They are classified into several distinct
categories: assignment, arithmetic, logical, comparison.

1.5.1. Assigning operators

Thanks to the equal sign, we can store the value of the right in the left. This operator provides a value to a
variable.
Operators +=, =, *= et /= are syntactic shortcuts.
Example :
[CODE:java]

35
Created by XMLmind

XSL-FO Converter.

x = x + 5;
//You can write it in terms of a shortcut operator
x += 5;

1.5.2. Arithmetic operators


In mathematics, we are all familiar with the arithmetic operators which allow us to carry out operations on the
operands. The arithmetic operators supported by the Java language are grouped in the following table:

1.5.2.1. Addition, substraction, multiplication, division and priority


Use them the same way as in mathematics:
[CODE:java]
x = 4 + 5 * 3; // x = 4 + 15 ; x = 19

1.5.2.2. Increment and decrement


Operators ++ and can be used two different ways:
[CODE:java]
int x;
int y;
x = 5;
y = x++;
//Now, y = 5 and x = 6
y = ++x;
//Now, y = 7 and x = 7

Indeed when the operator ++ or is placed before the operand, the increment is treated first. However, when the
operator ++ or is placed after the operand, the increment is treated as a second step.
1.5.2.3. Modulo
The % operator allows to get the rest of a division, for example :
[CODE:java]
x = 15 % 4 ; //x = 3
x = -11 % 3 ; //x = 2

We can notice that the result of modulo always carry the sign of the first operand.

1.5.3. Bitwise operators


These operators are used to test and arrange followspecific bits. A bitwise operator interprets its operands as an
ordered collection of bits, where each bit can contain either the value 0 or the value 1. These operators are
summarized in the following table:

36
Created by XMLmind

XSL-FO Converter.

It is rare to use them.


1.5.3.1. AND
Table truth of the & operator:

Example : Use the AND operator on the numbers 117 and 89:
We write 117 and 89 in binary, we obtain:

1.5.3.2. OR

37
Created by XMLmind

XSL-FO Converter.

Example : Using the previous example this time using XOR operator:
We write 117 and 89 in binary, we obtain:

1.5.3.3. NOT
Using ~ can reverse the bit, a bit to 1 changes to 0, and vice versa.
[CODE:java]
byte x = 4 ; //x = 0000 0100
byte y = ~x ; //y = 1111 1011

1.5.4. The logical operators


The logical operators acting on their Boolean level, truth tables are identical to those on the "Bitwise Operators

With versions "shortcircuit" as soon as a sub expression is estimated to be false (in the case of & &) or true (in
the case of | |), the assessment of sub expressions following is dropped.
[CODE:java]
true && false ; //return false
false || true, //return true

1.5.5. Relational operators


A relational operator, also called a comparison operator, compare the values of two operands and return a
Boolean value (true or false). Different operators are listed in the table below:

38
Created by XMLmind

XSL-FO Converter.

Warning! There is a difference between compare primitive types and compare two objects, as regards equality.
Example:
Consider a version of Person who has only an age:
[CODE:java]
class Person{
int age;
public void setAge(int a){
age = a;
}
public static void main(String[] args){
Person p1 = new Person();
p1.setAge(31);
Person p2 = new Person();
p2.setAge(31);
if (p1 == p2)
System.out.println("p1 has the same memory address as p2");
else
System.out.println("p1 has not the same memory address as p2");
}
}

This program will display: p1 has not the same memory address as p2.
In the previous code, even if the two people have the same age, they are not equal using the ==. So, to compare
values (ages) you must override the method equals (), and rewrite the comparison, as follows:
[CODE:java]
class Person{
int age;
public void setAge(int a) {
age = a;
}
public boolean equals(Object o) // override the method
{
if (o instanceof Person)
{
Personne p = (Person) o;
if (age == p.age)
return true;
}
return false;
}
public static void main(String[] args)
{
Person p1 = new Person();
p1.setAge(31);

39
Created by XMLmind

XSL-FO Converter.

Person p2 = new Person();


p2.setAge(31);
if (p1.equals(p2)) {
System.out.println("p1 is equal to p2");
} else {
System.out.println("p1 is diffrent from p2");
}
}
}

The instanceof operator checks if o is a kind of Person (This includes subclasses of Person) or not.
Warning ! There is also a trap in the comparison of strings
abc == def Is it true or false ?
Its false because they are physically different objects (obvious because they have different values)
abc == abc
Is it true or false ? Unfortunately, it depends on the compiler. Indeed, it is free to optimize these two references
to "abc" as an object instead of two, in this case the phrase is true. However, he did not make this optimization.
The phrase would be wrong!

1.5.6. The ternary operator


The conditional operator, noted ? ", has the following syntax:
[CODE:java]
(<booleanexpression> ? <expression> : <expression>

Lets take an example. Consider x = max (a ; b) in Java :


[CODE:java]
int a;
int b;
<otherinstructions>...
int x = (a > b) ? a : b;

Although use of this syntax works very well and shows that you are an experienced programmer, we do not use
it because the code is difficult to read.

1.5.7. The instanceOf operator


As you will see, Java uses an object concept. The instanceof operator allows us to check if a variable match a
type of class :
[CODE:java]
Object obj = new String("Hello world");
if (obj instanceof String) {
System.out.println("obj is an instance of the String class");
}

This example displays texte obj is an instance of the String class because the operation obj instanceof String
returns true.
You will see in the future with multiple inheritance concepts and implementation, it is not always possible to
predict the type of object which a method will be able to receive and it is in cases like this that the instanceof
operator may be useful.

1.5.8. The new operator


The new operator is used to instantiate a class or to create an array (the chapter 7 we will talk about arrays).
Example:
[CODE:java]

40
Created by XMLmind

XSL-FO Converter.

String greeting = new String("Hello !!!");

1.6. Arrays
In Java, the arrays are objects. They are used to store multiple variables of the same type. These variables can be
primitive type or reference.

1.6.1. Declaring an array


To declare an array, you have to specify the type of data that will be stored followed by an identifier and a pair
of brackets before or after the identifier.
[CODE:java]
// Example of declaring an array variable of primitive data type int
int myArray[];
// This declaration is the same as
int[] myArray;

When an array is declared, its size is not specified because the declaration of this array does not cause memory
allocation. The size will e defined when the array will be initialized, moreover, once the size.

1.6.2. Create an array


An array is an object, the new operator is used to allocate some memory and initialize the array.
1.6.2.1. One dimension array
In a new array, all the elements are null or equal to 0. The first position in the array begin at the index 0, like in
the C language. In our example, the elements are numbered from 0 to 9.
[CODE:java]
// This array contains 10 int-typed element
int myArray[] = new int[10];

When we initialize an array, the memory is automatically assigned to the array to put values initialized which
does not require the use of the new operator.
[CODE:java]
char[] genre= {'h', 'f'};

1.6.2.2. Multidimensional array


You can define some arrays with as many dimension as you want.
[CODE:java]
// Bi-dimensional arrays
float[][] doubleArray = new float[10][10];
int[][] doubleArray = {{1, 3}, {7, 5}};

Note: When you represent a multidimensional array, you can omit the size dimensions except for the first, which
is mandatory.

1.6.3. Assigning values to an array


To reach an element of an array, just index the variable of the array. Therefore, we must precise the index
between brackets after the identifier.
[CODE:java]
char firstSlot = genre[0]; // 'h'
char secondSlot = genre[1]; // 'f'

If you specify an index incorrect, an error (Exception) will be generated. We will talk about the management of
errors in another course (Exceptions).
You can get the size of an array by using the parameter legnth of your array :
41
Created by XMLmind

XSL-FO Converter.

[CODE:java]
int[] myArray = {1, 10, 12, 9};
System.out.println("Longueur du tableau " + myArray.length);

1.7. Java Platform Specificities


1.7.1. Common and differences of the C/C++ syntax
Java manages almost all the operators of the language C/C++. The priority are the same, however, some of them
dont exist anymore, for example, the coma to combine multiple expressions.
The operators &, * and sizeof are not manage by Java because you cant modify pointers with Java.
To compensate, Java adds a few new operators like "+" to concatenate values of type String.

1.7.2. Using JARs


The java archive format, JAR, allows you to gather several files into one thanks to a zip compression.
In general, a JAR file contains compiled classes (the .class files), as well as auxiliary resources associated with
the application (images or configuration files).
The addition to the archive of a particular configuration file, called manifest, makes the archive executable. The
manifest must contain information about the class to launch at the execution of the archive.
1.7.2.1. Syntax
To manipulate the JAR, use the jar command :
[CODE:java]
jar [options] [manifest] destination inputfile [inputfile]

1.7.2.2. Principal options

Examples :
1.7.2.3. Archive creation
[CODE:java]
jar cf MyFirstJar input-file(s)

1.7.2.4. Listing the content of an archive


[CODE:java]
jar tf MyFirstJar

1.7.2.5. Extract the content of the archive


42
Created by XMLmind

XSL-FO Converter.

[CODE:java]
jar xf MyFirstJar
jar xf MyFirstJar MyFirstJavaProgram

1.7.2.6. Execute an archive


[CODE:java]
java [options] jar MyFirstJar

1.7.2.7. Create an executable JAR


To create an executable JAR, we just have to create a file named manifest.mf, and precise the class which
contains the main() method executed when the program is launched.
Example of a manifest.mf file :
[CODE:java]
ManifestVersion: 1.0
MainClass: mypackage\MyFirstJavaProgram

When the file is created, we will add it to the archive. We use the following command :
[CODE:java]
jar umf manifest.mf MyFirstJar

1.7.3. Comments
The comments are indispensable in your source code, in fact, they can explain in a few words what do your
code, it will be easier maintainable and reusable. The comments are ignored when compiling.
1.7.3.1. On one line
It begins with // , then you can type your comments:
[CODE:java]
int x; //un commentaire

1.7.3.2. On several lines


The text between /* and */ will be ignored by the compiler.
[CODE:java]
/*
La variable x
est
un entier :
*/
int x;

1.7.3.3. Javadoc
This type of comment is used to generate documentation Java. The tool javadoc converts comments in HTML
format.
In this type of comments, it is possible to specify annotations in order to standardize:

43
Created by XMLmind

XSL-FO Converter.

For example, a method may be commented in the following manner:


[CODE:java]
/**
* Compute the root square of the number specified as parameter
* @param number
* @return the correctly rounded positive square root of the parameter
*/
double rootSquare(int number){
return Math.sqrt(number);
}

There are many ways to launch it:

44
Created by XMLmind

XSL-FO Converter.

Via a console (but complicated)

Use an IDE (Eclipse or NetBeans)

Write a script for using Ant or Maven

Example of a technical manual generated by the javadoc.

1.7.4. Decompilation
Java program are interpreted, the .class files contain enough informations to rebuild the source code.
If you are worried about decompilation :
Dont give your .class files (use servlets).

45
Created by XMLmind

XSL-FO Converter.

Dont add debug informations in your .class files (javac O Source.java).

Use a byte code obfuscator, name mangler or a .class file shrinker ( http://proguard.sourceforge.net/, for
example)

1.7.5. Getting source code from the byte code


The first tool, called javap help recover the structure of a class from its byte code. Thus, from the .class file of
HelloWorld class we were able to retrieve the following information:
[CODE:java]
javap Go

The tool will display :


Compiled from "MyFirstJavaProgram.java"
[CODE:java]
public class MyFirstJavaProgram extends java.lang.Object {
public static void main(String args[]);
}

Another utility allows users to retrieve the source code of your application from your byte code. Its called
Jad, you can get it at this address: http://www.kpdus.com/jad.html
It is very easy to use it :
[CODE:java]
jad MyFirstJavaProgram.class

We were thus able to retrieve the source code, from HelloWorld byte code, which we wrote in the first part of
this essential.
MyFirstJavaProgram.jad :
[CODE:java]
// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name: Go.java
import java.io.PrintStream;
public class MyFirstJavaProgram
{
public MyFirstJavaProgram ()
{
}
public static void main(String args[])
{
System.out.println("This is my First Java program!!!");
System.exit(0);
}
}

We can notice that except the comments nothing has been lost !

1.7.6. The main method


In Java, the entry point of a program is defined by this method, and it is important to keep the same syntax. This
method does not return value; its return type is therefore void. This method must be static (static) because the
class that contains it is not instantiated at startup.
On the other hand, an array of type String is passed as a parameter and allows us to retrieve parameters passed
on the command line. So, let us start our command line application:
[CODE:java]

46
Created by XMLmind

XSL-FO Converter.

java MyFirstJavaProgram I am 23

The content of the args array will be:


args[0] => I
args[1] => am
args[2] => 23
Note : Most development environments offer a debugging tool to see the contents of a variable (see course on
Eclipse).

Eclipse debugger allowed us to stop the application while its execution, you can search informations about
memory.
A Java program can contain several main methods, but, only one these could be used as the entry point of your
program.

1.8. Conclusion
We have seen in this essential the bases of the Java programming language. These are fundamentals and no
good Java programmer should ignore them.
To complement this course, it is strongly recommended to consult the one on the classes. These are certainly
part of the syntax, but their understanding is so central that a fullfledged course necessary.

47
Created by XMLmind

XSL-FO Converter.

Chapter 3. Classes
With this course you will :

Understand the Object-0riented concepts

Be able to create a complete Java Class

Understand the Inheritance concept

Know how to use interfaces

Understand the visibility concept and be able to use the different modifiers

Understand what is a Java Bean

Understand what is the Garbage Collector

1. Course
1.1. OOP presentation
1.1.1. The notion of object
Java langage is an Object Oriented Programming language, or OOP. OOP means that we try to model real entity
(Examplse : a car, a personn, an account), in dataprocessing entity named (Examples : myCar, mikael,
myAccount), with characteristics (Examples : color, weight, balance) and fonctions (Examples : start, speak,
credit). These entities are called, Object . An object has an identity, some characteristics called Attributes
and some fonctions called Methods . We could reprensent a car like this example :

48
Created by XMLmind

XSL-FO Converter.

1.1.2. Design of classes


In our example, and in the real world we could say :
To create a car, we need a complex machinery which one programs to create with the request a personalized car.
Generaly, in OOP, we could say:
To create an object, we need a class to instance with the request a personalized object.
Indeed, a Class is a kind of structure which defines the attributes and methods of the objects that one can
instance.

We will use this class to create cars as many as we want which will have their own color (String type), a motor
(String type), a current speed (int type), and 2 methods start (returns an integer) and stop (returns an integer
too).

1.1.3. Principles of encapsulation and abstraction


Encapsulation indicate the fact of prohibiting the access inside an object to the other elements of the
software. It creates for itself a kind of caspule invisible which protects the interior of the object.
In Java, this encapsulation is associated the principle of abstraction of data. I.e that the implementation of the
data of the object is completely independent in the way in which one them use.

49
Created by XMLmind

XSL-FO Converter.

In my program I dont really know what is the contents of the red square !
I cant modify myself the attributes of my object, thats why I cant modify directly the current speed (principle
of encapsulation).
To cure it I have two methods which are accessibles. I can use it, but I dont know what they really do (principle
of abstraction) : here to start the car, the method increment the current speed. But, it could make a multiplication
or a division ! Why not
The other part of my program doesnt know what the method do, they just use the green methods .

1.2. The classes


1.2.1. Use of packages to organise my program
A program in Java is entirely made up of classes. Each class is defined is a file with the extension : .java. The
files are associated to a package.
A package allows you to organise the classes. For example the classes which work on the principles objects of
the application (like persons, or cars) and the classes which design the graphic interface.
A package is just a succesion of repertory on your harddisk. This succesion is defined by the name of the
package. The name of the package is composed by word separed by . . For example the name
myProgram.myObjects. All your classes will be storen in the repertory root\myProgram\myObjects .
When we want to make a new project, we organise our classes in our packages.

50
Created by XMLmind

XSL-FO Converter.

It is important to respect this way of creating a software in Java. The overlap of the classes in various packages
is a key point for safety, the clearness and the maintenance of the program.

1.2.2. How to make a class


It exists differents types of variables :
Primitives types : int, boolean, float

References types : Object, String, System ...


The latter, contrary to the first types, are in fact of the classes. And with each time one creates a class, one thus
creates a type of reference.
In practice it is written that only one class per file .java. But it happens that one creates several in certain quite
precise cases of them (See course on Inner and Nested Class).

To create a class we have to :


1.
Use the keyword package to specify where the class is located
2.
Use the key word class followed by the name of the class
[CODE:java]
//file Car.java
package myprogram.myobjects;
// The class Car
public class Car {
//my code
}

We can see another key word : public


This key word indicates the visibility of the class in our program. (See chapiter N5)
It should be retained that only one class can be public by file!
Sometimes, as one mentioned above, one will need to put other classes in this same file. We just have to use the
key word import.I.e that we import in our file another class in our file.
51
Created by XMLmind

XSL-FO Converter.

[CODE:java]
//file Car.java
package myprogram.myobjects;
//we import a file
import com.labosun.OldObjects;
//we import all the contents of another package
import com.linuxlabs.*;
public class Voiture {
//our code
}

1.3. Inheritance
1.3.1. Definition
Inheritance is the ability to build a class from another one, which inherite variables and methods from the base
class. The new class will have the defined accessibility.
Java has a difference with other object language like C++ because the multiple inheritances is not available.
However there is a way to solve this problem with interfaces., qui prend un argument parmi ceux ci :
For example a car BXLeader (where BXLeader is an object of the class Car), here is what you could obtain
with the class hierarchy. It is only an example, there is no predefined solution, but the result must be coherent
and useful. It is useless to use this hierarchy if we only use one kind of vehicle (for example only Cars).

Parents classes are called superclass, child class are called subclass. In the previous example Vehicle is the
superclass, Motorized the subclass, etc
In java, everything is object because every class inherits from the Object class. The object class is the root of
any hierarchy. We can say that it is the root class.

1.3.2. Extends
Inheritance is done with the extends keyword. It is placed after the class name, when you define it. It is
followed by the name of the parent class.
[CODE:java]
class Person {
//superclass
}

52
Created by XMLmind

XSL-FO Converter.

class Student extends Person {


//subclass
}

1.3.3. Super
The keyword super is similar to this. Contrary to the keyword this which allows referencing the class in which
it is called, the keyword super reference the superclass of the class where it is called.
It allows you to call the constructor of the superclass. Super must be declared at the start of a subclass
constructor. So the constructor can do the same tasks as the constructor of the parent class.
[CODE:java]
class Person {
Person (String name) {
//constructor
}
}
class Student extends Person {
int mark;
Student (String name, int mark) {
super(name); // constructor of the parent class
this.mark = mark;
}
}

In this example super() call the constructor of the parent class Person.

1.4. Interfaces
1.4.1. Definition
An interface is similar to a class. Here are the differences with a class:

it only has method body

it does not have any constructor

you can not instance it

its variables must be initialized


In fact, an interface is the skeleton of the class, so all abstract methods owned by this interface must be
redefined in the class. An interface can inherit (use of extends) of one or several interfaces.
[CODE:java]
interface Math extends Serializable {
float pi = 3.14; // pi must be initialized
float perimeter(float a);
}

1.4.2. Implementation
Interface implementation allows solving the lack of multiple inheritances. A class can implements several
interfaces. By implementing an interface, a class inherits of its variables and its methods (that must be
redefined).

53
Created by XMLmind

XSL-FO Converter.

It must be done with the keyword implements.


[CODE:java]
class Circle implements Math, Interface1 {
float perimeter(float radius){// we define the body of the method
return pi*radius*2;
// pi is inherited from Math
}
}
class Example implements Interface1,Interface2,Interface3 {
}

1.4.3. Differences with abstract classes


In an abstract class we can put classic methods whereas in an interface we cant : all methods have to be abstract
and the class which implements the interface have to redefine the methods. Dont forget that we can extends
only one class but we can implement several interfaces !

1.5. Visibility modifier


1.5.1. public
It means accessible from all classes. Classes, methods and class variables can be public. Some classes must be
public to allow the application running (classes with a main method).

1.5.2. private
It means Inaccessible from other classes. Only variables and methods can be private. A class can not be private.

1.5.3. protected
It means accessible from other child classes and class located in the same package. Only attributes and methods
can be protected. A class can not be protected.
The protected attribute allows the access to the resource by child classes (even if they are located in another
package) and all classes in the same package, like explain in the following example:
[CODE:java]
//File (..)\exa\Parent.java
package exa;
public class Parent {
protected int tdb;
}
[CODE:java]
//Fichier (..)\exb\Child.java
package exb;
import exa;
class Child extends Parent {
public static void main (String [] args) {
tdb++ ; // authorized access
Child objf ;
objf.tdb++ ; //authorized access
Parent objm ;
objm.tdb++ ; //forbidden access
}
}

1.5.4. no modifier
When you do not specify any modifier, Java uses a default modifier. Variables, methods and declared class are
54
Created by XMLmind

XSL-FO Converter.

accessible by classes from the same package and inaccessible by other (like friend in C++).

1.6. Java Bean


1.6.1. What is a Java Bean ?
A Java Bean is just a class which respects some rules :
3.
It has a default constructor
4.
All its attributes are private
5.
It has getters and setters for all its attributes
[CODE:java]
public class Car {
//All the attributes are private
private String color;
private int currentSpeed;
private boolean position;
//The default constructor
public Voiture() {
}
/* My getters and setters, to get and set the values of my attributes */
//My setters
public void setColor(String pcolor) {
this.color = pcolor;
}
public void setVitesseCourante(int pspeed) {
this.vitesseCourante = pspeed;
}
public void setEtat() {
this.position = !this.position;
}
//My getters
public String getColor() {
return this.color;
}
public int getCurrentSpeed() {
return this.CurrentSpeed;
}
public boolean isPosition(){
return this.position;
}
}

1.7. Other modifier


1.7.1. abstract
1.7.1.1. Definition
An abstract class can not be instantiated. Abstract classes are used to be inherited like a superclass. Contrary to
classical class, it can contain abstract methods.
An abstract method is a method skeleton. They have not any body (no code line). An abstract method is empty
so it must be override (polymorphism) by child classes.

55
Created by XMLmind

XSL-FO Converter.

1.7.1.2. Use
Abstract classes or method are declared with the keyword abstract
[CODE:java]
public abstract class Test {
public abstract void abstractMethod();
public void classicalMethod(){
}
}

We can not have an abstract method in a class that is not declared abstract.
[CODE:java]
public classIllegalClass{
public abstract void illegalMethod();
}

If you try to compile this code, you will have an error: class IllegalClass must be declared abstract.
1.7.1.3. Purpose
A subclass that inherits from an abstract class must override abstract methods from the mother class (except if it
is itself abstract). The interest is that each subclass must define these methods.
[CODE:java]
public class Animals{
public abstract class Animal {
public abstract void move();
// all animals can move, but not with the same manner.
}
// Class Cat inherit from Animal
public class Cat extends Animal {
public void move(){
run();
}
public void run(){
// code
}
}
// Class Bird inherit from Animal
public class Bird extends Animal {
public void move(){
fly();
}
public void fly(){
// code
}
}
// Class Application
public class Application {
public static void main(String[] args) {
Animal animal1 = new Cat();
Animal animal2 = new Bird();
animal1.seDeplacer();
animal2.seDeplacer();
}
}

In this example, the Animal class declares a method move that is defined by all sub classes. This method is
56
Created by XMLmind

XSL-FO Converter.

abstract because all animals can move but not with the same manner. It is the subclasses to describe how to
move. This example explain how to use the polymorphism: we manipulate animal1 and animal2 like a simple
Animal without knowing what is its kind of Animal. We only know that they are Animal, so they have a move()
method.
1.7.1.4. Comparison with interfaces
It is sometime hard to make the difference between an abstract class and an interface. The advantage of an
abstract class is that it can contain normal methods (not abstract). An interface only contains methods without
body that must be defined by class which implement it. Interfaces advantages are that it is possible to implement
several interfaces although we can not inherit from several classes.

1.7.2. final
The keyword final is used to specify what can be modified. It can be associated to a variable, a method or a
class.
1.7.2.1. final variable
A final variable can not be modified. We give it a value during its declaration. When the object is created
(constructor called), we can not change the value. This variable is a constant.
[CODE:java]
public class Math {
public final float pi = 3.14;
}

1.7.2.2. final mthod


A final method can not be overridden in the child class.
[CODE:java]
public class Example {
public final void aMethod(){
}
}

1.7.2.3. final Class


A final class can not be inherited and can not be abstract. Final class interest is to enhance optimization and
security. All classes at the end of a hierarchy should be declared final.
[CODE:java]
final class Example {
}

1.7.3. static
The key word static can be associated to a variable or a method. It allows accessing a resource without having
created any object.
[CODE:java]
public class Math {
static float pi = 3.14;
static float perimeter(float width, float height) {
return ((width+height)*2);
}
}
public class Example {
public static void main(String[] args) {
float p = Math.pi;
p = Math.perimeter(3, 4);
}
}

57
Created by XMLmind

XSL-FO Converter.

In this example, we access to a variable pi and to the method perimeter() without having created the object of
type Math.
Another particularity is that a static variable will have the same value for all its instances (objects) of the class.
We must be very careful when we modify the value of a static variable. That is why constants are declared static
and final.
[CODE:java]
public class Exemple2 {
public static void main(String[] args) {
Math m1 = new Math();
m1.pi = 4;
Math m2 = new Math();
float p = m2.pi; // p equals 4
}
}

1.7.4. garbage Collector


1.7.4.1. Goal
Contrary to the C++, Java does not own any destructor. The garbage collector destroys all instances that are not
referenced. The garbage collector spies all instances, detect useless one, and delete them from the memory.
However, before destroy them, he call the finalize() method, if it exists.
1.7.4.2. finalize() method
So the finalize() method is called by the garbage collector before the destruction of an instance, it allows to free
resources used by the instance or to execute a task before the instance destruction. The method must be written
by the programmer, you must define it in the class.
[CODE:java]
public class Example {
public void finalize() throws Exception {
// be careful with exceptions
//(read the course about exceptions for more information)
}
}

1.7.4.3. Manage the garbage collector


The garbage collector is integrated to the JVM (Java Virtual Machine). It work when there is a lack of memory.
It is impossible to manage its activity. However we can force it to free memory with the static method gc() from
the
System
class.

58
Created by XMLmind

XSL-FO Converter.

Chapter 4. Exceptions
By completing this course, you will:

Learn what an exception is

Learn how to manage them

Learn how to create and throw your own exceptions

Learn how to use exceptions

1. Course
1.1. Introduction
Originally, Java was created as an embedded system. These embedded systems or programs are integrated in
specialized devices such as PDA (Personal Digital Assistant), cell phones, and other electrical devices. For this
use we must have an efficient error management.
Indeed it is not conceivable for a lot of users to have a device like phones, microwaves or toasters that
breakdown due to device integrated softwares bug.
It is not possible to eliminate all possible errors in our programs, but we can solve problems by targeting and
analyzing the possible applications errors that can be foreseen in a set and systematic way.

1.2. Errors management


Monitored errors:
If errors have been monitored by developers (a user who would enter a too big value) then the program must
monitor which lines of code can generate errors and treat these particular errors.

Unmonitored errors:
Depending on whether the error was monitorable or not, two cases are possible:

Errors that were monitorable: it cannot exist in Java because the compiler must detect all errors and force
the programmer to repair it. Monitorable errors come from developers who have failed to manage them
with some critical parameters.

Unmonitorable errors: the error comes from a lack in the program and depends on the conditions in which
the program has been executed. Java interpreter (JVM) produces an error message and stops the execution.
An exception is throw during the Runtime , for example, the used of an object method which had a null
reference.
[CODE:java]
package com.labo.sun

59
Created by XMLmind

XSL-FO Converter.

public class Exceptions{


public static void main(String[] args){
String var=null;
var.charAt(0);
}
}

This give the following exception.


Exception in thread "main" java.lang.NullPointerException
at com.labo.sun.Exceptions.main(Exceptions.java:7)

Monitored errors / unmonitored errors:


Java obliges developers to manage the monitored errors and to catch them. A monitored error by the compiler
obliges the developer to provide the necessary code to treat this error.
The unmonitored errors are considered too serious to be treated. The treatment of the error is managed by the
compiler itself. The exceptions that need not be caught are instances of the RuntimeException class. None
block code is susceptible to treat this operation.
Example: Division by zero, in this case an error occurs but the compiler doesn't handle it, its up to the
programmer to manage this error.
[CODE:java]
public static void main (String[] args){
int i=10/0;
System.out.println(i);
}

This give the following exception:


Exception in thread "main" java.lang.ArithmeticException: / by zero
at com.labo.sun.Exceptions.main(Exception.java:6)

A message error appears which indicates then that the error has been treated and the execution is interrupted.
It is an exceptional treatment and not an error.

1.3. Exceptions
1.3.1. Introduction
These errors are called exceptions, and the management of these exceptions must be implemented in Java.

The compiler must detect the majority of the errors in the goal to have minimum errors during execution.

The treatment of the errors must be separate from the code in order to make it as understandable as possible
and especially exempt all error messages.
The management of exceptions is almost the same as C++.
Exceptions have been created to warn programmers about occurred errors. Program control is transferred to a
particular code section which has to treat the error. Thanks to it, error management is separated slightly from the
code.
As errors are separated it is no longer useful to have return values for methods (Boolean). Program runtimes
control can be remotely called. You can specify only one location to treat all errors.
A method must specify types of exception that it cannot capture directly. The compiler could be sure that
exceptions will be managed by the program. With this concept you manage all errors with one method and all
60
Created by XMLmind

XSL-FO Converter.

have the same priority.

1.3.2. Definition
An exception is an error signal. It is an object that is created when a strange situation occurs, during the program
execution. Exceptions always inherit from Throwable class. The two under Error classes and Exception inherits
from this Throwable class. They are represented by objects which must inherit from java.lang.Exceptionclass
and its subclasses. A lot of subclasses of exception manage information specialized for different problems.
When an error is thrown:
1.
The interpreter creates an object (with the new operator) of a particular class, subclass of Exception class.
2.
Then the operator searches a part of the code that should be capable of receiving the created object and to
treat it.
3.
If there is no case, Java interpreter applies itself to the treatment: throw (rise of an exception). To find the
code able to treat this object, the interpreter uses the type of this object.
4.
If code is found, the object is transmitted and the execution goes on this codes location.

1.3.3. The exception classes


Hierarchy of the subclasses of java.lang.Exception and java.lang.Errors:

1.3.3.1. The error subclasses


The Error subclasses represent serious errors of virtual machine (infinite iteration, class in untraceable loading,
61
Created by XMLmind

XSL-FO Converter.

etc...).
Errors defined in the Error class of the java.lang package generally stop the interpreter after showing an error
message. These errors won't have to be captured.
1.3.3.2. The Exception subclasses
The Exception subclasses define the exceptions set capable of being treated directly by the developer. The
standard classes as RuntimeException or IOException inherit from Exception. The RuntimeException class
corresponds to the small incident (variable references to null will give NullpointerException). However one is
not obliged to treat these exceptions for practical reasons, because if not your code java primarily will be
devoted to the management of exceptions and thus, your useful code will be tiny room compared to the code of
treatment.
All exceptions inherit from the Throwable class. This class defines two constructors:

Throwable()

Throwable(String)
The string passed in parameter is generally used to describe the problem represented by the exception. You can
get this string by calling getMessage() method which is inherited from the Throwable class.
The Throwable class also defines the printStackTrace() method which displays the exception and the state of the
execution stack at the time of its call.
For exceptions which inherit from RuntimeException, you need not manage them. However everything which is
inherited from Exception must use the try/catch otherwise the compiler will refuse to compile.
Here a correct method (in term of syntax) which does not require management
[CODE:java]public void myMethod(){
throw new Error("My error...");
}

1.3.4. Exception management


An Exception object is created by the interpreter when an error occurs. This object can contain some
information concerning the problem but also a stack of execution useful to debug. The object is passed by
argument of the treatment block. The Exception object is sent through by the keyword throw to be caught by
another code place with the keyword: catch.
1.3.4.1. Try/catch bloc
Mechanism
An exception is an object which is created when an incident happens. It is said that the exception is thrown. The
treatment of code of method is interrupted and the exception is propagated through the parent method.
If no methods capture the exception, it can return to the first method. An indication of error is given at the end
of the execution.
The block try/catch helps you to catch Exceptions.
Using good words...
When the compiler generates an exception, it means that it throws an exception. Kill the exception is called:
catching it. The block catch is also called exception handler.
try includes an instruction block for which we want to capture exceptions that could be thrown. In the case
where several exceptions could be produced, the execution of the block surrounded by the try will be interrupted
62
Created by XMLmind

XSL-FO Converter.

by the first exception throw.


catch is a block to specify the type of exception you can catch and the treatment you do for it. You can use
several catch blocks to catch different exceptions.
Example:
[CODE:java]
catch(RuntimeException e)

To differentiate the exceptions with a catch :


[CODE:java]
try{
//code that can generates a RuntimeException
}catch(RuntimeException e){
System.out.println(e.getMessage());
}

In this example all instructions descended from the RuntimeException class (and inherited classes) are caught in
the catch block that follows.
To differentiate the possibilities of multiple errors, it is necessary to create several catch blocks:
[CODE:java]
try{
//code that can throw exception
}catch(IndexOutOfBoundsException e){
//IndexOutOfBoundsException's management
}catch(RuntimeException e){
//RuntimeException's management
}catch(ArithmeticException e){
//ArithmeticException's management
}

The order of the three catch blocks is very important because if all three dont inherit the same Exception class,
it is necessary to locate the catch blocks according to their importance (the most specific case to the most
general). Example: ArithmeticException is an Exception derivative class. The catch block which manages the
ArithmeticException should be placed before the one which manages the Exception.

1.3.5. The throw of the exceptions


When an exception is thrown it is propagated to the calling method. It goes back until it can be caught or it
arrives to the highest level and provokes an execution error.
When a first method calls a second integrated method in a try/catch zone of this first method, and this second
method calls a third method which throws an exception, if this last method doesnt own a try/catch block, the
exception is sent back to the superior level. The second method doesn't catch it too. Finally the exception is sent
back to the first method. It catches this one thanks to its try area and it treats this one in its catch area.

63
Created by XMLmind

XSL-FO Converter.

In this example, we leave the calling method to manage exceptions. We have just defined that methods can
throw exception with the throws keyword. In this case the method which creates the exception neednt to look
for Exceptions.

1.3.6. Linked Exceptions


An exception always has a cause which perhaps an exception or null. This enables us to go up with the source of
the problem and thus the programmer can correct there.
As some exceptions will be able to go back up very far, it will be interesting to determine from where these
exceptions have been thrown.
The printStackTrace() method enables you to get the exception stacked trace. This stacked trace permits you to
recover the origin method which has been thrown by the exception and all methods between it and the last one.
[CODE:java]
try{
//code that can throw exception
}catch(Exception e){
e.printStackTrace(System.err);
}

It is possible to indicate several types of exceptions by separating their names by comma.


[CODE:java]void example(String s) throws IOException, InterruptedException{
}

1.3.6.1. You can modify the exception origin


When an exception is detected, the interpreter indicates that this exception occurred in the line of the block try
and not in the method. Indeed the handler doesn't have to worry about verifying the content of the exception nor
its source.
64
Created by XMLmind

XSL-FO Converter.

To get a different result, Java proposes two methods that are going to allow you to modify either the origin of
the exception or its type:
5.
To allow you to recover the exact origin where the return has been done, it is necessary to use the
fillInStackTrace () method.
6.
Another way to modify the exception is to change its type. For it you can use overcasting:
[CODE:java]
catch(IndexOutOfBoundsException e){
System.err.println("Error");
throw (RuntimeException e);
}

1.3.6.2. Finally keyword


You use it after the try/catch block. You can use it when you want to do some actions which will always be
executed even if an exception is was thrown and the program stopped.
[CODE:java]
try{
//code that can throw exception
}catch(Exception e){
//exception's management
}finally{
//code always execute
}

Its very useful when you want to clean some things before leaving a method. With this concept you can share
some part of code between all parts of your catch blocks. For example: when you open a file, you must close it
at the end.

65
Created by XMLmind

XSL-FO Converter.

If some instructions are executed in the catch block, the instructions of the finally block will be executed after. If
the catch block doesn't catch the exception, the finally block is going to be executed before the exception went
back up to a superior level.
Finally if you want to just do some cleaning operations you can use only try and finally blocks.

1.4. To throw exceptions


It is possible to use the throw keyword to create personalized error messages. This keyword will indicate that
something was not carried out normally.
Throwing an exception is usually used to inform the user when, for example, an incorrect word is entered.
[CODE:java]
if(!testWord.equals("")){
System.out.println("Test OK");
}else{
throw new Exception("Test error");
}

We are able, in this way, to manage the exception thrown in another part of the code, separating thus completely
the test and the consequently action.
In this example, we generate an Exception instance. That can however be problematic, knowing that an
intermediate catch could manage this exception in place of the one specialized for. It is generally necessary to
redefine our own exception, as we will see it in the following chapter.

1.5. Create your own exceptions


The best method to throw exceptions is creating your own exception classes. They must inherit from the
66
Created by XMLmind

XSL-FO Converter.

Exception class to allow compiler to verify if a caught exception is correctly declared in a program.
It allows you to have its own types of exceptions in the program. It mainly allows you to personalize the
management of your errors (to record the errors for example in a file text).
Example of personalized exception:
[CODE:java]
//Class inherits of the Exception class
public class MyException extendx Exception{
//Constructor of the MyException class
public MyException(String s){
super(s);
}
}
public class TestException{
public static void main(String[]args){
try{
System.out.println(Some display...);
function();
}catch(MyException e){
System.out.println(e.getMessage();
}
}
static int function() throws MyException {
throw new MyException("Exception");
}
}

1.6. Logs messages


When a management of the events is install to be able to recall a problem rather quickly, the installation of a
management by logs makes it possible to safeguard and define levels of priority on event or exceptions. What
makes it possible to effectively determine the exceptions at the origin of the problem according to levels' of
priority which are following them for commons-logging:

Trace (less serious)

Info

Warn

Error

Fatal (more serious)

1.6.1. Logs treatments


1.6.1.1. Install commons-logging
The use of an implementation of Log which is LogFactory makes it possible to set up our management of the
logs:
[CODE:java]
static Log log= LogFactory.getFactory.getInstance(MyClass.class);

67
Created by XMLmind

XSL-FO Converter.

With the method getInstance(Class class) or getInstance(String name) one definite the class which will be
supervised.
1.6.1.2. The different warning
Like known as previously, we have several levels of logs, these levels will allow to meet our needs, here at the
time of the management of the errors, one can determine if an exception is serious or not, if one wishes to post
infos of debug etc...
In the posted results, we have several information such as the hour, the date the method, the package and the
personalized message.
15 sept. 2006 14:42:13 com.labosun.MyClass <init>
INFO: Information message
15 sept. 2006 14:42:13 com.labosun.MyClass <init>
ATTENTION: Advertice message
15 sept. 2006 14:42:13 com.labosun.MyClass <init>
GRAVE: Error message
15 sept. 2006 14:42:13 com.labosun.MyClass <init>
GRAVE: Fatale error

1.6.2. Example of management of log with commons-logging


[CODE:java]try{
throw new Exception("My test exception");
}catch(Exception e){
e.printStackTrace();
//logs
log.trace("Traced message");
log.info("Information message");
log.warn("Advertice message");
log.error("Error message");
log.fatal("Fatale error");
}

To

download

common-logging:http://jakarta.apache.org/site/downloads/downloads_commons-

logging.cgi

1.7. Conclusion
We saw that there are exceptions that it is necessary to treat and of other which are managed by the JVM.
Thanks to commons-logging, we as saw as it was possible to manage the levels of log in an application and thus
to
set
up
a
fast
debug.

68
Created by XMLmind

XSL-FO Converter.

Chapter 5. Collections
By completing this chapter, you will :

Learn what a collection is

How to use it

Know the majority of available collections

1. Course
1.1. What is a collection ?
In this section, you are going to learn what is a Collection and what it is use for.

1.1.1. Introduction
Since version 2, the Java platform includes a collection framework. A Collection is an object which represents a
group of Objects or wrapped primitives. In other words, a Collection is used to store objects. We can use arrays
to store object quickly but Collections improve memory management and reduce programming effort.
In fact, Collections size is dynamically managed. Thus, a Collection is never too small ! Moreover, Collection
provide lots of methods which make this type of object easier to hold compared to arrays.

1.1.2. Generics
Previous Java 5, a Collection could handle multiple types of objects because a Collection had to contain Object
type classes. When we wanted to retrieve an object from a Collection, we had to cast it. Casting was dangerous
because you could throw a ClassCastException during the runtime.
Java 5 includes Generics, which allows you to specify a type for the objects located in a collection. You can
always use Collections without Generics but it's recommended to deal with it. In this chapter, all examples use
Generics.
[CODE:java]
Collection myNonGenericCollection = new ArrayList(); //Not recommended but legal
//This Collection handles Cat objects only
Collection<Cat> myGenericCollection = new ArrayList<Cat>();
myGenericCollection.add(new Cat());
myGenericCollection.add(new Dog()); //Compilation error

1.1.3. Reminder : Arrays


In Java, arrays are objects (contrary to C/C++ where they are a continuation of contiguous memory locations).
They provide ordered collections of elements. Elements of an array can be basic types variables (int, boolean,
double, char) or Objects references (so we can have arrays of arrays).
1.1.3.1. One dimensional arrays
Here are basics array declarations
[CODE:java]
typeOfElements[] nameOfArray;
typeOfElements nameOfArray[];

69
Created by XMLmind

XSL-FO Converter.

typeOfElements = basic type (int, char, float ) or a class name

nameOfArray = identifier of the arrays


You mustn't determinate the size of the array when you declare it. You will specified this at the instantiation of
the object by using the new keyword. Also, you will not be able to modify the size later, because this one is
fixed.
[CODE:java]
int[] myArray;
myArray = new int[50];

The instantiation of an array with new :

Allocates the necessary memory according to the type of the array and the specified size
Initiates the arrays content: 0 for a simple type, null for an object
You can explicitly specify the list of your array when you declare it (list of values between braces). Memory
allocation (like using new) is handled by compiler.
[CODE:java]
int[] myArray = {1, 2, 3, 4, 5};

Like in C/C++, indexes start to zero. You can access elements with this kind of expression : nameOfArray[index]
where nameOfArray.length - 1 index 0.
Java checks automatically the index thanks to the limits defined just before. If you exceed these limits, an
ArrayIndexOutOfBoundsException exception is generated.
[CODE:java]
public class GoingBeyond {
public static void main(String[] args){
int array[] = new int[3];
System.out.println("Size of the array : " + array.length);
try {
// Write out of the array
array[array.length] = 1;
}
catch (ArrayIndexOutOfBoundsException e) {
System.out.println(e + ", well caught!");
}
}
}

Display :
[CODE:java]
Size of array: 3
java.lang.ArrayIndexOutOfBoundsException: 3, well caught!

1.1.3.2. Multidimensional arrays


As we said before, you can create arrays of arrays. Thus, each element of an array can have another array, and
so on, without any limit.
Like one dimensionals, multidimensional arrays are not specified when you declare your array but when you
instantiate it.
[CODE:java]
typeOfElements[][] nameOfArray;
nameOfArray = new typeOfElements [size1][ size2];
//Sizes size1 and size2 are not necessarily equal.

70
Created by XMLmind

XSL-FO Converter.

typeOfElements[] nameOfArray []; //Weird but it compiles !

You access the elements thanks to an expression like the following example :
[CODE:java]
nameOfArray[index1][index2]

nameOfArray.length - 1 >= index1 >= 0

nameOfArray[index1].length - 1 >= index2 >= 0

Here is a concrete example :


[CODE:java]
char[][] text = new char[5][8];
text[0][1] = 'H';
text[0][2] = 'L';

Like one dimensional arrays, you can create arrays by giving the list of the elements when declare it (list of
values between braces).
[CODE:java]
int[][] matrix = {
{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10},
{11, 12} //Size can be different !
};
System.out.println(matrix [1][1]);
Display :
7

1.1.3.3. Increase the size of an array


As we said before, arrays' size are set at the instantiation. After that, the only way to change it is to create a new
array and to copy previous values by using arraycopy() method from java.lang.System class.
[CODE:java]
int [] oldArray = {1,2,3};
int newSize = 10;
int[] newArray = new int[newSize];
int sourceIndex = 0;
int destIndex = 0;
System.arraycopy(oldArray, sourceIndex, newArray, destIndex, oldArray.length);

1.2. Interfaces' hierarchy


For each type of data structure, there is an interface and some implementations. Each implementation uses a
strategy with its advantages and drawbacks. Thus, you have to choose it according to your needs. This course
will sum up collections which are the most used. All these interfaces are in the java.util package. Note that all
these interfaces use generics.

71
Created by XMLmind

XSL-FO Converter.

1.2.1. The Collection interface


Collection is the interface from which Set, List, and Queue extend. It provides methods such as adding elements
or converting to array.
[CODE:java]
public interface Collection<E> {
//Basic Operations
int size();
boolean isEmpty();
boolean contains(E element);
boolean add(E element);
boolean remove(E element);
Iterator iterator();
//Bulk Operations
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E> c);
boolean removeAll(Collection<?> c);
boolean retainAll(Collection<?> c);
void clear();
//Array Operations
Object[] toArray();
<T> T[] toArray(T[] a);
}

1.2.1.1. Few methods of the Collection interface

boolean add(<T> element) method allows adding an element at the end of the list

boolean contains(<T> element) method checks whether the Collection contains the specified object

boolean containsAll(Collection<?> col) method tests whether the collection contains all the specified collections

elements

Object[] toArray() return an array of objects from the collections


[CODE:java]
collection.add("Monday");
collection.add("Tuesday");
collection.add("Wednesday");
collection.add("Thursday");
collection.add("Friday");

72
Created by XMLmind

XSL-FO Converter.

Object[] myArray = new Object[10];


myArray = collection.toArray();
for (int i = 0; i < myArray.length; i++) {
System.out.println(myArray[i]);
}

Display :
Monday
Tuesday
Wednesday
Thursday
Friday

<T> T[] toArray(T a[]) allows to get a specific type of array. To do so, you just have to give an array as
parameter of the type that you want. But youll have to make a cast. An ArrayStoreException exception is

thrown if one of the elements of the collection is different from the type of the array giving in parameter. If
the array giving in parameter is smaller than the returned array, only this one will be fulfill with the elements
of the collection. Whereas, if the array given as parameter is stronger than the array which gets the values,
then the returned array will have the size of the first array and both of them will be fulfill
[CODE:java]
collection.add("Monday");
collection.add("Tuesday");
collection.add("Wednesday");
collection.add("Thursday");
collection.add("Friday");
String [] myArray = new String[collection.size()];
myArray = (String[]) collection.toArray(new String[0]);
for (int i = 0; i < myArray.length; i++) {
System.out.println (myArray[i]);
}

Display :
Monday
Tuesday
Wednesday
Thursday
Friday

1.2.2. The List interface


Collections java.util.List are ordered collections of elements that you can access by their position (indexes),
which is between 0 and size of the collection minus 1.
[CODE:java]
public interface List<E> extends Collection<E> {
// Informations
int size();
int hashCode();
// Positional Access
E get(int index);
E set(int index, E element);
boolean add(E element);
void add(int index, E element);
boolean addAll(int index, Collection<? extends E> c);
boolean addAll(Collection<? extends E> c);
void clear();
E remove(int index);
boolean remove(E element);
boolean removeAll(Collection<?> c);
boolean retainAll(Collection<?> c);
// Search
int indexOf(E element);

73
Created by XMLmind

XSL-FO Converter.

int lastIndexOf(E element);


boolean containsAll(Collection<?> c);
boolean contains(E element);
boolean isEmpty();
// Comparator
boolean equals(E element);
// Iteration
Iterator<E> iterator();
ListIterator<E> listIterator();
ListIterator<E> listIterator(int begin);
// Rangeview
List<E> subList(int from, int to);
Object[] toArray();
<T> T[] toArray(T[] element);
}

1.2.2.1. Few methods of the List interface

E get(int index) method allows to get an element positioned at a specified index

void add(int index, E element) adds an element at a specified index

E set(int index, E element) replaces the element at the specified position in this list with the specified element.
[CODE:java]
List<String> myList = new ArrayList<String>();
myList.add("Monday");
myList.add("Tuesday");
myList.add("Wednesday");
myList.add("Thursday");
myList.add("Friday");
myList.add("Saturday");
myList.add("Sunday");
String theDay = myList.get(3);
System.out.println("The fourth day of the week is " + theDay);
System.out.println("\n... Display in an ascending ordered...\n");
for(int i=0 ; i < myList.size() ; i++){
System.out.println(myList.get(i));
}
System.out.println("\nThe first day of the week is Sunday !\n");
myList.remove("Sunday");
myList.set(0, "Sunday");
myList.add(1, "Monday");
for(int i=0 ; i < myList.size() ; i++){
System.out.println(myList.get(i));
}

Display :
The fourth day of the week is Thursday
... Display in an ascending ordered...
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
The first day of the week is Sunday !

74
Created by XMLmind

XSL-FO Converter.

Sunday
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday

1.2.2.2. List implementations


There are different implementations of the List interface. We will focus on Vector, Stack, ArrayList and LinkedList.

1.2.2.2.1. Vector
Vector is a holdover from the earliest days of Java. It acts like an array but its size grows when you add more
elements. You can also insert or remove elements at any positions. Vectors are "thread safe" which means that
they cannot be used by many threads at a time.
[CODE:java]
// Methods of the Vector class
// Informations
int capacity();
void ensureCapacity(int minCapacity);
int hashCode();
int size();
void setSize(int newSize);
void trimToSize();
String toString();
// Positional Access
E get(int index);
E set(int index, E element);
void setElementAt(E element, int index);
boolean add (E element);
void add (int index, E element);
boolean addAll(int index, Collection<? extends E> c);
boolean addAll(Collection<? extends E> c);
void addElement(E element);
void clear();
void copyInto(Object[] tab);
void insertElementAt(E element, int index);
E remove(int index);
boolean remove(E element);
boolean removeAll(Collection<?> c);
void removeAllElements();
boolean removeElement(E element);

75
Created by XMLmind

XSL-FO Converter.

void removeElementAt(int index);


void removeRange(int fromIndex, int toIndex);
boolean retainAll(Collection<?> c);
// Search
int indexOf(E o);
int indexOf(E o, int index);
int lastIndexOf(E o);
int lastIndexOf(E o, int index);
boolean contains(E element);
boolean containsAll(Collection<?> c);
boolean isEmpty();
E elementAt(int index);
E firstElement();
E lastElement();
Enumeration<E> elements();
// Comparator
boolean equals(E element);
// Rangeview
List<E> subList (int fromIndex, int toIndex);
Object[] toArray();
<T> T[] toArray(T[] element);

All the functions of the parents classes and interfaces are accessible too.
1.2.2.2.1.1. Declaration
There are different ways to instantiate a Vector.

Default constructor
[CODE:java]
Vector<E> newVector = new Vector<E>();

Constructor which initiates its size. All objects of your Vector will be initiated with the null value. You may
have some memory problem with this constructor because if you pass over this initial size by adding more
elements, your Vector size will be doubled.
[CODE:java]
Vector<E> newVector = new Vector<E>(int initialCapacity);

Constructor which initiates its size and the value of increment capacity. In this case, if you overpass the
defined size, it will be increased by this value
[CODE:java]
Vector<E> newVector = new Vector<E>(int initialCapacity, int capacityIncrement);

Constructor which takes another Collection. This collection has to implement the Collection interface.
[CODE:java]
Vector<E> newVector = new Vector<E>(Collection<? extends E> aCollection);

1.2.2.2.1.2. Vector's size


Two methods allow getting the capacity and the size of a vector. Obviously those fields give two different
pieces of information. The capacity is the length of its internal data array (kept in the field elementData of the
vector) and the size is the number of components (kept in the field elementCount of the Vector). The
capacityIncrement is the amount that the size of your vector will increase by when youll overpass it.
[CODE:java]
int capacity = myVector.capacity();
int size = myVector.size();

76
Created by XMLmind

XSL-FO Converter.

Moreover the Vector class has some methods, which allow to modify these parameters :

setSize(int newSize) determinates a new size of the vector

ensureCapacity(int capacity) increases the capacity of the Vector if its necessary

trimToSize() adapts the capacity regarding the current size of the Vector.

1.2.2.2.1.3. Few methods of the Vector class

E elementAt(int index) method returns the element found at the index specified.

E firstElement() and E lastElement() method return respectively the first and the last element of the Vector.
[CODE:java]
Vector<String> myVector = new Vector<String>(5);
myVector.add("Monday");
myVector.add("Tuesday");
myVector.add("Wednesday");
myVector.add("Thursday");
myVector.add("Friday");
String firstDay = myVector.firstElement();
System.out.println("The first day of the week is " + firstDay);
String lastDay = myVector.lastElement();
System.out.println("The last day of the week is " + lastDay);
String wednesday = myVector.elementAt(2);
System.out.println("The third day of the week is " + wednesday);

Display :
The first day of the week is Monday
The last day of the week is Friday
The third day of the week is Wednesday

1.2.2.2.1.4. Stack
The Stack class inherits the Vector class. It implements methods like push() or pop() which allow to create a
LIFO (Last In First Out) stack, the last inserted element is the first which will be taken off the stack. Its better
to create a stack by implementing a collection of the API Java 2. In fact, methods of the Stack class are
synchronized and so slower.
[CODE:java]
Stack<String> myStack = new Stack<String>();

Here are some useful methods :

boolean empty() method checks if the Stack collection is empty or not. It returns true if the Stack is empty,

false if its not.

E peek() method returns the element positioned in first place in the collection.

E pop() method removes and returns the element positioned in first place in the collection.

E push(E element) adds the element in first place and returns it.

77
Created by XMLmind

XSL-FO Converter.

int search(E element) method searches the element in the stack and returns its position. Be Careful, position 1

is the first position of the stack and -1 signified that the element does not exist.
1.2.2.2.2. ArrayList
The ArrayList class looks like the Vector class. It uses an internal array to organize its data and supplies an
access to elements thanks to their indexes, optimize to add and suppress elements at the end of the list.
[CODE:java]
// Methods of the ArrayList class
//Informations
int size();
void trimToSize();
void ensureCapacity(int minCapacity);
// Positional Access
E get(int index);
E set(int index, E element);
boolean add(E element);
void add(int index, E element);
boolean addAll(int index, Collection<? extends E> c);
boolean addAll(Collection<? extends E> c);
void clear();
E remove(int index);
boolean remove(E element);
void removeRange(int fromIndex, int toIndex);
// Search
int indexOf(E element);
int lastIndexOf(E element);
boolean contains(E element);
boolean isEmpty();
// Rangeview
Object[] toArray();
<T> T[] toArray(T[] element);

All the functions of the parents classes and interfaces are accessible too.
The purpose of an ArrayList is to easily add an element to your list. In fact the internal array used is oversized.
So, an ArrayList initialized with a size of 5 will be able to contain until 20 millions elements.
When youll add a new element, it will be inserted at the first place of the internal array. You will not have to
create a new array. Obviously by adding more and more elements, the internal array will be full. In this case, a
new array will be automatically created. All of these actions are transparent.
Even if the size of the array is automatically managed, its better for your program to improve performances :

When you create a list, you usually know roughly how many elements your array will contains. So you
should create an array by indicating a size. It will avoid having too much reallocation of the internal array

Also, before adding a lot of elements you can specify a minimal size thanks to the ensureCapacity(int
minCapacity) method. Its important to use these pieces of advice if your list contains a lot of elements
1.2.2.2.2.1. ArrayList's constructors
There are 3 constructor types for the ArrayList class :

Default constructor which creates an empty ArrayList with a size of 10

78
Created by XMLmind

XSL-FO Converter.

[CODE:java]
ArrayList<String> myAList = new ArrayList<String>();

Constructor which creates an ArrayList with a capacity of initialCapacity


[CODE:java]
ArrayList<String> myAList = new ArrayList<String>(int initialCapacity);

Constructor which creates an ArrayList with a Collection giving as parameter


[CODE:java]
ArrayList<String> myAList = new ArrayList<String>(aCollection);

1.2.2.2.2.2. An ArrayList instantiation


There are 2 ways to instantiate your array :
[CODE:java]
List<String> myList = new ArrayList<String>();
//or
ArrayList<String> myList = new ArrayList<String>();

The first declaration allows to easily change the implementation (from ArrayList to Vector or LinkedList).
1.2.2.2.2.3. Few methods of the ArrayList class

void ensureCapacity(int minCapacity) method allows to provide a minimal capacity.

void trimToSize() method reduces the size of the list to be equals to the number of elements it contains.

Example :
[CODE:java]
List<String> myList = new ArrayList<String>(12);
for (int i = 0; i < 12; i++) {
myList.add("element" + i);
}
for (int i = 0 ; i < 12 ; i++) {
System.out.println(myList.get(i));
}

Display :
element0
element1
element2
element3
element4
element5
element6
element7
element8
element9
element10
element11

1.2.2.2.3. LinkedList
LinkedList are group of elements dynamically organized. It takes a lot of memory when you access elements by
their indexes, so you should better use a ListIterator (we'll see Iterator at the end of this course). A LinkedList is
the best way to manage data you do not know how many you want.
1.2.2.2.3.1. LinkedList's constructor
79
Created by XMLmind

XSL-FO Converter.

There are two types of constructors :

Default constructor which create an empty LinkedList


[CODE:java]
LinkedList<String> myLinkedList = new LinkedList<String>();

Constructor which creates the LinkedList with a Collection giving as parameter


[CODE:java]
LinkedList<String> myLinkedList = new LinkedList<String>(Collection<? extends E> aCollection);

1.2.2.2.3.2. LinkedLists specificities


The LinkedList has a lot of methods to add or extract which look like using stacks that well see later. In fact,
there are methods to add at the first or last position with addFirst() and addLast(), extract the first or the last
element with getFirst() and getLast() and remove the first or the last element with removeFirst() and removeLast().
Other functions are similar to those of other classes. More explanation on the Javadoc.
Example :
[CODE:java]
LinkedList<String> myLinkedList = new LinkedList<String>();
myLinkedList.addFirst("Ahmed");
myLinkedList.addFirst ("Ferid ");
myLinkedList.addFirst("Imad");
myLinkedList.addFirst("Yacine");
System.out.println("The first display: " + myLinkedList);
myLinkedList.removeLast();
myLinkedList.removeFirst();
System.out.println("The second display: " + myLinkedList);

Display :
The first display: [Yacine, Imad, Frid, Ahmed]
The second display: [Imad, Frid]

1.2.2.2.3.3. A FIFO Stack with LinkedList


Thanks to methods of the LinkedList class, it's easy to create a LIFO (Last In First Out) or a FIFO (First in First
Out) stack. Here is an example :
[CODE:java]
import java.util.LinkedList;
class FIFOStack<T>{
private LinkedList<T> linkedList;
public FIFOStack() {
linkedList = new LinkedList<T>();
}
public boolean isEmpty() {
return linkedList.isEmpty();
}
public void push(T element) {
linkedList.addFirst(element);
}
public T pop() {
return linkedList.removeLast();
}
public T peek() {
return linkedList.getFirst();

80
Created by XMLmind

XSL-FO Converter.

}
public int size() {
return size();
}
public String toString() {
return this.linkedList.toString();
}
}
public class Main {
public static void main(String ...args) {
FIFOStack<Integer> myStack = new FIFOStack<Integer>();
myStack.push(1);
myStack.push(2);
myStack.push(3);
myStack.push(4);
System.out.println("Default stack state : " + myStack);
System.out.println("First out : " + myStack.pop());
System.out.println("Stack state : " + myStack);
}
}

Display :
Default stack state : [4, 3, 2, 1]
First out : 1
Stack state : [4, 3, 2]

1.2.3. Set Interface


1.2.3.1. Definition
The java.util.Set collections are groups of unique elements. Whereas the List interface, a Set object cannot have
any duplicates. If a new object inserted already exist in the collection, it will not be added.
The HashSet class, which implements the Set interface, is the most commonly used.
This kind of collection grants constant performances whatever you insert, erase or search in it.
1.2.3.2. The Set interface
[CODE:java]
public interface Set<E> extends Collection<E> {
// Informations
int size();
// Positional Access
boolean add(E element);
boolean addAll(Collection<? extends E> c);
void clear();
boolean remove(E element);
boolean removeAll(Collection<?> c);
boolean retainAll(Collection<?> c);
// Search
boolean containsAll(Collection<?> c);
boolean contains(E element);
boolean isEmpty();
// Comparator
boolean equals(E element);
// Iteration
Iterator<E> iterator();
Object[] toArray();
<T> T[] toArray(T[] array);
}

81
Created by XMLmind

XSL-FO Converter.

1.2.3.3. Set implementations


1.2.3.3.1. HashSet
1.2.3.3.1.1. HashSet
The HashSet collections organize unique elements with a random order and accept only one null element.
You can't have duplicate values.
1.2.3.3.1.2. HashSet's constructors
[CODE:java]
HashSet<E> ensemble = new HashSet<E>();

This constructor is the default constructor. It initializes your collection with default values : an initial capacity of
16 and a load factor of 0.75.
[CODE:java]
HashSet<E> ensemble = new HashSet<E>(int capacity);
HashSet<E> ensemble = new HashSet<E>(int capacity, float loadFactor);

You can either indicate the minimal capacity only or the load factor too.
[CODE:java]
HashSet<E> ensemble = new HashSet<E>(Collection<? extends E> collection);

This constructor accepts a collection as parameter that will initialize the new instance.
The methods which are the most used are methods to :

add elements: add(E elt) and addAll(Collection<E> c)

remove elements: remove(E elt), removeAll(Collection<E> c), retainAll(Collection<E> c) and clear()

check elements: isEmpty(), contains(E elt) and containsAll(Collection<E> c)

82
Created by XMLmind

XSL-FO Converter.

The methods toArray() and toArray(Object[] elt) which implement the Set interface allow returning the group of
elements which are contained in the Set collection in an array.
The method iterator() return an Iterator of the elements of the collection. This Iterator object is the only way to
iterate the Set collection. We will explain what an Iterator is in a later part.
[CODE:java]
Iterator valeurs = aSet.iterator();
while(valeurs.hasNext()) {
System.out.println("Elements : " + valeurs.next());
}

1.2.3.3.2. TreeSet
1.2.3.3.2.1. TreeSet
The TreeSet class organizes a set of unique elements which are sorted by an ascending order.
The TreeSet class guaranties constant performances to basic actions like adding, removing elements.
1.2.3.3.2.2. TreeSet's constructors
[CODE:java]
TreeSet<E> aTset = new TreeSet<E>(); //default constructor

This is the default constructor. It initializes the object by giving it an ascending order for its organization.
[CODE:java]
TreeSet<E> aTset = new TreeSet<E>(Collection<E> myCollection);

This constructor takes a Collection object as parameter.


Each field will be past in the TreeSet object. Also, it initializes the object by giving it an ascending order for its
organization.
[CODE:java]
TreeSet<E> aTset = new TreeSet<E>(SortedSet<E> collection);

This constructor accepts as parameter a SortedSet object. Each element of the collection will be past in the
TreeSet.
The collection will be sorted according the order of the SortedSet object.
[CODE:java]
TreeSet<E> aTset = new TreeSet<E>(Comparator aComparator);

Here, you specify a comparator that will allow you to choose how to sort the elements.
1.2.3.3.2.3. Methods of the TreeSet class

A TreeSet object, defined without comparator, uses compareTo() and equals() methods of the elements it
contains

You can access the comparator of the collection TreeSet with the comparator() method :
[CODE:java]
Comparator aComparator = aTset.comparator();

The most used methods are :

add(Object elt) and addAll(Collection c)

83
Created by XMLmind

XSL-FO Converter.

remove(Object elt), removeAll(Collection c),retainAll(Collection c) and clear()

isEmpty(), contains(Object elt) and containsAll(Collection c)


The TreeSet class implements two methods first() and last(), which respectively return the first and the last
element.
[CODE:java]
Object firstOne = aTset.first();
Object lastOne = aTset.last();

The toArray() and toArray(Object o) methods which inherit the Set interface allow to return elements of the
collection in an array

The headSet(Object toElt) method returns only elements of the object TreeSet, which are strictly lower than
the object in parameters

The tailSet(Object fromElt) method returns only entries of the TreeMap. Their keys are strictly lower or equal
to the object in parameter

The subSet(Object fromElt, Object toElt) method extracts a part of elements which are between the element
from(subset) and toKey(offset)
1.2.3.3.3. SortedSet
The SortedSet interface is close to the SortedMap interface. It allows creating a sorted Map object which will be
sorted by key, with an ascending order or an order specified by a Comparator.
1.2.3.3.4. LinkedHashSet
1.2.3.3.4.1. LinkedHashSet
The LinkedHashSet class is the same than the HashSet class, it just keeps the insertion order of the elements.
The order is still the same if you add an element which already exists.
1.2.3.3.4.2. LinkedHashSet's constructors
[CODE:java]
LinkedHashSet<E> myLkHashSet = new LinkedHashSet<E>();

This constructor is the default constructor. It initializes your collection with default values; an initial capacity of
16 and a load factor of 0.75.
[CODE:java]
LinkedHashSet<E> myLkHashSet = new LinkedHashSet<E>(Collection c);

This constructor accepts a Collection as parameter that will initialize the new instance.
[CODE:java]
LinkedHashSet<E> myLkHashSet = new LinkedHashSet<E>(int initialCapacity);

This constructor allows affecting an initial capacity to the Collection.


[CODE:java]
LinkedHashSet<E> myLkHashSet = new LinkedHashSet<E>(int initialCapacity, float loadFactor);

This constructor allows affecting an initial capacity and a load factor to the Collection.

1.2.4. Map Interface


84
Created by XMLmind

XSL-FO Converter.

1.2.4.1. Definition
Interface java.util.Map(associations) allows storing key/value pairs.
Youll be able to find a value associated to a key if you know the key. Keys are unique but a value can be
associated to different keys.
1.2.4.2. The Map interface
[CODE:java]
public interface Map<K,V> {
// Informations
int size();
// Positional Access
void clear();
V get(K key);
V put(K key, V value);
void putAll(Map<? extends K,? extends V> t);
V remove (Object element);
// Search
boolean containsKey(Object key);
boolean containsValue(Object value);
boolean isEmpty();
int hashcode();
// Comparator
boolean equals(Object element);
// Collections return
Set<Map.Entry<K,V>> entrySet();
Set<K> keySet();
Collection<V> values();
}

You can't have twice the same key for a Map collection. It is unique.
Map objects depend of two important methods for collections working:

hashCode() which returns the hash code value of the keys

equals(E e) which tests whether two keys are equal to or not


These methods are essential because they assure the collections coherence when you use to the following
methods:

get(E key) which returns the associated value to the key

put(E key, E value) which adds an association key/value

remove(E key) which removes an association key/value corresponding to the key


So, if you add a new key/value pair and the key already exists, the value of this key will take the place of the old
value and no pair will be added.
The Map interface is extended by the SortedMap interface. This one is useful to sort maps keys.

85
Created by XMLmind

XSL-FO Converter.

1.2.4.3. Map implementation


1.2.4.3.1. HashMap
1.2.4.3.1.1. HashMap
The HashMap class is a Map interfaces implementation (see HashSet).
You can't have more than one null key on a HashMap instance, but several null values.
HashMap objects don't guaranty the order of elements, (see TreeMap). In fact, the function, which calculates the
hashcode, places element anywhere in the collection.
1.2.4.3.1.2. The HashMap Constructors
[CODE:java]
HashMap<K,V> myHashMap = new HashMap<K,V>();

This constructor is the default constructor. It initializes your collection with default values; an initial capacity of
16 and a load factor of 0,75.
[CODE:java]
HashMap<K,V> myHashMap = new HashMap<K,V>(int capacity);

You specify the initial capacity of your collection.


[CODE:java]
HashMap<K,V> myHashMap = new HashMap<K,V>(int capacity, float loadFactor);

You specify the initial capacity and the load factor of your collection.
Definitions:

The initial capacity is the initial size of the collection

The load factor defines when the capacity will have to be revaluated to eventually accept more elements
I.e. if you have a capacity of 100 for a collection and a load factor of 0.70, its capacity will be revaluated when
86
Created by XMLmind

XSL-FO Converter.

the collection will be equal to 70%. So if you want to have optimal performances you will have to specify these
fields according to your needs.
[CODE:java]
HashMap<K,V> maHashMap = new HashMap<K,V>(Map<? extends K,? extends V> collection);

This constructor accepts a collection as parameter to initialize the HashMap. Each pair of the collection will be
copied to the HashMap.
1.2.4.3.1.3. A few explanations of HashMap class' methods

put(K key,V value) and putAll(Map<? extends K,? extends V> m) methods allow respectively adding a
key/value pair and all fields of a Map collection.
These adding methods check first if keys are or are not already in the collection. If they are, new values
associated to the keys take the place of old values.
Example :
[CODE:java]
import java.util.*;
public class TestHashMap {
public static void main(String[]args) {
HashMap<String, Object> myHashMap = new HashMap<String, Object>();
String student = "Lehajam";
int[] marks = {12,14,10,7};
/* put() method */
myHashMap.put(student, marks);
int[] result = (int[]) myHashMap.get(student);
System.out.println(student + " is " + result[1]);
/* putAll() and clear() methods */
myHashMap.clear();
//you delete all elements of the HashMap object
Map<String, String> collection = new HashMap<String, String>();
collection.put("Lise", "B2");
collection.put("Lucas", "B3");
myHashMap.putAll(collection);
// you fullfil the myHashMap collection with the new
// collection thanks to putAll()
System.out.println("Lise is in grade " + (String)
myHashMap.get("Lise"));
System.out.println("Lucas is in grade " + (String)
myHashMap.get("Lucas"));
}
}

Display :
Lehajam is 14
Lise is in grade B2
Lucas is in grade B3

Remove a specific value according to its key or the remove all fields can be done thanks to the following
remove(Object key) or clear() method.
Example:
[CODE:java]
//remove a field associated to a key giving as parameter
int[] theMarks = (int[]) myHashMap.remove("Lehajam");
//remove all fields of a HashMap collection
myHashMap.clear();

You can check fields (key or value) by using isEmpty(), containsKey(Object key) and containsValue(Object
value) methods
87
Created by XMLmind

XSL-FO Converter.

Example :
[CODE:java]
if (myHashMap.isEmpty())
System.out.println("The collection is empty!");
if (myHashMap.containsKey("Lise"))
System.out.println("Lise's key has been found!");
if (myHashMap.containsValue("B3"))
System.out.println("The value 'B3' has been found!");

Display :
Lise's key has been found!
The value 'B3' has been found!

The entrySet() method returns all fields of a HashMap collection in a Set collection. The contents of this Set
collection are Map.Entry which contains the key and the value of each couple of the HashMap
Example :
[CODE:java]
Set<Map.Entry<String,String>> entries = myHashMap.entrySet();
Iterator it = entries.iterator();
while (it.hasNext()) {
Map.Entry entry = (Map.Entry) it.next();
System.out.println(entry.getKey() + " is in grade " + entry.getValue());
}

Display :
Lise is in grade B2
Lucas is in grade B3

1.2.4.3.2. TreeMap
1.2.4.3.2.1. TreeMap
The TreeMap class implements the SortedMap interface and extends the AbstractMap class.
Elements will be organized in an ascending order of the keys or thanks to a comparator that youll define when
you create your TreeMap object.
TreeMap objects offer good performances with basic operations when you extract, insert, remove or check for
some key.
1.2.4.3.2.2. TreeMap constructors
[CODE:java]
TreeMap<K,V> myTreeMap = new TreeMap<K,V>();

This is the default constructor. It initializes the object by giving it an ascending order for its organization.
[CODE:java]
TreeMap<K,V> myTreeMap = new TreeMap<K,V>(Map<? extends K,? extends V> collection);

This constructor takes a Map object as parameter. Each couple of key/value will be past in the TreeMap object.
Also, it initializes the object by giving it an ascending order for its organization.
[CODE:java]
TreeMap<K,V> myTreeMap = new TreeMap<K,V>(SortedMap<K,? extends V> collection);

This constructor takes a SortedMap object as parameters. Each couple key/value of the specified collection will
be past in the Treemap object. The collection will respect the order specified in the SortedMap object.
[CODE:java]
TreeMap<K,V> myTreeMap = new TreeMap<K,V>(Comparator<? super K> aComparator);

88
Created by XMLmind

XSL-FO Converter.

This constructor allows defining your specific Comparator to range the fields.
When there is no Comparator, the TreeMap object uses the compareTo() and equals() methods of the objects
that your collection contains.
1.2.4.3.2.3. A few explanation of the TreeMap class methods

The adding methods put(K key, V value) and putAll(Map<? extends K,? extends V> m) allow respectively
adding a couple key/value and add a Map collection

The removing method remove(Object key) and clear() allow respectively removing a couple of key/value and
removing all couples of key/value of the collection

The firstKey() and lastKey() methods return respectively the first and the last key of a Map collection
[CODE:java]
import java.util.*;
public class TestTreeMap {
public static void main(String[] args){
TreeMap<String,String> maTreeMap=new TreeMap<String,String>();
maTreeMap.put("Xuan", "Economic");
maTreeMap.put("Isabelle", "Communication");
maTreeMap.put("Fred", "Computer Science");
maTreeMap.put("Remi", "Computer Science Law");
maTreeMap.put("Marie", "Movies");
System.out.println("The first is: " + (String)maTreeMap.firstKey());
System.out.println("The last is: " + (String)maTreeMap.lastKey());
}
}

Display:
The first is: Fred
The last is: Xuan

You can access the associated comparator of your TreeMap collection thanks to the comparator() method
[CODE:java]
TreeMap<String,String> maTreeMap = new TreeMap<String,String>();
Comparator aComparator = maTreeMap.comparator();

The SortedMap collection has several methods which allow extracting the whole or part of the entries, or only
keys or values of your TreeMap object. headMap(), tailMap(), subMap(), keySet() and values() methods allow
having a specific view of the TreeMap collection:

The headMap(K toKey) method returns a SortedMap<K,V> which contains entries of the TreeMap object
which have their keys are strictly upper than the one in parameter

The tailMap(K fromKey) method returns a SortedMap<K,V> which contains entries of the TreeMap object
which have their keys lower than the one in parameter

The subMap(K fromKey, K toKey) method extracts a part of entries which are between the keys
fromKey(subset) and toKey(offset) in a SortedMap<K,V>

The keySet() method returns all keys which you can get in a Set<K> collection

89
Created by XMLmind

XSL-FO Converter.

The values() method returns all values which you can get in a Collection<V>
[CODE:java]
SortedMap<String,String> maSortMdeb = maTreeMap.headMap("Marie");
System.out.println("The first field of headMap(Marie) is "
+ (String) maSortMdeb.firstKey()
+ " and the last "
+ (String)maSortMdeb.lastKey());
SortedMap<String,String> maSortMfin = maTreeMap.tailMap("Marie");
System.out.println("The first field of tailMap(Marie) is "
+ (String) maSortMfin.firstKey()
+ " and the last "
+ (String)maSortMfin.lastKey());

Display:
The first field of headMap(Marie) is Fred and the last Isabelle
The first field of tailMap(Marie) is Marie and the last Xuan

1.2.4.3.3. IdentityHashMap
This class is really close to the HashMap class. The simple difference is that it uses to '==' to compare two
objects (and not the equals(Object o) method); that mean that itll use the equality of references and not objects.
1.2.4.3.4. WeakHashMap
The WeakHashMap class is close to the HashMap class too. Its specificity is that it keeps pairs by using weak
references. If the key is not used anywhere, the couple will be automatically removed even if there are some
trace left.
1.2.4.3.5. The SortedMap interface
1.2.4.3.5.1. The SortedMap interface
The SortedMap interface allows creating a sorted Map object which will be sorted by key, with an ascending
order or an order specify by a Comparator.
The SortedMap interface extends the Map interface but is implemented by only one class which allows creating
sorted collection; the TreeMap collection weve just seen.
The interfaces methods presented below allow to manipulate the collection easier.
[CODE:java]
Comparator<? super K> comparator();
// returns the comparator associated to the SortedMap
K firstKey();
// returns the first (lowest) key of the Sorted Map
SortedMap<K,V> headMap(K toKey);
// returns a SortedMap object which contains all elements of the
// SortedMap which are strictly before the key toKey specified.
K lastKey();
// returns the last (highest) key which is in the Sorted Map
SortedMap<K,V> subMap(K fromKey, K toKey);
// returns a SortedMap object which contains all elements of the
// SortedMap which are between the key fromKey, inclusive, and the key
// toKey, exclusive.
SortedMap<K,V> tailMap(K fromKey);
// returns a SortedMap object which contains all elements of the
// SortedMap which are after the key fromKey.

All keys inserted in a SortedMap collection have to implement the java.lang.Comparable interface or to be
accepted by the Comparator object.
Moreover youve to notice that all keys of the collection have to be comparable each other otherwise a
ClassCastException exception will be generated.

90
Created by XMLmind

XSL-FO Converter.

1.2.4.3.6. Hashtable
The Hashtable class, identical to the HashMap class, is an old class from Java 1. Its kept just for compatibility
reasons. Moreover it is synchronised. Anyway its best to use HashMap. Note that the Hashtable class has a
lower 't'.

1.3. Advanced Features


1.3.1. Iterator
1.3.1.1. The Iterator interface
[CODE:java]
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}

An Iterator allows iterating over a range of objects of any collection. You get the iterator of a collection thanks
to the Iterator iterator() method.
This Iterator interface takes the place of Enumeration. Its advantages are that it allows removing elements that
you don't know the position.
Creation of an Iterator from a collection:
[CODE:java]
Iterator it = myCollection.iterator();

So you can iterate a collection thanks to the method of the Iterator interface:
Example :
[CODE:java]
while (it.hasNext()) {
// return false if there are no elements anymore,
// true if there are
String s = (String) it.next();
// return an element and increment the index in the same time
if (s.equalsIgnoreCase("error")) {
it.remove(); // remove an element from myCollection
} else {
System.out.println(s);
}
}

The next() method of Iterator returns an object of the Object class. Thats why you have to do a cast to get the
object that you want. That means that you will have to redefine the type of the object returned.
Notice:
The remove() method can be invocated only once for a call of the next() method.
1.3.1.2. The ListIterator interface
The ListIterator is richer than the Iterator weve just seen; it allows iterating collections from the first to the last
element but from the last to the first too.
You can also add or remove elements but it works only for the List collections.
[CODE:java]
public interface ListIterator<E> extends Iterator<E>{
void add(E o);
boolean hasNext();
boolean hasPrevious();
E next();

91
Created by XMLmind

XSL-FO Converter.

int nextIndex();
E previous();
int previousIndex();
void remove();
void set(E o);
}

Notice :
The add(E o) method allows adding the element o to the collection whereas the method set(E o) allows to the
element o to take the place of the last element returned by the next() or previous() methods.

ListIterator List.listIterator() and Listiterator List.listIterator(int from) methods of the AbstractList class
return ListIterator objects which contain Vectors elements
Example :
[CODE:java]
List<String> myList = new LinkedList<String>();
maList.add("Monday");
maList.add("Tuesday");
maList.add("Wednesday");
maList.add("Thursday");
maList.add("Friday");
maList.add("Saturday");
maList.add("Sunday");
// Using listIterator() method
ListIterator li = myList.listIterator();
System.out.println("\tListIterator");
System.out.println("\n...Display in an ascending ordered...\n");
while(li.hasNext()) {
System.out.println(li.next().toString());
}
System.out.println("\n...Display in an descending ordered...\n");
while(li.hasPrevious()) {
System.out.println(li.previous().toString());
}
// Using listIterator(int from) method
ListIterator li2 = myList.listIterator(3);
// retourne les lments du vecteur partir de lindice spcifi : 3
System.out.println ("\n\tListIterator 2\n");
while(li2.hasNext()) {
System.out.println(li2.next().toString());
}

Display :
ListIterator
...Display in an ascending ordered...
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
...Display in an ascending ordered...
Sunday
Saturday
Friday
Thursday
Wednesday
Tuesday
Monday

92
Created by XMLmind

XSL-FO Converter.

ListIterator 2
Thursday
Friday
Saturday
Sunday

The subList(int from, int end) method allows the extraction of a elements collection from the List from the
index from to the index end
[CODE:java]
List<String> alist = myList.subList(1, 5);
//Extraction of the elements from index 1 to 4
Object o = alist.get(3);
//Return the element positioned at the index 3

1.3.2. Enumeration
Like with an Iterator, you can iterate a collection with an Enumeration. But its available only for Vector
(implementation of Collection, cf. Chapter 6.4.1) or Hashtable (implementation of Map, cf. Chapter 7.3.12).
You should use Iterator either than Enumeration because it has shorter methods name and has a remove
method.
In fact, the Enumeration interface has only 2 methods:
[CODE:java]
public interface Enumeration<E> {
boolean hasMoreElements();
E nextElement();
}

Example with Vector :


[CODE:java]
Vector<String> aVector = new Vector<String>();
aVector.addElement("one");
aVector.addElement("two");
Enumeration<String> e = aVector.elements();
while (e.hasMoreElements()) {
System.out.println(e.nextElement());
}

Display:
one
two

1.3.3. The Comparator interface


[CODE:java]
public interface Comparator<T> {
int compare(T t1, T t2);
}

The Comparator class has to be defined by the user. To do so, you have to write a class which will implement
the Comparator interface and redefine compare() method. The method compares only comparable objects, that
means, only objects that implements the Comparable interface. You can determine how you want to organize
your collection.
1.3.3.1. Example of using the Comparator
[CODE:java]
public class MyComparator implements Comparator<String>{
public int compare(String s1, String s2){
return s1.compareTo(s2);
}

93
Created by XMLmind

XSL-FO Converter.

1.3.4. The Comparable interface


As we said, in order to compare objects, they have to implements the Comparable interface
[CODE:java]
public interface Comparable<T> {
int compareTo(T t1);
}

String and Wrappers classes already implements Comparable


1.3.4.1. Example of using Comparable
We want to create a TreeMap collection of animals; a method compareTo(T t) has to be redefined. We decide
that the collection will be sorted by name and alphabetically.
[CODE:java]
public class Animal implements Comparable<Animal> {
private String name;
private String color;
public Animal(String name, String color) {
this.name = name;
this.color = color;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int compareTo(Animal a) {
return name.compareTo(a.getName());
}
}

To sort the collection by colors, you just have to compare the String color with the compareTo method
[CODE:java]
public int compareTo(Animal a) {
return color.compareTo(a.getColor());
}

The compareTo() method which have been defined compare the name of the current Animal with Animal a. It
returns 0 if names are equals, a positive number if the current name is upper, and a negative one if it is less.

1.4. Custom-made Collections


As youve seen it, there are a lot of collections, which are adapted to different needs. But you can create your
own collection with exactly your specific needs.
Heaps or LIFO and FIFO stacks are very used classes.

1.4.1. Heap
94
Created by XMLmind

XSL-FO Converter.

The Heap class uses an one dimensional array. It has the forthfollowing methods:
[CODE:java]
public abstract boolean upperThan(Object o1, Object o2);
// this method return true if o1 is upper than o2 and false if its not.
public boolean add(Object o);
// this method allow adding the o object by sorting the collection in an ascending way. It return true if the action is
successful.
public Object remove();
// this method remove the first element of the heap cette mthode retire le plus grand lment du tas
public void display();// display the list of the datas heap.

The Heap class:


[CODE:java]
public abstract class Heap {
private int capacity;
private int nbData = 0;
private Object[] heap;
Heap(int capacity) {
this.capacity= capacity;
heap = new Object[capacity];
}
public abstract boolean upperThan(Object o1, Object o2);
public boolean add(Object obj) {
int index;
int halfIndex;
if(nbDonnees == capacity) {
// return false if the heap is full
System.out.println("the heap is full");
return false;
}
index = nbData;
halfIndex = (index 1) / 2;
while((index > 0) && (upperThan(obj, heap[halfIndex]))) {
// you look for the position of the object you
// want to add
heap[index] = heap[halfIndex];
index = halfIndex;
halfIndex = (halfIndex 1) / 2;
}
heap[index] = obj; // you place the object at the good position
nbData++;
return true;
}
public Object remove() {
// return null if there are no elements anymore
if(nbData == 0) {
return null;
}
int index, doubleIndex, raisedIndex;
Object removedObject = heap[0];
Object movedObject = heap[nbData 1];
index = 0;
doubleIndex = 1;
nbData;
while(doubleIndex < nbData) {
raisedIndex = doubleIndex;
if((doubleIndex < nbData 1) && (upperThan(heap[doubleIndex + 1], heap[doubleIndex]))) {
raisedIndex = doubleIndex + 1;
}
if(upperThan(heap[raisedIndex], movedObject)) {
heap[index] = heap[raisedIndex];
index = raisedIndex;
doubleIndex = 2 * index + 1;
} else {
doubleIndex = nbData;

95
Created by XMLmind

XSL-FO Converter.

}
}
heap[index] = movedObject;
return removedObject;
}
public void display() {
for(int i = 0; i < nbData; i++) {
System.out.print(heap[i] + " ");
}
}
}

The upperThan() method is abstract because it will be define in a child class. In fact it will allow you managing
any kind of object.
When a class contains an abstract method, the class has to be abstract.

1.4.2. The LIFO stack (Last In First Out)


For a LIFO stack, the last added is the first treated.

[CODE:java]
boolean push(Object o);
// adds an element in the first position and return true if it's been successful
Object pop();
// removes the last element added in the stack and return it
Object peek();
// removes the last element added in the stack
boolean isEmpty();
// returns true if the stack is empty, false if it's not

You can add as much methods or elements that you want like a display method. The goal is to have a
customized class. Anyway the best solution is to use a collection of the Java 2 API, either for best performances
than an easier programming.

1.4.3. The FIFO stack (First In First Out)


Here, its the first added which is the first treated.

96
Created by XMLmind

XSL-FO Converter.

Usual methods are the following:


[CODE:java]
boolean push(Object o);
// adds an element in the first position and return true if the action as been succesful
Object pop();
// removes the last element of the stack and return it
Object peek();
// returns the last element of the stack
boolean isEmpty();
// returns true if the stack is empty, false if it's not

Like with the LIFO stack, you can customize your FIFO stack.
Here it is an example of a FIFO stack, which implements LinkedList class in the chapter 6.4.

97
Created by XMLmind

XSL-FO Converter.

Chapter 6. Input/Output
This Chapter will teach you how to :

Represent a file in Java.

Read a file and get its contents.

Read keyboard entries.

Use Pipe Streams.

Serialize objects.

Use zip to compress and decompress data.

1. Course
1.1. Introduction
1.1.1. Working With the Streams
Very often, applications need to access externals resources (files, by reaching data through a network ...). This
data transfer name is stream (data moves). Since its version 1.0, the Java language provides classes allowing
handling streams. All these classes constitute the java.io package. The name of this package is for Input/Output.
Indeed, this package allows to manage/handle input and output streams. In a general way, the principle of
handling remains same whatever the type of flow:

Opening of flow

Writing or reading of the data in flow

Closing of flow
In this course, we will study the management of input and output streams with the standard java.io package.

1.1.2. History
1.1.2.1. Version 1.0
The java.io package appeared at the same time of the creation of the Java language. Originally, the provided
classes only allowed reading and writing binaries data. In fact, those classes allow reading and writing bytes. So,
those classes work with byte streams. The following schema shows the hierarchy of java.io package in the
version 1.0.

98
Created by XMLmind

XSL-FO Converter.

We notice that this tree structure is divided in two great families: input stream (extended InputStream) and
output stream (extended OutputStream). The classes having the InputStream suffix are useful for the reading of
data while those having for OutputStream suffix allow writing. The direct subclasses of InputStream and
OutputStream are communication stream: they only allow reading and writing on the streams. FilterInputStream
and FilterOutputStream are super classes of treatment streams. They make a treatment on the data read or
written via flow of communication to which they are connected. File class is an abstract representation of file
and directory pathnames. Be careful, the File class is not abstract!
1.1.2.2. Version 1.1
With version 1.1 of the JRE, new classes were added. These classes work on streams of characters. They thus
make it possible to read and write characters (char). The following diagram presents arborescence of the classes
added to the java.io package for version 1.1.

99
Created by XMLmind

XSL-FO Converter.

As for the first classes of the package, the arborescence shows separation in two great families: the Readers and
Writers. The classes extended the abstract class Reader allow the reading on streams of characters. The classes
extended the Writer class, as for them, are useful for writing on streams of characters.

1.2. File class


1.2.1. Purpose
As seen in the chapter before, the File class is an abstract representation of all kind of files (files or repertories).
Thereafter, we will use the term "file" to indicate a file or directory. This representation is known as "abstract"
because the represented file doesnt inevitably exist.
This class is very useful to obtain information on a file or a directory. By using the property system
file.separator (in a transparent way for the developer), you can create files in a repertory without having to
trouble you about the type of system on which the application will be carried out.

1.2.2. Constructors
By creating a File object, you dont physically create a file but only a representation of a file (which exists or
not). This class has 4 constructors:

File( String pathname) : This constructor takes in parameter a string corresponding to the pathname (relative
or absolute) of the file

File( String parent, String child) : Creates a new instance from a parent pathname string and a child
pathname string

100
Created by XMLmind

XSL-FO Converter.

File( File parent, String child) : Creates a new instance from a parent abstract pathname and a child
pathname string

File( URI uri) : Creates a new instance by converting the given file: URI into an abstract pathname. An URI
(Uniform Ressource Identifier) is quiet similar to an URL. Here the schema is file :, this URI must be
hierarchical. Here are few instances of URI :
http://java.sun.com/j2se/1.3/
docs/guide/collections/designfaq.html#28
../../../demo/jfc/SwingSet2/src/SwingSet2.java
file:///~/calendar

1.2.3. The Principal methods


boolean canRead() : Tests whether the application can read the file denoted by this abstract pathname

boolean canWrite() : Tests whether the application can modify to the file denoted by this abstract pathname

boolean createNewFile() : Atomically creates a new, empty file named by this abstract pathname if and only
if a file with this name does not yet exist

boolean delete() : Deletes the file or directory denoted by this abstract pathname

boolean exists() : Tests whether the file or directory denoted by this abstract pathname exists

String getAbsolutPath() : Returns the absolute pathname string of this abstract pathname

String getName() : Returns the absolute pathname string of this abstract pathname

File getParentFile() : Returns the abstract pathname of this abstract pathname's parent, or null if this
pathname does not name a parent directory

boolean isDirectory() : Tests whether the file denoted by this abstract pathname is a directory

boolean isFile() : Tests whether the file denoted by this abstract pathname is a normal file

String[] list() : Returns an array of strings naming the files and directories in the directory denoted by this
abstract pathname

File[] listFiles() : Retourne Returns an array of abstract pathnames denoting the files in the directory denoted
by this abstract pathname. These two methods can take in parameters a FilenameFilter to filter the files
contained in the directory

boolean mkdir() : Creates the directory named by this abstract pathname

101
Created by XMLmind

XSL-FO Converter.

boolean mkdirs() : Creates the directory named by this abstract pathname, including any necessary but
nonexistent parent directories

1.3. Byte Streams


In this chapter, we will study the classes introduced in the version 1.0 of Java and working with data in bytes
form.

1.3.1. Input Streams


The objects allowing the reading of binary data streams all extend the abstract class InputStream. The various
objects inheriting InputStream provide methods allowing the sequential reading (we move in the stream) of
bytes.
1.3.1.1. InputSream
InputStream is the super class of all those representing a byte input stream.
Each subclass must redefine a method read() returning the next byte on the input stream. With each call of this
method we move one byte ahead on the stream. Although a byte is 8 bits the method read() returns an int (32
bits). Indeed, it is more usual to work with integers than bytes; moreover there is no problem of conversion, an
int is stronger than byte. If the end of the stream was reached and that we cannot read any more, the method
returns the 1 value.
The class also provided two other read() methods:

int read(byte[] b) : With this method, you can read more than only one byte each time. Indeed, the read bytes
are store in the array given in parameter, replacing possible old values. The method reads as much bytes as it
can store in the array and as much as it can read on stream. The method returns the real number of read bytes
and 1 if it cannot read (end of stream)

int read(byte[] b, int off, int len) : The principle is similar to the preceding method, however instead of
filling out the array from the first position, it starts to write the bytes at the specified index (off) of the array.
The parameter len corresponds to the maximum number of byte to read. Thus pay attention so that your array
has the necessary size. As for the preceding method the returned int corresponds to the real number of read
bytes and to 1 if nothing could be read
This class also provides other useful methods for its subclasses:

int available() : Returns the number of bytes that can be read (or skipped over) from this input stream
without blocking by the next caller of a method for this input stream

close() : Closes this input stream and releases any system resources associated with the stream. This should
always be called once you finished working with the stream

mark(int readlimit) : Marks the current position in this input stream. A subsequent call to the reset() method
repositions this stream at the last marked position so that subsequent reads reread the same bytes. The
readlimit arguments tells this input stream to allow that many bytes to be read before the mark position gets
invalidated

reset() : Repositions this stream to the position at the time the mark()method was last called on this input
stream

102
Created by XMLmind

XSL-FO Converter.

boolean markSupported() : Tests if this input stream supports the mark() and reset() methods.

skip( long n) : Skips over and discards n bytes of data from this input stream
1.3.1.2. Communication Streams
The InputStream subclasses are communication streams. They allow sequential reading of bytes on the specific
stream that they represent.
Here are the principal classes that extend InputStream:

ByteArrayInputStream: Contains an internal buffer that contains bytes that may be read from the stream.
An internal counter keeps track of the next byte to be supplied by the read method. Closing a
ByteArrayInputStream has no effect.
[CODE:java]
byte[] byte1 = new byte[1000];
FileInputStream fis = new FileInputStream("object.obj");
fis.read(byte1);

ObjectInputStream: Deserializes primitive data and objects. It will be studied in detail at the 5th chapter.
[CODE:java]
try {
FileInputStream fis = new FileInputStream("object.obj");
ObjectInputStream ois = new ObjectInputStream(fis);
/*
* Get the object into the file
*/
MonObject object = (MonObject) ois.readObject();
object.getName();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

SequenceInputStream: Represents the logical concatenation of other input streams. It starts out with an
ordered collection of input streams and reads from the first one until end of file is reached, whereupon it reads
from the second one, and so on, until end of file is reached on the last of the contained input streams.

StringBufferInputStream: This class and all its methods are deprecated. We will not study this one because
it should be used.
1.3.1.3. Treatment Streams
The following classes are under classes of FilterInputStream. They make a treatment on the data read on an
associated flow of communication. The communication stream (InputStream) passed in parameter to the
constructor.

BuffferedInputStream: This class has an internal buffer. It adds the ability to buffer the input and to support
the mark() and reset() to another input stream.

DataInputStream : A data input stream lets an application read primitive Java data types from an underlying
103
Created by XMLmind

XSL-FO Converter.

input stream in a machineindependent way. An application uses a data output stream to write data that can
later be read by a data input stream. It represents Unicode strings.

LineNumberInputStream: This class is deprecated.

PushbackInputStream: Adds functionality to another input stream, namely the ability to "push back" or
"unread" one byte. This is useful in situations where it is convenient for a fragment of code to read an
indefinite number of data bytes that are delimited by a particular byte value; after reading the terminating
byte, the code fragment can "unread" it, so that the next read operation on the input stream will reread the
byte that was pushed back.

Scanner : With this class, it is possible for you to read the contents of a file and to recover according to a
regular expression the various elements of the file (the default delimiter is space but it is possible to modify it
with the method useDelimiter()):
[CODE:java]
Scanner sc = new Scanner(new FileInputStream("data.txt"));
System.out.println(sc.next());

Here how to recover information in the file data.txt according to:


1 other 2 test

Example of sequential read:


[CODE:java]
Scanner sc = new Scanner(new FileInputStream("data.txt"));
//Read the next which is an int
System.out.println(sc.nextInt());
//Read the next which is a text
System.out.println(sc.next());
//Read the next which is an int
System.out.println(sc.nextInt());

The delimitor by defect is space but it is possible to redefine it:


[CODE:java]
Scanner sc = new Scanner(new FileInputStream("data.txt"));
//Change the delimiter
sc.useDelimiter( Pattern.compile("MyDelimitor"));
System.out.println(sc.nextInt());
System.out.println(sc.next());
System.out.println(sc.nextInt());

1.3.1.4. Example of reading


This example shows in a simple way the reading of the 53 first bytes of a file (an image).
[CODE:java]
import java.io.*;
public class BinaryReaderInFile {
public static void main(String[] args) {
byte[] buffer = new byte[53];
try{
FileInputStream fis = new FileInputStream("C:\\java.gif");
int i = fis.read(buffer);
String s = new String(buffer);
System.out.println(s);
System.out.println(i);
}catch(FileNotFoundException e){
System.out.println("File not found");
}catch(IOException e){
System.out.println("Cant read");
}

104
Created by XMLmind

XSL-FO Converter.

}
}

1.3.2. Output Streams


All the objects allowing reading of binary data on a stream extend the abstract class OutputStream. These
objects provide methods allowing sequential bytes reading. For the majority of the InputStream corresponds a
OutputStream as we will see it in chapter 3.2.2 and 3.2.3.
1.3.2.1. OutputStream
OutputStream is the super class of all which represent an output byte stream.
Each subclass must always redefine at least a write(int b) method taking a byte as parameter (although contained
in an int) to be written on the output stream.
The class provides also two other methods write() :

int write(byte[] b) : Writes b.length bytes from the specified byte array to this output stream

int write(byte[] b, int off, int len) : Writes len bytes from the specified byte array starting at offset off to this
output stream
It provides two other useful methods:

close() : Closes this output stream and releases any system resources associated with this stream. This method
must always be called at the end of writing

flush() : Flushes this output stream and forces any buffered output bytes to be written out
1.3.2.2. Communication Streams
Here is the list of the classes allowing writing of data in bytes form:

ByteArrayOutputStream: Implements an output stream in which the data is written into a byte array. The
buffer automatically grows as data is written to it. The data can be retrieved using toByteArray() and
toString(). Closing a ByteArrayOutputStream has no effect.

FileOutputStream: An output stream for writing data to a File or to a FileDescriptor. Whether or not a file is
available or may be created depends upon the underlying platform. Some platforms, in particular, allow a file
to be opened for writing by only one FileOutputStream: (or other filewriting object) at a time. In such
situations the constructors in this class will fail if the file involved is already open. It is possible to specify at
the instantiation if the data should be append or not. By default, the new data replace the old ones.

ObjectOutputStream: Allows the serialization of data. This will be discuss in detail in the chapter 5.
[CODE:java]
FileOutputStream fos = new FileOutputStream("object.obj");
ObjectOutputStream oos = new ObjectOutputStream(fos);
MonObject object = new MonObject();
oos.writeObject(object);

The generated contents are not comprehensible by human.


1.3.2.3. Treatment Streams

105
Created by XMLmind

XSL-FO Converter.

The following classes extend FilterOutputStream and allow you to make a treatment on the data to be written

BuffferedOutputStream: The class implements a buffered output stream. By setting up such an output
stream, an application can write bytes to the underlying output stream without necessarily causing a call to the
underlying system for each byte written

DataOutputStream: Lets an application write primitive Java data types to an output stream in a portable
way. An application can then use a data input stream to read the data back in
Nous avons un fichier data.txt qui contient :
Test de mon fichier data
Seconde ligne

Voici le code qui va lire et afficher la premire ligne :


[CODE:java]
FileInputStream fis = new FileInputStream("data.txt");
DataInputStream dis = new DataInputStream(fis);
System.out.println(dis.readLine());

PrintStream: Adds functionality to another output stream, namely the ability to print representations of
various data values conveniently (primitives, String or Object via the toString() method).

1.4. Characters Stream


In this chapter, we will study the classes introduced in the version 1.1 of Java and working with data in
characters form. Concepts and methods used for the bytes streams were adapted to characters streams. There are
big similarities with what we have seen in the chapter 3.

1.4.1. Input Streams


Objects allowing reading on characters streams inherit all the abstract class Reader. They provide methods
allowing the sequential reading of characters.
1.4.1.1. Reader
The Reader classe provides methods allowing reading characters. These read() methods are similar to those of
the bytes stream. The only abstract method it declares is the int read(char[] cbuff, int off, int len) method.

int read() : Reads a single character and returns it as an int. To really use it as a character (char), it is
necessary to make an explicit conversion (cast)

int read(char[] cbuff) : Read characters into an array

int read(char[] cbuff, int off, int len) : Read characters into a portion of an array, from off position to len
The Reader class also provides close(), mark(int readlimit), markSupported(), reset(), skip(long n) methods. She
has also a boolean ready() method which tests whether this stream is ready to be read without blocking the
stream.
1.4.1.2. Communication Streams

FilterReader: This abstract class is used to read filtered character streams. It provides default methods that
pass all requests to the contained stream. Subclasses of this class have to override some of these methods but
106
Created by XMLmind

XSL-FO Converter.

may also provide additional methods.

PipedReader: This class will be connected to a PipedWriter, with the connect(PipedWriter p) method or
when you instantiate it with PipedReader(PipedWriter p).

InputStreamReader: This class will allow the communication between byte streams to character streams. It
reads bytes and decodes them into characters using a specified Charset.You can define this Charset with
InputStreamReader(InputStream in, Charset cs) or let the platform default charset.
1.4.1.3. Treatment Streams

StringReader: This class is a character stream created from a string. This string will be specified thanks to
the constructor: StringReader(String s).

CharArrayReader: This class implements a character buffer and can be used as character input stream.
BufferedReader : This class allows reading characters input stream. If the size hasnt been specified, it will
be the default size:

BufferedReader( Reader in)

BufferedReader( Reader in, int size)

1.4.2. Output Streams


It allows writing characters streams. Those one implement Writer abstract class. So well present you these
classes, which allow writing streams.
1.4.2.1. Writer
This abstract class allows writing character streams. Subclasses have to implement the following methods:

close() : to close a stream( you have to use it after flush())

flush() : allows flushing streams

write(char[] cbuf, int off, int len): allows writing a portion of an interval of an array characters
1.4.2.2. Communication Streams

FilterWriter: Abstract class will allow writing filtered character streams. It provides default methods that
pass all requests to the contained stream. Subclasses should override some of these methods
PrintWriter: This method implements all methods of PrintStream class. Methods of PrintWriter doesnt
generate any exception, so the user will have to handle it by himself, with the checkError() method
1.4.2.3. Treatment Streams

107
Created by XMLmind

XSL-FO Converter.

BufferedWriter: Allow writing text to a character output stream by memorize characters to an efficient
character writing

OutputStreamWriter: This class will allow the communication between character streams to byte streams

CharArrayWriter: This class implements a character buffer that can be used as a Writer. The buffer
automatically grows when data is written to the stream

StringWriter: This class is a character stream that collects its output in a string buffer which can be used to
construct a String

1.5. Standard Input Keyboard


Get the keyboard inputs is important in almost all the Console applications. Well present you the method.

1.5.1. System.in
Just like the writing in the Console uses the final class System, the reading of keyboard entries is doing by
getting the in property, of InputStream type.
Thus, the standard input (generally keyboard) is symbolized by System.in.

1.5.2. Methods of reading


It is known that the property in of System is an object InputStream. It is thus enough to use a class taking
InputStream in argument of its constructor and to use the methods of reading of this class. There are thus several
ways of proceeding (according to the type of entries until you wait).
Here a method:
[CODE:java]
BufferedReader keyboardIn = new BufferedReader(new InputStreamReader(System.in));
String s;
try {
while((s= keyboardIn.readLine()) != null && s.length != 0)
System.out.println(s);
} catch(IOException e) {
e.printStackTrace();
} finally {
keyboardIn.close();
}

Another interesting way is to use the Scanner class (this one appeared with Java 5). The power of this class lies
in its methods allowing fine management of the regular expressions and thus the parsing of your entry (that it is
System.in or a file). An example:
[CODE:java]
Scanner keyboardIn = new Scanner(System.in);
while(keyboardIn.hasNext())
System.out.println(keyboardIn.next());
keyboardIn.close();

1.6. Pipe Streams


1.6.1. Goal
The Pipe Streams are using to link two threads, inspired by the Pipe of UNIX system. The data will be transport
by the Pipe between the two threads. For example, set up a Pipe could be useful in the case of several data
treatments, where the result of one method would be passed on the Pipe and used as argument by another
108
Created by XMLmind

XSL-FO Converter.

method (every method being in a different thread). The following plan illustrates its functioning:

A writer thread writes the data in the pipe which will be read then treated by the reader thread.

1.6.2. The Classes


As all the classes of java.io package, there are classes dedicated to Pipes for bytes streams and others for chars
streams.
1.6.2.1. PipedInputStream and PipedOutputStream
PipedOutputStream to insure the communication; its constructor takes a PipedOutputStream in argument.
[CODE:java]
PipedOutputStream pos = new PipedOutputStream();
try {
PipedInputStream pis = new PipedInputStream(pos);
} catch (IOException e) {
e.printStackTrace();
}

If a PipedInputStream is instantiated without argument, you could use the method connect(PipedOutputStream
pos) which will create the connection with the corresponding PipedOutputStream.
For reading you have numerous methods:

int read(): returns the byte read in the pipe

int read(byte[] b, int off, int len): reads len bytes from the specified byte array starting at offset off , result
puts in b

void receive(int b): the next byte read is put in b


PipedOutputStream is thus going to take charge of the writing of bytes in the Pipe.
It has classic methods of writing:

void write(int b): with this method, you write one byte at the time

void write(byte[] b, int off, int len): allows writing a portion of an interval of array bytes
1.6.2.2. PipedReader and PipedWriter
Similar to the classes seen above, PipedReader and PipedWriter, respectively sub class of Reader and Writer,
are using to create a Pipe of chars streams between 2 threads. In the same way, PipedReader must be instantiate
109
Created by XMLmind

XSL-FO Converter.

with a PipedWriter in argument (or subsequently connect by the method connect()).


PipedReaders methods of reading:

int read(): Reads a single character and returns it as an int. To really use it as a character (char), it is
necessary to make an explicit conversion (cast)

int read(char[] cbuff, int off, int len): Read characters into a portion of an array, from off position to len

int read(char[] cbuff): the data read are inserted in the table cbuff
PipedWriters methods of reading:

write(String s): writes the String s in the Pipe

write(char[] cbuf, int off, int len): allows writing a portion of an interval of array characters

1.6.3. Example of Use


The following program shows the use of Pipe streams.
Here the reading thread, which will get the date from the Pipe and print them in the console:
[CODE:java]
import java.io.PipedReader;
import java.io.IOException;
public class MyReaderThread implements Thread {
private PipedReader pr;
public MyReaderThread(PipedReader pr){
this.pr = pr;
}
public void run(){
try {
char[] entry = new char[19] ;
pr.read(entry) ; //we read an entry and put it in char[]
pr.close() ;
System.out.println (entry) ;
} catch(IOException e){
e.printStackTrace() ;
}
}
}

The writing thread, send a String in the Pipe :


[CODE:java]
import java.io.PipedWriter;
import java.io.IOException;
public class MyWriterThread implements Thread {
private PipedWriter pw;
public MyWriterThread(PipedWriter pw){
this.pw = pw;
}
public void run(){
try {
pw.write("The Pipe is working"); //we write a String
pw.close() ;
} catch(IOException e){
e.printStackTrace() ;}
}

110
Created by XMLmind

XSL-FO Converter.

Finally the main class, which creates the Pipe (by instantiate PipedWriter and PipedReader) then instantiate the
threads and start them:
[CODE:java]
import java.io.PipedWriter;
import java.io.PipedReader;
import java.io.IOException;
public class MainTest {
public static void main(String[] args){
try {
PipedWriter pw = new PipedWriter() ;
PipedReader pr = new PipedReader(pw) ; //connection created
MyReaderThread reader = new MyReaderThread(pr) ;
MyWriterThread writer = new MyWriterThread(pw) ;
reader.start() ; //starting up of threads
writer.start() ;
} catch(IOException e){
e.printStackTrace() ;}
}
}

1.7. RandomAccessFile
The RandomAccesFile class support both reading and writing (in a direct way, not sequential) to a random
access file. A random access file behaves like a large array of bytes stored in the file system. The pointer of this
table is positionable. This class implements the interfaces DataInput and DataOutput.

1.7.1. Constructors
There are two constructors:

RandomAccessFile(File file, String mode) : instantiates an object on the File file in the selected mode

RandomAccessFile(String filePath, String mode): the object is instanciate on the file whose path passed in
argument
Examples:
[CODE:java]
//Create an instance of RandomAccess mode with reading and writing mode
RandomAccessFile inout = new RandomAccessFile("hello.dat","rw");
[CODE:java]
//Use a File to create the RandomAccessFile with reading mode
File myFile = new File("C:\\file.txt");
RandomAccessFile in = new RandomAccessFile(myFile,"r");

1.7.2. Modes
Table 6.1.
MODE

MEANING

"r"

Reading only

"rw"

Reading and writing

"rws" and "rwd"

Like rw , plus writing must be synchronous


(blocking writing)

1.7.3. Methods
You will find many methods concerning the reading and the writing (one for each type, refer to JavaDoc where
111
Created by XMLmind

XSL-FO Converter.

necessary). Here the most useful methods:

void Seek(long pos): the pointer is positioned with pos

long getFilePointer(): returns the current position of the pointer

long length(): returns the length of the file

void writeUTF(String str): writing String str in the file according to encoding UTF8

String readUTF(): reads a String

void write(int b): with this method, you write a byte at the same time

void write(byte[] b, int off, int len): This principle makes it possible at the same time to write several bytes,
which will be sent in the form of a table. However instead of writing on flow the entirety of the table, it starts
to write the bytes starting from the position (offset) off the table. The parameter len corresponds to the
number of bytes to write

1.7.4. Example
The following code shows the use of RandomAccessFile; the principle and the handling of the pointer and the
read/write:
[CODE:java]
RandomAccessFile inout = new RandomAccessFile("hello.dat","rw");
inout.writeUTF("Hello World");
System.out.println(("Pointer is at: "+ inout.getFilePointer());
inout.seek(6);
System.out.println(("Pointer is at: "+ inout.getFilePointer());
inout.writeUTF("Java!");
inout.seek(0);
System.out.println(inout.readUTF());
inout.close();

1.8. Wrapped Streams


1.8.1. Problematic
To solve some IO problems, its interesting and useful to work with wrapped streams. This comes to use several
classes to perform a specific process. We need to use compatible classes, which means they must inherit form
the same abstract classes.

1.8.2. Example

112
Created by XMLmind

XSL-FO Converter.

In this example, one FileReader object is instantiated on a file, to read it. This FileReader is used as argument to
instantiate a BufferedReader, which will allow using faster reading methods. We notice a third class is added,
LineNumberReader, to simplify the line process. We observe these classes inherit from the same abstract class
(here Reader), that is prerequisite to build wrapped streams.
Here, the goal is to read this file. However, we want to read it line by line, moreover we wish this reading to be
efficient (quick). The constructor of BufferedReader accepts an instance of any Reader subclass (such as
LineNumberReader). Compose new variations of an operation is the reason to use these different classes. Its
the objective of the Decorator design pattern.
[CODE:java]
public class WrappingReading {
public WrappingReading(File source2read){
String s;
try {
FileReader simpleReader = new FileReader(source2read);
BufferedReader bufferReader = new
BufferedReader(simpleReader);
LineNumberReader lineReader = new
LineNumberReader(bufferReader);
while((s = lineReader.readLine()) != null){
System.out.println(s);
}
System.out.println(source2read.getName() + " is a file
of " + lineReader.getLineNumber() + " lines.");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}

1.8.3. Constraints
Using wrapped streams require following some rules to avoid the problems. Proceed with the previous example.
The FileReader instance is created with a File argument. This FileReader is used as argument to create a
BufferedReader object. The same goes for LineNumberReader object, which uses the BufferedReader object. In
that case, its better to only use the BufferedReader object. To generalize, let us say that wrapping object
(meaning the decorator) is the only stream to use.
113
Created by XMLmind

XSL-FO Converter.

Indeed, if you closed the wrapped stream before the first utilization of the wrapping stream, this last one hasnt
been able to establish a connection with the data source, and that will trigger an exception. Use the wrapped
stream could also head to synchronization problems, because it will move the pointer on the source and lead to
unexpected situations.

To sum up and to stay clear from problems, respect this rules when you are using streams sequence:

Only use the upper stream (the wrapping object)

Close all the streams just when all the processes are done

1.9. Serialization
1.9.1. Goal
By default, in Java the objects are transitory. Indeed, as soon as the application terminates, the objects are
destroyed. It is then impossible to recover the data when the application restarts. So its important to be able to
stock these data on another external resource than the JVM memory.
The solution is serialization. Serialization will allow stocking Java objects in any stream. Objects will be
persistent because they exist even after the running of the program. After being physically saved they can be
recovered at another time. In this case we call it deserialization.
The stored data are the specific variables of the objects. Thus it is not really the object itself which is stored (the
methods are not preserved) but its internal state (its variables). At the deserialization time, it is necessary to have
the original class (the byte codes) to rebuild the object.

1.9.2. Serializable interface and transient keyword


The primitive types Java can be preserved physically without any particular constraint. It does not need to set up
a particular process. On the other hand, it is (normally) impossible to store any object.
The solution to serialize an object is the Serializable interface. Once Implemented, the object becomes
persistent. Its fields and their values can thus be stored on any support. However if these variables are
themselves objects, they will have to also implement Serializable.
Many classes provided with the JRE implement Serializable interface. It is not necessary sub classifying them
and it is very easy to store your own objects having for variables standard objects.
However it can be problematic to store all the values of the variables. That can, indeed, posed problems of
safety. Java provides for this reason the transient modifier. The variables declared with the transient modifier
will be stored (type and name) but not their values. Once deserialized, they will have the default values: 0 for
the numbers, false for a boolean and null for the objects.

1.9.3. Storing objects


As we have just seen it, the goal of the serialization is to be able to store objects apart from the memory of the
JVM.

114
Created by XMLmind

XSL-FO Converter.

The principle consists to write the object (like any other type of data) in a stream.
It is the ObjectOutputStream class which allows this operation via its method writeObject(Object obj). Passing
the object to be stored as parameter, it writes it in the communication stream.
Here is an example of serialization of an object implementing the Serializable interface:
Example of serialization:
First, we create a persistent class. Here, the class Animal.
[CODE:java]
import java.io.Serializable;
public class Animal implements Serializable {
int age;
boolean vaccine;
String color;
Animal(){
this.age = 0;
this.vaccine = false;
this.color = "";
System.out.println("Creation of an animal!");
}
Animal(int a, boolean v, String c){
this.age = a;
this.vaccine = v;
this.color = c;
System.out.println("Creation of an animal!");
}
}

Then we make a class to serialize the object.


[CODE:java]
import java.io.*;
public class Serial {
public static void main(String[] args) throws IOException{
Animal dog = new Animal(5, true, "black");
FileOutputStream fos = new
FileOutputStream("SaveAnimal.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(dog); // Serialization
oos.close(); // We close the stream
}
}

1.9.4. Recovering an object


The purpose of persistence is to be able reused an object created previously. One thus needs a mechanism
allowing of reconstitutes this object state, in order to use it again. This action is call deserialization.
The deserialization consists in reading an object on a stream. We do it thanks to the readObject() method of the
ObjectInputStream class. This class represents a treatment stream connected to a communication stream. The
readObject() method will read the next object present in stream. This returns an Object. It is just necessary to
reconvert this object into its original type (cast) to handle it (to reach its methods and variables) as at its origin.
In the following example, we deserialize the animal serialized in the previous example.
[CODE:java]
import java.io.*;
public class Deserial {
public static void main(String[] args) throws IOException,
ClassNotFoundException{
FileInputStream fis = new FileInputStream(args[0]);
ObjectInputStream ois = new ObjectInputStream(fis);
Animal obj = (Animal)ois.readObject();

115
Created by XMLmind

XSL-FO Converter.

ois.close();
System.out.println("Age = " + obj.age);
System.out.println("Color = " + obj.couleur);
if (obj.vaccine){
System.out.println("Vaccine!");
}
}
}

1.10. Working With ZIP Files


In this chapter we will see how to compress data using the widely known ZIP compression. The java.util.zip
package provides the necessary classes to use this compression. The JRE provides classes allowing compressing
in other formats too (like GZip and Jar) but the principles are the same.

1.10.1. Compression
The ZipOutputStream class handle data compression with the write(byte[] b, int off, int len) method. This
method is linked with a stream where compressed data will be available (this stream in given as a parameter to
the constructor of this class). The following example show you how to compress files.
[CODE:java]
try {
FileOutputStream fos = new FileOutputStream("C:\\dev\\archive.zip");
ZipOutputStream zos = new ZipOutputStream(fos);
zos.write(data, 0, count);
// byte[] data holds the data to be compressed
// 0 means that it starts a the beginning of the data
// count is the number of bytes that are written
...
zos.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}

A Zip archive is composed of many ZipEntry objects. A ZipEntry represents a file or a directory inside the Zip
archive. So you have to create a ZipEntry every time you want to add a file/directory into the Zip archive. Its
constructor takes a String as first parameter which designates the location of the entry inside the archive (often
the filename). An item is added to the ZipOutputStream with the putNextEntry(ZipEntry) method. Every data
written to the stream will be associated to this item until the closeEntry() method is called.
You can find a complete example of compression in the next example.
[CODE:java]
import java.io.*;
import java.util.zip.*;
public class Zip {
static final int BUFFER = 2048;
public static void main(String args[]) {
try {
// File creation
FileOutputStream fos = new FileOutputStream("C:\\dev\\archive.zip");
// Creation of the ZIP stream
ZipOutputStream zipos = new ZipOutputStream(fos);
byte[] data = new byte[BUFFER];
// Opening of the file to compress
FileInputStream fis = new FileInputStream("C:\\file.txt");
// Item creation for the existing file
ZipEntry ze = new ZipEntry("file.txt");
// On place litem dans le zip
zipos.putNextEntry(ze);
int count;
// Reads the whole file
while ((count = bis.read(data, 0, BUFFER)) != 1) {
// Writing to the compression stream
zipos.write(data, 0, count);
}

116
Created by XMLmind

XSL-FO Converter.

// Item closing
zipos.closeEntry();
// Zip closing
zipos.close();
fis.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}

1.10.2. Decompression
Decompression is done with the read(byte[] b, int off, int len) method of the ZipInputStream class. This method
reads data corresponding to a ZipEntry. So you have to retrieve a ZipEntry before calling the read() method.
This is done with the getNextEntry() method. The getName() method of the ZipEntry class allows you to
retrieve the original filename.
[CODE:java]
import java.io.*;
import java.util.zip.*;
public class UnZip {
static final int BUFFER = 2048;
public static void main(String args[]) {
try {
// Creation of the reading stream (ZIP file to decompress)
FileInputStream fis = new FileInputStream("C:\\dev\\archive.zip");
// Creation of the decompression stream
ZipInputStream zis = new ZipInputStream(fis);
ZipEntry entry;
// Each item is retrieved
while ((entry = zis.getNextEntry()) != null) {
int count;
byte[] data = new byte[BUFFER];
// Creation of the destination file
FileOutputStream fos = new FileOutputStream("C:\\Unziped\\" + entry.getName());
// The whole file is read
while ((count = zis.read(data, 0, BUFFER)) !=1) {
// Data are written
fos.write(data, 0, count);
}
// The destination file is closed
fos.close();
}
// The archive is closed
zis.close();
fis.close();
} catch(Exception e) {
e.printStackTrace();
}
}
}

117
Created by XMLmind

XSL-FO Converter.

Chapter 7. Sockets
Have an introduction to Sockets

Learning how to use them

1. Cours
1.1. Introduction
This course goal is to teach you how to use the java.net package containing the required stuffs for network
programming. The java.net and javax.net packages as well as the classes which they provide make Java a really
good network programming language. The java.net packages classes encapsulate the socket concept of the
Berkeley Software Distribution (BSD) project, created at the Berkeley University in California.

1.1.1. Bases of networking


In 1978, at the Berkeley University, Bill Joy was with the head of a project intended to bring some important
evolutions to the UNIX system like virtual memory or fullscreen display functionalities. In 1984, Bill Joy
decided to leave this project to found Sun Microsystems, and then launches a 4.2 version of BSD UNIX also
called the Berkeley UNIX and including some functionalities of network communication. The communication
support delivered with this 4.2 version has became a standard for the Internet. Quickly the sockets were adopted
for the network and interprocess communications, and then the concept was integrated at the end of 80 to
Windows and Macintosh.

1.1.2. Sockets
A socket is an end point in a bidirectional communication between to program working on a network. A socket
is associated to a port number so that the TCP layer can identify the application towards the data has to be
transmitted. Under normal operation, a server application works on a computer and owns a listening socket
associated to a listening port. The server waits for a connection request from the client on this port.

If all occurs well, the server accepts the connection. Following this acceptance, the server creates a new socket
associated to a new port. Thus he will be able to communicate with one or many clients using the same socket.

1.2. Network Programming in Java


118
Created by XMLmind

XSL-FO Converter.

1.2.1. java.net et javax.net


The java.net and javax.net packages furnish these classes and interfaces :

IP Address : InetAddress

TCP Socket : Socket, ServerSocket, JSSE (Java Secure Socket Layer)

UDP Socket : DatagramSocket, DatagramPacket

MultiCast Socket : MulticastSocket, DatagramPacket

Application layer classes (OSI) : URL, URLConnection, HttpURLConnection, JarURLConnection


In this course we wont see JSSE, MulticastSocket and the URL.
1.2.1.1. java.net.InetAddress
The InetAddress class represents an IP protocol address, composed by an IP and a host name.
This class can be seen as the IP address representation and is used by the Socket and DatagramSocket class.
The following three methods are for the DNS resolution :
To obtain the address or the addresses whose name passed in parameter :
[CODE:java]
public static InetAddress getByName(String hostname) throws UnknownHostException
[CODE:java]
public static InetAddress[] getAllByName(String hostname) throws UnknownHostException

To obtain the local address :


[CODE:java]
public static InetAddress getLocalHost() throws UnknownHostException

1.2.1.2. Connected mode socket (TCP)


The TCP/IP sockets are used to establish reliable flow, bidirectional and point to point between differents
computers on the Internet.
The sockets can also permit a Java application to communicate with another application of the localhost
anywhere on the Internet.
In connected mode (TCP), a reliable connection is established between client and server (error control packets
resend and so on).
Java considers two types of TCP sockets :

The ServerSocket class allows you to implement the server. It waits for a connection request and then accept
it.

The Socket class allows you to implement a client. He asks for the connection establishment with the server.
We will find the communication methods in this class.

119
Created by XMLmind

XSL-FO Converter.

The communication execution process by socket in connected mode is presented below :

Server ( java.net.ServerSocket )
Use :
Creation of a listening socket :
[CODE:java]
ServerSocket Server = new ServerSocket(port);

Wait for the request and creation of a communication Socket :


[CODE:java]
Socket Communication = Server.accept(); // blocking on standby of connection

The communication will be done by the means of the Socket class


Constructors :
[CODE:java]
public ServerSocket(int port) throws IOException // Create a socket listening to the specified port.
[CODE:java]
public ServerSocket(int port, int backlog) throws IOException
/* Create a socket listening to the specified port, specifying the size of
the connection queue */
[CODE:java]
public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException
/* Create a socket listening to the specified port, specifying the size and
the request of connection queue, and restricting the address on which we
accept the connection. */

Useful methods :
[CODE:java]
public Socket accept() throws IOException /* Accept the connection and return a new socket */

The method above blocks the application, but you can set a time out with the following method :
[CODE:java]

120
Created by XMLmind

XSL-FO Converter.

public void setSoTimeout(int timeout) throws SocketException


/* This method take as paramater the keep delay expressed in milliseconds.
The default value 0 is equivalent ad infinitum . To the expiry of the of the
keep delay , the java.io.InterruptedIOException is raised. */
[CODE:java]
public void close() // Close the listening socket.
[CODE:java]
public InetAddress getInetAddress() // Return the address from which the socket is listening
[CODE:java]
public int getLocalPort() // Return the port on which the socket is listening

1.2.1.3. Client (java.net.Socket )


Use :
Creation of the client socket :
[CODE:java]
Socket Client = new Socket(host, port);

Communication : Well use the InputStream, OutputStream flows and their derivatives.
[CODE:java]
InputStream entry = Client.getInputStream();
OutputStream exit = Client.getOutputStream();

Constructors :
[CODE:java]
public Socket() // Create a non connected socket
[CODE:java]
public Socket(InetAddress address, int port) throws IOException
/* Create a communication socket and establish a connection on the computer
desired port whose IP address is specified. */
[CODE:java]
public Socket (InetAddress ad, int port, InetAddress localAd, int localPort) throws IOException
/* Create a communication socket and establish a connection on the desired
computer port whose IP address is specified. Specify the port and the local
address. */
[CODE:java]
public Socket(String host, int port) throws UnknownHostException, IOException
/* Create a communication socket and establish a connection on the desired
port of the computer whose IP address is specified. */
[CODE:java]
public Socket(String host, int port, InetAddress localAd, int localPort) throws IOException, UnknownHostException
/* Create a communication socket and establish a connection on the desired
port of the computer whose host name is specified. Specify the port and the
localaddress. */

Useful methods :
1. Communication
The effective communication on a socket connection is based on data flow (java.io.OutputStream and
java.io.InputStream).
The two methods below are used to obtain Input and Output flows.

121
Created by XMLmind

XSL-FO Converter.

[CODE:java]
public InputStream getInputStream() throws IOException
// Return the corresponding object to the input flow of the socket object
[CODE:java]
public OutputStream getOutputStream() throws IOException
// Return the corresponding object to the output flow of the socket object

2. Blocking reading
A reading operation on these flows is blocking as long as these data arent available. However, it is possible to
fix a guard delay for the wait of the data (the same guard delay as the listening socket : throws the
java.io.InterruptedIOException.
[CODE:java]
public void setSoTimeout(int timeout) throws SocketException

3. Additional methods A whole of methods allow you to obtain the constituitive elements of the established link
:
[CODE:java]
InetAddress getInetAddress()
/*
Return the address where the socket is connected
The InetAddress address type concatene the IP address and the corresponding
domain name
For example : www.yahoo.com/216.109.117.207
*/
[CODE:java]
int getPort() // Return the distant port where the socket is connected
[CODE:java]
InetAddress getLocalAddress() // Return the local address to which the socket is associated
[CODE:java]
int getLocalPort() // Return the local port to which the socket is associated

4. Closing
The close operation close the connection and release the ressources of the system associated to the socket.
[CODE:java]
void close() // Close the socket

1.2.1.4. An example of a client and a server (very basic)


This is an example of a server which accepts a connection.
He receives an integer then return to the client (integer +1) .
Server :
[CODE:java]
import java.net.*;
import java.io.*;
public class BasicServer {
public static void main(String[] args) {
try {
ServerSocket listen = new ServerSocket(18000, 5);
Socket service = (Socket) null;
while (true) {
service = listen.accept();
OutputStream os = service.getOutputStream();
InputStream is = service.getInputStream();
os.write(is.read() + 1);
service.close();
}
} catch (Exception e) {
/* Error treatment */

122
Created by XMLmind

XSL-FO Converter.

}
}
}

The corresponding client asks for a connection to the server.


The client returns an integer, then reads the socket input flow.
Client :
[CODE:java]
import java.net.*;
import java.io.*;
public class BasicClient {
public static void main(String[] args) {
try {
Socket s = new Socket("localhost", 18000);
OutputStream os = s.getOutputStream();
InputStream is = s.getInputStream();
os.write((int) 'a');
System.out.println((char) is.read());
s.close();
} catch (Exception e) {
/* Error treatment */
}
}
}

1.2.1.5. Exceptions Understanding


In certain cases, for example if we ask for a connection to a server which doesnt have a waiting listening
socket, an exception is thrown.
The list below will allow you to understand the meaning of the thrown exceptions in the case you have a
problem.
[CODE:java]
java.net.BindException // Linking error to a bind local address
[CODE:java]
java.net.ConnectException // Refusal of connection by the host
[CODE:java]
java.net.NoRouteToHostException // Host unreachable (route not find)
[CODE:java]
java.net.ProtocolException // Protocol Error (TCP, ...)
[CODE:java]
java.net.SocketException // Protocol Error (TCP, ...)
[CODE:java]
java.net.UnknownHostException // DNS Error

1.2.1.6. Datagram Mode Sockets


The TCP/IP protocol answers to the majority of the network needs. It allows to transport in a higly reliable way
data packets. However, because of the execution of many treatments algorithms for network congestions or lost
packets, it constitutes an expensive transport solution.
The datagram represents an alternative choice.
A datagram is a whole of transmissible from computers to computers. There is no control to say if a datagram is
arrived or if it was intercepted by another computer. In the same way, there is no way to know if it has been
damaged during the transfer.
Java implements the datagram within the UPD protocol, and furnishes two classes :

123
Created by XMLmind

XSL-FO Converter.

DatagramPacket : Allow you to create objects containing the datagram data. A DatagramPacket own a data
zone, a port number and eventually an IP address.

DatagramSocket : Mechanism to send and receive DatagramPacket.


Constructors
[CODE:java]
public DatagramSocket() throws SocketException
// Construct a Datagram socket.
[CODE:java]
public DatagramSocket(int port) throws SocketException
// Construct a Datagram socket specifying a local port.
[CODE:java]
public DatagramPacket(byte[] buf, int length)
// Construct a packet in the Datagram mode.
[CODE:java]
public DatagramPacket(byte[] buf, int length, InetAddress address, int port)
// Construct a packet in Datagram mode specifying the address and the
destination port.

Send/Receive
[CODE:java]
public void send(DatagramPacket p) throws IOException // Send a packet
[CODE:java]
public void receive(DatagramPacket p) throws IOException // Receive a packet

Connection
It is possible to connect a socket in datagram mode to a receiver. In this case, the packets sent on the socket will
always be for the specify address.
The connection simplify the send of a lot of packets (it is no more necessary to specify the destination address
for each of them) and accelerate the security controls (they occur once for all at the connection).
The disconnection removes the link (the socket becomes available again as in the initial state).
[CODE:java]
public void connect(InetAddress address, int port)
[CODE:java]
public void disconnect()

Other methods
[CODE:java]
public InetAddress getAddress()
// Return the destination address of a packet in the InetAddress form.
[CODE:java]
public int getPort()
// Return the destination port number.
[CODE:java]
public byte[] getData()
// Return the data array furnish by a datagram. We often use this method at the receive of a DatagramPacket object.
[CODE:java]
public int getLength()
// Return the length of the valid data in the datagram data array.
[CODE:java]
public void close()
// Free the system ressources associated to the socket.

124
Created by XMLmind

XSL-FO Converter.

Example :
Sending a message in datagram mode :
[CODE:java]
import java.net.*;
import java.io.*;
public class SendMessage {
// Port on which we send the data
static final int port=47;
// Entry point of the program
public static void main(String argv[]) {
// We check is the IP address or the recipient computer name is specified.
if (argv.length != 1) {
System.err.println("Give us the recipient computer name");
System.exit(0);
}
BufferedReader input = new BufferedReader(new
InputStreamReader(System.in));
InetAddress address = null;
DatagramSocket socket;
// Creation of the recipient address with the argument
try {
adresse = InetAddress.getByName(argv[0]);
// Message send
String ligne = "Hello world";
byte[] message = new byte[ligne.length()];
message = ligne.getBytes();
DatagramPacket send = new DatagramPacket(message,
ligne.length(), address,port);
socket = new DatagramSocket();
socket.send(send);
} catch (Exception exc) {
System.err.println("Error when sending the message !");
}
}
}

Receive a message in datagram mode :


[CODE:java]
import java.net.*;
import java.io.*;
class ReceptionMessage {
// Reception port
static final int port=47;
// Entry point
public static void main(String argv[]) {
byte[] byteReception = new byte[1000];
String text;
try {
DatagramSocket socket = new DatagramSocket(port);
DatagramPacket reception = new
DatagramPacket(byteReception, byteReception.length);
socket.receive(reception);
texte = new String(byteReception);
System.out.println("Receiving from computer " +
reception.getAddress().getHostName());
System.out.println("On the port " + reception.getPort());
System.out.println("Text:" + text);
} catch (Exception e) {
System.err.println("Error when opening the socket");
}
}
}

1.3. Multithreaded Server


1.3.1. Recall on the Threads
125
Created by XMLmind

XSL-FO Converter.

Java propose an integrated assumption of responsibility of the multithreaded programmation thanks to the
Thread class and the Runnable interface.
A multithreaded program contains many parts which can work in parallel.
Each of these parts is called threads. The threads share the same address space and exploit the same system
process in cooperation.

1.3.2. Thread class and Runnable interface


The multithreading system in Java lays on the Thread class, his methods, and on his interface associated:
Runnable.
To create a new thread the main program can extends the Thread class, or use the Runnable interface.
[CODE:java]
public class MyProgram extends Thread { ...
public class MyProgram implements Runnable { ...

Many methods of the Thread class ease the thread management :

getName() : Obtain the thread name

getPriority() : Obtain the thread priority

isAlive() : Determine if a thread still in activity

join() : Wait for the end of a thread (for the synchronization)

run() : Entry point for a thread

sleep() : Put down a thread for a certain time

start() : Start a thread


1.3.2.1. Main thread
The Java program execution imply the creation of a thread : the main thread, from which can be generated other
threads, called child thread.
Even if the main thread is automatically created at the execution of a program, it can also be controlled by a
Thread object.
The currentThread() method allows you to obtain a reference of the thread in which it is executed.
It is also possible to control it as well as another thread.
[CODE:java]
public class MyProgram {
public static void main(String args[]) {
Thread t = Thread.currentThread();
System.out.println("Thread : " + t + " executing");
t.setName("My Thread"); // Changing the name
try {
t.sleep(2000);
} catch(InterruptedException e) { }
System.out.println("Restart of the thread : " + t + " and end of the program ");

126
Created by XMLmind

XSL-FO Converter.

}
}

1.3.2.2. Create a thread


The easiest way to create a thread is to create a class implementing the Runnable interface.
The second way to proceed is to create a class extending the Thread class.
Use Runnable
To implement the Runnable interface, a class must own the following method :
[CODE:java]
public void run()

This method is the entry point of a new concurrent thread in the program.
A thread ends at the exit of run().
The instanciation of a Thread type object is done with the following constructor :
[CODE:java]
Thread(Runnable ThreadObj, String ThreadName)

ThreadObj indicates an instance of a class which implements the Runnable interface. ThreadName indicates the
name of the thread. The new thread will be active only when we will call the start() method.
Example of multithreaded programmation thanks to Runnable.
[CODE:java]
public class MyProgram {
public static void main(String args[]) {
new NewThread("Child 1");
new NewThread("Child 2");
Thread t = Thread.currentThread();
t.setName("Parent");
for (int i = 0; i < 10; i++) {
System.out.println("Thread : " + t.getName() + "executing");
}
}
}
class NewThread implements Runnable {
Thread t;
NewThread(String name) {
t = new Thread(this, name);
t.start();
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Thread : " + t.getName() + "executing");
}
}
}

Extend Thread
It means to define a new class extending Thread.
The extended class must redefine the run() method., which is also the entry point of the new thread. It must
invoke start() to launch the thread execution.
We can ask why Java proposes two ways to create child threads. In fact, the Thread class owns many
redefinable methods by a derivated class, of which run().
However we can redefine run() method that belong to Runnable.
Everyone is free to choose the way he prefers.
127
Created by XMLmind

XSL-FO Converter.

The precedent example is including in the following page but this time with the method extends Thread.
Taking the previous example where a class inherited from Thread :
[CODE:java]
public class MyProgramme {
public static void main(String args[]) {
new NewThread("Child 1");
new NewThread("Child 2");
Thread t = Thread.currentThread();
t.setName("Parent");
for (int i = 0; i < 10; i++) {
System.out.println("Thread : " + t.getName() + "executing");
}
}
}
class NewThread extends Thread {
NewThread(String Name) {
setName(Name);
start();
}
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("Thread : " + getName() + "executing");
}
}
}

1.3.3. Multithreaded server and simple client(s)


This is an example of a basic multithreaded server which accepts connections, wait for a ( Hello ) text line
and answer ( Happy to hear you ) :
[CODE:java]
import java.net.*;
import java.io.*;
public class Server {
public static void main(String [] args) {
try {
ServerSocket listen = new ServerSocket(18000, 5);
while (true){
new NewConnection(listen.accept());
}
} catch (Exception e) {
/* error treatment */
}
}
}
class NewConnection implements Runnable {
Thread t;
Socket sck;
PrintWriter output;
BufferedReader input;
NewConnection(Socket sck) {
t = new Thread(this, sck.getInetAddress().getHostName() + "/" +sck.getPort());
this.sck = sck;
try {
output = new PrintWriter(this.sck.getOutputStream());
input = new BufferedReader(new
InputStreamReader(this.sck.getInputStream()));
} catch (IOException e) {}
t.start();
}
public void run() {
System.out.println("New connection accepted : " + t.getName());
try {
System.out.println("Receive : " + entree.readLine() + " on" + t.getName());
sortie.println("Happy to hear you");

128
Created by XMLmind

XSL-FO Converter.

sortie.flush();
sck.close();
} catch (IOException e) {}
}
}

Client code :
[CODE:java]
import java.net.*;
import java.io.*;
public class Client {
public static void main(String [] args) {
try {
Socket connection = new Socket("localhost", 18000);
PrintWriter output = new
PrintWriter(connection.getOutputStream());
BufferedReader input = new BufferedReader(new
InputStreamReader(connection.getInputStream()));
output.println("Hello");
output.flush();
System.out.println(input.readLine());
connection.close();
} catch (Exception e) {
/* error treatment */
}
}
}

1.4. The communication using flows


To communicate via TCP/IP, the Socket class gives the access to the send and receive flows.
Before the 1.1 JDK version, the input/output classes support only one byte flow. The character concept flow, i.e.
supporting Unicode character on 16 bits, was introduced at the same time as the 1.1 JDK.
It remains that on the lower level, all the Input/Output system is byte oriented. The characters flow as for them,
constitute a useful tool for the characters management.

1.4.1. The bytes flows, InputStream and OutputStream


The bytes flows are defined using two classes hierarchy, with the head of which we can find the abstracts
classes InputStream and OutputStream.
Each of them own many concrete subclasses which manage the differences between various devices, like
stocked files on a disk, buffer area.
The abstract classes InputStream and OutputStream define many essentials methods, implementing by the others
flow classes.
Among the most important we can quote read() and write(), which respectively, read and write data flows.
These two methods declare as abstract are redefine by each of the extends classes.
The InputStream flows and OutputStream one can directly be obtain by the socket with the following methods :
[CODE:java]
Socket client = new Socket("ftp.free.fr", 21);
InputStream ReceptionFlow = client.getInputStream();
OutputStream SendFlow = client.getOutputStream();

1.4.2. Character flows


The character flow is defined with two hierarchy of classes, with the head of which two abstract classes, Reader
and Writer.
129
Created by XMLmind

XSL-FO Converter.

These classes manage the Unicode character flows. Java include many concrete subclasses of each of them.
The abstract classes Reader and Writer define many methods essentials for the other flow classes. In the most
important of them, we found read() and write() which read and write respectively data characters. They are
redefine by each of the flow classes extended from Reader and Writer.
In network programming, when we want to pass from getInputStream() or getOutputStream(), to a character
flow, it would be necessary to convert the bytes in characters (in the case of InputStream) or the characters in
bytes (in the case of OutputStream).
[CODE:java]
Socket client = new Socket("ftp.free.fr", 21);
BufferedReader ReceptionFlow = new BufferedReader(
new InputStreamReader(client.getInputStream())
);
BufferedWriter SendFlow = new BufferedWriter(
new OutputStreamWriter(client.getOutputStream())
);

This wont be systematically the case, for example for PrintWriter we will have :
[CODE:java]
PrintWriter SendFlow = new PrintWriter(client.getOutputStream());

It is a good thing to go to the Java documentation when necessary.

1.4.3. Data flow Input/Output classes


The data flow I/O classes are briefly presented below :

BufferedInputStream : Input flow stored in the temporary memory

BufferedOutputStream : Output flow stored in the temporary memory

ByteArrayInputStream : Input flow reading from a byte array

ByteArrayOutputStream : Output flow writing to a byte array

DataInputStream : Input flow who contains some methods dedicated to the reading of Java standard data type

DataOutputStream : Output flow who contains some methods dedicated to the writing of Java standard data
type

FileInputStream : Input flow reading from a file

FileOutputStream : Output flow writing to a file

FilterInputStream : Implements InputStream and override his methods

FilterOutputStream : Implements OutputStream and override his methods

130
Created by XMLmind

XSL-FO Converter.

InputStream : Abstract class describing the input flow

OutputStream : Abstract class describing the output flow

PipedInputStream : Input pipe

PipedOutputStream : Output pipe

PrintStream : Output flow containing print() and println()

PushBackInputStream : Output flow which allow to go back of a byte

RandomAccessFile : Take in charge the file I/O with a random access

SequenceInputStream : Output flow, composed of many input flows, which will be read sequentially, one
after the over.

1.4.4. Character flow Input/Output classes


The character flow I/O classes are briefly presented below :

BufferedReader : Input character flow, stored in the temporary memory

BufferedWriter : Output character flow, stored in the temporary memory

CharArrayReader : Input flow reading from a character array

CharArrayWriter : Output flow writing to a caracter array

FileReader : Input flow reading from a file

FileWriter : Output flow writing to a file

InputStreamReader : Input flow transcribing bytes in characters

OutputStreamReader : Output flow transcribing characters in bytes

LineNumberReader : Input flow counting lines

PipedReader : Input pipe

131
Created by XMLmind

XSL-FO Converter.

PipedWriter : Output pipe

PrintWriter : Output flow containing print() and println()

PushBackReader : Input flow which allow to return characters to the input flow

Reader : Abstract class, describing the input of the character flow

Writer : Abstract class describing the output of the character flow

StringReader :Input flow reading from a String

StringWriter : Output flow writing to a String

1.5. Transmission of a serialized object


1.5.1. Send of a serialized object
The serialisation allows to save the internal state of an object, i.e. his variables, then to restore them in a flow.
So we can send this instance information by network after using the serialization.
First of all, the object we want to serialize must implement the Serializable interface.
Then we instanciate a Socket specifying for example the IP address and the port, or accepting an input
connection.
Then we declare a BufferedOutputStream which take the Socket flow in parameter (Socket.getOutputStream()).
The object serialization is done when calling the writeObject() method on an object implementing the interface
ObjectOutput (for example an object of the ObjectOutputStream) by passing the object we want to serialize as a
parameter of the writeObject() method, and in the ObjectOutputStream contructor parameter the flow we want
to send the serialize object.

1.5.2. Reception of a serialize object


The reception of a serialize object works the same as an object transmission.
We initialize a Socket. We declare a BufferedInputStream which take in parameter the socket input flow.
The deserialisation of an object is done calling the readObject() method on an object implementing the
ObjectInput interface (for example an object from the ObjectInputStream class).

1.5.3. Examples
Our example will have three classes : a Human class which the instance will be serialize and send on the
network. The Send class will be in charge to send this instance of Human, and the Reception class will receive
the instance and will post the instance variable to check if all is well done.
1.5.3.1. Human class
[CODE:java]
import java.io.*;
public class Human implements Serializable {
String name;
int age;

132
Created by XMLmind

XSL-FO Converter.

public Human(String n, int a) {


name = n;
age = a;
}
public void show() {
System.out.println("name:" + name);
System.out.println("age:" + age);
}
}

1.5.3.2. Send class


[CODE:java]
import java.io.*;
import java.net.*;
public class Send {
public static void main(String args[]) throws Exception {
Socket client = new Socket("localhost", 21);
BufferedOutputStream out = new
BufferedOutputStream(client.getOutputStream());
ObjectOutput s = new ObjectOutputStream(out);
s.writeObject(new Personne("Andrew", 22));
s.flush();
}
}

1.5.3.3. Reception class


[CODE:java]
import java.io.*;
import java.net.*;
public class Reception implements Serializable{
public Reception() {
}
public static void main(String args[]) throws Exception {
ServerSocket server = new ServerSocket(21);
Socket communication = serveur.accept();
// blocking, waiting for a connection
BufferedInputStream in = new
BufferedInputStream(communication.getInputStream());
ObjectInput s = new ObjectInputStream(in);
Human e = (Human) s.readObject();
e.affiche();
}
}

1.6. Input/Output programmation


To program input/output on the network, we use one of the four following classes, but you are free to choose
other (ZipOutputStream ).

java.io.BufferedReader : This class is used to read with setting in the temporary memory, et non continuous,
of Socket

java.io.PrintWriter : We use this class when we treat protocols based on text request (print(), println())

java.io.BufferedInputStream : This class is perfect when we want to do binaries transfer and continuous
between two sockets. It permits the setting in temporary memory of data and accelerate the reading process

java.io.BufferedOutputStream : Equivalent to the preceding for what concerns the Socket output

1.6.1. BufferedReader et PrintWriter


133
Created by XMLmind

XSL-FO Converter.

These classes are used together very often to read and write a Socket. To detect the EOF reception (which
happen when the distant Socket is closed), we test the null value. Once these instance classes are created, it is
very simple to manage a communication based on a protocol. Indeed these classes give the methods print(),
read(), println(), readLine().
1) Various choices can be operated as, for example, the sending of the number of lines follow by the send of
these lines, a for loop can be use for the successives reading.
2) Another solution consists in setting up a protocol based on an end sequence, such as for example the sending
of END or FINISHED at the end of a sendings sequence.
3) Finally we can consider the installation method by the ftp protocol to indicate if there are still lines to be read.

We can note that when there are remaining lines to be read, we find the following sequence code+-. On the
other hand when the last line is sent, we find the sequence code+ . We have to set up a detection of these
informations( using substring() for example), to avoid making a readline() in excess.

1.6.2. BufferedInputStream and BufferedInputStream


We generally use these classes for continuous binaries transfer. The binary send using these classes is easy to
implement. Being given that the trasnfer is binary, the most use type will be int.
To detect the reception of an EOF (which happen when the distant Socket is closed), we test the value 1.
This is a binary reading example :
[CODE:java]
try {
Socket socket = new Socket(host, port); // Socket creation
BufferedInputStream in = new
BufferedInputStream(socket.getInputStream());
int ch;
while ((ch = in.read()) != 1){
/* Placing into a file, Showing in form of chars ... */
}
in.close();
socket.close();
} catch (Exception exception) {
exception.printStackTrace();
}

134
Created by XMLmind

XSL-FO Converter.

Chapter 8. Threads, concurrents proc


esses
This chapter will provide you means to :

create parallels processes

generate daemons from your application

1. Course
1.1. Introduction
1.1.1. Definition
Threads allow simultaneous executions to run at the same time. They are called lightweight processes because
they share the same memory area. Indeed, an object created by a thread can be used from another thread.
At machine level, only one thread can use the processor, the execution of the others is suspended meanwhile.
This is called concurrent access (they are sharing processor cycles). When the time granted to a thread is over, it
is suspended and another thread is granted the use of the processor. A living thread can be suspended even if its
execution is not finished.

1.1.2. Usefulness
Enabling a program to run several operations at the same time allow you to build powerful applications:
One can create separated process which will execute a given task, each one in an independent way, without
hobbling the execution of the program.
Threads allow access to concurrent programming to make threads work with the same data. To prevent
inconsistencies due to shared data access, synchronization mechanisms can also be implemented.
They also enable programs not to hang on blocking methods. For example in the network API, it allow to handle
several connections at the same time. Use of threads hides the complexity of time slicing because the Java
Virtual Machine is responsible of its management.

135
Created by XMLmind

XSL-FO Converter.

1.2. Threads
1.2.1. The Thread class
1.2.1.1. Definition
At a program execution, there is only one lightweight process.
In Java, there is the Thread class which has methods allowing threads management. One common way is to
inherit from this class in order to make a class "threadable".
1.2.1.2. The start() and run() methods
The run() method has the public visibility; it is inherited from the Thread class and must be overridden if you
want your class to make any concurrent task. It must hold the bloc of instructions which will be ran by the
thread. This method is called by the start() method. You must call the start() method in order to execute the
instructions of the run() method in a threaded way.
Before calling the start() method, a thread has a state of "new ". When start() is called, the thread has the
"runnable " state. A thread is considered as alive when its state is runnable .
When the virtual machine gives processor time to a thread, its state is running .
When a thread has finished the execution of the run() method, is enters the dead state and cannot be run again.
Its instance is still present, allowing us to retrieve piece of information about the thread.
[CODE:java]public void run() {
}

Warning : to use threading, you must not directly call the run() method, you must use the start() method.
1.2.1.3. Creating a thread using the Thread class
[CODE:java]public class MyThread extends Thread {
public void run() {
// Code to be executed in a threaded way
}
public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.start(); // start() will call the run() method
}
}

1.2.1.4. Stopping a thread


There a several ways to stop a thread: You can monitor periodically the value of a variable to check whether you
should return from the run() method. It can be a simple boolean value, set to true when the thread need to be
stopped. by proceeding like this, you can release resources in a proper way (closing connections, releasing
locks, etc.).
You can also watch for the InterruptedException exception obtained by calling the interrupt() method on the
thread. This allow a thread to be released from blocking call like the wait() , join() or sleep() methods. If
hanging on a java.nio.channel.InterruptibleChannel , interrupt() will cause a ClosedByInterruptException
exception to be thrown.
Moreover, there is a stop() method which is deprecated because it stops the thread brutally, without letting you
release resources in a proper way (lock may stay acquired, causing dead lock situations). You should not use the
stop() method any more.
1.2.1.5. Wating with the sleep() method
The static sleep() method allow a thread to be suspended for a given time. Its unique argument is given in

136
Created by XMLmind

XSL-FO Converter.

milliseconds as a long . When the delay is over, the execution of the thread goes on. An InterruptedException
can be thrown by sleep() if the interrupt() method is called on the thread before the delay is over.
[CODE:java]public class MyThread extends Thread {
public void run() {
try {
System.out.println("Start of the thread, waiting for 7 seconds...");
sleep(7000);
System.out.println("Delay is over!");
} catch (InterruptedException e) {
System.out.println("Thread woken before the end of the delay");
} finally {
System.out.println("Thread end");
}
}
public static void main(String[] args) {
try {
MyThread t = new MyThread();
t.start();
Thread.sleep(3000);
System.out.println("interrupt() at 3 seconds");
t.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

This exhibit displays the following result:


Start of the thread, waiting for 7 seconds...
<3 seconds pause>
interrupt() at 3 seconds
Thread woken before the end of the delay
Thread end

One can see that the static Thread.sleep() method can be called anywhere, not only inside a Thread instance, like
in the main() method.
1.2.1.6. Waiting for a threads end: join()
The join() method makes the current thread (from which the call is done) to wait for another threads end. When
the thread is over, the current thread can continue its execution.
[CODE:java]public class MyThread extends Thread {
public void run() {
try {
System.out.println("Begin of a long processing");
sleep(3000);
System.out.println("End of the long processing");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
Thread t = new MyThread();
t.start();
System.out.println("Waiting for the thread to finish");
t.join();
System.out.println("The thread has finished");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

137
Created by XMLmind

XSL-FO Converter.

This exhibit displays the following result:


Waiting for the thread to finish
Begin of a long processing
<3 seconds pause>
End of the long processing
The thread has finished

Like the sleep() method, join() can throw an InterruptedException exception. This is done when the following
conditions are met:

A t1 thread has not finished its execution


A t2 thread calls t1.join()
t2.interrupt() is called
You can also define how much your thread will wait with join(long) or join(long, int) .
1.2.1.7. Testing a thread: isAlive()
The isAlive() method let you know if a thread is still alive. A thread is known as alive if it has been started (the
start() method has been called) and if it has not finished its execution of the run() method.
[CODE:java]boolean state;
Thread t1 = new Thread();
state = t1.isAlive();

1.2.1.8. Priority
You can make some threads being executed faster than others by modifying their priority. The priority of a
thread is specified by an integer value between 1 and 10 (10 is the highest priority). There are three main
priority defined in the Thread class:

MIN_PRIORITY
MAX_PRIORITY
NORM_PRIORITY (default priority)
The priority of a thread can be retrieved with getPriority() , and set with setPriority(int) .

1.2.2. The Runnable interface


1.2.2.1. Definition
There is another way to thread a class by implementing the java.lang.Runnable interface. It makes you defining
the run() method.
Using the Runnable interface rather than the Thread class let you extend from another class and creating a
threadable class at the same time. It was not possible with the Thread class because multiple inheritance is not
allowed in Java.
With the Runnable interface, you can share data without the use of the static keyword.
[CODE:java]public class Exemple implements Runnable {
public void run() {
// instructions...
}
}
[CODE:java]public class Exemple extends JApplet implements Runnable {

138
Created by XMLmind

XSL-FO Converter.

1.2.2.2. Using the Runnable interface


To execute a thread with the Runnable interface, you must pass an instance of your implementation of Runnable
to the Tread constructor:
[CODE:java]public class RunnableImpl implements Runnable {
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
}
public static void main(String[] args) {
Thread t1, t2;
RunnableImpl ex1 = new RunnableImpl();
t1 = new Thread(ex1);
t2 = new Thread(ex1);
t1.start();
t2.start();
}
}

This may display:


0
0
1
1
2
2
3
3
4
4

The result may differ, depending on many factors, and because there is no synchronization between the thread.
When implementing the Runnable interface, you do not have access anymore to the methods of the Thread class
to control execution of the current thread. To have access back to these methods, you can use the static method
Thread.currentThread() which will return the current executing thread.
Here is a sample with the getName() method of the Thread class:
[CODE:java]public class RunnableImpl implements Runnable {
public void run() {
System.out.println("My name is " + Thread.currentThread().getName());
}
public static void main(String[] args) {
new Thread(new RunnableImpl()).start();
}
}

You get the same display by extending the Thread class:


[CODE:java]public class MyThread extends Thread {
public void run() {
System.out.println("My name is " + getName());
}
public static void main(String[] args) {
new MyThread().start();
}
}

139
Created by XMLmind

XSL-FO Converter.

1.2.3. Concurent access - sharing information between threads


1.2.3.1. Static fields
A static field is a class variable in so that every instance of this class will be able to access the same value of this
variable.
[CODE:java]public class MyThread extends Thread {
static int a; // static field shared between every instance of MyThread
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(getName() + ": " + a++);
}
}
public static void main(String[] args) {
new MyThread().start();
new MyThread().start();
}
}

This displays: (this can vary due to lack of synchronization and time sharing)
Thread1: 1
Thread0: 0
Thread1: 2
Thread0: 3
Thread1: 4
Thread0: 5
Thread1: 6
Thread0: 7
Thread1: 8
Thread0: 9

1.2.3.2. Constructor Thread(Runnable)


Using implementations of the Runnable interface let you share information only between threads coming from
the same instance of your implementation. With that, data are not globally shared between instances of your
class.
[CODE:java]public class RunnableImpl implements Runnable {
private int a, b;
private String text;
MyRunnable(String text) {
this.text = text;
}
public void run() {
for (int i = 0; i < 3; i++) {
System.out.println(text + " " + Thread.currentThread().getName() + " a: " + a++);
System.out.println(text + " " + Thread.currentThread().getName() + " b: " + b++);
}
}
public static void main(String[] args) {
RunnableImpl o1, o2;
o1 = new RunnableImpl("Group 1");
new Thread(o1).start();
new Thread(o1).start();
o2 = new RunnableImpl("Group 2");
new Thread(o2).start();
new Thread(o2).start();
}
}

This sample shows a way not to share globally data between instances of your class.
140
Created by XMLmind

XSL-FO Converter.

Possible output:
Group 1 Thread0 a: 0
Group 1 Thread1 a: 1
Group 2 Thread3 a: 0
Group 1 Thread0 b: 0
Group 2 Thread2 a: 1
Group 1 Thread1 b: 1
Group 2 Thread3 b: 0
Group 1 Thread0 a: 2
Group 2 Thread2 b: 1
Group 1 Thread1 a: 3
Group 2 Thread3 a: 2
Group 1 Thread0 b: 2
Group 2 Thread2 a: 3
Group 1 Thread1 b: 3
Group 2 Thread3 b: 2
Group 1 Thread0 a: 4
Group 2 Thread2 b: 3
Group 1 Thread1 a: 5
Group 2 Thread3 a: 4
Group 1 Thread0 b: 4
Group 2 Thread2 a: 5
Group 1 Thread1 b: 5
Group 2 Thread3 b: 4
Group 2 Thread2 b: 5

Output may vary, that will be the point of the next chapter about the synchronization.
You can also pass an instance of Thread to the Thread() constructor because Thread implements Runnable .
Note the use of Thread.currentThread() to refer to the current executing thread.

1.3. Synchronization
1.3.1. Principe
When several threads access to a shared variable, it is possible that they modify it in a non coherent way in
absence of a synchronization mechanism. Thats why we need those mechanisms to temporally prevent access
to our objects in order to ensure coherent data handling inside our program.

1.3.2. Block synchronization


1.3.2.1. Definition
Synchronizing a block of instruction is the use of a lock on an object during the execution of a block of
instructions. This is defined with the synchronized keyword, and the lock is released only after the last
instruction of the block. When the lock over an object is acquired, others thread can not acquire it and so cannot
enter the block of instructions. They wait for the other threads to release the lock by running out the block of
instruction, releasing the lock over the object.
[CODE:java]synchronized (object) { // acquiring the lock
// code
} // releasing the lock

In order to make this locking mechanism efficient, the locked object must be shared between threads. Otherwise,
there will be as many locks as threads.
1.3.2.2. Sample
The following shows a use of the synchronized keyword over an object:
[CODE:java]public class Synch extends Thread {
static Integer i;
int max;

141
Created by XMLmind

XSL-FO Converter.

String nom;
public Synch(String nom, int max) {
i = new Integer(0);
this.max = max;
this.nom = nom;
}
public void run() {
synchronized (i) {
while (i.intValue() < max) {
try {
sleep(100);
} catch (Exception e) {
System.err.println(e);
}
System.out.println(nom + " modify i");
i = new Integer(i.intValue() + 1);
System.out.println(i.intValue());
}
System.out.println(nom + " ended!");
}
}
public static void main(String args[]) {
new Synch("t1", 50).start();
new Synch("t2", 100).start();
}
}

t2 waits for t1 to finish before modifying i .

1.3.3. Method synchronization


1.3.3.1. Definition
Methods can also benefit the use of the synchronized keyword. It is here used as a modifier of the method,
without specifying any object to lock on.
Thread issued from a same object will not be able to access a synchronized method at the same time, causing the
other threads to wait for the first thread to return from the method.
If the method is static , no matter if the threads are from the same object, only one thread at a time can access
the method in the program.
1.3.3.2. Sample
[CODE:java]public class RunnableImpl implements Runnable {
public void run() {
for (int i = 0; i < 5; i++) {
move();
}
}
synchronized private void move() {
System.out.println(Thread.currentThread().getName() + " enters");
System.out.println(Thread.currentThread().getName() + " leaves");
}
public static void main(String[] args) {
RunnableImpl o = new MyRunnableImpl();
new Thread(o).start();
new Thread(o).start();
}
}

Only one thread accesses the move method at a time:

142
Created by XMLmind

XSL-FO Converter.

Thread-0 enters
Thread-0 leaves
Thread-1 enters
Thread-1 leaves
Thread-0 enters
Thread-0 leaves
Thread-1 enters
Thread-1 leaves
Thread-0 enters
Thread-0 leaves
Thread-1 enters
Thread-1 leaves
Thread-0 enters
Thread-0 leaves
Thread-1 enters
Thread-1 leaves
Thread-0 enters
Thread-0 leaves
Thread-1 enters
Thread-1 leaves

Without synchronized , you may see both threads entering at the same time.

1.3.4. The wait() , notify() & notifyAll() methods


A thread can wait for another thread without expecting it to finish, like it is the case with the join() method. In
order to achieve this, the wait() , notify() and notifyAll() methods are used.
Those methods do not belong to the Thread class as the join() method. They belong to the Object class which is
the main superclass of every class.
Warning: in order to use those methods, you must acquire a lock on the concerned object with the synchronized
keyword. Failing to do that will cause an IllegalMonitorStateException exception to be thrown.
1.3.4.1. Waiting for a notify: wait()
The a.wait() method makes the current thread to wait until the thread a calls the notify() method. You can
specify the maxium amount of time to wait. After calling the wait() method, the state of a thread is waiting .
Calling the notify() or notifyAll() methods can remove the waiting state of a thread. When calling the wait()
method, the lock on the locked object is temporary released; when the thread is reenabled (with notify() or
notifyAll() ), the lock is reacquired.
1.3.4.2. Notify a thread: notify()
This method wakes a waiting thread, which has called the wait() method. If there is several thread waiting, only
one thread will be awakened. You can not predict which thread will be awakened.
1.3.4.3. Notify every thread: notifyAll()
This method wakes every thread which has called the wait() method.
1.3.4.4. Sample
[CODE:java]public class RunnableImpl implements Runnable {
public void run() {
Thread t = Thread.currentThread(); // represents the current Thread
try {
System.out.println("Start of " + t.getName() + ", calling wait()");
synchronized (t) {
t.wait();
}
System.out.println(t.getName() + " has stopped waiting");
} catch (Exception e) {
e.printStackTrace();
} finally {

143
Created by XMLmind

XSL-FO Converter.

System.out.println("End of " + t.getName());


}
}
public static void main(String[] args) {
try {
Thread t = new Thread(new RunnableImpl());
t.start();
System.out.println("Waiting 3 seconds...");
Thread.sleep(3000);
System.out.println("Waking up " + t.getName());
synchronized (t) {
t.notify();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("main end");
}
}
}

This displays:
Waiting 3 seconds...
Start of Thread-0, calling wait()
<3 seconds pause>
Waking up Thread-0
main end
Thread-0 has stopped waiting
End of Thread-0

Here is another sample, with three threads. One thread will wait three seconds before waking the two other
threads, which are waiting.
[CODE:java]public class RunnableImpl implements Runnable{
private Thread t;
RunnableImpl() {
super();
}
RunnableImpl(Thread t) {
super();
this.t = t;
}
public void run() {
Thread currentThread = Thread.currentThread();
try {
if (t == null) {
System.out.println(currentThread.getName() + " waiting 3 seconds before waking up the others");
Thread.sleep(3000);
System.out.println(currentThread.getName() + " waking up the other threads");
synchronized (currentThread) {
currentThread.notifyAll();
}
} else {
synchronized (t) {
System.out.println(currentThread.getName() +" waiting for " + t.getName());
t.wait();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
System.out.println("End of " + currentThread.getName());
}
}

144
Created by XMLmind

XSL-FO Converter.

public static void main(String[] args) {


RunnableImpl m1, m2;
Thread t1, t2, t3;
m1 = new RunnableImpl();
t1 = new Thread(m1);
m2 = new RunnableImpl(t1);
t2 = new Thread(m2);
t3 = new Thread(m2);
t1.start();
t2.start();
t3.start();
}
}

This displays:
Thread-0
waiting 3 seconds before waking up the others
Thread-1
waiting for de Thread-0
Thread-2
waiting for de Thread-0
<3 seconds pause>
Thread-0
waking up the other threads
End of Thread-0
End of Thread-2
End of Thread-1

1.3.5. Deadlocks
Synchronization techniques are a way to ensure coherent data handling inside your application but, when badly
used, may cause situations where two threads of your application are waited for each other, causing your
application to hang: it is the deadlock.
Deadlocks are hardly predictable at programming time because can vary depending on many factor like the
processor usage between the threads. Thats why you should pay attention to those situations since the
beginning of your application, to prevent them from happening.
Here is a three seconds deadlock sample:
[CODE:java]public class Deadlock extends Thread {
private Thread t;
public void setThread(Thread t) {
this.t = t;
}
public void run() {
try {
System.out.println(getName() + " waiting for " +
t.getName());
synchronized (t) {
t.wait();
}
System.out.println(getName() + " stopped waiting for " + t.getName());
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Deadlock t1 = new Deadlock();
Deadlock t2 = new Deadlock();
t1.setThread(t2);
t2.setThread(t1);

145
Created by XMLmind

XSL-FO Converter.

t1.start();
t2.start();
try {
Thread.sleep(3000);
System.out.println(t1.getName() + " & " + t2.getName() + " are deadlocked, waking up " + t1.getName());
synchronized (t1) {
t1.notify();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

This displays:
Thread-0
waiting for Thread-1
Thread-1
waiting for Thread-0
<3 seconds pause>
Thread-0 & Thread-1 are deadlocked, waking up Thread-0
Thread-1 stopped waiting for Thread-0
Thread-0 stopped waiting for Thread-1

146
Created by XMLmind

XSL-FO Converter.

Chapter 9. Swing Basic


By completing this course, you will be able to :

Write your own GUIs

Handle the main components : text fields, value lists, buttons, etc...

Manage the events

Use look and feel

1. Course
1.1. Introduction
Swing is a Java library provided with the standard JDK (Java Development Kit).
Historically it is not the first library provided by Sun to construct graphic interfaces, the AWT library happened
to be the first. It is still used because Swing is based on and uses AWT. One can consider that Swing is an
evolution of AWT.

1.1.1. AWT
AWT (Abstract Windowing Toolkit) is a library to construct graphic interfaces.
It encapsulates the resources system that it uses by abstractions, so that the developer doesn't directly discern
these resources proper to the system.
So the graphical elements (Fields, let's put) created with the help of AWT will have the appearance that the
operating system gives to them.
Besides it is not possible with such architecture to use specific graphical elements of a particular system because
they would not know how to be drawn on the screen by other systems.

1.1.2. Swing
The Swing library has been developed in order to correct some inconveniences as the one described previously
and generally to assure an increased portability.
The graphical elements developed with the help of Swing are drawn by the library. The display is not delegated
to the system.
A graphical Swing element will always have the same appearance on every platform. A graphical element can
be defined by Swing without having an OSspecific equivalent one.
It is important to note that Swing does not replace AWT, because Swing is mostly based on AWT.

1.2. Java Fundation Class


The JFC (Java Foundation Classes) are a set of Java libraries permitting the construction of graphical
applications capable to function at a time under Windows, but also on other more and more popular operating
systems such as Linux or Mac OS.

147
Created by XMLmind

XSL-FO Converter.

The JFC are composed of five major parts:

AWT: Library allowing you to create executable programs in one graphical environment (GIF) as Windows,
Linux or Mac OS

Swing: Extension of AWT for the conception of graphical applications (Topic of the survey)

Accessibility: Support for individuals with disabilities

Java 2D: Advanced graphical functions for 2D, the management of the graphics and impression.

Internationalization: Support for the language and the cultural conventions

Drag & Drop : Select a graphical component and drop it between your windows.

1.3. First application


1.3.1. Architecture
The graphical user interface is composed of nested objects.
We use the containers objects to gather the componants which we want to display. It can be either frames or
panels.

Figure 9.1.

Figure 9.2. In this tree, we can see the components:

The window, from the JFrame class ( keyword this )

The welcome list, from a JPanel

148
Created by XMLmind

XSL-FO Converter.

The welcome list, from a JPanel


The displayed components are label text fields, but there is many others (buttons, dropdown list, etc.).

1.3.2. Write the code


On the following example, we are going to write a window, which contains labels (uneditable text fields). When
you launch the application, you should have something similar as the screenshot above.
The purpose of this application is to discover the first concepts, not to know precisely how to write it.
1.3.2.1. Create the class
We are going to create a class called ProfileMaker, located within the package com.labosun.profileMaker.form :
[CODE:java]package com.labosun.profileMaker.form;
// import awt and swing objects
import java.awt.*;
import javax.swing.*;
public class ProfileMaker extends JFrame {

On the following steps we are going to create this class.


1.3.2.2. Declare the graphical components
Now, we declare all the required components.
[CODE:java]// optional field, used by Serialization ( DDMMYYYYHHMM is
good )
private static final long serialVersionUID =
070720071456L;
// root container of the JFrame
private JPanel jContentPane = null;
// enclose some jlabels
private JPanel jPanel = null;
// display text informations
private JLabel hello1 = null;
private JLabel hello2 = null;
private JLabel hello3 = null;
private JLabel jLabel = null;

1.3.2.3. Initialize the GUI (Graphical User Interface)


The constructor initialize the frame, the keyword this relate to the current class which is a JFrame subclass:
[CODE:java]/**
* This is the default constructor
*/
public ProfileMaker() {
super();
initialize();
}
/**
* This method initializes "this"
* @return void
*/
private void initialize() {
// define the size of the frame
this.setSize(300, 200);
// define the default operation when
// the frame is closed
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// define which panel is the root panel
this.setContentPane(getJContentPane());

149
Created by XMLmind

XSL-FO Converter.

// define the title of the frame


this.setTitle("Profile Maker");
}

1.3.2.4. Define the root container


The container is the variable called jContentPane . We instantiate it within the following method:
[CODE:java]/**
* This method initializes jContentPane
*
* @return javax.swing.JPanel
*/
private JPanel getJContentPane() {
// if the jContentPane has not been initialized yet
if (jContentPane == null) {
// create an instance of JPanel
jContentPane = new JPanel();
// display the following phrase "Welcome to Profile Maker !"
// on the top of your application
jLabel = new JLabel();
jLabel.setText("Welcome to Profile Maker !");
jContentPane.add(jLabel);
// dispose a panel in the middle of the frame
jContentPane.add(getHelloJPanel());
}
return jContentPane;
}

Here the method getHelloJPanel :


[CODE:java]/**
* This method initializes jPanel
*
* @return javax.swing.JPanel
*/
private JPanel getHelloJPanel() {
// if this object has not been initialized yet
if (jPanel == null) {
// create an instance of JPanel
jPanel = new JPanel();
// the jPanel variable contains the
// following 3 labels, which are
// also initialized in the current method
hello3 = new JLabel();
hello3.setText("Bienvenida");
hello2 = new JLabel();
hello2.setText("Willkommen");
hello1 = new JLabel();
hello1.setText("Bienvenue");
// add the labels to the jPanel
jPanel.add(hello1, null);
jPanel.add(hello2, null);
jPanel.add(hello3, null);
}
return jPanel;
}

1.3.2.5. Launch the application


The main() method is the entry point of your application :
[CODE:java]/**
* This is the entry point of the application
*

150
Created by XMLmind

XSL-FO Converter.

* @param args
*/
public static void main(String[] args){
ProfileMaker pm = new ProfileMaker();
// a JFrame is not visible by default
pm.setVisible(true);

1.4. Swing components


There are many Swing components, so, we gather them by groups :
High Level Components : the windows (JFrame, JDialog, )
General purpose containers : tabs (JTabbedPane), scrolling (JScrollPane), panels (JPanel),
Specific containers : nested windows, often called MDI (JDesktopPane), layers (JLayeredPane),
Common controls : buttons (JButtons, JRadioButton, JToggleButton, ), lists (JList, JComboBox), menus
(JMenuBar, JMenu, JMenuItem),
Noneditable graphical components : progress bar (JProgressBar), label (JLabel),
On the following picture, we can see many components, like containers (JFrame, jContentPane, JPanel), buttons
(JButton, JRadioButton), value list (JComboBox), menu (JMenuBar, JMenu, JMenuItem) and label (JLabel).

Figure 9.3.

1.4.1. High Level Containers


Swing offers the possibility to use three types of windows: JFrames, JDialogs, and JWindow. JFrame
corresponds to the windows that we know classically, for the two other, to see the annexes.
1.4.1.1. JFrame Container
javax.swing.JFrame class
In a Swing application, the main container is a JFrame (the window).
151
Created by XMLmind

XSL-FO Converter.

It can be represented by the border of the window, and provide method associated.
Useful methods:
JFrame class

JFrame(): Creates a new initially invisible window

JFrame(String): Creates a new initially invisible window with a title

setDefaultCloseOperation(int): specify the default close operation

setJMenuBar(): Assigns a menu bar to the window

setVisible(): Show or not the window

setTitle(String): Assigns a title to the window

setPreferredSize(int, int): Sets the size of the window


1.4.1.2. jContentPane container
In a JFrame the content of the frame is called contentPane. It is generally a JPanel container. All the contents of
a window is added to the contentPane ( that can be other containers imbricate )
These two methods allow to define or retrieve this root container :

setContentPane(Component container)

getContentPane()
It is possible to define our container and set it to the window with the setter, or to get the already init container
with the getter for adding our contents.

1.4.2. Common containers


For example : the jPanel
The JPanel container is the most commonly used container. It gathers the components, in order the ease their
layout. Its graphical aspect is not important and most of the time it is invisible. Nevertheless you can set its size,
position, border
JPanel is an interesting node within your tree structure.
On the following example, we create two JPanels, then we define which components are inside them. It allows
us to group them together. At last, we call the root container of the JFrame with the method getContentPane().
This one is a Container, a parent class of JPanel, which also has to add(Components) method.
[CODE:java]JFrame myFrame = new JFrame();
JPanel panel1 = new JPanel();
JButton button1 = new JButton();
JButton button2 = new JButton();

152
Created by XMLmind

XSL-FO Converter.

JButton button3 = new JButton();


panel1.add(button1);
panel1.add(button2);
panel1.add(button3);
JPanel panel2 = new JPanel();
JLabel myLabel = new JLabel();
JTextField myTextField = new JTextField();
panel2.add(myLabel);
panel2.add(myTextField);
myFrame.getContentPane().add(panel1);
myFrame.getContentPane().add(panel2);

In the following picture, we can see how the components are stored in the structure of the graphical interface:

Figure 9.4. How does the components are nested together?

1.4.3. Other containers


For example : the JMenuBar
JMenuBar is a bar menu. There is only one per JFrame.
A JMenuBar instance is composed of many JMenu instances, which are the entries, mostly called File, Edit,
or Help. A JMenu can be used as submenu.
Each JMenu can contain many JMenuItem which are visible elements, mostly called File > Quit, Edit >
Copy, or Hep > About.

Figure 9.5. JMenuBar allows displaying menu items

Below we can see the available methods :

JMenuBar class

JMenuBar() : Constructor
153
Created by XMLmind

XSL-FO Converter.

add(JMenu) : Add a menu

JMenu class

JMenu() : Default constructor

JMenu(String s) : Define the displayed text

add(JMenu subMenu) : Add a sub- JMenu

add(JMenuItem item) : Add a JMenuItem

addSeparator() : Add a separator bar (see the screenshot above)

JMenuItem class

JMenuItem() : Default constructor

JMenuItem(String s) : Constructor, this parameter is the displayed text

addActionListener(ActionListener al) : This method add a Listener, it allows to manage the event which are
occurred on this item (we will study Listener on the following chapters).

JFrame class

setJMenuBar(JMenuBar menuBar) : This method define the menu bar to the current JFrame.

1.5. Common components


Until now, we only have studied containers, now we are going to explore the most important and exciting part
of this course : the components. There is many of them : buttons, input text areas, picture We will study and
demonstrate most of them.

1.5.1. JComponent
The JComponent class is the parent class of all the Swing components (a part highlevel containers which extend
java.awt.Container).
JComponent provide facilities to support borders, icons, tooltips,
Below you can see most of the available methods :

JComponent() : Default constructor

getBorder() : Return the border of the component, and null wether no one has been defined
154
Created by XMLmind

XSL-FO Converter.

getPreferredSize() : Return the preferred (aka default) size

getMinimumSize() : Return the minimum size

getMaximumSize() : Return the maximum size

paint(Graphics g) : Draw the component

requestFocus() : Request for the focus

setVisible(boolean aFlag) : Set the component visible (true) or unvisible (false)


setBackground(Color bg) : Define the background color (java.awt.Color.RED, )

setBorder(Border) : Define the border

setDoubleBuffered(boolean aFlag) : Enable (true, default value) or disable (false) the double buffering. It
allows better performance although it consumes more memory slot

setPreferredSize() : Define the prefered (default) size

setMinimumSize() : Define the minimum size

setMaximumSize() : Define the maximum size

setToolTipText(String text) : Define the parameter as tool tip text

1.5.2. Buttons
1.5.2.1. AbstractButton
The AbstractButton class is the parent class of all the buttons. You will not use it directly, but one of its subclass.
It provides the common properties and methods from the buttons. Furthermore it extends JComponent, so it can
use borders, tooltips ).
The following method within AbstractButton allow to manage events (we will study events handling on a next
chapter) :

void addActionListener(ActionListener l) : Add an ActionListener to the button.

ActionListener[] getActionListeners() : Return an array of the ActionListener which have subscribed to the
button.

155
Created by XMLmind

XSL-FO Converter.

void removeActionListener(ActionListener l) : Remove the ActionListener specified in the parameter.

void doClick() : Simulate a click

protected void fireActionPerformed(ActionEvent event) : Simulate an event.

String getActionCommand()

void setActionCommand(String actionCommand)


Define/Return the identifier of the button. This value allows to know exactly wich button has generated an
event

void setEnabled(boolean b) : Enable (or disable) the button (according to the value of the parameter). When
disabling the button is freeze.
Other methods :

void setText(String text) : Define the text displayed of the button ( can be set with the constructor )

void setUI(ButtonUI ui) : Define the Look&Feel of the component (this facility manages the rendering of the
component). To see chapter on Look and Feel for more information.
1.5.2.2. JButton
JButton is the commonly used button. It is very simple to use. It extends AbstractButton which has been
described above, and it is quite similare to JLabel thank to its setText(String) and setIcon(Icon) methods.
Available methods:
JButton() : Create a button without neither text or icon (you can call setText() and setIcon() afterward)

JButton(Icon) : Create a button with a picture

JButton(String) : Create a button with text

JButton(String, Icon) : Create a button with text and pictures

setHorizontalAlignement(int) : Define the text and icon horizontal alignment

setVerticalAlignement(int) : Define the text and icon vertical alignment

setHorizontalTextPosition(int) : Define the text horizontal alignment

156
Created by XMLmind

XSL-FO Converter.

setVerticalTextPosition(int) : Define the text vertical alignment

setIcon(Icon icon) : Define an icon

setPressedIcon(Icon) : Define the displayed icon when the button is pressed

setRolloverIcon(Icon) : Define the displayed icon when the mouse roll over the button

getText() : Retrieve the text

setText(String) : Define the text (html syntax enabled)

getIcon() : Retrieve the icon

setIcon(Icon) : Define the icon

setMnemonic(char) : Create a shortcut with the keyboard (ex : setMnemonic('C') create a binding to Alt+C
)

addActionListener(ActionListener) : Add an ActionListener

setEnabled(boolean) : Enable / Disable the button

setActionCommand(String) : Define the identifier of the button (useful for event management)
In order to define the alignement, the following constants are available:

SwingConstants.RIGHT

SwingConstants.LEFT

SwingConstants.CENTER

SwingConstants.LEADING

SwingConstants.TRAILING
Here is a code sample, which shows how to add a button to your frame:
[CODE:java]JFrame myFrame = new JFrame("Commercial Survey");
JButton btnSend = new JButton("Send");
myFrame.add(btnSend);

Below you can see a screenshot :

157
Created by XMLmind

XSL-FO Converter.

Figure 9.6. There are also others kinds of buttons which are going to study now.

1.5.2.3. JRadioButton
A JRadioButton is a radio button ! It allows to display multiple choice, and there is (most of the time) only
one choice selectable on the same time.
It is required to use a ButtonGroup in order to gather the JRadioButtons inside the same logical group. First you
have to create an instance of the ButtonGroup, then you add JRadioButton instances through the method
add(Button).
On the following code sample, we are going to create JRadioButton instance and then we insert them inside the
ButtonGroup:
[CODE:java]
/****************************
* create radio buttons *****
****************************/
// mario choice
JRadioButton buttonMario =
new JRadioButton("<html><font color='red'>Mario Bros</font></html>");
// this one is selected by default
buttonMario.setSelected(true);
// sonic choice
JRadioButton buttonSonic =
new JRadioButton("<html><font color='blue'>Sonic the hedgehog</font></html>");
// warcraft choice
JRadioButton buttonWarcraft =
new JRadioButton("<html><font color='green'>Warcraft</font></html>");
// group the radio buttons together ( logically, not graphically )
ButtonGroup group = new ButtonGroup();
group.add(buttonMario);
group.add(buttonSonic);
group.add(buttonWarcraft);

In order to retrieve the selected button, we have to call the method getSelection() from the ButtonGroup
instance. This one returns the model of the selected button (a model is an object which contains the state and the
logic of the component but we will talk about it lately!).
On the following screenshot you can see an application which use radio buttons :

Figure 9.7.

158
Created by XMLmind

XSL-FO Converter.

1.5.3. Text components


When you create a graphical interface, we need to display a lot of textual informations (as well as pictures). We
are going to discover which component will broad your message!
1.5.3.1. JLabel
This class display text and pictures very easily.
The following application use JLabels in order to display text:

Figure 9.8.

Below you can see the most commonly used methods:


JLabel() : Create a label without neither text nor picture (you will can use setText() and setIcon()
afterward).

JLabel(Icon) : Create a JLabel with an icon

JLabel(Icon, int) : Create a label with an Icon, and the second parameter is the horizontal alignment value
(either SwingConstants.LEFT, CENTER, RIGHT, LEADING or TRAILING)

JLabel(String) : Create a JLabel with a String

JLabel(String, int) : Create a JLabel with text and the second parameter is the horizontal alignment value
(either SwingConstants.LEFT, CENTER, RIGHT, LEADING or TRAILING)

JLabel(String, Icon , int) : Create a JLabel with text and an icon. The third parameter is the horizontal
alignment value (either SwingConstants.LEFT, CENTER, RIGHT, LEADING or TRAILING)

159
Created by XMLmind

XSL-FO Converter.

setHorizontalAlignement(int alignement) : Define the horizontal alignment

setVerticalAlignement(int alignement) : Define the vertical alignment

setHorizontalTextPosition(int) : Define the horizontal text position (either SwingConstants.LEFT, CENTER,


RIGHT, LEADING or TRAILING)

setVerticalTextPosition(int textPosition) : Define the vertical text position (either SwingConstants.LEFT,


CENTER, RIGHT, LEADING or TRAILING)setIcon(Icon)

setText(String) : Define the text displayed inside the JLabel (support HTML syntax)
[CODE:java]
jLabel = new JLabel();
jLabel.setText("JLabel");

If you want to add a picture inside your JLabel, you can use the ImageIcon class specifying the path to the
picture: ImageIcon(String filename)
[CODE:java]
pictureLabel = new JLabel();
pictureLabel.setText("");
// load the picture thanks to the ClassLoader,
// this is required in order to load a picture from the
classpath
URL iconURL = getClass().getResource("/age/0.jpg") ;
pictureLabel.setIcon(imageIcon);

We will talk about the ClassLoader a bit later. In the following GUI (Graphical User Interface), we used a
JLabel in order to display a picture:

Figure 9.9.

160
Created by XMLmind

XSL-FO Converter.

By default, the horizontal alignement for the text is on the left. However, if your label contains a pictures, the
alignement is on the middle.
Just like we said beforce, in order to define the alignement you can use the following constants :

SwingConstants.LEFT

SwingConstants.CENTER

SwingConstants.RIGHT

SwingConstants.TOP

SwingConstants.BOTTOM
On the following schema you can see how your component will be displayed:

Figure 9.10.

1.5.3.2. JTextField
This component is the simplest input text field. It supports only one line of text, and it does not enable the style
(bold, italic ).
We can use one of the two following constructors:

JTextField() : Create an empty input text field

JTextField(String text) : Create an input text field with default text value from the parameter.
In order to retrieve the content of the input text field, you can use the getText() method, which returns a String
value.

1.5.4. Value Lists


For example : JComboBox
This component provide a list of values to the user, and he can only select one. It is a mix between the JList
component and a JButton.

Figure 9.11.

161
Created by XMLmind

XSL-FO Converter.

Below you can see the available method :

JComboBox() : Create an empty ComboBox

JComboBox(Vector) : Create a ComboBox with the elements inside the Vector specified as parameter.

JComboBox(Object[ ]) : Create a ComboBox with the elements inside the array.

JComboBox(ComboBoxModel) : Create a ComboBox with the model specified. A model is an object which
contains the data and the logic.

addActionListener(ActionListener) : Add an ActionListener to the JComboBox

addItem(Object) : Add an item to the list

getSelectedIndex() : Returns the index of the selected item

getSelectedItem() :Returns the object corresponding to the selected item

insertItemAt(Object, int) : Inserts an object at the specified index

paramString() : Returns a string representation of this JComboBox

removeAllItems() : Flushes the list

removeItem(Object) : Removes an object from the list

removeItemAt(int) : Removes an object designed by its index from the list

setEditable(boolean) : Determines whether the JComboBox field is editable

setEnabled(boolean) : Enables the combo box so that items can be selected.

setMaximumRowCount(int) : Sets the maximum number of rows the JComboBox displays.

162
Created by XMLmind

XSL-FO Converter.

setModel(ComboBoxModel) : Sets the data model that the JComboBox

setSelectedIndex(int) : Selects the item at the specified index (starting from 0)

setSelectedItem(Object) : Sets the selected item in the combo box display area to the object in the argument.

1.5.5. Display a menu


This is a musttouse component. Almost all the applications handle one. ( to see 4.3.1 chapter )
1.5.5.1. JMenuBar
The menu bar is a container, which is located inside a JFrame. It allows to group menu entries, as you can see
on the following screeshot:

Figure 9.12. This JMenuBar instance content File , Edit , Language and Help
entries

It is rather simple to use:

Create an instance with the default constructor (it is the only one available)

We add JMenu entries

We add it to the JFrame


Below is a code sample:
[CODE:java]// initialize
JMenuBar menuBar = new JMenuBar();
// add a JMenu entry with its getter
menuBar.add(getLangMenu());
// add the menu bar to the frame
myFrame.setJMenuBar(menuBar);

Figure 9.13. This tree shows how the menu components are nested

163
Created by XMLmind

XSL-FO Converter.

1.5.5.2. JMenu
This component is a node inside the menu bar:

Figure 9.14. Language and Quit are JMenu

The following code sample shows you a method, which creates and initializes a JMenu instance:
[CODE:java]/**
* This method initializes langMenu
*
* @return javax.swing.JMenu
*/
private JMenu getLangMenu() {
if (langMenu == null) {
langMenu = new JMenu();
// define a shortcut : CTRLL

164
Created by XMLmind

XSL-FO Converter.

langMenu.setMnemotecnic(KeyEvent.VK_L);
langMenu.setText("Language");
langMenu.add(getEnglishItem());
langMenu.add(getFrenchItem());
langMenu.add(getQuitMenu());
}
return langMenu;
}

The setMnemotecnic(String key) method allows to bind the menu entry with a shortcut. Here CRTLL opens
automatically the Language menu node.
At last, the method add(Component c) allows to add an entry inside a node (JMenu). The method take a
Component as parameter, it means that you can add any graphical component inside. Nonetheless it is advised
to add specific ones, like JButton, JRadioButton
1.5.5.3. JMenuItem and JRadioButtonMenuItem
These components fit well for the menu bar. They are quite similar to button but they are able to manage
specific functionalities:

Figure 9.15. This is an example of JMenu with JMenuItems, JRadioButtons, and


JCheckBoxButtons

As you can see above, JSeparator allows creating a separation between the buttons.
Below is a code sample, which create an instance and initialize a JRadioButtonMenuItem:
[CODE:java]/**
* This method initializes englishItem
*
* @return javax.swing.JMenuItem
*/
private JRadioButtonMenuItem getEnglishItem() {
if (englishItem == null) {
englishItem = new JRadioButtonMenuItem();
// a listener receive events of the button
englishItem.addActionListener(new java.awt.event.ActionListener() {
//
});
}
return englishItem;
}

1.6. Handle events


1.6.1. Basics
With Java, all the events generated by the user (click over a button, enter text inside an input text field ) create
165
Created by XMLmind

XSL-FO Converter.

events under the hood. These events are objects, which contains much information about the events
(which component has generated the event? When? ...).
If you want intercept an event, you have to create a Listeners which will subscribe to a component and will
be called each time an event is thrown.

1.6.2. Event classes


EventObject is the parent class of all the events.
An event is able to encapsulate data about its context:

The component which has generated the event (getSource()).

The clic position (in a MouseEvent event).

The value of a key pressed for a KeyEvent.

...
The object which intercepts the event is called a Listener. Its purpose is to listen to the events thrown by the
component.

Figure 9.16.

Most of the components have methods like addXxxListener(XxxListener l) where Xxx is the kind of event.
For example:

addActionListener()

addKeyListener()

addFocusListener()

...
Moreover, these methods come from the Container class and are common to most of the components and
containers.
The most famous one is addActionListener, and its ActionListener interface, which is used to perform a
treatment when the user clicks on a button.
166
Created by XMLmind

XSL-FO Converter.

It is also possible to unsubscribe a listener thank to the removeXxxListener() method, where Xxx has to be
replaced by the name of the event.

1.6.3. Practical
There is two ways to manage event. The shortest one implements the interface directly inside the code
(anonymous class), and the cleanest one create a new class which implements the interface.
1.6.3.1. Create an anonymous class
We can create an implementation of the code directly inside you graphical interface class:
[CODE:java]public class MyFrame extends JFrame {

public MyFrame(){

this.addWindowListener(
new WindowListener(){
public void windowActivated(WindowEvent arg0) {
// TODO Autogenerated method stub
}
public void windowClosed(WindowEvent arg0) {
System.exit(0); // close application
}
public void windowClosing(WindowEvent arg0) {
// TODO Autogenerated method stub
}
public void windowDeactivated(WindowEvent arg0){
// TODO Autogenerated method stub
}
public void windowDeiconified(WindowEvent arg0) {
// TODO Autogenerated method stub
}
public void windowIconified(WindowEvent arg0) {
// TODO Autogenerated method stub
}
public void windowOpened(WindowEvent arg0) {
// TODO Autogenerated method stub
}
}
);
}

We have created a WindowListener and we subscribe it to the JFrame events. This way when the user will close
the JFrame, the application will finish.
1.6.3.2. Declare the listener inside an external class
Apart from the previous code sample, we can use another syntax by creating an external class in order to
implement the WindowListener.
Inside the frame:
[CODE:java]
this.addWindowListener(new MyWindowListener());

In an external class called MyWindowListener:


[CODE:java]import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class MyWindowListener implements WindowListener {
public void windowActivated(WindowEvent e) {

167
Created by XMLmind

XSL-FO Converter.

// TODO Autogenerated method stub


}
public void windowClosed(WindowEvent e) {
System.exit(0); // kill the current application
}
public void windowClosing(WindowEvent e) {
// TODO Autogenerated method stub
}
public void windowDeactivated(WindowEvent e) {
// TODO Autogenerated method stub
}
public void windowDeiconified(WindowEvent e) {
// TODO Autogenerated method stub
}
public void windowIconified(WindowEvent e) {
// TODO Autogenerated method stub
}
public void windowOpened(WindowEvent e) {
// TODO Autogenerated method stub
}
}

This strategy is really much cleaner and allow us to use the same listener for many component ( like many
button in a same context).

1.6.4. Specific events


ActionEvent : Events generated when we perform an action related to the component ( click on a button, choose
a menu item, select an option in a combo box, etc )
[CODE:java]String getActionCommand()
Return the name of the component which has launched the event.
(If the component has no action command, it returns null)

ComponentEvent : Event generated when a component is hidden, displayed, resized or moved.


[CODE:java]Component getComponent()
Return the object which has generated the event (you will
probably have to cast the object)

ContainerEvent : Event generated when a component is added or removed from a container.


[CODE:java]Container getContainer()
Return the container which has generated the event.
Component getChild()
Return a reference to the child component which is inside the
container.

FocusEvent : Event generated when a component gain or loose the focus.


[CODE:java]boolean isTemporary()
Return true if the event is temporary, and false if it is
permanent. A text area loose automaticaly the focus if the user
handle the scroll bar.

KeyEvent : Event generated when the user press keys.


[CODE:java]char getKeyChar() return the pressed caractere
int getKeyCode() return the code of the key
and many others

MouseEvent : Event generated when the mouse is moved, released, pressed, etc
[CODE:java]int getX() return the horizontal position
int getY() return the vertical position
Point getPoint() return the positions of the cursor within a java.awt.Point
int getClickCount() return how many time the mouse has beenclicked during the event.

1.6.5. Listeners
168
Created by XMLmind

XSL-FO Converter.

ActionListener : Define methods in order to launch your code when an event happen. It handle clicks on buttons,
for example.
This interface contains the following method :
[CODE:java]void actionPerformed(ActionEvent ae)

Shes call when an action is performed on the component.


ComponentListener : Define methods which handle events when a component is either hidden, moved, resized
or shown.
[CODE:java]void componentHidden(ComponentEvent ce)
void componentMoved(ComponentEvent ce)
void componentResized(ComponentEvent ce)
void componentShown(ComponentEvent ce)

ContainerListener : Define methods which handle events when a component is added or removed from a
container.
[CODE:java]void componentAdded(ContainerEvent ce)
void componentRemoved(ContainerEvent ce)

FocusListener : Define methods which handle events when a component gain or loose the focus. You can also
use the FocusAdapter which provide you a default implementation.
[CODE:java]void focusGained(FocusEvent fe)
void focusLost(FocusEvent fe)

ItemListener is most of the time called when an item is selected inside a JComboBox. It contains the method
itemStateChanged(ItemEvent).
ListSelectionListener is used with JList in order to handle the events related to the selection of items. It contains
the method valueChanged(ListSelectionEvent).
KeyListener : handle the keyboard events.
[CODE:java]void keyPressed(KeyEvent ke)
void keyReleased(KeyEvent ke)
void keyTyped(KeyEvent ke)

KeyListener is used over components which allow to enter text, like JTextField, JPasswordField,
MouseListener : is used when you want to retrieve informations about the mouse cursor. (click, press a button,
release the button, if the cursor is inside a specific component
[CODE:java]void mouseClicked(MouseEvent me)
void mouseEntered(MouseEvent me)

1.7. Model
We have now seen the majority of Swing thinks and we know how Swing works. We will so see how to use it
correctly with the design pattern called MVC for ModelViewController.
We have seen the view and the controller ( explain a bit later ), we will now see the model part.
First, we are going to create a model of a form, then, in a second time we will see models of Swing components.

1.7.1. Use a model for a form


We are going to use models for forms in order to externalise the data and logic. Indeed, when you gather the
model and the form inside the same class your application is more difficult to write, maintain and update. With
this architecture your application is modular.
In a first time, we have the user interface, also called the view

169
Created by XMLmind

XSL-FO Converter.

Figure 9.17.

In a second time, we create a class, which contains data and validation methods it is what we call the model

Figure 9.18.

Below you can see the implementation:


[CODE:java]import com.labosun.profileMaker.model;
/**
* This is the model of our application,
* it allows to store values of the form
* and also provide validation.
*/
public class RegistrationModel {
private String name;
private String firstname;
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* check text fields values
* check if the fields are not empty
*
* @throws EmptyFieldException when the form is empty
*/
public void validate() throws EmptyFieldException{
if(name == null || name.equals("")){

170
Created by XMLmind

XSL-FO Converter.

throw new EmptyFieldException();


}
if(firstname == null || firstname.equals("")){
throw new EmptyFieldException();
}
}
}

Like you can see, a model is a very easy class, who only contains properties to store with her getters and setters,
and logical validation of these properties.
In a third time we need the controller, who will link the view with the model. This is the listener job.
Below you can see the controller :
[CODE:java]package com.labosun.profileMaker.controler;
// imports
public class RegistrationAction implements ActionListener {
private CreateProfile registrationFrame;
/**
* retrieve the CreateProfile Frame (the view), it handles its properties with ease
* @param registrationFrame
*/
public RegistrationAction(CreateProfile registrationFrame)
{
super();
this.registrationFrame = registrationFrame;
}
/**
* This method is performed automaticaly when an event occure.
* It synchronizes the view (jframe) with model during the event
*/
public void actionPerformed(ActionEvent arg0) {
RegistrationModel rec = new RegistrationModel();
// put value from the view inside the model
rec.setFirstname(registrationFrame.getFirstnameTxt().getText());
rec.setName(registrationFrame.getNameTxt().getText());
// check if the form is valid
try {
// check the values of the form
// if there is a mistake, an exception is thrown
rec.validate();
// display a success message
registrationFrame.getRegistrationLabel().setText("registration complete !");
registrationFrame.getRegistrationLabel().setForeground(Color.BLACK);
} catch (Exception e) {
registrationFrame.getRegistrationLabel().setText("Input Fields should not be empty");
registrationFrame.getRegistrationLabel().setForeground(Color.RED);
}
}
}

We can list the tasks performed during validation of the form:

The user press the button on the view layer

It creates an event which is managed by a listener (this is the controller)

The controller retrieve data from the view and send them to the model

The controller asks the model whether the validation is all right or not

171
Created by XMLmind

XSL-FO Converter.

The controller returns the answer to the view

1.7.2. Use models for Swing components


Like we have use the MVC design pattern for a form ( a group of component ), we can use it for one component
only.
Many Swing components have already existing model. That be useful and more quick to implements these
model than write our.
Here a short list of these models :

ButtonModel
:
JButton,
JToggleButton,
JRadioButtonMenuItem, JCheckBoxMenuItem

JCheckBox,

JRadioButton,

JMenu,

JMenuItem,

ComboBoxModel : JComboBox

BoundedRangeModel : JProgressBar, JScrollBar, JSlider


Document : JTextField, JPasswordField, JTextArea, JEditorPane and many others.

Figure 9.19. Swing components have a MVC architecture

Models are an important part of each component and some components define it implicitly with the constructor.
Here an example with the JComboBox :
[CODE:java]String[] s = {"from 1 to 10","from 11 to 20","from 21 to 30"};
ageComboBox = new JComboBox(s);
ageComboBox.getSelectedIndex();
ageComboBox.getSelectedItem();

And manually we can also do the same thing by handling the model:
[CODE:java]String[] s = {"from 1 to 10","from 11 to 20","from 21 to 30"};
ageComboBox = new JComboBox();
ComboBoxModel boxModel = new DefaultComboBoxModel(s);
ageComboBox.setModel(boxModel);
boxModel.getSelectedItem();

1.8. Look and feel


1.8.1. Introduction
172
Created by XMLmind

XSL-FO Converter.

Swing provide a pluggable look & feel architecture. It means that it is easy to change the graphical aspect and
behaviours. Indeed a Swing application can appear and act differently on different platforms and seems to be
native.
Below you can see the same application in action on different platforms:

Figure 9.20. Over MacOs X

Figure 9.21. Over Windows

Figure 9.22. Over Linux (GTK)

1.8.2. Change the look and feel


It is also possible to change the look and feel your application easily, about is the used platform.

173
Created by XMLmind

XSL-FO Converter.

For that are related to the look and feel, the UIManager class is used. What she allows will be explain now with
some sample of code.
A look is a class, and so, have a class name like javax.swing.plaf.metal.MetalLookAndFeel. It is this name
who will be used to change the look and feel, easily by passing it to the UIManager. Like this :
[CODE:java]
UIManager.setLookAndFeel(javax.swing.plaf.metal.MetalLookAndFeel);

Figure 9.23.

1.8.2.1. Retrieve available look


By defect, depending on the running platforms, some looks are available. To retrieve this list, the UIManager
have a useful method who will return the list of these available look.
A look have some related information, like this name, and the UIManager return a specific list that contains
these information. So, one more time, we use the UIManager to store the list and use it.
[CODE:java]// return look available
UIManager.LookAndFeelInfo[] info =
UIManager.getInstalledLookAndFeels();
for(int i = 0; i < info.length; i++) { // for each look
info[i].getName(); // get the look name
info[i].getClassName(); // get the look class name
}

1.8.2.2. Change the look dynamically


That we have seen until now work great, but at one condition : change the look before initialize the graphical
interface. That is caused because the UIManager dont refresh the GUI component after changing the look.
Hopefully, we have another class, SwingUtilities, who allow us to refresh the GUI component displayed !
To do this, we only need to call a method of this class after changing the look, like this :
[CODE:java]SwingUtilities.updateComponentTreeUI(frame);

Where the frame parameter, is the frame to refresh.

174
Created by XMLmind

XSL-FO Converter.

With that skill, we can display the available look to the user, and let him choose his preferred look !
The chapter 7 of the exercise book do it, to see for more information ( a video correction is available ).
1.8.2.3. Add new look
Changing the look of our application is very great, but in the fact, we have approximates three look available.
this will not very great. But hopefully, project like Substance exist and provide a large choice of look and feel !

Figure 9.24.

The substance project is available here :

https://substance.dev.java.net/
and can be try directly ( with java web start ) here :

https://substance.dev.java.net/webstart/test.jnlp
To add it to your application, you only need to add the JAR archive available on the web site to your project,
and you are ready to call the containing class of look and feel ! For more information, look at the readme, or the
detailed online documentation.

Figure 9.25.

175
Created by XMLmind

XSL-FO Converter.

1.8.2.4. Create a look


Like the Substance project, it is possible to create our custom look ! But of course, this is a bit more advanced,
and that will not be seen in this manual. However, two books on the subject are available freely on the web site
of java, here :

http://java.sun.com/products/jlf/

1.9. Conclusion
During this course we browsed most important parts of Swing in order to create a functional and pleasant user
interface, and secondly to see how to structure our application with MVC.
You can also improve your skills with the course Advanced Swing which is about highlevel components and
architecture.
Glossary and tutorials about main Swing components:

http://java.sun.com/docs/books/tutorial/uiswing/index.html
A book about Swing:
http://java.sun.com/products/jlf/ed2/book/.
Many articles:

http://java.sun.com/javase/technologies/desktop/articles.jsp
More informations about MVC:

http://www.javaworld.com/javaworld/jw041998/

jw04howto.

176
Created by XMLmind

XSL-FO Converter.

html

Chapter 10. Swing Advanced


By completing this course, you will be able to:

Position components efficiently

Integrate high-level components

Manage events

Write a multilingual software

1. Course
1.1. Introduction
The Swing library allows Java developers to express their creativity in graphical user interface. However, a
certain ignorance of the working procedure of this API led to considerable graphic and structural incoherence in
phase of production. A significant aspect of the Swing programming is the use of positioning managers. We will
explain the inheritent concepts in their use and the programming sciences techniques allowing to automatically
place the graphic components in a window.

Then we will study more complex components of Swing, such as JTree or JTable. We will benefit from their
power.

In the third time we will see how to manage Threads within Swing efficiently because there are certain concepts
to know before carrying out heavy treatments within a graphic interface. Then we will finish with the
synchronization of the model and the view with the Observable design pattern.

177
Created by XMLmind

XSL-FO Converter.

1.2. LayoutManager
The layout managers are objects which can manage the positioning of the components inside a container (ex:
JPanel). Their utility is to manage situations such as the width of the window. Thus, they make it possible to
discharge the programmer from this tiresome work. Each layout manager defines its own strategies and meets
recurrent requirements in term of positioning. We will see that several types exist however they implement the
entire LayoutManager interface. In case we wish to create our own manager it is necessary to implement it, but
this contribution will not be very useful because sufficient one already exist!

1.2.1. Place components with absolute values (AbsoluteLayout)


Let us begin with a first manager which is not really one since it does not do anything automatically. Indeed,
you will have to place yourself the components. The great inconvenience is that it does not manage the
enlarging of a window nor even the components which would risk to be superimposed. To be able to place it we
are going to define the value null on the manager of placement of the container in the course of use:
[CODE:java]... // set display layout
setLayout(null);
...

Then we must place each component with the following values :

Its x coordinate

Its y coordinate

178
Created by XMLmind

XSL-FO Converter.

Its width

Its height
[CODE:java]// ... first we retrieve the size of a component and we set him location values
Dimension size = jLabel.getPreferredSize();
jLabel.setBounds(25 , 5, size.width, size.height);
// ... and we do the same thing for the other components
size = getJTextField().getPreferredSize();
getJTextField().setBounds(25, 20, size.width, size.height);
size = getJButton().getPreferredSize();
getJButton().setBounds(25, 40, size.width, size.height);
// define the size of the current frame
setSize(300 , 125);

And finally we can add the components to the container:


[CODE:java]jContentPane.add(jLabel, null);
jContentPane.add(getJTextField(), null);
jContentPane.add(getJButton(), null);

We obtain the following window :

We notice that the elements are superimposed slightly and are badly arranged; moreover the elements remain in
their place when the window is increased.
We treated this way of managing the placement to highlight the interest of the positionning devices.

1.2.2. FlowLayout
It is a very simple layout which places the components from left to right, the ones beside the others and on the
same line as much as possible by basing on the ideal size of the components.
If there is not place enough on a line to contain a component, a new line is added under the current one. As the
placement depends on the current size of the window, it is impossible to know in advance the line on which will
be placed component.
FlowLayout is the default layout of all JPanels except for JFrame which is initialized by default with a
BorderLayout.
Here is the detail of the builders that you can use :

FlowLayout() : create a centered FlowLayout;

FlowLayout(int) : create a FlowLayout with a specific alignment;


If you wish to build JPanel by using a specific layout manager, you will have to specify it:

With the creation of JPanel thanks to the following builder: JPanel(LayoutManager).

When your JPanel is created, modify its layout manager thanks to the method setLayout(LayoutManager).

179
Created by XMLmind

XSL-FO Converter.

The alignment constants are the following ones:

FlowLayout.LEFT

FlowLayout.CENTER

FlowLayout.RIGHT
Here is an example of using a FlowLayout with its modifications during a redimensioning :

Here is an example of code :


[CODE:java]/* ... */
JPanel jContentPane = new JPanel();
// set display layout
jContentPane.setLayout(new FlowLayout());
// add components
jContentPane.add(jLabel, null);
jContentPane.add(getJTextField(), null);
jContentPane.add(getJButton(), null);

1.2.3. BorderLayout
BorderLayout implements a very useful positioning strategy. The container is composed of five boxes. A
central box occupies the maximum of space possible in all the directions, and four boxes around this central
box. These peripheral boxes have the name of the cardinal points.

The central zone always takes the maximum of place however if the peripheral components do not take all the
place (if the window is reduced too much for example).
The north and south zones occupy the maximum of horizontally place but the minimum vertically. In other
words, they have their desirable sizes vertically, but are stretched horizontally.
The east and west zones occupy the maximum of vertically place but the minimum horizontally. In other words,
they have their desirable sizes horizontally, but are stretched vertically. If you wish to instance a BorderLayout
object, you will be able to do it thanks to the following builders :
180
Created by XMLmind

XSL-FO Converter.

BorderLayout() : create BorderLayout without space between the boxes.

BorderLayout(int hgap, int vgap) : create BorderLayout with specified spacings.


If you wish to specify the site of a component when it is added in ContentPane or other containers, you will
have to use the following methods : add(Component, Object): add one componant to the box specified by the
constant (see the constants of the BorderLayout object).
Here are the positionning constants related to the cardinal points:

BorderLayout.NORTH

BorderLayout.SOUTH

BorderLayout.EAST

BorderLayout.WEST

BorderLayout.CENTER
Here is an example of using BorderLayout with modifications at the time of a redimensioning :

It is the manager by default for JRootPane (the container of one JFrame).


Here is a concrete example of use:
[CODE:java]/**
* This method initializes jContentPane
*
* @return javax.swing.JPanel
*/
private JPanel getJContentPane() {
if (jContentPane == null) {
jLabel = new JLabel();
jLabel.setText("How old are you ?");
jContentPane = new JPanel();

181
Created by XMLmind

XSL-FO Converter.

jContentPane.setLayout(new BorderLayout());
jContentPane.add(jLabel, BorderLayout.NORTH);
jContentPane.add(getJTextField(),
BorderLayout.CENTER);
jContentPane.add(getJButton(),
BorderLayout.SOUTH);
}
return jContentPane;
}

1.2.4. GridLayout
GridLayout cuts out space in a grid (table) of the number of lines and columns which are fixed at instanciation.
The grid fills from the left to the right according to the number of columns, then from the top to the bottom
following the number of lines. GridLayout tries to make occupy all the place available in a container, which can
bring undesired changes of the size of the components.
Here are the various builders you have access to create objects of the GridLayout type :

GridLayout() : create GridLayout (1 row x 1 column)

GridLayout(int nbLine,int nbCol) : create a GridLayout of nbLine rows and nbCol columns

GridLayout(int nbLine,int nbCol,int width,int height) : create a GridLayout of nbLine rows, nbCol columns
with sizes the given width and height
Here is an example of using GridLayout with its modifications at the time of a redimensioning :

Here is a concrete example of use:


[CODE:java]/** */
GridLayout gridLayout = new GridLayout();
gridLayout.setRows(1);
gridLayout.setColumns(2);
jPanel = new JPanel();
jPanel.setLayout(gridLayout);
jPanel.add(getJButton(), null);
jPanel.add(getJButtonReset(), null);

182
Created by XMLmind

XSL-FO Converter.

/** */

1.2.5. Other devices supplied with Java SE


The following display devices are not to know in details however they could be useful in precise situations. In
order to know how to use them we advise to consult the Sun tutorials :
http://java.sun.com/docs/books/tutorial/uiswing/layout/layoutlist.html.
1.2.5.1. CardLayout
This layout can display only one component at the same time. Thus they are superimposed, as if it was about a
card deck and each one has a name. To be able to reach a component we must call it and it will appear masking
the previous component visible with the screen.

The concept is close to a system of tabs because we can navigate between several components and it displays
just one of them at the same time.

1.2.5.2. GridBagLayout
GridBagLayout allows to define a location according to a flexible squaring. Components will have for example
the possibility of extending on several lines or columns.

The squaring is known as flexible device because the rows and the columns inevitably do not have the same
heights and widths. GridBagLayout places the components in rectangles and refers then to their size by default
to know if it must extend them (see the method getPreferredSize(): JComponent class).
The use of java.awt.GridBagLayout is related to the use of the java.awt.GridBagConstraints which is the
class which will allow to define specificities of the squaring as well as the positioning of the objects.
[CODE:java]// definition of the arrangement (GridBagLayout and GridBagConstraints)
container.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();

Once the positionning grid is defined (number of rows/columns), the instance of the GridBagConstraints type
makes it possible to define the position and the characteristics of positioning for each component which will be
added to the Container.
1.2.5.3. BoxLayout
BoxLayout is a vertical or an horizontal FlowLayout. It allows to align some components next to others or
some below the others.
As soon as the components are aligned in a direction, they will remain to it whatever the size of the container.
BoxLayout has only one builder, which receives the reference of the container that it will manage, as well as a
183
Created by XMLmind

XSL-FO Converter.

direction. The components are displayed according to their preferredSize, and does not change their dimension
with this layout.
Here the builder to be used : BoxLayout(Container target, int axis) : create BoxLayout where components are
aligned along the given axis.
Here is an example using a BoxLayout with its changes at the time of a redimensioning :

1.2.5.4. SpringLayout
SpringLayout defines relations between the sides of components. For example you can define that the left edge
is fixed to a distance of 5 pixels of the right edge of another component. By default this device of location uses
the value Preferred Size to know the size of the component (see getPreferredSize() method of JComponent
class).
The distance between the edges is represented by "Spring" objects. Each one has four properties (minimum,
preferred, maximum, in progress).

1.2.6. GroupLayout
This device of positioning is provided by NetBeans. Its main interest is to be easy to handle with the graphic
editor of this last.
184
Created by XMLmind

XSL-FO Converter.

It combines at the same time the absolute values, but also the relative values compared to the edges of the
container or other components. It proposes for that a system of anchors :

So, even when the window is increased, the button will remain stuck on the right in bottom of the window.
We will not study code here because its interest is to be handled graphically. Moreover NetBeans blocks the
access in writing of this type of component.
Warning : it is not available in Java SE that is why you have to provide the jar file at the same time your
application using otherwise your clients will have "ClassNotFoundException" exceptions.

1.3. The high-level components


1.3.1. A spreadsheet with JTable
JTable is extremely useful component. Indeed a complete package, named javax.swing.table is devoted to him.
JTable component makes it possible to display data tables, by allowing the edition of its data. JTable does not
contain its own data but obtains them starting from a table of objects with 2 dimensions, or starting from a data
model.
Example of JTable :

JTable class implements the interface Scrollable (means that it can be placed in JScrollPane).
Each JTable has three models which are :
185
Created by XMLmind

XSL-FO Converter.

TableModel : defines the way in which the data are stored, and manages the additions and suppressions as
well as the recovery of the data. It defines also the types of data of each column, and specifies if a cell is
ditable or not. All the data of the table are stored in TableModel (table with 2 dimensions or vector of
vectors).

TableColumnModel : manages intances of TableColumn (column of the table). TableColumnModel is


responsible for the display of the columns in the table. Each TableColumn has a cell renderer, a cell editor, a
table header, and a cell renderer for the table header.

ListSelectionModel : defines the mode of selection (singleinterval, multipleinterval). ListSelectionModel is


very flexible and makes it possible to customize the selections in all the manners we want.
At first we are going to see the parameter setting of the "view" part, and we will study TableModel in order to
be able to create our own table in an optimal way.
1.3.1.1. The view
We use the JTable class mainly in order to configure the graphic part of the component :

setEnabled(boolean) : activate or deactivate the component

setBackground(java.awt.Color) : defines the basic color being used by using the constants defined in the
enumeration.

selectionBackground(java.awt.Color) : defines the colour of the selection.

...
We have many other parameters like the tab parameter of Eclipse:

186
Created by XMLmind

XSL-FO Converter.

Finally we underline the existence of the method setModel (DefaultTableModel) which allows to define the
model to be used. We are going to study the creation of a model.
1.3.1.2. The model: DefaultTableModel
We must inherit the DefaultTableModel class because it defines a model by default. We will redefine certain
methods in order to be able to display and modify desired information.
Here the list of the methods which Eclipse proposes to override :

187
Created by XMLmind

XSL-FO Converter.

We must redefine the method getColumnCount () in order to be able to manage the number of columns to be
displayed. In the same way, for getRowCount () we have the number of lines to display.
We are going to list the most interesting methods.

public int getColumnCount() : return the number of columns.


[CODE:java]public int getColumnCount() {
return 2;
}

public String getColumnName(int column) : return the name of each column. Thus we had defined two
columns so the table calls the method getColumnName twice (), first once with index 0 and one second time
with index 1.
[CODE:java]public String getColumnName(int column) {
if(column==0){
return "Id";
}else {
return "Nickname";
}
}

public int getRowCount() : return the number of lines in the table. In general we use a collection so the
following code returns the size of the table. We admit in the following code the method getMyDataCollection
() returns a list of the List type:
[CODE:java]public int getRowCount() {
return getMyDataCollection().size();
}

188
Created by XMLmind

XSL-FO Converter.

public Object getValueAt(int row, int column) : return the value of each cell of the table. The first parameter
corresponds to the number of line, then the second is the number of the column. We admit in the following
code the method getMyDataCollection () returns a list of the List type:
[CODE:java]public Object getValueAt(int row, int column) {
if(column==0){
return getMyDataCollection().get(row).getId();
}else{
return getMyDataCollection().get(row).getNickname();
}
}

public boolean isCellEditable(int row, int column) : return a boolean value determining if the cell indicated
by the parameters is editable or not. The fact that a cell is editable means that the value can be changed by the
user. However that does not mean that the modifications are validated in the data source (for that we will see
the method setValueAt ()). Here no column is editable.
[CODE:java]public boolean isCellEditable(int row, int column) {
return false;
}

And finally, we admit we want to display a third column editable:


[CODE:java]public boolean isCellEditable(int row, int column) {
if(column==2){
return true;
}
return false;
}

Warning, of course it is necessary that the number of columns is fixed at 3 so that the method can be called
with parameter 3:
[CODE:java]public int getColumnCount() {
return 3;
}

public void setValueAt(Object aValue, int row, int column) : this method is called in order to apply the data
modified in the table towards the data source.
[CODE:java]public void setValueAt(Object aValue, int row, int column) {
if(column==2){
MyData myData = getMyDataCollection.get(row);
myData.setSelectedGame((Game)aValue);
new GamerDaoImpl().update(myGamer);
}
}

We can display this manner the following spreadsheet starting from the data contained in our list :

1.3.1.3. Display a list of values


We consider that the user must choose a game in a dropdown list. A simple manner to create an editor is to use
189
Created by XMLmind

XSL-FO Converter.

the DefaultCellEditor class.


This one encapsulates the graphic component in the form of a named variable editorComponent. It is possible to
display JTextField, JCheckBox or JComboBox. DefaultCellEditor lays out builders making it possible to
accept each above mentioned component.
[CODE:java]Object[] games = {"CounterStrike", "Warcraft", "Arcanoid", "Sonic"};
JComboBox cboGames = new JComboBox(games);
DefaultCellEditor myEditor = new DefaultCellEditor(cboGames);
TableColumn col3 = myTable.getColumnModel().getColumn(2);
col3.setCellEditor(myEditor);

1.3.2. An explorer with JTree


We can represent an explorer with the JTree class. It is often compared with a reversed tree because it has an
entry root with several ramifications called "Node" and of the input "Leaf".

In the case of JTree a difficulty concerning the creation of the tree structure exists. Indeed even if there is a
builder which takes in parameter a vector of objects, this one creates a tree where all the elements are located at
the same level of tree structure (in fact with the root).
With a JTree object, the nodes are represented by TreeNode objects. There are methods giving access to the
parents and the list of the children of TreeNode.
The builder most commonly used to build JTree is the following one : JTree (TreeNode root)
The parameter of this builder is an object implementing the TreeNode interface which is in the package
javax.swing.Tree.
An instanciable class implementing TreeNode is the DefaultMutableTreeNode class. This class is very easy to
use, we can add children, reach a parent, etc
The creation of a tree and nodes is done in the following way :
[CODE:java]DefaultMutableTreeNode top = new DefaultMutableTreeNode("Top");
DefaultMutableTreeNode n1 = new DefaultMutableTreeNode("N1");
DefaultMutableTreeNode n1_1 = new DefaultMutableTreeNode("N1");
DefaultMutableTreeNode n2 = new DefaultMutableTreeNode("N1");
...

Then we describe the tree structure by adding the children to their parent :
[CODE:java]n1.add(n1_1);

190
Created by XMLmind

XSL-FO Converter.

top.add(n1);
top.add(n2);

Finally we create the tree thanks to the builder evoked previously :


[CODE:java]JTree arbre = new JTree(top);

1.3.2.1. The view


JTree class proposes a certain number of parameter in order to customize its displaying as we can see it in the
tab Properties of Eclipse :

But the most important element for returned is the use of a "render". It is a class which allows to customize the
displayed icons we will study it later.
1.3.2.2. DefaultMutableTreeNode
As we already saw previously, it is a class which allows to represent an input and makes it possible to contain
other input via method add (TreeNode).
It contains much method allowing to navigate through the input, to recover the input parents ("Ancestor") and
children ("Child"), of knowing on which level ("Depth") an input is located, to recover the nodes ("Node") and
the leafs ("Leaf") of explorer tree,
We will not describe them because their name is in general sufficient to describe their operation :
[CODE:java]void add (MutableTreedNode newChild);
Enumeration breadthFirstEnumeration();
Enumeration childrenn();
Enumeration depthFirstEnumeration();
boolean getAllowsChildren();
TreeNode getChildAfter(TreeNode aChild);
TreeNode getChildAt(int index);
TreeNode getChildBefore(TreeNode aChild);
int getChildCount();
int getChildCount();
int getDepth();
TreeNode getFirstChild();
DefaultMutableTreeNode getFirstLeaf();
int getIndex (TreeNode aChild);

191
Created by XMLmind

XSL-FO Converter.

TreeNode getLastChild();
DefaultMutableTreeNode getLastLeaf();
int getLeafCount();
int getLevel();
DefaultMutableTreeNode getNextLeaf();
DefaultMutableTreeNode getNextNode();
DefaultMutableTreeNode getNextSibling();
TreeNode getParent();
TreeNode[] getPath();
protected TreeNode[] getPathToRoot(TreeNode aNode, int depth);
DefaultMutableTreeNode getPreviousLeaf();
DefaultMutableTreeNode getPreviousNode();
DefaultMutableTreeNode getPreviousSibling();
TreeNode getRoot();
TreeNode getSharedAncestor(DefaultMutableTreeNode aNode);
int getSiblingCount();
Object getUserObject();
Object[] getUserObjectPath();
void insert(MutableTreeNode newChild, int childIndex);
boolean isLeaf();
boolean isNodeAncestor(TreeNode anotherNode);
boolean isNodeChild(TreeNode aNode);
boolean isNodeDescendant(DefaultMutableTreeNode anotherNode);
boolean isNodeRelated(DefaultMutableTreeNode aNode);
boolean isNodeSibling(TreeNode anotherNode);
boolean isRoot();
Enumeration pathFromAncestorEnumeration(TreeNode ancestor);
Enumeration postorderEnumeration();
Enumeration preorderEnumeration();
void remove(int childIndex);
void remove(MutableTreeNode aChild);
void removeAllChildren();
void removeFromParent();
void setAllowsChildren(boolean allows);
void setParent(MutableTreeNode newParent);
void setUserObject(Object userObject);

We advise you to consult JavaDoc in order to have more information on these many methods.
A practice we advise you to make is to inherit from this class to represent more effectively the data in your
model. So the data will be easier to treat. To represent it we shall take the enumeration Game that here:
[CODE:java]package com.labosun.swing.advanced.bo;
public enum Game {
CounterStrike, Warcraft, Arcanoid, Sonic
}

Then we will create a customized type of input for the values of the enumeration :
[CODE:java]package com.labosun.swing.advanced.exercise07;
import javax.swing.tree.DefaultMutableTreeNode;
import com.labosun.swing.advanced.bo.Game;
public class GameTreeNode extends DefaultMutableTreeNode {
private Game game;
public GameTreeNode(Game game) {
super(game.toString());
this.game = game;
}
public Game getGame() {
return game;
}
public void setGame(Game game) {
this.game = game;
}
}

192
Created by XMLmind

XSL-FO Converter.

We can add the following elements in the instance of your JTree :


[CODE:java]DefaultMutableTreeNode top = new
DefaultMutableTreeNode("Gamers");
for(Game game : Game.values()){
GameTreeNode gameNode = new GameTreeNode(game);
top.add(gameNode);
}
jTree = new JTree(top);

The most interesting element will be the recovery of the elements at the time of the events because we can test
the type of input with the key word java instanceof in order to have a particular treatment according to the
type of input:
[CODE:java]public class MyListener implements MouseListener {
/** */
private JTree jtree;
/** */
public void mousePressed(MouseEvent e) {
// retrieve selection
TreePath selection = jtree.getSelectionPath();
// retrieve text
if(selection != null && selection.getLastPathComponent() instanceof GameTreeNode){
// retrieve the game
Game game = ((GameTreeNode) selection.getLastPathComponent()).getGame();
// display the menu, then the list of players
JOptionPane.showMessageDialog(null, new GamerDaoImpl().findGamersForGame(game));
}
}
}

1.3.2.3. Returned of the explorer


To customize a tree (customized icons), we can use the renderers method. The renderers allow to modify the
graphic aspect of the components directly starting from the code, as in this case, customize a component. With
JTree we are going to use DefaultTreeCellRenderer. We can specify the 3 following icons :

setClosedIcon(Icon) : Closed Node

setOpenIcon(Icon) : Opened Node

setLeafIcon(Icon) : Leaf
Here an example using this method:
[CODE:java]/** */
ImageIcon leafIcon =createImageIcon("image.gif");
if (leafIcon != null) {
DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
renderer.setLeafIcon(leafIcon);
tree.setCellRenderer(renderer);
}
/** */

193
Created by XMLmind

XSL-FO Converter.

However most effective, if we wish to have returned a more customized tree, it is necessary to implement the
TreeCellRenderer interface.

See

the

following

site

for

more

information:

http://www.cs.cf.ac.uk/Dave/HCI/HCI_Handout_CALLER/node155.html
Note: do not forget to use the system of classloader, as we have seen it in the course on the basic functionalities
of Swing, in order to charge your pictures when your application is in the JAR form.

1.3.3. Display of a dropdown menu


The display of a dropdown menu corresponds of the use of a menu when we did a rightclick on an element as
we can see it in the following screenshot :

Its use is closed to the menu of a window. Indeed, the components have practically the same name and are used
in a similar way. However, it is necessary to see for the moment how managing the events coming from the
rightclick.
1.3.3.1. Management of the event rightclick
It is important to speak about this event because it can cause an inconsistency on this subject. Indeed, this button
does not exist on the Apple machines, so how they be able to access this functionality?
In a certain manner it is possible to recover the button used in the following way :
[CODE:java]public class MyListener implements MouseListener {
private JTree jtree;
public MyListener(JTree jtree){

194
Created by XMLmind

XSL-FO Converter.

this.jtree=jtree;
}
/** */
// we deprecate this
public void mousePressed(MouseEvent e) {
if(e.getButton() == MouseEvent.BUTTON1) {
/** display popup menu */
}
}
}

However it is preferable to use the method isPopupTrigger() so that the virtual machine manages this event
in an autonomous way. Thus the virtual machine of Windows reference "true" when the user presses the
rightclick and under MacOsX it acts of the click and the button "ctrl" pressed simultaneously. Here the code to
be used:
[CODE:java]public class MyListener implements MouseListener {
private JTree jtree;
public MyListener(JTree jtree){
this.jtree=jtree;
}
/** */
// we advise this
public void mousePressed(MouseEvent e) {
if(e.isPopupTriggered() == true) {
/** display popup menu */
}
}
}

We have just seen how to manage the rightclick, we now will be able to study the components with instance.
1.3.3.2. Components necessary to display the dropdown menu
The classes used for the displaying of a dropdown menu are as follows:
JPopupMenu : it is about the root element of the menu. Its methods add () mainly allow to add instances
of the JMenuItem type. Finally to make visible the dropdown menu we can proceed in the following way:
[CODE:java]/** */
public void mousePressed(MouseEvent e) {
if(e.isPopupTriggered() == true) {
JPopupMenu menu = new JPopupMenu();
menu.add(new JmenuItem("See"));
menu.add(new JmenuItem("Delete"));
menu.show(e.getComponent(),e.getX(),e.getY());
}
}
/** */

JMenuItem : this class allows to create entries within the dropdown menu. It has a name and we can add
listeners to it in order to manage its events.
[CODE:java]// we want to delete all the players
JMenuItem menuItemDelete = new JMenuItem("Delete");
menuItemDelete.setText("Delete");
menuItemDelete.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
/** ... */
}
});

JCheckBoxMenuItem and JRadioButtonMenuItem are children classes of JMenuItemn so they are used in
the same way except to use check boxs and radio buttons. In this case it is necessary to see the part of course
on JCheckBox and JRadioButton.
195
Created by XMLmind

XSL-FO Converter.

1.3.4. Navigate in the filing system with JFileChooser


The JFileChooser class provides a dialog box with advanced functions of navigation. Here are the builders:

JFileChooser(File CurrentDirectory) : create JFileChooser positioned on File

JFileChooser(String CurrentDirectoryPath) : create JFileChooser positioned on CurrentDirectoryPath


As well as the most used methods :

getSelectedFiles() : return the selected files (File[]).

getSelectedFile() : return the selected file (File).

getCurrentDirectory() : return the File object associated with the current directory.

setDialogTitle(String title) : define the title of the dialog box.

setFileSelectionMode(int Mode) : JFileChooser.FILES_ONLY , JFileChooser.DIRECTORIES_ONLY. By


default, both are allowed.

showDialog(Component parent, String ApproveButton) : custom dialog box

showOpenDialog(Component parent) : display the dialog box OpenFile . The parameter can be null but
we can also specify a parent component in order to facilitate the placement as well as the management of the
Look and Feel.

showSaveDialog(Component parent) : display the dialog box SaveFile . The parameter can be null but
we can also specify a parent component in order to facilitate the placement as well as the management of the
Look and Feel.
1.3.4.1. Open a JFileChooser
Here is an example of call of the method showOpenDialog() :
[CODE:java]/** */
// open a file selection box
JFileChooser fileChooser = new JFileChooser();
// we only want one selection
fileChooser.setMultiSelectionEnabled(false);
int result = fileChooser.showOpenDialog(myFrame);
// we retrieve the absolute path
if(result == JFileChooser.APPROVE_OPTION){
// update view and model
File file = fileChooser.getSelectedFile();
/** */
}
/** */

196
Created by XMLmind

XSL-FO Converter.

We can thus navigate easily through the filing system and recover the selection.
We will now see another great part of Swing which is the management of advanced events.
This code shows how to select a directory:
[CODE:java]public class Directory {
static public void main(String[] args) {
// open a file selection box
JFileChooser jFileChooser = new JFileChooser();
jFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int result = jFileChooser.showOpenDialog(null);
}
}

1.3.4.2. Use FileFilters


FileFilters can be used to only display specifics file, for example, only images.
You can create your own filters by implementing the FilterFilter interface.

197
Created by XMLmind

XSL-FO Converter.

[CODE:java]public class MyFilter implements FilterFilter {


public boolean accept(File f) {
boolean acceptThisFile;
// Determine if the file can be accepted
return acceptThisFile;
}
public String getDescription() {
return "Your file filter description";
}
}

After that, you only need to set your filter to your JFileChooser :
[CODE:java]/** ... */
MyFilter filter = new MyFilter();
myFileChooser.setFileFilter(filter);
/* ... */

1.4. Advanced management of the events


We have seen in the course Basic Swing how the system of the listeners works. We will see some subparts
in order to avoid the problems of update and returns with the management of Threads, but also how to make the
graphic interfaces more reactive with the "Observable" design pattern.

1.4.1. Threads within Swing


Swing has its own Threads returned. This one manages the resizing of the window, the state of a change of
button, etc. This one is not visible by the programmer because it is managed in a completely transparent way as
well for the user and the programmer.
1.4.1.1. The problem
However it can create problems when a treatment takes too much time to finish because Thread is occupied and
it cannot manage returned application any more as we can see it in the screenshot below:

We used the following code :


[CODE:java]/** */
/**
* This method initializes jButton
*
* @return javax.swing.JButton
*/
private JButton getJButton() {
if (jButton == null) {
jButton = new JButton();
jButton.setText("OK");
jButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
for(int i= 0 ; i<=100;i++){
getJProgressBar().setValue(i);
getJProgressBar().setString(i + "%");
System.out.println(i + "%");
try {

198
Created by XMLmind

XSL-FO Converter.

Thread.sleep(20);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
});
}
return jButton;
}
/** */

1.4.1.2. The solution


To avoid this, it is necessary to execute the treatment in an different Thread. So the calculation will not be
executed in the same thread of Swing components.
In this way we propose one second version of the code written previously:
[CODE:java]/** */
/**
* This method initializes jButton
*
* @return javax.swing.JButton
*/
private JButton getJButton() {
if (jButton == null) {
jButton = new JButton();
jButton.setText("OK");
jButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent e) {
// process is in inside a Thread
new MyThread(getJProgressBar()).start();
}
});
}
return jButton;
}
/** ... */

Here is MyThread class inheriting Thread :


[CODE:java]package com.labosun.swing.advanced.exercise10;
import javax.swing.JProgressBar;
public class MyThread extends Thread {
JProgressBar progressBar;
public MyThread(JProgressBar progressBar){
this.progressBar = progressBar;
}
@Override
public void run() {
for(int i= 0 ; i<=100;i++){
progressBar.setValue(i);
progressBar.setString(i + "%");
System.out.println(i + "%");
try {
Thread.sleep(100);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
}

For recall the run( ) method is called during the starting of Thread however the starting of Thread in itself is
done at the time of the call of the start( ) method.
1.4.1.3. Another solution, the use of SwingUtilities
We can also use Thread of returned in order to make calculation via SwingUtilities.invokeLater (). That will
199
Created by XMLmind

XSL-FO Converter.

cause to use the idle periods of the thread of made graphic in order to treat calculation (it need for that to be
waited until all the events are treated). The interest is to limit the number of Thread because the first solution
consumes slightly more memory but that can make the difference in important applications.
This method will not be seen in detail because it is not always used, in particular in the example preceding
because Thread of returned remains always "imprisoned" by the treatment until the treatment is finished.

1.4.2. The "Observable" DesignPattern


1.4.2.1. Principle
We have seen previously that a graphical interface is most of the time separate between its views (an intance of
the type JFrame for example) and a model (a class containing of the variables and the methods intended to
contain the data and the logic of the man/machine interface). We must now ask ourselves on the simpliest way
and most elegant to synchronize these two elements.
A response to this interrogation is the use of the model of "DesignPattern" called "Observable". That makes it
possible for the views to be registered towards a model. So vies are informed when the state of the model
changes.
We use for example the case where we have two JFrame which have the same model (we take two views
because Observable is particularly appropriate to the use of several views but it is not an obligation, only
one would have been enough) :

The second step is to record the views near the model :

200
Created by XMLmind

XSL-FO Converter.

Then each one takes again its activities our model is calculating a theory which will be able to perhaps
revolutionize science:

201
Created by XMLmind

XSL-FO Converter.

We learn finally that our scientist found a formula of capital importance: E=MC . Concretely we will say that
the statute of the model changed :

202
Created by XMLmind

XSL-FO Converter.

So that is the result which is displayed to the user. The model will use the references which it has at disposal :

203
Created by XMLmind

XSL-FO Converter.

We saw how the concept functions; now we will study how to set up it.
1.4.2.2. Classes provided with Java
In order to facilitate the comprehension of the concept saw previously, Java SE provides a named class
"Observable" whose model will have to inherit. This name comes to the fact that the model will be observed! In
addition we have an interface called "Observer" that the view will have to implement. Here an example of
model :
[CODE:java]public class MyModel extends Observable {
private int i;
public void incrementCounter(){
i++;
setChanged(); // set data has changed
notifyObservers(new Integer(i)); // notify observers with value
}
}

The method incrementCounter() relates to the trade of our application so it is not necessary to remember its
name, however it uses two method of the Observable class :

setChanged() which allows to define that the status of the model changed. The views will not be updated as
long as this method will not have been called.

notifyObservers(...) which notifies the views with the parameter passed in the method.
Let us see an example :
[CODE:java]public class MyFrame extends JFrame implements Observer {

204
Created by XMLmind

XSL-FO Converter.

private static final long serialVersionUID = 1L;


private MyModel model;
private JPanel jContentPane = null;
private JLabel jLabelCounter = null;
/** ... */
/**
* This is the default constructor
*/
public MyFrame(MyModel myModel) {
super();
myModel.addObserver(this);
initialize();
setModel(myModel);
}
public void update(Observable o, Object arg) {
if(o instanceof MyModel){
jLabelCounter.setText(arg.toString());
}
}
/** ... */
}

For all it is necessary that the view is recorded to the model. That is done by the call of the method addObserver
( ) as we wrote within the builder. That makes it possible the model to record a reference towards a sight
implementing "Observer".
Then we notice that the interface "Observer" obliges the implementation of the method update (Observable,
Object). This method is called when the model notifies the changes carried out. The first parameter corresponds
to the model, and to the second one with the value which is passed in parameter at the time of the notification.
Without having needed particularly complex code we were able to set up this powerful concept.

1.5. Elements untreated in the course


1.5.1. Drag & Drop
Swing supports the displacement of elements by simple slipped/deposited. This functionality is available by
default for the simple elements (as for the text) and is similar to copy/paste. However it is possible to overload
its operation but that leaves the framework of this course.

1.5.2. Undo / Redo


It is possible to place the events in a pile in order to be able to retrogress, or replay an event. However that
leaves the framework of this course.

1.5.3. Drawing (Java 2D)


All graphical components are drawn with Java 2D... after a whole button is only one rectangle with an
inscription inside! Thus it is possible to overload displaying it as well as the look & feel of a component.
Moreover it is interesting to use this library in order to handle images (to modify contrast, the luminosity), to
plot diagrams, etc.

1.5.4. Impression
Swing is able to work with the manager of impression of your operating system.

1.5.5. SwingX
Upgrade

of

certain

components,

like

JTable.

See

https://swingx.dev.java.net/

http://swinglabs.org/projects.jsp.
1.5.6. Structure
1.5.6.1. SwingWorker, improvement of the management of Threads
205
Created by XMLmind

XSL-FO Converter.

and

It is about a class which allows more efficiently management of Thread in Swing with also more functionalities
(in particular to cancel a trade treatment in progress). However its use leaves the framework of this course. See
https://swingworker.dev.java.net/ for more details.
1.5.6.2. Composite, represents the elements of JTree
This "DesignPattern" allows to represent the data contained in an explorer. It is also used for the information
contained in XML in the form of classes. In a few words that consists in having a trade object which we will be
named "Car" and to inherit it in a class "CarComposite" which will be able to record cars in a collection. Thanks
to polymorphism you can record authorities of the type "CarComposite" so you will be able to represent data in
a recursive way.

1.5.7. Platforms Rich Client


Various products exist in order to provide components of very high level in order to automatically manage even
more elements. Their acquisition spends a certain time in general because they are complex to control.
1.5.7.1. Eclipse RCP
Consist in reusing parts of code of Eclipse. Many tutorials are provided with Eclipse in the menu "Help > Cheat
sheets ...".

Its use is particularly current in the products of professional quality. However it rests on graphic components
SWT, which does not in take part in the Java specifications published by Sun MicroSystem.
1.5.7.2. Spring RCP
Spring-RCP's mission is to provide an elegant way to build highly-configurable, GUI-standards-following richclient applications faster by leveraging the Spring Framework, and a rich library of UI factories and support
classes. See http://spring-rich-c.sourceforge.net/1.0.0/index.html for more details.
1.5.7.3. NetBeans Platform
It is about a product similar to Eclipse RCP except that it rests on components of NetBeans. The most obvious
difference compared to this last is the use of Swing.

206
Created by XMLmind

XSL-FO Converter.

Many tutorials are available on the official sites of NetBeans: http://www.netbeans.org.


1.5.7.4. Swing Application Framework (Specification 296)
For the moment it is not an absolutely needed specification however it should be implemented with Java 7. Its
interest is to make simpler the adoption of this type of library Rich Client . See
http://java.sun.com/developer/technicalArticles/javase/swingappfr/ for more details.

1.6. Others functionalities


1.6.1. Internationalisation (I18N)
Internationalization is the process of creating an application so it can be adapted to different languages and
countries without ay coding changes. The term internationalization is abbreviated as i18n, because there are 18
letters between the first "i" and the last "n".
Localization is the process of adapting software for a specific region or language by adding localespecific
components and translating text To internationalize a swing application, you must follow several steps:

create the Default Properties File

specify the Locale Class

create the ResourceBundle


1.6.1.1. Properties File
This file allows to manage the translating of the different elements of our application. That is to say, we must
create a simple text which ends with the .properties suffix. Each file created will correspond to a language and
will contain these following lines for example :
[CODE:java]window_title=Etude commerciale
choose_favourite_videogames=Lequel est votre prfr ?
thank_you=Merci

1.6.1.2. Locale Class


The Locale class allows to identify or modify, the country and the language used by the computer on which is
carried out the application.
To create a Locale object, you typically specify the language code and the country code. For example, to specify
the French language and the country of Canada, you would invoke the constructor as follows :
[CODE:java]aLocale = new Locale("fr", "CA");

Methods of class :

Local [] getAvailableLocales () : allows to obtain the list of Local available.

Local getDefault () : allows to obtain the Local one by default

void setDefault (Local L) : modify the Local one by defect.


The default language is the default one from your operating system. However if we would like to modify it we
can use the following syntax :

207
Created by XMLmind

XSL-FO Converter.

[CODE:java]Locale.setDefault(Locale.FRENCH);

1.6.1.3. ResourceBundle
One of the essential phases of the internationalization of an application is to separate the code from the program
of the data specific to the localization of the program.
The RessourceBundle class allows to use packages of resources. A package of resources is a whole of files
whose names are built in the following way: basename{_langue{_pays}}.properties. Thus each file is
associated with a local, which can exist or not. A file consists of a couple (key, value). Example :
[CODE:java]buttonSubmit.setText(
java.util.ResourceBundle.getBundle("lang").getString("submit"));

1.7. Conclusion
We have just seen new concepts about Swing. Those are particularly interesting because they make it possible to
use all the potential of this library like the high level components, the particular management of Thread, etc.
You will be able to provide to the users of your solutions, reactive, functionnal and user-friendly graphical
interfaces.

208
Created by XMLmind

XSL-FO Converter.

Chapter 11. JDBC - Java Data Base


Connectivity
In this chapter you'll learn :

the differents architectures of a program using jdbc

how to set up a connection to a database.

how to execute SQL request.

how to retrieve and manage data.

the correspondence between SQL and Java data types

1. Course
1.1. Introduction
1.1.1. DB reminder
Here come some definitions, in order to refresh your mind:
Relational data base: collection of tables or relations.
DBMS is a software that allows you to manage some data bases. It can :

Create and modify tables.

Query the database.

Assume the security and integrity of data.

Manage transactions and simultaneous access.


Transaction: Logical unit of handling which, applied to a coherent state of the database, return a new coherent
state, but modified, of the database.
SQL: Language of data manipulation.
ODBC: Open Data Base Connectivity. Interface access to Microsoft SQL data base.

1.1.2. JDCD = Java Data Base Connectivity


JDBC is an access API to relational data base management systems which allows you to carry out SQL requests
within a JAVA program and retrieve results; that represents an alternative to owner solutions.Moreover, it is an
attempt to standardize accesses to data bases because JDBC API is independent of the chosen DBMS if the
209
Created by XMLmind

XSL-FO Converter.

JDBC pilot exists for this DBMS. The program has just to use classes and interfaces of JDBC API.

1.2. Customerserver JDBC and architectures multitiers


1.2.1. 2-tiers Customerserver architectures
In 2-tiers customerserver architecture, customer software reaches directly a data base on a distant computer (the
server) to exchange information, via SQL JDBC orders automatically translated in the DBMS suitable query
language. The main advantage of this architecture type is that in the event of a DBMS change, there is only to
update or change the JDBC driver on customer side. However, for a great diffusion of the customer software,
this architecture becomes problematic, because such a modification requires the update of all customer software.

1.2.2. 3-tiers architectures


In 3-tiers architecture, customer software does not reach directly the data base, but an application server which
does itself the accesses to the data base. There are several advantages with this architecture. First of all, it allows
you to manage connections more effectively on the application server and optimize treatments. Moreover,
contrary to architecture 2/tiers, a change of DBMS does not require any update of the drivers on all the customer
software, but only on the application server.

1.3. API JDBC


1.3.1. General structure
To carry out a treatment with a data base, it is necessary:

To load a driver in memory

To establish a connection with the data base

To retrieve connection information

To carry out stored SQL requests and/or procedures

210
Created by XMLmind

XSL-FO Converter.

To retrieve the data base returned information (if necessary)

To close the connection.

1.3.2. Necessary Libraries


When you want to use the JDBC API , it is necessary to import the following libraries:

java.sql.*;

sun.jdbc.odbc.*; (to include JDBCODBC bridge)

1.3.3. Load a driver in memory


1.3.3.1. Different types of drivers
There are four types of JDBC drivers:
1. JDBCODBC Bridge which is used with ODBC and a specific data base ODBC driver.
This solution works very well under Windows. It is the best solution for local application developments with
Windows execution environment. But this is simple development solution has several drawbacks:

The multiplication of layers number makes the architecture complex (although transparent for the developer)
and deteriorates the performances

During the deployment, ODBC and its pilot must be installed on all the stations where the application will run

The native part (ODBC and its driver) makes the application less portable and dependent of a platform
(Windows).

2. A driver written in java calls native data base API.


This driver type converts JDBC orders to directly call the data base APIs. It is necessary then to provide native
data base APIs to the customer. They are generally in C or C++.

211
Created by XMLmind

XSL-FO Converter.

3. A driver written in Java using a specific network protocol to dialogue with an intermediate server.
This type of driver uses a proprietary network protocol specific to an intermediate server. The dedicated server
receives the messages and dialogues directly with the data base. This type of driver can be easily used by an
applet, but in this case the intermediate server must be installed on the Web server computer.

4. Type 4: A native Java driver.


This type of driver, written in java, directly calls the DBMS through the network. It is provided by the data base
editor. This type of driver is the best solution.t is simple to use, has good performances and it is easy to deploy.

List of some drivers:

For an Oracle data base: oracle.jdbc.driver.OracleDriver

For an Access data base: sun.jdbc.odbc.JdbcOdbcDriver

For a postgreSQL data base: postgresql.Driver

For a mySQL data base: org.gjt.mm.mysql.Driver or com.mysql.jdbc.Driver


You will find various drivers on the following web link:

http://servlet.java.sun.com/products/jdbc/drivers
1.3.3.2. How to do
212
Created by XMLmind

XSL-FO Converter.

JDBC Driver knows methods to connect to your data base; this is why this one is essential. This driver is
generally available in a jar package. The path must be added to the classpath to make the program able to use it.
The first stage is to load the driver with the method Class.forName(String driver). This class allows the program
to remain completely independent from used data base by preserving the driver name in a properties file.
The method Class.forName(String driver) can throw an exception of the ClassNotFoundException type if an
error occur during the driver loading.
Here an example with the driver used to connect to a data base via ODBC (sun.jdbc.odbc.JdbcOdbcDriver):
[CODE:java]try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
}catch (ClassNotFoundException e){
...
}

To connect to a base by using a specific driver, the driver documentation provided the class name to use. For
instance, if the class name is package.DriverXXX, the driver loading will be done with the following code:
Class.forName("package.DriverXXX");
Example:
[CODE:java]try{
Class.forName("org.gjt.mm.mysql.Driver");
}catch (ClassNotFoundException e){

This example shows the MySQL driver

1.3.4. Establish a connection


1.3.4.1. Define data base
The data base name is declared in the ODBC control panel (the DSN name(Data Source Name). The URL
syntax can vary slightly according to the type of the data base.
It is generally about an address of the form:
[CODE:java]String url = "jdbc:subprotocole:DataSource";

Examples:

with JDBCODBC bridge :


[CODE:java]String url = "jdbc:odbc:DBemployees";

with MySQL specific driver


[CODE:java]String url = "jdbc:mysql://server/DBemployes";

with Oracle specific driver


[CODE:java]String url = "jdbc:oracle:oci8:@DBemployes";
//DBemployes is the SERVICE_NAME
[CODE:java]String url = "jdbc:oracle:thin:@server:1521:DBemployes";

1.3.4.2. Use of the Connection interface


Connection to a data base is done via any instance of Connection implementation. It represents a data base work
213
Created by XMLmind

XSL-FO Converter.

session. To establish the connection with the data base we have to use the methods getConnection(...) of the
DriverManager class. The data base URL has to be passed in method parameter.Be careful, the methods
getConnection(...) can throw a java.sql.SQLException exception.
The creation of a simple connection is done with the method:
public static Connect getConnection(String url) throws SQLException;
[CODE:java]try{
Connection connect = DriverManager.getConnection(url);
}catch (SQLException e){

In The connection creation you can add a username and a password.It is done with the method:
public static Connection getConnection(String url, String login, String password) throws SQLException;
[CODE:java]try{
Connection connect = DriverManager.getConnection(url, "log", "pwd");
}catch (SQLException e){

In place of "log", it is necessary to put the username who connects to the data base and to put his password in
place of "pwd". It is also possible to create a connection with a username and his password with the function:
public static Connection getConnection(String url, Properties info) throws SQLException;
[CODE:java]Properties info = new Properties();
info.put("userid", "admin");
info.put("password", "adminpass");
try{
Connection connect = DriverManager.getConnection(url, info);
}catch (SQLException e){

A Connection instance provide more methods, allows to close connection, and to test its state:
public void close() throws SQLException;
public boolean isClosed() throws SQLException;

1.3.5. SQL requests execution


To execute a SQL request, several objects can be use to send request to data base:

Statement: object used to execute static SQL request. Return the results of the request.

PreparedStatement: object used to execute SQL request several times, with different parameters.

CallableStatement: object used to call a stored procedure.


Instances of these objects are available thanks to any instance of Connection.
1.3.5.1. The Statement interface: simple requests
A Statement object represents an instruction of SQL treatment. It is created by an instance of Connection with
the method:
public Statement createStatement() throws SQLException;

214
Created by XMLmind

XSL-FO Converter.

Example:
[CODE:java]try{
Statement state = connect.createStatement();
}catch (SQLException e){

This object has some methods in order to carry out:

A consultation SQL request (SELECT), returning its results:


public ResultSet executeQuery(String sql) throws SQLException;

A request of modification (UPDATE, DELETE, INSERT, CREATE, DROP), returning only the number of
occurrences affected:
public int executeUpdate(String sql) throws SQLException ;

A batch of requests, returning an array of entity corresponding to their results:


public int[] executeBatch() throws SQLException;
used jointly with the methods:
public void addBatch(String sql) throws SQLException;
public void clearBatch() throws SQLException;
Examples:
[CODE:java]try{
ResultSet resultat = state.executeQuery("SELECT DISTINCT name FROM student ORDER BY name;");
}catch(SQLException e){

Obtain student names from the table, alphabetically ordered.


[CODE:java]try{
state.executeUpdate("CREATE TABLE salesman
(salesmanId integer,
Name char(15),
Firstname char(10),
RecruitingDate date,
managerId integer,
Salary numeric(6,0),
Commission numeric(4,1),
Level integer
);"
);
}catch(SQLException e){

Create a table salesman in the current data base.


[CODE:java]try{
state.addBatch("DELETE FROM salesman WHERE salesmanId= '06897'");
state.addBatch( "UPDATE salesman SET salary = 1215 WHERE salary < 1215");
int[] results = state.executeBatch();
}catch(SQLException e){

215
Created by XMLmind

XSL-FO Converter.

Remove the salesman occurrence having salesman ad equals to 06897 and fix all the wages at 1215 minimum.
The results array of integer will contain for example [1, 15], that means that the first request ("DELETE")
will have affected only one line, where as seconds ("UPDATE") will have affected 15.
1.3.5.2. The PreparedStatement interface: precompiled requests
The PreparedStatement object represents an instruction of precompiled SQL treatment. It is a Statement
subclass. This object is usually used when it is necessary to reuse several times the same request with different
parameters, identified by a ? in the request. It is created by an instance of Connection thanks to the method:
public PreparedStatement prepareStatement(String sql) throws SQLException;
Example:
[CODE:java]try{
PreparedStatement prepState = connect.prepareStatement(sql);
}catch(SQLException e){

This object has other methods available allowing:

To execute the SQL request, returning results:


public ResultSet executeQuery() throws SQLException;
public int executeUpdate() throws SQLException;

To specify type and value of each parameter:


public void setXxxx(int parameterIndex, Xxxx value) throws SQLException;
where parameterIndex is the parameter index where Xxxx is the value type
setString(int parameterIndex, String value);
setInt(int parameterIndex, int value);

To empty the list of the parameters:


public void clearParameters() throws SQLException;
Example:
[CODE:java]String sql = "SELECT name FROM salesman WHERE sex = ? and level > ?";
try{
PreparedStatement prepState = connect.prepareStatement(sql);
prepState.setString(1, "W");
prepState.setInt(2, 5);
ResultSet rs = prepState.executeQuery();

prepState.clearParameters();
prepState.setString(1, "M");
prepState.setInt(2, 3);
rs = prepState.executeQuery();

}catch(SQLException e){

216
Created by XMLmind

XSL-FO Converter.

Obtain the saleswomen names of level higher than 5, then salesmen names of level higher than 3.
1.3.5.3. The CallableStatement interface: stored procedures
The CallableStatement object represents an instruction of stored SQL treatment. It is a PreparedStatement
subclass. As PreparedStatement interface, it is possible to put ? to reuse the request with different parameters.
It is created by an instance of Connection with the method:
public CallableStatement prepareCall(String sql) throws SQLException ;
Example:
[CODE:java]try{
CallableStatement callState = connect.prepareCall(sql);
}catch(SQLException e){

Syntaxes available to call stored procedures are as follows:


{call procedure_name[( ?, ?, )]}
{? = call procedure_name[( ?, ?, )]}
The second one allows the function to have a parameter of return.
This object has some other methods available:
To execute the SQL request, returning results:
public ResultSet executeQuery() throws SQLException;
public int executeUpdate() throws SQLException;
To specify type and value of each parameter:
public void setXxxx(int parameterIndex, Xxxx value) throws SQLException;
where parameterIndex is the parameter index where Xxxx is the value type
setString(int parameterIndex, String value);
setInt(int parameterIndex, int value);

To empty the list of the parameters:


public void clearParameters() throws SQLException;
To specify type of the returned parameter:
public void registerOutParameter(int parameterIndex, int typeSQL) throws SQLException;
where parameterIndex is the parameter index where typeSQL is the value SQL type (constants available in
java.sql.Types)
Example:
[CODE:java]String sql = "{call list_salesman_by_city(?)}";
try{
CallableStatement callState = connect.prepareCall(sql);
callState.setString(1, "Paris");
ResultSet rs = callState.executeQuery();

}catch(SQLException e){

217
Created by XMLmind

XSL-FO Converter.

1.3.5.4. Access parameter setting


It is also possible to parameter the access, the software will have on the obtained results, with methods of the
Connection interface:
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException;
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws
SQLException;
public CallableStatement prepareCall (String sql, int resultSetType, int resultSetConcurrency) throws
SQLException;
The parameters resultSetType and resultSetConcurrency are constants of the ResultSet interface used to recover
the data returned by the data base.
The parameter resultSetType corresponds to the cursor moving type on the results:

TYPE_FOWARD_ONLY: indicate the cursor may move only forward.

TYPE_SCROLL_INSENSITIVE: indicate that the cursor is scrollable but not sensitive to changes made by
others.

TYPE_SCROLL_SENSITIVE: indicate that the cursor is scrollable and sensitive to changes made by others.
The parameter resultSetConcurrency corresponding to the possibility to update data returned by the data base:

CONCUR_READ_ONLY: indicate the concurrency mode for a ResultSet object that may NOT be updated

CONCUR_UPDATABLE: indicate the concurrency mode for a ResultSet object that may be updated
1.3.5.5. Data base structure information
It is also possible to reach data base structure information with the method of the Connection interface:
public DatabaseMetaData getMetaData() throws SQLException;
Example:
[CODE:java]try{
DatabaseMetaData dbMetaData = connect.getMetaData();
System.out.println("Base : " +
dbMetaData.getDataBaseProductName());

}catch(SQLException e){

1.3.6. Result recovery


When you execute a SQL request (SELECT), a ResultSet object is returned. This one represents the list of the
data returned by the request.
1.3.6.1. Consultation of the data structure
During the results retrieving, informations are formatted in a certain form. Then it is necessary to have
218
Created by XMLmind

XSL-FO Converter.

information on their structure. That is why, ResultSet provided a method allowing to recover a
ResultSetMetaData instance, which includes all structure properties (name of column, type, access):
public ResultSetMetaData getMetaData();
WARNING: first column index is 1; there is no column 0.
Example:
[CODE:java]ResultSet rs = state.executeQuery("SELECT * FROM salesman");
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
for(int i = 1; i <= columnCount; i++){
System.out.print(""+rsmd.getColumnName(i)+"\t");
}
while(rs.next){
System.out.print("");
for(int i = 1; i <= columnCount; i++){
System.out.print(""+rs.getObject(i)+"\t");
}
System.out.println("");
}

Display column names and the list of the values contained.


1.3.6.2. Reading data
To be able to recover the data contained in the ResultSet instance, this one provides some methods allowing:

To move the cursor down of one row from its current position:
public boolean next();
Return a boolean indicating the validity of the following row.

To get the value of the given type and the given column (by index or name) of the row currently pointed by
the cursor:
public Xxxx getXxxx(int columnIndex);
public Xxxx getXxxx(String columnName);
where Xxxx is the value type
getString(int columnIndex);
getInt(int columnIndex);

Example:
[CODE:java]ResultSet rs = state.executeQuery("SELECT * FROM salesman");
while(rs.next){
System.out.println("["+rs.getString("Name")+", "+rs.getInt("Name ")+", "+rs.getDate("RecruitingDate")+"]");
}

Display the list of the salesmen, followup of their age and their respective date of recruiting.
1.3.6.3. Modify data
To be able to modify the data contained in the ResultSet instance, this one provides some methods allowing:
219
Created by XMLmind

XSL-FO Converter.

To modify the value of the given type and the given column (by index or name) on the row currently pointed
by the cursor:
public void updateXxxx(int columnIndex, Xxxx value) ;
public void updateXxxx(String columnName, Xxxx value) ;
where Xxxx is the value type
updateString(int columnIndex, String value) ;
updateInt(int columnIndex, int value) ;

To apply to the data base the changes carried out to the row currently pointed by the cursor :
public void updateRow();

To insert in the data base the new row currently pointed by the cursor :
public void insertRow();

Move the cursor on an empty row which allows you to create a new row :
public void moveToInsertRow();
WARNING: Some drivers do not manage or manage these methods badly (ie: for Access). It is necessary to
know which are compatible with these methods (ie: for mySQL, compatible driver since the version 3.0.7)
Example:
[CODE:java]ResultSet rs = state.executeQuery("SELECT * FROM salesman");
rs.next();

rs.updateString("Name", "Bob");
rs.updateInt("commission", 280);
rs.updateDouble("Salary", 1300);
updateRow() ;
rs.moveToInsertRow();
rs.updateString("Name", "Doe");
rs.updateString("Firstname", "John");
rs.updateDouble("Salary", 1215);

rs.insertRow();

Modify a row, then insert new one and affect the changes in the base for each one.

1.3.7. Manage transactions


There are two ways to manage transactions in a Java application:

With the JDBC API, in each client software, with the adapted methods

With the JTA API (Java Transaction API), shared between several customers.
1.3.7.1. Local transaction management: JDBC
220
Created by XMLmind

XSL-FO Converter.

A Connection instance provides methods allowing:

To enable/disable the automatic validation of each request (default: enable) :


public void setAutoCommit(boolean autoCommit) throws SQLException;

To manually validate request(s) :


public void commit() throws SQLException;

To cancel last modification made by invalidated request(s):


public void roolback() throws SQLException;
Example:
[CODE:java]String sql1 = "UPDATE salesman SET salary = 1215 WHERE salary < 1215";
String sql2 = "DELETE FROM salesman WHERE salary < 1215";
try{
connect.setAutoCommit(false);
Statement state = connect.createStatement();
state.executeUpdate(sql1);
Statement state2 = connect.createStatement();
state2.executeUpdate(sql2);
connect.commit();

}catch(Exception e){
try{
connect.rollback();
}catch(SQLExection e){

1.3.7.2. Shared transaction management: JTA


JTA is an API provided by the J2EE version of Java. It allows a remote management of transactions. This API
works like JDBC on the client software side: we call methods commit() and rollback() from UserTransaction
(javax.transaction.UserTransaction) instance as if we called the methods from Connection. However, the
transaction is not managed on the client software side, but these methods calls the corresponding methods on a
JTS implementing server (Java Transaction Service); it is this server which will act directly on the data base.
The object UserTransaction provides methods allowing:

To inform the server of a new transaction beginning:


public void begin() throws NotSupportedException;

To validate the transaction:


public void commit() throws RollbackException, [];

To cancel last modification made by invalidated transaction:


public void rollback() throws IllegalStateException, [];

221
Created by XMLmind

XSL-FO Converter.

To specify the transaction lifespan:


public void setTransactionTimeout(int secondes) throws SystemException;

To know the transaction state:


public int getStatuts() throws SystemException;
The returned value correspond to a constant from the class javax.transaction.Status.
Example:
[CODE:java]String sql = "DELETE FROM salesman WHERE salary < 1215";
try{
// recovery of one connection to the base by JDBC

UserTransaction ut = getSessionContext().getUserTransaction();
ut.begin();
connect.executeUpdate(sql);
ut.commit();
}catch(Exception e){
try{
ut.rollback();
}catch(IllegalStateException e){

1.3.8. Closing connection


After all these actions done on data base, it is necessary to close all instances that manage the connection. This
action is carried out by calling the method close() from a Statement instance, PreparedStatement,
CallableStatement, Connection, ResultSet.
Example:
[CODE:java]try{
rs.close();
state.close();

connect.close();
}catch(Exception e){

NOTICE: A Statement instance must be closed before starting again another SQL request.

1.4. Correspondence SQL/Java of the data types


To retrieve the field values in a data base, it is necessary to know its SQL type. According to its SQL type,
recovery is done with a type or another.
Here the correspondence between reading methods and the SQL data types. "x" represent the compatible types,
and "X" the best adapted correspondences.

222
Created by XMLmind

XSL-FO Converter.

Case of Null values :


It may be that a value in ResultSet is NULL according to SQL, but Java does not know this value for the
primitive types.
Then, if there is a NULL for a field, there is a conversion which is done:

for the objects (such as String) the returned value is null,

for the numerical ones, the returned value is 0 (it is sometimes awkward because 0 do not want to always say
the same thing as anything),

for the boolean ones, the returned value is false.


It is possible to test if the last value read is null by the ResulSet method wasNull(). It gives true if this value is
NULL, if not false.
Example:
[CODE:java]ResultSet rs;

rs.next();

int i = rs.GetInt(1);
if(rs.wasNull()){
System.out.println("No value in this field!");
}

223
Created by XMLmind

XSL-FO Converter.

1.5. General Example


[CODE:java]// Importation of the necessary classes for JDBC
import java.sql.*;
// Other importation
import java.util.Vector;
public class JdbcSimpleExample{
// SQL Request
private String sqlQuery = "SELECT * FROM salesman ";
// Allows data base connection
private Connection connect;
// Allows to send SQL request
private Statement state;
// Allows to recover data
private ResultSet rs;
// Modified lines count
private int modifiedLineCount;
public JdbcSimpleExample(){
connectToDB();
updateLocalData();
printLocalData();
modifyData(2,1, "Doe");
commitModificationOnDB();
printLocalData();
modifyData(2,1, "John");
printLocalData();
rollbackModificationOnDB();
printLocalData();
modifyData(2,1, "Bill");
commitModificationOnDB();
}
// Initialize useful instances
// to connect to the data base
private void connectToDB(){
initConnection("org.gjt.mm.mysql.Driver", "jdbc:mysql://localhost/innoDB", "user", "test");
try{
// Instanciate a Statement with an access type
state = connect.createStatement( ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
// send SQL request
rs = state.executeQuery(sqlQuery);
}catch (Exception e){
System.out.println("Error while retrieve data: \n"+e);
System.exit(0);
}
}
// Initialize connection with data base
private void initConnection(String driver, String url, String login, String password){
try{
// Register the Driver
Class.forName(driver);
// Instanciate the object allowing connection
connect = DriverManager.getConnection(url, login, password);
// Allows to manage transactions
connect.setAutoCommit(false );
System.out.println("Connection established!");
}catch (ClassNotFoundException e){
System.out.println("Error while loading JDBC driver: \n"+e);
System.exit(0);
}catch (SQLException e){
System.out.println("Error while connecting to the Data base: \n"+e);
System.exit(0);
}
}
// Vector containing column names
private Vector vColumnName;
// Vector of Vector containing data
// of each row
private Vector vData;
// Column count

224
Created by XMLmind

XSL-FO Converter.

private int columnCount;


// Display results
private void printLocalData(){
System.out.print("|");
for(int i = 0; i < vColumnName.size(); i++){
System.out.print("["+vColumnName.get(i)+"]\t|");
}
System.out.print("\n");
for(int i = 0; i < vData.size(); i++){
System.out.print("|");
for(int j = 0; j < vData.size(); j++){
System.out.print(((Vector)(vData.get(i))).get(j)+"\t\t|");
}
System.out.print("\n");
}
}
// Updates data vectors and column names one
private void updateLocalData(){
try{
vColumnName = new Vector();
// Recovering data
// on data structure
ResultSetMetaData rsMetaData = rs.getMetaData();
// Column count
columnCount = rsMetaData.getColumnCount();
// Generation of column names Vector
for(int i = 1; i <= columnCount; i++){
vColumnName.add(rsMetaData.getColumnName(i));
}
vData = new Vector();
Vector vLine;
// Generation of data Vector while
// ResultSet has more element
while (rs.next()){
vLine = new Vector();
// For each column, read each field
// of the current ResultSet row
// and generation of the corresponding Vector
for(int i = 1; i <= columnCount; i++){
// Recovering the data in the field
// and add it into the Vector
vLine.add(""+rs.getObject(i));
}
vData.add(vLine);
}
}catch (SQLException e){
System.out.println("Error while recovering data: "+e);
System.exit(0);
}
}
// Modify the data at coordinate updatableLine/updatableRow
// with the data named "data"
private void modifyData(int updatableLine, int updatableRow, Object data){
System.out.println(" Modifying data ");
try {
// Move to the line to modify
rs.absolute(updatableLine+1);
// Update the ResultSet whit the new value
rs.updateObject(updatableRow+1,data);
// Update on the data base
rs.updateRow();
// Recover the modified line
Vector vLine = (Vector)vData.get(updatableLine);
// Modify the local data
vLine.set(updatableRow,data);
System.out.println(" Data modified ");
} catch (SQLException e) {
System.out.println("Error while modifying data:\n"+e);
System.exit(0);
}
}

225
Created by XMLmind

XSL-FO Converter.

// Validate modifications on data base (COMMIT)


private void commitModificationOnDB(){
try {
connect.commit();
System.out.println(" Commit done ");
} catch (SQLException e) {
System.out.println("Error while committing: \n"+e);
System.exit(0);
}
}
// Cancel uncommitted modification on the data base (ROLLBACK)
private void rollbackModificationOnDB(){
try {
connect.rollback();
System.out.println(" Rollback done ");
// Relaunch SQL request to
// Recover data once more
rs = state.executeQuery(sqlQuery);
// Update local data
updateLocalData();
} catch (SQLException e) {
System.out.println("Error while rollbacking: \n"+e);
System.exit(0);
}
}
public static void main (String args[]){
new JdbcSimpleExample();
}
}

226
Created by XMLmind

XSL-FO Converter.

Você também pode gostar