Programming Paradigms

158
EINSTEIN COLLEGE OF ENGINEERING Sir.C.V.Raman Nagar, Tirunelveli-12 CS55 PROGRAMMING PARADIGMS E - NOTES Unit No Title I Object-oriented Programming Fundamentals II Object-oriented Programming Inheritance III Event-Driven Programming IV Generic Programming V Concurrent Programming

description

Anna University Chennai Based Notes

Transcript of Programming Paradigms

Page 1: Programming Paradigms

EINSTEIN COLLEGE OF ENGINEERING

Sir.C.V.Raman Nagar, Tirunelveli-12

CS55 PROGRAMMING PARADIGMS

E - NOTES

Unit No Title

I Object-oriented Programming – Fundamentals

II Object-oriented Programming – Inheritance

III Event-Driven Programming

IV Generic Programming

V Concurrent Programming

Page 2: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 2 of 158

© Einstein College of Engineering

UNIT I

OBJECT-ORIENTED PROGRAMMING – FUNDAMENTALS

1) Review of OOP Concepts

a) Encapsulation

b) Inheritance

c) Polymorphism

2) Objects and Classes in Java

3) Language Basics

a) Comments

b) Data Types

c) Variables

d) Statements

e) Functions

4) Defining Classes

5) Methods

6) Access Specifiers

7) Static Members

8) Constructors

a) Parameterized Constructors

b) this Keyword

c) Garbage Collection

9) Finalize Method

10) Arrays

a) One Dimensional Arrays

b) Multi Dimensional Arrays

11) Strings

12) Packages

13) JavaDOC Comments

14) References

1. Review OOP concepts

The object oriented paradigm is built on the foundation laid by the structured

programming concepts.

The fundamental change in OOP is that a program is designed around the data

being operated upon rather upon the operations themselves.

Data and its functions are encapsulated into a single entity.

OOP facilitates creating reusable code that can eventually save a lot of work.

Polymorphism permits to create multiple definitions for functions.

Inheritance permits to derive new classes from old ones.

Benefits of object oriented programming

Data security is enforced.

Inheritance saves time.

User defined data types can be easily constructed.

Page 3: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 3 of 158

© Einstein College of Engineering

Inheritance emphasizes inventions of new data types.

Large complexity in the software development can be easily managed.

Java History

Java is a general-purpose object oriented programming language developed by Sun

Microsystems of USA in 1991. Originally called ―oak‖ by James Gosling, one of the inventors if

the language. This goal had a strong impact on the development team to make the language

simple, portable, highly reliable and powerful language. Java also adds some new features.

While C++ is a superset of C. Java is neither a superset nor a subset of C or C++.

Basic concepts of Object oriented programming

All Java programs are object oriented. Computer programs consist of two elements: code

and data.

In process oriented model code acting on data. Procedural languages such as C employ

this model.

To manage increasing complexity object-oriented Programming approach was conceived.

Object-oriented programming organizes a program around its data (that is, objects) and a

set of well-defined interfaces to that data. An object-oriented program can be

characterized as data controlling access to code.

Abstraction

An essential element of object-oriented programming is abstraction. Abstraction refers to

the act of representing essential features without including the background details or

explanations.

For example, people do not think of a car as a set of tens of thousands of individual parts.

They think of it as a well-defined object with its own unique behavior. This abstraction allows

people to use a car to drive to the grocery store without being overwhelmed by the complexity of

the parts that form the car. They can ignore the details of how the engine, transmission, and

braking systems work. Instead they are free to utilize the object as a whole.

The Three OOP Principles

All object-oriented programming languages provide mechanisms to implement the

object-oriented model. They are

Encapsulation

Inheritance

Polymorphism

C++

C

Java

Page 4: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 4 of 158

© Einstein College of Engineering

a) Encapsulation

Encapsulation is the mechanism that binds together code and the data it manipulates, and

keeps both safe from outside interference and misuse.

For example, shifting gears does not turn on the headlights in car, because it encapsulates

the information about all process.

In Java the basis of encapsulation is the class. A class defines the structure and behavior

(data and code) that will be shared by a set of objects. For this reason, objects are sometimes

referred to as instances of a class. Thus, a class is a logical construct and an object has physical

reality.

b) Inheritance

Inheritance is the process by which one object acquires the properties of another object.

This is important because it supports the concept of hierarchical classification. For example

The bird 'robin ' is a part of the class 'flying bird' which is again a part of the class 'bird'.

The concept of inheritance provides the idea of reusability.

c) Polymorphism

Polymorphism means the ability to take more than one form. Subclasses of a class can

define their own unique behaviors and yet share some of the same functionality of the parent

class.

2. Class and Object

Class defines a new data type. Once defined, this new type can be used to create objects

of that type. Thus, a class is a template for an object, and an object is an instance of a class.

Class

A class is a blueprint or prototype from which objects are created. The entire set of data

and code of an object can be made of a user defined data type with the help of a class. We can

create any number of objects for the same class.

Shape

Draw()

Circle Object

Draw()

Box Object

Draw()

Triangle Object

Draw()

Bird Attributes:

Feathers

Lay eggs

Flying bird

Attributes:

-----------

----------

Non flying bird

Attributes:

-----------

-----------

Page 5: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 5 of 158

© Einstein College of Engineering

For example the construction of building requires a plan. Without plan we can't construct

building. Here plan acts as class. Building acts as object. Using the same plan we can build any

number of buildings. In the same way we can create any number of objects for the same class.

Class tells the object’s state and behavior. Basically class tells what the object should have.

Object

Object is an instance of class. Object is real world entity which has state, identity and

behavior. It may represent a person, a place, a bank account, a table of data or any item that the

program has to handle.

JAVA Program structure

A file containing Java source code is considered a compilation unit. Such a compilation

unit contains a set of classes and, optionally, a package definition to group related classes

together. Classes contain data and method members that specify the state and behavior of the

objects in your program. Java programs come in two flavors:

1. Standalone applications that have no initial context such as a pre-existing main window

2. Applets for WWW programming

Execution begins when you launch the java virtual machine and tell it to find a particular class.

After finding the class, java executes the enclosed main() method with signature:

public static void main(String[] args)

{

………...

}

Program Execution

Create a source code file using a text editor. The source code is then compiled using the

java compiler javac. Each java program is converted into one or more class files. The content of

the class file is a set of instructions called bytecode to be executed by Java Virtual Machine

(JVM).Java introduces bytecode to create platform independent program. JVM is an interpreter

for bytecode which accepts java bytecode and produces result.

Java Source Code

Java Compiler (Javac)

Java Byte Code (.class)

Java Virtual Machine

Java program Output

Page 6: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 6 of 158

© Einstein College of Engineering

3. Language Basics

a) Comments

Java comments make your code easy to understand, modify and use. Java supports three

different types of comment styles.

1.Everything between initial slash –asterisk and ending asterisk-slash is ignored by the java

compiler.(/*……*/)

2.Double slash (//)mark is ignored by java compiler.

3.Everything between initial slash – asterisk - asterisk and ending asterisk-slash is ignored

by the java compiler and another program called JAVADOC.EXE that ships with the

JDK uses these comments to construct HTML documentation files that describe your

packages, classes and methods as well as all the variables used. (/**……*/)

b) Data Types

Java defines eight simple (or elemental) types of data: byte, short, int, long, char, float,

double, and boolean. These can be put in four groups:

Integers - This group includes byte, short, int, and long, which are for whole valued

signed numbers.

Floating -point numbers- This group includes float and double, which represent numbers

with fractional precision.

Characters - This group includes char, which represents symbols in a character set, like

letters and numbers.

Boolean - This group includes boolean, which is a special type for representing true/false

values.

c) Variables

Variables are locations in memory in which values can be stored. They have a name, a

type, and a value. Before you can use a variable, you have to declare it. After it is declared, you

can then assign values to it.

Java actually has three kinds of variables: instance variables, class variables, and local

variables.

Instance variables are used to define attributes or the state for a particular object.

Class variables are similar to instance variables, except their values apply to all

that class’s instances (and to the class itself) rather than having different values

for each object.

Local variables are declared and used inside method definitions, for example, for

index counters in loops, as temporary variables, or to hold values that you need

only inside the method definition itself.

Although all three kinds of variables are declared in much the same ways, class and

instance variables are accessed and assigned in slightly different ways from local variables.

Scope

Page 7: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 7 of 158

© Einstein College of Engineering

Java has no global variables.

All variables must be declared within either a class scope or a function scope.

Declaring Variables

For variable declarations, Java syntax is similar to C and C++ syntax. For native types,

the syntax may be summarized as follows:

One word type name.

A list of variable names, separated by commas.

An optional initializer following each variable name.

Terminated by semicolon.

The following are examples of variable declarations:

This line of Java code declares a 32-bit integer variable named i:

int i;

This line declares two 32-bit integer variables named i and j:

int i , j;

This line declares i and j as above and initializes them:

int i=3, j=4;

d) Statements

Java, like C, is an expression-based language. Expressions must always appear in the

context of statements. A statement consists of an expression followed by a terminating semicolon

(;).

Statements can be made up of zero or more expressions, provided that their combination

makes syntactic sense. Expressions (except for the return value of void methods) have a value

and a type. A terminating semicolon (e.g., 27;) turns it into a legal statement even though it does

not do anything useful. A simple statement consists of an expression and a semicolon. The

semicolon is a required terminator.

4. Defining Class

The class is at the core of Java. It is the logical construct upon which the entire Java

language is built because it defines the shape and nature of an object. As such, the class forms

the basis for object-oriented programming in Java. The entire set of data and code of an object

can be made of a user defined data type with the help of a class. Thus, a class is a template for an

object, and an object is an instance of a class.

The General Form of a Class

The class contains data and the code that operates on that data. A class is declared by use

of the class keyword. The data, or variables, defined within a class are called instance variables.

The code is contained within methods. Collectively, the methods and variables defined within a

class are called members of the class. The general form of a class definition is shown here:

class classname

{

type instance-variable1;

type instance-variable2;

Page 8: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 8 of 158

© Einstein College of Engineering

// ...

type instance-variableN;

type methodname1(parameter-list){

// body of method

}

type methodname2(parameter-list) {

// body of method

}

// ...

type methodnameN(parameter-list) {

// body of method

}

}

Here is a class called Box that defines three instance variables: width, height, and depth.

Currently, Box does not contain any methods (but some will be added soon).

class Box

{

double width;

double height;

double depth;

}

Instantiating a class

Class declaration only creates a template; it does not create an actual object. To create a

Box object, you will use a statement like the following:

Box mybox = new Box(); // create a Box object called mybox

The new operator allocates space for the new object, calls a class constructor and returns

a reference to the object.

It should be noted that the class and its constructor have the same name.

After this statement executes, mybox will be an instance of Box. Each time you create an

instance of a class, you are creating an object that contains its own copy of each instance variable

defined by the class. Thus, every Box object will contain its own copies of the instance variables

width, height, and depth. To access these variables, you will use the dot (.) operator. The dot

operator links the name of the object with the name of an instance variable. For example, to

assign the width variable of mybox the value 100, you would use the following statement:

mybox.width = 100;

This statement tells the compiler to assign the copy of width that is contained within the

mybox object the value of 100.

5. Methods

Classes usually consist of two things: instance variables and methods.

This is the general form of a method:

Type name (parameter-list)

Page 9: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 9 of 158

© Einstein College of Engineering

{

// body of method

}

Type specifies the type of data returned by the method. This can be any valid type,

including class types that you create. If the method does not return a value, its return type must

be void.

The name of the method is specified by name. This can be any legal identifier other than

those already used by other items within the current scope.

The parameter-list is a sequence of type and identifier pairs separated by commas.

Parameters are essentially variables that receive the value of the arguments passed to the method

when it is called. If the method has no parameters, then the parameter list will be empty.

Methods that have a return type other than void return a value to the calling routine using

the following form of the return statement:

return value;

Here, value is the value returned.

Program includes a method inside the box class.

class Box

{

double width;

double height;

double depth;

// display volume of a box

void volume() {

System.out.print("Volume is ");

System.out.println(width * height * depth);

}

}

class BoxDemo3

{

public static void main(String args[]) {

Box mybox1 = new Box();

Box mybox2 = new Box();

// assign values to mybox1's instance variables

mybox1.width = 10;

mybox1.height = 20;

mybox1.depth = 15;

/* assign different values to mybox2's instance variables */

mybox2.width = 3;

mybox2.height = 6;

mybox2.depth = 9;

// display volume of first box

mybox1.volume();

// display volume of second box

Page 10: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 10 of 158

© Einstein College of Engineering

mybox2.volume();

}

}

This program generates the following output.

THE JAVA LANGUAGE

Volume is 3000.0

Volume is 162.0

The mybox1.volume() invokes the volume( ) method on mybox1. That is, it calls

volume( ) relative to the mybox1 object, using the object’s name followed by the dot operator.

Thus, the call to mybox1.volume( ) displays the volume of the box defined by mybox1, and the

call to mybox2.volume( ) displays the volume of the box defined by mybox2. Each time

volume( ) is invoked, it displays the volume for the specified box.

6. Access specifiers

Encapsulation provides another important attribute: access control. Through

encapsulation, you can control what parts of a program can access the members of a class. By

controlling access, you can prevent misuse.

How a member can be accessed is determined by the access specifier that modifies its

declaration. Java supplies a rich set of access specifiers. Some aspects of access control are

related mostly to inheritance or packages. (A package is, essentially, a grouping of classes.)

Java’s access specifiers are

Public

Private

Protected

default access level.

Public

When a member of a class is modified by the public specifier, then that member can be

accessed by any other code. So main( ) has always been preceded by the public specifier.

Classes can be declared public. A public class is accessible by any other Java class. A

class that is not declared public has package access, which means that only classes within the

same package may access it. Class members labeled public are accessible to all other classes.

Private

When a member of a class is specified as private, then that member can only be accessed

by other members of its class.

Class members can be declared public or private to enforce proper encapsulation. Certain

data elements or methods that are necessary for the class’s internal behavior should be protected

from access by outside classes. These should be declared private. A class member that has been

declared as private will remain private to its class. It is not accessible by any code outside its

class, including subclasses.

Protected

Any member that is declared protected is accessible only by a class that is derived from

the current class or is in the same package as the containing class.

Page 11: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 11 of 158

© Einstein College of Engineering

default access level

When no access specifier is used, then by default the member of a class is public within

its own package, but cannot be accessed outside of its package.

7. Static Members

Static Variables

If you define a field as static, then there is only one such field per class. In contrast, each

object has its own copy of all instance fields. For example, let's suppose we want to assign a

unique identification number to each employee. We add an instance field id and a static field

nextId to the Employee class:

class Employee

{

. . .

private int id;

private static int nextId = 1;

}

Now, every employee object has its own id field, but there is only one nextId field that is shared

among all instances of the class. Let's put it another way. If there are one thousand objects of the

Employee class, then there are one thousand instance fields id, one for each object. But there is a

single static field nextId. Even if there are no employee objects, the static field nextId is present.

It belongs to the class, not to any individual object.

Constants

Static variables are quite rare. However, static constants are more common. For example,

the Math class defines a static constant:

public class Math

{

. . .

public static final double PI = 3.14159265358979323846;

Page 12: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 12 of 158

© Einstein College of Engineering

. . .

}

You can access this constant in your programs as Math.PI. If the keyword static had been

omitted, then PI would have been an instance field of the Math class. That is, you would need an

object of the Math class to access PI, and every object would have its own copy of PI. Another

static constant that you have used many times is System.out. It is declared in the System class as:

public class System

{

. . .

public static final PrintStream out = . . .;

. . .

}

As we mentioned several times, it is never a good idea to have public fields because everyone

can modify them. However, public constants (that is, final fields) are ok. Since out has been

declared as final, you cannot reassign another print stream to it:

out = new PrintStream(. . .); // ERROR--out is final

Static Methods

Static methods are methods that do not operate on objects. For example, the pow method

of the Math class is a static method. The expression:

Math.pow(x, y)

Computes the power xy. It does not use any Math object to carry out its task. In other words, it

has no implicit parameter. In other words, you can think of static methods as methods that don't

have a this parameter. Because static methods don't operate on objects, you cannot access

instance fields from a static method. But static methods can access the static fields in their class.

Here is an example of such a static method:

public static int getNextId()

{

return nextId; // returns static field

}

To call this method, you supply the name of the class:

int n = Employee.getNextId();

Could you have omitted the keyword static for this method? Yes, but then you would need to

have an object reference of type Employee to invoke the method. You use static methods in two

situations:

1. When a method doesn't need to access the object state because all needed

parameters are supplied as explicit parameters (example: Math.pow)

2. When a method only needs to access static fields of the class (example:

Employee.getNextId)

8. Constructors

A constructor is a special method whose purpose is to construct and initialize objects.

Constructors always have the same name as the class name.

The constructor is automatically called immediately after the object is created, before the

new operator completes.

Box mybox1 = new Box();

Page 13: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 13 of 158

© Einstein College of Engineering

new Box( ) is calling the Box( ) constructor. When you do not explicitly define a

constructor for a class, then Java creates a default constructor for the class. The default

constructor automatically initializes all instance variables to zero.

There is an important difference between constructors and other methods: A constructor

can only be called in conjunction with the new operator. You can't apply a constructor to an

existing object to reset the instance fields.

Features of constructor

A constructor has the same name as the class.

A class can have more than one constructor.

A constructor may take zero, one, or more parameters.

A constructor has no return value.

A constructor is always called with the new operator.

a) Parameterized Constructors

Add parameters to the constructor.

class Box

{

double width;

double height;

double depth;

// This is the constructor for Box.

Box(double w, double h, double d) {

width = w;

height = h;

depth = d;

}

// compute and return volume

double volume() {

return width * height * depth;

}

}

class BoxDemo7

{

public static void main(String args[]) {

// declare, allocate, and initialize Box objects

Box mybox1 = new Box(10, 20, 15);

double vol;

// get volume of first box

vol = mybox1.volume();

System.out.println("Volume is " + vol);

}

}

The output from this program is shown here:

Volume is 3000.0

Page 14: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 14 of 158

© Einstein College of Engineering

Object is initialized as specified in the parameters to its constructor.

Box mybox1 = new Box(10, 20, 15);

The values 10, 20, and 15 are passed to the Box( ) constructor when new creates the object.

Thus, mybox1’s copy of width, height, and depth will contain the values 10, 20, and 15,

respectively.

b) “this” Keyword

this can be used inside any method to refer to the current object. this keyword has two

meanings:

to denote a reference to the implicit parameter

to call another constructor of the same class.

// A redundant use of this.

Box(double w, double h, double d)

{

this.width = w;

this.height = h;

this.depth = d;

}

c) Garbage Collection

The purpose of garbage collection is to identify and discard objects that are no longer

needed by a program so that their resources can be reclaimed and reused. A Java object is subject

to garbage collection when it becomes unreachable to the program in which it is used.

9. Finalizer method

Finalizer methods are like the opposite of constructor methods; whereas a constructor

method is used to initialize an object, finalizer methods are called just before the object is

garbage collected and its memory reclaimed. To create a finalizer method, include a method with

the following signature in your class definition:

void finalize() {

...

}

Inside the body of that finalize() method, include any cleaning up you want to do for that

object. Before you start using finalizer methods extensively in your Java programs, however, be

aware that finalizer methods have several very important restrictions. First of all, the finalizer

method is not guaranteed to be called until the object’s memory is actually reclaimed, which may

be some time after you’ve removed all references to that object.

However, calling finalize() does not trigger an object to be garbage-collected. Only

removing all references to an object will cause it to be marked for deleting, and even then, Java

may or may not call the finalize() method itself—regardless of whether or not you’ve already

called it. Finalizer methods are best used for optimizing the removal of an object—for example,

by removing references to other objects, by cleaning up things that object may have touched, or

for other optional behaviors that may make it easier for that object to be removed. In most cases,

you may not need to use finalize() at all.

Page 15: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 15 of 158

© Einstein College of Engineering

Some object-oriented programming languages, notably C++, have explicit destructor

methods for any cleanup code that may be needed when an object is no longer used. The most

common activity in a destructor is reclaiming the memory set aside for objects. Since Java does

automatic garbage collection, manual memory reclamation is not needed, and Java does not

support destructors. Of course, some objects utilize a resource other than memory, such as a file

or a handle to another object that uses system resources. In this case, it is important that the

resource be reclaimed and recycled when it is no longer needed. You can add a finalize method

to any class. The finalize method will be called before the garbage collector sweeps away the

object. In practice, do not rely on the finalize method for recycling any resources that are in short

supply—you simply cannot know when this method will be called. If a resource needs to be

closed as soon as you have finished using it, you need to manage it manually. Add a dispose

method that you call to clean up what needs cleaning. Just as importantly, if a class you use has a

dispose method, you will want to call it when you are done with the object. In particular, if your

class has an instance field that has a dispose method, provide a dispose method that disposes of

the instance fields.

10. Arrays

An array is a group of like-typed variables that are referred to by a common name. Arrays

of any type can be created and may have one or more dimensions. A specific element in an array

is accessed by its index. Arrays offer a convenient means of grouping related information.

Arrays are ordered collections of identical objects that can be accessed via an index. Java

arrays have their own behavior that is encapsulated into their definition when the compiler

creates them. Since arrays are objects, array variables behave like class-type variables. It is

important to distinguish between the array variable and the array instance to which it refers.

Declaring an array only declares the array variable.

To instantiate the array, the new operator must be used with the [] operator to

enclose the array size. The array size can be any integer expression.

The following code declares an array variable and initializes it to null:

char data[] = null;

Array Constants

The declaration of an array must include its type, but not its size. An array initializer is

either a new expression that evaluates to the correct array type, or a list of initial element values

enclosed in { }. The following array constant provides initial values for its elements:

int[] int_array = {1, 3, 4, 15, 0};

Using Arrays

Array elements can be accessed using an index in square brackets [n], where the index

must be an integer. Arrays start with index number 0, not 1. The index can be thought of as an

offset from the beginning of the array. The index may not be less than zero or greater than the

declared size. If the array is declared size n, the index must be in the range 0 to n-1. Any attempt

to index an array with an illegal value will cause an exception to be thrown. All arrays have a

data field called length that indicates its size.

int ia[] = new int[100];

for (int i = 0; i < ia.length; i++)

{

Page 16: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 16 of 158

© Einstein College of Engineering

ia[i] = i * i;

}

Copying Array Elements

The library method System.arraycopy() is useful for copying a number of elements from

one array to another. The method can be used on any type of array and is declared as follows:

public static void arraycopy (Object src, int src_position, Object dst, int dst_position, int

length)

The method copies elements from the given source array, beginning at the specified

position to the destination array at the specified position. It copies the number of elements

specified by the length argument. The destination array must already be allocated. Any type of

array may be copied. If range exceeds bounds of either array, a run-time error results.

Arrays in Java are in between a class and a data type although they are implemented as a

class internally by Java.

char data[] = null;

char[] data = null;

int length = 60;

char[] data = new char [length];

a) One-Dimensional Arrays

A one-dimensional array is a list of like-typed variables. Array is created by following steps.

1. Create an array variable of the desired type. The general form of a one dimensional array

declaration is

type var-name[ ];

2. Allocate memory for array.

Method1: The general form of new as it applies to one-dimensional arrays appears as

follows:

array-var = new type[size];

The elements in the array allocated by new will automatically be initialized to zero.

Method2: Arrays can be initialized when they are declared. The process is much the

same as that used to initialize the simple types. An array initializer is a list of comma-

separated expressions surrounded by curly braces. The commas separate the values of the

array elements. The array will automatically be created large enough to hold the number

