Java GUI Programming - DOC

Document Sample
Java GUI Programming - DOC Powered By Docstoc
					                           COSC 2946 --- 05SF --- J. Rajnovich

Lecture #9: Monday, May 30, 2005

Topic: Java GUI Programming (1 of 2)

0) Questions?

1) Course Evaluation

2) Hand Back and Review Test #3

3) Preparing for Test #4

4) Basic Video Graphics Concepts

5) Images, Frames, Panels and Panes

6) Asynchronous (Threaded) Execution

7) Graphics User Interface Programming

(1) Course Evaluation

Thank you for your participation in the course evaluation.

(2) Review of Test #3

(3) Preparing for Test #4

30-minute test Wednesday, June 1, 9:15-9:45 p.m.

Closed book.

Based on all material presented in lectures one through eight, with an emphasis on lecture

In your test review, focus on:

      All definitions presented in lectures.
      Issues related to computer graphics in Java.
      Basic Java programming for elementary graphics application programs.

Expect questions formats from the following types:

      Reciting definitions
        Comparing (show how same) and contrasting (show how different) pairs of
        Drawing and labelling diagrams to help illustrate course concepts
        Writing short paragraphs to explain concepts.
        Writing very short Java programs or fragments.

(4) Basic Video Graphics Concepts


Pixel = picture element, the smallest visible unit which can be manipulated by a graphics

A pixel appears to the viewer as a single dot.

Each pixel has an assigned location in a 2D grid, with (for Java graphics) the upper left
corner of the screen (or of individual window panels) being coordinated (x=0,y=0).

The x-coordinate increases to the left, the y-coordinate increases downward.

Tristimulus Colour Theory

In tristimulus colour theory, visible colours are compositions of three primary colours, in
this case red, green and blue.

(There is a comparable CMY (cyan, magenta, yellow) ink scheme used by printers.)

Each pixel is assigned some colour and intensity value according to a 32-bit RGBA

Eight bits are associated with the „R‟ component to represent the intensity of the pure
colour red, with 255 being full intensity and 0 being none at all.

(The Java programmer may choose to specify the intensity with floating point values in
the range 1.0 to 0.0, but the video processor hardware still represents this in eight bits.)

Similarly eights bits each are associated with the „G‟ component for green and the „B‟
component for blue.

Combinations of these three values are capable of producing any one of more than 16
million colours visible to the human eye.

(As an aside, the human eye is capable of greater colour discrimination than this.

Amazingly, the tristimulus system does not in fact cover the full gamut of what the
human eye can perceive!)
The remaining eight bits, associated with the „A‟ component, often called the “Alpha
channel”, determine the extent to which a given pixel is transparent.

Alpha channel values range from 0 (fully transparent) to 255 (fully opaque).

Control over alpha channel values permits overlaid images to affect each other in various

As one example, this permits the graphics programmer to create a visible (glass) window
through which the viewer can see objects on the other side.

(5) Images, Frames, Panels and Panes

In the last lecture we learned how to create an application frame and install a panel in it.

We then learned the basics of 2D computer graphics, drawing primitive figures on the
panel in various colours and coordinate locations.

Today we start by learning how to fetch an already made image from a file and draw it on
an application panel.

Our first demonstration application, “”, is a simple extension of the test
driver for the graphics demos from last class.

The driver is responsible for instantiating a frame object and a panel object for this
application, adding the panel to the frame and ensuring that the resulting window and its
contents will be visible.

The important difference today is the call to a JPanel constructor in which we pass the
name of the file which contains the image we wish to draw.


Images can come from any source (eg. hand drawn, computer generated, scanned or
digitally photographed) so long as it is saved in a “.gif”, “.jpg” or “.png” file format.

The overloaded constructor can take either a String object representing the path/file name
or a URL object representing its general internet location.

As we learned from last class, the real work of the application is handled in an event-
driven fashion by the paintComponent() method of the JPanel object.

We now take a look at the file “” in which we implement a subclass of

After making the obligatory call to the parent class constructor, our constructor calls the
method java.awt.Graphics.createImage()(or the method
java.awt.Graphics.getImage()) to fetch the image from the disk file and
display it on the current panel.

(See the notes in the file itself for comments on why Sun recommends we use the latter
rather than the former.)

