Professional Documents
Culture Documents
Context
The purpose of this unit is to explain how Java can be used to create stand-alone
applications suitable for non-trivial, real world tasks. Most real-world applications
manipulate files on the users’ computers, so this unit introduces the subject of how Java
works with files. Relating to files, and in fact almost all non-trivial programs, is the concept
of Java exceptions — the handling of special cases and errors.
Objectives
Study Planning
You should expect to spend approximately 9 hours studying this unit. You may find it
convenient to break up your study as follows:
Disk-based Content: 2¼
hours
Application: 3 hours
Set textbook Content: 1 hour
Reflection (On-line discussions, 1 hour
review
questions):
Tutorial Work: 1 hour
Related Coursework: ¼ hour
Extension Work: ½ hour
Equipment/software required
Online Resources:
1. Frequently-asked questions
2. Additional Source Code Examples
Introduction to Unit 10
Firstly, the relatively straightforward way that an applet can be converted into an
application is investigated. The reason for doing this is usually when there is a desire to
write a program that uses Java features that are restricted for applets, such as file
handling.
Files and file handling is investigated, mainly concentrating on the most commonly
encountered type of files — text files.
A feature of all robust and well written programs is that they cope appropriately with
incorrect user responses, and situations such as missing files. The last section of this unit
investigates the mechanisms of writing programs that both respond to system generated
exceptions, and also user-defined and generated exceptions.
If you go on from this module and programme in situations where you are developing
large-scale programs, you will be likely to have to write programs that involve all three of
the Java features presented in this unit.
Limitations of applets
Although the use of applets has the notional advantage of simplicity for the end user, in
practice this advantage is often not realised because Web browser technology cannot
keep pace with developments in the Java language. In practice it is often the case that
Web browsers lag behind the development of Java by one or two major revisions (for
example, Java version 1.3 is widely available but some Web browsers support only
version 1.1 or Java 1.2).
However, the main problem with distributing software as applets is that the applet is
allowed hardly any interaction with the user’s computer. For example, an applet can
donone of the following :
Please note that it has not been said that an applet cannot read or write files — rather,
an applet cannot read or write files on the computer that is running the applet unless it is
the same computer the applet originates from.
Advantages of applets
Applets are easy to distribute to any platform (via the use of Web browsers). The
programmer does not have to maintain the program’s interaction with the GUI to the same
extent as with applications — the browser handles many of the events such as window
closing etc.
Despite the limitations of applets, applet programming is quite popular because it makes
software very easy to distribute using a Web browser. The end user does not have to set
anything up: merely viewing a Web page is sufficient (in principle).
Moreover, the Web browser provides an environment in which the applet can run. The
programmer does not have to worry about how the user starts and stops it, or changes
the size of its screen area.
For some distributed programming applications (for example where the data the user
works on is not held on his or her own computer, but at a remote site) applet programming
can be very effective. For example, a number of banks are providing on-line access for
their customers based on Java applets. Since all the user’s data is held by the bank’s
central computers, there is no need for data to be read or written from the user’s own
computer. So this particular limitation of applets does not present a problem.
So when writing a Java program for distribution, the developers must make a decision to
support an applet or a stand-alone application. The creation of stand-alone applications
presents no particular problem for the Java programmer, as we shall see.
If it has a graphical user interface (GUI) — and most programs do — an application must
do at least these three things that an applet will not usually be concerned with:
A Java application starts at the method called ‘ main() ’ in the primary class (often
called the ‘main’ class).
When method main() has finished, the program does not necessarily finish (there may be
‘threads’ running). An application should call System.exit() to finish.
The Java compiler will be quite fussy that the method is defined exactly like this. If you
are creating a program with a graphical user interface the data passed in the
argument args[] will not usually be of interest. This argument will contain the data
specified by the user when running the program from a command prompt. As a GUI
program will normally be run by clicking on something, there will not be a command line
and args[] will be empty.
The method main() is often defined in a class that does nothing else but provide this
method. Conventionally this class has the same name as the program itself. For example:
class MyWindowApp
} // class
Creating the main window
The application must create a main window within which all its output will be confined. It
is usual to set the initial size of the window, but the user may change it. Normally the main
window will be an object of a subclass of Frame.
The program can create a main window simply by creating an object of type Frame . For
example, the following two line will make a window appear:
mainWindow.setVisible (true);
The problem with this is that the built in Frame class cannot do anything specific. It
provides a lot of standard functionality, but it won’t do anything useful for a given
application. We create a subclass of Frame to do those things that are specific to this
application. In particular, objects of class Frame will not stop the program when the user
clicks on the ‘close’ button in the corner of the window, which is the usual convention.
With this definition inside our main() method for the application we would create the main
window by executing:
mainWindow.setVisible (true);
Although the class MainWindow does not yet have any functional methods, it must have
a constructor. The constructor in this case simply calls the constructor for Frame, passing
the name of the program as the argument. This name will appear in the caption bar of the
window. It also sets the initial size of the window using setSize() .
A simple application using the approach would require 2 source files, MainWindow.java:
import java.awt.*;
} // class
and MyWindowApp.java
class MyWindowApp
mainWindow.setVisible (true);
} // class
This application does not handle window events the window will not close when we try to
close the applet or click on top right hand button 'x'. to stop the MyWindowApp from Kawa,
you need to select stop run from the Build pull down menu.
When running this application simple displays an empty Frame window with the title ‘My
program’s title’:
When the user interacts with the main window, Java sends events. The events can be
received by a WindowListener. The main window itself can be a window listener, or
another class can take this responsibility.
There are seven different events, and the listener must handle all of them, even to ignore
them. WindowListener is an interface, and specifies seven different methods:
windowClosing()
(the most important) which is called when the user clicks on the ‘close’ icon to close the
window. In summary, the others are:
WindowActivated()
The main window has been activated (e.g., raised to the ‘top’ of the display)
WindowDeactivated()
The main window has been deactivated (e.g., a different window has been raised to the
‘top’ of the display)
WindowClosed()
The window has been closed (this is different from windowClosing , which indicates an
intention to close)
WindowDeiconified()
WindowIconified()
WindowOpened()
To make the main window able to manage itself, that is, receive events from the user
interface, it can be defined like this:
However, MainWindow must now implement all the methods described above, even if
they don’t do anything. To enable the receiving of events, the main window’s constructor
can have the line:
AddWindowListener (this);
public MainWindow()
{
super("Do-nothing program");
setSize(300, 300);
addWindowListener (this);
} // class
When the user indicates that the program is to exit, it should shut down gracefully. By
convention there are at least two ways for the user to do this:
For example, if you are editing a document in a word processor and click on the ‘close’
button, and there are some changes made since the last change, the word processor
should ask if you want to save the work first.
If stopping the program is uncomplicated — no files to save, for example — it can simply
call System.exit() from within windowClosing() .
So the windowClosing() method would look as follows:
public void windowClosing (WindowEvent e)
// terminate program
System.exit(0);
When testing, the simplest way to run the application is usually to start it from the
command line. For example, if the main() method were defined in the classMyProgram ,
then after compiling the MyProgram.java source file:
java MyProgram
Do not enter java MyProgram.java . You want to execute a class (object file), not a source
file.
import java.awt.*;
import java.awt.event.*;
C.setSize(300,300);
C.setVisible(true);
public TheCircleWindow(){
setLayout(new FlowLayout());
add(grow);
grow.addActionListener(this);
add(shrink);
shrink.addActionListener(this);
add(left);
left.addActionListener(this);
add(right);
right.addActionListener(this);
add(up);
up.addActionListener(this);
add(down);
down.addActionListener(this);
myCircle = new Circle();
this.addWindowListener(this);
if (event.getSource() == grow)
myCircle.changeSize(10);
if (event.getSource() == shrink)
myCircle.changeSize(-10);
if (event.getSource() == right)
myCircle.moveRight();
if (event.getSource() == left)
myCircle.moveLeft();
if (event.getSource() == up)
myCircle.moveUp();
if (event.getSource() == down)
myCircle.moveDown();
repaint();
System.exit(0);
myCircle.display(g);
}
// The Circle class
class Circle {
g.setColor(colour);
}
public void moveUp(){
add(new MyApplet());
The Circle example will be shown as an applet TheCircle.java. There are some deliberate
diferences such as the initial state of the Circle, colour, etc.
The UML diagram is now:
import java.awt.*;
import java.applet.Applet;
import java.awt.event.*;
class Circle {
private int radius = 10;
private int xCoord = 20, yCoord = 50;
private Color colour = Color.blue;
repaint();
What is a file?
Examples of files include the text files that are your Java source files, documents storing
word processor pages, databases, numerical tables and charts from spreadsheet
applications. Files can store any type of data, in any format. To the computer a file is
simply a heap of bytes.
If you use a computer for ordinary applications, then you probably have a mental model
of a ‘file’ already. The problem that many novice programmers face is that their mental
models of files do not correspond at all with the way that the program ‘sees’ a file. User
interfaces like those provided with Microsoft Windows have encouraged us to see files as
documents and folders; but to the programmer a file is simply a heap of bytes.
There is no intrinsic structure to files . If a file has a particular meaning, e.g., it is a word
processor document, it is because the programmer defined it to be that way.
Note also that Microsoft Windows has a convention of using ‘file extensions’ (.txt, .exe,
.html, .java etc.) to represent the contents of files. This is merely a convention . The
content of a file is specified in the program that writes it.
Java’s File class models both files and directories. It manipulates both files and directories
as entities.
Often the first complication that new Java programmers experience when they begin to
write programs that use files is the function of the File class. This class is used to
manipulate files and directories, but only as whole entities. You cannot use the File class
to read or write data . A File object is created like this:
Having created the object we have access to some useful methods, for example:
File.canRead(), File.canWrite()
File.createNewFile()
As the name suggests, creates a new file with the specified filename
File.Delete()
Delete the file
File.length()
The file class is also important because most of the other classes that read and write files
will require the filename to be given as a File object, not as a text string.
Note: all the Java file handling classes are part of the package java.io, so you probably
need to include the line
import java.io.*;
Consider a text file called examples.txt containing the following 2 lines of text:
import Java.io.*;
} // class
The basic input stream is class InputStream. InputStream is an abstract class: it does
not define how to read the data. The real functionality is provided by subclasses
of InputStream .
This is a class that can read a specified file from beginning to end.
Note that the FileInputStream needs to be supplied with a file object, not a simple
filename, so we have to create a File object as well. You will often see this code shortened
to:
The program can read the first byte of data in the file like this:
Byte b = fis.read();
Each new call to the read() method reads the next byte in the file, until the end.
We can write a program to display the numeric value of each byte in this file. The output
of the file is as follows:
The bytes with values 13 and 10 correspond the characters to carriage return ( <cr> )
and new-line ( <nl> ) respectively (which are how the Windows system indicates a new
line in a text file).
import java.io.*;
FileInputStream stream;
int b;
try
try
b = stream.read();
catch (IOException e) {}
} // class
Ignore the ‘try’ and ‘catch’ statements for now — these are related to dealing with
exceptional conditions, such as the file not being found. Exceptions, file related and
otherwise, are covered later in this unit.
This application is given to illustrate how stream , an object of theFileInputStream
The class FileInputStream is fine if we want to read a file one byte at a time.
One of the most widely-used files structures in the computing industry is the ‘plain text’
file. Here each byte represents a character (letter, symbol, etc) and there are special
characters to indicate the break between lines. This is the format that Windows Notepad
uses, and is accepted by the Java compiler. HTML files are similar, but here some of the
characters have extended meanings.
We can read a plain text file using a FileInputStream . All we have to do is read each
character one byte at a time, and add it to a String. When we detect an end-of-line
character, we process that line. Fortunately we don’t have to do this, as Java provides a
class for it: the BufferedReader .
Creating a BufferedReader
So here’s how we create a BufferedReader that will allow us to read the file ‘readme.txt’
one line at a time:
File aFile = new File ("readme.txt");
Note that four different classes are involved in this simple method! This is what happens
when the program executes ‘ br.readLine() ’.
3. The FileInputStream gets the byte from the file specified by the File object
Of course all this complication is hidden from the programmer — the explanation has
been included so that you can see what the four classes do.
Reading a text file a line at a time is such a common method that it is surprising that Java
does not contain a class to automate it. Some proprietary Java development tools include
extended class libraries that have this sort of facility. For example, Microsoft’s Visual
J++ has a class called TextReader that does exactly this job. However, it is simple enough
to implement a TextReader class yourself and use it in any program that requires this
facility.
The process described above can be simplified slightly by the use of the FileReaderclass.
Writing data to a file is very similar to reading data from a file. To write a file one byte at
a time we create an object of class FileWriter , and call its write() method to write
each byte. There is also a BufferedWriter class than cofunctionality complementary to
the BufferedReader .
Example of interactive programs reading/writing files
As well as the ‘byte stream’, Java supports other models of a file which are extensions of
the ‘byte stream’ concept.
Data stream: sees the file of a stream of variable values (e.g., double, int)
Object stream: sees the file as a stream of objects
The data stream approach is useful for storing the values of Java variables, particularly
arrays, in a file. An object stream is useful for storing the states of objects between uses
of a program.
Non-stream files access
Java provides a class called RandomAccessFile for this. A random access file models a
file as an array of bytes, rather than a stream of bytes
File handling is an area where the programmer needs to take particular care that the
program responds correctly if something unfortunate happens. For example, if we ask a
word processor to open a file that does not exist, it should politely warn us of the problem.
It should not crash, or print a meaningless error message like ‘ null pointer
exception 0030:1023 in module aargh.exe’ ). The reason it responds
appropriately is that the programmer anticipated that the user might make this mistake,
and wrote program code to respond correctly. The programmer must provide program
statements to deal with most or all errors and mis-operations that the program may
encounter.
To simplify and regulate the process, Java uses a mechanism called ‘exception handling’.
We have not covered this subject yet, but in brief it is a technique for specifying what can
go wrong in any particular method. Java uses the statementsthrow , try and catch to
control this process.
For example, it was explained earlier in this unit how to define a BufferedReader , but
this would not work as it standard because the code did not deal with the exceptions that
might arise. When a method specifies that it might generate a particular exception, the
program that uses it must take account of this. The compiler will not proceed otherwise.
So this earlier section of Java should really have written like this:
try
catch (Exception e)
Here the keyword try means that the following section contains methods that are
defined to produce exceptions (Java programmers talk about ‘throwing an exception’).
The section starting with ‘ catch ’ defines what to do if one of these exceptions is actually
generated.
Exceptions
The purpose of this section is to introduce the types of exceptions (‘errors’) to which a
computer program is subject, and describe how a Java program can be made to behave
predictably even in the presence of exceptions
It is important for the design and development of usable and robust programs to anticipate
the kinds of errors to which your programs will be subject. Java’s Exception
handling system can be used to write programs that are tolerant of user and system
errors.
The word ‘exception’ has a similar meaning to the word ‘error’, but ‘error’ is very vague in
normal usage. It can mean a specific logical error in a line of program (like adding 2 when
you should have added 3), or an incorrect operation on the part of the user (like opening
a non-existent file). The first of these is simply a mistake on the part of the programmer,
and no particular mechanisms exist to detect such mistakes. Finding errors like this is
part of the normal process of testing and debugging. The second is an adverse input to
the program, which must be detected and corrected by the program when it is running.
In Java, the words exception and error have reasonably well-defined meanings.
In Java, an exception is anything that would cause a program to deviate from its ‘normal’
course of operation. An exception may result from incorrect operation by the user, or
failure of any part of the computer system on which the program is running. An exception
may also arise because the programmer did not anticipate user inputs that are impossible
to process (like asking a calculator to divide something by zero). In Java, some
programming errors are also classified as exceptions, as will be discussed later.
In Java an error usually means a system error . That is, a serious problem resulting from
something beyond the control of the programmer or the user.
There is not enough free space on the selected disk to save this document.
If you want to continue you should delete some files on this disk or select a
different disk
Disk full!
Sorry!
ERROR
The last of these responses probably constitutes a crash . This is probably the result of
the programmer doing nothing at all to deal with the incorrect operation, and the
consequences being detected by something else. The notion of a crash is discussed in
more detail below.
Sometimes computer programs are subject to system errors. Such errors result, for
example, from unplugging a cable to switching the power off without warning. In rare
cases computer equipment has been known to catch fire.
It is impossible to respond in any useful way to most system errors. If the power is
switched off it is impossible to respond at all. However, the system should respondsafely .
By this it is meant that the amount of damage caused by the failure is minimized. For
example, most word processors save the user’s work to disk automatically at regular
intervals. Even if the power is switched off, the user will lose only a limited amount of
work.
What is a ‘crash’?
The term ‘Crash’ is rather vague, even to programmers. Typically a program is said to
have crashed when it has done some or all of the following:
The last of these is probably the most annoying for the end user. In a well-designed
computer system it should be impossible for the failure of a single program to compromise
the operation of the system, but it does sometimes happen. Fortunately, it is almost
impossible for a Java program to have such a drastic effect. A Java program can,
however, exhibit all the other symptoms of a crash.
If the programmer has not written the program in such a way that it detects and handles
exceptions, usually one of three things will happen:
We have already seen that the programmer should not ignore exceptions. Why would
they get ignored?
File handling in particular is an area where a great many things can go wrong. It can be
very time-consuming (and sometimes difficult) to write instructions that deal correctly with
all the possible exceptions.
Java’s exception handling scheme is designed to make it difficult for the programmer to
forget or ignore exception handling. Whenever an exception can occur, the programmer
is forced to do something about it, even if it is only to write instructions to ignore it.
It is important to realize that good exception handling requires a lot of extra programming.
In many cases, there may be as much or more code concerned with exception handling
than with the normal operation of the program.
In Java, methods ‘throw’ and ‘catch’ exceptions. Exceptions are defined as classes. Many
of the Java built-in classes can ‘throw’ exceptions. The programmer can add new
exceptions if necessary.
Exceptions are defined as classes. For example, the exception generated by opening a
file that does not exist is represented as an object the class FileNotFoundException. If we
want to indicate that an attempt has been made to open a non-existent file, then we ‘throw
a FileNotFoundException ’. The mechanism for doing this will be described later.
Catching an exception
Consider this section of Java, that opens a file called ‘readme.txt’ for reading.
If you look in the on-line documentation for the class FileInputStream , you will find
that its constructor is defined to throw a FileNotFoundException . The compiler is
telling us that this exception must be handled. We can handle it in one of two ways: by
doing something about it, or by passing it on to the method that called the current one.
try
catch (FileNotFoundException e)
System.out.println
The ‘try’ section encloses the statements that will throw the exception. The ‘catch’ section
defines what happens if an exception is thrown.
Note that each catch must specify the exception which is to be handled.
The try section can be of any length, and there can be as many catch sections as required.
This means that it is possible to write an method in two parts, like this:
try
}
catch (...)
// handle exceptions
catch (...)
// handle exceptions
This structure has the ‘important’ (that is ‘normal method’) part of the method first,
followed by all the error handling code. This makes it easier to follow how the program
works, because the main functions of the method are separated from the exception
handling.
Suppose we are writing a method that does some file manipulations, but it is not
appropriate for the exceptions to be handled in that method. For example, we might be
writing a general-purpose class that will be used in a number of different programs. The
ways that errors are reported to the user will differ according to the application.
Here is an example. A class has been defined called FileManager() which contains
useful methods for copying, renaming and deleting files. Clearly there is a need for
exception handling here. The method copyFile() might be defined in outline
something like this:
This method will contain a lot of statements that generate exceptions. Where will they be
handled? A typical scheme is to ‘pass upwards’ the exceptions. This means that the
exceptions are not handled in this method, but in the method that called it. In this case
the method that uses the copyFile() method must handle the exceptions
(using try and catch as before).
The passing upwards of exceptions is indicated like this:
throws FileNotFoundException
Here ‘throws’ means that this method can itself throw an exception. If
aFileNotFoundException occurs during the execution of copyFile() , then it is
the method that called copyFile() that must handle it. copyFile() itself will stop as
soon as the exception is detected. This means that if there are a long series of statements,
and an exception occurs in the first one, then the rest of the method will be skipped.
Exception classes
In Java, exceptions are represented as classes and form a hierarchy. The advantage of
this structure is that it allows the programmer to handle groups of exceptions rather than
individual cases. For example, suppose we are writing a section of program that
undertakes a number of file methods (reading, writing, etc). All the classes concerned
with file handling exceptions are subclasses of the class IOException . So if we want to
catch all such exceptions in one ‘catch’ section, we can write:
catch (IOException e)
System.out.println
The problem with this approach is that treating all the exceptions as equivalent may not
be what we want. It probably doesn’t help the user very much if the program cannot give
a more detailed explanation of what is wrong.
Note that all exceptions used by the Java standard classes are subclasses of Exception.
So if a program catches an Exception then it guarantees to handle all possible exceptions.
This is sometimes useful when developing a program, but is not normally good practice
because, again, it is difficult to tell the user what has happened.
Defining new exceptions
The standard built-in Java classes define and use exceptions. It is also possible to define
new exceptions to organise exception handling for your own classes. Suppose, for
example, we are writing a class that displays text files for the user to browse. It contains
a method called ‘ openTextFile() ’ that reads a specified text file and displays it. If the user
selects a file that is not a text file, the method cannot continue. We might define this
method like this:
throws NotTextFileException
The line:
throws NotTextFileException
When defining a new exception, we can make it a subclass of Exception, or of one of the
existing subclasses of exception. With this example, NotTextFileException is similar to
the existing file handling exceptions (like FileNotFoundException ) so we probably want
to define it as a subclass of IOException (as the other file handling exceptions are). The
definition will look like this:
So we know how to define an exception; how does the program throw it?
Throwing an exception
Note that it is a specific object of the class that is thrown, not the class itself. So we use
new to create the exception object, and throw to throw the new exception.
A program can throw any exception, not just the ones it defines. However, this is usually
not useful; the built-in exceptions are thrown by the methods in the built-in classes.
In Java, a ‘run-time exception’ is one that does not have to be caught by the program.
The compiler will not report an error if the programmer does not handle a run-time
exception. An example of a run-time exception is ArithmeticException . This exception
occurs when the program tries to carry out an arithmetic operation which cannot succeed
(like dividing by zero). The programmer does not have to handle this exception.
What happens if the exception is thrown and the programmer does not handle it? The
program will automatically be stopped, and the name of the exception displayed. This is
a very ugly way for a program to finish, so the programmer may choose to handle the
exception anyway.
try
int x = 2/0;
catch (ArithmeticException)
Run-time exceptions differ from ordinary exceptions in that they are subclasses
ofRuntimeException , rather than of Exception .
Java ‘error’ classes
In Java, the word ‘error’ usually denotes a system error . That is, a problem arising from
hardware or from a logical error in the Java system itself. A typical example of a system
error is not having enough memory to complete a method.
Like run-time exceptions, the program does not have to handle errors. Indeed, Java
standards recommend that the program does not handle these exceptions. The reason
for this is that if the computer or the program is in a state where such an error occurs, it
is probably impossible for the program to do anything useful. For example, if the program
runs out of memory, then it won’t be able to do anything to correct this situation because
it won’t have enough memory to carry out whatever corrections are required.
Activities
A ‘do-nothing’ application is one that provides the outline of a program, but does not do
anything useful. Write such a program as a stand-alone Java application. The program
should create a main window with the title ‘do-nothing program’. When the user clicks on
the ‘close’ icon, the program should close.
The program should appear something like this:
Test the FileDemoReversed.java program by supplying any text file an see how it will be
displayed in the TextArea. As an example you could use the source code file of a program
You have to be careful to make sure that the file you load can be found.
I have used files from my local a:drive.
You can also experiment with creating files either using the FileDemo.java
or otherwise. Discuss any problems with your tutor.
A common problem when processing numeric input from users is that they enter real
values, or values with comma’s etc. when, say, an integer is required. So for example a
program might request an age from the user (expecting an integer), and a small child
might enter ‘3.5’ or ‘3 and a half’.
The application below uses a Swing dialogue box to request and get input from the user.
This showInputDialogue() method returns the value entered by the user as
aString , whether we wanted a String , or char , or int or double or whatever. One
convenient way to convert from a String to an int is to use the class
methodparseInt() provided by the String class. This method converts from a String . ,
such as ‘21’ (i.e. character ‘2’ followed by character ‘1’) to the int 21.
When the application is run it first displays a message in the console window
(viaSystem.out.println() ):
Then the application presents to the user an input dialogue, requesting their age:
Then the application displays the current age (having parsed it to an int), and the age of
the person next birthday. Then the application terminates:
The problem occurs if what the user enters is not a valid integer (say 4.5). Then the
application crashes with the following messages:
The listing of the application is as follows:
import javax.swing.*;
String ageString;
int age;
System.exit(0);
} // class
Find out about parseInt() and the exception it throws when its String is not a valid, and
amend the application to display the following message before terminating if the age
entered is invalid:
where <age> is whatever the user entered. So if the user entered ‘4.5’ the message would
be:
Catching an exception
From the Javadoc html pages it was possible to find details about the exceptions that
might occur when sending String.parseInt() messages:
Therefore we need to catch a NumberFormatException exception, and display a
message to the user indicating that their input could not be processed as a valid integer.
The code that parses the String and displays the output can be changed to the
following:
try
catch (NumberFormatException n)
}
A full listing of the revised code can be found in the file Exception2.java.
Exercises
Study the example program WebMerge.java and answer the questions in it.
It is possible to create a File object corresponding to a file that does not exist. It has to
be, because the method File.createNewFile() will create a new file, and this would be
unnecessary if the file had to exist already.
The variable directoryName contains the name of the directory where the file will be
written. The variable inputFilename is the name of the input file; the output file will have
the same name but be in a different directory. So the line cthe full name of the new file
from the directory name, the ‘/’ character and the filename.
If the file were very long, then the computer may not have enough memory to hold it. In
this case we would have to process the file in pieces. In practice a modern PC ought to
be able to manage files of a few megabytes in memory without too much trouble.
The method available() returns the number of bytes that are available to read. If this
is zero, then we have read to the end of the file.
Complete the table below summarising the difference between exceptions, run-time
exceptions, and errors in Java:
Handled by Subclass of Example
program
Exceptions Exception
Run-time
Optional
exceptions
Errors
Complete the following statements that summarise the concepts explored in the
‘Interfaces’ section of this unit:
When an exception has been ______, it must either be dealt with in the _______ ______ or thrown
‘_______’ to the calling method, which must deal with it in its turn.
___-____ exceptions and errors do not have to be caught, but if they are not the program will _________.
Exceptions Summary
When an exception has been thrown, it must either be dealt with in the current
method or thrown ‘upwards’ to the calling method, which must deal with it in its turn.
Run-time exceptions and errors do not have to be caught, but if they are not the
program will terminate.
File handling is traditionally an area where the program has to be able to deal with all
sorts of errors and unexpected results (these are collectively called ‘exceptions’ by Java
programmers) Assuming that a program is well written (and therefore will not fail because
of a trivial error on the part of the programmer), what can go wrong while attempting to
read to data from, or write data to, a file? Some of these errors may be the result of a
mistake on the part of the user, but the program must deal with them nonetheless. Try to
think of at least five possible exceptions.
Attempts to read a file to which the program does not have access rights
Attempting to read or write to a file to which the program does not have
access rights
Although many exceptions are the consequence of problems beyond the control of the
programmer, some errors on the part of the programmer will be detectable in the form of
exceptions. Which of the following errors on the part of a programmer do you think will (1)
always given rise an exception? (2) possibly give rise to an exception or (3) not give rise
to an exception? Assume that x, y and z are integer variables.
1 int x = y + 2; int x = y + 4;
2 int x = y / 0; int x = y / o;
1. This will not generate an exception. It is a straightforward logical error on the part of
the programmer. However, the variable ‘x’ now contains the ‘wrong’ value, and it is
possible that an exception will be generated later when this value is used.
5. This will not generate an exception; although ‘x’ now contains the ‘wrong’
value.
The use of a graphical user interface limits the likelihood that user errors will occur.
Programs that operate by the user typing commands are far more prone to user errors.
Why is this?
User errors
1. Graphical user interfaces usually provide the user with a choice of operations. For
example, if the ‘File’ menu provides commands ‘File’, ‘Open’, etc., the user is limited to
these operations. The user does not have the opportunity to ask the program to do
something that is totally meaningless. If you run the Java compiler from the command
line, you could readily type
javac test.html
but test.html is probably an HTML file and will make no sense to the Java compiler. A
Java compiler with a graphical user interface may only allow the user to select files from
a list of files that are known to be Java programs. Thus there is no opportunity for this
kind of error to occur.
2. The user is normally only offered choices that are valid in the current
context. For example, a desktop publishing program may change the facilities
offered to the user depending on whether text or a diagram is being edited.
This prevents the user trying to do something that, although meaningful, is not
appropriate in the current context. For example, a desktop publishing program
may have the facilities to change the font of text, but it would be inappropriate
to change the font of a circle or rectangle. The program will normally not
present the user with a command to change font while editing a circle or
rectangle. This is what is meant by ‘appropriate to the context’.
3. A graphical user interface allows the programmer to restrict the type of data entered
by the user. For example, if the program is expecting a number, the data entry field can
be configured to accept only digits (not letters or symbols) as input. So the error that
might result from the user entering the wrong type of data is prevented. Of course this
does not prevent the user entering meaningless data, it only prevents the user
entering grossly meaningless data.
One of the most important run-time exceptions is the ‘null pointer exception’. Use the Java
documentation to find out what a null pointer exception is, and write a few lines of Java
that will generate such an exception.
A null pointer exception occurs when the program tries to use an variable declared to
refer to objects of a particular class, but which at that point in the program does not refer
to any object (probably has not been initialised, or the object it was referring to has been
destroyed). Such an (object) variable is described as having the value ‘null’ in Java, or
the variable is said to be referring to a null object.
Frame myFrame;
myFrame.setVisible(true);
The compiler will warn me that myFrame is not init. The problem usually occurs when
objects are used as attributes of another class. For example, consider this section of
Java:
class Test
Frame myFrame;
Test()
{
myFrame.setVisible(true);
This will cause a null pointer exception as soon as an object of class Test is created.
This is because the constructor calls myFrame.setVisible() , but myFrame at that point is
a null object: it has not been set to any value.
In this case the compiler is not smart enough to spot that the programmer has made a
mistake. A similar problem arises when passing an object as the argument to a method.
The compiler cannot work out whether the object is initialised or not.
Review Questions
Applications
Review Question 1
The stand-alone program does not require another piece of software (like a
Web browser) to support it, so is less dependent on the reliability of the
supporting software. In Java a stand-alone application is allowed to do certain
things that an applet cannot; the most important of these is to read and write
data into files on the user’s computer.
Review Question 2
An applet has to have a graphical user interface, but an application does not. If an
application does have a graphical user interface, what must the programmer provide that
is available automatically to an applet?
Review Question 3
The user clicks on the ‘close’ icon in the window, or carries out some other
similar action
Review Question 4
What Java class usually forms the base for an application’s main window?
Frame class. If you prefer using Swing classes rather than AWT classes, then
the main window would probably be aJFrame object.
Review Question 5
When the user clicks on the close icon of a Frame window, Java sends a windowClosing
event to the listener for that Frame. Why can it not simply terminate the program, and
save the programmer a bit of work?
Files
Review Question 6
The File class models a file as a single unit, that is, it allows files to be
created, deleted and tested for various things, but it does not allow any data to
be read or written
Review Question 7
Review Question 8
Review Question 9
When reading a plain text file one line at a time, why can we not accomplish this using
only a BufferedReader object? Why do we need other classes as well?
Review Question 10
What classes would we use to write a file containing 1000 integer values (rather than
1000 bytes)
Review Question 11
In this unit it was stated that it requires four different classes to allow a Java program to
read a text file one line at a time. This is because we could not make BufferedReadera
subclass of FileInputStream.
However, if Java allowed multiple inheritance these problems could be overcome, and
we could do this job with only one class. How is this?
Discussion of Review Question 11
Review Question 12
A number of complications arise from the fact that Java uses two bytes of memory to
represent a character, and most other programming languages use a single byte. In fact,
normally a ‘byte’ and a ‘character’ are equivalent. These complications could be
overcome if text files were written such that each character was two bytes and not one
(as Java requires). What would be the implications of this for a Java program?
A Java program would be able to read and write the ‘two-byte character’ text
files, but most other programs would not. If the data was only to be read by
the one program then that’s fine. However, one of the great advantages of the
‘plain text’ file format is that almost all computers understand it. This portability
would be lost if a program invented its own format for plain text files. However,
as time goes by more and more computer systems are starting to use two-
byte characters as the standard. Windows NT, for example, uses the same
UNICODE two-byte format that Java uses. So in the future a two-byte
character may become standard, and programs won’t have to make special
arrangements to convert one to the other.
Exceptions
Review Question 13
What are the main differences between subclasses of RunTimeException and
subclasses of Exception in Java?
Review Question 14
Review Question 15
The program is trying to throw a class. In fact an exception is an object of the specific
exception class. It should be written like this:
throw (FileNotFoundException);
Review Question 16
Why are Java exceptions organised as a hierarchy of classes, rather than simply as
direct subclasses of the Exception class?
The use of a class hierarchy allows the programmer to group the handling of
different types of exception together. This can make the program easier to
understand and manage. For example, it is quite likely that all the exceptions
that are subclasses of IOException will need to be handled in similar ways, so
they can usefully be handled as a class in some situations.
Review Question 17
If a programs throws an exception upwards, that is, ‘out of’ a method, where is it
‘caught’?
Discussion Topics
There are many new concepts in this unit. If you want to discuss with your colleagues or
make comments about the concepts to them, use the on-line facilities.
Java is probably the most widely-taught programming language in the World today. At
any one time at least a million people are studying Java programming. However, at the
time of writing very little commercial software is being developed in Java. This is in spite
of the fact that almost all of the most widely used pieces of software currently in use could
have been developed in Java, and their potential market would have been greater (owing
to Java’s portability).
What reasons might there be for the relatively slow uptake of Java in
the commercialsector?
Do you think that the current developments in Java (like the use of ‘just-in-time’
compilers and native code compilers) will make any difference to this?
Until there is a rise in e-commerce few commercial software systems will involve applet
programming. Therefore applets, which form one of the strengths of Java over other
languages, currently act as a motivation for commercial companies to use Java.
Companies invest resources (time, money, training) in their software systems and
software staff. Large systems are designed to be extensible and to be used for many
years, or even tens of years. Therefore even though a new system being written today
might be written in Java, most software work is on existing systems written in older
languages such as C, C++ and Visual Basic.
Just-in-time and native code compilers can, to some extent, improve the performance
limitations of Java. Although, like many object-oriented languages, features such as
dynamic binding (required to support polymorphism) will always carry a performance
overhead, since it means that some statements can never be compiled as efficiently as
for non-dynamic programming languages.
One of the most important limitations of Java applets is that they are not able to interact
with the user’s computer to any great extent. This greatly limits the usefulness of applets.
What is it about the way that applets are distributed that makes these security
restrictions important?
Applets are programs that users download from the internet and run on their local
computers. Were applets allowed to access the files and memory of the local computer,
the potential for malicious (e.g. viruses) and accidental (i.e. poorly written) software to
delete files and corrupt memory would be enormous.
However, these restrictions mean that applets are very limited in certain areas,
such as file handling.
There is no real way to relax such restrictions without risking problems. It would
be possible to safely use applets with file access facilities, for example, if a user
had, say, 2 computers, only one of which was connected to the internet. Then
the internet computer could be used to run applets and programs from non-
trusted sources, with physical separation from important files on the other
computer.
If software is coming from a trusted source, there is no need to restrict oneself to applets,
since a trusted source can be trusted to provide applications (with all their file handling
etc. features) that will not damage the user’s system.
In this unit we have described how a Java program could read a text file one line at a time
— this required four classes. We have also described how a text file can be read as if it
were an array of bytes, where any byte can be read at any position — this requires only
one class: RandomAccessFile.
Why do we need four classes to read a text file one line at a time, but only one
class to read it like a byte array?
Java does not treat files as a special case for input of data. Files are treated as a sub-
category of byte streams, which might be input from a mouse, keyboard etc.
The extra classes are required to process the byte stream data in terms of
representations meaningful for files (such as characters, not bytes, and
recognising end-of-line characters etc.).
While for some files, such as a graphics image, a file can be treated in some random
fashion, many files are sequential, and therefore separators (like end-of-line) needs to be
read in sequence and processed appropriately.
In your Learning Journal write up your experience of your learning on this unit. Say what
you thought was good or bad, what you had difficulty understanding, and how you
resolved your problems.
Additional Content
A technique often used by Java developers working on large software projects is to write
a main() method for every class they write. Each main() method creates one or more
instance objects of the class, sends the object(s) some message(s) and displays the
changing state of the object(s).
In this way each individual class can be tested in isolation. For large software systems
this can help reduce bugs, or mean that they are found earlier, since it can be very difficult
debugging a system with many objects from many class.
Although for the programs you are developing for this module you probably do not need
to test each class in isolation (since it almost as easy to debug programs containing only
2 or 3 classes), an example is given here to illustrate this technique.
Consider a simple applet to draw 2 triangles in its window. This applet makes use of a
class MyTriangle.
The writer of our applet has made the mistake of forgetting that the origin of Java graphics
is the top left (i.e. the smaller the Y co-ordinate the higher up the screen a point is). The
writer of this applet can test that their MyTriangle class works in isolation as follows:
import java.awt.*;
class MyTriangle
// variables
left = newX;
// draw() method
} // class
We can run the main method of the MyTriangle class using the java command:
Had the programmer used such a method, they might have remembered that for Java
graphics the bottom of the triangle has a larger Y value than the top, which explains why
the triangle is draw with the point to the top of the screen. Even if they cannot remember
that, at least they now know the values of the variables forming arguments for
thedrawLine() messages and so on.
import java.applet.Applet;
import java.awt.*;
// variables
t1.draw( g );
t2.draw( g );
} // class
So if there are 2 (or more classes) and each has a main() method, how does Java decide
which main() method to execute?
The answer is that Java will execute the main method in the class youprovide
to the run-time interpreter.
if there are several applications that have a main method, such as in client/server
applications. We will first run the application that is being used, then the second
application. The client program will attempt to access a server - use a server, therefore
the server program will run first.
Additional Activities
Study the listing of this program and answer the questions in it.
resultLabel.setText(e.toString());
in method actionPerformed(). It is not the first line of the following ‘catch’ block,
because this only
catches NumberFormatExceptions. The NegativeNotAllowedException is thrown out of
the method getFieldValue(), and picked up by:
catch (Exception e)
in actionPerformed().
The line indicated is inside a catch block that catches NumberFormatExceptions. The only
method that is called in the preceding try block is parseDouble(), so the exception must
come from there. If you look up parseDouble() in the on-line documentation, you will see
that it can indeed throw this exception.
Because we are catching Exceptions (not its subclasses), then this section will be
executed if any exception is thrown by a statement in the preceding try block, or was
thrown upwards by any of the methods called inside the try block. The only method
called inside the try is getFieldValue(), so a line inside getFieldValue() must have
been executed immediately before this point. You will see that getFieldValue() can
throw for different
exceptions: EmptyNumberFieldException, NotANumberException , NegativeNotAllowedExc
eption, andZeroNotAllowedException. The lines that throw these exceptions are the
ones that caused:
catch (Exception e)
to be activated.
Reflective Question 1
Reflective Question 2
Most of the Java classes concerned with handling files use the standard Java exception
handling scheme. However, the ‘File’ class uses a different scheme (as well). Use the
Java documentation to find out what it is and how it works. What implications does this
have for the programmer when using this class?
Reflective Question 3
If a method passes an exception upwards (that is, declares it as being thrown out of the
method), then the method that called the throwing method must itself catch the
exception. If this method in its turn throws the exception upwards, and all other methods
do the same, eventually we will reach the ‘top’ of the calling chain, and there will be
nowhere to ‘throw’ the exception. What will happen to the program then? Should the
compiler allow the programmer to define such a sequence of throws and, if so, what
happens when the exception reaches the ‘top’?
In practice and exception can be ‘thrown’ ‘out of the program’. For example, in a Java
application with a ‘main()’ method like this:
throws FileNotFoundException
the FileNotFoundException will be thrown out of the program. The standard behaviour
when this happens is to terminate the program with an error message. Java did not
have to be organised like this, but ‘main’ is a method like other methods. No method
within the program calls main(), so the compiler does not have the opportunity to check
whether the thrown exception is caught anywhere. To change this behaviour would
mean that ‘main()’ has to be treated differently to other methods.
Optional Discussion topics
If you wish to study Java exceptions in more detail you may wish to reflect upon the
following 3 optional discussion topics.
Topic 1 — Why treat arithmetic and file not found exceptions differently?
What reasons might there be for the Java developers’ imposing this distinction?
A Java program should check that the data entered by the user is basically
sound. For example, if asked to enter a person’s age, it is probably incorrect
to enter ‘Fred Bloggs’. This is probably a mistake on the part of the user. On
the other hand, if the user enters ‘200’ for a person’s age this is probably a
mistake as well, but it is much harder for the programmer to detect. To what
extent should the programmer anticipate these kinds of user error?
Why does a Java program throw objects of exception classes, rather than classes
themselves?
Answer this question in two ways:
You should work through this set of review questions. When you have
completed the questions you will be able to obtain the answers for future
reference.
Your performance with these questions will not affect your grade for the
module, but may be monitored so that your tutor can be alerted if you are
having difficulty.
Please contact your tutor if you feel you have not done as well as you
expected.
Now complete the end of unit review questions online.
Listing of DoNothing.java
/*
DoNothing.java
A stand-alone Java program that does nothing! This can be used as the outline
*/
import java.awt.*;
import java.awt.event.*;
/*
MainWindow
*/
public MainWindow()
super("Do-nothing program");
setSize(300, 300);
addWindowListener (this);
// do-nothing program
/*
windowClosing
*/
System.exit(0);
}
} // class
/////////////////////////////////////////////////////////////////////
/*
DoNothing
*/
mainWindow.setVisible(true);
Listing of CalculatorApp.java
/*
CalculatorApp.java
*/
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
/*
MainWindow
This class defines the main window for the application. It is
*/
public MainWindow()
super("Calculator");
setSize(300, 300);
addWindowListener (this);
// program
/*
windowClosing
*/
System.exit(0);
} // class
////////////////////////////////////////////////////////////////////////
/*==============================================================================
==============================================================================*/
// the user can be. A Java `double’ can store a value with a
//precision of
/*
Display modes
The variable `displayMode’ can take one of three values. For ease of reading
at all what the values of these constants are (I have used 0, 1 and 2), as
will either be the number being entered by the user (INPUT_MODE), the
the program. For example, if the user types a digit when the program is
should be cleared and the new digit put at the start. In fact,
many of the methods in this class behave differently according to the
value of displayMode
*/
// QUESTION: why have I defined constants for these values? In the program
int displayMode;
Label displayLabel;
// typed. This causes the next digit entered to be the start of a new number.
boolean clearOnNextDigit;
// lastNumber is the number that was entered by the user before the
// last operator.
// for example, if the user type `2’ followed by `+’, then lastNumber
//will be
// set to `2’
double lastNumber;
// `+’ sign (or clicks on the `+’ button), then lastOperator is set to
char lastOperator;
/*==============================================================================
Calculator constructor
This operator (as with all constructors) is executed when the new object
is created. In this case we create all the buttons (and the panels that
The layout of buttons in this Applet is quite complex. We have three groups
of buttons, one for digits, one for operators and one for `controls’
(`=‘, `AC’ and `C’). I’m not sure `controls’ is the right word here, but
layout manager. The job of the layout manager is to group the buttons in
the right order. For example, the button panel has a grid of buttons, with
7 8 9
4 5 6
1 2 3
. 0 +/-
So we set the layout manager for this panel to a new GridLayout object.
which means `create a new GridLayout with four rows of three columns’.
Having created the panels, we add the buttons. Finally we add all the
panels into a single panel (called `buttonPanel’) and add this to the
==============================================================================*/
public Calculator()
super();
buttonPanel.add(numberPanel);
buttonPanel.add(operatorPanel);
buttonPanel.add(controlPanel);
displayLabel.setAlignment(Label.CENTER);
add(displayLabel, "North");
displayResult(0);
add(buttonPanel);
addKeyListener(this);
requestFocus();
clearAll();
/*==============================================================================
setDisplayString
This method sets the text in the display area to the specified string.
it is called many many other methods, and using a method for this
have to be modified.
==============================================================================*/
void setDisplayString(String s)
displayLabel.setText(s);
/*==============================================================================
getDisplayString
This method gets the text currently in the display area. See the note for
==============================================================================*/
String getDisplayString ()
return displayLabel.getText();
}
/*==============================================================================
clearAll
Sets the state of the calculator to the `just switched on’ state, that is,
`0’ in the display, ready to input digits, and the last operator equal to
zero (that is, there is no last operator). This method is called by the
clicks on `AC’
==============================================================================*/
void clearAll()
setDisplayString("0");
lastOperator = 0;
lastNumber = 0;
displayMode = INPUT_MODE;
clearOnNextDigit = true;
/*==============================================================================
clearLastEntry
Clears the number currently in the display. This is called when the user
==============================================================================*/
void clearLastEntry()
setDisplayString("0");
clearOnNextDigit = true;
displayMode = INPUT_MODE;
/*==============================================================================
displayResult
Displays the specified number in the display area, and sets the variables to
indicate that a result is being displayed. Specifically this method sets
a digit, the display will be cleared to make space for a new number.
==============================================================================*/
setDisplayString(Double.toString(result));
lastNumber = result;
displayMode = RESULT_MODE;
clearOnNextDigit = true;
/*==============================================================================
displayError
Displays the specified error message in the display area, and sets the
as the user types a digit, the display will be cleared to make space
error message and not a number. This is important because the user might
press a button that modifies the current number (like `+/-’). Clearly
we can’t change the sign of an error message (or take its square root, etc).
==============================================================================*/
setDisplayString(errorMessage);
lastNumber = 0;
displayMode = ERROR_MODE;
clearOnNextDigit = true;
}
/*==============================================================================
addButtonToPanel
number of lines in the program (and therefore make it more convenient for the
a new button to the display. It sets the buttons colour, and sets the
key listener and action listener to the appropriate methods (this has
to be done for every button, as we can’t predict which button will have
==============================================================================*/
panel.add(button);
button.setBackground(backgroundColour);
button.addKeyListener(this);
button.addActionListener(this);
/*==============================================================================
actionPerformed
This method is called whenever the user clicks a button. This happens
every button. All this method does is pass on the text on the button to
`processButton’
==============================================================================*/
processButton(e.getActionCommand());
/*==============================================================================
processButton
This method takes action according to the user’s input. It is called from
keyPressed (when the user presses a key on the keyboard). This method
examines the text on the button (the argument `command’) and calls the
==============================================================================*/
if (command.equals("0")) addDigit(0);
if (command.equals("1")) addDigit(1);
if (command.equals("2")) addDigit(2);
if (command.equals("3")) addDigit(3);
if (command.equals("4")) addDigit(4);
if (command.equals("5")) addDigit(5);
if (command.equals("6")) addDigit(6);
if (command.equals("7")) addDigit(7);
if (command.equals("8")) addDigit(8);
if (command.equals("9")) addDigit(9);
if (command.equals(".")) addDecimalPoint();
if (command.equals("*")) processOperator(‘*’);
if(command.equals("-")) processOperator(‘-’);
if (command.equals("/")) processOperator(‘/’);
if (command.equals("+")) processOperator(‘+’);
if (command.equals("=")) processEquals();
if (command.equals("+/-")) processSignChange();
if (command.equals("AC")) clearAll();
if (command.equals("C")) clearLastEntry();
/*==============================================================================
getNumberInDisplay
Returns a double value indicating the number in the display. This method
should never be called if the display does not contain a number. When an
==============================================================================*/
double getNumberInDisplay()
return Double.parseDouble(input);
/*==============================================================================
processLastOperator
Carries out the arithmetic method specified by the last operator, the last
If the operator causes an error condition (i.e., the user tries to divide
==============================================================================*/
// QUESTION: if the user clicks on the buttons `2’, `+’ and `3’, what values
// variable `numberInDisplay’?
double result = 0;
switch (lastOperator)
case ‘*’:
result = lastNumber * numberInDisplay;
break;
case ‘+’:
break;
case ‘-’:
break;
case ‘/’:
if (numberInDisplay == 0)
break;
return result;
/*==============================================================================
processOperator
_last_ operator typed (not this one), and store this current variable
operator, or `=‘.
==============================================================================*/
if (displayMode != ERROR_MODE)
if (lastOperator != 0)
{
try
displayResult(result);
lastNumber = result;
catch (DivideByZeroException e)
displayError("Division by zero!");
else
lastNumber = numberInDisplay;
clearOnNextDigit = true;
lastOperator = op;
/*==============================================================================
processEquals
Deals with the user clicking the `=‘ button. This method finishes the
==============================================================================*/
void processEquals()
if (displayMode != ERROR_MODE)
{
try
displayResult(result);
catch (DivideByZeroException e)
displayError("Division by zero!");
lastOperator = 0;
/*==============================================================================
processSignChange
This method is called when the user clicks on the `+/-’ (sign change)
the number in the display is zero, nothing happens (as `-0’ is meaningless).
==============================================================================*/
// QUESTION: Why is this? Why does this method have to behave differently
// is quite a subtle problem. The program would work correctly most of the
void processSignChange()
{
if (displayMode == INPUT_MODE)
if (input.length() > 0)
if (input.indexOf("-") == 0)
setDisplayString(input.substring(1));
else
setDisplayString("-" + input);
if (numberInDisplay != 0)
displayResult(-numberInDisplay);
/*==============================================================================
addDigit
This method is called when the user clicks a digit button, or types a
digit key. If the number currently being entered is less than 17 digits long,
==============================================================================*/
if (clearOnNextDigit)
setDisplayString("");
// like `000’. If the number in the display is `0’, and the user
setDisplayString(inputString + digit);
displayMode = INPUT_MODE;
clearOnNextDigit = false;
/*==============================================================================
addDecimalPoint
Called when the user clicks on the decimal point button. Puts a decimal
point on the end of the number currently being entered. If the number
==============================================================================*/
void addDecimalPoint()
displayMode = INPUT_MODE;
if (clearOnNextDigit)
setDisplayString("");
// do anything to it.
if (inputString.indexOf(".") < 0)
}
/*==============================================================================
keyPressed
This method is called when the user presses a key, when any button has the
nothing.
==============================================================================*/
/*==============================================================================
keyReleased
Called automatically whenever the user presses and then releases a key. See
==============================================================================*/
/*==============================================================================
keyTyped
This method is called when the user presses a key, and then releases it
when any button has the input focus. This happens because the method
about.
This method converts the key press to the text of the corresponding button,
presses `enter’, this should have the same effect as clicking `=‘. So this
method calls `processButton’ with the text `=‘. If the user
presses `escape’ this should be treated the same as the `C’ button. All other
keys are treated as digits. If the user presses a letter rather than
==============================================================================*/
String command;
if (keyChar == KeyEvent.VK_ENTER)
else
processButton(command);
} // class
/*==============================================================================
DivideByZeroException class
This class is used to indicate that the user has tried to divide a number
==============================================================================*/
DivideByZeroException()
super("Divide by zero");
/*
CalculatorApp
*/
mainWindow.setVisible(true);
Listing of Loan.java
/*=======================================
Loan.java
This applet calculates the time it would take to repay a loan of money, when
back £100,000 every year, how long will it take to pay off the whole loan?
This applet calculate both these figures, from the user’s figures for
what units of currency are used, as long as you are consistent (i.e.,
the repayment amount and the amount borrowed are in the same currency).
<img src=loan.gif>
<p>
(If you aren’t looking at the HTML version of this file, you won’t see
the picture)
The user should enter the appropriate figures, then click on `Calculate’
1. The user may not fill all the data entry fields in
2. The user may enter values which are not numbers at all (e.g., text)
3. The user may enter values which are valid numbers, but are nonetheless
is less than the interest on the loan (then the loan will never be
repayed)
A good program will deal correctly with all these problems, and produce
You will notice that in this application approximately half the code
is concerned with checking and handling errors. But the good thing about the
exception throwing scheme is that the `normal’ program code and the
classes are all defined after the main part of the program
==============================================================================*/
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
/*==============================================================================
Loan class
==============================================================================*/
/*==============================================================================
==============================================================================*/
TextField amountBorrowedField;
TextField interestRateField;
TextField repaymentField;
// The result label is that part of the display where the result will be
// displayed
Label resultLabel;
/*==============================================================================
Loan constructor
This method (as with all constructors) is executed when the new object
is created.
The applet’s display area has three main parts; from top to bottom these
are: the result display, the data entry area, and the `calculate’
button. The data entry area has three text areas and the corresponding
will go in the centre of this area, the result area at the top
==============================================================================*/
public Loan()
super();
l.setAlignment (Label.RIGHT);
entryPanel.add(l);
entryPanel.add(amountBorrowedField);
l.setAlignment (Label.RIGHT);
entryPanel.add(l);
entryPanel.add(interestRateField);
l.setAlignment (Label.RIGHT);
entryPanel.add(l);
entryPanel.add(repaymentField);
setLayout(new BorderLayout());
add(entryPanel, "Center");
resultLabel.setAlignment(Label.CENTER);
add(resultLabel, "North");
calculateButton.addActionListener(this);
add(calculateButton , "South");
/*==============================================================================
getFieldValue
This method attempts to get a numerical value from a specified data entry
This method has three arguments. The first, `field’ is the data entry
field itself. This will have been created in the constructor with a
call to `new TextField()’. The second is the name of the field. This name will
be saved in the exception if anything goes wrong, so that the exception can
`zero’ as its value. In this application, the interest rate can meaningfully
==============================================================================*/
throws EmptyNumberFieldException,
NotANumberException,
NegativeNotAllowedException,
ZeroNotAllowedException
// First get the text value out of the data entry fieinto a
// String.
if (stringValue.equals(""))
try
// zeroNotAllowedException.
catch(NumberFormatException e)
/*==============================================================================
calculateNumberOfRepayments
amount, repayment and interest rate. Note that the final repayment may
not be of the full amount, as by this point there may be less money owing than
amount of the repayment is not large enough to pay the loan at all
==============================================================================*/
double repayment)
throws NeverRepayException
int repayments = 0;
repayments++;
// So the new balance becomes the input to the next cycle, and
sumOutstanding = newSumOutstanding;
return repayments;
/*==============================================================================
actionPerformed
This method is called whenever the user clicks a button. Since there is
only one button, and no menus, we can assume that when this method is
called, it is because the user has clicked `calculate’ and wants to calculate
a result
==============================================================================*/
try
// If we get this far, the values for amount borrowed, interest rate,
// and repayment amount have been entered, and they are basically
catch (Exception e)
/// QUESTION: there are four lines of prgram that could have been
resultLabel.setText(e.toString());
} // class
/*==============================================================================
This is the end of the `Loan’ class. We now define all the classes that
In general each of these classes only has two methods: a constructor and
constructor is used to set values for any of the data that will be stored in
==============================================================================*/
/*==============================================================================
NeverRepayException
the amount of the repayment is not large enought to pay off the loan in
==============================================================================*/
// constructor
NeverRepayException()
super("NeverRepayException");
// toString
} // class
/*==============================================================================
BadValueEnteredException
This is the base class for all the exceptions that are concerned with the
user entering invalid data values. Note that this is an abstract class; this
exception can never be thrown. The program must created one of the subclasses
of this class and throw that instead. This class is used for grouping the
==============================================================================*/
String fieldName;
String fieldValue;
// constructor
BadValueEnteredException(String _fieldName)
fieldName = _fieldName;
// constructor
fieldName = _fieldName;
fieldValue = _fieldValue;
} // class
/*==============================================================================
EmptyNumberFieldException
This exception is thrown if the user leaves a data entry field blank.
==============================================================================*/
// constructor
EmptyNumberFieldException(String fieldName)
super(fieldName);
// toString
} // class
/*==============================================================================
ZeroNotAllowedException
This exception is thrown when the user enters a value that is zero, and zero
of `0’, or to borrow `0’. Note, however, that `0’ is a credible value for the
interest rate
==============================================================================*/
// constructor
ZeroNotAllowedException(String fieldName)
super(fieldName);
}
// toString
} // class
/*==============================================================================
NegativeNotAllowedException
This exception is thrown when the user enters a value that is negative
In this program, it is not meaningful for any field to have a negative value
==============================================================================*/
// constructor
NegativeNotAllowedException(String fieldName)
super(fieldName);
// toString
} // class
/*==============================================================================
NotANumberException
==============================================================================*/
// constructor
super(fieldName, fieldValue);
// toString
} // class
Listing of WebMerge.java
/*
WebMerge.java
This program does not have a graphical user interface; it is so simple that
it does not need one. It is designed to be run from the command prompt, by
When used this way, the file `mysite.html’ will be treated as the `template’
file. This file will form the background for all the other files. Somewhere
in this should be the string `%%CONTENT%%’. This string will be replaced
a new set of file will be written, in a directory whose name is the same
as the template file. So the example above will write a new set of files
was specified in the template. In other words, the program looks for the
This program demonstrates two simple methods for managing data files in
In the operation `readFile’, the data file is read into a string one
these simple operations on files, that is, reading and writing fixed
*/
import java.io.*;
// command line, `args[1]’ is the second, and so on. In this program the
// user must specify at least two things: the template file and one file
if (args.length < 2)
{
System.err.println
("You are using this program incorrectly. You must specify the");
System.err.println
("template HTML file and the input HTML files on the command line");
System.exit(-1);
// In Java, a File object represents the name of a file or directory. When we need
/// QUESTION: what does it mean if `canRead’ returns the value `false’?
if (!templateFile.canRead())
System.exit(-1);
// The name for the new directory is given by the filename of the template file,
// with the `.html’ suffix stripped off. So we will inspect the filename to
// check that it ends in .html, and if it does make the directory name
if (htmlSuffixPosition < 0)
System.exit(-1);
/// QUESTION: what would happen if the user specied a filename like `fred.html.xyz’?
/// Would the program work, and what would the new directory end up being called?
String directoryName = new String
(templateFile.toString().substring(0, htmlSuffixPosition));
// If the directory has been created already, we don’t need to do anything (but
// Note that Java uses the same class `File’ to represent the name of either
// at file, or a directory.
/// QUESTION: is it possible to construct a new File object so that it’s name
if (directory.isDirectory())
else
if (directory.mkdir())
else
System.exit(-1);
// As we will use the data in the template many times (if the user specifies many
// files on the command line), we will read the data from that file into a
// String at this stage, and then work with the String. This means we only
// So now we will process the user-specified files, one at a time. The operation
/*
processFile
This operation takes the template file and one input file, and merges the
Parameters:
*/
String outputFilename)
if (!inputFile.canRead())
{
// This file can’t be read: no point to carrying on
+ inputFilename + "‘");
return;
// Get the text of the input file into a string for processing
/// QUESTION: suppose the input file were several megabyte long.
/// Do you think that reading the whole file into a string would
/// be sensible?
StrininputString = readFile(inputFile);
// Later we will want to write the new file to disk. Before we try
// can be written
+ outputFilename + "‘");
return;
// The `body’ is between the HTML tags `body’ and `/body’. If these
// tags can’t be found in the file, then take the whole file as
// input.
if (bodyTagPos >= 0)
{
bodyTagPos = inputString.indexOf(">");
// So now, `inputString’ contains the `body’ of the Web page. Now we look for
// the tag `%%CONTENT%%’ in the template, and replace this tag with the
if (templateTagPos < 0)
return;
// Make a new string that contains the template data up to `%%CONTNENT%%’, plus
// the `body’ of the input file, plus the remainer of the template file
+ inputString
+ templateString.substring(templateTagPos + 11);
/*
readFile
This operation reads a file and returns its contents as a string.
Paramters:
file The file object that contains the name of the file to read
Returns:
*/
try
s = s + (char)inputStream.read();
catch (FileNotFoundException e)
System.err.println(e.toString());
System.exit(-1);
catch (IOException e)
System.err.println(e.toString());
System.exit(-1);
}
return s;
/*
writeFile
Paramters:
file The file object that contains the name of the file to read
Returns:
otherwise
*/
try
outputStream.write(textBytes, 0, textBytes.length);
catch (IOException e)
return false;
return true;
}
Listing of Exception2.java
import javax.swing.*;
String ageString;
int age;
JOptionPane.QUESTION_MESSAGE);
try
catch (NumberFormatException n)
a valid integer");
System.exit(0);
} // class