of elements you specify in the array initializer. There is no need to use new. For example,

to store the number of days in each month, the following code creates an initialized array

of integers:

// An improved version of the previous program.

class AutoArray {

public static void main(String args[]) {

int month_days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31,30, 31 };

System.out.println("April has " + month_days[3] + " days.");

}

}

Page 17: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 17 of 158

© Einstein College of Engineering

b) Multidimensional Arrays

In Java, multidimensional arrays are actually arrays of arrays. These, as you might

expect, look and act like regular multidimensional arrays. However, as you will see, there are a

couple of subtle differences. To declare a multidimensional array variable, specify each

additional index using another set of square brackets. For example, the following declares a two-

dimensional array variable called twoD.

int twoD[][] = new int[4][5];

This allocates a 4 by 5 array and assigns it to twoD. Internally this matrix is implemented as an

array of arrays of int.

There is a second form that may be used to declare an array:

type[ ] var-name;

Here, the square brackets follow the type specifier, and not the name of the array variable. For

example, the following two declarations are equivalent:

int al[] = new int[3];

int[] a2 = new int[3];

The following declarations are also equivalent

11. String objects

The Java String class (java.lang.String) is a class of object that represents a character

array of arbitrary length. While this external class can be used to handle string objects, Java

integrates internal, built-in strings into the language.

Page 18: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 18 of 158

© Einstein College of Engineering

An important attribute of the String class is that once a string object is constructed, its

value cannot change (note that it is the value of an object that cannot change, not that of a string

variable, which is just a reference to a string object). All String data members are private, and no

string method modifies the string’s value.

String Methods Although a string represents an array, standard array syntax cannot be used to inquire into

it. These are detailed in the below Table.

String Comparison

String comparison methods listed in below Table.

Page 19: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 19 of 158

© Einstein College of Engineering

String Searching

The String class also provides methods that search a string for the occurrence of a single

character or substring. These return the index of the matching substring or character if found, or -

1 if not found.

int indexOf (char ch)

int indexOf (char ch, int begin)

int lastIndexOf (char ch)

int lastIndexOf (char ch, int fromIndex)

int indexOf (String str)

int indexOf (String str, int begin)

int lastIndexOf (String str)

int lastIndexOf (String str, int fromIndex)

The following example shows the usage of these functions:

if (s1.indexOf (’:’) >= 0)

{

}

String suffix =

s1.substring (s1.lastIndexOf (’.’));

int spaceCount = 0;

int index = s1.indexOf (’ ’);

while (index >= 0)

{

++spaceCount;

index = s1.indexOf (’ ’, index + 1);

Page 20: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 20 of 158

© Einstein College of Engineering

}

int index = s1.indexOf (―that‖);

String Concatenation

The String class provides a method for concatenating two strings:

String concat (String otherString)

The + and += String operators are more commonly used: The Java compiler recognizes the + and

+= operators as String operators. For each + expression, the compiler generates calls to methods

that carry out the concatentation. For each += expression, the compiler generates calls to

methods that carry out the concatenation and assignment.

Converting Objects To Strings

The String + operator accepts a non-string operand, provided the other operand is a

string. The action of the + operator on non-string operands is to convert the non-string to a string,

then to do the concatenation. Operands of native types are converted to string by formatting their

values. Operands of class types are converted to a string by the method toString() that is defined

for all classes. Any object or value can be converted to a string by explicitly using one of the

static valueOf() methods defined in class String:

String str = String.valueOf (obj);

If the argument to valueOf() is of class type, then valueOf() calls that object’s toString() method.

Any class can define its own toString() method, or just rely on the default. The output produced

by toString() is suitable for debugging and diagnostics. It is not meant to be an elaborate text

representation of the object, nor is it meant to be parsed. These conversion rules also apply to the

right-hand side of the String += operator.

Converting Strings To Numbers

Methods from the various wrapper classes, such as Integer and Double, can be used to

convert numerical strings to numbers.

The wrapper classes contain static methods such as parseInt() which convert a string to its

own internal data type.

12. Packages

Java allows you to group classes in a collection called a package. A class can use all

classes from its own package and all public classes from other packages.

You can import a specific class or the whole package. You place import statements at the

top of your source files (but below any package statements). For example, you can import all

classes in the java.util package with the statement:

import java.util.*;

Adding a class into a package

To place classes inside a package, you must put the name of the package at the top of

your source file, before the code that defines the classes in the package. For example,

package com.horstmann.corejava;

public class Employee

Page 21: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 21 of 158

© Einstein College of Engineering

{

. . .

}

Package scope

Public features can be used by any class.

Private features can only be used by the class that defines them.

If you don't specify either public or private, then the feature (that is, the class, method, or

variable) can be accessed by all methods in the same package.

13. Documentation Comments

The Java SDK contains a very useful tool, called javadoc, that generates HTML

documentation from your source files. If you add comments that start with the special delimiter

/** to your source code, you too can produce professional-looking documentation easily. This is

a very nice scheme because it lets you keep your code and documentation in one place. If you

put your documentation into a separate file, then you probably know that the code and comments

tend to diverge over time. But since the documentation comments are in the same file as the

source code, it is an easy matter to update both and run javadoc again.

How to Insert Comments

The javadoc utility extracts information for the following items:

• Packages

• Public classes and interfaces

• Public and protected methods

• Public and protected fields

You can (and should) supply a comment for each of these features. Each comment is

placed immediately above the feature it describes. A comment starts with a /** and ends with a

*/. Each /** . . . */ documentation comment contains free-form text followed by tags. A tag starts

with an @, such as @author or @param. The first sentence of the free-form text should be a

summary statement. The javadoc utility automatically generates summary pages that extract

these sentences. In the free-form text, you can use HTML modifiers such as <em>...</em> for

emphasis, <code>...</code> for a monospaced ―typewriter‖ font, <strong>...</strong> for strong

emphasis, and even <img ...> to include an image. You should, however, stay away from

heading <h1> or rules <hr> since they can interfere with the formatting of the document.

Class Comments

The class comment must be placed after any import statements, directly before the class

definition. Here is an example of a class comment:

/**

A <code>Card</code> object represents a playing card, such as "Queen of Hearts". A

card has a suit (Diamond, Heart, Spade or Club) and a value (1 = Ace, 2 . . . 10, 11 =

Jack, 12 = Queen, 13 = King).

*/

public class Card

Page 22: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 22 of 158

© Einstein College of Engineering

{

. . .

}

Method Comments

Each method comment must immediately precede the method that it describes. In

addition to the general-purpose tags, you can use the following tags:

@param variable description

This tag adds an entry to the ―parameters‖ section of the current method. The description can

span multiple lines and can use HTML tags. All @param tags for one method must be kept

together.

@return description

This tag adds a ―returns‖ section to the current method. The description can span multiple lines

and can use HTML tags.

@throws class description

Field Comments

You only need to document public fields—generally that means static constants. For

example,

/**

The "Hearts" card suit

*/

public static final int HEARTS = 1;

General Comments

The following tags can be used in class documentation comments.

@author name

This tag makes an ―author‖ entry. You can have multiple @author tags, one for each author.

@version text

How to Extract Comments

Here, docDirectory is the name of the directory where you want the HTML files to go. Follow

these steps:

1. Change to the directory that contains the source files you want to document. If you have

nested packages to document, such as com.horstmann.corejava, you must be in the

directory that contains the subdirectory com. (This is the directory that contains the

overview.html file, if you supplied one.)

2. Run the command javadoc -d docDirectory nameOfPackage for a single package. Or run

javadoc -d docDirectory nameOfPackage1 nameOfPackage2... to document multiple

packages. If your files are in the default package, then run javadoc -d docDirectory *.java

instead. If you omit the -d docDirectory option, then the HTML files are extracted to the

current directory. That can get messy, and we don't recommend it. The javadoc program

can be fine-tuned by numerous command-line options. For example, you can use the -

author and -version options to include the @author and @version tags in the

documentation. (By default, they are omitted.)

Page 23: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 23 of 158

© Einstein College of Engineering

14. References

1. Cay S. Horstmann and Gary Cornell, ―Core Java: Volume I – Fundamentals‖, Eighth

Edition, Sun Microsystems Press, 2008.

2. Herbert Schildt ―JAVA2:The complete reference‖ Fifth Edition, McGraw-Hill/Osborne.

3. http://java.sun.com

Page 24: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 24 of 158

© Einstein College of Engineering

UNIT II OBJECT-ORIENTED PROGRAMMING – INHERITANCE

1. Inheritance

1.1. Member Access And Inheritance

1.2. Super Keyword

2. Class Hierarchy

3. Polymorphism

3.1. Overridden Methods

3.2. Overloaded Methods

4. Dynamic Binding

4.1. Dynamic Binding

4.2. Static Binding

5. Final Keyword

6. Abstract Classes

6.1. Abstract Methods

7. The Object Class

8. Reflection

9. Interfaces

10. Object Cloning

11. Inner Classes

12. Proxies

Inheritance

Inheritance is a process of making a new class that derives from an existing class. The

existing class is called the superclass, base class, or parent class. The new class is called the

subclass, derived class, or child class.

Therefore, a subclass is a specialized version of a superclass. It inherits all of the

instance variables and methods defined by the superclass and add its own, unique elements.

Subclasses of a class can define their own unique behaviors and yet share some of the

same functionality of the parent class.

To inherit a class, you simply incorporate the definition of one class into another by using

the extends keyword. The general form of a class declaration that inherits a superclass is shown

here:

class subclass-name extends superclass-name

{

// body of class

}

You can only specify one superclass for any subclass that you create. Java does not

support the inheritance of multiple superclasses into a single subclass.

Protected features in Java are visible to all subclasses as well as all other classes in the

same package.

Page 25: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 25 of 158

© Einstein College of Engineering

Member Access and Inheritance

A class member that has been declared as private will remain private to its class. It is not

accessible by any code outside its class, including subclasses.

Super keyword

Super is a special keyword that directs the compiler to invoke the superclass method.

super has two general forms.

to invoke a superclass constructor.

to invoke a superclass members(variables &methods). invoke a superclass

constructor

Invoke superclass constructor:

A subclass can call a constructor method defined by its superclass by use of the following

form of super:

super(parameter-list);

Here, parameter-list specifies any parameters needed by the constructor in the superclass.

super( ) must always be the first statement executed inside a subclass constructor.

The compiler implicitly calls the base class’s no-parameter constructor or default

constructor.

If the superclass has parameterized constructor and the subclass constructor does not call

superclass constructor explicitly, then the Java compiler reports an error.

Invoke superclass members:

Super always refers to the superclass of the subclass in which it is used. This usage has

the following general form:

super.member;

Here, member can be either a method or an instance variable. This second form of super

is most applicable to situations in which member names of a subclass hide members by

the same name in the superclass.

If a parent class contains a finalize() method, it must be called explicitly by the derived

class’s finalize() method.

super.finalize();

When Constructors are Called

Constructors are called in order of derivation, from superclass to subclass. Because a

superclass has no knowledge of any subclass, any initialization it needs to perform is separate

from and possibly prerequisite to any initialization performed by the subclass. Therefore, it must

be executed first.

CLASS HIERARCHY

The collection of all classes extending from a common superclass is called an inheritance

hierarchy; the path from a particular class to its ancestors in the inheritance hierarchy is its

inheritance chain.

Simple class hierarchies consist of only a superclass and a subclass. But you can build

hierarchies that contain as many layers of inheritance as you like.

Page 26: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 26 of 158

© Einstein College of Engineering

For example, create three classes called A, B, and C, C can be a subclass of B, which is a

subclass of A. When this type of situation occurs, each subclass inherits all of the traits found in

all of its superclasses. In this case, C inherits all aspects of B and A.

POLYMORPHISM

Polymorphism means the ability of methods to behave differently based on the kinds of

input.

Types of polymorphism

Method Overloading

Method overriding

Overloaded methods

Overloaded methods are methods with the same name but different method signature

(either a different number of parameters or different types in the parameter list).

public class Test{

public static void main(String arg[]){

A a=new A();

a.display();

B b=new B();

b.display("Hello");

}

}

class A{

void display(){

System.out.println("Hai");

}

}

class B extends A{

void display(String s){

System.out.println(s);

}

}

Output

Hai

Hello

Overridden methods

The process of a subclass redefining a method contained in the superclass (with the same

parameter types) is called overriding the method.

Overridden methods allow Java to support run time polymorphism. Whenever a method

is called for a subclass object, the compiler calls the overriding version instead of the superclass

version. The version of the method defined by the superclass will be hidden.

Page 27: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 27 of 158

© Einstein College of Engineering

Call to an overridden method is resolved at run time, rather than compile time. Superclass

reference variable can refer to a subclass object. Java uses this fact to resolve calls to overridden

methods at run time. When an overridden method is called through a superclass reference, Java

determines which version of that method to execute based upon the type of the object being

referred to at the time the call occurs. This determination is made at run time.

class Dispatch {

public static void main(String args[]) {

A a = new A(); // object of type A

B b = new B(); // object of type B

C c = new C(); // object of type C

A r; // obtain a reference of type A

r = a; // r refers to an A object

r.callme(); // calls A's version of callme

r = b; // r refers to a B object

r.callme(); // calls B's version of callme

r = c; // r refers to a C object

r.callme(); // calls C's version of callme

}

}

When you override a method, the subclass method must be at least as visible as the

superclass method.

In particular, if the superclass method is public, then the subclass method must also be

declared as public. It is a common error to accidentally omit the public specifier for the subclass

method. Then the compiler complains that you try to supply a weaker access privilege.

public class Test1{

public static void main(String arg[]){

A a=new A();

a.display();

B b=new B();

b.display();

}

}

class A{

protected void display(){

System.out.println("Hai");

}

}

class B extends A{

public void display(){

System.out.println("Hello");

}

}

Page 28: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 28 of 158

© Einstein College of Engineering

Output

Hai

Hello

Methods labeled final, private, or static are not subject to dynamic lookup because they

may not be overridden. private methods are simply not inherited because they would never be

callable anyway. static methods apply to a particular class’s static data and thus make no sense in

a derivation. final methods are those designated as not-overridable for reasons of complexity or

safety.

public class Test1{

public static void main(String arg[]){

A a1=new A();

a1.display();

A a2=new B();

a2.display();

}

}

class A{

void display(){

System.out.println("Hai");

}

}

class B extends A{

void display(){

System.out.println("Hello");

}

}

Output

Hai

Hello

DYNAMIC BINDING

Selecting the appropriate method at runtime is called dynamic binding. Dynamic Binding

refers to the case where compiler is not able to resolve the call and the binding is done at runtime

only.

All the instance methods in Java follow dynamic binding.

Dynamic binding has a very important property:

It makes programs extensible without recompiling the existing code.

Suppose a new class is added, and there is the possibility that the variable refers to an

object of that class. The code contains the method invoking statement of that class need not be

recompiled. The method is called automatically if the object happens to refer to the class.

Page 29: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 29 of 158

© Einstein College of Engineering

Dynamic Binding or Late Binding It is important to understand what happens when a method call is applied to an object. Here

are the details:

1. The compiler looks at the declared type of the object and the method name. The compiler

knows all possible candidates for the method to be called.

2. Next, the compiler determines the types of the parameters that are supplied in the method

call. If among all the methods called fun there is a unique method whose parameter types

are a best match for the supplied parameters, then that method is chosen to be called. This

process is called overloading resolution.

3. If the method is private, static, final, or a constructor, then the compiler knows exactly

which method to call.

4. When the program runs and uses dynamic binding to call a method, then the virtual

machine must call the version of the method that is appropriate for the actual type of the

object. The virtual machine precomputes a method table for each class that lists all

method signatures and the actual methods to be called. When a method is actually called,

the virtual machine simply makes a table lookup. This is used to reduce the time

consumed by searching process.

STATIC BINDING OR EARLY BINDING

If the compiler can resolve the binding at the compile time only then such a binding is

called Static Binding or Early Binding. Resolve the call and binding at compile time.

If the method is private, static, final, or a constructor, then the compiler knows exactly

which method to call. This is called static binding.

All the member variables in Java follow static binding.

All the static method calls are resolved at compile time itself.

All private methods are resolved at compile time itself.

FINAL KEYWORD

The keyword final has three uses.

Used to create the equivalent of a named constant.

Used to Prevent Overriding

Used to Prevent Inheritance

Named constant

A variable can be declared as final. Doing so prevents its contents from being modified.

This means that you must initialize a final variable when it is declared. For example:

final int constant = 1;

Variables declared as final do not occupy memory on a per-instance basis. Thus, a final variable

is essentially a constant. The keyword final can also be applied to methods, but its meaning is

substantially different than when it is applied to variables. Attempts to change it will generate

either a compile-time error or an exception.

Page 30: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 30 of 158

© Einstein College of Engineering

Using final to Prevent Overriding

Methods declared as final cannot be overridden.The syntax is simple, just put the

keyword final after the access specifier and before the return type like this:

class A

{

final void meth() {

System.out.println("This is a final method.");

}

}

class B extends A

{

void meth() { // ERROR! Can't override.

System.out.println("Illegal!");

}

}

Normally, Java resolves calls to methods dynamically, at run time. This is called late

binding. However, since final methods cannot be overridden, a call to one can be resolved at

compile time. This is called early binding.

Using final to Prevent Inheritance

Declaring a class as final implicitly declares all of its methods as final. So it prevents a

class from being inherited. To do this, precede the class declaration with final.

It is illegal to declare a class as both abstract and final since an abstract class is

incomplete by itself and relies upon its subclasses to provide complete implementations.

Here is an example of a final class:

final class A

{

// ...

}

// The following class is illegal.

class B extends A

{ // ERROR! Can't subclass A

// ...

}

ABSTRACT CLASSES

An abstract class is a type of class that is not allowed to be instantiated. The only reason

it exists is to be extended. Abstract classes contain methods and variables common to all the

subclasses, but the abstract class itself is of a type that will not be used directly. Even a single

abstract method requires that a class be marked abstract.

Page 31: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 31 of 158

© Einstein College of Engineering

To declare a class abstract, you simply use the abstract keyword in front of the class

keyword at the beginning of the class declaration.

abstract class classname

{

public abstract type methodname();

// no implementation required

……..

}

There can be no objects of an abstract class. That is, an abstract class cannot be directly

instantiated with the new operator. Such objects would be useless, because an abstract class is

not fully defined.

Also, you cannot declare abstract constructors, or abstract static methods. Any subclass

of an abstract class must either implement all of the abstract methods in the superclass, or be

itself declared abstract.

Here is a simple example of a class with an abstract method, followed by a class which

implements that method:

// A Simple demonstration of abstract.

abstract class A

{

abstract void callme();// concrete methods are still allowed in abstract classes

void callmetoo() {

System.out.println("This is a concrete method.");

}

}

class B extends A

{

void callme() {

System.out.println("B's implementation of callme.");

}

}

class AbstractDemo

{

public static void main(String args[]) {

B b = new B();

b.callme();

b.callmetoo();

}

}

That is, sometimes you will want to create a superclass that only defines a generalized

form that will be shared by all of its subclasses, leaving it to each subclass to fill in the details.

Such a class determines the nature of the methods that the subclasses must implement. You can

require that certain methods be overridden by subclasses by specifying the abstract type

Page 32: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 32 of 158

© Einstein College of Engineering

modifier. These methods are sometimes referred to as subclasser responsibility because they

have no implementation specified in the superclass.

Thus, a subclass must override them—it cannot simply use the version defined in the

superclass.

Abstract methods

An abstract method is a method declaration that contains no functional code. The reason for

using an abstract method is to ensure that subclasses of this class will include an implementation

of this method. Any concrete class (that is, a class that is not abstract, and therefore capable of

being instantiated) must implement all abstract methods it has inherited.

Methods declared with the keyword abstract define a skeleton for a method but do not

implement it. This requires a derived class to provide the code for this class.

A class with one or more abstract methods must itself be declared abstract and cannot be

instantiated. It can only be used for derivation.

To declare an abstract method, use this general form:

abstract type name(parameter-list);

UAGE

But while an abstract class can define both abstract and nonabstract methods, an interface can

have only abstract methods. Interface as being similar to an abstract class with no instance fields.

Interfaces

An interface is a collection of method definitions (without implementations) and constant values.

Defining an Interface

This is the general form of an interface:

An interface must be declared with the keyword interface.

access interface name {

return-type method-name(parameter-list);

type final-varname = value;

}

It is also possible to declare that an interface is protected so that it can only be

implemented by classes in a particular package. However this is very unusual.

Rules for interface constants. They must always be

public

static

final

Once the value has been assigned, the value can never be modified. The assignment happens in

the interface itself (where the constant is declared), so the implementing class can access it and

use it, but as a read-only value.

To make a class implement an interface, have to carry out two steps:

Page 33: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 33 of 158

© Einstein College of Engineering

Declare that your class intends to implement the given interface.

Supply definitions for all methods in the interface.

To declare that a class implements an interface, use the implements keyword:

access class classname implements interfacename

{

//definitions for all methods in the interface

}

Implementation classes must adhere to the same rules for method implementation as a class

extending an abstract class. In order to be a legal implementation class, a nonabstract

implementation class must do the following:

When you implement an interface method, method must be declared as public. (The

access level can be more accessible than that of the overridden method.)

Type signature of the implementing method must match exactly the type signature

specified in the interface definition. (The argument list and return type must exactly

match that of the overridden method.)

A class can implement one or more interfaces.

Partial Implementations: If a class includes an interface but does not fully implement the

methods defined by that interface, then that class must be declared as abstract.

Inner Classes

An inner class is a class that is defined inside another class.

Inner classes let you make one class a member of another class. Just as classes have

member variables and methods, a class can also have member classes.

Regular Inner Class

You define an inner class within the curly braces of the outer class, as follows:

class MyOuter {

class MyInner { }

}

And if you compile it, %javac MyOuter.java , you’ll end up with two class files:

MyOuter.class

MyOuter$MyInner.class

The inner class is still, in the end, a separate class, so a class file is generated. But the

inner class file isn’t accessible to you in the usual way. The only way you can access the inner

class is through a live instance of the outer class.

Page 34: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 34 of 158

© Einstein College of Engineering

Instantiating an Inner Class

To instantiate an instance of an inner class, you must have an instance of the outer class.

An inner class instance can never stand alone without a direct relationship with a specific

instance of the outer class.

Instantiating an Inner Class from Within Code in the Outer Class

From inside the outer class instance code, use the inner class name in the normal way:

class MyOuter {

private int x = 7;

MyInner mi = new MyInner();

class MyInner {

public void seeOuter() { System.out.println("Outer x is " + x);

}

}

public static void main(String arg[]){

MyOuter mo=new MyOuter();

mo.mi.seeOuter();

}

}

Output:

Outer x is 7

Method-Local Inner Classes

A method-local inner class is defined within a method of the enclosing class.

class MyOuter {

void inner()

{

final int c=9;

class MyInner {

int x=5;

public void display() {

System.out.println("Inner x is " + x);

System.out.println("Inner c is " + c);

}

}

MyInner mi = new MyInner();

mi.display();

}

public static void main(String arg[]){

MyOuter mo = new MyOuter();

mo.inner();

}

}

Page 35: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 35 of 158

© Einstein College of Engineering

Output: x is 5

c is 9

Anonymous Inner Classes

Anonymous inner classes have no name, and their type must be either a subclass of the

named type or an implementer of the named interface.

An anonymous inner class is always created as part of a statement, so the syntax will end

the class definition with a curly brace, followed by a closing parenthesis to end the

method call, followed by a semicolon to end the statement: });

An anonymous inner class can extend one subclass, or implement one interface. It cannot