In OOP fashion, all the file handling details are hidden from the calling program.

Just pass the disk file name or url and “wait” for the results.

(The “wait” part is the most important part of today‟s lecture!

But we have to see the application in action before we can appreciate how important and
how subtle all this is.

So, we defer discussion of it until after discussing the actual drawing of the image.)

The work horse of this class is the overridden method paintComponent().

There are six overloaded versions of this method in java.awt.Graphics.

Here we examine the behaviour of only two of these.

The call to g.drawImage(image, 0, 0, this)paints the image data in its
original proportions on the available panel space.

As we can see from the constructor, the panel has been instantiated with preferred
dimensions of 20 pixels wide and 150 pixels height.

It happens that the image I have chosen is a digital photograph 3008 pixels wide by 2000
pixels high, far too large to fit the computer screen let alone the panel.

The alternative call to
                   0, 0,
scales the image as needed to fit the available panel space (200 x 150) and places it in the
upper left corner of that space.

This gives more satisfactory results, since we may now see the whole picture.
In addition, event-driven calls to paintComponent() now ensure that if the
application window is resized the picture will be rescaled to fit it.

(Be sure you understand why resizing the window also means that the panel is resized.)

Observe, however, that if the window/pane is resized in such a way that its aspect ratio
(width/height) no longer matches the aspect ratio of the original image (3008/2000 or
3/2) then the automatic scaling of the image will distort the picture.

(It is left as an exercise for you to find out how the Java graphics programmer might deal
with this.)

Finally, we need to understand why the reference to the calling JPanel object is passed
as the „this‟ parameter to this version of the method.

Asynchronous Execution

It is crucial to understand that the call to
java.awt.Graphics.createImage()initiates operating system calls involving
file input and system buffering which may take quite long to complete.

The method is designed to execute in an asynchronous fashion, meaning that it executes
as a separate thread (= an independent process).

This permits the rest of the program to continue execution.

In time the program will be informed when the asynchronous thread has completed its

In most cases the constructor will have terminated and the program continued its normal
execution long before the image is fully loaded.

We can actually see this when we run the demonstration program.

Watch carefully.

You will see the frame first appear along with a blank panel.

It will take a measurable number of seconds before the image appears.

In those first few seconds paintComponent() is called numerous times with no
image to display.

Eventually the image is fully loaded and ready for display.
How does paintComponent() get informed?

The answer is that the JPanel object „this‟ has been registered as an
ImageObserver object by having its reference passed in the fifth parameter position.

(ImageObserver is in the inheritance hierarchy of all Container objects such as
JFrame and JPanel.)

This means that when createImage() has completed its execution thread, it signals
the registered observer(s) that the image is now ready.

At this point paintComponent() can sample the image to find its properties such as
width and height.

Be clear that the calls to getWidth() and getHeight() in the parameter list of
paintComponent() are implicitly calls to this.getWidth() and

These calls inform paintComponent() how big the available panel space is.

The paint method uses these to scale the image to fit.

But the information as to how big the image itself is is not known until a signal is sent
asynchronously to the observer object, the panel itself.

In this test driver we verify this by sampling the return values for image.getWidth()
and image.getHeight() first at the time of the constructor call and later on each
event-driven call to paintComponent().

These methods return -1 as a way of indicating that the image is not yet fully loaded, so
its dimensions are not yet known.

Eventually we learn that the image is 3008 x 2000 pixels.

(6) Asynchronous (Threaded) Execution

A thread is any program unit that is executed independently of other parts of the

It is not possible to understand Java graphics, GUI programming or any other form of
event-driven programming without understanding the concept of threaded execution.

We‟ll look closely at this topic in future lectures.

Each panel object, for instance, is an independent thread.
As we shall see, an application may have multiple panels, each with its own
paintComponent() method.

Each of these threads executes concurrently (i.e. in parallel, or, at the same time),
responding to whatever event-driven messages are received specific to it.

Concurrent processes which execute strictly independently of each other are said to be
asynchronous; i.e. their action steps do not need to be timed or synchronized.

As we shall see in future lectures, it often necessary for threads to cooperate with each,
timing their execution steps so as not to interfere with each other.

