Unit I The Creation of Java
Unit I The Creation of Java
Unit I The Creation of Java
The keywords const and goto have been defined but are not used. In addition, Java reserves :
true, false and null. These are values defined by Java and these words cannot be used as
names for variables, methods, classes etc. The Java environment depends on a number of
built in class libraries which contain numerous built in methods that provide support for
input/output, string handling, networking etc. Thus Java in totality is a combination of the
Java language itself, and its standard classes. The class libraries provide much of the
functionality that comes with Java. So it is essential for the student to learn using the standard
Java classes.
Data types
Java defines the following simple data types :
Integers : This group includes byte, short, int and long. These are used for whole values
which are signed numbers.
Floating point types : This group includes float and double. These represent values with
fractional parts.
Characters : This group includes char, and they represent symbols in a character set. eg.
letters, numbers.
Boolean : This is a special type for representing true/false values.
These simple data types form the basis of all the other types of data that you can create. It is
important to note that these simple types represent single values and not complex objects.
They are similar to the simple types found in most other non-object oriented languages. In
Java all data types have a strictly defined range. This is essential to achieve the requirement
of portability. This helps to make the programs architecture independent.
Integers
All the four integer data types viz. byte, short, int and long are signed i.e. positive and
negative values. Java does not support unsigned integers. This differs from C/C++ where both
signed and unsigned integers are supported.
byte : The smallest integer type is byte. This is a signed 8 bit type with a range from -128 to
127. A byte variable is declared using the keyword byte. eg. byte b, b1;
Such types of variables are useful when working with a stream of data from a network or a
file and also when working with raw binary data which may not be directly compatible with
other built in types supported by Java.
short : short is signed 16-bit type which has a range of values form - 32,768 to 32,767. eg.
short s, s1;
int : This is the most commonly used integer data type with a range of values from
-2,147,483,648 to 2,147,483,647. It is a signed 32 bit data type, Variables of type int are
mainly used to control loops and to index arrays. It is important to note that anytime you have
an integer expression which involves bytes, shorts and ints, and literal numbers, the entire
expression will be promoted to the type int before the calculation is done.
int is the most versatile and efficient data type among integers.
long : long is signed 64 bit and useful in situations where the int data type is not large enough
to hold a particular value.
Floating point types
Floating point numbers are also known as real numbers. These are useful in expressions
involving fractional values. There are two types of floating point types : float and double.
float : float represents single precision value. It uses 32 bits of storage. It can be useful when
you need a fractional component but where the degree of precision required is not very high.
A float variable is declared with the float keyword. The following example will illustrate :
float max, min;
double : Double precision is denoted by the keyword double. It uses 64 bits to store a value.
All transcendental mathematical functions like sin(), cos(), sqrt() etc. return double values.
Double precision is actually faster than single precision on some modern processors of today
which have been optimised for high speed mathematical calculations.
Characters
The data type used to store characters is char. Remember however that char in Java is
different than C/C++ where the char is an integer which occupies 8 bits. In Java, Unicode is
used to represented char. Unicode defines a fully international character set that can represent
all of the characters found in all human languages. Therefore the char data type requires 16
bits and the range of char is from 0 to 65,536. There are no negative character data types.
Even though char is not treated as integers, you can add chars or increment the value of char
variables.
Boolean
boolean is the simple data type for logical values. It has only one of the possible values : true
or false. This is the type returned by all relational operators. boolean is also the type required
by the conditional expressions in the control statements like if and for.
Variables
A variable is the basic unit of storage in a Java program. All variables must be declared
before they are used. The general form of declaring a variable is :
type identifier [=value][,identifier[=value]....];
type is one of Java’s atomic type or the name of a class or an interface and identifier is the
name of the variable. Variable can be initialised at the time of declaration by giving an equal
to sign and a value. We use a comma to separate variables if we are declaring more than one
variable of the specified type. Following examples illustrate :
int a = 10, b, c;
double radius;
char a = ‘a’, ch;
Java also allows variables to be initialised dynamically by using any expression valid at the
time the variable is declared. The following example will illustrate :
class Circum
{
public static void main(String args[])
{
float r = 4.2;
//initialise circumference dynamically
float cir = 2 * 3.14 * r
System.out.println(“Circumference is “+ cir);
}
}
In this example you can see that the variable r is initialised with a constant value. Variable cir
is dynamically initialised to the circumference of the circle with radius r.
Scope and Lifetime of variables: Java allows variables to be declared in any block. A block
defines the scope. This means that every time you create a new block, you create a new
scope. The scope determines what objects are visible to other parts of the program and it also
determines the lifetime of the objects. In Java, the two major scopes are those defined by a
class and those defined by a method. The class scope has several unique properties and
attributes. These do not apply to the scope defined by a method. Let us for the moment see
the scope defined within a method.
Variables declared inside a scope are not visible to code that is defined outside the scope. This
means that when a variable is declared within a scope, it is localised to that scope and is
protected from unauthorised access and modification. Scope rules provide the basis of
encapsulation. Scopes can also be nested. The objects declared in the outer scope will be
visible to the code within the inner scope, however the objects declared within the inner
scope are not visible outside it. In Java, variables are created when their scope is entered and
destroyed when their scope is left. Once a variable goes out of its scope, it will no longer
retain its value. This means that the lifetime of a variable is only within its scope. If a variable
is initialised at the time it is declared, then that variable will be reinitialised every time the
block in which it is declared is entered.
Arrays
An array is group of variables of the same type and which have a common name. Arrays can
be of any type and can have one or more dimensions. Any specific value or element in an
array is accessed by its index. Remember that arrays in Java differ from the way they work in
C/C++.
One dimensional array : A one dimensional array is a list of like typed variables. The
general form for creating a one dimensional array is :
type var-name[ ] ;
here type is the base type of the array which determines the data type of the elements of the
array. var-name is an array variable. You can declare an array as shown below :
int arr1[ ];
here arr1 is an array type variable, but it is important to note that with this declaration no
array actually exists. The value of arr1 is set to null, which represents an array with no value.
To link arr1 to a list of variables of type int, you must allocate one using the new operator.
new is a special operator that allocates memory. The general form of new when applied to a
one dimensional array is :
array-var = new type[size];
type specifies the type of data, size specifies the number of elements in the array. array-var is
the variable that is linked to the array. The elements in the array allocated by new will
automatically be initialised to zero. Thus in the above example if we wish to allocate ten
elements to arr1 then we can do so as :
arr1 = new int[10];
arr1 now refers to an array of 10 integers and the elements initialised to zero.
You can combine array declaration and allocation in one step as :
int arr1 = new int[10];
An alternative form of declaring arrays is given below :
type [ ] var-name;
eg. int [ ] a1 = new int[5];
Here the square brackets come first after the type specifier and then the name of the array
variable. This form is included mainly as a part of convenience. All arrays are dynamically
allocated in Java. Once you have allocated an array, you can access the elements of the array
by specifying an index in a square bracket. All array indexes start at zero. i.e. arr1[0] is the
first element of arr1, arr1[1] is the second element and so on.
Arrays can be initialised at the time of their declaration. An array initialiser is a list of comma
separated expressions surrounded by curly braces. The commas separate the values of the
array elements. Java will automatically create an array large enough to hold the number of
values specified in the array initialiser. There is no need of using new when initialising arrays
at the time of declaration.
eg. int odd_nos = {1, 3, 5, 7, 9, 11};
Java run time system will check to be sure that all array indexes are in the correct range, it
makes sure that you do not accidently try to store or reference values outside the range of the
array. This is different than in C/C++ where there is no bounds checking.
Multidimensional arrays :
Multidimensional arrays are arrays of arrays. In order to declare a multidimensional array
variable you should specify each additional index using another set of square brackets. eg. if
you wish to initialise a two dimensional array you can do so as follows :
int array1[][] = new int[4][5];
Operators
Most of the operators in Java can be divided into the following groups : arithmetic, bitwise,
relational and logical. Java also supports certain additional operators to handle special
situations. Most operators in Java work in the same way as they do in C/C++. Let us now
study these operators in detail.
Arithmetic Operators
These are useful in mathematical operations. The operands of arithmetic operators must be of
numeric type. Arithmetic operators cannot be used on boolean types, but they can be used on
char types. The following is the list of operators supported by Java : Remember that the unary
- operator negates the operand. When the division operator is applied to integer types, the
fractional component of the result will be truncated. Also the modulus operator returns the
remainder of the division operation. It can be applied to both integer and floating point types.
However, in C it can be applied on to integer data types.
The arithmetic assignment operator is used as follows : eg. a = a + 5; can be written as
a += 5; Here we have made use of the addition assignment operator. Both the statements
perform the same operation. As we can see from the above table, there are assignment
operators for all the arithmetic binary operators. The general form can therefore be expressed
as :
var op= expression;
The assignment operators are shorthand for their equivalent long forms. They are also
implemented more efficiently by the Java run-time system than their equivalent long forms.
Increment and Decrement operators : As in C/C++ the increment operator increases the
value of the operand by 1, and the decrement operator decreases the value of the operand by
1. Both are unary operators and can appear in both the postfix and prefix forms.
eg. a = a + 1;
can be rewritten using the increment operator as :
a++;
or
++a;
Similarly with the decrement operator.
Bitwise Operators
Bitwise operators can be applied to the integer data types, byte, char, short, int and long. They
act upon invidisual bits of the operands. As we have already studied all the integer types
except char are signed integers. This means they can represent positive and negative values.
Java uses the 2s complement encoding method. This means that the negative numbers are
represented by inverting all the bits in the value and then adding 1 to the result. Remember
that the high-order bit determines the sign of an integer.
Bitwise Logical operators : The bitwise logical operators are & (AND) , | (OR) , ^ (XOR)
and ~ (NOT). The truth table of the bitwise logical operators is given below :
Bitwise NOT (~) is also called as the bitwise complement operator and it inverts all of the
bits of its operand.
Bitwise AND (&) produces a 1 bit if both the operands are also 1 and a 0 bit otherwise.
Bitwise OR (|) : In bitwise OR if either of the bits in the operands is a 1, then the resultant bit
is 1.
Bitwise XOR (^) : This operator combines the bits such that if exactly one operand is 1, then
the result is a 1, otherwise the result is a 0. In bitwise XOR, whenever the second operand has
a 0 bit, the first operand is unchanged.
The Left Shift : The left shift operator (<<) shifts all of the bits in a value to the left a
specified number of times. The general form of the left shift operator is :
value << num
where num specifies the number of positions to left shift the value of value. For each shift
left, the high order bit is shifted out and is lost, and a zero is brought in on the right. Shifting
left by a value of 1, has the same effect as doubling the original value, therefore this can be
used as an alternative way to multiplication by 2.
The Right Shift :This operator shifts all of the bits in a value to the right the specified
number of times. The general form of right shift is :
value >> num
Where num specifies the number of positions to right shift the value in value. When a value
has bits that are shifted off, those bits are lost. Each time a value is shifted to the right, it gets
divided by two and discards any remainder. This means that right shift can be used for integer
division by 2. When shifting to the right, the leftmost bits exposed by the right shift are filled
in with the previous contents of the top bit. This is called as sign extension and it preserves
the sign of the negative numbers when you right shift.
The Unsigned Right Shift : In the right shift operator, the sign of the numbers is preserved.
However in certain situations, especially when you are not shifting numeric values you may
not want the sign extension to take place. You would generally want to shift a zero in the high
order bit irrespective of what its initial value is. For this purpose you make use of the
unsigned right shift operator >>> which always shifts zeroes into the high order bit. This is
known as unsigned shift.
Bitwise Operator Assignments : All the bitwise operators have a shorthand form which is
similar to that of algeabric operators. It combines the assignment with the bitwise operation
eg. a = a << 2; can also be written as
a <<= 2;
x = x & y; can also be written as
x &=y;
Relational Operators
Relational operators determine the relationship that one operand has to the other operand. The
relational operators in Java are :
The result of these operations yields a boolean value. Any type in Java, including integers,
floats, chars, and booleans can be compared for equality and inequality. Only integer, floating
point and character operands may be compared to see which is less than or greater than the
other.
Java does not define true or false in the same way as C/C++. In C/C++, true implies any non
zero value and false is a zero value. However, in Java, true and false are non numeric values.
Therefore to test for zero or non zero you must explicit**y make use of one or more
relational operators. The following example will illustrate :
In C/C++ you can write a block of code as :
int check;
if(check) ....
if(!check) ...
However, in Java you would be required to write as follows :
if(check == 0) ....
if(check != 0) ...
This means in Java to test for zero or non zero you have to explicitly make use of one or more
of the relational operators.
Boolean Logical Operators
These operators operate only on boolean operands. All the binary logical operators combine
two boolean values to form a resultant Boolean value.
The logical Boolean operators &, | and ^ operate on boolean values in the same way that they
operate on bits of an integer. The logical ! operator inverts the Boolean state, i.e. !true = false
and !false = true.
Short Circuit Logical Operators : Short circuit operators are secondary versions of Boolean
AND and OR operators. They are not found in most other computer languages. We can see
from the truth table of the operators that the OR operator results in true when A is true,
irrespective of whatever B is. Similarly the AND operator results in a false when A is false,
irrespective of what B is. So if you use the short circuit OR (||) and short circuit AND (&&)
forms rather than the | and & forms, Java does not evaluate the right hand operand because
the result can be determined by the left hand operand alone.
The Assignment Operator
The assignment operator is the = sign. The general form of the assignment operator is :
var = expression;
Note that the type of var must be compatible with expression.
Assignment operator allows you to create a chain of assignments which is an easy wasy to set
a group of variables to a common value. eg.
int a, b, c;
a = b = c = 10; is valid in Java.
The ?: operator
This operator works in the same way as it does in C/C++.
The general form of this operator is :
exp1? exp2 :: exp3
exp1 is any expression that evaluates to a boolean value. If exp1 is true then exp2 is evaluated
else exp3 is evaluated. The result of the operation is that of the expression that is evaluated
(either exp2 or exp3).
Note that both exp2 and exp3 should return the same type and the return type cannot be void.
Operator Precedence
The following table shows the order of precedence of the Java operators from highest to
lowest.
Control Statements
The control statements in Java can be divided into the following catagories : selection,
iteration and jump. Selection statements allow the program to choose different paths of
execution based upon the outcome of an expression or the state of a variable. Iteration
statements are useful to repeat one or more statements i.e. they form loops, and jump
statements allow the program to execute in a non linear fashion. Control statements in Java
are nearly identical to those in C/C++, there are only a few differences. Therefore the control
statements shall be discussed very briefly in this section.
SELECTION
The two selection statements in Java are : if and switch.
The if statement :
This is a conditional branching statement. The general form of if is :
if (condition) statement1;
else statement2;
Each statement may be a single statement or a group of statements enclosed within a pair of
braces. The condition is an expression which returns a boolean value. Note that the else
clause is optional. If the condition is true, then statement1 is executed, else statement2 is
executed. Remember that both statement1 and statement2 will not be executed in any
situation.
A nested if is an if statement within another if or else. Here it is important to remember that
an else statement always refers to the nearest if statement which is within the same block and
which is not already associated with an else.
A sequence of nested ifs is the if-else-if ladder. The general form of the if-else-if ladder is :
if(condition)
statement;
else if(condition)
statement;
else if(condition)
statement;
:
:
else
statement;
The if statements are executed in a top down manner.
The switch statement
The switch statement provides multiway branching and is often a better alternative to nested
if-else-if statements. The general form of the switch statement is :
switch(expression) {
case value1:
statement block;
break;
case value2:
statement block;
break;
:
:
case valuen:
statement block;
break;
default:
default statement block;
}
The expression must be of type byte, short, int or char. Each of the values specified in the
case statements must be of a type compatible with the expression. Each case value must be a
unique literal, it cannot be a variable. Duplicate case values are also not allowed. The value of
the expression is compared with each literal value in the case. When a match is found, the set
of statements following that case statement is executed. If none of the values match, then the
default statement is executed. Note however, that the default statement is optional. If there are
no case matches and there is no default statement then no further action takes place.
The use of the break statement is to terminate the statement block, when the break is
encountered execution branches to the first line of the code that follows the switch
statement.The break statement is optional. If you do not use the break statement, execution
continues with the next case.
It is also possible to have nested switch statements. Each switch statement defines its own
block so there are no conflicts between case constants in the inner switch and those in the
outer switch.
ITERATION STATEMENTS
We have already studied that a loop executes a set of instructions repeatedly until a
termination condition is met. In this section let us study the looping statements provided in
Java.
while loop : The general form of the while is:
while(condition) {
body of the loop
}
The condition can be any Boolean expression. The body of the loop is executed as long as the
condition is true. When the condition becomes false, the control passes to the next line which
immediately follows the loop. If you wish to have more than one statements after the while,
then they should be enclosed within a pair of braces. Since the while loop evaluates the
conditional expression at the beginning of the loop i.e. at the top, the body of the loop may
not execute even once if the condition is false the first time itself. The body of the while (or
any of the loops in Java) can be empty.
This is because Java allows the null statement i.e. a statement which consists only of a
semicolon. Thus it is possible to write short loops without bodies when the controlling
expression itself can handle all the details itself. The following example will illustrate:
class EmptyLoop {
public static void main(String args[ ]) {
int i, j;
i = 100;
j = 200;
while(++i < --j) //find midvalue of i and j
;
// null statement
System.out.println(“Midpoint is : “ + i);
}
}
do-while loop :
The general form of the do-while is :
do {
body of the loop
}
while(condition);
Each iteration of the do-while loop first executes the body of the loop and then evaluates the
conditional expression. If the expression evaluates to true, then the loop repeats otherwise it
terminates. The condition must be a Boolean expression. Note that the do-while loop always
executes its body at least once. This is because it checks the expression at the bottom of the
loop. The do-while loop is used in situations where the loop termination test is to be done at
the end of the loop rather than at the beginning. eg. the do-while loop is useful in menu
selection, where the body of the menu loop should be executed at least once.
for loop : The general form of the for statement is :
for(initialisation;condition;iteration) {
//body of the loop
}
The for loop operates as follows. When the loop first starts, the initialisation portion of the
loop is executed. Generally, this portion contains the expression which sets the value of the
loop control variable. (The loop control variable acts as a counter which controls the loop.)
Note that the initialisation expression is executed only once. Next is the condition, which
must be a Boolean expression. The condition generally tests the loop control varaible and if
the expression is true then the body of the loop is executed. The iteration is executed next. It
is usually an expression which increments or decrements the loop control variable. The loop
then iterates, first evaluates the condition, then executes the loop body, then executes iteration
expression again. This process continues till the controlling expression becomes false. It is
also possible to declare the variable that controls the for loop in the initialisation portion of
for. eg. for(int i = 0; i <=10; i++)
Here i is declared in the for loop. Note however, that the scope of i will end as soon as the for
statement ends. Outside the for loop the variable will not exist. You can include more than
one statement in the initialisation and iteration portion of the for loop. Each statement should
be separated by a comma. This is particularly useful in situations where the for loop is
controlled by the interaction of more than one variable.
class ForLoop {
public static void main(String args[ ]) {
int a, b;
for(a = 1, b = 6; a<b; a++,b--) {
System.out.println(“a = “ + a);
System.out.println(“b = “ + b);
}
}
}
The condition controlling the for loop can be any Boolean expression. eg.
boolean over = false;
for(int i = 1; !over; i++) {
if(...)
over = true;
}
Here the for loop will continue to execute until the variable over is set to true, which will be
when the if condition evaluates to true. Remember that it does not test the value of i. Java
also allows loops to be nested. One loop can be nested in another.
JUMP STATEMENTS
Jump statements are used to transfer control to another part of the program. Java supports
three jump statements : break, continue and return.
break
The break statement has three uses : to break from the switch statement, to exit a loop and it
can be used instead of the goto (The goto statement is best avoided). We have already seen
the use of break in switch. You can forcefully terminate a loop using the break, bypassing the
conditional expression and any remaining code in the loop. When the break statement is
encountered in a loop, the loop is terminated and program control is transferred to the
statement following the loop. The break statement can be used with any of the loops in Java.
When break is used in a set of nested loops, it will only break out of the innermost loop, the
outer loop remains unaffected.
Using break as a Form of Goto : Java defines an extended form of the break statement
which is called the labeled break. With this form of the break, it is possible to break out of
one or more blocks of code. These parts of code need not be part of a loop or switch, they can
be any block of code. You can also specify where the execution should resume.
The general form of the labeled break is :
break label;
label is the name of the label that identifies a block of code. When this form of code executes
control is transferred out of the named block of code. You can use a labeled break to exit from
a set of nested blocks. However, you cannot use a break to transfer control to a block of code
that does not enclose the break statement. A label is any valid Java identifier followed by a
colon. Once a block is labeled, you can use this label as the target of the break statement. This
will cause execution to resume at the end of the labeled block. The following example will
illustrate :
class BreakDemo {
public static void main(String args[ ]) {
boolean flag = true;
first: {
second: {
third: {
System.out.println(“Before break”);
if(flag) break second;
System.out.println(“Block breaks, hence this will not execute”);
}
System.out.println(“This won’t execute, since break second”);
}
System.out.println(“Encountered after executing break second”);
}
}
}
The output of the program is :
Before break
Encountered after executing break second
In the example there are three nested blocks. Each block has its own label. When the break
statement is encountered, it will cause the execution to jump forward, past the end of the
block labeled second. It will skip the print statements within third and second. One of the
most common uses of labeled break is to exit from nested loops. Remember that you cannot
break to any label which has not been defined for an enclosing block.
continue :
Sometimes you may want to continue running a loop, but stop processing the remaining loop
body for this particular iteration. In such a situation, you make use of the continue statement.
In a while and do-while loop the continue statement causes control to be directly transferred
to the conditional expression that controls the loop. In the for loop, the control first goes to
the iteration portion of the for statement and then to the conditional expression. In all the
three cases, any intermediate code is bypassed. continue may also specify a label to describe
which enclosing loop to continue.
return :
The return statement is used to explicitly return from a method. It causes the program control
to transfer back to the caller of the method. At any time in a method, we can use the return to
cause execution branch back to the caller of the method. The return statement immediately
terminates the method in which it is executed. A detailed discussion of return is deferred till
the study of methods. It has been introduced here since it is catagorised as a jump statement
which causes program control to transfer back to the caller of the method.
Introducing Classes:
Class Fundamentals:
A class is a logical construct upon which the entire Java language is built. A class defines the
shape and nature of an object. Any concept that you wish to implement in a Java program,
must be encapsulated within a class. A class defines a new data type. This data type is then
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.
When you define a class, you specify the data it contains and the code that operates on that
data.
The general form of declaring a class is :
class classname {
type instance-variable1;
type instance-variable2;
...
...
type instance-variablen;
type methodname1(parameter list) {
body
}
type methodname2(parameter list) {
body
}
.....
....
type methodnamen(parameter list) {
body
}
}
The variables defined within a class are called instance variables. The code is contained
within methods. The variables and the methods within a class are called as members of the
class. It is the methods that determine how the variables of the class i.e. the class’ data can be
used. Each instance of a class contains its own copy of the instance variables. This implies
that the data for one object is separate and unique from the data of another object. Remember
that Java classes do not need to have a main() method. You only specify a main() method in a
class if that class is the starting point of your program. Also remember that applets do not
have a main() method.
Declaring a Class
Let us begin our study of classes and methods with the following example.
class Volume {
int length;
int breadth;
int height;
}
This is a class with the name Volume which defines three instance variables length, breadth
and height. We have now created a new data type called Volume. We now use this data type
to create objects of type Volume. A class declaration only creates a template, it does not
create any objects. To actually create a object of the type Volume you use a statement as
follows :
Volume vol = new Volume(); //create an object vol of type Volume
Thus vol will be an object of Volume and a physical reality. Every object of the type Volume
will contain its own copies of the instance variables length, breadth and height. It is possible
to create multiple objects of the same class. Remember that changes to the instance variables
of one object will have no effect on the instance variables of another object.
You can create multiple objects for the above class Volume as:
Volume vol2 = new Volume();
Volume vol3 = new Volume();
The new operator dynamically allocates memory for an object and returns a reference to it.
This reference is the memory address of the object allocated by new. Thus in Java all objects
must be dynamically allocated. The advantage of dynamic allocation is that the program can
create as many objects as required during program execution. It may also be possible, that
due to memory not being available, new may not be able to allocate memory for an object. In
such situations a run-time exception occurs.
The above method of declaring objects can also be declared in two steps as follows :
Volume vol1; //declare a reference to object
vol1 = new Volume(); // allocate the object
Thus we can see that the new operator dynamically allocates memory to the object. Its
general form can be written as :
clas-var = new Classname();
where class-var is a variable of type classname. Note that the class name followed by the pair
of parenthesis specifies the constructor for the class. A constructor defines what occurs when
a class is created. If no explicit constructor is specified, Java automatically supplies the
default constructor. We shall study how to define our own constructors subsequently. It is
important to note here that Java’s simple types like integers or characters are not implemented
as objects, and therefore you do not need to use the new operator with them. Java treats
objects differently than the simple types.
To access the instance variables we make use of the dot (.) operator. eg. to access the length
variable of vol you and assign it a value 10, you can use the following statement:
vol.length = 10;
Having understood the basic concept, let us now write a program to determine the volume by
making use of the above class.
class Volume {
int length;
int breadth;
int height;
}
class Demo {
public static void main(String args[ ]) {
Volume vol = new Volume();
int v;
vol.length = 10;
vol.breadth = 10;
vol.height = 10;
v = vol.length * vol.breadth * vol.height;
System.out.println(“Volume is :” + v);
}
}
Remember that the main() method is in the class Demo. Therefore save the file with the
filename Demo.java. When you compile this file, you will see that two .class files are created,
one for class Volume and one for class Demo. Thus each class is put into its own .class file.
You can also put each class in a separate file.
To run the program, you execute the Demo class. The output would be :
Volume is 1000
Now consider the following example :
Volume vol1 = new Volume();
Volume vol2 = vol1;
In such a situation it is important to remember that both vol1 and vol2 refer to the same
object. This means any changes made to vol1 will affect the object to which vol2 is refering
because they are both the same object. Now a subsequent assignment to vol1 will unhook
vol1 from the original object. However, neither the object nor vol2 will be affected. eg.
Volume vol1 = new Volume();
Volume vol2 = vol1;
....
vol1 = null;
In this case, vol1 has been set to null but vol2 still points to the original object. This implies
that when you assign one object reference variable to another object reference variable, you
do not create a copy of the object, you are only making a copy of the reference.
Methods
The code that operates on the data is contained in the methods of a class.
The general form of a method is :
type name(parameter-list) {
body of the method
}
type specifies the data type returned by the method. This can be any valid data type including
the class type that you create. If a method does not return a value, its return type must be
declared void. name specifies the name of the method. The parameter-list is a sequence of
type and identifier pairs separated by commas. Parameters are variables which receive values
of the arguments passed to the method, when it is called. If a method has no parameters, the
parameter list will be empty.
Remember that methods which have a return type other than void, should return a value to
the calling routine using the return statement as follows :
return value;
where value is the value returned.
We know that we can use methods to access the instance variables defined by the class.
Methods define the interface to most classes and therefore the internal data structures remain
hidden. Let us modify the above program to add a method to compute the volume.
class Volume {
int length;
int breadth;
int height;
void calvol() { // method to display volume
System.out.print(“Volume is :”);
System.out.println(length * breadth * height);
}
}
class Demo {
public static void main(String args[ ]) {
Volume vol = new Volume();
int v;
vol.length = 10;
vol.breadth = 10;
vol.height = 10;
vol.calvol(); // call method to
display volume
}
}
/vol.calvol() invokes the method calvol() on the object vol. When the method is executed the
Java run time system transfers control to the code defined inside the volume. When the code
is executed control is transferred back to the calling routine and execution continues from the
following line of code. Remember that in the method calvol() the instance variables are
accessed directly without the dot operator. This is because a method is always invoked
relative to some object of its own class.
In the above example, we have declared the return type of our method to be void which
means our method will not return any value to the calling routine. We can modify the above
method by computing the volume in the method and making the method return the value to
the calling routine. The modified method may be written as :
int calvol() {
return length * breadth * height;
}
In our calling routine we can receive this value in a variable as :
v = vol.calvol();
where v is a variable of type int. Alternatively the volume can directly be printed without an
intermediate variable as:
System.out.println(“Volume is :” + vol.calvol());
In this case, vol.calvol() will be called automatically and its value passed to println().
Remember :
- the type of data returned by a method must be compatible with the return type specified by
the method.
- The variable receiving the value returned by a method must also be compatible with the
return type specified for the method.
Parameterised methods :-
Parameters allow a method to be generalised. A parameterised method can operate on a
variety of data and can be used in a number of slightly different situations. A parameter is a
variable defined by a method which receives a value when the method is called. An argument
is a value that is passed to the method when it is invoked. We can further modify the above
program and add a method which will receive values from the invoking routine as
parameters. These can then be used to compute the volume. Here is a revised version of the
program where we add a method setval().
class Volume
{
int length;
int breadth;
int height;
int calvol() // method to compute volume
{
return length * breadth * height;
}
void setval(int l, int b, int h)
{
length = l;
breadth = b;
height = h;
}
}
class Demo
{
public static void main(String args[ ])
{
Volume vol = new Volume();
vol.setval(10,5,10); // call set
val to set values
int v = vol.calvol(); // call method to compute
volume
System.out.println(“Volume is : “ + v);
}
}
Thus the method setval() is used to set the dimensions length, breadth and height.
CONSTRUCTORS
Constructors
It can be time consuming to initialise all of the variables in a class each time an instance is
created. Therefore Java allows objects to initialise themselves when they are created. This
automatic initialisation is performed through the use of a constructor. A constructor initialises
an object as soon as it is created. It has the same name as the name of the class in which it
resides. Constructors do not have a return type, not even void. This is because the implicit
return type of the class’ constructor is the class type itself. Let us modify the above program
by adding a constructor to it.
class Volume {
int length;
int breadth;
int height;
Volume() {
length = 10;
breadth = 5;
height = 10;
}
int calvol() { // method to calculate volume
return length * breadth * height;
}
}
class Demo {
public static void main(String args[ ]) {
int v;
Volume vol = new Volume();
Volume vol2 = new Volume();
v = vol.calvol(); // call method to
compute volume
System.out.println(“Volume is : “ + v);
v = vol2.calvol();
System.out.println(“Volume is : “ + v);
}
}
Both the objects vol and vol1 were initialised by the Volume() constructor when they were
created. The constructor gave the same set of values to vol and vol2 and therefore the volume
of both vol and vol2 will be the same.
Thus when you allocate an object with the following general form
:
class-var = new classname();
when a constructor is not explicitly defined for a class, Java creates a default constructor.
However, once you define your own constructor the default constructor is no longer used.
Parameterised constructors :
We saw that the above constructor initialised all the objects with the same values. But
actually what is needed in practice is that we should be able to set different initial values. For
this purpose, we make use of parameterised constructors and each object gets initialised with
the set of values specified in the parameters to its constructor. The following modification in
the above program will illustrate :
class Volume {
int length;
int breadth;
int height;
Volume(int l, int b, int h) {
length = l;
breadth = b;
height = h;
}
int calvol() { // method to compute volume
return length * breadth * height;
}
}
class Demo {
public static void main(String args[ ]) {
int v;
Volume vol = new Volume(10,5,10);
Volume vol2 = new Volume(5,5,5);
v = vol.calvol(); // call method to compute volume
System.out.println(“Volume is : “ + v);
v = vol2.calvol();
System.out.println(“Volume is : “ + v);
}
}
Remember that the parameters are passed to the Volume() constructor when new creates the
object. Thus you pass values to the object vol when you create it as : Volume vol = new
Volume(10,5,10).
Garbage Collection
In languages like C++, dynamically allocated objects must be manually released by making
use of the delete operator. Java however handles deallocation automatically. The technique
which accomplishes this task is called garbage collection. When no references to an object
exist, that object is assumed to be no longer needed and the memory occupied by that object
can be reclaimed. There is no explicit need to destroy objects. However, remember that
garbage collection only occurs sporadically during your program execution. It will not occur
just because one or more objects exist which are not used anymore.
finalize() method :
Sometimes an object may be required to perform some specific action when it is destroyed.
eg. if it is holding some non-Java resource like a file handle then such resources should be
freed before the object is destroyed. For this purpose, Java provides a mechanism called
finalization. With finalization, you can define specific actions that will occur when an object
is just about to be destroyed. You can define a finalize() method to specify those actions that
must be performed before an object is destroyed. The Java runtime mechanism calls that
method whenever it is about to recycle an object of that class.
The general form of the method is :
protected void finalize() {
finalization code
}
The protected keyword prevents access to finalize() by code defined outside its class.
finalize() is called prior to garbage collection. It is not called when an object goes out of
scope. Thus you have no way of knowing when (or even if) the method will be executed.
Therefore your program must not depend upon finalize() for normal program operation. It
must have other means of releasing system resources used by the object.
Overloading Methods
When two or more methods in the same class share the same name, as long as their parameter
declarations are different the methods are said to be overloaded and the process is referred to
as method overloading. Java supports overloading. It is one of the ways that Java implements
the concept of polymorphism. When an overloaded method is invoked, Java uses the type
and/or number of arguments as a guide to determine which version of the overloaded method
to call. When Java encounters a call to an overloaded method, it executes that version of the
method whose parameters match the arguments used in the call.
Overloading allows related methods to be accessed by the use of a common name. Thus
through the application of polymorphism, several names have been reduced to one. When
methods are overloaded each method can perform any desired activity. There is no rule
stating that overloaded methods must relate to one another. However, in practice you should
only overload closely related operations.
The following example demonstrates overloading methods.
class Area {
void area(int i) {
int a = i * i;
System.out.println(“Area of a square is :” + a);
}
void area(int i, int j) {
int a1 = i * j;
System.out.println(“Area of a rectangle is :” + a1);
}
void area(float r) {
double a2 = 3.14 * r * r;
System.out.println(“Area of a circle is :” + a2);
}
}
class Over {
public static void main(String args[]) {
Area A = new Area();
A.area(10);
A.area((float)7.2);
A.area(10,5);
}
}
In the above example area() is overloaded thrice, one which takes one integer parameter,
second takes two integer parameters and the third takes one float parameter. When you call a
method, Java looks for a match between the arguments used to call the method and the
parameter list of the method. Upon finding a match, the corresponding method is invoked.
Recursion
Java supports recursion. A method that calls itself is a recursive method.
Example:
public class RecursionExample1 {
static void p(){
System.out.println("hello");
p();
}
class B extends A {
void meth() {
System.out.println(“Implement the abstract method of
superclass A”);
}
}
class Abstracts {
public static void main(String args[]) {
B b = new B();
b.meth ();
b.meth1();
}
}
The output of the program would be :
Implement the abstract method of superclass A Method in abstract class A Remember that
you cannot create an instance of class A. The method meth() which is abstract in class A is
provided a body in the subclass B.
Packages
Packages are containers for classes which are used to keep the class name space
compartmentalised. They are stored in a hierarchical manner and are explicitly imported into
new class definitions. Interfaces can be used to specify a set of methods which can be
implemented by one or more classes. The interface, itself does not define any
implementation. An interface is similar to an abstract class, however a class can implement
more than one interface. On the other hand, a class can only inherit a single superclass.
Packages and interfaces are two of the basic components of a Java program.
In general a Java source file contains the following four internal parts :
- A single package statement (optional)
- Any number of import statements(optional)
- A single public class declaration (required)
- Any number of classes private to the package (optional)
Before studying packages it is important to understand CLASSPATH. The specific location
that the Java compiler will consider as the root of any package is controlled by CLASSPATH.
Till this time, we have been storing all our classes in the same, unnamed default package.
This allows you to compile the source code and run the Java interpreter on the compiled
program by giving the name of the class on the command line. This works because the default
current working directory is usually in the CLASSPATH environmental variable. This
variable is defined for the Java run time system by default. Suppose you create a class
MyPack in a package called pack. This means you have to create a directory called pack and
put MyPack.java into this directory. Pack should now be made the current directory to
compile the program. The class file MyPack.class which will be created after compilation
will also be stored in the pack directory. Now when you try to run MyPack, the Java
interpreter reports an error. This is because the class is now stored in a package called pack.
Thereofore you cannot refer to it only as MyPack. You should now refer to the class by
enumerating its package hierarchy and separating the package by dots. Thus the class will
now be called MyPack.pack. Now if you try using MyPack.pack, you will still receive an
error message. This is because CLASSPATH sets the top of the class hierarchy. So there is no
directory called pack, in the current working directory since you are working in pack itself.
To overcome this problem you have two alternatives :
i) change directories up one level and type java MyPack.pack
ii) add the top of your development class hierarchy to the CLASSPATH environment
variable. Then you will be able to use java MyPack.pack from any directory and Java is able
to find the correct .class file. eg. if you are working on source code in a directory called
c:\student then you should set your CLASSPATH as :
C:\student;C:\java\classes
Defining Packages
You can define classes inside a package that are not accessible to the code outside the
package. You can also define class members that are only exposed to other members of the
same package. Thus the classes can have knowledge of each other, but it is not exposed
outside the package.
To create a package, you should include a package command as the first statement in a Java
source file. Any classes defined within that file will belong to the specified package. The
general form for the package statement is :
package pkg;
where pkg is the name of the package. eg. package pack
will create a package named pack.
Java uses the file system directories to store packages. Therefore any .class files for any
classes declared to be a part of pack, must be stored in a directory called pack. The directory
name must match the package name. More than one file can be included the same package
statement. You can also create a hierarchy of packages. The general form of a multilevel
package statement is :
package pkg1[.pkg2 [.pkg3]];
remember that the package hierarchy should be reflected in the file system of your Java
development system. eg. package java.awt.image; should be stored in java\awt\image on your
Windows file system.
Let us create a small package with the following example :
package Pack;
class Student {
String name;
int roll;
Student(String n, int r) {
name = n;
roll = r;
}
void display() {
System.out.println(“Name : “ + name + “ Roll No. : “ + roll);
}
}
class Studrec {
public static void main(String args[]) {
Student S[] = new Student[3];
S[0] = new Student(“Vikram ”, 20);
S[1] = new Student(“Jerry ”,10);
S[2] = new Student(“Vishnu ”,15);
for(int i = 0; i<3; i++)
S[i].display();
}
}
Save this file as Studrec.java and put in a directory called Pack. When you compile this file,
make sure that the resulting .class file has also been stored in Pack. Then execute Studrec at
the command line as follows :
java Pack.Studrec
Either set the CLASSPATH environment as described previously or go into the directory
above Pack to execute the program. Remember that since Studrec is now a part of the
package Pack, it cannot be executed by itself i.e. a command line
java Studrec
cannot be used.
Access Protection
Packages act as containers for classes and other subordinate packages. Java addresses four
catagories of visibility for class members with reference to packages :
- subclasses in the same package
- non subclasses in the same package
- subclasses in different packages
- Classes that are neither in the same package nor subclass.
The following table summarises the class member access
Anything declared public can be accessed from anywhere. Anything declared private is not
accessible outside of its class. When a member does not have any specific access
specification, it is visible to all subclasses as well as to other classes in the same package.
This is the default access. If you want to allow an element to be seen outside your current
package but only to classes that are the direct subclasses of your class, you have to declare
that element as protected.
Importing packages
All of the built in Java classes are stored in packages. In order to make visible certain classes
or entire packages, Java makes use of the import statement. Once imported, a class can be
referred to directly using only its name. In a Java source file, the import statements occur
immediately following the package statement (if it exists) and before any class definitions.
The general form of the import statement is :
import pkg1[.pkg2].(classname|*);
pkg1 is the name of the top level package, pkg2 is the name of the subordinate package and is
separated by a dot. Practically there is no limit to the depth of a package hierarchy.Then you
can specify either an explicit classname or a star (*). A * indicates that the Java compiler
should import the entire package. eg.
import java.util.Date;
import java.io.*;
All the standard Java classes included with Java are stored in a package called java. The basic
language functions are stored in a package called java.lang. java.lang is implicitly imported
by the compiler for all the programs because is provides a lot of functionality. This is
equivalent to importing it as :
import java.lang.*;
If a class with the same name exists in two different packages which you import using the *
form, then compiler does not issue any warning unless you try to use one of the classes. In
that case a compile time error occurs and you have to explicitly name the class and its
package name.
Wherever you use a class name you can use its fully qualified name which will include its
full package hierarchy. eg.
import java.util.*;
class Example extends Date {
}
can be written without import as :
class Example extends java.util.Date {
}
Only those items within the package declared as public will be available to non subclasses in
the importing code.
Interfaces
Defining an Interface
Using an interface you can specify what a class must do, but not how it does it. You can fully
abstract a class’ interface from its implementation. Interfaces do not have instance variables
and their methods do not have any bodies. Once an interface is defined, any number of
classes can implement an interface. Also one class can implement any number of interfaces.
In order to implement an interface, a class must create a complete set of methods defined by
the interface, but each class is free to implement its own details.
Interfaces are designed to support dynamic method resolution at run time. Usually, for a
method to be called from one class to another class, both the classes need to be present at
compile time. Since interfaces are in a different hierarchy from classes, it is possible for
classes that are unrelated in terms of the class hierarchy to implement the same interface.
The general form of an interface is :
access interface name {
return-type method-name1(parameter-list);
return-type method-name2(parameter-list);
return-type method-name2(parameter-list);
.....
return-type method-nameN(parameter-list);
type final-varnameN = value;
}
In this form, access is either public or not used. The default access applies when no specifier
is used. It implies that the interface is only available to other members of the package in
which it is declared. When the interface is declared public, the interface can be used by
another code. name is the name of the interface which is a valid identifier. The methods in an
interface are abstract methods. Each class which includes an interface must implement all the
methods. Variables can also be declared inside interface declarations. They are implicitly
final and static. This means they cannot be changed by the classes which implement the
interface. The variables must be initialised with constant values. If an interface is declared
public, then all the methods and variables are implicitly declared public.
Let us see an example of interface declaration :
interface A {
void meth1(int i);
}
Implementing an interface
To implement an interface include the implements clause in the class definition and then
create the methods that are defined by the interface The general form of a class which
includes the implements clause is :
access class classname [extends superclass]
[implements interface [,interface....]] {
class body
}
access is either public or not used. If a class implements more than one interface they should
be separated by commas. The methods that implement an interface must be declared public.
Also note that classes which implement interfaces, can have additional members of their own
also. The following example will demonstrate how to implement the above declared
interface:
class One implements A {
public void meth1(int i) {
System.out.println(“Implement interface A in class One”);
System.out.println(“i is :” + i);
}
}
You can also declare variables as object references that use an interface rather than a class
type. Any instance of any class that implements the declared interface can be stored in such a
variable. When a method is called through any such references, the correct version based
upon the actual instance of the interface being referred to will be called. The method to be
executed is looked up dynamically at run time. This allows classes to be created later than the
code which calls methods on them.
Let us call the method meth1() in the above example with the help of an interface reference
variable as shown :
class Iface {
public static void main(String args[]) {
A Ainter = new One();
Ainter.meth1(10);
}
}
In this example, the variable AInter is of interface type A, but it is assigned an instance of
class One. Ainter can access meth1(), but it cannot access any other members of the class One
because the interface reference variable has only knowledge of the methods declared by that
interface declaration. It cannot be used to access any other methods of the class. If a class
includes an interface but does not fully implement the methods defined by that interface, then
the class must be declared abstract. eg
abstract class Two implements A {
int p, q;
void display() {
System.out.println(“p and q” + p + q);
}
}
This class does not implement meth1() of the interface A therefore is declared abstract.
Unit V
The Applet Class:
Applets are small applications that are accessed on an Internet server, transported over the
Internet, automatically installed and run as part of a web document. Once an applet arrives on
the client machine it has limited access to resources. Therefore it can produce an arbitrary
multimedia user interface and run complex computations without introducing the risk of
viruses or breaching data integrity.
Fundamentals
To understand applets let us begin with the following example :
import java.awt.*;
import java.applet.*;
public class AppletDemo extends Applet {
public void paint(Graphics g) {
g.drawstring(“Applet Fundamentals”, 50,20);
}}
From this example you can see that the applet begins with two import statements. The first
imports the Abstract Window Toolkit (AWT) classes. Applets interact with the user through
the AWT and not through console based I/O classes. The AWT contains support for a window
based graphical interface. The second import statement is import java.applet.*; This
statement imports the applet package which contains the Applet class. Every applet that you
create must be a subclass of Applet.
In the next line we declare a class called AppletDemo which extends the Applet class.
Remember that this class must be declared as public, because it will be accessed by code that
is outside the program.
paint() method declared in the class is a method defined by AWT and must be overridden by
the applet. Each time the applet wants to redisplay its output, paint() should be called. Output
may be required to be redisplayed for a number of reasons :
- the window in which the applet is running may be overwritten by another window and then
uncovered again
- the applet window may be minimized and then restored
The paint() method is also called when the applet begins execution. paint() has one parameter
Graphics. This contains the graphics context which describes the graphics environment in
which the applet is running. This context is used whenever output to the applet is required.
drawString() is called inside paint(). drawString() is a member of the Graphics class. The
general form of this method is :
void drawString(String message, int x, int y)
This method outputs a string (in this case message) beginning at the specified x, y location.
Remember that the upper left hand corner is location 0,0 in Java. Thus the message Applet
Fundamentals will be displayed at location 50, 20. Note that the applet does not have a main()
method. Instead, an applet begins execution when the name of its class is passed to an
appletviewer or to a network browser.
Compile the source code in the same way as you compile other programs.
However note the two ways to run an applet :
i) Execute the applet with a Java compatible web browser like Netscape Navigator : To
accomplish this you need to write a short HTML text file which contains the appropriate
APPLET tag.
To execute AppletDemo the HTML file you write should be as follows :
<applet code = “AppletDemo” width = 200 height = 60>
</applet>
The width and height specify the dimensions of the display area used by the applet. After you
create this file, you can execute your browser and then load this file. It will cause
AppletDemo to be executed.
ii) Use an applet viewer such as the standard JDK tool, appletviewer. An appletviewer
executes the applet in a window. This is generally the fastest and easiest way to test your
applet.
You can execute the above HTML file in an appletviewer also. eg. if you name your HTML
file as ApDemo.html then type the following command line to run the applet :
C:\> appletviewer ApDemo.html
There is another convenient way to do this. In this method, you include a comment at the
head of your Java source file that contains the APPLET tag. This documents your code with a
prototype of the necessary HTML statements, and you can test your applet by starting the
appletviewer with the Java sourcecode file. The revised code of your source program in this
situation will be as follows :
import java.awt.*;
import java.applet.*;
/* <applet code = “AppletDemo” width = 200 height = 60>
</applet>
*/
public class AppletDemo extends Applet {
public void paint(Graphics g) {
g.drawstring(“Applet Fundamentals”,50,20);
}}
Remember :
- Applets do not need main() method
- Applets must run under an Appletviewer or a Java compatible browser
- User I/O is not accomplished with Java’s stream I/O classes. Instead the interface provided
by the AWT is used by applets for user I/O.
THE APPLET CLASS
The Applet class provides the necessary support for applet execution. It also provides
methods that load and display images, and methods that load and display audio clips. Applet
extends the AWT class Panel which in turn extends Container, which extends Component.
These classes provide support for Java’s window based graphical interface.
Applet Architecture
An applet is a window based program. Applets are event driven. An applet resembles a set of
interrupt driven routines. An applet waits until an event has occured. The AWT notifies that
applet about an event by calling an event handler that has been provided by the applet. Once,
this happens the applet must take the necessary action and quickly return control to the AWT.
Remember, your applet should not enter a mode of operation in which it maintains control for
an extended period. Instead it must perform specific actions in response to events and return
control to AWT run time system. If there are situations where your applet needs to perform
repetitive tasks on its own, you must start an additional thread of execution.
The user initiates an interaction with the applet, the applet does not. These user interactions
are sent to the applet as events to which the applet responds. eg. when the user clicks a mouse
within an applet's window, a mouse-clicked event is generated. Applets can contain various
controls like push buttons and checkboxes. When the user interacts with these controls an
event is generated.
An Applet Skeleton
Applets override a set of methods which provide the basic mechanism by which the browser
or applet viewer interfaces to the applet and controls its execution. Four of these methods
init(), start(),stop() and destroy() are defined by Applet. The method paint() is defined by the
AWT Component class. Default implementations of these methods are provided. Also applets
need not override those methods which they do not use.
Let us study these methods with the following skeleton of an applet program:
import java.awt.*;
import java.applet.*;
/*
<applet code = “Skeleton” width = 300 height = 60>
</applet>
*/
public class Skeleton extends Applet {
public void init() {
// initialisation
}
public void start() {
// start or resume execution
}
public void stop() {
// suspends execution
}
public void destroy() {
// perform shut down activity
}
public void paint(Graphics g) {
// redisplay the contents of a window
}
}
When an applet begins, the AWT calls the following methods in the given sequence :
init() : This is the first method to be called. This is where variables should be initialised. This
method is called only once during the run time of your applet.
start() : The start() method is called after init(). It is also called to restart an applet after it has
been stopped. start() is called each time an applet’s HTML document is displayed on screen.
This means that if an user leaves a web page and comes back, the applet resumes execution at
start().
paint() : This method is called everytime the output is to be redrawn. We have already
studied paint() in the previous section.When an applet is terminated the following methods
are called in this sequence :
stop() : This method is called when a web browser leaves the HTML document containing
the applet. When stop() is called the applet is probably still running.
stop() should be used to suspend threads which don’t need to run when the applet is not
visible. You can restart them when start() is called.
destroy() : This method is called when the environment determines that your applet needs to
be removed completely from memory. At this point all the resources that the applet may be
using should be freed. The stop() method is always called before destroy().
update() : update() is a method defined by AWT. In some situations you may be required to
override the update() method. This method is called when your applet has requested that a
portion of its window be redrawn. The default version of update() first fills an applet with the
default background colour and then calls paint(). If you fill the background using a different
colour in paint() the user will experience a flash of the default background everytime update()
is called. To avoid this, you can override the update() method so that it will perform the
necessary activities. Then call update() in paint(). eg.
public void update(Graphics g) {
// redisplay your window
}
public void paint(Graphics g) {
update(g);
}
Passing Parameters to Applets
The APPLET tag in HTML allows you to pass parameters to your applet. To retrieve a
parameter, you have the getParameter() method, which returns the value of the specified
parameter in the form of a String object. Therefore numeric and Boolean values have to be
converted from their string representations to their internal formats. The following example
will illustrate :
import java.awt.*;
import java.applet.*;
/*
<applet code = “Parameters” width = 300 height = 60>
<param name = fontName value = Courier>
<param name = fontSize value = 12>
<param name = leading value = 2>
</applet>
*/
public class Parameters extends Applet {
String fontName;
int fontSize;
float leading;
public void start() {
String p;
fontName = getParameter(“fontName”);
if(fontName == null)
fontName = “Not found”;
p = getParameter(“fontSize”);
try {
if(p != null)
fontSize = Integer.parseInt(p);
else
fontSize = 0;
}
catch(NumberFormatException e) {
fontSize = -1;
}
p = getParameter(“leading”);
try {
if(p != null)
leading = Float.valueOf(p).floatValue();
else
leading = 0;
}
catch(NumberFormatException e) {
leading = -1;
}
}
public void paint(Graphic g) {
g.drawString(“Font name : “ + fontName, 10, 10);
g.drawString(“Font size : “ + fontSize, 10, 20);
g.drawString(“Leading : “+ leading 10, 30);
}
}
Event Handling
An important aspect of Java that relates to applets is events. Applets are event driven
programs. The most commonly handled events are those generated by the mouse, the
keyboard, and the various controls like push buttons. Events are supported by the
jawa.awt.event package.
The Delegation Event Model
The delegation event model defines standard and consistent mechanisms to generate and
process events. In this model, the concept is, that a source generates an event and sends it to
one or more listeners. The listener simply waits for an event, once it receives the event, the
listener processes it and returns. The advantage of this design is that the application logic
which processes the events is cleanly separated from the user interface logic that generates
the events. Thus the user interface element is able to delegate the processing of an event to a
separate piece of code. In this model, the listeners must register with a source in order to
receive the notification of an event. This means that notifications are sent only to those
listeners who wish to receive them.
Events
In the delegation model, an event is an object which describes a state change in a source. The
event can be generated as a result of a person interacting with the elements in a graphical user
interface. Pressing a button, entering a character via a keyboard, selecting an item in a list,
clicking the mouse are some of the activities which cause events to be generated. Events may
also occur as a consequence which is not directly caused by user interface. eg. An event may
be generated if a timer expires, a counter exceeds a value, hardware or software failure occurs
etc. You are free to define events that are appropriate to your application.
Sources of Events
A source is an object which generates an event. This occurs when the internal state of the
object changes in some way. 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. Each type of event has its own registration method.
The general form is :
public void addTypeListener(TypeListener el)
where Type is the name of the event and el is the reference to the event listener. eg the method
that registers a keyboard event listener is called addKeyListener().
When an event occurs, all the registered listeners are notified and receive a copy of the event
object. This is known as multicasting the event. Some sources may allow only one listener to
register.
The general form of this method is :
public void addTypeListener(TypeListener el) throws java.util.TooManyListenersException
where Type is the name of the event and el is the reference to the event listener. When such an
event occurs, the registered listener is notified. This is called as unicasting the event.
A source must also provide a method to allow a listener to unregister an interest in a specific
event. The general form of this method is :
public void remove TypeListener(TypeListener el)
here, Type is the name of the event and el is the reference to the event listener eg to remove a
keyboard listener you would call the removeKeyListener() method. The methods that add or
remove listeners are provided by the source that generates the events.
Event Listeners
A listener is an object that is notified when an event occurs. It has two major requirements :
- First it must have been registered with one or more sources to receive the notifications about
specific types of event.
- Second it must implement methods to receive and process these notifications.
The methods which receive and process events are defined in a set of interfaces found in
java.awt.event.
Event Classes
The classes which represent events are at the core of Java’s event handling mechanism. At the
root of the Java class event hierarchy is the EventObject, which is in java.util. It is the
superclass for all events. One of its constructors is :
EventObject(Object src)
where src is the object that generates the event.
EventObject contains two methods : getSource() and toString().
getSource() method returns the source of the event. Its general form is :
Object getSource()
toString() returns the string equivalent of the event.
The class AWTEvent, which is defined in the java.awt package, is a subclass of EventObject.
It is the superclass of all AWT-based events used by the delegation event model. The method
getID() of this class is used to determine the type of the event.
Its form is :
int getID()
The Action Event Class
From the table we can see that an ActionEvent is generated when a button is pressed, a list
item is double clicked or a menu item is selected. This class defines four integer constants
which can be used to identify any modifiers associated with an action event. These constants
are ALT_MASK, CTRL_MASK, META_MASK, SHIFT_MASK. There is also an integer
constant ACTION_PERFORMED, which can be used to identify action events.
The constructors of ActionEvent are :
ActionEvent(Object src, int type, String cmd)
ActionEvent(Object src, int type, String cmd, int modifiers)
where src is a reference to the object which generated the event.
type specifies the type of the event and cmd is the command string. The argument modifiers
indicates which of the modifier keys (ALT, CTRL, META and/or SHIFT) were pressed when
the event was generated.
getActionCommand() is the method which used to obtain the command name for the
invoking ActionEvent object. Its form is :
String getActionCommand()
The getModifiers() method returns a value that indicates which modifier keys were pressed
when the event was generated. Its general form is :
int getModifiers()
The Key Event Class
A KeyEvent is generated when a keyboard input occurs. There are three types of key events
which are identified by the integer constants : KEY_PRESSED, KEY_RELEASED,
KEY_TYPED. The first two events are generated when any key is pressed or released. The
last event occurs only when a character is generated. We know that all key presses do not
result in characters eg. pressing the SHIFT key will not generate any character. KeyEvent
defines many other integer constants. eg. VK_0 through VK_9 and VK_A through VK_Z
define the ASCII equivalents of the numbers and literals respectively. KeyEvent is a subclass
of InputEvent. Its constructors are :
KeyEvent(Component src, int type, long when, int modifiers, int code)
KeyEvent(Component src, int type, long when, int modifiers, int code, char ch)
where src is a reference to the component that generated the event, type of the event is
specified by type. The system time at which the key was pressed is passed in when. The
modifiers argument indicates which modifiers were pressed when this key event occured. The
virtual key code is passed in code. The character equivalent, if it exists is passed in ch. If no
valid character exists, then ch contains CHAR_UNDEFINED.
The commonly used methods of the KeyEvent class are :
getKeyChar() : which returns the character that was entered and has the following general
form :
char getKeyChar()
getKeyCode() : which returns the key code. Its general form is :
int getKeyCode()
Introducing the AWT:
AWT Classes:
The AWT (Abstract Window Toolkit) contains numerous classes and methods which allow
you to create and manage windows. In this chapter you will learn how to create and manage
windows, manage fonts, output text and utilise graphics. The next chapter will describe the
various controls like push buttons and scroll bars supported by AWT. Remember that though
the main purpose of the AWT is to support applet windows, it can also be used to create stand
alone windows that run in a GUI environment. The AWT classes are contained in the java.awt
package. It is one of the largest packages of Java.
Window Fundamentals:
The AWT defines windows according to a class hierarchy that adds functionality and
specificity with each level. The two most common windows are those derived from Panel,
which is used by applets and those derived from Frame which creates a standard window. At
the top of the AWT hierarchy is the Component class. This is an abstract class which
encapsulates all of the attributes of a visual component. All those user interfaces which are
displayed on the screen and those which interact with the user are subclasses of Component.
Component defines over a hundred public methods which are useful for managing events like
mouse and keyboard inputs, etc. The Container class is a subclass of Component. It has
additional methods which allow other Component objects to be nested within it. Other
container objects can be stored inside a Container, since they themselves are instances of
Component. A container is responsible for laying out any components that it contains. This is
done through the use of layout managers.
The Panel class is a concrete subclass of Container. It simply implements the Container. It
does not add any new methods. Panel is the superclass for Applet. When screen output is
directed to an applet, it is drawn on the surface of a panel object. A Panel is a window which
does not contain a title bar, a menu bar or a border. This is the reason you don’t see these
items when an applet is run inside a browser. However, when you run an applet in an applet
viewer, the applet viewer provides the title and the border. Other components can be added to
the Panel object by using the add() method which is inherited from Container.
The Window class creates a top level window. A top level window is a window which is not
contained within any other object; it sits directly on the desktop. Generally, you don’t create a
Window object directly. You use a subclass of Window called Frame.
Frame is a subclass of Window and has a title bar, menu bar, borders and resizing corners. If
you create a Frame object from within an applet, it will contain a warning message (eg.
Warning : Applet Window) to the user indicating that an applet window has been created.
This message warns the user that the window was started by an applet and not by software
running on their computer.
Canvas encapsulates a blank window upon which you can draw. Remember Canvas is not a
part of the hierarchy for applet or frame windows.
Working with Frame Windows:
Frame is used to create child windows within applets and top level or child windows for
applications. It creates a standard style window. Frame supports the following constructors :
Frame()
Frame(String title)
The first form creates a window which does not contain a title while the second form creates
a window with the title specified by title. Remember that you cannot specify the dimensions
for the window, you must set the size of the window after it has been created. Some of the
methods we shall use when working with Frame windows include:
The setSize() method is used to set the dimensions of the window. It takes the following form
:
void setSize(int newWidth, int newHeight)
void setSize(Dimension newSize)
newWidth and newSize specify the size of the window in the first case. In the second case the
size of the window is specified by the width and height fields of the Dimension object passed
in newSize. The dimensions are specified in pixels. To obtain the current size of the window
the method is getSize(). Its form is:
Dimension getSize()
It returns the current size of the window in contained in the width and height fields of the
Dimension object.
A frame window created will not be visible until you call the setVisible() method. This
method is :
void setVisible(boolean visibleFlag)
If visibleFlag is true, the component is visible else it is hidden.
To change the title in the frame window use the method setTitle(). Its form is:
void setTitle(String newTitle)
where newTitle is the new title for the window.
Your program must remove the window from the screen when it is closed by calling
setVisible(false). To intercept a window close event, you should implement the
windowClosing() method of the WindowListener interface.
Inside windowClosing() you must remove the window from the screen.
Let us now create a Frame window in an Applet as shown below:
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<applet code = “Frames” width = 300 height = 100>
</applet>
*/
class DemoFrame extends Frame {
DemoFrame(String title) {
super(title);
}
public void paint(Graphics g) {
g.drawString(“This is the Frame Window”, 50, 50);
}
public class Frames extends Applet {
public void init() {
Frame f;
f = new DemoFrame(“A Frame Window”);
f.setSize(200,200);
f.setVisible(true);
}
public void start() {
f.setVisible(true);
}
public void stop() {
f.setVisible(false);
}
public void paint(Graphics g) {
g.drawString(“This is the Applet window”, 10, 30);
}
}
First you create a subclass of Frame. Once a subclass of Frame is created, you create an
object of that class. This causes the frame window to come into existence, but you should call
setVisible() (by setting it to true) to make it visible. You can also set the size of the window
explicitly by calling setSize(). Next override any of the standard window methods like init(),
start(), stop() and paint(). Note that we have not implemented any event handling mechanism.
You can modify the above program to create an object to handle window events to close the
frame window by implementing the windowClosing() method of the WindowListener
interface by calling setVisible() .
Working With Graphics
The AWT support a rich set of graphics methods. All graphics are drawn relative to a window.
The window can be the main window of an applet, a child window of an applet or a stand
alone application window. Each window originates at the upper left hand corner and is 0,0.
All the output to a window takes place through a graphics context. A graphics context is
encapsulated by the Graphics class and is obtained in the following ways :
- It is passed to an applet when one of its various methods like paint() or update() is called.
It is returned by the getGraphics() method of Component. 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. Whenever
a graphics object is drawn which exceeds the dimensions of the window, the output is
automatically clipped. Let us see some of the drawing methods in this section.
Drawing Lines
The method drawLine() is used to draw lines. Its form is :
void drawLine(int startX, int startY, int endX, int endY)
The line is drawn in the current drawing color beginning at startX, startY and ending at endX,
endY. In the following example a number of lines are drawn :
import java.awt.*;
import java.applet.*;
/*
<applet code = “Lines” width = 300 height = 200>
</applet>
*/
public class Lines extends Applet {
public void paint(Graphics g) {
g.drawLine(10, 10, 100, 100);
g.drawLine(0, 0, 150, 200);
g.drawLine(5,50, 400, 250);
g.drawLine(40, 25, 250, 180);
}
}
Drawing Rectangles :
drawRect() and fillRect() are the methods which display an outlined and filled rectangle
respectively. These methods are :
void drawRect(int top, int left, int width, int height)
void fillRect(int top, int left, int width, int height)
top,left is the upper left corner of the rectangle. width and height specify the dimensions of
the rectangle.
drawRoundRect() or fillRoundRect() are the methods to draw rounded rectangle. A rounded
rectangle has rounded corners. The methods are:
void drawRoundRect(int top, int left, int width, int height, int xDiam, int yDiam)
void fillRoundRect(int top, int left, int width, int height, int xDiam, int yDiam)
top,left is the upper left corner of the rectangle. width and height specify the dimensions of
the rectangle. The diameter of the rounding arc along the X axis is specified by xDiam and
the diameter of the rounding arc along the Y axis is specified by yDiam.
The following example illustrates
import java.awt.*;
import java.applet.*;
/*
<applet code = “Rect” width = 300 height = 200>
</applet>
*/
public class Rect extends Applet {
public void paint(Graphics g) {
g.drawRect(10, 10, 50, 80);
g.fillRect(100, 10, 50, 80);
g.drawRoundRect(200, 10, 50, 60, 20, 20);
g.fillRoundRect(270, 10, 50, 50, 35, 40);
}
}
Drawing Ellipses and Circles :
To draw an ellipse use the drawOval() method and to fill an ellipse use the fillOval() method.
These methods are :
void drawOval(int top, int left, int width, int height)
void fillOval(int top, int left, int width, int height)
The ellipse is drawn within a bounding rectangle whose upper left corner is top, left and
whose width and height are specified by width and height respectively. To draw a circle you
will have the specify a square as the bounding rectangle. The following example draws
ellipses :
import java.awt.*;
import java.applet.*
/*
<applet code = “Circles” width = 300 height = 200>
</applet>
*/
public class Circles extends Applets {
public void paint(Graphics g) {
g.drawOval(10, 10, 50, 60);
g.drawOval(80, 10, 50, 70);
g.fillOval(160, 10, 40,40);
g.fillOval(80, 90, 50, 50);
}
}
AWT CONTROLS
Let us study the various controls supported by AWT in the following sections:
Labels
A label is an object of type Label and contains a string which it displays. Labels do not
support any interaction with the user and are therefore passive controls. The constructors for
Label are :
Label()
Label(String str)
Label(String str, int how)
where the string is specified by str. This string is by default left justified. How specifies the
alignment which will be used by str. The value of how must be one of these three constants :
Label.LEFT, Label.RIGHT, Label.CENTER.
setText() method is used to set or change text in a label. The getText() method is used to
obtain the current label. These methods have the following form :
void setText(String str) str sets the string for the label
String getText() returns the current label
To set the alignment of the string within the label you use the method :
void setAlignment(int how)
how is the alignment constant already discussed.
getAlignment() is used to obtain the current alignment :
int getAlignment()
The following example will demonstrate :
import java.awt.*;
import java.applet.*;
/*
<applet code = “Labels” width = 200 height = 300>
</applet>
*/
public class Labels extends Applet {
public void init() {
Label first = new Label(“First”);
Label second = new Label(“Second”); // Create Labels
Label third = new Label(“Third”);
add(first);
add(second); // Add labels to applet window
add(third);
}
}
Buttons
A push button is a component that contains a label and generates an event when pressed. Push
buttons are objects of type Button. Button defines the following constructors :
Button() Button(String str)
The second constructor creates a button which contains str as a label.
After a button has been created, you can set its label with the setLabel() method. The label
can be retrieved using the getLabel() method. These methods are :
void setLabel(String str)
String getLabel()
Each time a button is pressed an action event is generated which is sent to any listeners which
have previously registered for receiving the action event notification. Each listener
implements the ActionListener interface. This interface defines the actionPerformed()
method. This method is called when an event occurs. It takes an ActionEvent object as its
argument. This object contains both a reference to the button that generated the event and a
reference to the string that is the label of the button. Either value may be used to identify
the button.
The following example illustrates using the label of the button to determine which button is
pressed. Each time a button is pressed, a message is displayed which reports which button is
displayed. Note that we obtain the label by calling the getActionCommand() method on the
ActionEvent object passed to actionPerformed().
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<applet code = “Buttons” width = 100 height = 300>
</applet>
*/
public class Buttons extends Applet implements ActionListener {
String s = “ “;
Button yes, no;
public void init() {
yes = new Button(“Yes”);
no = new Button(“No”);
add(yes);
add(no);
yes.addActionListener(this);
no.addActionListener(this);
}
public void actionPerformed(ActionEvent ae) {
String s1 = ae.getActionCommand();
if(s1.equals(“Yes”))
s = “You pressed Yes”;
else
s = “You pressed No”;
repaint();
}
public void paint(Graphics g) {
g.drawString(s, 10, 80);
}
}
The following example shows how to use the getSource() method to obtain the object to
determine which button has been pressed. For this purpose you should keep a list of the
button objects when they are created.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<applet code = “Buttons1” width = 250 height = 100>
</applet>
*/
public class Buttons1 extends Applet implements ActionListener {
String s= “ “;
Button bList[] = new Button[2];
public void init() {
Button yes = new Button(“Yes”);
Button no = new Button(“No”);
bList[0] = (Button) add(yes);
bList[1] = (Button) add(no);
for(int i = 0; i < 2; i++)
bList[i].addActionListener(this);
}
public void actionPerformed(ActionEvent ae) {
for(int i = 0; i < 2; i++)
{
if(ae.getSource() == bList[i])
s = “You pressed “ + bList[i].getLabel();
}
repaint();
}
public void paint(Graphics g) {
g.drawString(s, 10, 80);
}
}
Check Boxes
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. It
describes the option that the check box represents. Check boxes can be used individually or
as part of a group. Check boxes are objects of the Checkbox class. Its constructors are :
Checkbox() Checkbox(String str)
Checkbox(String str, boolean on)
Checkbox(String str, boolean on, CheckboxGroup cbGroup)
Checkbox(String str, CheckboxGroup cbGroup, boolean on)
str specifies the label for a check box. on allows you to set the initial state of the check box. If
on is true then the checkbox is initially checked, otherwise it is cleared. cbGroup specifies the
group for a checkbox. If the check box is not a part of the group then cbGroup must be null.
getState() method used to retrieve the current state of a check box. Its form is :
boolean getState()
setState() is used to set the state of the check box. Its form is :
void setState(Boolean on)
If on is true, the box is checked, if false the box is cleared.
To obtain the current label, you use getLabel() and to set the label you use setLabel(). These
methods are as follows :
String getLabel() void setLabel(String str)
where str specifies the label for the check box.
Each time a check box is checked or cleared, an item event is generated which is sent to any
listener which previously registered an interest in receiving item event notifications from that
component. Each listener implements the ItemListener interface. This interface defines the
itemStateChanged() method which takes as its argument an object of ItemEvent.
In the following example we illustrate the use of check boxes and display status of each box.
Every time you change the status of the check box, the status display will be updated.
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<applet code = “Checks” width = 240 height = 200>
</applet>
*/
public class Checks extends Applet implements ItemListener {
String s = “ “;
Checkbox swim, hockey, cricket, football;
public void init() {
swim = new Checkbox(“Swimming”, true);
hockey = new Checkbox(“Hockey”);
cricket = new Checkbox(“Cricket”);
football = new Checkbox(“Football”);
add(swim);
add(hockey);
add(cricket);
add(football);
swim.addItemListener(this);
hockey.addItemListener(this);
cricket.addItemListener(this);
football.addItemListener(this);
}
public void itemStateChanged(ItemEvent ie) {
repaint();
}
public void paint(Graphics g) {
s = “Current state of Check boxes :”;
g.drawString(s, 10, 80);
s = “ Swimming : “ + swim.getState();
g.drawString(s, 10, 100);
s = “ Hockey : “ + hockey.getState();
g.drawString(s, 10, 120);
s = “ Cricket : “ + cricket.getState();
g.drawString(s, 10, 140);
s = “ Football : “ + football.getState();
g.drawString(s, 10, 160);
}
}
Checkbox Group
Radio buttons are 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. In order to create radio buttons you must
first define a group to which they belong and then specify that group when you construct the
check boxes. Check box groups are objects of type CheckBoxGroup. It has only the default
constructor defined, which creates an empty group.
To determine which check box in a group is currently selected you call the
getSelectedCheckbox() method. To set a check box you call the setSelectedCheckbox()
method. These methods are as follows :
Checkbox getSelectedCheckbox()
void setSelectedCheckbox(Checkbox which)
where which is the check box you want to be selected. In this case, the previously selected
check box will be turned off.
The following example will demonstrate :
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<applet code = “CheckGroup” width = 300 height = 200>
</applet>
*/
public class CheckGroup extends Applet implements ItemListener {
String s= “ “;
Checkbox swim, hockey, cricket, football;
CheckboxGroup cbg;
public void init() {
cbg = new CheckboxGroup();
swim = new Checkbox(“Swimming”, cbg, true);
hockey = new Checkbox(“Hockey”, cbg, false);
cricket = new Checkbox(“Cricket”, cbg, false);
football = new Checkbox(“Football”, cbg, false);
add(swim);
add(hockey);
add(cricket);
add(football);
swim.addItemListener(this);
hockey.addItemListener(this);
cricket.addItemListener(this);
football.addItemListener(this);
}
public void itemStateChanged(ItemEvent ie) {
repaint();
}
public void paint(Graphics g) {
s = “Currently selected : “;
s+=cbg.getSelectedCheckbox().getLabel();
g.drawString(s, 10, 100);
}
}
Text Field
The TextField class implements a single line text entry area usually called as edit control.
Text fields allow the user to enter strings and to edit the text using arrow keys, cut and paste
keys and mouse selections. TextField is a subclass of TextComponent. It defines the
following constructors :
TextField() TextField(int numChars)
TextField(String str) TextField(String str, int numChars)
The first form creates a default text field. The second form creates a text field which is
numChars wide. The third form initialises the text field with the string contained in str,
whereas in the fourth form you can initialise the text field and set its width.
To obtain the string currently contained in the text field you call the getText() method and to
set the text you call the setText() method. These methods are :
String getText()
void setText(String str)
where str is the new string.
You can select a portion of the text in the text field and you can also select a portion of the
text under program control. Both these can be achieved with the select() method. The
currently selected text can be obtained by your program by using getSelectedText(). These
methods are :
String getSelectedText()
void select(int startIndex, int endIndex)
The select() method selects characters beginning at startIndex and ending at endIndex-1.
To control whether the contents of the text field may be modified by the user or not you use
the setEditable() method. Its form is :
void setEditable(boolean canEdit)
Here, if canEdit is true then the text maybe changed, if it is false the text cannot be altered.
isEditable() is the method used to determine the editability of the text field.
Its form is :
boolean isEditable()
it returns true if the text maybe changed, false otherwise.
You can disable the character echoing on the screen as they are typed by the setEchoChar()
method. This method specifies a single character that the text field will display when
characters are entered. This means that the actual characters typed will not be shown. This is
particularly useful when entering passwords.
This method has the form :
void setEchoChar(char ch)
where ch specifies the character to be echoed.
You can retrieve the echo character by calling the getEchoChar() method.
Its form is :
char getEchoChar()
echoCharIsSet() is the method which can be used to check whether a text field is in this
mode. Its form is :
boolean getCharIsSet()
Text fields perform their own editing functions. So your program do not need to respond to
indivisual key events that occur within the text field. However, when the user presses Enter,
you may want to respond. This generates an action event.
Let us create the user name and password screen in the following example which will make
use of many methods which have been discussed above :
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/*
<applet code = “TextFieldDemo” width = 300 height = 200>
</applet>
*/
public class TextFieldDemo extends Applet implements ActionListener {
TextField name, pass;
public void init() {
Label n = new Label(“Name : “, Label.RIGHT);
Label p = new Label(“Password : “, Label.RIGHT);
name = new TextField(15);
pass = new TextField(5);
pass.setEchoChar(‘*’);
add(n);
add(name);
add(p);
add(pass);
name.addActionListener(this);
pass.addActionListener(this);
}
public void actionPerformed(ActionEvent ae) {
repaint();
}
public void paint(Graphics g) {
g.drawString(“Name :- “ + name.getText(), 10, 80);
g.drawString(“Selected text in Name :- “ +
name.getSelectedText(), 10,100);
}
}
Text Area
The AWT includes a simple multline editor called TextArea. Its constructors are :
TextArea() TextArea(int numLines, int numChars)
TextArea(String str) TextArea(String str, int numLines, int numChars)
TextArea(String str, int numLines, int numChars, int sBars)
numLines specifies the height, in terms of lines of the text area and numChars specifies its
width, in characters. Initial text can be specified in str.
sBars allows to specify the scroll bars you want the control to have. It can have
one of the following values: SCROLLBARS_BOTH SCROLLBARS_NONE
SCROLLBARS_HORIZONTAL_ONLY SCROLLBARS_VERTICAL_ONLY
TextArea is a subclass of TextComponent. It supports the getText(), setText(),
getSelectedText(), select(), isEditable(), and setEditable() methods which have been
previously described.
TextArea adds the following methods :
void append(String str) : appends the string specified by str to the end of the current text.
void insert(String str, int index) : inserts the string specified by str at the specified index.
void replaceRange(String str, int startIndex, int endIndex) : This method replaces characters
from startIndex to endIndex-1. The replacement text is passed in str.
Text areas are almost self contained controls.
The following program demonstrates the use of text areas :
import java.awt.*;
import java.applet.*;
/*
<applet code = “TextDemo” width = 400 height = 250>
</applet>
*/
public class TextDemo extends Applet {
public void init() {
String val = “Scroll bars are used to select continuous values\n” + “ between a specified
minimum and maximum.\n” + “ Scroll bars can be oriented horizontally or vertically.\n” +
“A scroll bar is in fact a composite of\n” + “ a number of indivisual parts.\n “;
TextArea text = new TextArea(val, 10, 30);
add(text);
}
}
LAYOUT MANAGERS
Fundamentals
In all our previous examples, all the components have been positioned by the default layout
manager. A layout manager automatically arranges the controls within a window. Each
Container object has a layout manager associated with it. A layout manager is an instance of
any class that implements the LayoutManager interface. The layout manager is set by the
setLayout() method. If no call to setLayout() is made, then the default layout manager is used.
Whenever a container is resized (or sized for the first time), the layout manager is used to
position the components in it.
The setLayout() method has the following form :
void setLayout(LayoutManager layoutObj)
wher layoutObj is a reference to the desired layout manager. It is also possible to the disable
the layout manager and position the components manually. For this purpose, you pass a null
for layoutObj. In such a situation, you should determine the shape and position of each
component manually by using the setBounds() method defined by Component. Normally
layout manager is used.
Each layout manager keeps a track of the list of components which are stored by their names.
The layout manager is notified everytime you add a component to a container. Each
component that is being managed by the layout manager contains the getPreferredSize() and
getMinimunSize() methods. These return the preferred size and the minimum size required
for each component. Whenever the container needs to be resized, the minimumLayoutSize()
and preferredLayoutSize() methods are used.
Flow Layout
This is the default layout manager. This was the layout manager which was used by all our
preceding examples. In the FlowLayout, components are laid out from the upper left hand
corner, left to right and top to bottom. When no more components fit on a line, the next
component appears on the next line. A small space is left between each component, above
and below it as well as to the left and right.
The constructors for FlowLayout :
FlowLayout()
FlowLayout(int how) FlowLayout(int how, int horz, int vert)
In the first form, all components are centered and a space of 5 pixels is left between each
component. In the second form, you can sepcify how each line is aligned. The valid values
for how are :
FlowLayout.LEFT FlowLayout.CENTER FlowLayout.RIGHT
These values specify the left, center and right alignment respectively. The third form allows
to specify the horizontal and vertical space left between components in horz and vert
respectively.
Let us modify our previous example of CheckBox control so that it uses the right aligned
flow layout. Note that this program is for the purpose of illustration of the layout manager.
No event handling mechanisms are incorporated.
import java.awt.*;
import java.applet.*;
/*
<applet code = “CheckGroup” width = 300 height = 200>
</applet>
*/
public class CheckGroup extends Applet {
Checkbox swim, hockey, cricket, football;
public void init() {
setLayout(new FlowLayout(FlowLayout.RIGHT));
swim = new Checkbox(“Swimming”, null, true);
hockey = new Checkbox(“Hockey”);
cricket = new Checkbox(“Cricket”);
football = new Checkbox(“Football”);
add(swim);
add(hockey);
add(cricket);
add(football);
}
}
Border Layout :
The BorderLayout class implements a common layout style for top level windows. It has four
narrow, fixed width components at the edges and one large area in the center. The four sides
are referred to as north, south, east and west. The middle area is called the center. The
constructors for BorderLayout are :
BorderLayout() BorderLayout(int horz, int vert)
The first form creates the default border layout. In the second form you can specify the
horizontal and vertical space left between the components by horz and vert respectively.
BorderLayout defines the following constants which specify the regions :
BorderLayout.CENTER BorderLayout.SOUTH
BorderLayout.EAST BorderLayout.WEST
BorderLayout.NORTH
These constants are to be used while adding the components with the following form of add()
which is defined by Container :
void add(Component compObj, Object region);
compObj is the component to be added and region specifies where the component will be
added.
The following example demonstrates the BorderLayout :
import java.awt.*;
import java.applet.*;
import java.util.*;
/*
<applet code = “BorderDemo” width = 300 height = 200>
</applet>
*/
public class BorderDemo extends Applet {
public void init() {
setLayout(new BorderLayout());
add(new Button(“This is the North”),
BorderLayout.NORTH);
add(new Button(“This is the South”),
BorderLayout.SOUTH);
add(new Button(“EAST”), BorderLayout.EAST);
add(newButton(“WEST”), BorderLayout.WEST);
String s = “This program demonstrates the Border Layout \n” + “It shows the North, South,
East and West Positions \n” + “It also shows the Center”;
add(new TextArea(s),
BorderLayout.CENTER);
}
}
Grid Layout :
This layout lays out the components in a two dimensional grid. You define the number of
rows and columns when you instantiate the GridLayout. The constructors for GridLayout
are :
GridLayout() GridLayout(int numRows, int numColumns)
GridLayout(int numRows, int numColumns, int horz, int vert)
The first form creates a single column grid layout. With the second form you can create a grid
layout of the specified number of rows and columns. The third form allows you to specify the
horizontal and vertical space between components using the horz and vert respectively. Either
numRows or numCols can be zero. If numRows is zero, it allows columns of unlimited length
and specifying numColumns as zero allow for unlimited-length rows.
Study the following example that creates a grid layout of size 4 x 4 and fills it with buttons,
where the button of each label is its index.
import java.awt.*;
import java.applet.*;
/*
<applet code = “Grid” width = 200 height = 200>
</applet>
*/
public class Grid extends Applet {
static final int n = 4;
public void init() {
setLayout(new GridLayout(n, n));
setFont(new Font(“Courier”, Font.BOLD, 16));
for(int i = 0; i < n; i ++) {
for(int j = 0; j < n; j++) {
int k = i*n + j;
add(new Button(“ “ + k));
}}}}