both extend a class and implement an interface, nor can it implement more than one

interface.

public class Test{ public static void main(String arg[]){

B b=new B();

b.ob.display();

}

}

class A{

void display(){

System.out.println("Hai");

}

}

class B { A ob=new A(){

void display(){

System.out.println("Hello");

}

};

}

Output: Hello

And if you compile it, %javac Test.java , you’ll end up with two class files:

A.class

B.class

B$1.class

Test.class

Static Nested Classes

Static nested classes are inner classes marked with the static modifier.

Technically, a static nested class is not an inner class, but instead is considered a top-

level nested class.

Page 36: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 36 of 158

© Einstein College of Engineering

Because the nested class is static, it does not share any special relationship with an

instance of the outer class. In fact, you don’t need an instance of the outer class to

instantiate a static nested class.

Instantiating a static nested class requires using both the outer and nested class names as

follows:

BigOuter.Nested n = new BigOuter.Nested();

A static nested class cannot access nonstatic members of the outer class, since it does not

have an implicit reference to any outer instance (in other words, the nested class instance

does not get an outer this reference).

public class Test{ public static void main(String arg[]){

A.B b=new A.B();

b.display();

}}

class A {

static class B {

int m=5;

void display(){

System.out.println("m="+m);

}

}

}

Output: m=5

The Object Class - The Cosmic Superclass

The Object class sits at the top of the class hierarchy tree in the Java development

environment. The Object class is the ultimate ancestor

Every class in Java extends Object class.

The Object class defines the basic state and behavior that all objects must have, such as

the ability to compare with another object, to convert to a string, to wait on a condition variable,

to notify other objects that a condition variable has changed, and to return the object's class.

Object defines the following methods, which means that they are available in every

object.

Reflection

Reflection is the ability of the software to analyze itself at runtime.

Reflection is provided by the java.lang.reflect package and elements in class.

This mechanism is helpful to tool builders, not application programmers.

The reflection mechanism is extremely used to

Page 37: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 37 of 158

© Einstein College of Engineering

Analyze the capabilities of classes at run time

Inspect objects at run time

Implement generic array manipulation code

Analyze the capabilities of classes at run time - Examine the structure of class.

Return an array of public fields, methods

and constructors that the class supports. This

includes all public members of super class.

Return an array of fields, methods and

constructors that are declared in the class.

This includes private, protected and public

members of class but not members of super

class.

Methods (Field, Method & Constructor):

String getName() – return the name of the item.

int getModifiers()- return an integer, that describes the modifier.

Field

Provide information about fields.

The getFields method returns an array containing Field objects for the public fields.

The getDeclaredField method returns an array of Field objects for all fields. The methods

return an array of length 0 if there are no such fields.

import java.lang.reflect.*;

Java.lang.reflect

Field Method Constructor

Java.lang.Class

Field[] getFields()

Method[] getMethods()

Constructor[] getConstructors()

Field[] getDeclaredFields()

Method[] getDeclaredMethods() Constructor[] getDeclaredConstructors()

Page 38: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 38 of 158

© Einstein College of Engineering

class Test{

public int var1;

private int var2;

protected int var3;

int var4;

}

public class FieldDemo{

public static void main(String args[])throws Exception{

Class c=Class.forName("Test");

Field f[]=c.getFields();

Field fdec[]=c.getDeclaredFields();

System.out.println("public Fields:");

for(int i=0;i<f.length;i++)

System.out.println(f[i]);

System.out.println("All Fields:");

for(int i=0;i<fdec.length;i++)

System.out.println(fdec[i]);

}

}

Output:

public Fields:

public int Test.var1

All Fields:

public int Test.var1

private int Test.var2

protected int Test.var3

int Test.var4

Method

Provides information about method

The getMethods() method return an array containing Method objects that give you all the

public methods.

The getDeclaredMethods () return all methods of the class or interface. This includes

those inherited from classes or interfaces above it in the inheritance chain.

import java.lang.reflect.*;

class Test{

public void method1()

{}

protected void method2()

{}

private void method3()

{}

void method4()

{}

}

Page 39: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 39 of 158

© Einstein College of Engineering

public class MethodDemo{

public static void main(String args[])throws Exception{

Class c=Class.forName("Test");

Method m[]=c.getMethods();

Method mdec[]=c.getDeclaredMethods();

System.out.println("public Methods of class Test & its Super class:");

for(int i=0;i<m.length;i++)

System.out.println(m[i].getName());

System.out.println("All Methods:");

for(int i=0;i<mdec.length;i++)

System.out.println(mdec[i].getName());

}

}

Output:

public Methods of class Test & its Super

class:

method1

hashCode

getClass

wait

equals

notify

notifyAll

toString

All Methods:

method1

method2

method3

method4

Page 40: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 40 of 158

© Einstein College of Engineering

Constructor

Provide information about constructors

getConstructors () method return an array containing Constructor objects that give you all

the public constructors

getDeclaredConstructors () method return all constructors of the class represented by the

Class object.

Using Reflection to Analyze Objects at Run Time

Look at the contents of the data fields. It is easy to look at the contents of a specific field

of an object whose name and type are known when you write a program. But reflection lets you

look at fields of objects that were not known at compile time.

f.set(obj, value) sets the field represented by f of the object obj to the new value.

f.get(obj) returns an object whose value is the current value of the field of obj.

import java.lang.reflect.*;

class A{

public int var1,var2;

A(int i, int j){

var1=i;

var2=j;

}

}

public class ConstructorDemo {

public static void main(String args[]) throws Exception{

A obj=new A(10,20);

System.out.println("Before \n var1= "+obj.var1);

Field f1 = obj.getClass().getField("var1");

int v1 = f1.getInt(obj) + 1;

f1.setInt(obj, v1);

System.out.println("After \n var1= "+v1);

System.out.println("Before \n var2= "+obj.var2);

Field f2 = obj.getClass().getField("var2");

f2.set(obj,21);

System.out.println("After \n var2= "+f2.get(obj));

}

}

Output:

Before var1= 10

After

var1= 11

Before var2= 20

After

Page 41: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 41 of 158

© Einstein College of Engineering

var2= 21

Using Reflection to implement generic array manipulation code

The Array class in the java.lang.reflect package allows you to create arrays dynamically.

First the given array can be converted to an Object[] array. newInstance() method of Array class,

constructs a new array.

Object newarray= Array.newInstance(ComponentType, newlength)

newInstance() method needs two parameters

Component Type of new array

To get component type

1. Get the class object using getClass() method.

2. Confirm that it is really an array using isArray().

3. Use getComponentType method of class Class, to find the right type for the array.

Length of new array

Length is obtained by getLength() method. It returns the length of any array(method is

static method, Array.getLengh(array name)).

import java.lang.reflect.*;

public class TestArrayRef {

static Object arrayGrow(Object a){

Class cl = a.getClass();

if (!cl.isArray()) return null;

Class componentType = cl.getComponentType();

int length = Array.getLength(a);

int newLength = length + 10;

Object newArray = Array.newInstance(componentType,newLength);

System.arraycopy(a, 0, newArray, 0, length);

return newArray;

}

public static void main(String args[]) throws Exception{

int arr[]=new int[10];

System.out.println(arr.length);

arr = (int[])arrayGrow(arr);

System.out.println(arr.length);

}

}

Output:

10

20

Object cloning

Page 42: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 42 of 158

© Einstein College of Engineering

A clone of an object is a new object that has the same state as the original but a different

identity. You can modify the clone without affecting the original.

When you make a copy of a variable, the original and the copy are references to the same object.

This means a change to either variable also affects the other.

If you want to make a clone of any class then the class must

implement the Cloneable interface, and

Redefine the clone method with the public access modifier.

import java.util.*;

class Test implements Cloneable{

int a=10;

public void display(){

System.out.println("a="+a);

}

public Object clone(){

try{

Test cloned = (Test)super.clone();

return cloned;

}

catch(CloneNotSupportedException e){

return null;

}

}

}

public class CloneDemo{

public static void main(String arg[]){

Test original=new Test();

original.a=20;

Test copy=(Test)original.clone();

copy.a=80;

original.display();

copy.display();

}

}

Output:

a=20

a=80

Proxy

Proxy used to create new classes at runtime that implement a given set of interfaces. The

proxy class can create brand-new classes at runtime.

Page 43: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 43 of 158

© Einstein College of Engineering

The proxy class can create brand-new classes at runtime. Such a proxy class implements

the interfaces that you specify. In particular, the proxy class has the following methods:

• All methods required by the specified interfaces;

• All methods defined in the Object class (toString, equals, and so on).

To create a proxy object, you use the newProxyInstance method of the Proxy class. The method has

three parameters:

1. A class loader. As part of the Java security model, it is possible to use different

class loaders for system classes, classes that are downloaded from the Internet,

and so on.

2. An array of Class objects, one for each interface to be implemented.

3. An invocation handler.

Proxies can be used for many purposes, such as:

• Routing method calls to remote servers;

• Associating user interface events with actions in a running program;

• Tracing method calls for debugging purposes.

Page 44: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 44 of 158

© Einstein College of Engineering

Unit III Event-Driven Programming

Graphics programming

Frame

Frame is a top-level window that has a title bar, menu bar, borders, and resizing corners. By

default, a frame has a size of 0 × 0 pixels and it is not visible.

Frames are examples of containers. It can contain other user interface components such as

buttons and text fields.

Class hierarchy for Frame

Component & Window class Methods

java.awt.Component

void setVisible(boolean b) - shows or hides the component depending on whether b is

true or false.

void setSize(int width, int height) - resizes the component to the specified width and

height.

void setBounds(int x, int y, int width, int height) - moves and resizes this component. The

location of the top-left corner is given by x and y, and the new size is given by the width

and height parameters.

void setBackground(java.awt.Color) – set Background color to the window.

void setForeground(java.awt.Color)- set Foreground color to the window.

void repaint() - causes a repaint of the component ―as soon as possible.‖

Component

Frame

Container

Window

Java.awt

Page 45: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 45 of 158

© Einstein College of Engineering

java.awt.Window

void setTitle(String s) - sets the text in the title bar for the frame to the string s.

Frame’s constructors:

Frame( ) - creates a standard window that does not contain a title.

Frame(String title) - creates a window with the title specified by title

Methods of Frame class:

void setSize(int newWidth, int newHeight) - method is used to set the dimensions of the

window. The dimensions are specified in terms of pixels.

void setVisible(boolean visibleFlag)- The component is visible if the argument to this

method is true. Otherwise, it is hidden.

void setTitle(String newTitle)- change the title in a frame window.

Creating a Frame Window

Method 1: In main() method

Create an instance of a Frame class.

Frame f=new Frame(―frame name‖);

Set the frame size

f.setSize(500,500);

Make the frame visible

f.setVisible(true);

Example:

The following java program creates a frame with the dimension as 600 x 400 and makes it

visible in the screen. Import java.awt package because Frame class is available in that package.

import java.awt.*;

public class Demo{

public static void main(String arg[]){

Frame f=new Frame("Demo");

f.setSize(600,400);

f.setVisible(true);

}

}

Out Put:

Page 46: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 46 of 158

© Einstein College of Engineering

Method :2

Create a subclass of Frame.

In the Subclass constructor

Change the frame title by calling superclass [Frame] constructor using super(String)

method call.

Set the size of the window explicitly by calling the setSize( ) method.

Make the frame visible by calling setVisible() method.

In main() method

Create an instance of subclass.

Example:

The following java program creates a frame with the dimension as 600 x 400 and makes it

visible in the screen. Import java.awt package because Frame class is available in that package.

import java.awt.*;

public class Demo extends Frame{

Demo(String s){

super(s);

setSize(600,400);

setVisible(true);

}

public static void main(String arg[]){

Demo ob=new Demo("Demo");

}

}

Out Put:

Working with 2D shapes

Graphics: java.awt.Graphics

The Graphics class is part of the java.awt package. The Graphics class defines a number of

drawing functions. Each shape can be drawn edge-only or filled. Objects are drawn and filled in

the currently selected graphics color, which is black by default. When a graphics object is drawn

that exceeds the dimensions of the window, output is automatically clipped.

Java Coordinate System

Java’s coordinate system has the origin (0, 0) in the top left corner. Positive x values are to the

Page 47: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 47 of 158

© Einstein College of Engineering

right, and positive y values are down. Coordinate units are measured in pixels (picture element).

All pixel values are integers; there are no partial or fractional pixels.

X coordinate: Horizontal distance moving right from the left of the screen.

Y coordinate: Vertical distance moving from top to bottom of the screen.

The Graphics class provides a set of simple built-in graphics primitives for drawing, including

lines, rectangles, polygons, ovals, and arcs.

Lines

To draw straight lines, use the drawLine method. drawLine takes four arguments: the x and y

coordinates of the starting point and the x and y coordinates of the ending point.

void drawLine(int startX, int startY, int endX, int endY) - displays a line in the current

drawing color that begins at startX,startY and ends at endX,endY.

Example: Demo.java

import java.awt.*;

public class Demo extends Frame{

Demo(String s){

super(s);

setSize(100,100);

setVisible(true);

}

public void paint(Graphics g) {

g.drawLine(10,10,60,60);

}

public static void main(String arg[]){

Demo ob=new Demo("Line Demo");

}

}

Output:

Page 48: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 48 of 158

© Einstein College of Engineering

Rectangles

The Java graphics primitives provide two kinds of rectangles: Plain rectangles and Rounded

rectangles(which are rectangles with rounded corners).

void drawRect(int x, int y, int width, int height)

void fillRect(int x, int y, int width, int height)

void drawRoundRect(int x, int y, int width, int height, int xDiam, int yDiam)

void fillRoundRect(int x, int y, int width, int height, int xDiam, int yDiam)

A rounded rectangle has rounded corners. The upper-left corner of the rectangle is at x, y. The

dimensions of the rectangle are specified by width and height. The diameter of the rounding arc

along the X axis is specified by xDiam. The diameter of the rounding arc along the Y axis is

specified by yDiam.

Example: Demo.java

import java.awt.*;

public class Demo extends Frame{

Demo(String s){

super(s);

setSize(500,500);

setVisible(true);

}

public void paint(Graphics g) {

g.drawRect(100,100,60,60);

g.fillRect(250,100,60,60);

g.drawRoundRect(100,250,60,60,10,10);

g.fillRoundRect(250,250,60,60,20,20);

}

public static void main(String arg[]){

Demo ob=new Demo("Line Demo");

}

}

Output:

Page 49: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 49 of 158

© Einstein College of Engineering

Polygons

Polygons are shapes with an unlimited number of sides. Set of x and y coordinates are needed to

draw a polygon, and the drawing method starts at one, draws a line to the second, then a line to

the third, and so on.

void drawPolygon(int x[ ], int y[ ], int numPoints)

void fillPolygon(int x[ ], int y[ ], int numPoints)

x[]- An array of integers representing x coordinates

y[]- An array of integers representing y coordinates

numPoints- An integer for the total number of points

Example: Demo.java

import java.awt.*;

public class Demo extends Frame{

public void paint(Graphics g) {

int x1[] = { 39,94,97,112,53,58,26 };

int y1[] = { 133,174,136,170,208,180,206 };

g.drawPolygon(x1,y1,7);

int x2[] = { 139,194,197,212,153,158,126 };

int y2[] = { 133,174,136,170,208,180,206 };

g.fillPolygon(x2,y2,7);

}

public static void main(String arg[]){

Demo ob=new Demo("Polygon Demo");

}

}

Output:

Page 50: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 50 of 158

© Einstein College of Engineering

Ovals

Use ovals to draw ellipses or circles.

void drawOval(int top, int left, int width, int height)

void fillOval(int top, int left, int width, int height)

Page 51: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 51 of 158

© Einstein College of Engineering

Example:Demo.java

import java.awt.*;

public class Demo extends Frame{

Demo(String s){

super(s);

setSize(300,300);

setVisible(true);

}

public void paint(Graphics g) {

g.drawOval(20,120,70,70);

g.fillOval(140,120,100,70);

}

public static void main(String arg[]){

Demo ob=new Demo("Oval Demo");

}

}

Arc

The arc is drawn from startAngle through the angular distance specified by arkAngle. Angles are

specified in degrees. The arc is drawn counterclockwise if sweepAngle is positive, and clockwise

if arkAngle is negative.

void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle)

void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle)

x=0

y=0

width=100

height=100

Startangle=90

arcAngle=180

Page 52: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 52 of 158

© Einstein College of Engineering

Page 53: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 53 of 158

© Einstein College of Engineering

Example:Demo.java

import java.awt.*;

public class Demo extends Frame{

Demo(String s){

super(s);

setSize(300,300);

setVisible(true);

}

public void paint(Graphics g) {

g.drawArc(20,120,90,90,90,180);

g.fillArc(120,120,90,90,90,180);

g.drawArc(170,120,90,90,90,-180);

}

public static void main(String arg[]){

Demo ob=new Demo("Arc Demo");

}

}

Output:

Drawing Text

Draw text on the screen using the method drawstring().

void drawstring(String text, int x, int y)- draws a string in the current font and color.

import java.awt.*;

public class Demo extends Frame{

Demo(String s){

super(s);

setSize(200,200);

setVisible(true);

}

public void paint(Graphics g) {

g.drawString("welcome", 75, 100);

}

public static void main(String arg[]){

Demo ob=new Demo("Text Demo");

}

}

Page 54: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 54 of 158

© Einstein College of Engineering

Page 55: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 55 of 158

© Einstein College of Engineering

Using color, fonts, and images

Color: java.awt.Color

Color class creates a solid RGB color with the specified red, green, blue value in the range (0-

255). Java’s abstract color model uses 24-bit color. The values of each color must be in the range

(0- 255).

Constructor:

Color(int red, int green, int blue) - create new color object for any combination of red, green,

and blue.

Java.awt.Color class used to create new color object for any combination of red, green, and blue,

and it predefines a few color constants. They are stored in class variables,

Color.white (255,255,255)

Color.black (0,0,0)

Color.lightGray (192,192,192)

Color.gray (128,128,128)

Color.darkGray (64,64,64)

Color.red (255,0,0)

Color.green(0,255,0)

Color.blue (0,0,255)

Color.yellow (255,255,0)

Color.magenta (255,0,255)

Color.cyan( 0,255,255)

Color.pink (255,175,175)

Color.orange (255,200,0)

java.awt.Component

Component class defines setBackground() and setForeground() methods for setting background

and foreground colors to the window. Since Frame is a subclass of Component class it can use

these methods.

void setBackground(java.awt.Color) – set Background color to the window.

void setForeground(java.awt.Color)- set Foreground color to the window.

java.awt.Graphics

setColor() method used to set the current color for the graphics context which is defined in

Graphics class.

void setColor(java.awt.Color)

Page 56: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 56 of 158

© Einstein College of Engineering

Example: The following program for designing a frame with square boxes, each of which has a

randomly chosen color in it.

import java.awt.*;

public class Demo extends Frame{

Demo(String s){

super(s);setSize(200,200);setVisible(true);

setBackground(Color.black);

}

public void paint(Graphics g) {

int rval, gval, bval;

for (int j = 30; j < 200-30; j += 30)

for (int i = 30; i < 200-30; i+= 30){

rval = (int)Math.floor(Math.random() * 256);

gval = (int)Math.floor(Math.random() * 256);

bval = (int)Math.floor(Math.random() * 256);

g.setColor(new Color(rval,gval,bval));

g.fillRect(i,j,25,25);

}

}

public static void main(String arg[]){

Demo ob=new Demo("Color Demo");

}

}

Output:

Font: java.awt.Font

Font class is used to create Font Objects to set the font for drawing text, labels, textField, buttons

etc..,

One Font constructor has this general form:

Font(String fontName, int fontStyle, int pointSize)

Here, fontName specifies the name of the desired font. The style of the font is specified by

fontStyle. It may consist of one or more of thesethree constants: Font.PLAIN, Font.BOLD, and

Font.ITALIC. The size, in points, of the font is specified by pointSize. point size may or may

not be the height of the characters.

To draw characters in a font, first create an object of the class Font. then specify the font name,

the font style, and the point size.

Page 57: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 57 of 158

© Einstein College of Engineering

Methods

Java.awt.Graphics

void setFont(Font fontObj)- selects a font for the graphics context. That font will be used

for subsequent text drawing operations.

Font getFont( )- get the current font by calling getFont( ).

Java.awt.Component

void setFont(Font fontObj)

Example: The following program that draws several lines of text in different fonts.

import java.awt.*;

public class Demo extends Frame{

Demo(String s){

super(s);setSize(200,200);setVisible(true);

}

public void paint(Graphics g) {

Font f = new Font("TimesRoman", Font.PLAIN, 18);

Font fb = new Font("TimesRoman", Font.BOLD, 18);

Font fi = new Font("TimesRoman", Font.ITALIC, 18);

Font fbi = new Font("TimesRoman", Font.BOLD + Font.ITALIC, 18);

g.setFont(f);

g.drawString("This is a plain font", 10, 50);

g.setFont(fb);

g.drawString("This is a bold font", 10, 75);

g.setFont(fi);

g.drawString("This is an italic font", 10, 100);

g.setFont(fbi);

g.drawString("This is a bold italic font", 10, 125);

}

public static void main(String arg[]){

Demo ob=new Demo("Font Demo");

}

}

Output:

Image: java.awt.Image

Image class provides support for displaying and manipulation of graphical images. Image is

simply a rectangular graphical object.

Page 58: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 58 of 158

© Einstein College of Engineering

Java provides the functions for reading images that are stored in local files and display them on

graphics object.

Step1: Loading an image

java.awt.Toolkit

Toolkit getDefaultToolkit()- returns the default toolkit.

Image getImage(String filename) - returns an image that will read its pixel data from a

file.

Toolkit object can only read GIF and JPEG files.

Step2: displaying an image

java.awt.Graphics

boolean drawImage(Image img, int x, int y, ImageObserver observer)- draws a scaled image.

boolean drawImage(Image img, int x, int y, int width, int height, ImageObserver observer) -

draws a scaled image. The system scales the image to fit into a region with the given width

and height. Note: This call may return before the image is drawn.

Example: the following program draws a tiled graphics image from the top-left corner to bottom

right corner of the window.

import java.awt.*;

public class Demo extends Frame{

Demo(String s){

super(s);setSize(300,300);setVisible(true);

}

public void paint(Graphics g) {

Toolkit tk = Toolkit.getDefaultToolkit();

Image img= tk.getImage("E:/Sample/ball.jpg");

for (int i = 20; i <300-20; i=i+20)

for (int j = 40; j <300-20; j=j+20)

g.drawImage(img,i,j,20,20,null);

}

public static void main(String arg[]){

Demo ob=new Demo("Image Demo");

}

}

Output:

Page 59: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 59 of 158

© Einstein College of Engineering

AWT Components

All components are subclass of Component class

Components allow the user to interact with application. A layout manager

arranges components within a container (Frame/Applet/Panel).

Adding and Removing Controls

add(Component compObj)- add components to the conatainer. Once it is added, it will

automatically be visible whenever its parent window is displayed. Here, compObj is an

instance of the control that you want to add.

void remove(Component obj)- remove a control from a window

removeAll( )- remove all controls from a window

Component Constructor Methods

Label Label( )

Label(String str)

Label(String str, int how)

void setText(String str)

String getText( )

Button Button( )

Button(String str)

void setLabel(String str)

String getLabel( )

List List( )

List(int numRows)

List(int numRows, boolean multipleSelect)

void add(String name)

void add(String name, int

index)

String getSelectedItem( )

int getSelectedIndex( )

String[ ] getSelectedItems( )

Choice Choice( ) void add(String name)

String getSelectedItem( )

int getSelectedIndex( )

