Getting Started With
|
Applications and Applets are the most common Java programs. like Hot Java browser, Applications are stand-alone programs. Applets are similar to applications, but they adhere to some sets of conventions which allow them run within a browser which is Java-compatible.
|
"Hello World" Application Program
|
By following the steps given in the page below. you can do create and also use a standalone Java application.
|
|
Compile the given source file
|
Using Java compiler compile the source file. If the compilation succeeds, then the compiler creates a file called AppHelloWorld.class. If compilation fails, make sure what you have typed in and what name you have given.
|
Run the application program
|
Using the Java interpreter run the program. You will see "Hello World!" displayed on your standard output screen.
|
"Hello World" Applet
|
By following the steps given here, you can create and use applet. When you have followed all the steps, your directory/folder structure should look something like a tree as shown here:
|
Create a directory
|
Create a directory that can hold your HTML pages. and do this only if you have not created any.
note: If you want to reload the applet do NOT invoke the hotjava (or any other applet viewer) from the HTML directory. Because of the way the class loader do work, an applet cannot be reloaded (for example, after making changes to its code) when you invoke applet viewer from the directory which is having the applet's compiled code.
|
Create the Java source file
|
Create a file named HelloWorld.java in the HTML directory with the Java code shown here:
|
import java.awt.Graphics;
public class HelloWorld extends java.applet.Applet
{
public void init()
{
resize(150,25);
}
public void paint(Graphics g)
{
g.drawString("Hello world!", 50, 25);
}
} |
|
Compile your source file
|
Compile your source file using Java compiler. If the compilation succeeds, then compiler creates a file called HelloWorld.class. If compilation do fails, make sure you typed in and have named the code exactly as shown above.
|
Then Create an HTML file that includes applet
|
Create an HTMl file Hello.html containing the following text in your HTML directory:
|
<HTML>
<HEAD>
<TITLE> A Simple Program </TITLE>
</HEAD>
<BODY>
Here is the output of our program:
<br> <APPLET CODE="HelloWorld.class" WIDTH=150 HEIGHT=25>
</APPLET>
</BODY>
</HTML> |
|
Loading an HTML file
|
Load the new HTML file into HotJava by entering the file's URL in the Document URL field near to the top of the HotJava window, as shown below:
|
| file:/home/academic-tutor/HTML/Hello.html |
|
Once the you successfully completed these steps, you should get the following in the HotJava page that comes up:
|
Here is the output of our program:
Hello World!
|
|
|
This chapter explains the basic concepts behind object-oriented programming.
What is Object?
|
The real-world objects(any living or non- living thing) share two characteristics: they do have state and behavior. For example, dogs have a state ( like name, color, etc) and behavior ( like barking, fetching etc). Also consider for example a Bicycles have a state such as current gear, current wheels, number of gears etc and and behavior such as braking, accelerating etc.
After the real-world objects Software objects have been modeled in that, they too,have states and behaviours. A software object maintains states in the variables and implements behaviour by methods.
|
What is Encapsulation?
|
Packing up an object's variables within its methods is called encapsulation. Encapsulating the related variables and methods into neat software bundle seems simple but is a powerful idea that provides two benefits to the software developer:
|
- Modular programming-- The source code for any of the object can be written and maintained independently from those of the source code written for other objects. Also, an object can be easily used passing around in the system. For example you can give your bicycle to someone else and it will still work for them too.
- Information hiding-- An object has a public interface by which other objects can communicate with it. But on the other hand objects can maintain private information and methods that cannot be communicated to others.
|
What are Messages for?
|
Using "messages" software objects do interact and communicate with each other. When an object say A wants another object say B to perform one of its methods, then object A can send message to object B.
|
There are three components comprising a message:
|
Following three components are enough for the receiving object to perform the desired method. No other information or context is required. Thus, objects in different processes or even on different machines can communicate to each other through the use of messages.
|
- the object to whom the message is addressed (bicycle)
- the name of the method to perform (change gears)
- any parameters needed by the method.
|
The Benefit of Messages
|
- Since everything that an object can do is expressed through its methods, message passing supports all possible interactions between objects.
- To send and receive messages back and forth objects don't need to be in the same process or even on the same machine.
|
What are Classes?
|
In object-oriented software, it's also possible to have many objects of the same kind that share characteristics: rectangles, employee records, video clips and so on. Like the bicycle manufacturers, you can take advantage of the fact that objects of the same kind share certain characteristics and you can create a blueprint for those objects. Software blueprints for objects are called classes.
|
The Benefit of Classes
|
Objects provide the benefit of modularity and information hiding. Classes provide the benefit of reusability. Bicycle manufacturers reuse the same blueprint over and over again to build lots of bicycles. Software programmers use the same class over and over to again create many objects.
|
What is Inheritance?
|
Generally speaking, objects are defined in terms of classes. You know a lot about an object by knowing its class. Even if you don't know what a penny-farthing is, if I told you it was a bicycle, you would know that it had two wheels, handle bars and pedals.
|
Object-oriented systems take this a step further and allow classes to be defined in terms of other classes. For example, mountain bikes, race bikes and tandems are all different kinds of bicycles. In object-oriented terminology, mountain bikes, race bikes and tandems are all subclasses of the bicycle class. Similarly, the bicycle class is the superclass of mountain bikes, race bikes and tandems.
|
The Benefit of Inheritance
|
- Subclasses provide specialized behaviours from the basis of common elements provided by the superclass. Through the use of inheritance, programmers can reuse the code in the superclass many times.
- Programmers can implement superclasses that define "generic" behaviours (called abstract classes). The essence of the superclass is defined and may be partially implemented but much of the class is left undefined and unimplemented. Other programmers fill in the details with specialized subclasses.
|
|
Anatomy of a Java Application
|
Java programs which do run within a browser which is Java-compatible are known as applets. Here we have discussed about the components of a stand-alone Java program, that is, a program written in the Java language which can run independently of any browser.
Stand-alone programs in Java are also known as Java applications. The following application "DateApp" displays the current time and date.
|
import java.util.Date;
class DateApp
{
public static void main (String args[])
{
Date today = new Date();
System.out.println(today);
}
} |
|
Import statement
|
As we can see the first line in the program imports the Date class from the package called "java.util". By importing we can make that class available to the file into which it has been imported. A "java.util" package is a collection of classes that do provide miscellaneous functionality. The "Date" class from the java.util package allows you to manage and also manipulate calendar dates in system independent way.
|
How to Define a Class
|
In Java language, the general form of class definition is as shown below
|
|
|
The keyword class begins the class definition for a given classname here it is "name". All variables and methods of the given class are held inside the curly brackets that begins and ends the definition block of a class. In the class "DateApp" has no variables and has only one method called main().
|
Method: main()
|
main() method is called the brain of the Java application.you need to specify the name of the class which you want to run while running a Java application using the Java interpreter. Interpreter will do invokes the main() method defined in the class. The main() method will control the program flow, allocates all the resources which are needed, and will run any of the methods that do provide the functionality to the application.
|
Using Objects in the Programs
|
The first line in the method "main()", will declare, initialize and instantiate an object called "today". The default constructor is used to initialize today, that initializes the object new Date to contain the current time and date. In the second line of the method "main()" uses dot operator to refer to the class's or object's methods or variables. The above code illustrates the uses of instance variables and methods and class methods and variables
|
How to Save, Compile and Run an Application
|
To create and edit Java program, you can make use of any editor or word processing program. Java programs should be saved with the .java extension, so using any ASCII editor, write the program exactly as it appears in this page and save the program with the file name DateApp.java.
|
After creating your Java program, you should compile the program using the Java compiler before running it When a Java source file is compiled, the compiler creates a .class extension file in the folder in which the source file is stored. The compiler will name the resulting .class file after the class is defined in the source file. For example, when you compile the "DateApp" class which you have created above, the compiler will name the resulting class file "DateApp.class" after the class, with regardless of the name of the source file. Even if you would save the DateApp class as Wow.java, the compiler would still create a file called "DateApp.class".
|
After compilation, using the Java interpreter you can run the application . The program must display the current time and date.
|
|
Syntax and Semantics of Java
Here you will learn specifics about the syntax and semantics of Java programming language, including control flow and variables,
data types and operators and expressions. Here you will also come to know about the strings, the main() method, basic class definitions,variables and static methods. and how make system calls.
Application for Character-Counting
|
The following program reads and counts characters that are input and then it displays the number of characters read in. This program program uses several Java language components and the class libraries which is shipped with the Java development environment.
|
class Count
{
public static void main(String args[])
throws java.io.IOException
{
int count = 0;
while (System.in.read() != -1)
count++;
System.out.println("Input has " + count + " chars.");
}
} |
|
The program given above shows the basic syntax of, how the class should be declared. How the method should be called and how to print the output on the sceen. The detailed study of these syntax and semantics will produced in the subsequent chapters.
|
|
Java Objects, Classes, and Interfaces
Life Cycle of the Object
|
an object is a module that has both state and behaviour. An object's state is contained within the member variables and the behaviour is implemented by its methods. The Java programs that you write will create many different objects by the template, these templates are known as classes. The objects created interact with each other by sending messages. As a result of messag, method is invocated which will perform some action or it may also modify the state of object which is receiving the message. By these interaction of the objects, your Java code can implement a graphical user interface, run animations, or can also send and receive information over network. Once the object completes the work it was created for, it is destroyed and all the resources assigned to it are recycled for use, by some other objects.
|
Creating the Classes
|
A class is a template which can be used to create many objects. The class implementation comprises of two components: class declaration and class body.
|
classDeclaration
{
. . .
classBody
. . .
} |
|
Class Declaration
|
The class declaration, declares the name of a class along with some other attributes like class's superclass, and whether the class is final, public, or abstract. The class declaration should contain the class keyword and the name of the class that you are defining. Therefore the minimum class declaration will look like this:
|
class NameOfClass
{
. . .
} |
|
Class Body
|
Class body follows the class declaration and is always embedded within curly braces { and } as shown in the example above. Class body contains declarations for variables which are members of the class, methods declarations and implemenatations of the class. We will now discuss two special methods that you can declare within a class body: The Constructors and finalize() Method.
|
Constructors
|
These are some of the rules on constructors:
- private constructors()- keyword used "private", no one can instantiate the class as object. But can still expose public static methods, and these methods can construct object and return it, but no one else can do this.
- package constructors() - None of them outside your package can construct an instance of your class. This is useful when you want to have classes in your package which can do new yourClass() and don't want to let anyone else to do this.
- protected constructors() - keyword used "protected" only the subclasses of your class can make use of this package.
- public constructors() - keyword used "public" the generic constructor will use these.
|
Declaring the Member Variables
|
An object do maintains its state by the variables defined within that class. These variables are known as the member variables. While declaring the member variables for the class, you can specify a host of different "attributes" about those variables: its name, its type, access permission assigned to it, and so on.
Member variable declaration looks like this:
|
[accessSpecifier] [static] [final] [transient] [volatile] type variableName
The items in the square brackets are optional. The words inside the bracket are to be replaced by names. or keywords. |
|
Words specified inside the bracket defines the following aspects of variables:
- accessSpecifier defines that which all other classes do have access to tahat variable
- static indicates the variable declared is class member variable as opposed to instance member variables.
- final indicates the variable is constant.
- transient variables are not part of object's persistent state.
- volatile means the variable is modified asynchronously.
|
Writing a Method
|
In Java we define methods within the body of a class for which it implements the behaviour. We usually declare methods after its variables in the class body although not required. Similar to the class implementation, a method implementation also consists of two parts: method declaration and method body.
|
methodDeclaration
{
. . .
methodBody
. . .
} |
|
Method Declaration
|
At the minimum, the method declaration component has a return type which indicates the data type of value returned by the method, and name of the method.
|
returnType methodName()
{
. . .
} |
|
Cosider for example, the following code declares a simple method named isEmpty() within the Stack class that returns boolean value (either true or false).
|
class Stack
{
. . .
boolean isEmpty()
{
. . .
}
} |
|
The method declaration shown in the example above is very basic. Methods do have many other attributes like access control, arguments and so on. This section will cover these topics.
|
The Method Body
|
In the method body all the action of a method takes place, the method body do contains all legal Java instructions that implements the method. For example, here is a Stack class with the implementation for isEmpty() method.
|
class Stack
{
static final int STACK_EMPTY = -1;
Object stackelements[];
int topelement = STACK_EMPTY;
. . .
boolean isEmpty()
{
if (topelement == STACK_EMPTY)
return true;
else
return false;
}
} |
|
Within method body, you can do use "this" to refer the current object.
|
What is Subclasses, Superclasses, and Inheritance?
|
As other object-oriented programming languages in Java, one class can be derived from other class. For example, suppose you hav a class named MouseEvent that represents the event when user presses the mouse button in the GUI window environment. Later, while developing application, you realize that you need a class to represent event when user press a key on the keyboard. You can write the KeyboardEvent class from scratch, but since MouseEvent and the KeyboardEvent classes share some states and behaviours like which mouse button or key was pressed,the time that the event occurred, and so on, we can go for duplicating the MouseEvent class rather than re-inventing the wheel, You can take advantages of subclassing and inheritance..and so you create a class Event from which both MouseEvent and KeyboardEvent can be derive
|
Event is now a superclass of both MouseEvent and KeyboardEvent classes. MouseEvent and KeyboardEvent are now called subclasses of class Event. Event do contains all the states and behaviour which are common to both mouse events and keyboard events. Subclasses, MouseEvent and KeyboardEvent, inherit the state and behaviour from the superclass. Consider for example, MouseEvent and KeyboardEvent both inherits the time stamp attribute from super class Event.
|
How to Create a Subclass
|
You do declare that a class is subclass of another class in the Class Declaration. Suppose that you wanted to create a subclass called "ImaginaryNumber" of the "Number class". (where the Number class is a part of java.lang package and is base class for Floats, Integers and other numbers.).You can now write:
|
class ImaginaryNumber extends Number
{
. . .
} |
|
This line declares ImaginaryNumber as a subclass of Number class
|
Write a Final Class
|
Java allows us to declare our class as final; that is, the class declared as final cannot be subclassed. There are two reasons why one wants to do this: security and design purpose.
|
- Security: To subvert systems, One of the mechanism hackers do use is, create subclasses of a class and substitute their class for the original. The subclass looks same as the original class but it will perform vastly different things, causing damage or getting into private information possibly. To prevent this subversion, you should declare your class as final and prevent any of the subclasses from being created.
- Design: Another reason us to declare a class as final is object-oriented design reason. When we feel that our class is "perfect" and should not have subclasses further. We can declare our class as final.
|
To specify that the class is a final class, we should use the keyword "final" before the class keyword in the class declaration.If we want to declare the ImaginaryNumber class as final calss, its declaration should look like this:
|
final class ImaginaryNumber extends Number implements Arithmetic
{
. . .
} |
|
If subsequent attempts are made to subclass ImaginaryNumber, it will result in a compiler error as the following:
|
Imagine.java:6: Can't subclass final classes: class ImaginaryNumber
class MyImaginaryNumber extends ImaginaryNumber {
^
1 error |
|
Create a Final Method
|
If creating final class seems heavy for your needs, and you just want to protect some of the classes methods being overriden, you can use final keyword in the method declaration to indicate the compiler that the method cannot be overridden by subclasses.
|
Writing Abstract Classes
|
Sometimes you may want only to model abstract concepts but don't want to create an instance of the class. As discussed earlier the Number class in java.lang package represents only the abstract concept of numbers. We can model numbers in a program, but it will not make any sense to create a generic number object. Instead, the Number class behaves as a superclass to Integer and Float classes which do implements specific case of numbers. Classes like Number, that implements only the abstract concepts and thus should not be instantiated, are called abstract classes.
An abstract class is a class which can only be subclassed and cannot be instantiated.
|
To declare the class as an abstract class we use the keyword "abstract" before the keyword class in the class declaration:
|
abstract class Number
{
. . .
} |
|
If any attempt is made to instantiate an abstract class, compiler will displays error as shown below and refuses to compile the program:
|
AbstractTest.java:6: class AbstractTest is an abstract class.
It can't be instantiated.
new AbstractTest();
^
1 error |
|
Writing the Abstract Methods
|
An abstract class can contain abstract methods, abstract methods are the methods, with no implementation. Therefore an abstract class can define all its programming interface and thus provide its subclasses the method declarations for all the methods that are necessary to implement the programming interface. However, an abstract class can leave implementation details of the methods to the subclasses.
|
You would declare an abstract class, GraphicObject, which provides the member variables and methods which are shared by all of the subclasses. GraphicObject can also declare abstract methods for the methods, such as draw(), that needs to be implemented by the subclasses, but in entirely different ways. The GraphicObject class would look like this:
|
abstract class GraphicObject
{
int x, y;
. . .
void moveTo(int newX, int newY)
{
. . .
}
abstract void draw();
} |
|
An abstract class is not have an abstract method in it. But any of the class that do have an abstract method in it or in any of the superclasses should be declared as an abstract class. Each non-abstract subclass of GraphicObject, such as Circle and Rectangle, shoul provide an implementation for the draw() method.
|
class Circle extends GraphicObject
{
void draw()
{
. . .
}
}
class Rectangle extends GraphicObject
{
void draw()
{
. . .
}
} |
|
How to Create and Use Interfaces
|
Interfaces provides a mechanism to allow hierarchically unrelated classes do implement same set of methods. An interface is the collection of method definitions and the constant values which is free from dependency on a specific class or a class hierarchy. Interfaces are useful for the following purpose:
|
- declaring methods which one or more than one classes are expected to implement
- revealing the object's programming interface without revealing its class (objects like these called anonymous objects and are useful while shipping a package of classes to the other developers)
- capturing the similarities between unrelated classes without forcing the class relationship
|
Create an Interface
|
Creating an interface is similar to that of creating a new class. An interface definition consists of two components: interface declaration and interface body.
|
interfaceDeclaration
{
interfaceBody
} |
|
The interfaceDeclaration declares various attributes about the interface such as its name and whether it extends another interface. The interfaceBody contains the constant and method declarations within the interface.
|
Use an Interface
|
An interface is used when the class claims to implement that interface. A class do declares all the interfaces that are implemented in the class declaration. To declare that the class implements one or more interfaces, make use of the keyword "implements" followed by comma-delimited list of the interfaces implemented by the class.
|
Suppose that we are writing a class that implements a FIFO queue. Since the FIFO queue class is a collection of objects (an object which contains other objects) it doesnot make any sense to implement the Countable interface. The FIFOQueue class would declare that it do implements the Countable interface as shown below:
|
class FIFOQueue implements Countable
{
. . .
} |
|
And thereby guaranteeing that it provides implemenations for currentCount(), incrementCount(),setCount(), and decrementCount() methods.
|
|
The String and String Buffer Classes in Java
The two String Classes
|
Java programming environment provides two classes which stores and manipulates character data suich as String, for immutable strings (which should not be modified), and StringBuffer for mutable strings (which needs to be modified).
|
class ReverseString
{
public static String reverseIt(String source)
{
int i, len = source.length();
StringBuffer dest = new StringBuffer(len);
for (i = (len - 1); i >= 0; i--)
{
dest.append(source.charAt(i));
}
return dest.toString();
}
} |
|
The String class is provided for the constant strings; you can use Strings when you don't want its value to be changed. Let us consider for example, if you pass the string data into the method, and you don't want to modify the string by the method in any way, you can use "String". Typically, Strings are used to pass character data to methods and return character data from the methods. method reverseIt() takes an String argument and returns back a String value.
|
A StringBuffer class is used for non-constant string. When we know that value of the character data will do change we use StringBuffers. Typically StringBuffers are used for constructing the character data like that of reverseIt() method.
|
Creating Strings and StringBuffers classes
|
The reverseIt method in the above example creates a StringBuffer called "dest" whose initial length is equal to that of source. StringBuffer dest declares to the compiler that dest will be used to refer to an object whose type is of String, the new operator will allocate memory for the new object, and StringBuffer() will initialize the object. When we create any object in a Java program, we always do use the same three steps: declaration, instantiation, initialization.
|
The Accessor Methods
|
Methods which are used to obtain information about the object are known as accessor methods. The method reverseIt() uses two String's accessor methods to get the information about a source string.
|
First, reverseIt() uses String's length()
accessor method to obtain the length of the String source.
int len = source.length();
Second, reverseIt() uses the charAt()
accessor which returns the character at the position specified in the parameter.
source.charAt(i) |
|
Modifying a StringBuffer
|
To add characters to dest reverseIt() method uses StringBuffer's append() method. In addition to append() method, StringBuffer also provides methods to insert characters into buffer or modify the character at a specific location within buffer, among others.
|
| dest.append(source.charAt(i)); |
|
append() is the only StringBuffer's methods which allows you to append data to end of the StringBuffer. There are different append() methods which appends data of various types, like boolean, float, int, and even Object, to the end of the StringBuffer. The data is first converted into string before the append could takes place.
|
Converting the Objects to Strings
|
toString() Method
Sometimes it becomes necessary to convert an object into String because you may need to pass it to a method that accepts only String values. consider for example, System.out.println() will not accept StringBuffer, so there is need to convert a StringBuffer to String before you could print it. The reverseIt() method in the above example uses StringBuffer's toString() method to converte StringBuffer into String object before returning the String.
|
|
|
many of the classes in java.lang supports toString() including all the "type wrapper" classes such as Integer, Boolean,Character and others. Even the base Object class has toString() method which converts an Object to String. When we write a subclass of an Object, we can override the method toString() to perform the more specific conversion for the subclass.
|
valueOf() Method
for convenience, the String class do provides the static method "valueOf()" which we can use to convert variables of different types to the String. For example, to print the value of the pi
|
| System.out.println(String.valueOf(Math.PI)); |
|
|
Setting Program Attributes
|
A program typically needs this information about the system and application environment to make decisions about how to do something, or what to do. Also, a program may wish to modify certain attributes itself, or allow a user to change them. Thus a program needs to be able to read and write various system attributes and program-specific attributes. Java programs can manage these attributes through three mechanisms: properties, application command line arguments, and applet parameters.
|
- Properties
Use properties to define environmental attributes on a persistent basis. That is, use properties when they need to be in effect for each invocation of a program.
- Application Command Line Arguments
Use command line arguments to define or modify environmental attributes on a non-persistent basis. That is, use command line arguments to change one or more attributes for just one invocation of a program.
- Applet Parameters
Use applet parameters to define or modify environmental attributes on a non-persistent basis for applets. That is, use parameters to set one or more attributes for a single invocation of an applet.
|
Converting Objects to Strings
|
You can use the Properties class from java.util to manage attributes specific to your Java programs. A Properties object manages a set of key/value pairs: the key represents the name of a property and the value is the current value of the property. You can load key/value pairs into a Properties object from a stream, save the properties to a stream, and get information about the properties represented by the Properties object.
|
Setting up Your Properties Object
|
Often when a program starts up, it will use code similar to the following to set up the properties object:
|
// set up default properties
Properties defaultProps = new Properties();
FileInputStream defaultStream = new FileInputStream("defaultProperties");
defaultProps.load(defaultStream);
defaultsStream.close();
// set up real properties
Properties applicationProps = new Properties(defaultProps);
FileInputStream appStream = new FileInputStream("appProperties");
applicationProps.load(appStream);
appStream.close(); |
|
First the application sets up a default Properties object. This object contains the set of properties to use if values are not explicitly set elsewhere. This code snippet uses the load() method to read the default values from a file on disk named defaultProperties. Applications usually save and restore properties to files on the disk.
|
Next, the program uses a different constructor to create a second Properties object, applicationProps. This object uses defaultProps to provide its default values. Then the code snippet loads a set of properties into applicationProps from a file named appProperties. The properties loaded into appProperties can be set on a per user basis, a per site basis, or whatever is appropriate for the current application.
|
Getting Property Information
|
Once you've set up your Properties object, you can query it for information about various properties it contains. The Properties class provides several methods for getting property information
|
| getProperty() (2 versions) |
|
returns the value for the specified property. One version allows you to provide a default value--if the key is not found the default is returned.
|
|
|
writes all the properties to the specified stream. This is useful for debugging.
|
|
|
returns an Enumeration containing all of the keys contained in the Properties object.
|
Command Line Arguments
|
Your Java application can accept any number of arguments from the command line. Command line arguments allow the user to affect the operation of an application. For example, a program might allow the user to specify verbose mode--that is, specify that the application display a lot of trace information--with the command line argument -verbose.
|
When invoking an application, the user types the command line arguments after the application name. For example, suppose you had a Java application, called Sort, that sorted lines in a file, and that the data you want sorted is in a file named ListOfFriends. If you were using DOS, you would invoke the Sort application on your data file like this:
|
| C:\> java Sort ListOfFriends |
|
Echo Command Line Arguments
This simple application displays each of its command line arguments on a line by itself:
|
class Echo
{
public static void main (String args[])
{
for (int i = 0; i < args.length; i++)
System.out.println(args[i]);
}
} |
|
Try this: Invoke the Echo application with the command line shown in this DOS example:
|
| C:\> java Echo Drink Hot Java Drink Hot Java |
|
You'll notice that the application displays each word--Drink, Hot, and Java--on a line by itself. This is because The Space Character Separates Command Line Arguments.
|
. |
Using the System Resources
|
Often, a program requires the access to system resources like properties, the current time, standard input and output streams or Your program can use these resources directly from current runtime environment but your program would only be able to run in the environment for which it was written for. Each time you want the program to run in a new environment, you should have to "port" the program by rewriting the system-dependent sections of the code.
|
| The Java development environment solves this problem by allowing your program to use system resources by a system-independent programming interface implemented by the System class (it is a member of the java.lang package). |
|
Other system resources that are available through the System class include:
|
- The standard input, output and error streams
- The system properties
- The garbage collection
- loading the dynamic libraries
- finally the miscellany, including getting the current time, copying arrays, using the security manager and exiting the runtime environment
|
|
Threads of Control in Java
A thread is nothing but a single sequential flow of control within the program.
What is Thread?
|
Programmers are familiar with writing sequential programs. The program that displays "Hello World!", or program which sorts a list of names, or computes the list of prime numbers, are sequential all programs: each has beginning, end, sequence, and at any given time during runtime of program there is single point of execution.
|
A thread is similar to a sequential program, a single thread do also has beginning, end, sequence, and at any given time during runtime of thread there will be a single point of execution. But the thread itself is not a program it cannot run by itself but runs within the program.
|
Simple Thread example
|
The following example is a simple Java application that will create and start two independent threads.
|
class TwoThreadsTest
{
public static void main (String args[])
{
new SimpleThread("Japan").start();
new SimpleThread("India").start();
}
}
class SimpleThread extends Thread
{
public SimpleThread(String str)
{
super(str);
}
public void run()
{
for (int i = 0; i < 10; i++)
{
System.out.println(i + " " + getName());
try
{
sleep((int)(Math.random() * 1000));
} catch (InterruptedException e)
{}
}
System.out.println("DONE! " + getName());
}
} |
|
The first method in SimpleThread class is a constructor which takes only String as its argument. This constructor is implemented by calling the superclass constructor and is interesting because it sets Thread's name which is been used later in the program.
|
The next method in this class is run() method. run() method is the heart of any Thread, this is where the action of the Thread takes place. The run() method in the SimpleThread class contains a for loop which iterates ten times. In each of the iteration it displays the iteration number and name of the Thread and then sleeps for random interval of time between 0 and 1 second. After finishing the loop, the run() method prints "DONE!" along with the name of thread.
|
Attributes of a Thread
|
All the action takes place in the thread's body, in the thread's run() method. We can provide the body to Thread in one of the two ways: first by subclassing a Thread class and overriding the run() method of thread, secondly by creating a Thread with Runnable object as its target.
|
Body of a Thread
|
Java threads are implemented by using Thread class which is the part of java.lang package. A Thread class implements the system independent definition of Java threads. But, actual implementation of the concurrent operation is provided by the system-specific implementation. For most of the programming needs, underlying implementation doesn't matter; we can ignore the underlying implementation and program the thread API and other documentation provided with the Java system.
|
States of a Thread
|
Throughout the life, Java thread will be in one among several states. The state of a thread indicates what the Thread is doing currently and what it can do at that time of its life: whether it is running? is sleeping? or is dead? These states are illustrated below.
|
New Thread
The statement below creates a new thread but it will not start it thereby leaving the thread in a state labeled "New Thread".
|
| Thread myThread = new MyThreadClass(); |
|
When the thread is in "New Thread" state, merely it is an empty Thread object. No system resources are allocated for it yet. Thus when the thread is in this state, we can only start or stop the thread; when a thread is in this state calling any of the other method besides start() or stop() will not make any sense and causes an IllegalThreadStateException.
|
Runnable
The start() method creates all the necessary system resources to run a thread, It schedules the thread to run, and calls thread's run() method.
|
Thread myThread = new MyThreadClass();
myThread.start(); |
|
At this point the thread is in "Runnable" state. This state is called "Runnable" state rather than "Running" state because the thread may not be running actually when it is in this state. Many computers do have a single processor making it impossible to run all the "Runnable" threads at the same time. Therefore the Java runtime system should implement the scheduling scheme which shares the processor between all the "Runnable" threads. For most of the purposes however, we can think of "Runnable" state as simply "Running". When a thread is running, it is "Runnable" and is the current thread. The instructions in the run() method are executing sequentially.
|
Not Runnable
A thread enters into "Not Runnable" state when one of following events occur:
- When a suspend() method is called
- When a sleep() method is called
- When the thread uses its wait() method to wait for a condition variable
- When the thread is blocking on I/O.
|
Thread myThread = new MyThreadClass();
myThread.start();
try
{
myThread.sleep(10000);
} catch (InterruptedException e)
{
} |
|
The bold line in the above example puts myThread to sleep for 10 seconds. During these 10 seconds, even if the processor becomes available myThread will not run. After 10 seconds are over, myThread becomes "Runnable" again and if the processor is available it would run.
|
Following statements indicates the escape route for every entrance into "Not Runnable" state.
- If the thread is put to sleep, then the specified time should elapse.
- If the thread is suspended, then someone must call the resume() method.
- If the thread is waiting on condition variable, whatever object owns the variable should relinquish this by calling either notify() or notifyAll() method.
- If the thread is been blocked on I/O, then the specified I/O command should get complete.
|
Dead
A thread can die in two different ways: either by a natural cause, or being killed (stopped). A thread is said to die naturally when the run() method exits normally. Cosider for example, the while loop in the run method is a finite loop, it will iterate 100 times and then stops executing.
|
public void run()
{
int i = 0;
while (i < 100)
{
i++;
System.out.println("i = " + i);
}
} |
|
We can also kill a thread any time simply by calling the stop() method. This is as shown in the code below:
|
public void run()
{
Thread myThread = new MyThreadClass();
myThread.start();
try
{
Thread.currentThread().sleep(10000);
} catch (InterruptedException e)
{
}
myThread.stop();
} |
|
The run method here creates and starts myThread then it puts the current thread to sleep for some 10 seconds. When current thread wakes up, the bold line in the code segment will kill myThread.
|
The stop() method will throw a ThreadDeath object to kill the thread. When the thread is killed in this manner it dies asynchronously. Thread will die when it actually receives a ThreadDeath exception.
|
IllegalThreadStateException
runtime system throws an IllegalThreadStateException when we call a method on a thread and the thread's state will not allow for that method call. For example, IllegalThreadStateException is thrown when we call a suspend() method on a thread which is not "Runnable".
|
As per in the examples of threads studied so far in this chapter, when we call a thread method which can throw an exception, you should either catch and handle the exception, or should declare that, the calling method throws uncaught exception.
|
public void run()
{
Thread myThread = new MyThreadClass();
myThread.start();
try
{
Thread.currentThread().sleep(10000);
} catch (InterruptedException e)
{
}
myThread.stop();
} |
|
isAlive() Method
|
If the method isAlive() returns true then thread is started and not stopped. Thus, if isAlive() method returns false we know that the thread is either "New Thread" or "Dead" one . If isAlive() method returns true, you then the thread is either "Runnable" or "Not Runnable".
|
|
Thread Priority
|
When a Java thread is created, it inherits the priority from the thread that created it. We can also modify the thread's priority any time after its creation using the method setPriority(). Threads priorities range from MIN_PRIORITY to MAX_PRIORITY (these are the constants defined in class Thread). At any given instant of time, when multiple threads are ready to execute, the runtime system chooses "Runnable" thread having the highest priority for execution. Only when this thread stops, yields, or becomes "Not Runnable" for some sort of reason, the lower priority thread start executing. If there are two threads having same priority waiting for CPU, the scheduler will choose them in a round-robin fashion.
|
Daemon Threads
|
Any Java thread can be daemon thread. Daemon threads are service providers for those threads or objects running in same process as the daemon thread is running. For example, HotJava browser has a daemon thread, called Background Image Reader, which reads images from the file system or network for any of the object or thread which needs an image.
|
|
Errors and Exceptions in Java
The Java language make use exceptions to provide the error handling capabilities for all its programs.
What is an Exception?
|
Definition: An exception is an event which occurs during execution of the program which disrupts the normal flow of the instructions. Different types of errors can cause exceptions: problems which range from serious hardware errors, such as hard disk crash, to the simple programming errors, like trying to access the out-of-bounds array element. When such error occurs within a Java method, the method will create an exception object and hands it to the runtime system. The exception object do contains the information about exception including its type and state of the program when error occurred. Runtime system is then responsible to find some code to handle error. In the Java terminology, creating exception object and handing it to runtime system is called "throwing an exception".
|
Hotjava's Catch or Declare Requirement
|
import java.io.*;
import java.util.Vector;
class ListOfNumbers
{
private Vector victor;
final int size = 10;
public ListOfNumbers ()
{
int i;
victor = new Vector(size);
for (i = 0; i < size; i++)
victor.addElement(new Integer(i));
}
public void writeList()
{
PrintStream pStr = null;
System.err.println("Entering try statement");
int i;
pStr = new PrintStream(
new BufferedOutputStream(
new FileOutputStream("OutFile.txt")));
for (i = 0; i < size; i++)
pStr.println("Value at: " + i + " = " + victor.elementAt(i));
pStr.close();
}
} |
|
The example above defines and implements the class called "ListOfNumbers". Upon construction, the ListOfNumbers class creates a Vector which contains ten Integer elements with sequential values 0 through 9. ListOfNumbers class also defines the method "writeList()" that writes the list of numbers into the text file "OutFile.txt". The writeList() method calls up two more methods that can throw exceptions.
|
First,
pStr = new PrintStream(new BufferedOutputStream(new FileOutputStream("OutFile.txt"))); |
|
This line invokes the constructor for FileOutputStream which throws an IOException when the file cannot be opened for any of the reason.
|
Second, the Vector class's elementAt() method
pStr.println("Value at: " + i + " = " + victor.elementAt(i)); |
|
This method will throw ArrayIndexOutOfBoundsException if you pass an index whose value is very small (negative number) or very large (larger than number of elements contained by the Vector currently).
|
If you try to compile ListOfNumbers class, the compiler prints the error message about an exception thrown by FileOutputStream constructor, but it will not display the error message about an exception thrown by elementAt(). This is because the exception thrown by the FileOutputStream constructor, IOException, is non-runtime exception and the exception thrown by elementAt() method, ArrayIndexOutOfBoundsException, is the runtime exception. Java requires only to catch or declare non-runtime exceptions.
|
Catch and Handle an Exception
|
The first step for constructing an exception handler is to enclose statements that might throw exception within the try block. In general, try block looks something like this:
|
|
|
The segment "Java statements" in the code above consists one or more legal Java statements which could potentially throw an exception. To construct the exception handler for writeList() method from ListOfNumbers class, we need to enclose the exception-throwing statements of writeList() method within the try block. There are more than one ways to accomplish this task: we can put each statement which may potentially throw the exception within its own try statement, and provide the separate exception handlers for each of the try. Or you can put all the writeList() statements within the single try statement and associate multiple handlers to it. The following example uses single try statement for the entire method as the code tends to be easier to read.
|
PrintStream pstr;
try
{
int i;
System.err.println("Entering try statement");
pStr = new PrintStream(
new BufferedOutputStream(
new FileOutputStream("OutFile.txt")));
for (i = 0; i < size; i++)
pStr.println("Value at: " + i + " = " + victor.elementAt(i));
} |
|
The try statement governs the statements enclosed within it and it defines the scope of any exceptions handlers (which are established by subsequent catch blocks) associated with it. In other words, if an exception does occurs within the try statement, then that exception is handled by some appropriate exception handler which is associated with this try statement.
|
The catch Block(s)
|
As studied before, the try statement defines the scope of the associated exception handlers. We do associate exception handlers with a try statement by providing one or more of the sequential catch blocks directly after a try block.
|
try
{
. . .
} catch ( . . . )
{
. . .
} catch ( . . . )
{
. . .
} . . . |
|
There can be no intervening code between the end of try statement and the beginning of first catch statement. The general form of catch statement is:
|
catch (SomeThrowableClassName variableName)
{
Java statements
} |
|
Catch statement governs series of legal Java statements. These statements are executed when the exception handler is invoked. The runtime system invokes exception handler when a exception whose type matches with that of catch statement's argument is thrown within handler's try block.
|
The writeList() method from ListOfNumbers class uses two exception handlers for the try statement, one handler for each of the two types of exceptions which can be thrown within a try block, ArrayIndexOutOfBoundsException and IOException.
|
try
{
. . .
} catch (ArrayIndexOutOfBoundsException e)
{
System.err.println("Caught ArrayIndexOutOfBoundsException: " + e.getMessage()); } catch (IOException e)
{
System.err.println("Caught IOException: " + e.getMessage());
} |
|
|
Java Input and Output Streams
Overview of the java.io's Input and Output Streams
|
InputStream class is an abstract base class which do provides the minimal programming interface and partial implementation of the input streams in Java. The InputStream defines the methods to read bytes or the arrays of bytes, marking the locations in stream, skipping the bytes of input, finding out the number of bytes which are available for reading, and resetting current position within the stream. The input stream is automatically opened when we create it. we can explicitly close the stream with the method close(), or let it be closed implicitly when a object is garbage collected.
|
OutputStream class is the abstract base class which provides minimal programming interface and the partial implementation of the output stream in Java. the OutputStream defines methods for writing the bytes or arrays of bytes to stream and flushing the stream. The output stream is automatically opened when we create it. We can explicitly close the output stream using close() method, or let it be closed implicitly when an object is garbage collected.
|
A Simple Input and Output Streams
|
Following is an overview of input and output streams, classes which inherits directly from the InputStream and the OutputStream which are not abstract classes.
|
FileInputStream and FileOutputStream
Used to read the data from or write the data to the file on a native file system.
PipedInputStream and PipedOutputStream
Implements input and output components of a pipe. Pipes are used to channel the output from one program into an input of another. The PipedInputStream must be connected to the PipedOutputStream and vice versa.
ByteArrayInputStream and ByteArrayOutputStream
Reads the data from or writes the data to byte array in memory.
SequenceInputStream
Concatenates the multiple input streams into one input stream.
StringBufferInputStream
Allows the programs to read from StringBuffer as if it is an input stream. |
|
The Filtered Streams
|
The FilterInputStream and FilterOutputStream are subclasses of the InputStream and OutputStream respectively, and both are abstract classes. These classes will define interface for the filtered streams. Filtered streams processes the data as it is being read or written. Consider for example, BufferedInputStream and BufferedOutputStream classes buffer data while reading and writing to speed it up.
|
DataInputStream and DataOutputStream
Reads or writes the primitive Java data types in machine independent format.
BufferedInputStream and BufferedOutputStream
This is an efficient stream which buffers data while reading or writing.
LineNumberInputStream
The input stream which keeps the track of line numbers while reading.
PushbackInputStream
The Input stream with one-byte pushback buffer.
PrintStream
An output stream with a convenient printing methods. |
|
|
Overview of Java Applet
Most common Java programs are the applications and applets.
The Life Cycle of the Applet
|
Loading an Applet
When an applet is been loaded, this is what happens:
- An instance of applet's controlling class is created.
- The applet gets initialized itself.
- The applet starts to run.
|
Leaving and Returning to Applet's Page
When user leaves the page -- say for example, to go to different page -- the applet has an option to stop by itself. When the user returns to the page, applet can do start by itself again. The same thing takes place when the user iconifies a browser window which contains the applet.
|
Reloading the Applet
Some browsers let the users to reload the applets, which consists of unloading applet and then loading it again. Before an applet is been unloaded, it is given the chance to stop itself and then perform the final cleanup, so that the applet can do release any of the resources it holds. After that the applet is unloaded and loaded as described in Loading the Applet, above.
|
Role of Threads in Applets
|
Every applet can do run in multiple threads. example: when a HotJava browser first views the document that contains an applet, browser's DocumentSwitcher thread executes an applet's init() method. And when user scrolls the document, AWT WServer thread executes an applet's update() method.
|
So why would a applet need to create and use its own threads? Imagine an applet that performs the time-consuming initialization -- like loading images -- in its init() method. The thread which invokes the init() method cannot do anything else until the init() returns. In the HotJava browser, this means that browser cannot display applet or anything after it until the applet has finished the initializing itself. Therefoer if an applet is at the top of the page, then nothing would appear on the page until the applet has finished initializing itself.
|
The solution to this is to create a thread and move the initialization code from the init() method into thread body.
|
What the Applets Can and Can't Do
|
The Security Restrictions
For the security reasons, an applet which is loaded over network has the following restrictions:
- It cannot load the libraries or define native methods.
- It cannot ordinarily read or write the files on host that is executing it.
- It cannot make network connections except the host which it came from
- It cannot start any program on the host which is executing it.
- It cannot read every system property.
- Windows which an applet brings up look different than windows which an aplication brings up.
|
Each browser do have a SecurityManager object which checks for the applet security violations. When a SecurityManager detects violation, it throws up an SecurityException.
|
The Applet Capabilities
Here are some of the other things that an applet can do which you might not expect:
- Applets running within the Web browser can easily cause an HTML documents to be displayed.
- Applets can do invoke the public methods of other applets on same page.
- Applets that are loaded from local file system (from a directory in user's CLASSPATH) have none of the restrictions that applets loaded over the network do have.
- Although most of the applets stop running once you leave their page.
|
The java.applet package provides the API that gives an applets some capabilities which applications dont have. as an applets can play sounds, which other programs cannot do.
|
|
Creating an Applet User Interface in Java
Almost all the applets have graphical user interface .
Applet is a Panel.
|
Since an Applet is a subclass of AWT Panel class, applets can contain other Components, just as a Panel can contain. As Panels, Applets also do participate in AWT drawing and the event hierarchy.
|
Applets do appear in the pre-existing browser windows.
|
This is having two implications. First, unlike GUI-based applications, applets dont have to create the window to display themselves on. (They can do, if they have a good reason, but usually they just display themselves within the browser window ). Second, depending on browsers implementation, the applet's components may not be shown unless an applet calls the validate() after adding components to itself. Fortunately, calling validate() cannot hurt.
|
Each applet have a user-specified, pre-determined size.
|
Since the <APPLET> tag requires the applet's width and height to be specified, and because browsers not necessarily allow applets to resize themselves, applets should make with fixed amount of space that may not be ideal. Even if amount of space is ideal for one platform, the platform-specific parts of applet (such as buttons) may require a different amount of space on the other platform. You can do compensate by recommending the pages that includes your applet specify a little more space than be necessary, and by using the flexible layouts, like GridBagLayout and BorderLayout, which adapt well to extra space.
|
Applets do load images using Applet getImage() methods.
|
An Applet class do provide a convenient form of getImage() which lets you to specify a base URL as one argument, followed by second argument which specifies an image file location, relative to base URL. The Applet getCodeBase() and getDocumentBase() methods do provide the base URLs which the most applets use. Images that the applet always needs, or needs to rely on a backup, are usually specified relative to where an applet's code was loaded from. Images which are specified by an applet user (often with the parameters in HTML file) are usually relative to page which includes the applet (document base).
|
Applet classes and often the data files they use are loaded over the network,
|
Applets can perform several things to decrease the perceived startup time. Their Applet subclass can be small one which immediately displays the status message. And, if some of the applet classes or data are not used right away, the applet can preload classes or the data by referencing them before they are needed. Cosider for example, the AppletButton class, at the beginning of the main thread, gets the class object for the window the button brings up. Here its main purpose is to make sure that the class is valid, but an added benefit is getting the class object force the class file to be loaded before it is needed, which makes the class instantiating much quicker than if a class still had to be loaded.
|
|
Communicating with Other Programs in Java
Sending messages to other applets.
An applet can communicate with the other programs in three different ways:
- By invoking the public methods of other applets on the same page
A D V E R T I S E M E N T
- By using an API defined in the java.applet package, which allows it to communicate in limited way with a browser or applet viewer that contains it.
- By using the API defined in the java.net package to communicate over network with the other programs. Other programs must be running on a host which the applet originated from.
Sending Messages to Other Applets On Same Page
|
An applet can find other applet either by looking up by its name (using the AppletContext getApplet() method) or by finding all the applets present on the page (by using AppletContext getApplets() method). Both methods, if are successful, give the caller one or more applet objects. Once if the caller finds an Applet object, it can invoke methods on the object.
|
Finding up an Applet by Name: getApplet(receiverName)
|
This section gives the code that Sender uses to look up an applet by its name. Here is the Sender program
|
Applet receiver = null;
String receiverName = nameField.getText(); //get name to search for
receiver = getAppletContext().getApplet(receiverName); |
|
The Sender goes to make sure that Receiver was found and that it is an instance of correct class (Receiver). If everything goes well, then Sender sends a message to the Receiver. Here is the Receivers program.
|
if (receiver != null)
{
if (!(receiver instanceof Receiver))
{
status.appendText("Found applet named "
+ receiverName + ", "
+ "but it's not a Receiver object.\n");
} else {
status.appendText("Found applet named "
+ receiverName + ".\n"
+ " Sending message to it.\n");
((Receiver)receiver).processRequestFrom(myName);
}
} . . . |
|
Finding All the Applets on a Page: getApplets()
|
A getApplets() method returns the list (an Enumeration ) of all the applets on present in the page. For the security purpose, many browsers and the applet viewers implement the getApplets() method so that it will return only those applets which are originated from the same host as the applet calling getApplets(). Here is an applet that simply lists all the applets it finds on the page:
|
public void printApplets()
{
//Enumeration will contain all applets on this page (including
//this one) that we can send messages to.
Enumeration e = getAppletContext().getApplets();
. . .
while (e.hasMoreElements())
{
Applet applet = (Applet)e.nextElement();
String info = ((Applet)applet).getAppletInfo();
if (info != null)
{
textArea.appendText("- " + info + "\n");
} else
{
textArea.appendText("- " + applet.getClass().getName() + "\n");
}
}
. . .
} |
|
Communicating with a Browser
|
Many of the Applets and AppletContext methods involves some sort of the communication with a browser or applet viewer. Consider for example, Applet getDocumentBase() and getCodeBase() methods get the information browser or applet viewer where the applet and the HTML page came from. The method Applet showStatus() tells the browser or the viewer to display a status message. The Applets getParameterInfo() method can give a browser the list of parameters an applet understands. And, of course the browser or the applet viewer calls up Applet init, start, stop, and destroy methods to inform a applet of the changes in its state. Two other interesting methods are AppletContext showDocument() methods
|
public void showDocument(java.net.URL url)
public void showDocument(java.net.URL url, String targetWindow) |
|
...//In the Applet subclass...
urlWindow = new URLWindow(getAppletContext());
. . .
class URLWindow extends Frame
{
. . .
public URLWindow(AppletContext appletContext)
{
. . .
this.appletContext = appletContext;
. . .
}
public boolean action(Event event, Object o)
{
. . .
URL url = null;
try
{
url = new URL(urlString);
} catch (MalformedURLException e)
{
...//Inform the user, somehow, and return..
. }
if (url != null)
{
if (/* user doesn't want to specify the window */)
{
appletContext.showDocument(url);
} else {
appletContext.showDocument(url, /* user's choice */);
}
}
. . . |
|
Working with the Server-Side Application
|
Applets, like any other Java programs, can make use of the API defined in the java.net package to communicate across the network. Here the only difference is that, for security reasons, the only host with which an applet can communicate is the host from which it was delivered.
|
|
Overview of the Java UI
The applets and applications commonly present information to the user using the GUI.
The applets and applications commonly present information to the user (and invite the user's interaction) using the GUI. The Abstract Window Toolkit (AWT) contains the complete set of classes for writing the GUI programs.
A D V E R T I S E M E N T
The AWT Components
|
Every graphical User Interface component is implemented with the subclass of AWT Component class.
|
The Basic Controls are: Buttons, Lists, Menus, Checkboxes, Choices and Text Fields
|
Button, Checkbox, Choice, List, MenuItem, and TextField classes provide the basic controls. These are the most common ways which users give instructions to the Java programs. When the user activates one of these controls -- by clicking the button or by pressing the Return in the text field, for example -- it posts the event (ACTION_EVENT). An object which contains the control can react to the event by implementing the method action().
|
Other Ways ofor Getting User Input: Canvases and Text Areas
|
When the basic controls are not appropriate, we can use the Canvas and TextArea classes to get the user input. The TextArea class simply provides the area to display or allow editing of several lines of a text. Create a subclass of the Canvas class to draw custom graphics to the screen -- in a paint program, an image processor, or a game, for example.
|
Yet More Components: Scrollbars and the Labels
|
AWT provides two more handy components: the scrollbars and labels. Text areas automatically have the scrollbars, but we can use the Scrollbar class to make other kinds of areas scroll. Labels simply display uneditable, unselectable line of the text.
|
Containers: The Windows and Panels
|
AWT provides two types of containers, both of which are implemented as subclasses of the Container class (which is the Component subclass). Window subclasses -- Dialog, FileDialog, and Frame -- provide the windows to contain components. Panels group components within the area of an existing window.
|
|
Using GUI Building Blocks in Java
How to Use the Buttons
|
The Buttons class do provides a default button implementation. The onscreen appearance of the Buttons depends on a platform they are running on. If you want the program's buttons to look same for all platform or otherwise to have a special look, you should create a Canvas subclass to implement this look; the look can't be changed using the Button subclass. The only facets of Button's appearance that we can change without creating our own class are the fonts and text it displays and the foreground and background colors.
|
Below is an applet which displays three buttons. When you click the left button, it disables middle button and enables the right one. Similarly when you on click the right button, it will enable the left button and the middle button , and it disables itself. Below is the code which will create the buttons and reacts to the button clicks.
|
//In initialization code:
b1 = new Button();
b1.setLabel("Disable middle button");
b2 = new Button("Middle button");
b3 = new Button("Enable middle button");
b3.disable();
public boolean handleEvent(Event e)
{
Object target = e.target;
System.out.println("Event received: " + e);
if (e.id == Event.ACTION_EVENT)
{
if (target == b1)
{
b2.disable();
b1.disable();
b3.enable();
} else if (target == b3)
{
b2.enable();
b1.enable();
b3.disable();
}
}
return super.handleEvent(e);
} |
|
How to Use the Canvases
|
A Canvas class exist to be subclassed. It will not do anything on its own; it merely provides the way to implement the custom Components. For example, The Canvases are useful as a display area for images and the custom graphics, whether or not you wish to handle the events that occurs within a display area.
|
While implementing a Canvas subclass. do take care to implement the minimumSize() and the preferredSize() method to properly reflect the canvas's size. Otherwise, depending on the layout which the canvas's container uses, your canvas could end up too small -- perhaps even be invisible. Here is an example of the Canvas subclass that displays the image:
|
class ImageCanvas extends Canvas
{
ImageCanvas(Image img, Dimension prefSize)
{
image = img;
preferredSize = prefSize;
}
public Dimension minimumSize()
{
return preferredSize;
}
public Dimension preferredSize()
{
return preferredSize;
}
public void paint(Graphics g)
{
g.drawImage(image, 0, 0, this);
}
} |
|
How to Use the Checkboxes
|
The Checkbox class provides the checkboxes -- two-state buttons which can either be "on" or "off". If we want the group of checkboxes in which only one of the checkbox can be "on" at a time, you can add the CheckboxGroup object to oversee the checkboxes. Other good ways of providing a group of items the user can select are the choices, lists, and menus.
|
Given below is code for an applet that contains two columns of checkboxes. On the left are three independent checkboxes. You can select all the three checkboxes, if you like to. On the right are the three checkboxes which are coordinated by the CheckboxGroup object. The CheckboxGroup ensures no more than one of its checkboxes is selected at a time. Here is the program which performs this task. Below is the code that creates both the groups of checkboxes. Note: only the second, mutually-exclusive group of checkboxes is controlled by the CheckboxGroup.
|
Panel p1, p2;
Checkbox cb1, cb2, cb3; //independent checkboxes
Checkbox cb4, cb5, cb6; //only one of these three can be selected
CheckboxGroup cbg;
cb1 = new Checkbox();
cb1.setLabel("Checkbox 1");
cb2 = new Checkbox("Checkbox 2");
cb3 = new Checkbox("Checkbox 3");
cb3.setState(true);
. . . cbg = new CheckboxGroup();
cb4 = new Checkbox("Checkbox 4", cbg, false);
cb5 = new Checkbox("Checkbox 5", cbg, false);
cb6 = new Checkbox("Checkbox 6", cbg, false); |
|
How to Use the Choices
|
Choice class provides a menu-like list of choices, accessed by the distinctive button. User presses the button to bring up the "menu", and later chooses one of the items from the menu list. Another name for this UI element is the "pop-up list". Other ways of providing the multiple alternatives are checkboxes, lists, and menus.
|
Below is an applet code which has a Choice and Label. When the user chooses item from the Choice list, the Label changes to reflect an item chosen This code creates the Choice and handles the events from it. Note: that the second parameter to action() method is a string from the selected item.
|
//...Where instance variables are defined:
Choice choice; //pop-up list of choices
//...Where initialization occurs:
choice = new Choice();
choice.addItem("ichi");
choice.addItem("ni");
choice.addItem("san");
choice.addItem("shi");
label = new Label();
setLabelText(choice.getSelectedIndex(), choice.getSelectedItem());
. . . public boolean action(Event e, Object arg)
{
if (e.target instanceof Choice)
{
setLabelText(choice.getSelectedIndex(), (String)arg);
return true;
}
return false;
}
} |
|
How to Use the Dialogs
|
The thing that distinguishes dialogs from regular windows (that are implemented with Frame objects) is that the dialog is dependent on some other window (i'e Frame). When this other window is destroyed, and so are its dependent dialogs. When that other window is been iconified, its dependent dialogs will disappear from the screen. When the window is been deiconified, its dependent dialogs return to the screen. The AWT automatically provides this behavior to us.
|
Since no API currently do exists to let the applets find the window they are running in, applets generally cannot use dialogs. The exception is the applets that bring up their own windows can have the dialogs dependent on those windows. For this reason, the following applet consists of the button that brings up window which brings up a dialog. Here is the code for the window which the applet brings up. This code can be run as an standalone application or, with the help of AppletButton class, as an applet Here is the code that deals with the Dialog object:
|
//[HOW DO I MAKE THIS GET THE FOCUS?]
class SimpleDialog extends Dialog
{
private TextField field;
private DialogWindow parent;
private Button setButton;
SimpleDialog(Frame dw, String title)
{
super(dw, title, false);
parent = (DialogWindow)dw;
//Create and add components, such as the set button....
resize(350, 125);
}
public boolean action(Event event, Object arg)
{
if ( (event.target == setButton)
| (event.target instanceof TextField))
{
parent.setText(field.getText());
}
field.selectAll();
hide();
return true;
}
} |
|
How to Use the Frames
|
The Frame class provides the windows for applets and applications. Every application needs atleast one Frame. If an application has the window that should be dependent on another window -- disappearing when other window is iconified, for example -- then you should use the Dialog instead of Frame for the dependent window. (Unfortunately, applets cannot use the dialogs currently well, so they need to use the frames.)
|
Below is a code for the menu demonstration uses to create the window and handle the case where the user closes window.
|
public class MenuWindow extends Frame
{
private boolean inAnApplet = true;
private TextArea output;
public MenuWindow()
{
//This constructor implicitly calls the Frame no-argument
//constructor and then adds components to the window.
}
public boolean handleEvent(Event event)
{
if (event.id == Event.WINDOW_DESTROY)
{
if (inAnApplet)
{
dispose();
} else
{
System.exit(0);
}
}
return super.handleEvent(event);
}
. . .
public static void main(String args[])
{
MenuWindow window = new MenuWindow();
window.inAnApplet = false;
window.setTitle("MenuWindow Application");
window.resize(250, 90);
window.show();
}
} |
|
How to Use the Labels
|
Label class provides an easy way for putting uneditable, unselectable text into the program's GUI. The labels are aligned to the left of their drawing area, by default. we can specify that they be centered or right-aligned by specifying the Label.CENTER or by Label.RIGHT either to Label constructor or to setAlignment() method. As with every Component, you can also do specify the font and color of the Label.
|
Given below are the applets that use labels. The first applet (LabelDemo) simply creates three labels with a default (left) alignment, puts them in the GridLayout, and then displays them. Here is the code for LabelDemo.
|
import java.awt.*;
import java.applet.Applet;
public class LabelDemo extends Applet
{
public void init()
{
Label l1 = new Label();
l1.setText("Label 1");
Label l2 = new Label("Label 2");
Label l3 = new Label("Label 3");
//Add Components to the Applet.
setLayout(new GridLayout(0, 1));
add(l1);
add(l2);
add(l3);
validate();
}
} |
|
The second applet (LabelAlignDemo) does same, except that it make use of all three possible alignments. Since the applet is wider than necessary to display the text, and because the GridLayout uses all the available space, Labels have the wider display area than they need. This results in the visible difference in a horizontal position of the three differently aligned labels.
|
import java.awt.*;
import java.applet.Applet;
public class LabelAlignDemo extends Applet
{
public void init()
{
Label l1 = new Label();
l1.setText("Left");
Label l2 = new Label("Center");
l2.setAlignment(Label.CENTER);
Label l3 = new Label("Right", Label.RIGHT);
//Add Components to the Applet.
setLayout(new GridLayout(0, 1));
add(l1);
add(l2);
add(l3);
validate();
}
} |
|
Below is a code that LabelAlignDemo uses to create the labels and set their alignment. For the purpose of teaching, this applet uses all the three Label constructors.
|
Label l1 = new Label();
l1.setText("Left");
Label l2 = new Label("Center");
l2.setAlignment(Label.CENTER);
Label l3 = new Label("Right", Label.RIGHT); |
|
How to Use the Lists
|
List class provides the scrollable area containing the selectable text items (one for each line). Lists can allow either a multiple selections or only one selection at a time. Other components that allows the users to choose from the multiple selections are checkboxes (checkbox groups particularly), choices, and menus.
|
Below is code for an applet that shows two lists. The first list (which lists out the Spanish numbers) allows multiple selections. The second list (which lists the Italian numbers) allows a maximum of one selection. Below is a code which creates each list and handles events on the list. Note : the e.arg data for action events is the name of an acted-on item (similar to argument for action events on other components such as buttons and the menus). However, e.arg data for other list events is a number of acted-on item.
|
//where instance variables are declared:
TextArea output;
List spanish, italian;
//where initialization occurs:
//Build first list, which allows multiple selections.
spanish = new List(4, true); //prefer 4 items visible
spanish.addItem("uno");
spanish.addItem("dos");
spanish.addItem("tres");
spanish.addItem("cuatro");
spanish.addItem("cinco");
spanish.addItem("seis");
spanish.addItem("siete");
//Build second list, which allows one selection at a time.
italian = new List(); //Defaults to none visible, only one selectable
italian.addItem("uno");
italian.addItem("due");
italian.addItem("tre");
italian.addItem("quattro");
italian.addItem("cinque");
italian.addItem("sei");
italian.addItem("sette");
. . .
public boolean handleEvent(Event e)
{
if (e.target instanceof List)
{
List list = (List)(e.target);
String language = (list == spanish) ?
"Spanish" : "Italian";
switch (e.id)
{
case Event.ACTION_EVENT:
String string = (String)e.arg;
output.appendText("Action event occurred on \""
+ string + "\" in "
+ language + ".\n");
break;
case Event.LIST_SELECT:
int sIndex = ((Integer)e.arg).intValue();
output.appendText("Select event occurred on item #"
+ sIndex + " (\""
+ list.getItem(sIndex) + "\") in "
+ language + ".\n");
break;
case Event.LIST_DESELECT:
int dIndex = ((Integer)e.arg).intValue();
output.appendText("Deselect event occurred on item #"
+ dIndex + " (\""
+ list.getItem(dIndex) + "\") in "
+ language + ".\n");
}
}
return super.handleEvent(e);
} |
|
How to Use the Menus
|
The applet given above shows many of the menu features we are likely to use. The window it brings up has menu bar which contains four menus. Each menu contains one or more than one items. Menu 1 is a tear-off menu; by clicking a dashed line [implementation-specific?], we create a new window which contains same menu items as the Menu 1. Menu 2's only item has a checkbox. Menu 3 contains the separator between its second and the third items. Menu 4 is a window's help menu, which (depending on a platform) generally means that it is set off to the right. When we click on any menu items, the window displays the string indicating which item has been clicked and what menu it is in.
|
Here is the code for the window which the above applet brings up. This code can run as an standalone application or, with the help of an AppletButton class, as an applet. Here is the code that deals with menus:
|
public MenuWindow()
{
MenuBar mb;
Menu m1, m2, m3, m4;
MenuItem mi1_1, mi1_2, mi3_1, mi3_2, mi3_3, mi3_4, mi4_1, mi4_2;
CheckboxMenuItem mi2_1;
// ...Add the output displayer to this window...
//Build the menu bar.
mb = new MenuBar();
setMenuBar(mb);
//Build first menu in the menu bar.
m1 = new Menu("Menu 1", true);
mb.add(m1);
mi1_1 = new MenuItem("Menu Item 1_1");
m1.add(mi1_1);
mi1_2 = new MenuItem("Menu Item 1_2");
m1.add(mi1_2);
//Build help menu. Note that order in which it's added doesn't matter.
m4 = new Menu("Menu 4");
mb.add(m4); //Just setting the help menu doesn't work; must add it.
mb.setHelpMenu(m4);
mi4_1 = new MenuItem("Menu Item 4_1");
m4.add(mi4_1);
mi4_2 = new MenuItem("Menu Item 4_2");
m4.add(mi4_2);
//Build second menu in the menu bar.
m2 = new Menu("Menu 2");
mb.add(m2);
mi2_1 = new CheckboxMenuItem("Menu Item 2_1");
m2.add(mi2_1);
//Build third menu in the menu bar.
m3 = new Menu("Menu 3");
mb.add(m3);
mi3_1 = new MenuItem("Menu Item 3_1");
m3.add(mi3_1);
mi3_2 = new MenuItem("Menu Item 3_2");
m3.add(mi3_2);
m3.addSeparator();
mi3_3 = new MenuItem("Menu Item 3_3");
m3.add(mi3_3);
mi3_4 = new MenuItem("Menu Item 3_4");
mi3_4.disable();
m3.add(mi3_4);
}
public boolean action(Event event, Object arg)
{
String str = "Action detected";
if (event.target instanceof MenuItem)
{
MenuItem mi=(MenuItem)(event.target);
str += " on " + arg;
v if (mi instanceof CheckboxMenuItem)
{
str += " (state is "
+ ((CheckboxMenuItem)mi).getState()
+ ")";
}
MenuContainer parent = mi.getParent();
if (parent instanceof Menu)
{
str += " in " + ((Menu)parent).getLabel();
} else
{
str += " in a container that isn't a Menu";
}
}
str += ".\n";
//...Display string in the output area...
return false;
} |
|
How to Use the Panels
|
Panel p1 = new Panel();
p1.add(new Button("Button 1"));
p1.add(new Button("Button 2"));
p1.add(new Button("Button 3")); |
|
How to Use the Scrollbars
|
public boolean handleEvent(Event evt)
{
switch (evt.id)
{
case Event.SCROLL_LINE_UP:
case Event.SCROLL_LINE_DOWN:
case Event.SCROLL_PAGE_UP:
case Event.SCROLL_PAGE_DOWN:
case Event.SCROLL_ABSOLUTE:
if (evt.target == vert)
{
canvas.ty = ((Integer)evt.arg).intValue();
canvas.repaint();
}
if (evt.target == horz)
{
canvas.tx = ((Integer)evt.arg).intValue();
canvas.repaint();
}
}
return super.handleEvent(evt);
} |
|
How to Use the TextAreas and TextFields
|
//Where instance variables are defined:
TextField textField;
TextArea textArea;
public void init()
{ textField = new TextField(20);
textArea = new TextArea(5, 20);
textArea.setEditable(false);
...//Add the two components to the panel.
}
public boolean handleEvent(Event evt)
{
if (evt.id == Event.ACTION_EVENT)
{
String text = textField.getText();
textArea.appendText(text + "\n");
textField.selectAll();
}
return super.handleEvent(evt);
} |
|
|
Laying Out Components within a Container
This chapter tells us how to position the onscreen representations of the Components. It will show us how to use a layout managers the AWT provides. It will also show how to write our own layout manager.
It will even tell how to do without a layout manager and use the absolute positions. Finally, it will discuss some of the common layout problems and solutions.
General Rules to Use the Layout Managers
|
Unless we explicitly tell a Container not to use the layout manager, it will be associated with its own instance of a layout manager. This layout manager is been automatically consulted every time the Container needs to change its appearance. Most of the layout managers do not require programs to directly call layout manager's methods.
|
How to Choose a Layout Manager
|
AWT-provided layout managers have different strengths and weakness. This section discusses some of the common layout scenarios and which AWT layout managers may work for each scenario. If none of the AWT layout managers is right for our situation, we should use layout managers contributed to the net.
- Scenario: We need to display a component in as much space as it can. Consider using the BorderLayout or GridBagLayout. If you use the BorderLayout, we will need to put the space-hungry component at the center. With GridBagLayout, we will need to set constraints for the component so that the fill=GridBagConstraints.BOTH. Or, if we do not mind every other component in the same container being as large as our space-hungry component, we can use a GridLayout.
- Scenario: We need to display a few components in the compact row at their natural size. Consider using Panel to hold the components and using a Panel's default FlowLayout manager.
- Scenario: We need to display few same-sized components in rows and/or the columns. GridLayout is perfect for this purpose. Use the Panel if it isnecessary to contain the components.
|
How to Create a Layout Manager and Associate with a Container
|
Every container has the default layout manager associated with it. All Panels (including an Applets) are initialized to use the FlowLayout. All Windows (except the special-purpose ones like FileDialog) are initialized to use the BorderLayout.
|
If we want to use a Container's default layout manager, we don't have to do anything. The constructor for each of the Container creates the layout manager instance and initializes a Container to use it.
|
To use the non-default layout manager, we need to create instance of the desired layout manager class and tell the Container to use it. Below is a code that does this. This code creates the CardLayout manager and sets it as the layout manager for the Container.
|
| aContainer.setLayout(new CardLayout()); |
|
|
Working with Graphics in Java
Drawing simple Shapes
|
Graphics class defines methods for drawing the following types of shapes:
- Lines ( drawLine() )
- Rectangles ( drawRect() & fillRect() )
- Raised or lowered rectangles ( draw3DRect() and fill3DRect() )
- Round-edged rectangles ( drawRoundRect() and fillRoundRect() )
- Ovals ( drawOval() and fillOval())
- Arcs ( drawArc() and fillArc() )
- Polygons ( drawPolygon() and fillPolygon() )
Except for polygons and lines, all shapes are specified using their bounding rectangle. Once you understand rectangles, drawing other shapes is relatively easy. For this reason, this page will concentrate on rectangle drawing.
|
Drawing Simple Rectangle
|
The applet used the draw3DRect() and fillRect() methods to draw its interface. Here is an applet to drawing simple rectangle
|
//In FramedArea (a Panel subclass):
public void paint(Graphics g)
{
Dimension d = size();
Color bg = getBackground();
//Draw a fancy frame around the applet.
g.setColor(bg);
g.draw3DRect(0, 0, d.width - 1, d.height - 1, true);
g.draw3DRect(3, 3, d.width - 7, d.height - 7, false);
}
//In CoordinateArea (a Canvas subclass):
public void paint(Graphics g)
{
//If user has clicked, paint a tiny rectangle where click occurred
if (point != null)
{
g.fillRect(point.x - 1, point.y - 1, 2, 2);
}
} |
|
Loading the Images
|
AWT makes it easy to load the images in either of the two formats: GIF and JPEG. The Applet and Toolkit classes provides the getImage() methods that works for either format.We use them like this:
|
myImage = getImage(URL); //in an Applet subclass only
or
myImage = Toolkit.getDefaultToolkit().getImage(filenameOrURL); |
|
getImage() methods returns immediately, so that we don't have to wait for the image to be loaded before going to perform other operations in our program. While this improves the performance, some programs requires more control or information about the image loading. We can track image loading status either by using MediaTracker class or by implementing an imageUpdate() method defined by the ImageObserver interface.
|
Displaying the Images
|
It is easy to display an image using Graphics object that is passed into our update() or paint() methods. we simply invoke the drawImage() method on the Graphics object. Consider for example:
|
| g.drawImage(myImage, 0, 0, this); |
|
This section explains four forms of the drawImage(), two of which scale image. Like getImage(), drawImage() is asynchronous, returning immediately even if the image has not been fully loaded or drawn yet.
|
|
| |