16 August 2000
Simon Gronlund is earning his Master of Science in Computer Science at the Royal Institute of Technology, Sweden, as an adult student. He also teaches Java and computer-related courses on a senior high school level. When he isn't tampering with his Warp 4 PC, he spends his spare time with his two boys and his wife.
If you have a comment about the content of this article, please feel free to vent in the OS/2 eZine discussion forums
Into Java, Part 8
Welcome back to this eighth installment
of this Java column. I wouldn't have mentioned how lovely Swedish summers can be
since this summer seems to be one of the most rainy summers within living memory.
The Event Model
As stated the previous month, every
time we would like to use graphical objects, like buttons, menus or alike, we will
treat them as sources or originators of events. Java handles these events by instantiating
Event objects reflecting the action that took place. Clicking a button will cause
an ActionEvent to be created. And these actors will be built automatically by the
There are three ways to get in touch
with the classes of Java:
Upon compiling, the import lines
instructs the compiler where to look for the classes we refer to and are using.
The JDK compiler (javac) and most other, but not all, Java compilers searches several
possible directories to find the class we are referring to. Normally the compiler
starts to search the JDK environment, more exactly the
classes.zip located by the
CLASSPATH environment variable of your system. Within that zip-file the compiler
tries possible directories that the import statements implies, whether the directories
exist or not. Then the compiler continues with every possible path set by the CLASSPATH,
like swingall.jar and
others. Finally the compiler concatenates the current directory (.) with the import statements and tries to
find what it looks for.
The only package we never need to
import is java.lang that
is always searched, treated as the universal package and the origin of all beings
found in the community of Java.
In a future column we will discuss
what exactly is a package, until then we may know them as a group of classes, or
a collection of classes. The personnel at SUN have neatly structured the many classes
in packages reflecting the purpose of the classes, i.e.
java.io, java.net, etc.
Whenever you start creating your splendid Java tools yourself you may collect them
into a directory that will be your package.
To that we add the promise of implementing
the method(s) of the interface ActionListener. Looking java.awt.event.ActionListener
up we will find that only
one method was asked for, namely public void actionPerformed(ActionEvent
e). So, later we will see
to it and implement such a method. If we distrust ourselves we might add the method
right away as an empty method.
We declare the image file names as
variables as well. That will mainly remind us of the good habit of grouping information
that we may change later on among the variables. In fact that will not increase
the memory usage since only one object is made, but references to it are used. This
time we can assume that the image file names will change over time. Furthermore,
never hesitate using these long but descriptive variable names. In spite of the
abundant typing you will save time from looking up those clever but so-hard-to-remember
abbreviations and acronyms people love to use.
Toolkit is found in java.awt which
implies that it is a class handling user interfaces, painting graphics or images.
The Java API tells us that "subclasses of Toolkit
are used to bind the various
components to particular native toolkit implementations. ... The methods defined
by Toolkit are
the "glue" that joins the platform-independent classes... ."
The purport of this is that a toolkit acts as a channel, or "glue",
to the system-dependent information we would like to query or system-dependent resources
we would like to use. Hence we get ourselves the reference
tk that will give us access
to the system you are running, that may differ from your neighbor's system.
Dimension simply encapsulates
the width and height of a component (in integer precision) in a single object. There
is not much to tell about it except that it may only be used together with java.awt.Component and
its subclasses. Not to forget that the width and height are public variables and hence need no accessor
methods, you query them directly as the code shows.
How to compute the position of a
frame to put it at the middle of a screen? As seen we subtract the size of the frame
from the dimension of the screen and then halve the result. (If your frame size
is not known to you at this moment you may use the method
public Dimension getSize() and
maybe put these lines at the end of the constructor.) Since we declared w and h as integers
the result of the division will always be truncated down to closest integer upon
assigning them, that is one pixel at most.
For any possibility, test that w and h will not
be negative. Robust and sound code will always do such tests, how weird they may
seem there is always a user more weird anyway. Finally, we set the location of the
frame with the now safe values.
The latter part of the constructor
is well known to us, we add an adapter as a listener to the frame and override one
of its empty methods. But the next line, what does it say?
We know the sense of the former part
of the last line. But we have added a call to a method,
makeContent(), that seems
to be added to the contents pane. Yes, that is correct! Usually we move out as much
code as possible from the constructor to make it more readable, and that code lifted
out will be placed in a helper method such as makeContent(). This technique is especially useful when
there are plenty of panels and GUI components, each of these components may be constructed
in a method of its own. Another profit is that it will be a lot more easy to maintain
and rebuild the components.
Adding the panel at the "Center"
will be discussed next time, when we will look at layout managers. Until then you
may try to change the "North" parameter used the former month (FirstButtonFrame)
to "Center" or the other cardinal points. As you noticed then the background
color did not fill the entire area of the frame. Why? What is the result if you
change this parameter?
Finally we disable the right
button, as the application in use will show us why. Recall that
false is a basic data type,
a boolean. It is very common that only one method is used, such as
setEnabled, with boolean true or false sent
as parameter. The opposite would be two methods, a setEnabled()
setDisabled(), which is
A new touch is the convenient "flyover
help" that will guide new users of this splendid and complex application around.
Recall that this helper method was
supposed to return a Container, a superclass to many kind of graphical components
used in a Java application. The signature of this method is
private Container makeContent(),
hence we have to return the panel we made. Such helper methods are, as said, commonly
used and they more or less always follow this style. Imagine this app having several
such panels, how lengthy the constructor would become if no helper methods are used,
now only one line each container is necessary.
Next time we will use some more items
from Swing, discuss some OOP concepts that are essential to know about, have a look
at layout managers, how they work and what shortcuts there are and look at the Graphics
class. Now I hope that the rain will stop and tomorrow will be a sunny day. See
you next month.