Checkbox Checkbox( )

Checkbox(String str)

Checkbox(String str, boolean on)

Checkbox(String str, boolean on, CheckboxGroup cbGroup)

Checkbox(String str, CheckboxGroup cbGroup, boolean on)

boolean getState( )

void setState(boolean on)

String getLabel( )

void setLabel(String str)

TextField TextField( ) TextField(int numChars)

TextField(String str)

TextField(String str, int numChars)

String getText( ) void setText(String str)

void setEditable(boolean

canEdit)

TextArea TextArea( ) TextArea(int numLines, int numChars)

TextArea(String str)

TextArea(String str, int numLines, int numChars)

void append(String str) void insert(String str, int

index)

Page 60: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 60 of 158

© Einstein College of Engineering

Scrollbars Scrollbar( ) Scrollbar(int style)

Scrollbar(int style, int initialValue, int thumbSize, int min, int max)

int getMinimum( ) int getMaximum( )

void setValues(int

initialValue, int thumbSize,

int min, int max)

Label

Labels are components that hold text.

Labels don’t react to user input. It is used to identify components.

Constructors

Label(String str) - constructs a label with left-aligned text.

Label(String str, int how) - constructs a label with the alignment specified by how.

Methods

void setText(String str)- set the text in the label

String getText( )- return the text of label

Example: The following example creates three labels and adds them to a frame..The labels are

organized in the frame by the flow layout manager.

import java.awt.*;

public class Demo extends Frame{

Label lb1 = new Label("One");

Label lb2 = new Label("Two");

Label lb3 = new Label("Three");

FlowLayout flow= new FlowLayout();

Demo(String s){

super(s);

setSize(200,200);

setLayout(flow);

add(lb1);add(lb2);add(lb3);

setVisible(true);

}

public static void main(String arg[]){

Demo ob=new Demo("Label Demo");

}

}

Output:

Page 61: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 61 of 158

© Einstein College of Engineering

Page 62: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 62 of 158

© Einstein College of Engineering

Button

A push button is a component that contains a label and that generates an event when it is pressed.

Push buttons are objects of type Button.

Constructors

Button( )- creates an empty button

Button(String str)- creates a button that contains str as a label.

Methods

void setLabel(String str) -set the label in the button

String getLabel( ) -return the label of button

Example: The following example creates three buttons and adds them to a frame. The buttons

are organized in the frame by the flow layout manager.

import java.awt.*;

public class Demo extends Frame{

FlowLayout flow= new FlowLayout();

Button b=new Button();

Button b1=new Button();

Button b2=new Button("Button 2");

Demo(String s){

super(s);setSize(200,200);

setLayout(flow);

b1.setLabel("Button 1");

add(b);add(b1);add(b2);

setVisible(true);

}

public static void main(String arg[]){

Demo ob=new Demo("Button Demo");

} }

Output:

List

The List class provides a compact, multiple-choice, scrolling selection list. List object can be

constructed to display any number of choices in the visible window. It allows the user to select

multiple items.

Constructors

List( )- allows to select one item at any one time

List(int numRows)- the value of numRows specifies the number of entries in the list that

Page 63: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 63 of 158

© Einstein College of Engineering

will be visible always

List(int numRows, boolean multipleSelect)- if multipleSelect is true, then the user may

select two or more items at a time

Method

void add(String name)- Here, name is the name of the item added to the list. The first

form adds items to the end of the list.

void add(String name, int index) -adds the item at the index specified by index

String getSelectedItem( )- return the selected item

String[ ] getSelectedItems( )- return the selected items.

Example: The following example creates a list and adds it to a frame.

import java.awt.*;

public class Demo extends Frame{

FlowLayout flow= new FlowLayout();

List l1=new List(2);

List l2=new List(3);

List l3=new List(4,true);

Label lb1 = new Label("Dept");

Label lb2 = new Label("Dept");

Label lb3 = new Label("Dept");

Demo(String s){

super(s);

setSize(200,300);

setLayout(flow);

l1.add("CSE");l1.add("ECE");l1.add("EEE");l1.add("MECH");

l2.add("CSE");l2.add("ECE");l2.add("EEE");l2.add("MECH");

l3.add("CSE");l3.add("ECE");l3.add("EEE");l3.add("MECH");

add(lb1);add(l1);add(lb2);add(l2);add(lb3);add(l3);

setVisible(true);

}

public static void main(String arg[]){

Demo ob=new

Demo("List Demo");

}

}

Page 64: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 64 of 158

© Einstein College of Engineering

CheckBox

A check box is a control that is used to turn an option on or off. It consists of a small box that can

either contain a check mark or not. There is a label associated with each check box that describes

what option the box represents.

Constructors

Checkbox( )- check box whose label is initially blank

Checkbox(String str)- check box whose label is specified by str.

Checkbox(String str, boolean on) - allows you to set the initial state of the check box. If

on is true, the check box is initially checked

Checkbox(String str, boolean on, CheckboxGroup cbGroup)- group is specified by

cbGroup

Checkbox(String str, CheckboxGroup cbGroup, boolean on)

Methods

boolean getState( )

void setState(boolean on)

String getLabel( )

void setLabel(String str)

CheckboxGroup

Create a set of mutually exclusive check boxes in which one and only one check box in the group

can be checked at any one time. These check boxes are often called radio buttons. The default

constructor is defined, which creates an empty group.

Example: The following example creates a checkbox group (Gender) and checkboxes

(Languages Known).

import java.awt.*;

public class Demo extends Frame{

FlowLayout flow= new FlowLayout();

Label l1=new Label("Gender");

Label l2=new Label("Languages Known");

CheckboxGroup cg=new CheckboxGroup();

Checkbox c1=new Checkbox("Male",cg,true);

Checkbox c2=new Checkbox("Female",cg,false);

Page 65: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 65 of 158

© Einstein College of Engineering

Checkbox c3=new Checkbox("VisualBasic");

Checkbox c4=new Checkbox("C++");

Checkbox c5=new Checkbox("Java");

Checkbox c6=new Checkbox("C");

Demo(String s){

super(s);

setSize(200,200);

setLayout(flow);

add(l1);add(c1);add(c2);

add(l2);add(c3);add(c4);add(c5);add(c6);

setVisible(true);

}

public static void main(String arg[]){

Demo ob=new Demo("Checkbox Demo");

}

}

Output:

Choice

The Choice class is used to create a pop-up list of items from which the user may choose. It

allows the user to select single item at any time. Choice only defines the default constructor,

which creates an empty list.

To add a item to the list, call add( ). It has this general form:

void add(String name)

To determine which item is currently selected, you may call either getSelectedItem( ) or

getSelectedIndex( ).

import java.awt.*;

public class Demo extends Frame{

FlowLayout flow= new FlowLayout();

Label lb=new Label("City");

Choice c=new Choice();

Demo(String s){

super(s);

setSize(200,200);setLayout(flow);

c.add("Chennai");c.add("Coimbatore");

c.add("KanyaKumari");c.add("Madurai");

c.add("Tirunelveli");

add(lb);add(c);

setVisible(true);

}

public static void main(String arg[]){

Demo ob=new Demo("Checkbox Demo");

}

}

Page 66: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 66 of 158

© Einstein College of Engineering

TextField

Text fields allow the user to enter strings and to edit the text using the arrow keys, cut and paste

keys, and mouse selections.

TextField( )- creates a default text field

TextField(int numChars)- creates a text field that is numChars characters wide

TextField(String str)- initializes the text field with the string contained in str

TextField(String str, int numChars)

Methods

String getText( )

void setText(String str)

TextArea

Simple multiline editor allow the user to enter strings.

TextArea and TextField are subclass of TextComponent. Therefore, it supports the getText( ),

setText( ), getSelectedText( ), select( ), isEditable( ), and setEditable( ) methods described in

TextField class.

import java.awt.*;

public class Demo extends Frame{

FlowLayout flow= new FlowLayout();

Label lb1=new Label("Name");

Label lb2=new Label("No");

Label lb3=new Label("Message");

TextField t1=new TextField(20);

TextField t2=new TextField(15);

TextArea ta=new TextArea(2,10);

Demo(String s){

super(s);

setSize(250,200);

setLayout(flow);

add(lb1);add(t1);

add(lb2);add(t2);

add(lb3);add(ta);

Page 67: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 67 of 158

© Einstein College of Engineering

setVisible(true);

}

public static void main(String arg[]){

Demo ob=new Demo("TextComponents Demo");

}

}

output:

Page 68: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 68 of 158

© Einstein College of Engineering

Basics of Event Handling

Event handling concept is quite simple: a source generates an event and sends it to one or more

listeners. Listener simply waits until it receives an event. Once received, the listener processes

the event and then returns.

Events

An event is an object that describes a state change in a source. Some of the activities that cause

events to be generated are pressing a button, entering a character via the keyboard, selecting an

item in a list, and clicking the mouse.

Event Sources

A source is an object that generates an event. Sources may generate more than one type of event.

A source must register listeners in order for the listeners to receive notifications about a specific

type of event.

Event Source Description

Button Generates action events when the button is pressed.

Checkbox Generates item events when the check box is selected or deselected.

Choice Generates item events when the choice is changed.

List Generates action events when an item is double-clicked; generates item

events when an item is selected or deselected.

Mouse Generates Mouse events when Mouse input occurs.

Keyboard Generates Key events when keyboard input occurs.

Event Listeners

Listener is an object that is notified when an event occurs. It has two major requirements.

It must have been registered with one or more sources to receive notifications about

specific types of events.

It must implement methods to receive and process these notifications.

The package java.awt.event defines several types of events that are generated by various user

interface elements.

Page 69: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 69 of 158

© Einstein College of Engineering

How event handling in the AWT works

A listener object is an instance of a class that implements a special interface called

(naturally enough) a listener interface.

An event source is an object that can register listener objects and send them event objects.

The event source sends out event objects to all registered listeners when that event

occurs.

The listener objects will then use the information in the event object to determine their

reaction to the event.

You register the listener object with the source object by using lines of code that follow the

model:

eventSourceObject.addEventListener(eventListenerObject);

AWT Event Hierarchy

java.awt.event

Source Event Class Class Methods Listener Interface Interface Methods

Button ActionEvent String

getActionCommand( )

ActionListener actionPerformed(ActionEvent ae)

List,

Choice,

Checkbox

ItemEvent Object getItem( )

ItemSelectable

getItemSelectable( )

ItemListener itemStateChanged(ItemEvent ie)

Keyboard KeyEvent char getKeyChar( )

int getKeyCode( )

KeyListener keyPressed(KeyEvent ke)

keyReleased(KeyEvent ke)

keyTyped(KeyEvent ke)

Mouse MouseEvent int getX( )

int getY( )

MouseListener mouseClicked(MouseEvent me)

mouseEntered(MouseEvent me)

mouseExited(MouseEvent me)

mousePressed(MouseEvent me)

mouseReleased(MouseEvent me)

MouseMotionListener mouseDragged(MouseEvent me)

mouseMoved(MouseEvent me)

Page 70: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 70 of 158

© Einstein College of Engineering

Handling Keyboard Events

To handle keyboard events, class must implement the KeyListener interface.

Register key listener to receive notifications about KeyEvents.

addKeyListener(this);

Source: KeyBoard

Event Class: java.awt.event.KeyEvent

Listener Interface: java.awt.event.KeyListener

Example: The following program demonstrates keyboard input. When program receives

keystrokes, identifies the key and perform the corresponding actions specified by the program.

import java.awt.*;

import java.awt.event.*;

public class Demo extends Frame implements

KeyListener{

int x=20,y=20;

Demo(String s){

super(s);

setSize(300,300);

setVisible(true);

addKeyListener(this);

}

public void keyPressed(KeyEvent ke){

int kc=ke.getKeyCode();

if(kc==37 && x<300)

x=x-10;

if(kc==39 && x>0)

x=x+10;

if(kc==38 && y>0)

y=y-10;

if(kc==40 && y<300)

y=y+10;

repaint();

}

public void keyTyped(KeyEvent ke){

}

public void keyReleased(KeyEvent ke){

}

public void paint(Graphics g){

g.drawRect(x,y,30,30);

}

public static void main(String arg[]){

Demo ob=new Demo("Key event Demo");

}

}

Output:

Page 71: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 71 of 158

© Einstein College of Engineering

Handling Mouse Events

To handle Mouse events, class must implement the MouseListener & MouseMotionLiatener

interface. Register mouse listener & mouse motion listener to receive notifications about

MouseEvents.

addMouseListener(this);

addMouseMotionListener(this);

Source: Mouse

Event Class: java.awt.event.MouseEvent

Listener Interface: java.awt.event.MouseListener

java.awt.event.MouseMotionListener

Example: The following program demonstrates Mouse event handling. When user drag the

mouse it draws a line along the motion path.

import java.awt.*;

import java.awt.event.*;

public class Demo extends Frame implements

MouseListener,MouseMotionListener{

int x1,y1,x2,y2;

Demo(String s){

super(s);

setSize(300,300);

setVisible(true);

addMouseListener(this);

addMouseMotionListener(this);

}

public void mouseDragged(MouseEvent me){

x1=x2;y1=y2;

x2=me.getX();

y2=me.getY();

Graphics g=this.getGraphics();

g.drawLine(x1,y1,x2,y2);

}

public void mouseMoved(MouseEvent me){}

public void mouseClicked(MouseEvent me){}

public void mouseEntered(MouseEvent me){}

public void mouseExited(MouseEvent me){

}

public void mousePressed(MouseEvent me){

x1=x2=me.getX();

x1=y2=me.getY();

}

public void mouseReleased(MouseEvent me){}

Page 72: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 72 of 158

© Einstein College of Engineering

public void paint(Graphics g){}

public static void main(String arg[]){

Demo ob=new Demo("Mouse event Demo");

}

}

Page 73: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 73 of 158

© Einstein College of Engineering

Action Event

To handle Action events, class must implement the ActionListener interface. Source objects

needs to register action listener to receive events.

SourceObject.addActionListener(this);

Source: Button

Event Class: java.awt.event.ActionEvent

Listener Interface: java.awt.event.ActionListener

Example: The following program demonstrates Action event handling. Application window has

3 Text Fields and two buttons. Text fields are used to get user input and show the result to the

user. When the user presses Button, it will generate an action event. Listener receives the event

and performs the operation specified in the actionPerformed Method.

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

public class Demo extends Frame implements