Such threads are explicitly programmed to be synchronous.

Viewing Multiple Images

We now know the minimum Java programming to fetch an image from disk and display
it for the user, scaled to fit a panel of any desired size.

How might we display multiple images at the same time?

There are several approaches.

One is to create multiple frames, each with its own panel object to contain an image.

Another is to have one frame containing multiple panels, each with its one image.

Multiple Frames

The test driver file „‟ shows us how an application can generate
separate frames for each image.

Here we create two frames, give each one its own panel and request a different image for
each one.

Observe that in this driver we provide a String argument to each JFrame constructor to
give a title to each frame.

In addition, we set the default close operation for the first frame to be HIDE_ON_CLOSE
instead of EXIT_ON_CLOSE.

This is just for demonstration purposes.

You may experiment with all four of the options if you like.

See javax.swing.JFrame.setDefaultCloseOperation() for the details.

Be aware that the option EXIT_ON_CLOSE is to be used only for applications, not for

We won‟t spend further time on multiple frame applications, except to point out that
numerous interesting possibilities exist.

Keep in mind that each frame and its contents can execute as independent threads.

This means that interesting things can be implemented involving concurrent activities,
including both synchronous and asynchronous behaviour.

Further, observe that this test driver generates the second frame on top of the first one.

The user has to manually separate them before the first one is even visible.

It is possible to have the application place the frames wherever you might like on the
user‟s screen.

See Darwin‟s Recipe 14.11 for details (and be aware that some GUI platforms prefer you
do not take this kind of control of desktop layout).

Single Frame with Multiple Panels

Assignment #4 requires that you use a single frame containing not only multiple images,
but additional GUI objects such a buttons.

Test driver file “” demonstrates a way to contain multiple GUI
components in one frame.

In this case we use only panel objects.

But the stage is then set for full GUI (multi-component) applications.

The basic idea is that every JFrame object comes with two default containers called
panes, into which we may place any GUI components, includes panels.

The most commonly used pane is called the “content” pane.
(The other, called the “glass” pane, is used to do temporary painting of things over the
main pane.)

To create a pane we simply call the frame‟s setContentPane() method.

The method returns a reference to a generic Container class object.

Container c = frame.getContentPane() ;

As soon as we plan to have more than one visible object in a GUI container object, we
have to decide how they should be located in relation to each other.

AWT provides five predefined layout manager classes to help us with this crucial GUI

   1)   BorderLayout
   2)   CondLayout
   3)   FlowLayout
   4)   GridBagLayout
   5)   GridLayout

Here we‟ll use the simplest of these, FlowLayout.

c.setLayout( new FlowLayout() ) ;

We then create two panel objects add them to the pane.

c.add( panel_1 ) ;
c.add( panel_2 ) ;

Observe that in all these test driver programs, we are using the same panel class

Notice that if we maximize the application window the two panel objects/images are not
automatically resized to fill the new window space.

Our frame object resizes its content pane object, but the content pane is not synonymous
with its enclosed two panels.

If we want one or both of the panels to resize we now have to include explicit instructions
to support this.

This will require an understanding of events, event sources, event objects, event handlers
and event listeners.

This topic will engage us for the remainder of this course.
We now have the foundation concepts necessary to begin creating a GUI application with
a single frame and as many GUI components as we like.

We‟ll focus our investigation in the next lecture on the kinds of GUI objects which might
be useful for Assignment #5.

(6) GUI Programming Issues

Among the first useful GUI components we should add to our application are labels and

Adding labels and buttons to a container is very simple in Java.

Not so simple is understanding how to get GUI objects such as buttons to do something
useful in an event-driven environment.

We‟ll need to understand various “listener” classes, a topic which we will pursue in the
next lecture.

Another challenging task is learning how to arrange the various components of our GUI
application in an attractive and useful layout from the user‟s perspective.

How do we want our application to look to the user?

We need to think first about design issues, including ergonomics (the study of how to
design work environments which increase human operator effectiveness).

Then we have to find out how to exploit the layout manager classes provided by Java to
get the components arranged in a pleasing and effective way.

Shared By:
Jun Wang Jun Wang Dr
About Some of Those documents come from internet for research purpose,if you have the copyrights of one of them,tell me by mail you!