Tutorial Java Course
Tutorial Java Course
This document comes together with the course. Corresponding part has to be read before attending each
session with Professors.
1 Introduction 3
1.1 Few words about Java . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 Limitations of Java . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.3 External references . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
iii
iv CONTENTS
1
Chapter 1
Introduction
Java is platform independent. This means that it will run on just about any operating
system. So whether your computer runs Windows, Linux, Mac OS, it is all the my Java application
same to Java! The reason it can run on any operating system is because of the Java
Virtual Machine, which has been adapted to each operating system. Therefore, from
a Java application point of view, all the machines looks similar: the virtual machine JVM
interprets the Java codes and transforms it to codes that can be understood by the
3
4 Chapter 1 Introduction
Nowadays, Java is widely spread. Indeed, in 2002, Java was installed on 550 millions
of computers and 75% of the developers was using Java as a first language. Today,
4.5 millions of developers work with Java.
The Virtual Machine is a program that processes all your code correctly. So you
need to install this program (Virtual Machine) before you can run any Java code.
Although the presence of a virtual machine, Java programs run fast.
Java is owned by a company called Oracle, so you need to head over to Or-
acle’s website to get the Java Virtual Machine, also known as the Java Run-
time Environment (JRE). Nevertheless, source code of Java itself is available
i.e. Java is now open source. The official documentation is available at http:
//java.com/en/download/manual.jsp.
To write code and test it out, you need something called a Software Development
kit. The one we are going to be using is called Java SE (for Standard Edition).
You write the actual code for your programs in a text editor or in an integrated
development environment (IDE), such as Eclipse we are going to use. Basically,
an IDE integrates a text editor, a debugger with many other facilities to support
1.2 Limitations of Java 5
Mac OS X already contains a JDK. If you want to update the version, watch
6 Chapter 1 Introduction
https://youtu.be/qVulWqwfPy0
A good reference for learning Java is the Java programming wikibook https://en.
wikibooks.org/wiki/Java_Programming.
Books can also be found on the web such as ‘Java for dummies’ from Barry Burd
(Wiley) or ‘Apprenez à programmer en Java’ from Cyrille Herby (site du Zéro).
NetBeans began in 1996 as Xelfi, a Java IDE student project under the guidance of
the Faculty of Mathematics and Physics at Charles University in Prague. In 1997,
Roman Staněk formed a company around the project and produced commercial
versions of the NetBeans IDE until it was bought by Sun Microsystems in 1999.
Sun open-sourced the NetBeans IDE in June of the following year. Since then, the
NetBeans community has continued to grow. In 2010, Sun (and thus NetBeans) was
acquired by Oracle.
• A debugger, let you place breakpoints in your source code, add field watches,
step through your code, run into methods, take snapshots and monitor ex-
ecution as it occurs. See for instance https://www.youtube.com/watch?v=
2Z9B8wYhKWw.
• A profiler, provides expert assistance for optimizing application’s speed and
memory usage, and makes it easier to build reliable and scalable Java applica-
tions. See for instance https://www.youtube.com/watch?v=DI4EFkzqCCg.
• A Swing Graphic User Interface (GUI) builder, makes it possible to design
7
8 Chapter 2 The Netbeans IDE
This tutorial 1 provides a very simple and quick introduction to the NetBeans IDE
workflow by walking you through the creation of a simple "Hello World" Java
console application. Once you are done with this tutorial, you will have a general
knowledge of how to create and run applications in the IDE.
Figure 2.1
• In the New Project wizard, expand the Java category and select Java Applica-
tion as shown in the figure below. Then click Next.
10 Chapter 2 The Netbeans IDE
Figure 2.2
• In the Name and Location page of the wizard, do the following (as shown in
the figure below):
– In the Project Name field, type HelloWorldApp.
– Leave the Use Dedicated Folder for Storing Libraries checkbox unse-
lected.
– In the Create Main Class field, type helloworldapp.HelloWorldApp.
2.2 Creating a Java project with the Netbeans IDE 11
Figure 2.3
• Click Finish. The project is created and opened in the IDE. You should see
the following components:
– The Projects window, which contains a tree view of the components of
the project, including source files, libraries that your code depends on,
and so on.
– The Source Editor window with a file called HelloWorldApp open.
– The Navigator window, which you can use to quickly navigate between
elements within the selected class.
12 Chapter 2 The Netbeans IDE
Figure 2.4
Because you have left the Create Main Class checkbox selected in the New Project
wizard, the IDE has created a skeleton main class for you. You can add the "Hello
World!" message to the skeleton code by replacing the line:
// TODO code application logic here
Save the change by choosing File > Save. The file should look something like the
following code sample.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package helloworldapp;
/**
*
* @author <your name>
*/
public class HelloWorldApp {
2.2 Creating a Java project with the Netbeans IDE 13
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
System.out.println("Hello World!");
}
Because of the IDE’s Compile on Save feature, you do not have to manually compile
your project in order to run it in the IDE. When you save a Java source file, the IDE
automatically compiles it.
Information
The Compile on Save feature can be turned off in the Project Properties window.
Right-click your project, select Properties. In the Properties window, choose the
Compiling tab. The Compile on Save checkbox is right at the top. Note that in the
Project Properties window you can configure numerous settings for your project:
project libraries, packaging, building, running, etc.
Figure 2.5
If there are compilation errors, they are marked with red glyphs in the left and right
margins of the Source Editor. The glyphs in the left margin indicate errors for the
corresponding lines. The glyphs in the right margin show all of the areas of the file
that have errors, including errors in lines that are not visible. You can mouse over an
error mark to get a description of the error. You can click a glyph in the right margin
to jump to the line with the error.
Once you have written and test run your application, you can use the Clean and
Build command to build your application for deployment. When you use the Clean
and Build command, the IDE runs a build script that performs the following tasks:
You can view the build outputs by opening the Files window and expanding the
HelloWorldApp node. The compiled bytecode file HelloWorldApp.class is within the
build/classes/helloworldapp subnode. A deployable JAR file that contains the HelloWorldApp →
,→ .class is within the dist node.
2.3 Exporting and importing projects 15
Figure 2.6
You now know how to accomplish some of the most common programming tasks in
the IDE.
Exercise 3.1
Using the Netbeans platform, create a project ImprovedHelloWorld. Inside the
‘Source Packages’ of your new project, create a package1 ‘ense3’. Then create a
‘MyHelloWorld’ class i.e. a file that will contain the following Java code:
package ense3;
17
18 Chapter 3 The Java Basics
The first line package ense3; specifies to the Java virtual machine that the program is
in the ‘ense3’ sub-folder of the root folder ‘src’ (displayed as ‘Source Packages’
in Netbeans) for the code. Even if that information could be guessed by analyzing
folders, in Java, it has to be explicitly specified.
Then the name of the program (or class in Java) is specified in public class MyHelloWorld →
,→ { ... }. Note that the file name should be exactly the same than the class name.
Class ‘MyHelloWorld’ should be saved into a file ‘MyHelloWorld.java’. Once the
class has been created by Netbeans, you cannot change its name without renaming
the file.
0 Fortunately, Netbeans has
refactoring capabilities that
ease the renamings (right The ‘public’ keyword indicates that the class can be accessed from all the (upcoming)
click on what you want to re- classes of the projects.
name, Refactor > Rename...)
is a function bound to the class (program) ‘My-
public static void main(String[] args) { ... }
HelloWorld’. In Java, conversely to C, functions are named methods. ‘public’
keyword has the same meaning that before. ‘static’ means the method is related
to the class. ‘void’ means that the method does not return any value. String[] args
indicates that the method requires a array of String as argument. ‘args’ could be
named with any other labels provided it remains an array of String. It may be used
to access arguments passed through the command such as java HelloWorld arg1 arg2 ....
These arguments are generally not used but are still compulsory.
The method public static void main(String[] args) { ... } is special. Indeed, if its name, the
type of arguments and of the return or the keywords are changed, the class could
not be run anymore. In Java, only methods written in this way can be executed at
launch. Other methods can be called but not at launch.
Inside the method, you will recognize the ‘for’ loop, with which you are now familiar
because of C language. Let’s focus on the command to print a String: System.out. →
,→ println("Hello World "+i+"!");. To get a better understanding of the reason for
such a complex writing System.out.println, you can use the official Java documentation.
It must become usual for you to go to this web site to check the details of class.
In the lower left corner, you can find the class ‘System’: http://docs.oracle.com/
javase/7/docs/api/java/lang/System.html. You can see that the standard input (read
from keyboard) and output (print to console) streams are bound to the System class.
Printing on console requires to work with the output stream ‘out’. Clicking on
‘out’ shows that its type is ‘PrintStream’ http://docs.oracle.com/javase/7/docs/api/
java/io/PrintStream.html. Different ‘println’ methods (but also others) are available.
void println(String x) is the method we are using in ‘MyHelloWorld’ class.
¢ It is very important to un-
derstand that all the Java
classes are well documented
in http://docs.oracle.com/
javase/7/docs/api/
3.2 Java Naming Convention 19
Good developers follow naming convention to improve the readability of their codes.
Oracle, that markets Java, proposes Java naming convention at http://www.oracle.
com/technetwork/java/codeconventions-135099.html. We request you to use full
English descriptions for names and to avoid using abbreviations. For example, use
names like firstName, lastName, and middleInitial rather than the shorter versions
fName, lName, and mi.
variable. Choose meaningful names that describe what the variable is being used
for. Avoid generic names like number or temp whose purpose is unclear.
Compose variable names using mixed case letters starting with a lower case
letter. For example, use salesOrder and not SalesOrder or sales_order.
constant. Use ALL_UPPER_CASE for your named constants, separating words
with the underscore character. For example, use TAX_RATE and not taxRate
or TAXRATE.
class. Follow the variable naming convention but starts with an upper case letter
like ‘MyClass’. Class names should refer to a type of things that can be
manipulated. For instance, ‘Shape’ or ‘Matrix’.
method. Begin method names with a strong action verb (for example, ‘deposit’
or ‘addInterest’). It follows the variable naming convention but it starts by
a lower case letter. Try to come up with meaningful method names that
succinctly describe the purpose of the method.
getter and setter methods. Use the prefixes get and set for getter and setter meth-
ods. Getter methods merely return the value of a variable; setter methods
change the value of a variable. For example, use the method names getBal-
ance and setBalance to access or change the instance variable balance. If the
method returns a boolean value, use is or has as the prefix for the method
name. For example, use isOverdrawn or hasCreditLeft for methods that return
true or false values.
arguments in a method. It should follow the same naming conventions as with
variables, i.e. use mixed case, begin with a lower case letter, and begin each
subsequent word with an upper-case letter. Consider using the prefix a or an
with parameter names. This helps make the parameter distinguishable from
other types of variables.
Here is a proper way to indent a code (dots stand for space character) and to improve
its readability:
public class MyClass {
Note that Netbeans can automatically reindent properly your code (Source > Format).
Comments provide readers with the information helpful to understand your pro-
gram. Use comments to provide overviews or summaries of chunks of code and
to provide additional information that is not available in the code itself, but avoid
over-commenting your code. The frequency of comments sometimes reflects poor
quality of code. When you feel compelled to add a comment, consider rewriting the
code to make it clearer.
Use single-line comments, also called inline comments, to provide brief summary
comments for chunks of code. Begin single-line comments with a double slash (//)
that tells the compiler to ignore the rest of the line.
// Compute the exam average score for the midterm exam
sumOfScores = 0;
for (int i = 0; i < scores.length; i++)
sumOfScores = sumOfScores + scores[i];
average = float(sumOfScores) / scores.length;
Trailing comments are used to provide an explanation for a single line of code.
Begin trailing comments with a double slash (//) and place them to the right of the
line of code they reference. Trailing comments are used to explain tricky code,
3.5 Java keywords 21
specify what abbreviated variable names refer to, or otherwise clarify unclear lines
of code. In general, avoid the use of trailing comments. Instead rewrite tricky or
unclear code, use meaningful variable names, and strive for self-documenting code.
ss = s1 + s2 + s3; //add the three scores into the sum
a = float(ss) / x; //calculate the mean of the scores
In addition, the C style comments /* ... */ may be used temporarily for commenting
out blocks of code during debugging
Keywords are special tokens in the language, which have reserved use in the lan-
guage. Keywords may not be used as identifiers in Java. You cannot declare a field
whose name is a keyword, for instance.
Examples of keywords are the primitive types (see next section), int and boolean;
the control flow statements for and if; access modifiers such as public, and special
words which mark the declaration and definition of Java classes, packages, and
interfaces: class, package, interface.
You can find all the Java language keywords with explanations at https://en.wikibooks.
org/wiki/Java_Programming/Keywords. The keywords in blue are similar to C lan-
guage:
Basically, a package is a folder of the hard drive that contains classes i.e. Java files.
An example of package organization is given by:
All the Java classes inside the ‘folder32’ must start with:
package folder3.folder32;
...
If a class ‘ClassA’ in folder21 has to use a class ‘ClassB’ from folder12, the file
‘ClassA.java’ will look like:
package folder2.folder21;
import folder1.folder12.ClassB;
....
All the classes from ‘folder21’ can be imported at once: import folder2.folder21.*
Last but not least, because the root ‘src’ folder has not name, it cannot be imported
in other classes. It is therefore a bad habit to put classes in the root folder.
¢ Important
Data types are closed to the one you met in C language. Nevertheless, in Java, they
are additional data types.
Important
Primitive data types are passed by values and all the other types by reference.
Consider the following code:
public class PrimitiveCompoundType {
25
26 Chapter 4 Data types in Java
It yields:
i: 2
array:
2234
i: 2
array:
3234
The value of primitive type is not change for the variable ‘value’ whereas the first
value of the array has changed. You will get the same result with all the primitive
types. All the other compound types would be impacted by a change with one
exception with the ‘String’ type, which is immutable. It means that, even if it is a
compound type, it cannot be changed from within a function.
Exercise 4.1
Try to test the modification aText = aText + ``!'' of a String from within a function in
adapting the previous code.
In object oriented programming, it is also possible to create new data types: the
Object Data Types.
Definition
Primitive types are the most basic data types available within the Java language;
these include boolean, byte, char, short, int, long, float and double. These types
serve as the building blocks of data manipulation in Java. Such types serve only one
purpose — containing pure, simple values of a kind.
Because primitive data types are defined into the Java type system by default, they
come with a number of predefined operations. You can not define a new operation
for such primitive types. In the Java type system, there are three further categories
of primitives:
Numeric primitives: short, int, long, float and double. These primitive data types
hold only numeric data. Operations associated with such data types are those
of simple arithmetic (addition, subtraction, etc.) or of comparisons (is greater
than, is equal to, etc.)
4.1 Primitive data types 27
Textual primitives: byte and char. These primitive data types hold characters (that
can be Unicode alphabets or even numbers). Operations associated with
such types are those of textual manipulations (comparing two words, joining
characters to make words, etc.). However, byte and char can also support
arithmetic operations.
Boolean and null primitives: boolean and null.
All the primitive types have a fixed size. Thus, the primitive types are limited to
a range of values. A smaller primitive type (byte) can contain less values than a
bigger one (long).
Data conversion (casting) can happen between two primitive types. There are two
kinds of casting:
Implicit: casting operation is not required; the magnitude of the numeric value
is always preserved. However, precision may be lost when converting from
integer to floating point types
Explicit: casting operation required; the magnitude of the numeric value may not
be preserved
For instance:
int i1 = 65;
long l1 = i1; // Implicit casting (int is converted to long, casting is not needed)
long l2 = 656666;
int i2 = (int) l2; // Explicit casting (long is converted to int, casting is needed)
28 Chapter 4 Data types in Java
The following table shows the conversions between primitive types, it shows the
casting operation for explicit conversions:
Unlike C, C++ and similar languages, Java can’t represent false as 0 or null and
can’t represent true as non-zero. Java can’t cast from boolean to a non-boolean
primitive data type, or vice versa.
Boolean values are values that evaluate to either true or false, and are represented
by the boolean data type. Boolean expressions are very similar to mathematical
expressions, but instead of using mathematical operators such as "+" or "-", you use
comparative or boolean operators such as "==" or "!".
Java has several operators that can be used to compare variables. For example, how
would you tell if one variable has a greater value than another? The answer: use the
"greater-than" operator.
It comes out:
true
false
true
true
Comparative operators can be used on any primitive types (except boolean), but
only the "equals" and "does not equal" operators work on objects. This is because
the less-than/greater-than operators cannot be applied to objects, but the equivalent
operators can. Specifically, the == and ! = operators test whether both variables
point to the same object.
The Java boolean operators are based on the operations of the boolean algebra. The
boolean operators operate directly on boolean values.
• !: Boolean NOT
• &&: Boolean AND
• | |: Boolean inclusive OR
• ^: Boolean exclusive XOR
The boolean NOT operator (!) inverts the value of a boolean expression. The boolean
AND operator (&&) will result in true if and only if the values on both sides of the
operator are true. The boolean inclusive OR operator (| |) will result in true if either
or both of the values on the sides of the operator is true. The boolean exclusive
XOR operator (^) will result in true if one and only of the values on the sides of the
operator is true.
System.out.println("NOT operand:");
System.out.println(!iMTrue);
System.out.println(!iMFalse);
System.out.println(!(4 < 5));
System.out.println("AND operand:");
System.out.println(iMTrue && iMTrueToo);
System.out.println(iMFalse && iMFalseToo);
System.out.println(iMTrue && iMFalse);
30 Chapter 4 Data types in Java
Strings, which are widely used in Java programming, are sequences of characters.
In the Java programming language, strings are objects.
The Java platform provides the String class to create and manipulate strings.
Whenever it encounters a string literal in your code, the compiler creates a String
object with its value in this case, "Hello world!’. It is stored into memory just
4.3 Strings in Java 31
like with C language. The reference (pointer) is bound to the variable label but,
conversely to C, it is almost transparent for the programmer.
Methods used to obtain information about an object are known as accessor methods.
One accessor method that you can use with strings is the length() method, which
returns the number of characters contained in the string object.
Comparing strings is not as easy as it may first seem. Be aware of what you are
doing when comparing String’s using ==:
public class StringTest {
It yields:
Match not found.
32 Chapter 4 Data types in Java
Match found.
The difference between the ‘==’ and ‘equals’ comparisons is that the ‘==’ checks
to see whether objects are same i.e. in the same position in memory (similarly to
C, pointing to the same object). The ‘equals’ test compares the actual content of
strings.
There are two kinds of arrays: the static ones, whose size cannot be changed and the
dynamic ones. Other sequences such as Set or Map are also available.
Java provides a data structure, the array, which stores a fixed-size sequential collec-
tion of elements of the same type. An array is used to store a collection of data, but
it is often more useful to think of an array as a collection of variables of the same
type.
Instead of declaring individual variables, such as number0, number1, ..., and num-
ber99, you declare one array variable such as numbers and use numbers[0], num-
bers[1], and ..., numbers[99] to represent individual variables.
To use an array in a program, you must declare a variable to reference the array, and
you must specify the type of array the variable can reference. Here is the syntax for
declaring an array variable:
dataType[] arrayRefVar; // preferred way.
dataType arrayRefVar[]; // works but not preferred way.
You can create an array by using the new operator with the following syntax:
arrayRefVar = new dataType[arraySize];
• It assigns the reference of the newly created array to the variable arrayRefVar.
Declaring an array variable, creating an array, and assigning the reference of the
array to the variable can be combined in one statement, as shown below:
Here is a complete example of showing how to create, initialize and process arrays:
public class TestArray {
It leads to:
1.9
2.9
3.4
3.5
Total is 11.7
Max is 3.5
JDK 1.5 introduced a new for loop known as for-each loop or enhanced for loop,
which enables you to traverse the complete array sequentially without using an index
variable.
public class TestArray {
34 Chapter 4 Data types in Java
It results in:
1.9
2.9
3.4
3.5
Refering to “21” in the last array can be done with twoDimArray2[2][1] and to “03”
with twoDimArray2[0][3]. Indeed, a multi-dimensional array is a array of arrays. Note
that row can be missing and that the size of inner arrays can be different, just like in
the ‘weirdTwoDimArray’.
In Java, the easier way to create a dynamic array (dimensions can be dynamically
modified) is to use java.util.ArrayList. Here is an example:
import java.util.ArrayList;
4.4 Arrays in Java 35
It yields:
[1.3, 2.1, 4.5, 3.2, 5.6]
16.700000000000003
It is nevertheless possible to specify what a dynamic table will contain. The follow-
ing code is equivalent to the previous one but casting is not required here:
import java.util.ArrayList;
}
36 Chapter 4 Data types in Java
Note that double in starting by an upper case because primitive type cannot be used
here but the corresponding object type. The following correspondence holds for
primitive types:
• byte → Byte
• short → Short
• int → Integer
• long → Long
• float → Float
• double → Double
• char → Character
• boolean → Boolean
Regarding java.util.ArrayList, the following methods are available (for more see official
JavaDoc http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html):
add(E e): boolean Appends the specified element to the end of this list.
add(int index, E element): void Inserts the specified element at the specified po-
sition in this list.
clear(): void Removes all of the elements from this list.
clone(): Object Returns a shallow copy of this ArrayList instance.
contains(Object o): boolean Returns true if this list contains the specified element.
get(int index): E Returns the element at the specified position in this list.
indexOf(Object o): int Returns the index of the first occurrence of the specified
element in this list, or -1 if this list does not contain the element.
isEmpty(): boolean Returns true if this list contains no elements.
lastIndexOf(Object o): int Returns the index of the last occurrence of the specified
element in this list, or -1 if this list does not contain the element.
remove(int index): E Removes the element at the specified position in this list.
remove(Object o): boolean Removes the first occurrence of the specified element
from this list, if it is present.
size(): int Returns the number of elements in this list.
toArray(): Object[] Returns an array containing all of the elements in this list in
proper sequence (from first to last element).
toArray(T[] a): T[] Returns an array containing all of the elements in this list in
proper sequence (from first to last element); the runtime type of the returned
array is that of the specified array.
Note that ‘E’ stands for the type specified at the ArrayList creation new ArrayList<E>.
If ‘E’ is ‘Double’, replace ‘E’ by ‘Double’ everywhere. If no type is specified, by
default, E is an ‘Object’.
Two other kinds of collections exist: the sets in accordance with mathematical
concept of ‘set’, and the maps, which consist of a collections of couples of values
‘(key,value)’ where value can be obtained thanks to the ‘key’.
Set
We can see that even if “Elisabeth” element has been added twice, it is considered
as the same element. That’s why it appears only once. Conversely to ‘HashSet’,
‘TreeSet’ returns its elements in a sorted way.
add(E e): boolean Adds the specified element to this set if it is not already present.
clear(): void Removes all of the elements from this set (optional operation).
contains(Object o): boolean Returns true if this set contains the specified element.
equals(Object o): boolean Compares the specified object with this set for equality.
isEmpty(): boolean Returns true if this set contains no elements.
remove(Object o): boolean Removes the specified element from this set if it is
present.
38 Chapter 4 Data types in Java
size(): int Returns the number of elements in this set (its cardinality).
toArray(): Object[ ] Returns an array containing all of the elements in this set.
toArray(T[ a): T[]] Returns an array containing all of the elements in this set; the
runtime type of the returned array is that of the specified array.
Map
Similarly to sets, there are two kinds of maps: the standard ones (’HashMap’) and
the sorted ones (’TreeMap’).
Here is an example that illustrates the usage of both. It computes the number of
times a word appears in a text.
import java.util.*;
public class MapExample { //count the occurrencies of words in a text
}
4.4 Arrays in Java 39
It displays:
{incididunt=1, culpa=1, mollit=1, tempor=1, adipiscing=1, est=1, commodo=1, aute=1, laborum →
,→ =1, cupidatat=1, proident=1, du=1, officia=1, deserunt=1, cillum=1, voluptate=1, id=1, →
,→ ea=1, sunt=1, ut=2, enim=1, occaecat=1, ad=1, consequat=1, in=3, velit=1, eiusmod=1, →
,→ Excepteur=1, sint=1, et=1, esse=1, eu=1, ex=1, ipsum=1, exercitation=1, Duis=1, anim →
,→ =1, elit=1, nostrud=1, Ut=1, qui=1, pariatur=1, minim=1, veniam=1, fugiat=1, non=1, →
,→ dolor=2, sed=1, sit=1, nisi=1, irure=1, labore=1, ullamco=1, labori=1, magna=1, aliquip →
,→ =1, dolore=2, Lorem=1, amet=1, aliqua=1, quis=1, reprehenderit=1, consectetur=1, →
,→ nulla=1}
{Duis=1, Excepteur=1, Lorem=1, Ut=1, ad=1, adipiscing=1, aliqua=1, aliquip=1, amet=1, anim →
,→ =1, aute=1, cillum=1, commodo=1, consectetur=1, consequat=1, culpa=1, cupidatat=1, →
,→ deserunt=1, du=1, dolor=2, dolore=2, ea=1, eiusmod=1, elit=1, enim=1, esse=1, est=1, →
,→ et=1, eu=1, ex=1, exercitation=1, fugiat=1, id=1, in=3, incididunt=1, ipsum=1, irure=1, →
,→ labore=1, labori=1, laborum=1, magna=1, minim=1, mollit=1, nisi=1, non=1, nostrud →
,→ =1, nulla=1, occaecat=1, officia=1, pariatur=1, proident=1, qui=1, quis=1, reprehenderit →
,→ =1, sed=1, sint=1, sit=1, sunt=1, tempor=1, ullamco=1, ut=2, velit=1, veniam=1, →
,→ voluptate=1}
The main methods for ‘Map<K,V>’, where ‘K’ is the type of the keys and ‘V’, the
type of the corresponding value, are:
In object oriented programming, new types can be defined. There are named ‘Object’.
¢ Very important to remember
For instance, let’s create a new type, i.e. an object, ‘Rectangle’:
for the next. public class Rectangle {
double width;
double height;
double perimeter;
double surface;
It yields:
[rectangle1] perimeter: 10.0, surface: 50.0
[rectangle2] perimeter: 4.0, surface: 28.0
As you can observe, the new type Rectangle is a bit more than a structure in C
language. Indeed, there is a special method whose name is similar to the name of
the class (i.e. also similar to the file name) that is used to construct a element of the
type ‘Rectangle’. It is named constructor and it is called when ‘new’ is invoked. You
can see that the type contains the variables perimeter and surface that have not been
provided when ‘new’ was called. The values have been processed by the constructor.
In Java, the new type is named class and it has to be defined in a file holding the
same name. A new element of the type (class), such as ‘rectangle1’ or ‘rectangle2’,
is called an object or an instance of the new type or class.
Thanks to this mechanism, many new types can be defined and it is widely used in
object oriented programming.
4.5 New types: classes and objects 41
Format for testing and looping in a code are quite similar to the C language.
5.1.1 If statement
The if block executes only if the boolean expression associated with it is true. The
structure of an if block is as follows:
if (boolean expression1) {
statement_1;
statement_2;
...
statement_n;
}
Curly brackets can be omitted if there is only one statement in the block.
Here is an example to illustrate what happens if the condition is true and if the
condition is false:
int age = 6;
System.out.println("Hello!");
if (age < 13) {
43
44 Chapter 5 Processing data in Java
System.out.println("I'm a child.");
}
if (age > 20)
System.out.println("I'm an adult.");
System.out.println("Bye!");
It leads to:
Hello!
I'm a child
Bye!
The if block may optionally be followed by else-if and else blocks which will execute
depending on conditions. The structure such a block is as follows:
if (boolean expression1) {
statement_1.1;
statement_1.2;
...
statement_1.n;
} else if (boolean expression2) {
statement_2.1;
statement_2.2;
...
statement_2.n;
} ...
}
}
Conditional expressions use the compound ‘?:” operator. The syntax is: boolean →
,→ boolean_expression ? expression1 : expression2. For example: String answer = (p < 0.05)? →
,→ "reject" : "keep"; is equivalent to:
String answer;
if (p < 0.05) {
answer = "reject";
} else {
answer = "keep";
}
Here is an example:
int i = 3;
46 Chapter 5 Processing data in Java
switch(i) {
case 1: // i doesn't equal 1, so this code won't execute
System.out.println("i equals 1");
break;
case 2: // i doesn't equal 2, so this code won't execute
System.out.println("i equals 2");
break;
default: // i has not been handled so far, so this code will execute
System.out.println("i equals something other than 1 or 2");
}
If a case does not end with the break statement, then the next case will be checked,
otherwise the execution will jump to the end of the switch statement.
Starting in J2SE 7.0, the switch statement can also be used with an String value
instead of an integer:
String day = "Monday";
switch(day) {
case "Monday": // Since day == "Monday", this statement will execute
System.out.println("Mondays are the worst!");
break;
case "Tuesday":
case "Wednesday":
case "Thursday":
System.out.println("Weekdays are so-so.");
break;
case "Friday":
case "Saturday":
case "Sunday":
System.out.println("Weekends are the best!");
break;
default:
throw new IllegalArgumentException("Invalid day of the week: " + day);
}
5.2 Loop statements 47
Loops are a handy tool that enables programmers to do repetitive tasks with minimal
effort.
‘while’ loops are the simplest form of loop. The while loop repeats a block of code
while the specified condition is true. Here is the structure of a while loop:
while (boolean expression) {
statement_1;
statement_2;
...
statement_n;
}
The loop’s condition is checked before each iteration of the loop. If the condition is
false at the start of the loop, the loop will not be executed at all. The following code
sets in squareHigherThan200 the smallest integer whose square exceeds 200.
int squareHigherThan200 = 0;
while (squareHigherThan200 * squareHigherThan200 < 200) {
squareHigherThan200 = squareHigherThan200 + 1;
}
If a loop’s condition will never become false, such as if the true constant is used
for the condition, said loop is known as an infinite loop. Such a loop will repeat
indefinitely unless it is broken out of. Infinite loops can be used to perform tasks
that need to be repeated over and over again without a definite stopping point, such
as updating a graphics display.
The do-while loop is functionally similar to the while loop, except the condition is
evaluated AFTER the statement executes It is useful when we try to find a data that
does the job by randomly browsing an amount of data.
do {
statement_1;
48 Chapter 5 Processing data in Java
statement_2;
...
statement_n;
} while (boolean expression);
The for loop is a specialized while loop whose syntax is designed for easy iteration
through a sequence of numbers. It consists of the keyword for followed by three extra
statements enclosed in parentheses. The first statement is the variable declaration
statement, which allows you to declare one or more integer variables. The second is
the condition, which is checked the same way as the while loop. Last is the iteration
statement, which is used to increment or decrement variables, though any statement
is allowed.
The for-each loop automatically iterates through an array and assigns the value of
each index to a variable.
The example iterates through an array of words and prints them out like a sentence.
What the loop does is iterate through sentence and assign the value of each index to
word, then execute the code block.
5.2.5 Complements
The ‘break’ keyword exits a flow control loop, such as a for loop. It basically breaks
the loop.
In the following code, the loop would print out all the numbers from 1 to 10, but we
have a check for when i equals 5. When the loop reaches its fifth iteration, it will be
cut short by the ‘break’ statement, at which point it will exit the loop.
for (int i = 1; i <= 10; i++) {
System.out.println(i);
if (i == 5) {
System.out.println("STOP!");
break;
}
}
Result is:
1
2
3
4
5
STOP!
The ‘continue’ keyword jumps straight to the next iteration of a loop and evaluates
the boolean expression controlling the loop. The following code is an example of
50 Chapter 5 Processing data in Java
It yields:
1
2
3
4
Caught i == 5
6
7
8
9
10
As the break and continue statements reduce the readability of the code, it is rec-
ommended to reduce their use or replace them with the use of ‘if’ and ‘while’
blocks.
Labels can be used to give a name to a loop. The reason to do this is so we can
break out of or continue with upper-level loops from a nested loop.
To break out of or continue with a loop, use the break or continue keyword followed
by the name of the loop.
For example:
int i, j;
int[][] nums = { {1, 2, 5}, {6, 9, 7}, {8, 3, 4} };
Outer:
for (i = 0; i < nums.length; i++) {
for (j = 0; j < nums[i].length; j++) {
if (nums[i][j] == 9) {
System.out.println("Found number 9 at (" + i + ", " + j + ")");
break Outer;
}
}
}
5.3 Methods rather than functions 51
Look at how the label is used to break out of the outer loop from the inner loop.
However, as such a code is hard to read and maintain, it is highly recommended not
to use labels.
Methods can be just like methods in C i.e. bound to a class contained in a file named
identically. It this case, the keyword ‘static’ (named modifier) is used. Here is an
example:
public class StaticExample {
It prints 17. If you work with C-style function (it is quite unusual in Java because it
relies on an object oriented paradigm), and variables, you have to declare them as
‘static’ to bind them to the class i.e. to the file.
At this point, there is no real difference with C except for slight syntax differences.
But Java is intrinsically an object oriented language. We have seen that new types,
named objects, can be defined but it was already possible in C using structures.
What was not possible is to bind functions to new user-defined types i.e. to objects.
¢ Very important for the next:
it deals the object oriented
Here is an object oriented version of the previous code: programming core philoso-
public class Accumulator {
phy.
double result; // attributes of the new type
52 Chapter 5 Processing data in Java
A new type ‘Accumulator’ has been created: it embeds its own variables, named
attributes and its own functions that operate on the type attribute ‘result’. Comparing
to the previous version, the ‘static’ modifier is no longer present. In Java, each
element of a new type is named ‘instance’ or ‘object’. There are obtained thanks
to the ‘new’ keyword. Once ‘new’ is invoked, the class constructor is called. The
constructor is a special method, which hold the same name that the class and whose
return type is implicitly void.
Of course, functions bind to class (i.e. to the file), named static methods, can be
mixed with functions bind to a new type, named object or instance methods, but
there are some limitations. Object methods can access static variables and methods
bound to the class but, the opposite is not possible. Indeed, a static method cannot
access to object variables and methods because they operate on specific values that
are defined each time ‘new’ is invoked. Therefore their life cycles are different:
5.3 Methods rather than functions 53
Here is example that mixes both kinds of variables and methods. Consider the files
‘Bicycle.java’:
class Bicycle {
Bicycle(int aNumberOfGears) {
numberOfGears = aNumberOfGears;
currentGear = 1;
}
int getCurrentGear() {
return currentGear;
}
and ‘Person.java’:
class Person {
String name;
Bicycle bicycle;
Person(String name) {
this.name=name;
double distanceInKmh = Bicycle.convertMiles2Kmh(80); // allowed: method bound to class
bicycle = new Bicycle(10);
bicycle.changeGear(2); // allowed: methods applying to bicycle data
}
String getName() {
return name;
}
Bicycle getBicycle() {
return bicycle;
}
Just analyze how the methods are called. Static method are called by prefixing
with the class name such as Bicycle.convertMiles2Kmh(50) (notice the upper case in
‘Bicycle’), whereas other methods are related to an instance generated by the class
me.getBicycle(), denoted by ‘me’ here. currentGear = newGear; is not possible in static →
,→ void staticChangeGear(int newGear) because static methods cannot access to none static
variables because of life cycle issues.
Difference between static and object variables and methods can be also represented
5.4 Scope of variables 55
by:
Class C1 Class C2
static method 1.1, which can use exclusively static variables static method 2.1, which can use exclusively static variables
static method 1.2, which can use exclusively static variables static method 2.2, which can use exclusively static variables
…
XX …
The scope of a class, a variable or a method is its visibility and its accessibility. The
visibility or accessibility means that you can use the item from a given place.
The scope of a class, a variable or a method is its visibility and its accessibility. The
visibility or accessibility means that you can use the item from a given place.
A method parameter is visible inside of the entire method but not visible outside the
method
public class Scope {
public void method1(int i) { // parameter i is accessible only from inside this code block {...}
i = i++; // parameter i is accessible
method2(); // parameter i is accessible as argument but not from inside method2
int j = i * 2; // parameter i is accessible
} // from here, parameter i is no longer accessible
A local variable is visible after its declaration until the end of the block in which the
local variable has been created.
{
...
// myNumber is NOT visible
{
// myNumber is NOT visible
int myNumber;
// myNumber is visible
{
...
// myNumber is visible
}
// myNumber is visible
}
5.4 Scope of variables 57
• What is the syntax for main conditional and loop statements (if, while, for,
for-each)?
• What is the difference between static and non-static variables and attributes?
• What is a constructor?
• When ‘new’ shall be invoked?
• What is the difference between an object and a class?
• How visibility works in Java?
• What is the terminology in object oriented programming?
Chapter 6
The aim of this project is to process random series of data representing sensor data.
Outliers have to be detected. Times are expressed in hours with decimals. Series of
data are not regularly distributed but covers 24 hours. Here, we will used relative
time: it is worth 0 at the beginning of the day.
Outliers
Contextual outliers are defined as data points, which, in the contact of previous and
future data points, seem highly improbable. These points have been detected as the
ones that follow the equations simultaneously:
pdiffk = x k − x k−1
fdiffk = x k+1 − x k
| pdiffk |> m ∆x + λσ∆x
| fdiffk |> m ∆x + λσ∆x
pdiffk . fdiffk < 0
where:
59
60 Chapter 6 Problem: managing time series
All the data points that satisfy the above equation are outliers.
It is requested to:
1. create a class ‘Serie’ that collects doubles representing either relative times
in hours or measurement data. Each serie should be named and must contain
methods to return its name, its size and its values as ‘double[]’
2. design a ‘toString()’ method to display the series
3. with ‘Serie’, generate a random serie of 100 (start by 10 for debugging)
consecutive values of CO2 between 400 and 2500 using a method void →
,→ populateWithValues(int numberOfValues, double min, double max) for populating the
serie.
4. with ‘Serie’, generate a non equaly distributed serie of 100 (start by 10 for
debugging) consecutive relative times in hours covering 24 hours using a
method void populateWithTimes(int numberOfValues, double max) for populating the
serie.
5. add methods to compute average and standard deviation.
optional detect the outliers from the random data. If no outliers is found, reduce the
value of λ for testing.
6.2 Clues
• Math.random() generates a random number between 0 and 1.
• Math.abs(doubleValue)computes the absolute value of doubleValue.
• use the method set to replace a value in an ArrayList.
• to sort an ArrayList<T>, you can use the method sort bound to the class java. →
,→ util.Collections.
• to copy the elements of an ArrayList<T> of type T, use the method toArray( →
,→ T[] arrayWhereDataAreCopied)
Part II
61
Chapter 7
We have seen that Java classes can be used to create new types. Element of this new
type is a compound value named instance or object.
Each object is created thanks to a specific method, named constructor, holding the
same name that the class depicting the object, whose return type is implicitly ‘void’
and omitted.
The ‘static’ keyword is used to bind a variable or a method to the class i.e. to the
program. When the keyword is omitted, it means that the variable or the method is
related a particular object of the related class.
63
64 Chapter 7 Object oriented programming
The second time ‘object1’ is displayed, the 3rd value has changed because of the
construction of ‘object2’! Why? Because a static variable is bound to the class that
generates objects i.e. it is common to all objects stemmed from ‘Class’. Assignment
of value 2 during the generation of ‘object2’ modifies the value in all objects whereas
each non-static variable is independent (but same types) in each object.
Therefore, we can imagine two kinds on variable containers: one, which contains
static variables related to a class, and several variable containers, each of them bound
to a instance of the class. Actually, the containers related to an instance can be
represented by the keyword this. It is not really representative of the meaning. It is
cleared in Python language where the keyword ‘self’ is used.
In the previous code, ‘this’ where implicit. Let’s explicit the code:
public class Class {
Class object2 = new Class("object2", 2, 2); // a new object of type Class is constructed
System.out.println(object1);
System.out.println(object2);
}
}
Exercise 7.1
Develop a single class ‘Customer’ with attributes ‘name’ (String) and ‘credit’ (double)
with a counter with the number of customer generated. Try and check whether it
works properly.
66 Chapter 7 Object oriented programming
Java has been designed for object oriented programming. Practically, it means that
‘static’ variables and methods must remain exceptional. Processings result from
the interactions of new types reflecting actual objects or concepts. Each object
of a given class has its own values and its methods that operate on its own value.
As mentioned before, it is a lot more efficient for complex codes because objects
copy the reality and are therefore meaningful. Their attributes, i.e. object variables,
define their characteristics and their methods, their capabilities, i.e. the services
they can provide. Consequently, data and functions are encapsulated into objects
copying a meaningful reality: it is highly structured according to a representation
of a world. Object oriented design is therefore not sequential just like in structured
programming such as C, but it is highly dependent of a representation of a world
seen by the developer.
Exercise 7.2
The aim is to represent broken lines and to compute their length. With an object
oriented point of view, 2 classes should be created:
• a class ‘Point’ with x and y coordinates, and a method ‘double distance(Point
otherPoint)’
• a class ‘BrokenLine’ with a serie of points and a method ‘double length()’
Compute the length of the following broken line: ((0, 0), (2, 0), (2, 2), (1, 3), (0, 2), (0, 0)).
You can get further informations about ‘class’ and ‘object’ at https://en.wikibooks.
org/wiki/Java_Programming/Defining_Classes and https://en.wikibooks.org/wiki/
7.2 Polymorphism 67
Java_Programming/Object_Lifecycle.
7.2 Polymorphism
In Java, it is possible to have different methods holding the same name. Consider
for instance the code:
public class Rectangle {
Rectangle() {}
It comes out:
3.0 x 4.0
5.0 x 5.0
Their 2 methods ‘setSize’ offering different forms of a same service ‘setSize’: one
requires to provide 2 values and another one, only one length assuming the rectangle
is a square. Even if the name is identical, Java virtual machine can make the
difference using the method signatures:
void setSize(double, double)
68 Chapter 7 Object oriented programming
void setSize(double)
Only the signature is important: names of the arguments do not make any difference.
This Java facility is named ‘polymorphism’ because a same service i.e. same method
name, can adapt to different set of arguments providing thus different forms for the
service.
Similarly, there may be several ways to create an object: polymorphisms also exist
for constructor:
public class SimpleRectangle {
SimpleRectangle(double length) {
this.width = length;
this.height = length;
}
SimpleRectangle(double length) {
this(length, length);
}
7.3 Encapsulation
)
ue
ge
al
tA
tv
ttr
in
ib
(
t1
u t1
u
ib ()
ttr
tA
se
attributs
ge
tA
()
ttr
te
pu
ib
u
m
t2
() co
Here is an example:
public class EncapTest{
73
74 Chapter 8 Core object oriented programming
and
public class Car {
You can notice duplicated codes, which are difficult to maintain. Indeed, if you want
to update one class, then you have also to update the other class. Then, discrepancies
main appears. There is also another issue: although there are different, both types
(classes) of objects share some common attributes and methods but they cannot be
handled in the same way, in a for-loop for instance that would display the current
covered distance with getCoveredDistanceInKm().
double coveredDistanceInKm;
Vehicle(double intialCoveredDistanceInKm) {
coveredDistanceInKm = intialCoveredDistanceInKm;
}
double getCoveredDistanceInKm() {
return coveredDistanceInKm;
}
‘Plane’ and ‘Car’ then become ‘BetterPlane’ and ‘BetterCar’, where common at-
tributes and methods do not appear but are inherited from ‘Vehicle’. Here is the
‘BetterPlane’ class:
public class BetterPlane extends Vehicle { // note the `extends Vehicle'
int numberOfEngines;
}
76 Chapter 8 Core object oriented programming
• coveredDistanceInKm
• numberOfEngines
• addCoveredDistanceInKm(double)
• getCoveredDistanceInKm()
• toString()
When an ‘BetterPlane’ object is created using ‘new’, the first line to be executed is
super(intialCoveredDistanceInKm). It invokes the constructor of the superclass ‘Vehicle’
with the argument intialCoveredDistanceInKm. Indeed, through inheritance mechanism,
a plan is a specialization of a vehicle, it means that the vehicle has to be built first
then specialized into a vehicle. What happened then when calling new BetterPlane →
,→ (4, 12000)? Following steps are carried out:
• the program cursor reaches the first line of the constructor of ‘BestPlane’ with
the local variables numberOfEngines=4 and intialCoveredDistanceInKm=12000
• super(intialCoveredDistanceInKm); calls the constructor of ‘Vehicle’ with the local
variable intialCoveredDistanceInKm=12000
• the attributes of the Vehicle object under creation are created i.e. the attribute
‘coveredDistanceInKm’ here. It is bound to the ‘this’ object variable container
• the ‘Vehicle’ constructor is then run: it modifies the coveredDistanceInKm
attribute value with coveredDistanceInKm = intialCoveredDistanceInKm; (intialCov-
eredDistanceInKm=12000)
• then, it returns to ‘BestPlane’ and initializes its attributes: numberOfEngines. It
is set to 0.
• then it runs the instruction after the ‘super()’ of the ‘BestPlane’ constructor
i.e. this.numberOfEngines = numberOfEngines;. Yet, the attributes of ‘BestPlane’
numberOfEngines is worth 4.
• an object of class ‘BestPlane’ is now available. It has 2 attributes and 3
methods available
int numberOfGears;
String owner;
It leads to:
Plane with 4 engines. Covered distance is 13000.0
Car owned by Paul with 5 gears. Covered distance is 6000.0
If you look at the first line of the main method Vehicle[] fleet = new Vehicle[] {new →
,→ BetterPlane(4, 12000), new BetterCar(5,5000)}, you can see that because BestPlane and
BestCar objects are Vehicle, they can be combined in a same array of Vehicles: fleet.
The for−each loop can directly used the attributes and methods related to Vehicle but
not directly members that are specific to subclasses ‘BetterPlane’ or ‘BetterCar’. To
do so, just like in ((BetterCar)fleet[1]).setOwner("Paul"), the object has to be casted into
the class where the method is bound i.e. ‘BetterCar’ for method setOwner(String).
From a semantic point of view, it is said that ‘BestPlane’ and ‘BestCar’ are
specialization of ‘Vehicle’. ‘Vehicle’ is a generalization of ‘BestPlane’ and ‘Best-
Car’. In this relation, ‘BestPlane’ and ‘BestCar’ are subclasses of ‘Vehicle’. ‘Ve-
hicle’ is the superclass of ‘BestPlane’ and of ‘BestCar’. Therefore, the technical
inheritance mechanism can be also mapped to the objects of the world.
The relation between classes i.e. new type, can be represented by the following
UML class diagram:
78 Chapter 8 Core object oriented programming
Vehicle
~coveredDistanceInKm: double
~Vehicle(double intialCoveredDistanceInKm): ctor
~addCoveredDistanceInKm(double coveredDistanceInKm): void
~getCoveredDistanceInKm(): double
BetterPlane
~numberOfEngines: int
+BetterPlane(int numberOfEngines, double intialCoveredDistanceInKm): ctor
+toString(): String
BetterCar
~numberOfGears: int
~owner: String
+BetterCar(int numberOfGears, double intialCoveredDistanceInKm): ctor
~setOwner(String owner): void
+toString(): String
Exercise 8.1
Run the previous code in debug mode after putting a break point at line Vehicle →
,→ [] fleet = new Vehicle[] {new BetterPlane(4, 12000), new BetterCar(5,5000)}. Observe
how the program cursor evolves using ‘step into’ and ‘step over’ buttons.
Imagine now that you want to count the number of trips achieved but only for the cars.
You need to intercept the call of the ‘Vehicle’ method named addCoveredDistanceInKm →
,→ (double). To do that, we are going to overload the ‘Vehicle’ method in ‘BestCar’:
public class BetterCar extends Vehicle {
It yields:
Plane with 4 engines. Convered distance is 13000.0
Car owned by Paul with 5 gears. Covered distance is 6000.0; trips:1
Car owned by Paul with 5 gears. Covered distance is 6700.0; trips:2
Casting objects
A subclass can be assigned directly into its superclass (and super-superclass) without
any cast but the opposite is not that easy. Cast has to be explicitly done. Let’s consider
the following code architecture:
80 Chapter 8 Core object oriented programming
Shape
getSurface()
Rectangle Disk
getDiagonal() getRadius()
Last topic to develop in this section is the order of execution. We have already seen
how the execution order in non-sequential. Let’s go deeper into this important topic.
Consider a superclass with static and non static variables:
public class SuperClass {
static int var1=1; // #1
int var2=2; // #2
static {
code1; // #3
}
8.1 Inheritance and overloading 81
public SuperClass() {
code2; // #4
}
}
All the static variables but also the static block (which acts as a constructor for the
class) are initialized and run at first when the Java application under development
starts to run.
public class SubClass extends SuperClass {
static int var3=1; // #5
int var4=2; // #6
static {
code3; // #7
}
public SubClass() {
super();
code4; // #8
}
static public void main(String[] args) {
new SubClass(); // #9
}
}
When running the main method, the instructions are run in the following order: #5,
#7, #1, #3, #9, #2, #4, #6 and finally #8. Note that static variables and code blocks
are run first however, order in between #5, #7, #1 and #3 is not guarantee but it does
not really matter.
Some classes can be nested into the class holding the same name than the current
file but it has to be avoid as much as possible because of the potential increase of
code complexity. Nevertheless, it can be useful in some circumstances. To learn
more about nested classes, visit https://en.wikibooks.org/wiki/Java_Programming/
Nested_Classes.
82 Chapter 8 Core object oriented programming
Shape() {...}
abstract double getSurface(); // abstract there means that subclasses should implement this →
,→ method
}
double width;
double height;
double getDiagonal() {
return Math.sqrt(width*width + height*height);
}
double getSurface() { // Java will throw an error if this method is not implemented because of →
,→ the abstract class Shape
return width * height;
}
Another shape likes ‘Disk’ will also implement double getSurface() but its own way.
In Java multiple inheritance is not allowed for the sake of clarity. However, it
0 Inheriting from several su-
may be useful to specify that an object is of several types at the same time. Java
perclasses can indeed lead
to complex problems when provides a specific kind of types: the interfaces. Roughly speaking, an interface is
executing the superclass con- a totally abstract class without constructor. Because all the methods are necessary
structors: order is important
and it is not just to say the
subclass belongs to several
supertypes.
8.2 Abstract classes and interfaces 83
int method1(String parameter) { // just like for abstract methods, the methods specified in the →
,→ interface have to be developed
return 0;
}
Let’s come back to the shape example. Imagine we want a shape to belong to 2 types
at the same time: Shape and ColoredObject. Shape requires 2 methods: getSurface()
and getPerimeter(). ColoredObject contains color attributes and methods setColor(int)
84 Chapter 8 Core object oriented programming
and getColor(). Because multiple inheritance is not possible, at least one of these
types must be an interface. ShapeInterface is defined by:
public interface ShapeInterface {
int color = 0;
Object from class Disk are also from type ColoredObject, ShapeInterface and
(indirectly) ColorInterface.
8.2 Abstract classes and interfaces 85
ColoredObject
color: int implements
setColor(int color): void
ColorInterface
getColor(): int
setColor(int color): void
getColor(): int
extends
implements
Disk
ShapeInterface
getSurface(): double
getPerimeter(): double
An interface can extend several interfaces using the ‘extends’ keyword. Multiple
inheritance is thus allowed for interfaces:
public interface InterfaceA {
public void methodA();
}
This way, a class implementing the InterfaceAB interface has to implement the
methodA(), the methodB() and the otherMethod() methods:
public class ClassAB implements InterfaceAB {
public void methodA() {
System.out.println("A");
}
Interfaces are also widely used to structure codes. Let’s consider the collections and
maps we have already studied.
group of object
Interface with possible
Collection duplications
group of object
Interface Interface group of objects
with possible
List Set without duplications
duplications and
and indices
indices
sorted group of
Class Class Class Interface objects without
ArrayList ArrayList HashSet SortedSet duplications and
indices
group with
(key,value) Interface Class Class
elements Map HashMap TreeSet
group with
(key,value) Interface Class
elements SortedMap TreeMap
sorted
according
to keys
Details about these interfaces and classes can be found at the official Javadoc API:
8.3 Interfaces for structuring codes 87
http://docs.oracle.com/javase/7/docs/api/.
Interfaces and implemented classes can be summarized using the UML formalism.
ArrayList
HashMap
(equals)
TreeMap
ordonné (equals+compareTo)
Interfaces are widely used in Java. Consider for instance arrays and collections of
objects.
A list or an array can be sorted because of the comparable interface (see http:
//docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html):
Interface java.lang.Comparable<T> {
The compareTo() method returns a negative integer, zero, or a positive integer as the
current object (this) is less than, equal to, or greater than the specified object.
In general, errors can be broken up into two categories: design-time errors and logical
errors. Design-time errors are easy to spot because Eclipse usually underlines them.
If the error will prevent the program from running, Eclipse will underline it in red.
Logical errors are the most difficult to find. The program will run but, because you
did something wrong with the coding, there is a good chance the execution crashes.
In Java, errors are handled by an Exception object. Exceptions are said to be thrown,
and it is the developer job to catch them. You can do this with a try-catch block.
The try-catch block looks like this:
try {
// code to run with potential exceptions and errors
} catch (ExceptionType1 exceptionEvent) {
// what to do in case of ExceptionType1 has been captured
} catch (ExceptionType2 exceptionEvent) {
// what to do in case of ExceptionType2 has been captured
}
The try part of the try-catch block means "try this code". If something goes wrong,
Java will jump to the catch block. It checks the type of exception raised to see if you
have handled the error. If you have the corresponding Exception type then the code
between the curly brackets will get executed. If you do not have the corresponding
Exception type then Java will use its default exception handler to display an error
message.
91
92 Chapter 9 Exceptions and errors
try {
int x = 10;
int y = 0;
int z = x / y;
System.out.println( z );
} catch ( Exception err ) {
System.out.println( err.getMessage() );
}
}
It yields:
/ by zero
In the try part of the try-catch block, 3 integers: x, y and z have been defined. We
are trying to divide y into x, and then print out the answer.
If anything goes wrong, we have a catch part. In between the round brackets of
catch we have this: Exception err.
The type of Exception you are using comes first. In this case we are using the
Exception error object. This is a "catch all" type of Exception, and not a very good
programming practice.
After your Exception type you have a space then a variable name. We have called it
‘err’, but any label can be used.
In the curly brackets of catch, we have a print statement. Look what we have between
the round brackets of println: err.getMessage(). getMessage() is a method available to
Exception objects. As its name suggests, it gets the error message associated with
the Exception. When running the code, the displayed message is: / by zero.
Again, an error message is displayed in the Output window: Infinity. This time, Java
stops the program because the result will be an infinitely large number.
Errors that involve numbers should not really be handled by a "catch all" Exception
type. There is a specific type called ArithmeticException. It is better to replace the
word Exception between the round brackets of your catch block with ArithmeticEx-
ception.
9.2 Deeper into exceptions 93
However, exception can be propagated to the code block that called method(), which
can itself catch the exception or propagate it to its own caller.
{ 1
code block A; {
} code block B ; 2
} { 3 {
6 code block C; code block D;
exception } exception
5 4
caught thrown;
7 }
exception
propagated
{
exception
code block E;
is processed
}
here
RunTimeException and its subclasses are special because that do not require any
‘throws’ statement to be propagated: it is done automatically because they are critical
errors that will crash the code execution.
9.3 Raising an Exception 95
public MyClass(...) {
...;
}
• What is an exception?
• How to capture an exception?
• How to propagate an exception?
• How to raise an exception?
• What is specific to RunTimeException?
Chapter 10
The best way to design a Java code is to identify the classes of objects that are
going to be used. Theses classes should correspond to concepts of the real world.
The first step is then to list these objects and to define how they are linked. Then,
attributes and methods are defined for each. Attributes represent their characteristics
and methods the services they can provide.
Nevetheless, it is not easy to design when coding. It is usual to split the 2 steps.
The design is carried out thanks to a graphical language: the Unified Modeling
Language, and in particular, the class diagram.
The purpose of the class diagram is to show the types being modeled within the
system. In most UML models these types include ‘class’ and ‘interface’. Note that
just types of objects are represented but not directly objects.
97
98 Chapter 10 Designing your own object models
The top compartment shows the class’s name. The middle compartment lists the
class’s attributes. The bottom compartment lists the class’s operations. When
drawing a class element on a class diagram, you must use the top compartment,
and the bottom two compartments are optional. Here, the class name is ‘Flight’,
and in the middle compartment, we see that the ‘Flight’ class has three attributes:
flightNumber, departureTime, and flightDuration. In the bottom compartment, we
see that the ‘Flight’ class has two operations: delayFlight and getArrivalTime.
We have already seen how to represent inheritance. The next figure shows how both
CheckingAccount and SavingsAccount classes inherit from the BankAccount class.
The relationships between objects have also to be represented i.e. the variables in an
type that refer to another type. Relationships are modelled by associations in UML
10.2 Using UML class diagrams as design tool 99
class diagrams. The next figure shows a standard kind of association between the
Flight class and the Plane class:
Literally, it means:
We can find a multiplicy at each end of an association: min..max where min and
max stand respectively for minimum and maximum number of referred objects in
the type at the other end of the arrow. ‘*’ means zero or more. With a Java point of
view, the association will be translated into:
• an additional variable of type ‘Plane’ into the class ‘Flight’: Plane assignedPlane →
,→ .
• an additional array or a list of type ‘Flight’ into the class ‘Plane’: ArrayList< →
,→ Flight> assignedFlights, for instance.
Bi-directional associations are often used at design stage but, during coding, it is
100 Chapter 10 Designing your own object models
UML class diagram can be drawn on a sheet of paper but software applications can
also be used. We recommend UMLet because it is free, multi-OS, simple, powerful
and pluggable into Eclipse. See http://www.umlet.com/faq.htm to see how to install
it into Eclipse.
Problem: Matrices
Sparse matrices are matrices full of zeros. To avoid filling the memory with a lot of
useless zeros, only non-null elements are recorded in a sparse matrix. Nevertheless,
from a user point of view, it is hidden. Indeed, if an matrix element is not recorded,
it is worth obviously zero. To store the matrix elements, we are going to use a map:
TreeMap<MatrixElementCoordinate, Double> elements, sorted according to a unique order
defined by implementing the Java native java.lang.Comparable<MatrixElementCoordinate →
,→ > interface (see javadoc of the officiel Java api). The class diagram representing
of the requested code is below.
interface from
SparseMatrix native Java api
numberOfLines: int
numberOfColumns: int java.lang.Comparable<MatrixElementCoordinate>
--
compareTo(MatrixElementCoordinate otherMatrixElementCoordinate): int
SparseMatrix(int numberOfLines, int numberOfColumns): ctor
setValue(int i, int j, double value): void
getValue(int i, int j): double 1
getSize(): int[]
transpose(): SparseMatrix
toString(): String
MatrixElementCoordinate
int i: int
inheritance int j: int
TreeMap<MatrixElementCoordinate, Double> elements
* MatrixElementCoordinate(int i, int j): ctor
DiagnonalMatrix getI(): int
getJ(): int
DiagonalMatrix(int size): ctor toString(): String
setValue(int i, int j, double value): void
101
102 Chapter 11 Problem: Matrices
sparseMatrix.setValue(0, 1, 2);
sparseMatrix.setValue(2, 1, 1);
sparseMatrix.setValue(0, 0, 0);
sparseMatrix.setValue(2, 1, 0);
System.out.println(sparseMatrix);
SparseMatrix transposedMatrix = sparseMatrix.transpose(); // sparseMatrix should not →
,→ be altered by this method
System.out.println(transposedMatrix);
System.out.println(sparseMatrix);
2. Create your own exception raised when trying to write out of the matrix:
sparseMatrix.setValue(2, 4, −2); should raise the exception
3. Implement the class DiagonalMatrix. It should raise the exception when writing
out of the diagonal.
4. Find a solution for the transposition of a diagonal matrix to remain a diagonal
matrix (not possible to write out of the diagonal), without reimplementing the
transpose method into DiagonalMatrix.
11.2 Clues
Problem: Shapes
A disk can be constructed using a central point and a radius, or using 2 points
defining its diameter.
A retangle can be constructed using 2 points defining one of its diagonal, or using
one point, a width and a height.
103
104 Chapter 12 Problem: Shapes
canvas.getShape(rectangle1Id).setFilling(true);
canvas.getShape(rectangle2Id).setFilling(true);
canvas.getShape(disk1Id).setFilling(true);
canvas.getShape(disk2Id).setFilling(true);
canvas.deleteShape(disk2Id);
System.out.println(canvas);
System.out.println(canvas.getAllFilledShapesArea());
System.out.println(canvas.isInsideAShape(new Point(−2,2)));
System.out.println(canvas.isInsideAShape(new Point(1.5,−2.5)));
12.2 Clues
The class Shape cannot be instantiated i.e. a Shape must be either a disk or a rectangle.
Part III
105
Chapter 13
Let’s examine how GUI1 can be designed: it will be useful for the project.
Because modern GUI are resizable, the position of GUI visual elements is not static:
it depends on layouts, which are related to containers encompassing other GUI
elements. The type of layout determines how the visual elements are displayed
depending on the size of the container. Therefore, a GUI is organized hierarchically
with a top level. A top level container contains other containers or GUI visual
components like main window controls (frame), menu bar, toolbar, label, buttons,
editor, file picker,... Each component capture some predefined user events. The
developer has then to register or to bind a method to some events in order to handle
events and to trigger specific behaviors.
1 Graphic User Interfaces
107
108 Chapter 13 Programming Graphic User Interfaces
13.2.1 UI components
Visual components
JList A JList component presents the user with a scrolling list of text items.
JComboBox A JComboBox component presents the user with a to show up menu
of choices.
JTextField A JTextField object is a text component that allows for the editing of a
single line of text.
JPasswordField A JPasswordField object is a text component specialized for pass-
word entry.
JTextArea A JTextArea object is a text component that allows for the editing of a
multiple lines of text.
ImageIcon An ImageIcon control is an implementation of the Icon interface that
paints icons from images.
JScrollbar A Scrollbar control represents a scroll bar component in order to enable
user to select from range of values.
JOptionPane A JOptionPane provides set of standard dialog boxes that prompt
users for a value or informs them of something.
JFileChooser A JFileChooser control represents a dialog window from which the
user can select a file.
JProgressBar As the task progresses towards completion, the progress bar displays
the task’s percentage of completion.
JSlider A JSlider lets the user graphically select a value by sliding a knob within a
bounded interval.
JSpinner A JSpinner is a single line input field that lets the user select a number or
an object value from an ordered sequence.
13.2 Java Swing 111
HelloWorldFrame() {
JLabel helloWorldJLabel = new JLabel("Hello World");
add(helloWorldJLabel);
setSize(100, 100); // set size or use `pack();' to set it automatically
setVisible(true); // to display components
}
Swing provides three generally useful top-level container classes: JFrame, JDialog,
and JApplet. When using these classes, you should keep these facts in mind:
// Create the GUI and show it. For thread safety, this method should be invoked from the →
,→ event−dispatching thread.
private static void createAndShowGUI() {
JMenuBar greenMenuBar = new JMenuBar(); // Create the menu bar. Make it have a green →
,→ background.
greenMenuBar.setOpaque(true);
greenMenuBar.setBackground(new Color(154, 165, 127));
greenMenuBar.setPreferredSize(new Dimension(200, 20));
JLabel yellowLabel = new JLabel(); //Create a yellow label to put in the content pane.
yellowLabel.setOpaque(true);
yellowLabel.setBackground(new Color(248, 213, 131));
yellowLabel.setPreferredSize(new Dimension(200, 180));
frame.setJMenuBar(greenMenuBar); //Set the menu bar and add the label to the content →
13.2 Java Swing 115
,→ pane.
frame.getContentPane().add(yellowLabel, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true); // Display the window.
}
A standalone application with a Swing-based GUI has at least one containment hier-
archy with a JFrame as its root. A Swing-based applet2 has at least one containment
hierarchy, exactly one of which is rooted by a JApplet object. But applets are out of
the scope of the lesson.
You find the content pane of a top-level container by calling the getContentPane method.
The default content pane is a simple intermediate container that inherits from
JComponent, and that uses a BorderLayout as its layout manager (it will be explained
later).
To make a window dependent on another window i.e. disappearing when the other
window is iconified for example, use a dialog instead of frame. To make a window
that appears within another window, use an internal frame.
// Create the GUI and show it. For thread safety, this method should be invoked from the event →
,→ −dispatching thread.
private static void createAndShowGUI() {
JFrame frame = new JFrame("FrameDemo"); // Create and set up the window.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Exit the program when →
,→ your user closes the frame
frame.pack(); // Sizes the frame so that all its contents are at or above their preferred sizes
frame.setVisible(true); //Display the window.
}
Layout,
JPanel &
JComponents
By default, window decorations are supplied by the native window system. However,
you can request that the look-and-feel provides the decorations for a frame. You can
also specify that the frame have no window decorations at all, a feature that can be
used on its own, or to provide your own decorations, or with full-screen exclusive
mode.
Besides specifying who provides the window decorations, you can also specify
which icon is used to represent the window. Exactly how this icon is used depends
on the window system or look and feel that provides the window decorations. If
the window system supports minimization, then the icon is used to represent the
minimized window. Most window systems or look and feels also display the icon
in the window decorations. A typical icon size is 16 × 16 pixels, but some window
systems use other sizes.
The following snapshots show three frames that are identical except for their window
decorations. As you can tell by the appearance of the button in each frame, all three
use the Java look and feel. The first uses decorations provided by the window
system, which happens to be Microsoft Windows, but could as easily be any other
system running the Java platform. The second and third use window decorations
provided by the Java look and feel. The third frame uses Java look and feel window
decorations, but has a custom icon.
Here is an example of creating a frame with a custom icon and with window
decorations provided by the look and feel:
//Ask for window decorations provided by the look and feel.
JFrame.setDefaultLookAndFeelDecorated(true);
As the preceding code snippet implies, you must invoke the setDefaultLookAnd-
118 Chapter 13 Programming Graphic User Interfaces
FeelDecorated method before creating the frame whose decorations you wish to
affect. The value you set with setDefaultLookAndFeelDecorated is used for all
subsequently created JFrames. You can switch back to using window system deco-
rations by invoking JFrame.setDefaultLookAndFeelDecorated(false). Some look
and feels might not support window decorations; in this case, the window system
decorations are used.
Here is an example:
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JWindow;
public JWindowDemo(){
setBounds(60,60,100,100);
addWindowListener(new WindowAdapter(){
120 Chapter 13 Programming Graphic User Interfaces
addMouseMotionListener(new MouseMotionAdapter()
{
public void mouseDragged(MouseEvent e){
setLocation(getLocation().x+(e.getX()−X),getLocation().y+(e.getY()−Y));
}
});
setVisible(true);
}
public static void main(String[] args){
new JWindowDemo();
}
}
JPanel The JPanel class provides general-purpose containers for lightweight com-
ponents.
Here is an example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
public JPanelExample() {
createAndShowGUI();
}
setLayout(new FlowLayout());
// Set some border. Here a line border of 5 thickness, dark gray color and rounded edges
panel1.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY,5,true));
// Add panels
add(panel1);
add(panel2);
setSize(400,400);
setVisible(true);
pack();
}
13.2.2 Layouts
Layout are the way components added to a container are visually organized. They
are different layout managers.
BorderLayout
Here is an example:
import java.awt.BorderLayout;
import java.awt.Container;
import javax.swing.JButton;
import javax.swing.JFrame;
BorderLayoutExample() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container container = getContentPane();
container.add(BorderLayout.NORTH,new JButton("North"));
container.add(BorderLayout.SOUTH,new JButton("South"));
container.add(BorderLayout.EAST,new JButton("East"));
container.add(BorderLayout.WEST,new JButton("West"));
container.add(BorderLayout.CENTER,new JButton("Center"));
pack();
setVisible(true);
}
BoxLayout
The BoxLayout class puts components in a single row or column. It respects the
components’ requested maximum sizes and also lets you align components.
13.2 Java Swing 123
Here is an example:
import java.awt.BorderLayout;
import java.awt.Container;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
public BorderAndBoxLayoutExample() {
super("example");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Box verticalBox = Box.createVerticalBox();
for (int i = 0; i < 5; i++) verticalBox.add(new JButton("bv " + i));
Box horizontalBox = Box.createHorizontalBox();
for (int i = 0; i < 5; i++) horizontalBox.add(new JButton("bh " + i));
Container contentPane = getContentPane();
contentPane.add(BorderLayout.EAST, verticalBox);
contentPane.add(BorderLayout.SOUTH, horizontalBox);
pack();
setVisible(true);
}
FlowLayout
FlowLayout is the default layout manager for every JPanel. It simply lays out
components in a single row, starting a new row if its container is not sufficiently
wide.
Here is an example:
import java.awt.FlowLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
FlowLayoutExample() {
super("Example");
addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) →
,→ {System.exit(0);}});
JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); // or LEFT, RIGHT
jPanel.add(new JButton("button1"));
jPanel.add(new JButton("button2"));
add(jPanel);
pack();
setVisible(true);
}
GridLayout
GridLayout simply makes a bunch of components equal in size and displays them in
the requested number of rows and columns.
13.2 Java Swing 125
CardLayout
The CardLayout class lets you implement an area that contains different components
at different times. A CardLayout is often controlled by a combo box, with the state
of the combo box determining which panel (group of components) the CardLayout
displays. An alternative to using CardLayout is using a tabbed pane, which provides
similar functionality but with a pre-defined GUI.
pane.add(comboBoxPane, BorderLayout.PAGE_START);
pane.add(cards, BorderLayout.CENTER);
}
frame.pack();
frame.setVisible(true);
}
GridBagLayout
JButton button;
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
if (shouldFill) {
//natural height, maximum width
c.fill = GridBagConstraints.HORIZONTAL;
}
c.gridx = 0;
c.gridy = 0;
pane.add(button, c);
GroupLayout
GroupLayout is a layout manager that was developed for use by GUI builder tools,
but it can also be used manually. GroupLayout works with the horizontal and
vertical layouts separately. The layout is defined for each dimension independently.
Consequently, however, each component needs to be defined twice in the layout.
getContentPane().setLayout(layout);
layout.setAutoCreateGaps(true);
layout.setAutoCreateContainerGaps(true);
layout.setHorizontalGroup(layout.createSequentialGroup()
.addComponent(label)
.addGroup(layout.createParallelGroup(LEADING)
.addComponent(textField)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(LEADING)
.addComponent(caseCheckBox)
.addComponent(wholeCheckBox))
.addGroup(layout.createParallelGroup(LEADING)
.addComponent(wrapCheckBox)
.addComponent(backCheckBox))))
.addGroup(layout.createParallelGroup(LEADING)
.addComponent(findButton)
.addComponent(cancelButton))
);
layout.setVerticalGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(BASELINE)
.addComponent(label)
.addComponent(textField)
.addComponent(findButton))
.addGroup(layout.createParallelGroup(LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(BASELINE)
.addComponent(caseCheckBox)
.addComponent(wrapCheckBox))
.addGroup(layout.createParallelGroup(BASELINE)
.addComponent(wholeCheckBox)
.addComponent(backCheckBox)))
.addComponent(cancelButton))
);
setTitle("Find");
pack();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
SpringLayout
//Adjust constraints for the text field so it is at(<label's right edge> + 5, 5).
layout.putConstraint(SpringLayout.WEST, textField, 5, SpringLayout.EAST, label);
layout.putConstraint(SpringLayout.NORTH, textField, 5, SpringLayout.NORTH, →
,→ contentPane);
//Adjust constraints for the content pane: Its right edge should be 5 pixels beyond the text →
,→ field's right
//edge, and its bottom edge should be 5 pixels beyond the bottom edge of the tallest →
,→ component (which we'll
//assume is textField).
layout.putConstraint(SpringLayout.EAST, contentPane, 5, SpringLayout.EAST, textField);
layout.putConstraint(SpringLayout.SOUTH, contentPane, 5, SpringLayout.SOUTH, →
,→ textField);
frame.pack();
frame.setVisible(true);
}
Spacing
Rigid areas have a fixed horizontal and vertical size. A rigid area is a fixed size
filler with vertical and horizontal dimensions. It can be used in either horizontal
or vertical layouts. Create a rigid area by specifying its width and height in pixels
in a Dimension object, which has two parameters, an x distance and a y distance.
Typically the dimension you are not interested in is set to zero.
p.add(Box.createRigidArea(new Dimension(10, 0)));
This creates a rigid area component 10 pixels wide and 0 pixels high and adds it to a
panel.
Struts are fixed either vertically or horizontally. Generally use rigid areas instead of
struts. Create a strut by specifying its size in pixels, and adding it to the panel at the
point you want the space between other components. Use horizontal struts only in
horizontal layouts and vertical struts only in vertical layouts, otherwise there will be
problems. To avoid problems from nested panels, you are generally better off using
a rigid area.
p.add(Box.createHorizontalStrut(10));
For example, to create a new horizontal filler that can get no smaller that 4 pixels,
that prefers to be 16 pixels wide, and that will expand to no more than 32 pixels,
13.2 Java Swing 137
13.2.3 Events
Change in the state of an object is known as event i.e. event describes the change in
state of source. Events are generated as result of user interaction with the graphical
user interface components. For example, clicking on a button, moving the mouse,
entering a character through keyboard, selecting an item from list, scrolling the page
are the activities that causes an event to happen.
Foreground Events Those events caused by the direct interaction of user. They
are generated as consequences of a person interacting with the graphical
components in Graphical User Interface. For example, clicking on a button,
moving the mouse, entering a character through keyboard, selecting an item
from list, scrolling the page,...
Background Events Those events not caused by the direct interaction of end-user
are known as background events. Operating system interrupts, hardware or
software failure, timer expires, an operation completion are the example of
background events.
Event Handling is the mechanism that controls the event and decides what should
happen if an event occurs. This mechanism have the code which is known as event
handler that is executed when an event occurs. Java Uses the Delegation Event
Model to handle the events. This model defines the standard mechanism to generate
and handle the events. Let’s have a brief introduction to this model.
The Delegation Event Model has the following key participants namely:
source The source is an object on which event occurs. Source is responsible for
providing information of the occurred event to its handler. Java provide as
with classes for source object.
listener It is also known as event handler. Listener is responsible for generating
response to an event. From Java implementation point of view, the listener
is also an object. Listener waits until it receives an event. Once the event is
received, the listener processes the event and then returns.
The benefit of this approach is that the user interface logic is completely separated
from the logic that generates the event. The user interface element is able to delegate
the processing of an event to the separate piece of code. In this model, Listener
needs to be registered with the source object so that the listener can receive the
13.2 Java Swing 139
event notification. This is an efficient way of handling the event because the event
notifications are sent only to those listener that want to receive them.
In order to design a listener class we have to develop some listener interfaces. These
Listener interfaces forecast some public abstract callback methods which must be
implemented by the listener class. If you do not implement the predefined interfaces
then your class can not act as a listener class for a source object.
Examples of implementation
Most basic approach In the next example, the frame itself registers with the ‘JBut-
ton’ as a listener, more particularly as an ‘ActionListener’, which is called when
a MouseClickEvent is captured. The callback method is then named public void →
,→ actionPerformed(ActionEvent actionEvent). It is specified by the interface ActionListener →
,→ , that must be implemented to register as an action listener: jButton.addActionListener →
,→ (this);.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
pack();
setVisible(true);
}
public void actionPerformed(ActionEvent actionEvent) {
jLabel.setText("clicked at "+actionEvent.getWhen());
}
static public void main(String args[]) {
new HelloWorldFrame();
}
}
Better approach The next variant is better from a MVC point of view because it
distinguishes view (display) from control (event handling) by creating 2 classes.
−import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
and
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JLabel;
JLabel jLabel;
Best approach Few years ago, Java designers have introduced specific objects for
handling events: the actions. The principle is to extend an action and to inherit its
properties and capabilities. In this way, Java can reuse event handler at different
places. For instance, a same event handler can be bound both to a button and to
a menu item. It can embed an icon displayed both in the button and in the menu.
Obviously, this approach is also MVC compliant.
Events EventObject class is the root class from which all event state objects shall
be derived. All Events are constructed with a reference to the object, the source,
that is logically deemed to be the object upon which the Event in question initially
occurred upon. This class is defined in java.util package.
It contains 2 methods:
Listeners The Event listeners represent the interfaces responsible to handle events.
Java provides various Event listener classes but we will discuss those which are more
frequently used. Every method of an event listener method has a single argument
as an object which is subclass of EventObject class. For example, mouse event
listener methods will accept instance of MouseEvent, where MouseEvent derives
from EventObject.
Adapters Adapters are abstract classes for receiving various events. It is used
to be extended. The methods in these classes are empty: you just have to defined
the method corresponding to the event you want to capture. These classes exists as
convenience for creating listener objects.
Following is the list of commonly used adapters while listening GUI events in
SWING.
Plots can be carried out using Java2D but there is a lot to develop before getting
a beautiful curve or graph. We are going to use JFreeChart. JFreeChart is a free
100% Java chart library that makes it easy for developers to display professional
quality charts. JFreeChart’s extensive feature set includes (see http://www.jfree.org/
jfreechart/):
In order to be able to use JFreeChart, you must install the ‘jar’ files of JFreeChart
in the dependencies of your project available at https://sourceforge.net/projects/
jfreechart/files/. Download ‘jfreechart-1.0.19.zip’ and unzip. Create a ‘lib’ folder
in your eclipse project and drop all the files except ‘jfreechart-1.0.19-swt.jar’ in
the ‘jfreechart-1.0.19/lib’ folder into your own project ‘lib’ folder. Then, select the
project in the ‘Package Explorer’, right click, choose ‘Properties’, then select ‘Java
Build Path’. Select Libraries, then ‘add JARs’ and select all the ‘jar’ files you added
145
146 Chapter 14 Plotting curves into Java
in your project lib folder. JFreeChart can then be called from your project.
Installation and developer guides are available in Chamilo. Demo codes are also
available.
Creating charts with JFreeChart is a three step process. You need to:
// create a dataset...
DefaultPieDataset data = new DefaultPieDataset();
data.setValue("Category 1", 43.2);
data.setValue("Category 2", 27.9);
14.1 Introduction to JFreeChart 147
// create a chart...
JFreeChart chart = ChartFactory.createPieChart(
"Sample Pie Chart",
data,
true, // legend?
true, // tooltips?
false // URLs?
);
Each of the three steps outlined above is described, along with sample code, in the
following paragraphs.
Step one requires us to create a dataset for our chart. This can be done easily using
the DefaultPieDataset class, as follows:
// create a dataset...
DefaultPieDataset dataset = new DefaultPieDataset();
dataset.setValue("Category 1", 43.2);
dataset.setValue("Category 2", 27.9);
dataset.setValue("Category 3", 79.5);
Note that JFreeChart can create pie charts using data from any class that implements
the PieDataset interface. The DefaultPieDataset class (used above) provides a
convenient implementation of this interface, but you are free to develop an alternative
dataset implementation if you want to.
Step two concerns how we will present the dataset created in the previous section.
We need to create a JFreeChart object that can draw a chart using the data from our
pie dataset. We will use the ChartFactory class, as follows:
148 Chapter 14 Plotting curves into Java
// create a chart...
JFreeChart chart = ChartFactory.createPieChart(
"Sample Pie Chart",
dataset,
true, // legend?
true, // tooltips?
false // URLs?
);
Notice how we have passed a reference to the dataset to the factory method.
JFreeChart keeps a reference to this dataset so that it can obtain data later on
when it is drawing the chart.
The chart that we have created uses default settings for most attributes. There are
many ways to customize the appearance of charts created with JFreeChart, but in
this example we will just accept the defaults.
The final step is to display the chart somewhere. JFreeChart is very flexible about
where it draws charts, thanks to its use of the Graphics2D class.
For now, let’s display the chart in a frame on the screen. The ChartFrame class
contains the machinery (a ChartPanel) required to display charts:
// create and display a frame...
ChartFrame frame = new ChartFrame("Test", chart);
frame.pack();
frame.setVisible(true);
14.2 LineChartDemo2
import org.jfree.data.xy.XYDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
return dataset;
}
150 Chapter 14 Plotting curves into Java
return chart;
}
}
14.3 TimeSeriesDemo8 151
14.3 TimeSeriesDemo8
Let’s now focus on another useful example not coming from the developer guide:
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.data.time.Hour;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
public static void main(String[] args) { // be careful: this is not object oriented
DateFormat format = new SimpleDateFormat("yyyy-MM-d HH:mm:ss");
String[] stringDates = {"2015-04-01 00:00:00", "2015-04-01 01:00:00", " →
,→ 2015-04-01 02:00:00"};
double[] value1 = {3,1,2};
double[] value2 = {−1,2,1};
timeSeries1.add(new Hour(dates[i]),value1[i]);
} catch (ParseException e) {
e.printStackTrace();
}
}
For additional examples, refer to the Developer guide and the code examples.
You are going to be more autonomous than before to solve this problem. Just
remember that your codes have to be object oriented. It means that you have
to design the architecture of the code before coding, avoiding sequential solving.
Classes of objects have to be coded in the most general way as possible i.e. as
independent as possible of the other classes for the sake of readability but also for
the sake of re-usability. As a result, your main classes should be almost empty
(usually something like new Class()) and your class files should be small (200 lines
max but smaller is usually better).
155
156 Chapter 15 Problem: occupancy estimators
Tcorridor
office_CO2_concentration
corridor
cupboard
Toffice_for_heater
detected_motions
power_
laptop2
_zone2
office_CO2_concentration
power_ power_
laptop1 laptop3
_zone2 _zone2
outdoor
Toffice
solar_radiation
office
nebulosity
window_opening
door_opening
Tout
window power_zone2
zone2
zone1 door
power_zone1
heater
power_
laptop1
_ zo n e 1
Theater
cupboard
Sensor names appear into green squares. The corresponding measurements covering
the period April, 1st to June, 30th 2015 are given in the zip file ‘occupancy-help.zip’,
in file named ‘office.csv’. Data have been sampled with a 1 hour time resolution.
The comma-separated values (see https://en.wikipedia.org/wiki/Comma-separated_
values) text file format has been chosen because it is easy to read and widespread.
Even LibreOffice and Excel can read it. In subsection 15.2.1, an easy way to read
15.1 Problem Statement 157
A discussion about the pros and cons of the different estimators is requested. Practi-
cal considerations should be taken into account. Note that a communicating power
meter is about 80 euros, a motion detector 120 euros, a contact sensor for door or
window 50 euros and a CO2 sensor about 250 euros.
The code your are going to deliver must comply with the Java naming standard and
be easy to read. It must be objected oriented. Because you are Java beginners, an
example of code architecture is given in 15.2.2.
generated
JFreeChart
time plot
selected
variable
generate
a plot
Figure 15.2 Expected GUI type for visualizing measurements and estimations
Occupancy estimator based on laptop consumption is very easy to do. The con-
sumption of each one of the 4 laptops is measured by a power meter (variable
‘power_laptopX_zoneY’). If the average consumption is greater than the standby
consumption (15W), it is considered that someone is working on the computer.
Estimator based on motion detections is also easy to do. It is considered that the
number of motions detected within a hour is proportional to the number of occupants
in the office. In order to determine the best proportional coefficient, a simple
dichotomy can be done, considering the laptop consumption based estimations as
the actual occupancies. Scale the coefficient to minimize the error between laptop
consumption and motion detection based occupancy estimators. Algorithm is given
in 15.2.3.
The CO2 based estimator relies on an air mass balance. Let’s call Q out , the renewal
air flow exchanged from indoor and outdoor. It can be decomposed into Q out =
0 window where Q 0 stands for air infiltration, Q window for the average
Q out + ζwindowQ out out out
constant renewal air flow going through the windows when it is opened and ζwindow ,
the window opening. It is worth 0 when it is always closed and 1 when it is
always opened during a considered time period. An intermediate value represents
the fraction of the period the window was opened. This value corresponds to the
variable ‘window_opening’ of the CSV file.
In the same way, the renewable air flow through the door is given by: Q corridor =
0 door . ζ
Q corridor + ζdoorQ corridor door corresponds to the variable ‘door_opening’ whose
values are coming from a contact sensor.
Obviously, Q out and Q corridor are time-dependent because of openings ζwindow and
ζdoor .
• Γ, the CO2 concentration and Q out ≈ 395ppm, the outdoor average CO2
concentration
• V , the room volume i.e. 55m 3 for the office
• S breath , the average CO2 production per occupant. It is estimated at 4ppm.m 3 /s
• n , the number of occupants in the office
Considering average values over a time period of T s = 3600 seconds, the differential
equation can be solved to get a recurrent equation ( X k means average value of X
during period [kT s , (k + 1)T s )):
with:
Q out,k +Q corridor,k
Ts
• αk = e − V
(1−αk )Q out,k
• βout,k = Q out,k +Q corridor,k
(1−α )Q
• βcorridor,k = Q out,k k+Q corridor
coridor,k
,k
0 window ,Q 0 door
Q out ,Q out corridor ,Q corridor are constant values that should be determined using
a simple simulated annealing optimization algorithm given in 15.2.4. The problem
is to find the best values, considering the laptop consumption based estimations as
the actual occupancies. Following initial values are proposed:
0 25
• Q out = 3600 m 3 /s
0 25
• Q corridor = 3600 m 3 /s
• window = 150 m 3 /s
Q out 3600
door 150
• Q corridor = 3600 m 3 /s
15.2 Clues
Here is a simple example (it cannot be used in this way because it is not object
oriented):
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
try {
bufferedReader = new BufferedReader(new FileReader(fileName));
String line;
while ((line = bufferedReader.readLine()) != null) {
String[] tokens = line.split(",");
for(String token: tokens)
System.out.print(token + ", ");
System.out.println();
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("Done");
}
}
15.2 Clues 161
occupancy.data::DataContainer
~timeStrings: ArrayList<String>
occupancy.gui::MainFrame ~orderedVariableNames: ArrayList<String>
~dataContainer: DataContainer ~data: Hashtable<String, ArrayList<Double»
~plotFactory: PlotFactory ~numberOfSamples = 0: int
~variableCheckBoxes: JCheckBox[] +DataContainer(String csvFileName): ctor
-plotButton: JButton +getNumberOfSamples(): int
~plotCounter = 0: int +getNumberOfVariables(): int
1
+MainFrame(DataContainer dataContainer): ctor +getTimeStrings(): String[]
-initComponents(): void +getDates(): Date[]
+actionPerformed(ActionEvent e): void +getAvailableVariables(): String[]
+getData(String variableName): Double[]
occupancy.gui::PlotFactory +addData(String variableName, double[] values): void
~timeSeriesContainer: Hashtable<String,TimeSeries> +addData(String variableName, Double[] values): void
~dataContainer: DataContainer +toString(): String
1 +main(String[] args): void
+ PlotFactory(DataContainer csvDataReader): ctor
+ getPlot(String[] variableNames): JPanel
occupancy.fitters::DichotomicScaler
~referenceData: Double[]
~scaledData: Double[]
~bestScale: double
~numberOfIterations: int occupancy.data::DataContainerWithProcessing
~precision: double
+DataContainerWithProcessing(String csvFileName): ctor
+DichotomicScaler(Double[] referenceData, Double[] scaledData, double minScale, double maxScale, int maxIterations): ctor +main(String[] args): void
+getNumberOfIterations(): int
+getBestScale(): double
+getPrecision(): double
+toString(): String
-getError(double scale): double
+main(String[] args): void
occupancy.fitters::SimulatedAnnealing
~model: Model
~measurements: Double[]
~bestParameterValues: double[]
~bestError: double
~initialParameterValues: double[]
~initialError: double
~iteration, maxIterations: int
~radius: double
+SimulatedAnnealing(Model model, double[] initialParameterValues, Double[] measurements, int maxIterations, double radius): ctor
-temperature(): double
-neighborhood(double[] parameterValues): double[]
-error(double[] parameterValues): double
+error(): double
+parameterValues(): double[]
+toString(): String
occupancy.fitters.models::CO2OfficeModel
~doorOpening, windowOpening, officeCO2Concentration, corridorCO2Concentration, estimatedOccupation: Double[] 1
~roomVolume = 55: double
~co2BreathProduction = 4: double «interface»
~samplePeriod = 3600: double occupancy.fitters.models::Model
~outdoorCO2concentration = 395: double
+simulate(double[] parameters): Double[]
+CO2OfficeModel(Double[] doorOpening, Double[] windowOpening, Double[] officeCO2Concentration, Double[] corridorCO2Concentration): ctor
+simulate(double[] airFlows): Double[]
where r ∈ (0, 1) is the radius defining the neighborhood as a fraction of the current
variable value x ki , k is the current iteration and random(0, 1) is a random value
between 0 and 1.
Then, if the new variable values lead to a better f (X k+1 ) result, it can be kept for a
next random search and forget otherwise.
But simulated annealing is more than that. Always trying to improve a result can lead
to local minimal. To get around this problem, a diversification mechanism is added.
It means that sometimes, even if the result is worse, it can be kept, expecting latter
better results. A temperature function is used to allow more worse results at start than
at the final iterations. Therefore, the temperature must decrease with the iteration
number. It must also decrease if the current best value for f (X ) is decreasing. We
suggest the following simple temperature function T (k, f r ) = β f r kmax −k
k max where β is
a freely tunable parameter that impacts the convergence (β = 1 is a good start). Note
that f r is the current reference function for stepping and f ∗ is the current minimum
function value.