ActionListener{

FlowLayout flow=new FlowLayout();

Label lb1 = new Label("Number1");

Label lb2 = new Label("Number2");

Label lb3 = new Label("Result");

TextField t1=new TextField(20);

TextField t2=new TextField(20);

TextField t3=new TextField(20);

Button b1=new Button("Add");

Button b2=new Button("Multiply");

Demo(String s){

super(s);

setLayout(flow);

add(lb1);add(t1);

add(lb2);add(t2);

add(b1);add(b2);

add(lb3);add(t3);

b1.addActionListener(this);

b2.addActionListener(this);

setSize(280,280);

setVisible(true);

}

public void actionPerformed(ActionEvent ae){

String s=ae.getActionCommand();

int n1,n2;

n1=Integer.parseInt(t1.getText());

n2=Integer.parseInt(t2.getText());

if(s.equals("Add")){

t3.setText(String.valueOf(n1+n2));

}

if(s.equals("Multiply")){

t3.setText(String.valueOf(n1*n2));

}

}

public static void main(String arg[]){

Demo my=new Demo("Action event

demo");

}

}

Page 74: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 74 of 158

© Einstein College of Engineering

Item Event

To handle Item events, class must implement the ItemListener interface. Source objects needs to

register action listener to receive events.

SourceObject.addActionListener(this);

Source: List, Choice, Checkbox

Event Class: java.awt.event.ItemEvent

Listener Interface: java.awt.event.ItemListener

Example: The following program demonstrates Item event handling. Application window has

Text Field, Checkbox, and Choice. Text fields are used to show the result to the user. When the

user select item from any component, then the selected item will be displayed in text field. A

listener receives the event and performs the operation specified in the itemStateChanged()

Method.

import java.awt.*;

import java.awt.event.*;

public class Demo extends Frame implements

ItemListener{

String msg="";

FlowLayout flow=new FlowLayout();

Label lb1 = new Label("City");

Label lb2 = new Label("Qualification");

Label lb3 = new Label("Languages Known");

Choice c=new Choice();

CheckboxGroup cg=new CheckboxGroup(); Checkbox c1=new Checkbox("UG",cg,true);

Checkbox c2=new Checkbox("PG",cg,false);

Checkbox c3=new Checkbox("Visual Basic");

Checkbox c4=new Checkbox("C++");

Checkbox c5=new Checkbox("Java");

Checkbox c6=new Checkbox("dotnet");

TextField t=new TextField(20);

Demo(String s){

super(s);

setLayout(flow);

c.add("Chennai");c.add("Coimbatore");

c.add("KanyaKumari");c.add("Madurai");

c.add("Tirunelveli");

add(lb1);add(c);

add(lb2);add(c1);add(c2);

add(lb3);add(c3);add(c4);add(c5);add(c6);

add(t); setSize(200,300);

setVisible(true);

c.addItemListener(this);

c1.addItemListener(this);

c2.addItemListener(this);

c3.addItemListener(this);

Page 75: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 75 of 158

© Einstein College of Engineering

c4.addItemListener(this);

c5.addItemListener(this);

c6.addItemListener(this);

}

public void itemStateChanged(ItemEvent ie){

String msg=(String)ie.getItem();

t.setText(msg);

}

public static void main(String arg[]){

Demo ob=new Demo("List event Demo");

}

} Output:

Layout Management

Layout manager automatically arranges several components within a window. Each container

object has a layout manager associated with it.

Panel,Applet - Flow Layout

Frame - Border Layout

Whenever a container is resized, the layout manager is used to position each of the components

within it. General syntax for setting layout to container

Void setLayout(LayouManager obj)

Layout Managers are

FlowLayout

BorderLayout

Grid Layout

GridbagLayout

BoxLayout

Arrange component without using layout Manager:

You can position components manually using setBounds() method defined by

Component class.

1. Disable the default manager of your container.

setLayout(null);

2. Givethe location and size of the component which is to be added in the container.

Page 76: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 76 of 158

© Einstein College of Engineering

setBounds(int x, int y, int width, int height);

eg:

Button b=new Button(―click me‖);

b.setBounds(10,10,50,20);

FlowLayout

FlowLayout arranges the components in rows from left-to-right and top-to-bottom order based

on the order in which they were added to the container.

FlowLayout arranges components in rows, and the alignment specifies the alignment of the rows.

For example, if you create a FlowLayout that’s left aligned, the components in each row will

appear next to the left edge of the container.

The FlowLayout constructors allow you to specify the horizontal and vertical gaps that should

appear between components, and if you use a constructor that doesn’t accept these values, they

both default to 5.

Constructor:

FlowLayout() - create default layout, which centers component and leaves 5 pixels

spaces between each component.

FlowLayout(int how)-specify how ech line is aligned.

The flow layout manager lines the components horizontally until there is no more room and then

starts a new row of components. When the user resizes the container, the layout manager

automatically reflows the components to fill the available space. If you reduce the width of the

frame further, then portions of the wider components begin to disappear. Similarly, if you reduce

the frame’s vertical size so that there’s not enough vertical space to display all rows, some of the

components will become partially or completely inaccessible

import java.awt.*;

public class Demo extends Frame{

FlowLayout flow=new FlowLayout();

Button b1=new Button("one");

Button b2=new Button("Two");

Button b3=new Button("Three");

Demo(String s){

super(s);

setLayout(flow);

add(b1);add(b2);add(b3);

setSize(200,200);

setVisible(true);

}

public static void main(String arg[]){

Demo ob=new Demo("FlowLayout Demo");

}

}

Page 77: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 77 of 158

© Einstein College of Engineering

GridLayout

The GridLayout layout manager divides the available space into a grid of cells, evenly allocating

the space among all the cells in the grid and placing one component in each cell.

Cells are always same size. When you resize the window, the cells grow and shrink, but all the

cells have identical sizes.

Constructor

GridLayout(int rows, int cols)- construct a grid with specified rows and cols.

GridLayout(int rows, int cols, int hspace, int vspace) - to specify the amount of horizontal

and vertical space that should appear between adjacent components.

When you create a GridLayout, you can specify a value of 0 for either the row count or the

column count, but not both. If you set the number of rows to 0, GridLayout creates as many rows

as it needs to display all the components using the specified number of columns.

import java.awt.*;

public class Demo extends Frame{

GridLayout grid=new GridLayout(2,2);

Button b1=new Button("one");

Button b2=new Button("Two");

Button b3=new Button("Three");

Demo(String s){

super(s);

setLayout(grid);

add(b1);add(b2);add(b3);

setSize(200,200);

setVisible(true);

}

public static void main(String arg[]){

Demo ob=new Demo("GridLayout Demo");

}

}

BorderLayout

BorderLayout divides the container into five areas, and you can add a component to each area.

Page 78: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 78 of 158

© Einstein College of Engineering

The five regions correspond to the top, left, bottom, and right sides of the container, along with

one in the center. Each of the five areas is associated with a constant value defined in

BorderLayout: NORTH, SOUTH, EAST, WEST, and CENTER for the top, bottom, right, left,

and center regions, respectively.

Constructor

BorderLayout()

BorderLayout(int hspace, int vspace) – leave space between components.

Border layout grows all components to fill the available space.You can add components by

specifying a constraint - BorderLayout.CENTER|NORTH|SOUTH|EAST|WEST

void add(Component obj, constraint)

import java.awt.*;

public class Demo extends Frame{

BorderLayout grid=new BorderLayout();

Button b1=new Button("one");

Button b2=new Button("Two");

Button b3=new Button("Three");

Button b4=new Button("four");

Button b5=new Button("five");

Demo(String s){

super(s);

setLayout(grid);

add(b1,BorderLayout.NORTH);

add(b2,BorderLayout.SOUTH);

add(b3,BorderLayout.CENTER);

add(b4,BorderLayout.EAST);

add(b5,BorderLayout.WEST);

setSize(200,200);

setVisible(true);

}

public static void main(String arg[]){

Demo ob=new Demo("BorderLayout Demo");

}

}

GridBag Layout - Gridlayout without limitations

Page 79: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 79 of 158

© Einstein College of Engineering

In Grid bag layout, the rows and columns have variable sizes. It is possible to merge two

adjacent cells and make a space for placing larger components.

To describe the layout to grid bag manager, you must follow the procedure

1. Create an object of type GridBagLayout. No need to specify rows and column.

2. Set this GridBagLayout object to the container.

3. Create an object of type GridBagConstraints. This object will specify how the

components are laid out within the grid bag.

4. For each components, fill in the GridBagConstraints object.Finally add the component

with the constraint by using the call

add(Component, constraint);

GridBagConstraints:

Gridx – specify the column position of the component to be added

Gridy - specify the row position of the component to be added

Gridwidth- specify how many columns occupied by the component

Gridheight - specify how many rows occupied by the component

import java.awt.*;

public class Demo extends Frame{

GridBagLayout gb=new GridBagLayout();

GridBagConstraints gc1= new GridBagConstraints();

GridBagConstraints gc2= new GridBagConstraints();

GridBagConstraints gc3= new GridBagConstraints(); Button b1=new Button("one");

Button b2=new Button("Two");

Button b3=new Button("Three");

Demo(String s){

super(s);

setLayout(gb);

gc1.gridx=0;

gc1.gridy=0;

gc1.gridwidth=2;

gc1.gridheight=1;

gc2.gridx=0; gc2.gridy=1;

gc2.gridwidth=1;

gc2.gridheight=1;

gc3.gridx=1;

gc3.gridy=1;

gc3.gridwidth=1;

gc3.gridheight=1;

add(b1,gc1);add(b2,gc2);add(b3,gc3);

setSize(200,200);

setVisible(true); }

public static void main(String arg[]){

Demo ob=new Demo("GridBagLayout Demo");

}}

BoxLayout – javax.swing

Page 80: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 80 of 158

© Einstein College of Engineering

Arrange components in single row or single column. Components are arranged either vertically

from top to bottom or horizontally from left to right

BoxLayout(Container Obj, BoxLayout.X_AXIS | Y_AXIS);

Adapter classes

An adapter class provides an empty implementation of all methods in an event listener interface.

It is useful when you want to receive and process only some of the events that are handled by an

event listener interface.

Define a new class that extends the adapter class and overrides the desired methods only.

Extends adapter class to create Listener and override the desired methods. If you implement the

interface, you have to define all of methods in it. This adapter class defines null methods for all

events, so you can only redefine the methods that you needed.

Some Adapter classes are

KeyAdapter

MouseAdapter

MouseMotionAdapter

Example: If the user only interest in mouse pressed event,then simply extends MouseAdapter

class and redefine the mousePressed event. The following program listening MouseEvent

whenever the user press the mouse it will print ―mouse pressed‖ text on command prompt.

import java.awt.*;

import java.awt.event.*;

public class Demo extends MouseAdapter{

public static void main(String arg[]){

Frame f=new Frame("Mouse Adapter Demo");

f.setSize(200,200);

f.setVisible(true);

Demo ob=new Demo();

f.addMouseListener(ob);

}

public void mousePressed(MouseEvent me){

System.out.println("Mouse pressed..");

}

}

Page 81: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 81 of 158

© Einstein College of Engineering

Page 82: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 82 of 158

© Einstein college of engineering

Model-View-Controller design pattern

Swing uses the model-view-controller architecture (MVC) as the fundamental design

behind each of its components. Essentially, MVC breaks GUI components into three

elements. Each of these elements plays a crucial role in how the component behaves.

Model - (includes state data for each component)

The model encompasses the state data for each component. There are different models for

different types of components. Model has no user interface. Model data always exists

independent of the component's visual representation.

For example, model of a Choice list might contain the information about list of items and

currently selected item. This information remains the same no matter how the component

is painted on the screen.

View - (to display component on screen)

The view refers to how you see the component on the screen. It determines exactly where

and how to draw the choice list by the information offered by the model.

Controller- (handles user Input)

The controller decides the behavior of each component with respect to the events. Events

come in many forms (a mouse click, a keyboard event).The controller decides how each

component will react to the event—if it reacts at all.

Page 83: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 83 of 158

© Einstein college of engineering

MVC Interaction

In MVC, each of the three elements—the model, the view, and the controller—requires

the services of another element to keep itself continually updated.

Page 84: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 84 of 158

© Einstein college of engineering

Introduction to Swing

Swing Features

Pluggable look-and feels -- as above

Lightweight components

o Do not depend on native peers to render themselves.

o Simplified graphics to paint on screen

o Similar behaviour across all platforms

o Portable look and feel

o Only a few top level containers not lightweight.

New components -- tress tables, sliders progress bars, frames, text components.

Tooltips -- textual popup to give additional help

arbitrary keyboard event binding

Debugging support

Difference between AWT and Swing

S.No AWT(Abstract Window Toolkit) Swing

1 AWT components are heavy weight,

components are platform dependent.

Swing components are light weight,

components are platform independent.

2 AWT components support Delegate

Event Model.

Swing components support MVC (model,

view, control architecture)

3 AWT components provide static look

and feel.

Swing components provide dynamic look

and feel

4 It does not provide Tooltip text for

components

It provide Tooltip text for components

Page 85: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 85 of 158

© Einstein college of engineering

Swing Components

javax.swing

Component Constructor Methods

JLabel JLabel()

JLabel(String text)

JLabel(String text, int horizontalAlignment)

void setText(String str)

String getText( )

JButton JButton( )

JButton(String str)

void setLabel(String str)

String getLabel( )

JList JList()

JList(String[] )

Object getSelectedValue( )

int getSelectedIndex( )

String[] getSelectedItems( )

JRadioButton JRadioButton()

JRadioButton(String text)

JRadioButton(String text, boolean selected)

JRadioButton(String text, Icon icon, boolean

selected)

JComboBox JComboBox()

JComboBox(Object items[])

void add(String name)

String getSelectedItem( )

int getSelectedIndex( )

JCheckbox JCheckbox( )

JCheckbox(String str)

JCheckbox(String str, boolean on)

JCheckBox(String text, Icon icon)

boolean getState( )

void setState(boolean on)

String getLabel( )

void setLabel(String str)

JTextField JTextField(int numChars)

JTextField(String str, int numChars)

String getText( )

void setText(String str)

void setEditable(boolean

canEdit)

JTextArea JTextArea(int numLines, int numChars)

JTextArea(String str, int numLines, int numChars)

void append(String str)

void insert(String str, int index)

JPasswordField JPasswordField(String text, int columns) void setEchoChar(char echo)

The JLabel Class

Page 86: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 86 of 158

© Einstein college of engineering

Swing allows you to create labels that can contain text, images, or both. Unlike

java.awt.Label objects, JLabel objects may consist of both text and graphics (icons).

Text Input

In Java, two components are used to get text input:

JTextField

JTextArea.

The difference between them is that a text field can accept only one line of text and a text

area can accept multiple lines of text. The classes are called JTextField for single-line

input and JTextArea for multiple lines of text.

The JPasswordField Class

Password fields are a special kind of text field. To avoid nosy bystanders being able to

glance at a password, the characters that the user entered are not actually displayed.

Instead, each typed character is represented by an echo character, typically an asterisk

(*). The Swing set supplies a JPasswordField class that implements such a text field.

The JButton Class

They are typically used much like java.awt.Buttons. JButtons fire ActionEvents when

they are clicked.

The JCheckBox Class

It is used to allow the user to turn a given feature on or off, or to make multiple selections

from a set of choices. A JCheckBox is usually rendered by showing a small box into

which a "check" is placed when selected. The user could check either, both, or none of

the two check boxes.

The JRadioButton Class

JRadioButtons, allowing users to make a single selection from a set of options.

Page 87: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 87 of 158

© Einstein college of engineering

The JList Class

A list is a graphical component from which the user can select choices. Lists typically

display several items at a time, allowing the user to make either a single selection or

multiple selections.AWT limited the contents of its List component to strings. The Swing

JList component lifts this restriction. List elements can now be strings, images.

The JComboBox Class

A combo box component is actually a combination of a Swing list and a text field. Unlike

lists, a combo box only allows the user one selection at a time, which is usually copied

into an editable component at the top, such as a text field. The user can be permitted,

however, to manually enter in a selection as well.

JComboBox is the Swing version of a combo box component. It is very similar to the

AWT Choice component.

The JPanel Class

JPanel is an extension of JComponent (which, remember, extends java.awt.Container)

used for grouping together other components. It gets most of its implementation from its

superclasses.

Typically, using JPanel amounts to instantiating it, setting a layout manager (this can be

set in the constructor and defaults to a FlowLayout), and adding components to it using

the add() methods inherited from Container.

Page 88: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 88 of 158

© Einstein college of engineering

Unit IV

Generic Programming:

Generics are a facility of generic programming that was added to the Java programming

language.

Generic programming is a style of computer programming in which algorithms are

written in terms of to-be-specified-later types that are then instantiated when needed for

specific types provided as parameters.

As per Java Language Specification:

A type variable is an unqualified identifier. Type variables are introduced by

generic class declarations, generic interface declarations, generic method

declarations, and by generic constructor declarations.

A class is generic if it declares one or more type variables. These type variables

are known as the type parameters of the class. It defines one or more type

variables that act as parameters. A generic class declaration defines a set of

parameterized types, one for each possible invocation of the type parameter

section. All of these parameterized types share the same class at runtime.

An interface is generic if it declares one or more type variables. These type

variables are known as the type parameters of the interface. It defines one or more

type variables that act as parameters. A generic interface declaration defines a set

of types, one for each possible invocation of the type parameter section. All

parameterized types share the same interface at runtime.

A method is generic if it declares one or more type variables. These type variables

are known as the formal type parameters of the method. The form of the formal

type parameter list is identical to a type parameter list of a class or interface.

A constructor can be declared as generic, independently of whether the class the

constructor is declared in is itself generic. A constructor is generic if it declares

one or more type variables. These type variables are known as the formal type

parameters of the constructor. The form of the formal type parameter list is

identical to a type parameter list of a generic class or interface.

Motivation for Generics: Overloaded methods are often used to perform similar operations on different types of

data. To motivate generic methods, let’s begin with an example that contains three

overloaded printArray methods These methods print the string representations of the

elements of an Integer array, a Double array and a Character array, respectively. Note

that we could have used arrays of primitive types int, double and char in this example.

We chose to use arrays of typeInteger, Double and Character to set up our generic

method example, because only reference types can be used with generic methods and

classes.

Page 89: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 89 of 158

© Einstein college of engineering

public class OverloadedMethods

{

// method printArray to print Integer array

public static void printArray( Integer[] inputArray )

{

// display array elements

for ( Integer element : inputArray )

System.out.printf( "%s ", element );

System.out.println();

} // end method printArray

// method printArray to print Double array

public static void printArray( Double[] inputArray )

{

// display array elements

for ( Double element : inputArray )

System.out.printf( "%s ", element );

System.out.println();

} // end method printArray

// method printArray to print Character array

public static void printArray( Character[] inputArray )

{

// display array elements

for ( Character element : inputArray )

System.out.printf( "%s ", element );

System.out.println();

} // end method printArray

public static void main( String args[] )

{

// create arrays of Integer, Double and Character

Integer[] integerArray = { 1, 2, 3, 4, 5, 6 };

Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 };

Character[] characterArray = { 'H', 'E', 'L', 'L', 'O' };

System.out.println( "Array integerArray contains:" );

printArray( integerArray ); // pass an Integer array

System.out.println( "\nArray doubleArray contains:" );

printArray( doubleArray ); // pass a Double array

System.out.println( "\nArray characterArray contains:" );

printArray( characterArray ); // pass a Character array

Page 90: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 90 of 158

© Einstein college of engineering

} // end main

} // end class OverloadedMethods

Array integerArray contains:

1 2 3 4 5 6

Array doubleArray contains:

1.1 2.2 3.3 4.4 5.5 6.6 7.7

Array characterArray contains:

H E L L O

Generic class definitions

Here is an example of a generic class:

public class Pair<T, S>

{

public Pair(T f, S s)

{

first = f;

second = s;

}

public T getFirst()

{

return first;

}

public S getSecond()

{

return second;

}

public String toString()

{

return "(" + first.toString() + ", " + second.toString() + ")";

}

private T first;

private S second;

}

This generic class can be used in the following way:

Pair<String, String> grade440 = new Pair<String, String>("mike", "A");

Pair<String, Integer> marks440 = new Pair<String, Integer>("mike",

100);

System.out.println("grade:" + grade440.toString());

System.out.println("marks:" + marks440.toString());

Type erasure

Generics are checked at compile-time for type correctness. The generic type information

is then removed via a process called type erasure. For example, List<Integer> will be

Page 91: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 91 of 158

© Einstein college of engineering

converted to the raw type (non-generic type) List, which can contain arbitrary objects.

However, due to the compile-time check, the resulting code is guaranteed to be type

correct, as long as the code generated no unchecked compiler warnings.

As a result, there is no way to tell at runtime which type parameter is used on an object.

For example, when you examine an ArrayList at runtime, there is no general way to tell

whether it was an ArrayList<Integer> or an ArrayList<Float>. The exception to this

is by using Reflection on existing list elements. However, if the list is empty or if its

elements are subtypes of the parameterized type, even Reflection will not divulge the

parameterized type.

The following code demonstrates that the Class objects appear the same.

ArrayList<Integer> li = new ArrayList<Integer>();

ArrayList<Float> lf = new ArrayList<Float>();

if (li.getClass() == lf.getClass()) // evaluates to true

System.out.println("Equal");

Java generics differ from C++ templates. Java generics generate only one compiled

version of a generic class or function regardless of the number of types used.

Furthermore, the Java compiler does not need to know which parameterized type is used

because the type information is validated at compile-time and erased from the compiled

code. Consequently, one cannot instantiate a Java class of a parameterized type because

instantiation requires a call to a constructor, which is not possible when the type is

unknown at both compile-time and runtime.

T instantiateElementType(List<T> arg)

{

return new T(); //causes a compile error

}

Because there is only one copy of a generic class, static variables are shared among all

the instances of the class, regardless of their type parameter. As a result, the type

parameter cannot be used in the declaration of static variables or in static methods. Static

variables and static methods are "outside" of the scope of the class's parameterized types.

Generic methods:

Generic Methods

Genericity is not limited to classes and interfaces, you can define generic methods. Static

methods, nonstatic methods, and constructors can all be parameterized in almost the same

way as for classes and interfaces, but the syntax is a bit different. Generic methods are

also invoked in the same way as non-generic methods.

Before we see an example of a generics method, consider the following segment of code

that prints out all the elements in a collection:

public void printCollection(Collection c) {

Iterator i = c.iterator();

for(int k = 0;k<c.size();k++) {

System.out.println(i.next());

}

Page 92: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 92 of 158

© Einstein college of engineering

}

Using generics, this can be re-written as follows. Note that the Collection<?> is the

collection of an unknown type.

void printCollection(Collection<?> c) {

for(Object o:c) {

System.out.println(o);

}

}

Example:

public class GenericMethodTest

{

// generic method printArray

public static < E > void printArray( E[] inputArray )

{

// display array elements

for ( E element : inputArray )

System.out.printf( "%s ", element );

System.out.println();

} // end method printArray

public static void main( String args[] )

{

// create arrays of Integer, Double and Character

Integer[] intArray = { 1, 2, 3, 4, 5 };

Double[] doubleArray = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 };

Character[] charArray = { 'H', 'E', 'L', 'L', 'O' };

System.out.println( "Array integerArray contains:" );

printArray( integerArray ); // pass an Integer array

System.out.println( "\nArray doubleArray contains:" );

printArray( doubleArray ); // pass a Double array

System.out.println( "\nArray characterArray contains:" );

printArray( characterArray ); // pass a Character array

} // end main

} // end class GenericMethodTest

Array integerArray contains:

1 2 3 4 5 6

Array doubleArray contains:

1.1 2.2 3.3 4.4 5.5 6.6 7.7

Array characterArray contains:

H E L L O

Bounded Type Parameters:

There may be times when you'll want to restrict the kinds of types that are allowed to be

passed to a type parameter. For example, a method that operates on numbers might only

Page 93: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 93 of 158

© Einstein college of engineering

want to accept instances of Number or its subclasses. This is what bounded type

parameters are for.

To declare a bounded type parameter, list the type parameter's name, followed by the

extends keyword, followed by its upper bound, which in this example is Number. Note

that, in this context, extends is used in a general sense to mean either "extends" (as in

classes) or "implements" (as in interfaces).

public class Box<T> {

private T t;

public void add(T t) {

this.t = t;

}

public T get() {

return t;

}

public <U extends Number> void inspect(U u){

System.out.println("T: " + t.getClass().getName());

System.out.println("U: " + u.getClass().getName());

}

public static void main(String[] args) {

Box<Integer> integerBox = new Box<Integer>();

integerBox.add(new Integer(10));

integerBox.inspect("some text"); // error: this is still

String!

}

}

By modifying our generic method to include this bounded type parameter, compilation

will now fail, since our invocation of inspect still includes a String: Box.java:21: <U>inspect(U) in Box<java.lang.Integer> cannot

be applied to (java.lang.String)

integerBox.inspect("10");

^

1 error

To specify additional interfaces that must be implemented, use the & character, as in:

<U extends Number & MyInterface>

Exceptions:

Exceptions are such anomalous conditions (or typically an event) which changes the normal flow of execution of a program. Exceptions are used for signaling erroneous (exceptional) conditions which occur during the run time processing. Exceptions may occur in any programming language.

Page 94: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 94 of 158

© Einstein college of engineering

Occurrence of any kind of exception in java applications may result in an abrupt termination of the JVM or simply the JVM crashes which leaves the user unaware of the causes of such anomalous conditions. However Java provides mechanisms to handle such situations through its superb exception handling mechanism. The Java programming language uses Exception classes to handle such erroneous conditions and exceptional events.

Exception Hierarchy:

There are three types of Exceptions:

1. Checked Exceptions - These are the exceptions which occur during the compile time of the program. The compiler checks at the compile time that whether the program contains handlers for checked exceptions or not. These exceptions do not extend RuntimeException class and must be handled to avoid a compile-time error by the programmer. These exceptions extend the java.lang.Exception class These exceptional conditions should be anticipated and recovered by an application. Furthermore Checked exceptions are required to be caught. Remember that all the exceptions are checked exceptions unless and until those indicated by Error, RuntimeException or their subclasses.

For example if you call the readLine() method on a BufferedReader object then the IOException may occur or if you want to build a program that could read a file with a specific name then you would be prompted to input a file name by the application. Then it passes the name to the constructor for java.io.FileReader and opens the file. However if you do not provide the name of any existing file then the constructor throwsjava.io.FileNotFoundException which abrupt the application to succeed. Hence this exception will be caught by a well-written application and will also prompt to correct the file name. Here is the list of checked exceptions.

Page 95: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 95 of 158

© Einstein college of engineering

NoSuchFieldException

InstantiationException

IllegalAccessException

ClassNotFoundException

NoSuchMethodException

CloneNotSupportedException

InterruptedException

2. Unchecked Exceptions - Unchecked exceptions are the exceptions which occur during the runtime of the program. Unchecked exceptions are internal to the application and extend the java.lang.RuntimeException that is inherited from java.lang.Exceptionclass. These exceptions cannot be anticipated and recovered like programming bugs, such as logic errors or improper use of an API. These type of exceptions are also calledRuntime exceptions that are usually caused by data errors, like arithmetic overflow, divide by zero etc. Lets take the same file name example as described earlier. In that example the file name is passed to the constructor for FileReader. However, the constructor will throwNullPointerException if a logic error causes a null to be passed to the constructor. Well in this case the exception could be caught by the application but it would rather try to eliminate the bug due to which the exception has occurred. You must have encountered the most common exception in your program i.e. the ArithmeticException. I am sure you must be familiar with the reason of its occurrence that is when something tries to divide by zero. Similarly when an instance data member or method of a reference variable is to be accessed that hasn't yet referenced an object throws NullPointerException. Here is the list of unchecked exceptions.

IndexOutOfBoundsException

ArrayIndexOutOfBoundsException

ClassCastException

ArithmeticException

NullPointerException

IllegalStateException

SecurityException

Page 96: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 96 of 158

© Einstein college of engineering

3. Error - The errors in java are external to the application. These are the exceptional conditions that could not be usually anticipated by the application and also could not be recovered from. Error exceptions belong to Error and its subclasses are not subject to the catch or Specify requirement. Suppose a file is successfully opened by an application for input but due to some system malfunction could not be able to read that file then the java.io.IOError would be thrown. This error will cause the program to terminate but if an application wants then the error might be caught. An Error indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions.

Hence we conclude that Errors and runtime exceptions are together called as unchecked exceptions.

Throwing Exceptions

If a method needs to be able to throw an exception, it has to declare the exception(s) thrown in the method signature, and then include a throw-statement in the method. Here is an example:

public void divide(int numberToDivide, int numberToDivideBy)

throws BadNumberException{

if(numberToDivideBy == 0){

throw new BadNumberException("Cannot divide by 0");

}

return numberToDivide / numberToDivideBy;

}

When an exception is thrown the method stops execution right after the "throw" statement. Any statements following the "throw" statement are not executed. In the example above the "return numberToDivide / numberToDivideBy;" statement is not executed if a BadNumberException is thrown. The program resumes execution when the exception is caught somewhere by a "catch" block. Catching exceptions is explained later.

You can throw any type of exception from your code, as long as your method signature declares it. You can also make up your own exceptions. Exceptions are regular Java classes that

Page 97: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 97 of 158

© Einstein college of engineering

extends java.lang.Exception, or any of the other built-in exception classes. If a method declares that it throws an exception A, then it is also legal to throw subclasses of A.

Catching Exceptions

If a method calls another method that throws checked exceptions, the calling method is forced to either pass the exception on, or catch it. Catching the exception is done using a try-catch block. Here is an example:

public void callDivide(){

try {

int result = divide(2,1);

System.out.println(result);

} catch (BadNumberException e) {

//do something clever with the exception

System.out.println(e.getMessage());

}

System.out.println("Division attempt done");

}

The BadNumberException parameter e inside the catch-clause points to the exception thrown from the divide method, if an exception is thrown.

If no exeception is thrown by any of the methods called or statements executed inside the try-block, the catch-block is simply ignored. It will not be executed.

If an exception is thrown inside the try-block, for instance from the divide method, the program flow of the calling method, callDivide, is interrupted just like the program flow inside divide. The program flow resumes at a catch-block in the call stack that can catch the thrown exception. In the example above the "System.out.println(result);" statement will not get executed if an exception is thrown fromt the divide method. Instead program execution will resume inside the "catch (BadNumberException e) { }" block.

If an exception is thrown inside the catch-block and that exception is not caught, the catch-block is interrupted just like the try-block would have been.

Page 98: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 98 of 158

© Einstein college of engineering

When the catch block is finished the program continues with any statements following the catch block. In the example above the "System.out.println("Division attempt done");" statement will always get executed.

Propagating Exceptions

You don't have to catch exceptions thrown from other methods. If you cannot do anything about the exception where the method throwing it is called, you can just let the method propagate the exception up the call stack to the method that called this method. If you do so the method calling the method that throws the exception must also declare to throw the exception. Here is how the callDivide() method would look in that case.

public void callDivide() throws BadNumberException{

int result = divide(2,1);

System.out.println(result);

}

Notice how the try-catch block is gone, and the callDivide method now declares that it can throw a BadNumberException. The program execution is still interrupted if an exception is thrown from the divide method. Thus the "System.out.println(result);" method will not get executed if an exception is thrown from the divide method. But now the program execution is not resumed inside the callDivide method. The exception is propagated to the method that calls callDivide. Program execution doesn't resume until a catch-block somewhere in the call stack catches the exception. All methods in the call stack between the method throwing the exception and the method catching it have their execution stopped at the point in the code where the exception is thrown or propagated.

Example: Catching IOException's

If an exception is thrown during a sequence of statements inside a try-catch block, the sequence of statements is interrupted and the flow of control will skip directly to the catch-block. This code can be interrupted by exceptions in several places:

public void openFile(){

try {

// constructor may throw FileNotFoundException

FileReader reader = new FileReader("someFile");

Page 99: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 99 of 158

© Einstein college of engineering

int i=0;

while(i != -1){

//reader.read() may throw IOException

i = reader.read();

System.out.println((char) i );

}

reader.close();

System.out.println("--- File End ---");

} catch (FileNotFoundException e) {

//do something clever with the exception

} catch (IOException e) {

//do something clever with the exception

}

}

If the reader.read() method call throws an IOException, the following System.out.println((char) i ); is not executed. Neither is the last reader.close() or the System.out.println("--- File End ---"); statements. Instead the program skips directly to the catch(IOException e){ ... } catch clause. If the new FileReader("someFile"); constructor call throws an exception, none of the code inside the try-block is executed.

Example: Propagating IOException's

This code is a version of the previous method that throws the exceptions instead of catching them:

public void openFile() throws IOException {

FileReader reader = new FileReader("someFile");

int i=0;

while(i != -1){

i = reader.read();

System.out.println((char) i );

}

reader.close();

System.out.println("--- File End ---");

}

If an exception is thrown from the reader.read() method then program execution is halted, and the exception is passed up the call stack to the method that called openFile(). If the calling method has a try-catch block, the exception will be caught there. If the calling method also just throws the method on, the calling method is also interrupted at the openFile() method call, and the

Page 100: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 100 of 158

© Einstein college of engineering

exception passed on up the call stack. The exception is propagated up the call stack like this until some method catches the exception, or the Java Virtual Machine does.

Finally

You can attach a finally-clause to a try-catch block. The code inside the finally clause will always be executed, even if an exception is thrown from within the try or catch block. If your code has a return statement inside the try or catch block, the code inside the finally-block will get executed before returning from the method. Here is how a finally clause looks:

public void openFile(){

FileReader reader = null;

try {

reader = new FileReader("someFile");

int i=0;

while(i != -1){

i = reader.read();

System.out.println((char) i );

}

} catch (IOException e) {

//do something clever with the exception

} finally {

if(reader != null){

try {

reader.close();

} catch (IOException e) {

//do something clever with the exception

}

}

System.out.println("--- File End ---");

}

}

No matter whether an exception is thrown or not inside the try or catch block the code inside the finally-block is executed. The example above shows how the file reader is always closed, regardless of the program flow inside the try or catch block.

Note: If an exception is thrown inside a finally block, and it is not caught, then that finally block is interrupted just like the try-block and catch-block is. That is why the previous example had the

Page 101: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 101 of 158

© Einstein college of engineering

reader.close() method call in the finally block wrapped in a try-catch block:

} finally {

if(reader != null){

try {

reader.close();

} catch (IOException e) {

//do something clever with the exception

}

}

System.out.println("--- File End ---");

}

That way the System.out.println("--- File End ---"); method call will always be executed. If no unchecked exceptions are thrown that is. More about checked and unchecked in a later chapter.

You don't need both a catch and a finally block. You can have one of them or both of them with a try-block, but not none of them. This code doesn't catch the exception but lets it propagate up the call stack. Due to the finally block the code still closes the filer reader even if an exception is thrown.

public void openFile() throws IOException {

FileReader reader = null;

try {

reader = new FileReader("someFile");

int i=0;

while(i != -1){

i = reader.read();

System.out.println((char) i );

}

} finally {

if(reader != null){

try {

reader.close();

} catch (IOException e) {

//do something clever with the exception

}

}

System.out.println("--- File End ---");

}

}

Page 102: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 102 of 158

© Einstein college of engineering

Notice how the catch block is gone.

Logging:

The JDK contains the "Java Logging API". Via a logger you can save text to a

central place to report on errors, provide additional information about your program, etc.

This logging API allows to configure how messages are written by which class with which priority

Overview of Control Flow

Applications make logging calls on Logger objects. Loggers are organized in a hierarchical namespace and child Loggers may inherit some logging properties from their parents in the namespace.

Applications make logging calls on Logger objects. These Logger objects allocate LogRecord objects which are passed to Handler objects for publication. Both Loggers and Handlers may use logging Levels and (optionally) Filters to decide if they are interested in a particular LogRecord. When it is necessary to publish a LogRecord externally, a Handler can (optionally) use a Formatter to localize and format the message before publishing it to an I/O stream.

Each Logger keeps track of a set of output Handlers. By default all Loggers also send their output to their parent Logger. But Loggers may also be configured to ignore Handlers higher up the tree.

Some Handlers may direct output to other Handlers. For example, the MemoryHandler maintains an internal ring buffer of LogRecords and on trigger events it publishes its LogRecords through a target Handler. In such cases, any formatting is done by the last Handler in the chain.

Page 103: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 103 of 158

© Einstein college of engineering

The APIs are structured so that calls on the Logger APIs can be cheap when logging is disabled. If logging is disabled for a given log level, then the Logger can make a cheap comparison test and return. If logging is enabled for a given log level, the Logger is still careful to minimize costs before passing the LogRecord into the Handlers. In particular, localization and formatting (which are relatively expensive) are deferred until the Handler requests them. For example, a MemoryHandler can maintain a circular buffer of LogRecords without having to pay formatting costs.

Log Levels

Each log message has an associated log Level. The Level gives a rough guide to the importance and urgency of a log message. Log level objects encapsulate an integer value, with higher values indicating higher priorities.

The Level class defines seven standard log levels, ranging from FINEST (the lowest priority, with the lowest value) to SEVERE (the highest priority, with the highest value).

Loggers

As stated earlier, client code sends log requests to Logger objects. Each logger keeps track of a log level that it is interested in, and discards log requests that are below this level.

Loggers are normally named entities, using dot-separated names such as "java.awt". The namespace is hierarchical and is managed by the LogManager. The namespace should typically be aligned with the Java packaging namespace, but is not required to follow it slavishly. For example, a Logger called "java.awt" might handle logging requests for classes in the java.awt package, but it might also handle logging for classes in

Page 104: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 104 of 158

© Einstein college of engineering

sun.awt that support the client-visible abstractions defined in the java.awt package.

In addition to named Loggers, it is also possible to create anonymous Loggers that don't appear in the shared namespace. See section 1.14.

Loggers keep track of their parent loggers in the logging namespace. A logger's parent is its nearest extant ancestor in the logging namespace. The root Logger (named "") has no parent. Anonymous loggers are all given the root logger as their parent. Loggers may inherit various attributes from their parents in the logger namespace. In particular, a logger may inherit:

Logging level. If a Logger's level is set to be null then the Logger will use an

effective Level that will be obtained by walking up the parent tree and using the

first non-null Level.

Handlers. By default a Logger will log any output messages to its parent's

handlers, and so on recursively up the tree.

Resource bundle names. If a logger has a null resource bundle name, then it will

inherit any resource bundle name defined for its parent, and so on recursively up

the tree.

Logging Methods

The Logger class provides a large set of convenience methods for generating log messages. For convenience, there are methods for each logging level, named after the logging level name. Thus rather than calling "logger.log(Constants.WARNING,..." a developer can simply call the convenience method "logger.warning(..."

There are two different styles of logging methods, to meet the needs of different communities of users.

First, there are methods that take an explicit source class name and source method name. These methods are intended for developers who want to be able to quickly locate the source of any given logging message. An example of this style is:

void warning(String sourceClass, String sourceMethod, String msg);

Second, there are a set of methods that do not take explicit source class or source method names. These are intended for

Page 105: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 105 of 158

© Einstein college of engineering

developers who want easy-to-use logging and do not require detailed source information.

void warning(String msg);

For this second set of methods, the Logging framework will make a "best effort" to determine which class and method called into the logging framework and will add this information into the LogRecord. However, it is important to realize that this automatically inferred information may only be approximate. The latest generation of virtual machines perform extensive optimizations when JITing and may entirely remove stack frames, making it impossible to reliably locate the calling class and method.

Handlers

J2SE provides the following Handlers:

StreamHandler: A simple handler for writing formatted records to an

OutputStream.

ConsoleHandler: A simple handler for writing formatted records to System.err

FileHandler: A handler that writes formatted log records either to a single file, or

to a set of rotating log files.

SocketHandler: A handler that writes formatted log records to remote TCP ports.

MemoryHandler: A handler that buffers log records in memory.

It is fairly straightforward to develop new Handlers. Developers requiring specific functionality can either develop a Handler from scratch or subclass one of the provided Handlers.

Formatters

J2SE also includes two standard Formatters:

SimpleFormatter: Writes brief "human-readable" summaries of log records.

XMLFormatter: Writes detailed XML-structured information.

As with Handlers, it is fairly straightforward to develop new Formatters.

The LogManager

There is a global LogManager object that keeps track of global logging information. This

includes:

A hierarchical namespace of named Loggers.

Page 106: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 106 of 158

© Einstein college of engineering

A set of logging control properties read from the configuration file.

There is a single LogManager object that can be retrieved using the static

LogManager.getLogManager method. This is created during LogManager

initialization, based on a system property. This property allows container

applications (such as EJB containers) to substitute their own subclass of

LogManager in place of the default class.

Create a logger

The package java.util.logging provides the logging capabilities via the class Logger.

To create a logger in your Java coding.

import java.util.logging.Logger;

private final static Logger LOGGER = Logger.getLogger(MyClass.class .getName());

Level

The log levels define the severity of a message. The class Level is used to define which messages should be written to the log.

Die Log Levels in descending order are:

SEVERE (highest) WARNING INFO CONFIG FINE FINER FINEST

In addition to that you have also the levels OFF and ALL to turn the logging of or to log everything.

For example the following will set the logger to level info which means all messages with severe, warning and info will be logged.

LOGGER.setLevel(Level.INFO);

Page 107: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 107 of 158

© Einstein college of engineering

An Example

To help motivate the use of the logging API, we will use a simple program, based on the idea of a "Hello World" program.

public class HelloWorld {

public static void main(String[] args) {

HelloWorld hello = new HelloWorld("Hello world!");

hello.sayHello();

}

private String theMessage;

public HelloWorld(String message) {

theMessage = message;

}

public void sayHello() {

System.err.println(theMessage);

}

}

We will expand upon this simple program in order to demonstrate and motivate the logging API. The first thing we will do is actually generate a logging message. This is straightforward; we need to create a Logger object, which represents theHelloWorld class, like this:

package logging.example2;

import java.util.logging.Logger;

/**

* A simple Java Hello World program, in the tradition of

* Kernighan and Ritchie.

*/

public class HelloWorld {

private static Logger theLogger =

Logger.getLogger(HelloWorld.class.getName());

public static void main(String[] args) {

HelloWorld hello = new HelloWorld("Hello world!");

hello.sayHello();

}

private String theMessage;

Page 108: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 108 of 158

© Einstein college of engineering

public HelloWorld(String message) {

theMessage = message;

}

public void sayHello() {

System.err.println(theMessage);

}

}

This generates a Logger, which we can use to generate logging messages. Since you typically use one logger per class, we can make it a static field of the HelloWorld class. We use the fully qualified name of the HelloWorld class as the name of theLogger. We'll look at the reasons for this in more detail later. Now, let's actually use the Logger to try to generate a logging message:

import java.util.logging.Logger;

public class HelloWorld {

private static Logger theLogger =

Logger.getLogger(HelloWorld.class.getName());

public static void main(String[] args) {

HelloWorld hello = new HelloWorld("Hello world!");

hello.sayHello();

}

private String theMessage;

public HelloWorld(String message) {

theMessage = message;

}

public void sayHello() {

theLogger.finest("Hello logging!");

System.err.println(theMessage);

}

}

The logging API has a configuration file and by default, it provides a handler that will send logging messages, in the form of aLogRecord to the console (System.err). So we would expect to see the string "Hello logging!"; appear before our message of "Hello

world!". But if you run this program you only see "Hello world!":

Page 109: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 109 of 158

© Einstein college of engineering

% java logging.example3.HelloWorld

Hello world

What's going on here? The answer lies in the notion of logging levels.

Assertions

An assertion has a Boolean expression that, if evaluated as false, indicates a bug in the code. This mechanism provides a way to detect when a program starts falling into an inconsistent state. Assertions are excellent for documenting assumptions and invariants about a class. Here is a simple example of assertion:

BankAccount acct = null;

// ...

// Get a BankAccount object

// ...

// Check to ensure we have one

assert acct != null;

This asserts that acct is not null. If acct is null, an AssertionError is thrown. Any line that executes after the assert statement can safely assume that acct is not null.

Using assertions helps developers write code that is more correct, more readable, and easier to maintain. Thus, assertions improve the odds that the behavior of a class matches the expectations of its clients.

Note that assertions can be compiled out. In languages such as C/C++, this means using the preprocessor. In C/C++, you can use assertions through the assert macro, which has the following definition in ANSI C:

void assert(int expression)

The program will be aborted if the expression evaluates to false, and it has no effect if the expression evaluates to true. When testing and debugging is completed, assertions do not have to be removed from the program. However, note that the program will be larger in size and therefore slower to load. When assertions are no longer needed, the line

#define NDEBUG

Page 110: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 110 of 158

© Einstein college of engineering

is inserted at the beginning of the program. This causes the C/C++ preprocessor to ignore all assertions, instead of deleting them manually.

In other words, this is a requirement for performance reasons. You should write assertions into software in a form that can be optionally compiled. Thus, assertions should be executed with the code only when you are debugging your program -- that is, when assertions will really help flush out errors. You can think of assertions as a uniform mechanism that replaces the use of ad hoc conditional tests.

Implementing Assertions in Java Technology

J2SE 1.3 and earlier versions have no built-in support for assertions. They can, however, be provided as an ad hoc solution. Here is an example of how you would roll your own assertion class.

Here we have an assert method that checks whether a Boolean expression is true or false. If the expression evaluates to true, then there is no effect. But if it evaluates to false, the assert method prints the stack trace and the program aborts. In this sample implementation, a second argument for a string is used so that the cause of error can be printed.

Note that in the assert method, I am checking whether the value of NDEBUG is on (true) or off (false). If NDEBUG sets to true, then the assertion is to be executed. Otherwise, it would have no effect. The user of this class is able to set assertions on or off by toggling the value of NDEBUG. Code Sample 1 shows my implementation.

public class Assertion {

public static boolean NDEBUG = true;

private static void printStack(String why) {

Throwable t = new Throwable(why);

t.printStackTrace();

System.exit(1);

}

public static void assert(boolean expression, String why) {

if (NDEBUG && !expression) {

printStack(why);

}

Page 111: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 111 of 158

© Einstein college of engineering

}

}

Note: In order for Code Sample 1 to compile, use -source 1.3 because assert is a

keyword as of J2SE 1.4. Otherwise, you will get the following error message:

C:\CLASSES>javac Assertion.java

Assertion.java:11: as of release 1.4, 'assert' is a keyword, and may not be used

as an identifier

(try -source 1.3 or lower to use 'assert' as an identifier)

