Chapter 9 -- The Order Entry System: Adding
Graphics and a Logo
Chapter 9
The Order Entry System: Adding
Graphics and a Logo
CONTENTS
Currently, some of the most exciting aspects of Java are those
dealing with graphics. This chapter covers these features. First,
this chapter covers the AWT Graphics
class, which allows you to implement many different graphical
items. These features involve drawing, displaying images, and
setting colors, among others. This chapter also discusses the
Canvas class, which is a
special type of component designed for use in dealing with graphics
in AWT programs. The Order Entry System is also extended in this
chapter as you include the concepts dealt with in this chapter
in the applet.
The AWT graphics class is an abstract class that is the basis
for all graphical constructions in Java. You cannot implement
this class directly. To utilize it, you must copy another instance
of the Graphics class or
have a component generate it. The Graphics
class enables you to drawLines,
implement boxes and 3-D boxes, use different fonts, and implement
different colors. A number of functions in the Graphics
class implement these capabilities.
You use the paint and update
methods to implement the features in the Graphics
class in your programs. You use the following code line to declare
the paint method:
public void paint(Graphics g) {
Note that the paint method
accepts one parameter, an instance of the Graphics
class. Here's what happens in the paint
method: Your paint method
is sent an instance of the Graphics
class, which defines the current status of the segment of the
display that your class is responsible for. Next, your paint
method modifies that state using the methods in the Graphics
class and those implemented in other classes. Then the Java runtime
modifies the display to eventually match those changes once the
execution of your paint method
is completed. Then the whole process begins again. Understanding
this process is key to writing your own paint
method. The paint method
is written to describe in code how the display area should look
at the program's current status.
Caution: |
One of the most important concepts about applying the graphical features of the AWT to your programs is that every time the paint method is executed, it does not imply that any changes in the display are immediately displayed. As you will see in
later chapters on multithreading, the display of changes is sometimes less important than other processes that are running in parallel to your applet.
|
The update and paint
methods are initially implemented in the Component
class of the AWT. The paint
declaration in the code of the Component
class is empty until you override it. The update
method, by default, resets many of the settings in the Graphics
instance you are using and then calls the paint
method. The times you override it include occasions on which you
want to change the way your displays are changed or in dealing
with canvases and animation.
To include the different primitives of the Graphics
class, be sure to import it into your program:
import java.awt.Graphics;
Note: |
You can implement the update and paint methods. However, you usually don't make any calls to them. There are instances in which you want to force a call to repaint a piece of display as soon as possible. This is discussed in the section
covering the repaint method in this chapter, "The repaint Method."
|
The GExampleApplet example
applet shown in Listing 9.1 demonstrates these ideas. The output
from this applet is Figure 9.1.
Figure 9.1. : The GExample Applet when viewed through the Applet Viewer utility.
Listing 9.1. The GExampleApplet
code listing.
import java.awt.*;
import java.applet.*;
public class GExampleApplet extends Applet {
public void paint(Graphics g) {
g.drawRect(10,
10, 100, 100);
}
}
In Listing 9.1, the applet life cycle control methods (init,
stop, and so on) are all
left as defaults. The default paint
method is overridden, and the new method includes code to draw
a rectangle on the applet panel using the drawRect
method included in the Graphics
class. The new paint method
gets called repeatedly, and the same rectangle gets drawn on the
screen. Complete coverage of the graphics primitives is a major
focus of this chapter.
Caution: |
This chapter does not cover every method available in the Graphics class. If you want a description and listing of all the methods available, check the source code:
SRC/JAVA/AWT/Graphics.java.
|
Note: |
Note that Java's coordinate system begins with 0,0 at the top left. The bottom-right corner of a screen segment of width and height 100 would be point (100,100).
|
Sometimes you want to demand that the Java runtime repaint a component
display as soon as possible. This is done through a call to the
repaint method in the Component
class.
Note: |
Remember, since almost all the visible pieces of the AWT, including applets, panels, and frames, are descendants of the Component class, when I talk about painting components, I am not just talking about buttons and scrollbars, but containers too.
|
There are a number of other types of calls to the repaint
method. For example, you can specify exactly how long you want
it to be before the component is painted again. You can also specify
what portion of the component display you want to be repainted
(very helpful in animations). For now, just know that a call to
the repaint() method of a
component makes sure that the display is updated. Simply insert
a repaint() call, and the
display update will be expedited by the Java interpreter executing
your code.
The following sections cover the multiple methods available in
the Graphics class and related
classes that are used to draw graphics.
The process of drawing graphical strings is very simple using
the AWT. It is also very versatile. You can specify the exact
size, font characteristics, and placement of the strings that
you draw onto your instance of Graphics
class.
The first step in drawing a string on a component is to set the
font specifics that you want. This is accomplished using the Font
class, which is part of the AWT package. For example, include
this code line to declare an instance of the Font
class representing the Courier font with an italic style and a
point size of 18:
Font afont = new Font("Courier",
Font.ITALIC, 18);
The first parameter sets the font that you want to use. Examples
of some of the available fonts are Helvetica, Courier, and TimesRoman.
Caution: |
Not every font is available on every system. On some systems, for example, Helvetica is not available. When the font is not available, Java reverts to a default font, which is generally Courier. It is wise to take this factor into consideration when
representing strings graphically since you can easily specify TimesRoman and end up with Courier on one machine and TimesRoman on another, both running the same Java code.
|
The second parameter of the Font
constructor describes the font constants, which define italics,
bold, and so on. These constants can be Font.ITALIC,
Font.BOLD, or Font.PLAIN.
You can also define a font to be both bold and italic by using
the sum of the two constants. To set the font to be both bold
and italic, send the second parameter in as Font.BOLD
+ Font.ITALIC. If you want the text to be plain, use
the Font.PLAIN constant as
your parameter.
The third parameter sets the point size of the font in pixels.
You must set the font you have constructed to be the current font
for the instance of the Graphics
class that controls the display you are going to add the string
to. To do this, use the setFont
method of the Graphics class.
The following line sets the current font of an instance of the
Graphics class called g
equal to the font you just declared:
g.setFont(afont);
To draw the string, you use the following line:
g.drawString("Leopards Aquatics",
10, 20);
The drawString method accepts
three parameters. The first parameter is a string representing
the text you want to draw, and the second and third parameters
describe the x and y pixel position of the string, respectively.
The following short applet demonstrates the inclusion of these
statements into a complete applet that draws the string onto the
applet face. The code is shown in Listing 9.2, and the resulting
display is shown as Figure 9.2.
Figure 9.2. : The output from the First draw string Example when viewed from the Appler Viewer utility.
Listing 9.2. The FirstDrawStringExample
applet code.
import java.awt.*;
import java.applet.*;
public class FirstDrawStringExample extends Applet {
private Font afont = new Font("Helvetica",
Font.BOLD, 18);
public void paint(Graphics g) {
g.setFont(afont);
g.drawString("Leopards
Aquatics", 10, 20);
}
}
In the FirstDrawStringExample,
note that an instance of the Font
class is first declared from the AWT package that handles font
business such as scaling and italicizing. Then, in the paint
method, the font is set to be the current font for the g
variable, which describes the data concerning the display area
you are dealing with. Finally, the drawString
method actually draws the string at x equals 10 pixels and y equals
10 pixels from the origin.
Table 9.1 lists some of the Font
methods that are available.
Table 9.1. Font
methods.
Method | Description
|
String getName()
| Returns the name of the font (Helvetica, and so on).
|
int getStyle()
| Returns the constant that is the style of the font.
|
boolean isPlain()
| true or false depending on whether the font is Font.PLAIN.
|
boolean isBold()
| true or false depending on whether the font is Font.BOLD.
|
boolean isItalic()
| true or false depending on whether the font is Font.ITALIC.
|
getFont()
| Returns an instance of the currently selected font.
|
Just as the Font class implements
methods and values to define the different fonts and settings,
the Color class in the AWT
package implements the ability to manage color in your programs.
There are two ways to specify a color in Java. The first way is
to specify the amount of the red, green, and blue components in
the color. These values range from 0 to 255 for each different
component. You should probably recognize this as the RGB color
scheme. Java uses a 24-bit color specification, which is called
True Color on some platforms. To create an instance of
the Color class while initially
setting the color in this manner, you can utilize the Color
constructor, which accepts three different integers. For example,
if you want to define a color to be slightly darker than pure
white, you can use the following line:
Color AColor = new Color (240, 240, 240);
In this code line, you are setting the red, green, and blue. Red
is first, green is second, and blue is third.
Note: |
There is actually a third Color constructor. It takes three float parameters that range from 0.0 to 1.0. It is basically the same as the preceding constructor, except the range per value is now 0.0 to 1.0 instead of 0 to 255. Neither method is
more accurate because the method utilizing floats (from 0.0 to 1.0) simply converts those values to integers and calls this first method that takes 0 to 255.
|
The second way to set a color is to use one of the colors defined
in the Color class itself.
For example, if you want to create white, you can use the following
line:
Color WhiteColor = new Color(Color.white);
Table 9.2 shows a listing of the different color constants available
in the Color class.
Table 9.2. The color constants available in the Color
class.
Color.white
|
Color.lightGray
|
Color.darkGray
|
Color.gray
|
Color.red
|
Color.pink
|
Color.orange
|
Color.yellow
|
Color.green
|
Color.magenta
|
Color.cyan
|
Color.blue
|
Two more methods, which can prove to be very useful, are available
in the Color class. One brighter
method returns a brighter version of the calling color. For instance,
if you want to brighten a Color
called AColor, you can use
the following line:
AColor = AColor.brighten();
There is also a similar method called darken
along with a number of less useful methods in the Color
class. For more information on these methods, check the source
code in the class library. However, it isn't likely you'll need
more than is described here.
Once you define a Color,
there are a number of ways to use it.
To set the current color that you want to draw with in your instance
of the Graphics class, you
can use the setColor method
in your paint function. This
method accepts an instance of the Color
class and sets the current drawing color to that color. You can
imagine this to be like changing drawing-pen colors. Once you
select setColor, everything
you draw until you set the color again is drawn in that color.
The default color is black. The following line sets the current
drawing color to pink:
g.setColor(new Color(Color.pink));
Besides setting the "pen" color, you can also set the
foreground and background colors for a component. These two methods
are setForeground and setBackground,
respectively. Call this method for a component, and the color
gets set to the value of the instance of the Color
class, which is sent in as the parameter. Note that these two
functions set the background and foreground for the entire component,
including graphics that are already drawn. If you draw some graphics
in black and then set the foreground color to green, the original
black drawing turns green.
The MegaColorExample explores
the color capabilities of the AWT and is shown in Listing 9.3.
The output is shown in Figure 9.3.
Figure 9.3. : The output from the Draw String Example applet.
Listing 9.3. The DrawStringExample
applet code.
import java.awt.*;
import java.applet.*;
public class DrawStringExample extends Applet {
private Font afont = new Font("Helvetica",
Font.BOLD, 18);
public void init() {
setBackground(Color.black);
}
public void paint(Graphics g) {
g.setColor(Color.green);
g.setFont(afont);
g.drawString("This
is krazee!", 10, 40);
}
}
In this applet, an instance of the Font
class is declared and constructed. Then the init
method takes care of initially setting the background color to
black. The code in the paint
method sets the current drawing color to be green. Then it sets
the current font to be the afont
variable and then draws the string on the applet panel itself.
Tip: |
You can utilize the drawBytes and drawChars methods in the Graphics class. They have limited uses, but for more information, check javasrcjavaawtGraphics.java included with your JDK.
|
In the preceding example applet, you had to guess where to place
the string on the panel. For example, centering the string on
the applet panel involves some serious measurement. But the AWT
provides a class that automates and simplifies this process. This
class is named FontMetrics
and is incredibly useful in simplifying the process of placing
graphical strings. It is highly useful in centering strings or
animating strings. Table 9.3 summarizes the methods available
in the named FontMetrics
class.
Table 9.3. FontMetrics
methods available.
Method | Description
|
int stringWidth(String)
| Computes and returns the width of a string in pixels.
|
int getAscent()
| Returns the number of pixels from the top of the uppercase characters to the original y.
|
int getDescent()
| The opposite of the getAscent function.
|
int getMaxAscent()
| The maximum ascent value of all the characters in the string.
|
int getMaxDescent()
| The maximum descent value of all the characters in the string.
|
int getHeight()
| This returns the total height (including ascent, descent, and so on) of the font.
|
These methods are straightforward. To use them, you need to declare
an instance of the FontMetrics
class in your applet. The following code segment declares an instance
of the FontMetrics class
and then sets it to return information about a font called AFont:
FontMetrics AFontMetrics = new FontMetrics(AFont);
The different methods listed are all yours for the calling. To
find the total height of your font using the declared AFontMetrics
class, use the following line:
AFontMetrics.getHeight();
Caution: |
Remember that the FontMetrics class is part of the AWT package, so make sure to import it into your program.
|
When you place lines of graphical text one after another, increment
by the getHeight() function
of the Font you are using.
To center a string, use this.size.height()
and this.size.width() to
find out how wide your component screen area is. Then compute
where to place your string based on this information and the width
of the string in pixels that you can get using the FontMetrics
class.
So far, this chapter has covered how to draw strings, do neat
things with them, and set colors. The following sections cover
the graphics primitives you expect in any toolkit. The java.awt.Graphics
class includes methods for drawing lines, arcs, polygons, rectangles,
and so on. These methods are included in the paint
method of your programs.
drawLine
drawLine is the basic graphical
primitive. It takes four parameters that are two (x, y) pairs.
To draw a line from (0, 10) to (50, 50) on a Graphics
g, you use the following line:
g.drawLine(0, 10, 50, 50);
The first two parameters are x1
and y1, respectively, and
the final two parameters are x2
and y2.
drawPolygon
The implementation of this function is just an extension of the
drawLine function. There
are three parameters: the first two are integer arrays and the
third is the number of points, n,
in the polygon. The first array contains the x1
through xn, and the
second contains y1 through
yn. The declaration
for the drawPolygon method
in this graphics class takes this format:
void drawPolygon(int x[], int y[], int
numprs) {
There is also a second way to draw polygons. It involves declaring
an instance of the Polygon
class and then adding your points to the variable one at a time.
The following code segment declares an instance of the Polygon
class, adds three points, and then sends the polygon to be drawn:
Polygon PGon = new Polygon();
PGon.add(1,2);
PGon.add(4,4);
PGon.add(30,30);
DrawPolygon(PGon);
Both versions work and do the same job.
drawArc
drawArc is used to draw arcs.
The arc drawn is specified by a bounding rectangle. It takes six
parameters: the starting x and starting y, the width and height
of the bounding rectangle, and the starting and finishing degree
positions of the arc. drawArc
takes the format
drawArc(int x, int y, int WidthofRect,
int HeightofRect, int StartDeg, int EndDeg) {
where x and y
specify the center of the arc, WidthofRect
and HeightofRect specify
one corner of the bounding rectangle of the arc, and the remaining
two parameters specify the beginning and ending degree positions
of the arc. A summary of the drawing primitives is shown in Table
9.4.
Table 9.4. The available drawing primitives.
Method | Description
|
drawRect(int x, int y,
int width, int height);
| This draws a rectangle. It accepts four parameters: the initial x and initial y, and the width and height of the rectangle.
|
drawOval(int x, int y,
int width, int height);
| This draws an oval whose center is (x, y), and the width and height specify the distance from the origin to the side of the bounding rectangle and the top of the bounding rectangle respectively.
|
drawRoundRect(int x, int x,
int width, int height,
in arcWidth, int arcHeight);
| This draws a rectangle with rounded corners. The parameters are the same as in the drawRect function except for the last two parameters. The arcWidth and arcHeight specify the bounding width and height for the
curved corners.
|
draw3DRect(int x,int y,
int width, int height,
boolean ThreeD);
| This is the same as the drawRect method except it adds a Boolean field that specifies that the box should be raised off of the panel if it is true.
|
ClearRect(int x, int y,
int width, int height)
| Draws an outlined, clear rectangle using the current background color.
|
Filling is as simple as it gets: for all these methods described
in the "Drawing" section, replace the word "draw"
with the word "fill" and you're ready to go. For example,
the following code draws a filled rectangle starting at 0,0 and
of width 15 and height 30:
g.fillRect(0, 0, 15, 30);
Again, to draw these same shapes filled with the current color
of the graphics, simply replace the word "draw" with
"fill." This also works fine with 3-D rectangles.
The AdrawingExample example
in Listing 9.4 incorporates some of these methods into an applet
that draws onto its main panel. The applet has a paint
method, which draws three different figures using the primitives
discussed. There is no action, no motion, so the values stay the
same in the paint method.
When the time comes for animation later in the book, the paint
method is the place where the work gets done. But for now, the
Java runtime calls paint
over and over, and draws the same image on the screen. The output
from the applet is shown in Figure 9.4.
Figure 9.4. : A drawing Example demonsrates the basic method to use the different drawing primitives in the AWT's Graphics classs.
Listing 9.4. The ADrawingExample applet code.
import java.awt.*;
import java.applet.*;
public class ADrawingExample extends Applet {
public void paint(Graphics g) {
// Draw a rectangle
starting at 10, 15 with a height of 100
// and a width
of 120.
g.drawRect(10,
15, 100, 120);
// Draw a 3D rectangle
starting at 150,15 with a height of
// 140 and a width
of 100.
// The arc width
is 15 and the arc height is 10 for the corners.
g.drawRoundRect(150,
15, 100, 140, 15, 10);
// Draw a filled
arc which is 75% filled: going from 0
// degrees to
270 and a bounding rectangle of 130 in
// width and 140
in height.
g.fillArc(280,
35, 130, 140, 10, 280);
}
}
Tip: |
Basically, the only tricky issue about using these methods is keeping your parameters straight. Two things can help you with this: have a reference such as this book handy to check your implementations, and print out the actual source code for the
Graphics package and refer to it.
|
Java allows different images to be imported and displayed. There
are a great multitude of types of image formats in the world today,
and a number of them are supported by Java.
The basic class for image storage is the Image
class. The Image class is
platform dependent. It is first implemented as abstract
and then fully coded in the classes that define the platform-specific
code. However, this isn't of concern to you since one of the principles
of object-oriented design is that you aren't interested in how
things get done, just that they do. You are guaranteed a certain
specification in the Image
and other library classes.
To declare an instance of the Image
class use the following line:
Image AnImage;
You should notice that there is no constructor to set up an instance
of the Image type. Instead,
you go about placing pictures into the Image
type through other methods while the construction is taken care
of for you.
There are a couple of methods available to load images into your
programs. The first method is specific to some components, and
it involves using the getImage
method and the getDocumentBase
method to place the image into the instance of Image.
The getImage function returns
an instance of the Image
class, which you then can set another instance equal to that value.
The getDocumentBase returns
the URL of the document that the applet is embedded in. You can
use the getCodeBase function
to return the position of your actual applet code if you want
to place your images in the same location as your applet code.
The following line gets an image called Spalding.gif,
which is found in the same directory as the applet class file:
AnImage = getImage(getDocumentBase(),
"Spalding.gif");
This is simple enough. The first parameter is a function that
defines the basis for where the image was found. It returns an
instance of the URL class
that defines an http address.
The second, of course, is the name of the image itself.
The second method involves the direct use of the Toolkit
class. The AWT Toolkit is used to bind with a platform-specific
implementation of the toolkit. It provides different functions
when using Images. This is
a more specific manner to specify how you will get the image.
To get an image using the toolkit, use the following declaration:
AnImage = Toolkit.getDefaultToolkit.getImage("Spalding.gif");
This statement accesses the default toolkit for a platform and
then calls that toolkit's getImage
function, which returns an instance of the Image
class. This class is then placed in the AnImage
variable. Note that the Toolkit
is abstractly implemented in the AWT and then completely implemented
in a local machine's platform-specific libraries.
Note: |
There are a number of other implementations of the getImage method in both of these areas. For more information, check the source code in the class libraries. These implementations, however, should suit you fine for most tasks.
|
Caution: |
You must use the toolkit to get images into your programs if you are creating an application. The first method is useful only with applets because Sun has incorporated the toolkit features into the applet class for simplicity.
|
Displaying instances of the Image
class after you have placed an image into them using one of the
above methods is simple. You will utilize the drawImage
function in the Graphic class
to paint your image onto the display. The following code line
tells a Graphics g
to draw AnImage image you
declared previously at coordinates (10,20):
g.drawImage(AnImage, 10, 20, this);
The first parameter is the image itself. The second and third
parameters are integers that specify the x and y coordinates.
The last one specifies an instance of ImageObserver,
which sets what object receives notification of happenings during
the loading and display process of the image. You learn more details
about the Java Image model in the upcoming section, "The
Java Model of Images." In this case, the this
keyword refers to the object in which this code is contained.
The applet example ImageExample
loads an image and then paints it onto the Applet panel, as shown
in Listing 9.5. The output is shown in Figure 9.5.
Figure 9.5. : The output from the Image Example applet, which loads an image and displays it on the applet panel.
Listing 9.5. The ImageExample applet code.
import java.awt.*;
import java.applet.*;
public class ImageExample extends Applet {
private Image MyImage;
public void init() {
// Load the image
called Spalding.gif into the MyImage variable.
MyImage = getImage(getDocumentBase(),
"Spalding.gif");
}
public void paint(Graphics g) {
// Paint the display
with our image.
g.drawImage(MyImage,
10, 20, this);
}
}
Table 9.5 summarizes the different implementations of the drawImage
method.
Table 9.5. drawImage methods available.
drawImage(Image img, int x, int y, Image Observer iob)
drawImage(Image img, int x, int y, int w, int h, ImageObserver iob)
drawImage(Image img, int x, int y, Color bgcolor, ImageObserver iob)
drawImage(Image img, int x, int y, Color bgcolor, int w, int h, ImageObserver
Âiob)
|
Variables | |
x: |
The x coordinate where the image will be placed.
|
y: |
The y coordinate where the image will be placed.
|
bgcolor:
| The background color onto which the image will be drawn.
|
w: |
The allocated width for the image display. |
h: |
The allocated height for the image display. |
iob: |
An instance of the ImageObserver class (explained in the next section).
|
If you do not provide the exact space that your image occupies originally, it is scaled to fit. So make sure that you provide the right dimensions. Otherwise, your images will likely be distorted by the scaling. The
ImageObserver in this method is notified only if the graphic is incomplete.
|
The Java Model of Images |
The Web presents a problem when dealing with images. There is a notable amount of time that your applet needs to wait for applets to download. You don't want people browsing your pages to leave because they have to wait too long to see an image. Java is
designed with this facet of networking in mind. The model of how its images are loaded is reflected in how it deals with images.
The model is based on interaction between three different pieces: the ImageProducer, the ImageObserver, and the ImageConsumer types. Image producers get images and then relate that image to the consumer. You don't need to worry
about exactly where they are because this consumer and producer process happens out of your view for the most part. Image observers are objects that have a stake in what's going on. They can be interested in whether an image is loading or is incomplete.
For example, the this keyword included as a parameter in earlier declarations specified the current object to be an image observer. You commonly see an observer set to be the current object by using the this keyword. Using this keyword
says that you want the current object to be notified if things are incomplete.
The process of handling these notifications is done through an ImageObserver interface included in applets and other containers. To find out exactly what has gone wrong, you access the returned flag to the interface and then compare that to the
constants held in the ImageObserver class. This isn't really as important as it sounds, but if you are interested, check the library source code to implement it for yourself.
|
Some Killer Reserved Words |
Here are some "killer" reserved words (powerful words) and their meanings:
finalize This says that you're finished with an instance of an object and you want the runtime to free the object's resources.
super A parent of a class.
super() The constructor of an immediate parent of a class.
this Refers to the current class.
|
Note: |
The MediaTracker is a utility class that allows you to manage and track the loading of media components including Images. This class uses the concept of threading. Threading is covered in Chapter 16,
"Multithreading with Java," and the class is described there.
|
All the graphical examples so far have been drawn onto the applet
panel. This has worked great, but Figure 9.6 shows what can happen
if components and graphics are combined in this way on the same
panel.
Figure 9.6. : The dangers of mixing components and graphics on the same panel.
Since you don't know where exactly each of your components will
end up, it is impossible to be sure that the graphics and components
don't conflict when your applet appears on different machines.
What is the solution? Well, Java has a component that is designed
to solve this problem: the Canvas
class.
Canvases are components that
are designed to be drawn upon just like an artist's canvas. You
can draw onto a canvas and insert it into another container or
your applet display itself. The Canvas
class has its own paint()
method, which handles what is drawn on the canvas face just as
with the Applet and Frame
classes. For this reason, Canvases
must be declared as classes separate from the class that displays
them.
Here are the steps to include a Canvas
in your applet:
- Inside your applet file, declare another class that extends
the Canvas class.
- Declare a public void paint(Graphics
g) method in the new class from Step 1.
- In the paint void from
Step 2, do whatever drawing or image displaying you want to do
onto the canvas.
- If you want to tell the Canvas
when to refresh immediately, have your other methods in the class
from Step 1 call the repaint
method when you want to do so.
- Declare an instance of your new class in your applet and add
it to your applet panel.
And then you're ready to go. The CanvasImageFiesta
applet is shown in Listing 9.6. It puts these steps into practice.
It also demonstrates the process of importing and displaying images
in the canvas. The resulting output is shown in Figure 9.7.
Figure 9.7. : The output from the canvases both the use of canases and the importation and display of images.
Listing 9.6. The CanvasImageFiesta applet code.
import java.awt.*;
import java.applet.*;
public class CanvasImageFiesta extends Applet {
public void init () {
// Typical button
delcaration here.
Button AButton
= new Button("Ack!");
add(AButton);
Image anImage
= getImage(getDocumentBase(), "Ian.gif");
// Declare and
setup the instance of the OurCanvas class
OurCanvas OC =
new OurCanvas(anImage);
add(OC);
}
}
class OurCanvas extends Canvas {
private Image AnImage;
OurCanvas (Image InImage) {
// We have
to set the size, otherwise it is invisible.
resize(250,200);
// Put the
image into the AnImage variable.
AnImage
= InImage;
}
public
void paint(Graphics g)
{
//
Draw the image on our canvas.
g.drawImage(AnImage,5,5,this);
}
}
So, what's going on? Well, first you do the normal applet stuff.
The init method creates a
button and also an instance of the class that you created that
extends the Canvas
class. You also load the image and then declare an instance of
the OurCanvas class.
In the second class, OurCanvas,
you override the default paint
method for the Canvas class
and create one that draws the image that you receive in the construction
of the instance. Then the image is painted on the screen.
Of course, you want to incorporate the concepts of Canvases
into the Order Entry System, but to what end? First, you should
complete the long-standing goal of adding a graphical logo to
the system. Also, it may be nice to add some sort of graphical
divider between the different sections of the applet panel. This
is accomplished through the use of the Canvas
class and the different methods available in the Graphics
class.
To add a logo to the Order Entry System, follow the steps outlined
previously in the section on Canvases.
First, declare a class that is an extension of the Canvas
class, as follows:
class LogoCanvas extends Canvas {
Notice that this is not a public class. In your applet file, the
only class declaration that should be public is the applet class
itself.
To do some setup in the new class, define a constructor for it.
This constructor accepts the logo, which is loaded in the applet
itself. It sets the accepted logo as the private LogoImage
variable local to this class. Then the canvas is resized to fit
the logo, as follows:
private Image
LogoImage;
LogoCanvas (Image LogoInCanvas) {
// Get the
image and place it in LogoImage. .
LogoImage
= LogoInCanvas;
// Resize
the canvas to fit the Logo exactly.
resize (425, 87);
}
Next, you create a paint
method in the class that handles the continual updating of the
display, as in the following code. The code inside the paint
method draws the image onto the current graphics.
public void paint(Graphics g) {
// Draw the logo on the canvas.
g.drawImage(LogoImage,0,0,this);
}
Now declare an instance of this class in the original applet and
call the constructor. Listing 9.7 shows the LogoCanvas
class that is constructed along with an applet to display it.
Figure 9.8 shows the resulting output.
Figure 9.8.: The Logo TestApplet when viewed from the Applet Viewer utility. This applet demonstrates the use of a convas to incorporate graphics into containers.
Listing 9.7. The LogoTestApplet applet code.
import java.awt.*;
import java.applet.*;
import java.net.*;
public class LogoTestApplet extends Applet {
// Declare our specialized canvas declared
below.
private LogoCanvas Logo;
public void init() {
setLayout(new
FlowLayout());
// Declare the
logo.
Image LogoInApplet
= getImage(getDocumentBase(), "OESLogo.gif");
// Construct the
new canvas. .
Logo = new
LogoCanvas(LogoInApplet);
// Add the logo
canvas to the applet face.
add(Logo);
}
}
class LogoCanvas extends Canvas {
private Image LogoImage;
LogoCanvas (Image LogoInCanvas) {
// Get the
image and place it in LogoImage. .
LogoImage
= LogoInCanvas;
// Resize
the canvas to fit the Logo exactly.
resize (425, 87);
}
public void paint(Graphics g) {
// Draw the logo
on the canvas.
g.drawImage(LogoImage,0,0,this);
}
}
One major improvement is to better divide the applet panel so
the interface is easier to use and less jumbled. Horizontal bars
can be used to improve the organization. To do this, create another
class that extends the Canvas
class and have it draw a horizontal bar the width of the applet
and also display a string label in the middle of the bar Figure
9.9 shows what a bar looks like.
Figure 9.9: A sample divider that this section will create.
The first step in creating the divider is to create another class
that displays the logo, as in the preceding section. Call the
class HorizBar, as follows:
class HorizBar extends Canvas {
Then make a constructor that accepts two parameters-the string
to display and the width of the bar-as follows:
private String
LineString;
private int Width;
HorizBar(String InString, int InWidth)
{
// Set the size
of the canvas.
resize(InWidth,
25);
// Set the local
variables equal to parameters so that
// we can use
the values in the paint method.
Width = InWidth;
LineString = InString;
}
Then create the paint method,
which the runtime can use to place what you want on the screen.
public void paint(Graphics
g) {
// Set the font
and font metrics class.
Font f = new Font("TimesRoman",
Font.BOLD, 16);
FontMetrics FM
= getFontMetrics(f);
g.setFont(f);
// Draw a line
from x = 0 to x = 15.
g.drawLine(0,
20, 15, 20);
// Draw the string.
g.drawString(LineString,
20, 20);
// Draw the rest
of the line.
g.drawLine(FM.stringWidth(LineString)
+ 25, 20, Width, 20);
}
Then use it in an applet, and you're ready to go. Figure 9.10
shows this code added to the preceding LogoTestApplet.
Figure 9.10: The LogoTestApplet with an instance of the divider class that was just added.
There aren't any kind of sound capabilities incorporated into
the Order Entry System. At the present time, the audio handling
and production capabilities of Java are very limited. However,
it is possible to load and play audio bytes. The only format that
is currently supported is the AU format, or µ-law.
Caution: |
These capabilities are very limited. There are no methods to manage or cut up clips. They also do not sound very good in terms of quality. For best results, you may want to use other means such as the browser's own sound production
capabilities.
|
Audio clips are stored using variables of the type AudioClip.
One function, play, is key
to playing AudioClips.
The play method has two forms:
play(URL u) and play(URL
u, String Filename). Both accept an instance of the
URL class that specifies
the location of the audio clip. The second function accepts the
URL plus the file name.
Note: |
Another method, getAudioClip(URL u, String Filename), returns an instance of the AudioClip class. You can use this to load an audio clip one time. Then you can enter MyAudioClip.play(); and it is played.
|
One final limitation of the audio in Java is that it cannot be
used with the MediaTracker
class discussed earlier in this chapter. Hopefully, in future
releases of Java, the MediaTracker
class will be extended to deal with audio. Expect further releases
of Java to include more capabilities in terms of audio, graphics,
and multimedia such as video.
As of now, the Order Entry System is about 300 lines of code,
and it would be a waste to make you suffer through reading a listing
again. The changes made, however, were listed in this chapter.
You have made some minor, though important, changes. First, you
added two different canvas types: one holding a logo and a second,
more generic, class that creates a labeled bar to better separate
the panel. Figure 9.11 shows the Order Entry System user interface
so far.
Figure 9.11: The Order Entry System including modification from this chapter.
The next chapter, "The Order Entry System: Exception Handling
and Browser Interaction," covers a couple of important concepts.
One of these concepts is Exceptions,
which are explored to see if they are useful in making the Order
Entry System more robust. Also, the next chapter uses more of
the applet features that allow interaction with the browser.
Next
Previous
Contents
|