public static void assert(boolean expression, String why) {

^

1 error

Code Sample 2 demonstrates how to use the Assertion class. In this example, an integer representing the user's age is read. If the age is greater than or equal to 18, the assertion evaluates to true, and it will have no effect on the program execution. But if the age is less than 18, the assertion evaluates to false. The program then aborts, displays the message You are too young to vote, and shows the stack trace.

It is important to note that in this example assertions are used to validate user input and

that no invariant is being tested or verified. This is merely to demonstrate the use of

assertions.

import java.util.Scanner;

import java.io.IOException;

public class AssertionTest1 {

public static void main(String argv[]) throws IOException {

Scanner reader = new Scanner(System.in);

System.out.print("Enter your age: ");

int age = reader.nextInt();

//Assertion.NDEBUG=false;

Assertion.assert(age>=18, "You are too young to vote");

// use age

System.out.println("You are eligible to vote");

}

}

import java.io.IOException;

public class AssertionTest2 {

public static void main(String argv[]) throws IOException {

System.out.print("Enter your marital status: ");

int c = System.in.read();

Page 112: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 112 of 158

© Einstein college of engineering

//Assertion.NDEBUG=false;

switch ((char) c) {

case 's':

case 'S': System.out.println("Single"); break;

case 'm':

case 'M': System.out.println("Married"); break;

case 'd':

case 'D': System.out.println("Divorced"); break;

default: Assertion.assert(!true, "Invalid Option"); break;

}

}

}

In the three examples, if you do not want assertions to be executed as part of the code, uncomment the line

Assert.NDEBUG = false;

Using Assertions

Use the assert statement to insert assertions at particular points in the code. The assert statement can have one of two forms:

assert booleanExpression;

assert booleanExpression : errorMessage;

The errorMessage is an optional string message that would be shown when an assertion fails.

As an example, I will modify Code Sample 3 to use the assert statement instead of my Assertion class, as shown in Code Sample 4.

import java.io.*;

public class AssertionTest3 {

public static void main(String argv[]) throws IOException {

System.out.print("Enter your marital status: ");

int c = System.in.read();

switch ((char) c) {

case 's':

case 'S': System.out.println("Single"); break;

case 'm':

case 'M': System.out.println("Married"); break;

case 'd':

Page 113: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 113 of 158

© Einstein college of engineering

case 'D': System.out.println("Divorced"); break;

default: assert !true : "Invalid Option"; break;

}

}

}

prompt> javac -source 1.4 AssertionTest3.java

If you try to compile your assertion-enabled classes without using the -source

1.4 option, you will get a compiler error saying that assert is a new keyword as of

release 1.4.

If you now run the program using the command

prompt> java AssertionTest3

and you enter a valid character, it will work fine. However, if you enter an invalid character, nothing will happen. This is because, by default, assertions are disabled at runtime. To enable assertions, use the switch -enableassertion (or -ea) as follows:

prompt> java -ea AssertionTest3 prompt> java -enableassertion AssertionTest3

Following is a sample run:

C:\CLASSES>java -ea AssertionTest3

Enter your marital status: w

Exception in thread "main" java.lang.AssertionError: Invalid Option

at AssertionTest3.main(AssertionTest3.java:15)

When an assertion fails, it means that the application has entered an incorrect state. Possible behaviors may include suspending the program or allowing it to continue to run. A good behavior, however, might be to terminate the application, because it may start functioning inappropriately after a failure. In this case, when an assertion fails, an AssertionError is thrown.

Note: By default, assertions are disabled, so you must not assume that the Boolean

expression contained in an assertion will be evaluated. Therefore, your expressions must

be free of side effects.

The switch -disableassertion (or -da) can be used to disable assertions. This, however, is most useful when you wish to disable assertions on classes from specific packages. For example, to run the program MyClass with assertions disabled in class Hello, you can use the following command:

Page 114: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 114 of 158

© Einstein college of engineering

prompt> java -da:com.javacourses.tests.Hello MyClass

And to disable assertions in a specific package and any subpackages it may have, you can use the following command:

prompt> java -da:com.javacourses.tests... MyClass

Note that the three-dot ellipsis (...) is part of the syntax.

Switches can be combined. For example, to run a program with assertions enabled in the com.javacourses.tests package (and any subpackages) and disabled in the class com.javacourses.ui.phone, you can use the following command:

prompt> java -ea:com.javacourses.tests... -da:com.javacourses.ui.phone MyClass

Note that when switches are combined and applied to packages, they are applied to all classes, including system classes (which do not have class loaders). But if you use them with no arguments (-ea or -da), they do not apply to system classes. In other words, if you use the command

prompt> java -ea MyClass

then assertions are enabled in all classes except system classes. If you wish to turn assertions on or off in system classes, use the switches -enablesystemassertions (or -esa) and -disablesystemassertions (or -dsa).

Using Assertions for Design by Contract

The assertion facility can help you in supporting an informal design-by-contract style of programming. We will now see examples of using assertions for preconditions, postconditions, and class invariants. The examples are snippets of code from an integer stack, which provides operations such as push to add an item on the stack and pop to retrieve an item from the stack.

Preconditions

In order to retrieve an item from the stack, the stack must not be empty. The condition that the stack must not be empty is a precondition. This precondition can be programmed using assertions as follows:

public int pop() {

// precondition

assert !isEmpty() : "Stack is empty";

return stack[--num];

Page 115: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 115 of 158

© Einstein college of engineering

}

Note: Because assertions might be disabled in some cases, precondition checking can still

be performed by checks inside methods that result in exceptions such

asIllegalArgumentException or NullPointerException.

Postconditions

In order to push an item on the stack, the stack must not be full. This is a precondition. To add an item on the stack, we assign the element to be added to the next index in the stack as follows:

stack[num++] = element;

However, if you make a mistake and you write this statement as

stack[num] = element

then you have a bug. In this case, we need to ensure that invoking the push operation is working correctly. So the postcondition here is to ensure that the new index in the stack is the old index plus one. Also, we need to make sure that the element has been added on the stack. The following snippet of code shows the push operation with a precondition and a postcondition.

public void push(int element) {

// precondition

assert num<capacity : "stack is full";

int oldNum = num;

stack[num] = element;

// postcondition

assert num == oldNum+1 && stack[num-1] == element : "problem with counter";

}

Note that if a method has multiple return statements, then postconditions should be evaluated before each of these return statements.

Class Invariants

A class invariant is a predicate that must be true before and after any method completes. In the stack example, the invariant would be that the number of elements in the stack is greater than or equal to zero and the number of elements should not exceed the maximum capacity of the class. These conditions, for example, can be coded as follows:

Page 116: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 116 of 158

© Einstein college of engineering

private boolean inv() {

return (num >= 0 && num < capacity);

}

To check that the stack should satisfy this predicate at all times, each public method and constructor should contain the assertion

assert inv();

right before each return.

UNIT V

Multi Threading:

Java provides built-in support for multithreaded programming. A multithreaded

program contains two or more parts that can run concurrently. Each part of such a

program is called a thread, and each thread defines a separate path of execution.

A multithreading is a specialized form of multitasking. Multitasking threads

require less overhead than multitasking processes.

A process consists of the memory space allocated by the operating system that

can contain one or more threads. A thread cannot exist on its own; it must be a part of a

process. A process remains running until all of the non-daemon threads are done

executing.

Multithreading enables you to write very efficient programs that make maximum

use of the CPU, because idle time can be kept to a minimum.

Life Cycle of a Thread:

A thread goes through various stages in its life cycle. For example, a thread is

born, started, runs, and then dies. Following diagram shows complete life cycle of a

thread.

Page 117: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 117 of 158

© Einstein college of engineering

Above mentioned stages are explained here:

New: A new thread begins its life cycle in the new state. It remains in this state

until the program starts the thread. It is also referred to as a born thread.

Runnable: After a newly born thread is started, the thread becomes runnable. A

thread in this state is considered to be executing its task.

Waiting: Sometimes a thread transitions to the waiting state while the thread waits

for another thread to perform a task.A thread transitions back to the runnable state

only when another thread signals the waiting thread to continue executing.

Timed waiting: A runnable thread can enter the timed waiting state for a specified

interval of time. A thread in this state transitions back to the runnable state when

that time interval expires or when the event it is waiting for occurs.

Terminated: A runnable thread enters the terminated state when it completes its

task or otherwise terminates.

Creating a Thread:

Java defines two ways in which this can be accomplished:

You can implement the Runnable interface.

You can extend the Thread class, itself.

Create Thread by Implementing Runnable:

The easiest way to create a thread is to create a class that implements the Runnable

interface.

To implement Runnable, a class need only implement a single method called run( ),

which is declared like this:

Page 118: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 118 of 158

© Einstein college of engineering

public void run( )

You will define the code that constitutes the new thread inside run() method. It is

important to understand that run() can call other methods, use other classes, and declare

variables, just like the main thread can.

After you create a class that implements Runnable, you will instantiate an object of type

Thread from within that class. Thread defines several constructors. The one that we will

use is shown here:

Thread(Runnable threadOb, String threadName);

Here threadOb is an instance of a class that implements the Runnable interface and the

name of the new thread is specified by threadName.

After the new thread is created, it will not start running until you call its start( ) method,

which is declared within Thread. The start( ) method is shown here:

void start( );

Example:

Here is an example that creates a new thread and starts it running:

class NewThread implements Runnable {

Thread t;

NewThread() {

// Create a new, second thread

t = new Thread(this, "Demo Thread");

System.out.println("Child thread: " + t);

t.start(); // Start the thread

}

public void run() {

try {

for(int i = 5; i > 0; i--) {

System.out.println("Child Thread: " + i);

// Let the thread sleep for a while.

Thread.sleep(500);

}

} catch (InterruptedException e) {

System.out.println("Child interrupted.");

}

System.out.println("Exiting child thread.");

}

}

class ThreadDemo {

public static void main(String args[]) {

new NewThread(); // create a new thread

try {

Page 119: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 119 of 158

© Einstein college of engineering

for(int i = 5; i > 0; i--) {

System.out.println("Main Thread: " + i);

Thread.sleep(1000);

}

} catch (InterruptedException e) {

System.out.println("Main thread interrupted.");

}

System.out.println("Main thread exiting.");

}

}

This would produce following result:

Child thread: Thread[Demo Thread,5,main]

Main Thread: 5

Child Thread: 5

Child Thread: 4

Main Thread: 4

Child Thread: 3

Child Thread: 2

Main Thread: 3

Child Thread: 1

Exiting child thread.

Main Thread: 2

Main Thread: 1

Main thread exiting.

Create Thread by Extending Thread:

The second way to create a thread is to create a new class that extends Thread, and then

to create an instance of that class.

The extending class must override the run( ) method, which is the entry point for the new

thread. It must also call start( ) to begin execution of the new thread.

Example:

Here is the preceding program rewritten to extend Thread:

class NewThread extends Thread {

NewThread() {

// Create a new, second thread

super("Demo Thread");

System.out.println("Child thread: " + this);

start(); // Start the thread

}

// This is the entry point for the second thread.

public void run() {

Page 120: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 120 of 158

© Einstein college of engineering

try {

for(int i = 5; i > 0; i--) {

System.out.println("Child Thread: " + i);

// Let the thread sleep for a while.

Thread.sleep(500);

}

} catch (InterruptedException e) {

System.out.println("Child interrupted.");

}

System.out.println("Exiting child thread.");

}

}

class ExtendThread {

public static void main(String args[]) {

new NewThread(); // create a new thread

try {

for(int i = 5; i > 0; i--) {

System.out.println("Main Thread: " + i);

Thread.sleep(1000);

}

} catch (InterruptedException e) {

System.out.println("Main thread interrupted.");

}

System.out.println("Main thread exiting.");

}

}

This would produce following result:

Child thread: Thread[Demo Thread,5,main]

Main Thread: 5

Child Thread: 5

Child Thread: 4

Main Thread: 4

Child Thread: 3

Child Thread: 2

Main Thread: 3

Child Thread: 1

Exiting child thread.

Main Thread: 2

Main Thread: 1

Main thread exiting.

Thread Methods:

Following is the list of important medthods available in the Thread class.

Page 121: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 121 of 158

© Einstein college of engineering

SN Methods with Description

1

public void start()

Starts the thread in a separate path of execution, then invokes the run() method on this

Thread object.

2

public void run()

If this Thread object was instantiated using a separate Runnable target, the run() method is

invoked on that Runnable object.

3

public final void setName(String name)

Changes the name of the Thread object. There is also a getName() method for retrieving

the name.

4 public final void setPriority(int priority)

Sets the priority of this Thread object. The possible values are between 1 and 10.

5 public final void setDaemon(boolean on)

A parameter of true denotes this Thread as a daemon thread.

6

public final void join(long millisec)

The current thread invokes this method on a second thread, causing the current thread to

block until the second thread terminates or the specified number of milliseconds passes.

7 public void interrupt()

Interrupts this thread, causing it to continue execution if it was blocked for any reason.

8

public final boolean isAlive()

Returns true if the thread is alive, which is any time after the thread has been started but

before it runs to completion.

The previous methods are invoked on a particular Thread object. The following methods

in the Thread class are static. Invoking one of the static methods performs the operation

on the currently running thread

SN Methods with Description

1

public static void yield()

Causes the currently running thread to yield to any other threads of the same priority that

are waiting to be scheduled

2

public static void sleep(long millisec)

Causes the currently running thread to block for at least the specified number of

milliseconds

3 public static boolean holdsLock(Object x)

Returns true if the current thread holds the lock on the given Object.

4

public static Thread currentThread()

Returns a reference to the currently running thread, which is the thread that invokes this

method.

5

public static void dumpStack()

Prints the stack trace for the currently running thread, which is useful when debugging a

multithreaded application.

Example:

The following ThreadClassDemo program demonstrates some of these methods of the

Thread class:

Page 122: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 122 of 158

© Einstein college of engineering

public class DisplayMessage implements Runnable

{

private String message;

public DisplayMessage(String message)

{

this.message = message;

}

public void run()

{

while(true)

{

System.out.println(message);

}

}

}

// File Name : GuessANumber.java

// Create a thread to extentd Thread

public class GuessANumber extends Thread

{

private int number;

public GuessANumber(int number)

{

this.number = number;

}

public void run()

{

int counter = 0;

int guess = 0;

do

{

guess = (int) (Math.random() * 100 + 1);

System.out.println(this.getName()

+ " guesses " + guess);

counter++;

}while(guess != number);

System.out.println("** Correct! " + this.getName()

+ " in " + counter + " guesses.**");

}

}

// File Name : ThreadClassDemo.java

public class ThreadClassDemo

{

public static void main(String [] args)

Page 123: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 123 of 158

© Einstein college of engineering

{

Runnable hello = new DisplayMessage("Hello");

Thread thread1 = new Thread(hello);

thread1.setDaemon(true);

thread1.setName("hello");

System.out.println("Starting hello thread...");

thread1.start();

Runnable bye = new DisplayMessage("Goodbye");

Thread thread2 = new Thread(hello);

thread2.setPriority(Thread.MIN_PRIORITY);

thread2.setDaemon(true);

System.out.println("Starting goodbye thread...");

thread2.start();

System.out.println("Starting thread3...");

Thread thread3 = new GuessANumber(27);

thread3.start();

try

{

thread3.join();

}catch(InterruptedException e)

{

System.out.println("Thread interrupted.");

}

System.out.println("Starting thread4...");

Thread thread4 = new GuessANumber(75);

thread4.start();

System.out.println("main() is ending...");

}

}

This would produce following result. You can try this example again and again and you

would get different result every time.

Starting hello thread...

Starting goodbye thread...

Hello

Hello

Hello

Hello

Hello

Hello

Hello

Hello

Page 124: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 124 of 158

© Einstein college of engineering

Hello

Thread-2 guesses 27

Hello

** Correct! Thread-2 in 102 guesses.**

Hello

Starting thread4...

Hello

Hello

..........remaining result produced

Interrupting thrreads:

Interrupting a thread means stopping what it is doing before it has completed its task,

effectively aborting its current operation. Whether the thread dies, waits for new tasks, or

goes on to the next step depends on the application.

Although it may seem simple at first, you must take some precautions in order to achieve

the desired result. There are some caveats you must be aware of as well.

First of all, forget the Thread.stop method. Although it indeed stops a running thread, the

method is unsafe and was deprecated, which means it may not be available in future

versions of the Java.

Another method that can be confusing for the unadvised is Thread.interrupt. Despite what

its name may imply, the method does not interrupt a running thread (more on this later),

as Listing A demonstrates. It creates a thread and tries to stop it usingThread.interrupt.

The calls to Thread.sleep() give plenty of time for the thread initialization and

termination. The thread itself does not do anything useful.

Listing A:

class Example1 extends Thread {

public static void main( String args[] ) throws Exception {

Example1 thread = new Example1();

System.out.println( "Starting thread..." );

thread.start();

Thread.sleep( 3000 );

System.out.println( "Interrupting thread..." );

thread.interrupt();

Thread.sleep( 3000 );

System.out.println( "Stopping application..." );

System.exit( 0 );

}

public void run() {

while ( true ) {

System.out.println( "Thread is running..." );

long time = System.currentTimeMillis();

Page 125: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 125 of 158

© Einstein college of engineering

while ( System.currentTimeMillis()-time < 1000 ) {

}

}

}

}

If you run the code in Listing A, you should see something like this on your console:

Starting thread...

Thread is running...

Thread is running...

Thread is running...

Interrupting thread...

Thread is running...

Thread is running...

Thread is running...

Stopping application...

Even after Thread.interrupt() is called, the thread continues to run for a while.

Really interrupting a thread

The best, recommended way to interrupt a thread is to use a shared variable to signal that

it must stop what it is doing. The thread must check the variable periodically, especially

during lengthy operations, and terminate its task in an orderly manner.Listing

B demonstrates this technique.

Listing B: class Example2 extends Thread {

volatile boolean stop = false;

public static void main( String args[] ) throws Exception {

Example2 thread = new Example2();

System.out.println( "Starting thread..." );

thread.start();

Thread.sleep( 3000 );

System.out.println( "Asking thread to stop..." );

thread.stop = true;

Thread.sleep( 3000 );

System.out.println( "Stopping application..." );

System.exit( 0 );

}

public void run() {

while ( !stop ) {

System.out.println( "Thread is running..." );

long time = System.currentTimeMillis();

while ( (System.currentTimeMillis()-time < 1000) && (!stop) ) {

}

}

System.out.println( "Thread exiting under request..." );

Page 126: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 126 of 158

© Einstein college of engineering

}

}

Running the code in Listing B will generate output like this (notice how the thread exits

in an orderly fashion):

Starting thread...

Thread is running...

Thread is running...

Thread is running...

Asking thread to stop...

Thread exiting under request...

Stopping application...

Although this method requires some coding, it is not difficult to implement and give the

thread the opportunity to do any cleanup needed, which is an absolute requirement for

any multithreaded application. Just be sure to declare the shared variable as volatile or

enclose any access to it into synchronized blocks/methods.

So far, so good! But what happens if the thread is blocked waiting for some event? Of

course, if the thread is blocked, it can't check the shared variable and can't stop. There are

plenty of situations when that may occur, such as

calling Object.wait(),ServerSocket.accept(), and DatagramSocket.receive(), to name a

few.

They all can block the thread forever. Even if a timeout is employed, it may not be

feasible or desirable to wait until the timeout expires, so a mechanism to prematurely exit

the blocked state must be used.

Unfortunately there is no such mechanism that works for all cases, but the particular

technique to use depends on each situation. In the following sections, I'll give solutions

for the most common cases.

Interrupting a thread with Thread.interrupt()

As demonstrated in Listing A, the method Thread.interrupt() does not interrupt a running

thread. What the method actually does is to throw an interrupt if the thread is blocked, so

that it exits the blocked state. More precisely, if the thread is blocked at one of the

methods Object.wait, Thread.join, or Thread.sleep, it receives anInterruptedException,

thus terminating the blocking method prematurely.

So, if a thread blocks in one of the aforementioned methods, the correct way to stop it is

to set the shared variable and then call the interrupt() method on it (notice that it is

important to set the variable first). If the thread is not blocked, calling interrupt() will not

hurt; otherwise, the thread will get an exception (the thread must be prepared to handle

this condition) and escape the blocked state. In either case, eventually the thread will test

Page 127: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 127 of 158

© Einstein college of engineering

the shared variable and stop. Listing C is a simple example that demonstrates this

technique.

Listing C: class Example3 extends Thread {

volatile boolean stop = false;

public static void main( String args[] ) throws Exception {

Example3 thread = new Example3();

System.out.println( "Starting thread..." );

thread.start();

Thread.sleep( 3000 );

System.out.println( "Asking thread to stop..." );

thread.stop = true;

thread.interrupt();

Thread.sleep( 3000 );

System.out.println( "Stopping application..." );

System.exit( 0 );

}

public void run() {

while ( !stop ) {

System.out.println( "Thread running..." );

try {

Thread.sleep( 1000 );

} catch ( InterruptedException e ) {

System.out.println( "Thread interrupted..." );

}

}

System.out.println( "Thread exiting under request..." );

}

}

As soon as Thread.interrupt() is called in Listing C, the thread gets an exception so that it

escapes the blocked state and determines that it should stop. Running this code produces

output like this:

Starting thread...

Thread running...

Thread running...

Thread running...

Asking thread to stop...

Thread interrupted...

Thread exiting under request...

Stopping application...

Interrupting an I/O operation

But what happens if the thread is blocked on an I/O operation? I/O can block a thread for

a considerable amount of time, particularly if network communication is involved. For

example, a server may be waiting for a request, or a network application may be waiting

for an answer from a remote host.

Page 128: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 128 of 158

© Einstein college of engineering

If you're using channels, available with the new I/O API introduced in Java 1.4, the

blocked thread will get a ClosedByInterruptException exception. If that is the case, the

logic is the same as that used in the third example—only the exception is different.

But you might be using the traditional I/O available since Java 1.0, since the new I/O is

so recent and requires more work. In this case, Thread.interrupt() doesn't help, since the

thread will not exit the blocked state. Listing D demonstrates that behavior. Although

the interrupt() method is called, the thread does not exit the blocked state.

Listing D: import java.io.*;

class Example4 extends Thread {

public static void main( String args[] ) throws Exception {

Example4 thread = new Example4();

System.out.println( "Starting thread..." );

thread.start();

Thread.sleep( 3000 );

System.out.println( "Interrupting thread..." );

thread.interrupt();

Thread.sleep( 3000 );

System.out.println( "Stopping application..." );

System.exit( 0 );

}

public void run() {

ServerSocket socket;

try {

socket = new ServerSocket(7856);

} catch ( IOException e ) {

System.out.println( "Could not create the socket..." );

return;

}

while ( true ) {

System.out.println( "Waiting for connection..." );

try {

Socket sock = socket.accept();

} catch ( IOException e ) {

System.out.println( "accept() failed or interrupted..." );

}

}

}

}

Fortunately, the Java Platform provides a solution for that case by calling

the close()method of the socket the thread is blocked in. In this case, if the thread is

blocked in an I/O operation, the thread will get a SocketException exception, much like

theinterrupt() method causes an InterruptedException to be thrown.

Page 129: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 129 of 158

© Einstein college of engineering

The only caveat is that a reference to the socket must be available so that

its close()method can be called. That means the socket object must also be shared. Listing

Edemonstrates this case. The logic is the same as in the examples presented so far.

And here's the sample output you can expect from running Listing E:

Listing E: import java.net.*;

import java.io.*;

class Example5 extends Thread {

volatile boolean stop = false;

volatile ServerSocket socket;

public static void main( String args[] ) throws Exception {

Example5 thread = new Example5();

System.out.println( "Starting thread..." );

thread.start();

Thread.sleep( 3000 );

System.out.println( "Asking thread to stop..." );

thread.stop = true;

thread.socket.close();

Thread.sleep( 3000 );

System.out.println( "Stopping application..." );

System.exit( 0 );

}

public void run() {

try {

socket = new ServerSocket(7856);

} catch ( IOException e ) {

System.out.println( "Could not create the socket..." );

return;

}

while ( !stop ) {

System.out.println( "Waiting for connection..." );

try {

Socket sock = socket.accept();

} catch ( IOException e ) {

System.out.println( "accept() failed or interrupted..." );

}

}

System.out.println( "Thread exiting under request..." );

}

}

Starting thread...

Waiting for connection...

Asking thread to stop...

accept() failed or interrupted...

Thread exiting under request...

Stopping application...

Page 130: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 130 of 158

© Einstein college of engineering

Multithreading is a powerful tool, but it presents its own set of challenges. One of these is

how to interrupt a running thread. If properly implemented, these techniques make

interrupting a thread no more difficult than using the built-in operations already provided

by the Java Platform.

Thread Priorities:

Every Java thread has a priority that helps the operating system determine the order in

which threads are scheduled.

Java priorities are in the range between MIN_PRIORITY (a constant of 1) and

MAX_PRIORITY (a constant of 10). By default, every thread is given priority

NORM_PRIORITY (a constant of 5).

Threads with higher priority are more important to a program and should be allocated

processor time before lower-priority threads. However, thread priorities cannot guarantee

the order in which threads execute and very much platform dependentant.

Setting a threads priority can be very useful if one thread has more critical tasks to

perform than another.

The Thread class has a method called setPriority(int level) with which you can alter the

priority a Thread instance has.

The priority level range from 1 (least important) to 10 (most important) and if no level is

explicitly set, a Thread instance has the priority level of 5.

In the first example below no priorites are set, so both threads have the priority level 5.

The TestThread class implements the Runnable interface and in its

run() method loops from 1 to 10 and output the number along with its Thread id, which is

passed to the constructor.

public class Main {

public void setPrioritiesOnThreads() {

Thread thread1 = new Thread(new TestThread(1));

Thread thread2 = new Thread(new TestThread(2));

thread1.start();

thread2.start();

try {

thread1.join();

thread2.join();

} catch (InterruptedException ex) {

ex.printStackTrace();

Page 131: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 131 of 158

© Einstein college of engineering

}

System.out.println("Done.");

}

public static void main(String[] args) {

new Main().setPrioritiesOnThreads();

}

class TestThread implements Runnable {

int id;

public TestThread(int id) {

this.id = id;

}

public void run() {

for (int i = 1; i <= 10; i++) {

System.out.println("Thread" + id + ": " + i);

}

}

}

}

Since both threads have the same priority, the output will be a mix between them and

could look like this:

Thread2: 1

Thread1: 1

Thread2: 2

Thread1: 2

Thread2: 3

Thread1: 3

Thread2: 4

Thread1: 4

Thread2: 5

Thread1: 5

Thread2: 6

Thread1: 6

Thread2: 7

Thread2: 8

Page 132: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 132 of 158

© Einstein college of engineering

Thread2: 9

Thread2: 10

Thread1: 7

Thread1: 8

Thread1: 9

Thread1: 10

Done.

The output could look different from on execution to another since we have no control of

how the CPU will prioritize them.

If we set the priority on the threads we still haven't got exact control of the execution, but

at least we can tell the CPU which one we think is

most important. The next example is identical to the one above except for the lines where

the priority of the threads are set:

public class Main {

public void setPrioritiesOnThreads() {

Thread thread1 = new Thread(new TestThread(1));

Thread thread2 = new Thread(new TestThread(2));

//Setting priorities on the Thread objects

thread1.setPriority(Thread.MAX_PRIORITY);

thread2.setPriority(Thread.MIN_PRIORITY);

thread1.start();

thread2.start();

try {

//Wait for the threads to finish

thread1.join();

thread2.join();

} catch (InterruptedException ex) {

ex.printStackTrace();

}

System.out.println("Done.");

}

public static void main(String[] args) {

new Main().setPrioritiesOnThreads();

}

Page 133: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 133 of 158

© Einstein college of engineering

class TestThread implements Runnable {

int id;

public TestThread(int id) {

this.id = id;

}

public void run() {

for (int i = 1; i <= 10; i++) {

System.out.println("Thread" + id + ": " + i);

}

}

}

}

The output from the code looked like this when executed:

Thread1: 1

Thread1: 2

Thread1: 3

Thread1: 4

Thread1: 5

Thread1: 6

Thread1: 7

Thread1: 8

Thread1: 9

Thread1: 10

Thread2: 1

Thread2: 2

Thread2: 3

Thread2: 4

Thread2: 5

Thread2: 6

Thread2: 7

Thread2: 8

Thread2: 9

Thread2: 10

Done.

It is however not certain that the first thread will be prioritized to finish before the second

thread starts every time. It is up to the CPU to decide.

Page 134: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 134 of 158

© Einstein college of engineering

Thread Synchronization :

When two or more threads need access to a shared resource, they need some way to

ensure that the resource will be used by only one thread at a time.

The process by which this synchronization is achieved is called thread synchronization.

The synchronized keyword in Java creates a block of code referred to as a critical section.

Every Java object with a critical section of code gets a lock associated with the object. To

enter a critical section, a thread needs to obtain the corresponding object's lock.

This is the general form of the synchronized statement:

synchronized(object) {

// statements to be synchronized

}

Here, object is a reference to the object being synchronized. A synchronized block

ensures that a call to a method that is a member of object occurs only after the current

thread has successfully entered object's monitor.

Here is an example, using a synchronized block within the run( ) method:

class Callme {

void call(String msg) {

System.out.print("[" + msg);

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

System.out.println("Interrupted");

}

System.out.println("]");

}

}

// File Name : Caller.java

class Caller implements Runnable {

String msg;

Callme target;

Thread t;

public Caller(Callme targ, String s) {

target = targ;

msg = s;

t = new Thread(this);

t.start();

}

// synchronize calls to call()

public void run() {

Page 135: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 135 of 158

© Einstein college of engineering

synchronized(target) { // synchronized block

target.call(msg);

}

}

}

// File Name : Synch.java

class Synch {

public static void main(String args[]) {

Callme target = new Callme();

Caller ob1 = new Caller(target, "Hello");

Caller ob2 = new Caller(target, "Synchronized");

Caller ob3 = new Caller(target, "World");

// wait for threads to end

try {

ob1.t.join();

ob2.t.join();

ob3.t.join();

} catch(InterruptedException e) {

System.out.println("Interrupted");

}

}

}

This would produce following result:

[Hello]

[World]

[Synchronized]

Interthread Communication:

Consider the classic queuing problem, where one thread is producing some data and

another is consuming it. To make the problem more interesting, suppose that the producer

has to wait until the consumer is finished before it generates more data.

In a polling system, the consumer would waste many CPU cycles while it waited for the

producer to produce. Once the producer was finished, it would start polling, wasting more

CPU cycles waiting for the consumer to finish, and so on. Clearly, this situation is

undesirable.

To avoid polling, Java includes an elegant interprocess communication mechanism via

the following methods:

wait( ): This method tells the calling thread to give up the monitor and go to sleep

until some other thread enters the same monitor and calls notify( ).

notify( ): This method wakes up the first thread that called wait( ) on the same

object.

Page 136: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 136 of 158

© Einstein college of engineering

notifyAll( ): This method wakes up all the threads that called wait( ) on the same

object.c The highest priority thread will run first.

These methods are implemented as final methods in Object, so all classes have them. All

three methods can be called only from within a synchronized context.

These methods are declared within Object. Various forms of wait( ) exist that allow you

to specify a period of time to wait.

Example:

The following sample program consists of four classes: Q, the queue that you're trying to

synchronize; Producer, the threaded object that is producing queue entries; Consumer, the

threaded object that is consuming queue entries; and PC, the tiny class that creates the

single Q, Producer, and Consumer.

The proper way to write this program in Java is to use wait( ) and notify( ) to signal in

both directions, as shown here:

class Q {

int n;

boolean valueSet = false;

synchronized int get() {

if(!valueSet)

try {

wait();

} catch(InterruptedException e) {

System.out.println("InterruptedException caught");

}

System.out.println("Got: " + n);

valueSet = false;

notify();

return n;

}

synchronized void put(int n) {

if(valueSet)

try {

wait();

} catch(InterruptedException e) {

System.out.println("InterruptedException caught");

}

this.n = n;

valueSet = true;

System.out.println("Put: " + n);

notify();

}

}

Page 137: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 137 of 158

© Einstein college of engineering

class Producer implements Runnable {

Q q;

Producer(Q q) {

this.q = q;

new Thread(this, "Producer").start();

}

public void run() {

int i = 0;

while(true) {

q.put(i++);

}

}

}

class Consumer implements Runnable {

Q q;

Consumer(Q q) {

this.q = q;

new Thread(this, "Consumer").start();

}

public void run() {

while(true) {

q.get();

}

}

}

class PCFixed {

public static void main(String args[]) {

Q q = new Q();

new Producer(q);

new Consumer(q);

System.out.println("Press Control-C to stop.");

}

}

Inside get( ), wait( ) is called. This causes its execution to suspend until the Producer

notifies you that some data is ready.

When this happens, execution inside get( ) resumes. After the data has been obtained,

get( ) calls notify( ). This tells Producer that it is okay to put more data in the queue.

Inside put( ), wait( ) suspends execution until the Consumer has removed the item from

the queue. When execution resumes, the next item of data is put in the queue, and notify(

) is called. This tells the Consumer that it should now remove it.

Page 138: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 138 of 158

© Einstein college of engineering

Here is some output from this program, which shows the clean synchronous behavior:

Put: 1

Got: 1

Put: 2

Got: 2

Put: 3

Got: 3

Put: 4

Got: 4

Put: 5

Got: 5

Thread Deadlock:

A special type of error that you need to avoid that relates specifically to multitasking is

deadlock, which occurs when two threads have a circular dependency on a pair of

synchronized objects.

For example, suppose one thread enters the monitor on object X and another thread enters

the monitor on object Y. If the thread in X tries to call any synchronized method on Y, it

will block as expected. However, if the thread in Y, in turn, tries to call any synchronized

method on X, the thread waits forever, because to access X, it would have to release its

own lock on Y so that the first thread could complete.

Example:

To understand deadlock fully, it is useful to see it in action. The next example creates two

classes, A and B, with methods foo( ) and bar( ), respectively, which pause briefly before

trying to call a method in the other class.

The main class, named Deadlock, creates an A and a B instance, and then starts a second

thread to set up the deadlock condition. The foo( ) and bar( ) methods use sleep( ) as a

way to force the deadlock condition to occur.

class A {

synchronized void foo(B b) {

String name = Thread.currentThread().getName();

System.out.println(name + " entered A.foo");

try {

Thread.sleep(1000);

} catch(Exception e) {

System.out.println("A Interrupted");

}

System.out.println(name + " trying to call B.last()");

b.last();

Page 139: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 139 of 158

© Einstein college of engineering

}

synchronized void last() {

System.out.println("Inside A.last");

}

}

class B {

synchronized void bar(A a) {

String name = Thread.currentThread().getName();

System.out.println(name + " entered B.bar");

try {

Thread.sleep(1000);

} catch(Exception e) {

System.out.println("B Interrupted");

}

System.out.println(name + " trying to call A.last()");

a.last();

}

synchronized void last() {

System.out.println("Inside A.last");

}

}

class Deadlock implements Runnable {

A a = new A();

B b = new B();

Deadlock() {

Thread.currentThread().setName("MainThread");

Thread t = new Thread(this, "RacingThread");

t.start();

a.foo(b); // get lock on a in this thread.

System.out.println("Back in main thread");

}

public void run() {

b.bar(a); // get lock on b in other thread.

System.out.println("Back in other thread");

}

public static void main(String args[]) {

new Deadlock();

}

}

Here is some output from this program:

MainThread entered A.foo

RacingThread entered B.bar

MainThread trying to call B.last()

RacingThread trying to call A.last()

Page 140: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 140 of 158

© Einstein college of engineering

Because the program has deadlocked, you need to press CTRL-C to end the program.

You can see a full thread and monitor cache dump by pressing CTRL-BREAK on a PC .

You will see that RacingThread owns the monitor on b, while it is waiting for the monitor

on a. At the same time, MainThread owns a and is waiting to get b. This program will

never complete.

As this example illustrates, if your multithreaded program locks up occasionally,

deadlock is one of the first conditions that you should check for.

Thread Control:

While the suspend( ), resume( ), and stop( ) methods defined by Thread class seem to be

a perfectly reasonable and convenient approach to managing the execution of threads,

they must not be used for new Java programs and obsolete in newer versions of Java.

The following example illustrates how the wait( ) and notify( ) methods that are inherited

from Object can be used to control the execution of a thread.

This example is similar to the program in the previous section. However, the deprecated

method calls have been removed. Let us consider the operation of this program.

The NewThread class contains a boolean instance variable named suspendFlag, which is

used to control the execution of the thread. It is initialized to false by the constructor.

The run( ) method contains a synchronized statement block that checks suspendFlag. If

that variable is true, the wait( ) method is invoked to suspend the execution of the thread.

The mysuspend( ) method sets suspendFlag to true. The myresume( ) method sets

suspendFlag to false and invokes notify( ) to wake up the thread. Finally, the main( )

method has been modified to invoke the mysuspend( ) and myresume( ) methods.

Example:

// Suspending and resuming a thread for Java 2

class NewThread implements Runnable {

String name; // name of thread

Thread t;

boolean suspendFlag;

NewThread(String threadname) {

name = threadname;

t = new Thread(this, name);

System.out.println("New thread: " + t);

suspendFlag = false;

t.start(); // Start the thread

}

// This is the entry point for thread.

public void run() {

try {

for(int i = 15; i > 0; i--) {

System.out.println(name + ": " + i);

Thread.sleep(200);

Page 141: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 141 of 158

© Einstein college of engineering

synchronized(this) {

while(suspendFlag) {

wait();

}

}

}

} catch (InterruptedException e) {

System.out.println(name + " interrupted.");

}

System.out.println(name + " exiting.");

}

void mysuspend() {

suspendFlag = true;

}

synchronized void myresume() {

suspendFlag = false;

notify();

}

}

class SuspendResume {

public static void main(String args[]) {

NewThread ob1 = new NewThread("One");

NewThread ob2 = new NewThread("Two");

try {

Thread.sleep(1000);

ob1.mysuspend();

System.out.println("Suspending thread One");

Thread.sleep(1000);

ob1.myresume();

System.out.println("Resuming thread One");

ob2.mysuspend();

System.out.println("Suspending thread Two");

Thread.sleep(1000);

ob2.myresume();

System.out.println("Resuming thread Two");

} catch (InterruptedException e) {

System.out.println("Main thread Interrupted");

}

// wait for threads to finish

try {

System.out.println("Waiting for threads to finish.");

ob1.t.join();

ob2.t.join();

} catch (InterruptedException e) {

Page 142: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 142 of 158

© Einstein college of engineering

System.out.println("Main thread Interrupted");

}

System.out.println("Main thread exiting.");

}

}

Here is the output produced by the above program:

New thread: Thread[One,5,main]

One: 15

New thread: Thread[Two,5,main]

Two: 15

One: 14

Two: 14

One: 13

Two: 13

One: 12

Two: 12

One: 11

Two: 11

Suspending thread One

Two: 10

Two: 9

Two: 8

Two: 7

Two: 6

Resuming thread One

Suspending thread Two

One: 10

One: 9

One: 8

One: 7

One: 6

Resuming thread Two

Waiting for threads to finish.

Two: 5

One: 5

Two: 4

One: 4

Two: 3

One: 3

Two: 2

One: 2

Two: 1

One: 1

Two exiting.

Page 143: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 143 of 158

© Einstein college of engineering

One exiting.

Main thread exiting.

Using isAlive() and join():

Typically, the main thread is the last thread to finish in a program. However, there isn’t

any guarantee that the main thread won’t finish before a child thread finishes. In the

previous example, we told the main method to sleep until the child threads terminate.

However, we estimated the time it takes for the child threads to complete processing. If

our estimate was too short, a child thread could terminate after the main thread

terminates. Therefore, the sleep technique isn’t the best one to use to guarantee that the

main thread terminates last.

Programmers use two other techniques to ensure that the main thread is the last thread to

terminate. These techniques involve calling the isAlive() method and the join() method.

Both of these methods are defined in the Thread class.

The isAlive() method determines whether a thread is still running. If it is, the isAlive()

method returns a Boolean true value; otherwise, a Boolean false is returned. You can use

the isAlive() method to examine whether a child thread continues to run. The join()

method works differently than the isAlive() method. The join() method waits until the

child thread terminates and ―joins‖ the main thread. In addition, you can use the join()

method to specify the amount of time you want to wait for a child thread to terminate.

The following example illustrates how to use the isAlive() method and the join() method

in your program. This example is nearly the same as the previous example. The

difference lies in the main() method of the Demo class definition.

After the threads are declared using the constructor of the MyThread class, the isAlive()

method is called for each thread. The value returned by the isAlive() method is then

displayed on the screen. Next, the join() method is called for each thread. The join()

method causes the main thread to wait for all child threads to complete processing before

the main thread terminates.

class MyThread implements Runnable {

String tName;

Thread t;

MyThread (String threadName) {

tName = threadName;

t = new Thread (this, tName);

t.start();

}

public void run() {

try {

System.out.println("Thread: " + tName );

Thread.sleep(2000);

} catch (InterruptedException e ) {

System.out.println("Exception: Thread "

+ tName + " interrupted");

Page 144: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 144 of 158

© Einstein college of engineering

}

System.out.println("Terminating thread: " + tName );

}

}

class Demo {

public static void main (String args []) {

MyThread thread1 = new MyThread ("1");

MyThread thread2 = new MyThread ("2");

MyThread thread3 = new MyThread ("3");

MyThread thread4 = new MyThread ("4");

System.out.println("Thread Status: Alive");

System.out.println("Thread 1: "

+ thread1.t.isAlive());

System.out.println("Thread 2: "

+ thread2.t.isAlive());

System.out.println("Thread 3: "

+ thread3.t.isAlive());

System.out.println("Thread 4: "

+ thread4.t.isAlive());

try {

System.out.println("Threads Joining.");

thread1.t.join();

thread2.t.join();

thread3.t.join();

thread4.t.join();

} catch (InterruptedException e) {

System.out.println(

"Exception: Thread main interrupted.");

}

System.out.println("Thread Status: Alive");

System.out.println("Thread 1: "

+ thread1.t.isAlive());

System.out.println("Thread 2: "

+ thread2.t.isAlive());

System.out.println("Thread 3: "

+ thread3.t.isAlive());

System.out.println("Thread 4: "

+ thread4.t.isAlive());

System.out.println(

"Terminating thread: main thread.");

}

}

Page 145: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 145 of 158

© Einstein college of engineering

Here is what is displayed on the screen when this program runs:

Thread Status: Alive

Thread 1: true

Thread 2: true

Thread 3: true

Thread 4: true

Threads Joining.

Thread: 1

Thread: 2

Thread: 3

Thread: 4

Terminating thread: 1

Terminating thread: 2

Terminating thread: 3

Terminating thread: 4

Thread Status: Alive

Thread 1: false

Thread 2: false

Thread 3: false

Thread 4: false

Terminating thread: main thread.

Thread Pools:

Most of the executor implementations in java.util.concurrent use thread pools, which

consist of worker threads. This kind of thread exists separately from the Runnable and

Callable tasks it executes and is often used to execute multiple tasks.

Using worker threads minimizes the overhead due to thread creation. Thread objects use

a significant amount of memory, and in a large-scale application, allocating and

deallocating many thread objects creates a significant memory management overhead.

One common type of thread pool is the fixed thread pool. This type of pool always has a

specified number of threads running; if a thread is somehow terminated while it is still in

use, it is automatically replaced with a new thread. Tasks are submitted to the pool via an

internal queue, which holds extra tasks whenever there are more active tasks than threads.

An important advantage of the fixed thread pool is that applications using it degrade

gracefully. To understand this, consider a web server application where each HTTP

request is handled by a separate thread. If the application simply creates a new thread for

every new HTTP request, and the system receives more requests than it can handle

immediately, the application will suddenly stop responding to all requests when the

overhead of all those threads exceed the capacity of the system. With a limit on the

number of the threads that can be created, the application will not be servicing HTTP

requests as quickly as they come in, but it will be servicing them as quickly as the system

can sustain.

Page 146: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 146 of 158

© Einstein college of engineering

A simple way to create an executor that uses a fixed thread pool is to invoke the

newFixedThreadPool factory method in java.util.concurrent.Executors This class also

provides the following factory methods:

The newCachedThreadPool method creates an executor with an

expandable thread pool. This executor is suitable for applications that

launch many short-lived tasks.

The newSingleThreadExecutor method creates an executor that executes a

single task at a time.

Several factory methods are ScheduledExecutorService versions of the

above executors.

If none of the executors provided by the above factory methods meet your needs,

constructing instances of java.util.concurrent.ThreadPoolExecutor or

java.util.concurrent.ScheduledThreadPoolExecutor will give you additional options.

Callables:

Callables are a tweak to the existing runnable construct. Callables differ only by having a

generic return type - most specialized concurrency APIs already available (such as

Foxtrot ) already have the concept of a runnable + return type (such as the foxtrot Task

and Job classes). Some of you may already have noticed that the ExecutorService API is

biased to Callable objects - and some may consider that a problem since they have a lot

of code that already works with Runnable .

public class ComplexCalculation implements Callable<Long> {

public ComplexCalculation(int value1, int value2, long value3) {

// ...

}

public Long call() {

// perform complex calculation resulting in long

long result = //...

return result; // autoboxing!

}

}

java.util.concurrent

Interface Callable<V>

Type Parameters:

V - the result type of method call

Page 147: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 147 of 158

© Einstein college of engineering

public interface Callable<V>

A task that returns a result and may throw an exception. Implementors define a single

method with no arguments called call.

The Callable interface is similar to Runnable, in that both are designed for classes whose

instances are potentially executed by another thread. A Runnable, however, does not

return a result and cannot throw a checked exception.

Executors:

There's a close connection between the task being done by a new thread, as defined by its

Runnable object, and the thread itself, as defined by a Thread object. This works well for

small applications, but in large-scale applications, it makes sense to separate thread

management and creation from the rest of the application. Objects that encapsulate these

functions are known as executors.

The Executors class contains utility methods to convert from other common forms to

Callable classes.

V call()

Computes a result, or throws an exception if unable to do so.

Example:

import java.util.concurrent.CountDownLatch;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

class SimpExec {

public static void main(String args[]) {

CountDownLatch cdl = new CountDownLatch(5);

CountDownLatch cdl2 = new CountDownLatch(5);

CountDownLatch cdl3 = new CountDownLatch(5);

CountDownLatch cdl4 = new CountDownLatch(5);

ExecutorService es = Executors.newFixedThreadPool(2);

es.execute(new MyThread(cdl, "A"));

es.execute(new MyThread(cdl2, "B"));

es.execute(new MyThread(cdl3, "C"));

es.execute(new MyThread(cdl4, "D"));

try {

cdl.await();

cdl2.await();

cdl3.await();

Page 148: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 148 of 158

© Einstein college of engineering

cdl4.await();

} catch (InterruptedException exc) {

System.out.println(exc);

}

es.shutdown();

}

}

class MyThread implements Runnable {

String name;

CountDownLatch latch;

MyThread(CountDownLatch c, String n) {

latch = c;

name = n;

new Thread(this);

}

public void run() {

for (int i = 0; i < 5; i++) {

latch.countDown();

}

}

}

Synchronizers:

Java 5 introduces general purpose synchronizer classes, including semaphores, mutexes,

barriers, latches, and exchangers, which facilitate coordination between threads. These

classes are a apart of the java.util.concurrent package. A brief description of each of these

follows:

Semaphores

A counting semaphore maintains a set of permits. Each acquire() blocks if

necessary until a permit is available, and then takes it. Each release() adds a permit,

potentially releasing a blocking acquirer. However, no actual permit objects are used; the

Semaphore just keeps a count of the number available and acts accordingly.

Page 149: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 149 of 158

© Einstein college of engineering

Semaphores are often used to restrict the number of threads than can access some

(physical or logical) resource.

Example:

import java.util.concurrent.Semaphore;

import java.util.Random;

//Solving the mutual exclusion problem using Semaphore class

class Process2 extends Thread

{

private static final Random rand = new Random();

private int id;

private Semaphore sem;

public Process2(int i, Semaphore s)

{

id = i;

sem = s;

}

private void busy()

{

try

{

sleep(rand.nextInt(500));

} catch (InterruptedException e)

{

}

}

private void noncritical()

{

System.out.println("Thread " + id + " is NON critical");

busy();

}

private void critical()

{

System.out.println("Thread " + id + " entering critical section");

busy();

System.out.println("Thread " + id + " leaving critical section");

Page 150: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 150 of 158

© Einstein college of engineering

}

public void run()

{

for (int i = 0; i < 2; ++i)

{

noncritical();

try

{

sem.acquire();

} catch (InterruptedException e)

{

// ...

}

critical();

sem.release();

}

}

public static void main(String[] args)

{

final int N = 4;

System.out.println("Busy waiting...");

//Semaphore(int permits, boolean fair)

Semaphore sem = new Semaphore(N, true);

Process2[] p = new Process2[N];

for (int i = 0; i < N; i++)

{

p[i] = new Process2(i, sem);

p[i].start();

}

}

}

Barrier

A synchronization aid that allows a set of threads to all wait for each other to

reach a common barrier point. CyclicBarriers are useful in programs involving a fixed

sized group of threads that must occasionally wait for each other. The barrier is called

cyclic because it can be re-used after the waiting threads are released.

Page 151: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 151 of 158

© Einstein college of engineering

For the java.util.concurrent class see CyclicBarrier

A barrier is a type of synchronization method. A barrier for a group of threads or

processes in the source code means any thread/process must stop at this point and cannot

proceed until all other threads/processes reach this barrier.[1]

The basic Java synchronization mechanism centers on the keyword synchronized, which

predicates methods. In java, all objects can be used like monitors (protected types).

That means that given an object A, no more than one thread can execute a synchronized

method of A at any time.

Barrier implementation

/*

* Given object A, no more than one thread can execute a synchronized

method of A at any time.

*/

public class Barrier

{

public synchronized void block() throws InterruptedException

{

wait();

}

public synchronized void release() throws InterruptedException

{

notify();

}

public synchronized void releaseAll() throws InterruptedException

{

notifyAll();

}

}

And an example with two threads.

class BarrierExample

{

static class MyThread1 implements Runnable

{

public MyThread1(Barrier barrier)

{

this.barrier = barrier;

}

Page 152: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 152 of 158

© Einstein college of engineering

public void run()

{

try

{

Thread.sleep(1000);

System.out.println("MyThread1 waiting on barrier");

barrier.block();

System.out.println("MyThread1 has been released");

} catch (InterruptedException ie)

{

System.out.println(ie);

}

}

private Barrier barrier;

}

static class MyThread2 implements Runnable

{

Barrier barrier;

public MyThread2(Barrier barrier)

{

this.barrier = barrier;

}

public void run()

{

try

{

Thread.sleep(3000);

System.out.println("MyThread2 releasing blocked threads\n");

barrier.release();

System.out.println("MyThread1 releasing blocked threads\n");

} catch (InterruptedException ie)

{

System.out.println(ie);

}

}

}

public static void main(String[] args) throws InterruptedException

{

Barrier BR = new Barrier();

Page 153: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 153 of 158

© Einstein college of engineering

Thread t1 = new Thread(new BarrierExample.MyThread1(BR));

Thread t2 = new Thread(new BarrierExample.MyThread2(BR));

t1.start();

t2.start();

t1.join();

t2.join();

}

}

Exchangers

A synchronization point at which two threads can exchange objects. Each thread

presents some object on entry to the exchange method, and receives the object presented

by the other thread on return.

Example:

import java.util.concurrent.Exchanger;

class ExgrDemo {

public static void main(String args[]) {

Exchanger<String> exgr = new Exchanger<String>();

new UseString(exgr);

new MakeString(exgr);

}

}

class MakeString implements Runnable {

Exchanger<String> ex;

String str;

MakeString(Exchanger<String> c) {

ex = c;

str = new String();

new Thread(this).start();

}

public void run() {

char ch = 'A';

Page 154: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 154 of 158

© Einstein college of engineering

for (int i = 0; i < 3; i++) {

for (int j = 0; j < 5; j++)

str += (char) ch++;

try {

str = ex.exchange(str);

} catch (InterruptedException exc) {

System.out.println(exc);

}

}

}

}

class UseString implements Runnable {

Exchanger<String> ex;

String str;

UseString(Exchanger<String> c) {

ex = c;

new Thread(this).start();

}

public void run() {

for (int i = 0; i < 3; i++) {

try {

str = ex.exchange(new String());

System.out.println("Got: " + str);

} catch (InterruptedException exc) {

System.out.println(exc);

}

}

}

}

Latches

A synchronization aid that allows one or more threads to wait until a set of

operations being performed in other threads completes. A CountDownLatch is initialized

with a given count. The await methods block until the current count reaches zero due to

Page 155: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 155 of 158

© Einstein college of engineering

invocations of the countDown() method, after which all waiting threads are released and

any subsequent invocations of await return immediately.

Latching variables specify conditions that once set never change. This provides a way to

start several threads and have them wait until a signal is received from a coordinating

thread. [1]

The following program creates a set of threads, but doesn't let any thread start until all the

threads are created.

import java.util.concurrent.*;

public class LatchTest

{

private static final int COUNT = 10;

private static class Worker implements Runnable

{

CountDownLatch startLatch;

CountDownLatch stopLatch;

String name;

Worker(CountDownLatch startLatch, CountDownLatch stopLatch, String name)

{

this.startLatch = startLatch;

this.stopLatch = stopLatch;

this.name = name;

}

public void run()

{

try

{

startLatch.await(); // wait until the latch has counted down to

// zero

} catch (InterruptedException ex)

{

ex.printStackTrace();

}

System.out.println("Running: " + name);

stopLatch.countDown();

}

}

Page 156: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 156 of 158

© Einstein college of engineering

public static void main(String args[])

{

// CountDownLatch(int count)

// Constructs a CountDownLatch initialized with the given count.

CountDownLatch startSignal = new CountDownLatch(1);

CountDownLatch stopSignal = new CountDownLatch(COUNT);

for (int i = 0; i < COUNT; i++)

{

new Thread(new Worker(startSignal, stopSignal, Integer.toString(i)))

.start();

}

System.out.println("Go");

startSignal.countDown();

try

{

stopSignal.await();

} catch (InterruptedException ex)

{

ex.printStackTrace();

}

System.out.println("Done");

}

}

Thread and event driven programming:

The single-thread rule:

Here's the rule:

Once a Swing component has been realized, all code that might affect or depend on the

state of that component should be executed in the event-dispatching thread.

This rule might sound scary, but for many simple programs, you don't have to worry

about threads. Before we go into detail about how to write Swing code, let's define two

terms: realized and event-dispatching thread.

Realized means that the component's paint() method has been or might be called. A

Swing component that's a top-level window is realized by having one of these methods

invoked on it: setVisible(true), show(), or (this might surprise you) pack(). Once a

window is realized, all components that it contains are realized. Another way to realize a

component is to add it to a container that's already realized. You'll see examples of

realizing components later.

The event-dispatching thread is the thread that executes drawing and event-handling

code. For example, the paint() and actionPerformed() methods are automatically executed

Page 157: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 157 of 158

© Einstein college of engineering

in the event-dispatching thread. Another way to execute code in the event-dispatching

thread is to use the SwingUtilities invokeLater() method.

Example:

import java.awt.FlowLayout;

import java.lang.reflect.InvocationTargetException;

import javax.swing.JFrame;

import javax.swing.JLabel;

import javax.swing.JPanel;

import javax.swing.SwingUtilities;

public class InvokeAndWaitDemo extends Object {

private static void print(String msg) {

String name = Thread.currentThread().getName();

System.out.println(name + ": " + msg);

}

public static void main(String[] args) {

final JLabel label = new JLabel("--------");

JPanel panel = new JPanel(new FlowLayout());

panel.add(label);

JFrame f = new JFrame("InvokeAndWaitDemo");

f.setContentPane(panel);

f.setSize(300, 100);

f.setVisible(true);

try {

print("sleeping for 3 seconds");

Thread.sleep(3000);

print("creating code block for event thread");

Runnable setTextRun = new Runnable() {

public void run() {

print("about to do setText()");

label.setText("New text!");

Page 158: Programming Paradigms

CS55 PROGRAMMING PARADIGMS

Page 158 of 158

© Einstein college of engineering

}

};

print("about to invokeAndWait()");

SwingUtilities.invokeAndWait(setTextRun);

print("back from invokeAndWait()");

} catch (InterruptedException ix) {

print("interrupted while waiting on invokeAndWait()");

} catch (InvocationTargetException x) {

print("exception thrown from run()");

}

}

}