|
SYS-CON.TV Webcasts
Comments
Did you read today's front page stories & breaking news?
SYS-CON.TV
|
Top Links You Must Click On
General Java Interactive Graphics-Based Applets
Interactive Graphics-Based Applets
Nov. 1, 1997 12:00 AM
This article will show you how to create an interactive, graphics-based applet by designing only the graphical objects themselves and by specifying their behavior given some external event (i.e., a mouse click or a button press). The ipl and ipl.graphics classes and interfaces will let you design with both notification and interfaces, in order to coordinate communication between your graphical objects and between the graphical objects and the display medium (i.e., a canvas object). This article will also show you how to "wire-up" your interactive applet to buttons in order to give the user control over your graphical objects. I will assume that you are familiar with the Observer-Observable design pattern of notification. The notification scheme used here is adopted from Code and Mayfield's "Java Design: Building Better Apps & Applets" (1997). The graphical object management scheme is adopted from Todd Sundsted's "HotSpot" object-oriented drawing program.
Introduction This article shows you how to create an interactive, graphics-based applet where you only need to design what your graphic objects will look like and how they will react to some external event (i.e., a mouse click or a GUI button press). It will do this by presenting a working interactive applet and then, step-by-step, exploring the class design and objects that support the applet. The article will explore package classes and interfaces (i.e., ipl.* and ipl.graphics.*) that will let you design with both notification and interfaces in order to coordinate communication between the graphical objects and between the graphical objects and a canvas object. This article will also show you how to "wire-up" an interactive applet to buttons in order to give users control over the graphical objects. Finally, the package classes and interfaces introduced in the article will provide support for basic computer graphics operations (e.g., object management, double buffering, detecting mouse events inside a complex graphical object). You will not only learn how to manage multiple graphics objects within a notification design scheme and how to make them responsive to external events (i.e., button and mouse events), you will also walk away with a package of classes and interfaces designed to support these capabilities.
Applet Specification
The idea is to let users manipulate the bottom comparison line in order to make it as long as the top standard line. As you can see, the applet will contain many graphical objects: 1) a graphical object that specifics and controls the standard line; 2) one that specifies and controls the comparison line; and 3) two objects that control the standard line's and comparison line's arrowheads. Moreover, these graphical objects will behave in specific ways depending on the occurrence of certain external events. Specifically, we want:
Observer-Observable Notification Design Pattern
The ipl.graphics.Shape Class When you create a graphical object, you will need to decide what it will look like and how it will react to an external event (i.e., a mouse event or a button event). For example, the StandardLineShape class extends the ipl.graphics.Shape class. The constructor initializes the graphical object (i.e., it defines a data structure and assigns initial values - note that ipl.graphics.LineSegment is a very useful data structure for line-based graphics). In the StandardLineShape constructor you may have noticed the RegisterObject. This object is not part of the ipl.graphics package, but it is a useful device for letting the graphical objects be "aware of" other graphical objects. The StandardLineShape's constructor, "registers" the left and right end points of the standard line with the RegisterObject. In this way, as we will see shortly, the arrowheads of the standard line (themselves a separate graphic object) will use the RegisterObject to position themselves on each end of the standard line. Next, you will need to define ipl.graphics.Shape's drawMe method to specify what your graphics object will look like. A canvas object - which we will examine in a moment - will call this method whenever the canvas needs to be updated. The drawMe method will receive from the canvas a Graphics object (actually a handle to an off screen buffer, but you need not concern yourself with that). For example, StandardLineShape's drawMe method specifies what the standard line looks like. (Note: in StandardLineShape's drawMe method, you saw a call to the ToDisplaySpace. This method is defined in the abstract ipl.graphics.Shape class. Typically, when you design your graphical object, you will often build it in a coordinate system that assumes an origin in the left hand bottom corner of a canvas component. I call this "model space." However, when dealing with a canvas object, just the opposite is true! I call the canvas coordinate system "display space." By using ToDisplaySpace, you can build and maintain your model or graphical object in model space, but when it comes time to display your graphical object, just transform the model y-coordinates to display space coordinates using this method). Once your graphics object is defined, you need to instantiate it in your main applet and tell it how big your canvas area is. Listing 1 is a snippet from the constructor of the main IllusionApplet applet. The ipl.graphics.Display, ipl.IObserver Interface and ipl.graphics.ShapeMrg Classes By now you've probably noticed that the StandardLineShape is not an Observable object. This is because it never changes and thus, it never needs to notify the Display object of a change. Nevertheless, when the Display object gets the call to update itself, it will use the ShapeMrg to access all of graphical object's drawMe methods. In this way, StandardLineShape's drawMe will get called, and that shape will be drawn on the canvas. Below we will see how to make a class that extends the Shape object an Observable object and how such an object "notifies" the Display object given a change.
The ipl.IObservable Interface When you implement the IObservable interface, you will need to define the three methods in Table 2. So, how do you define these methods? Easy! Just use the code in Listing 2 in any Shape object that implements this interface. The ipl.ObservableComponent object simply maintains a vector of observer objects--don't worry about this object, just instantiate it in your Observable object and use the code in Listing 2 as is. Bounding Areas - Defining areas of "activation" where users will interact with your graphical objects Recall that we want to detect a mouse down event on either end of the standard line (where the standard arrowheads will be attached). To do this, we can use the ipl.graphics.BoundingArea to create an "active" area on the canvas that will signal a mouse event. (While the bounding areas used in this applet are quite straightforward, the virtue of this object is that just about any complex bounding area can be created with a sufficient number of straight lines. The BoundingArea object has methods to detect whether or not a mouse event occurred within or on just about any boundary area that you create. Specifically, we are going to define two square areas (each side 10 pixels wide) and position them such that they are centered on each endpoint of the standard line (see Figure 2). The private method createBoundingArea, in the StdArrowHeadShape class defines two boundary areas (i.e., baLeft and baRight). The Display object will detect all mouse events. It will pass the event along to the ShapeMrg object which will call the public void mouseDetect method of each graphical (i.e., Shape) object. Each graphical object then decides what to do with the event. The StandardLineShape graphical object will simply ignore the event. However, the mouseDetect method of the StdArrowHeadShape graphical object needs to toggle its arrowheads on and off--note that the call to getActivation in the mouseDetect method is defined in the abstract Shape class. After the StdArrowHeadShape object detects a mouse down event in either area of activation, it notifies the Display object that it has changed. The Display object then calls the drawMe method of each Shape object that implements the Observable interface. StdArrowHeadShape's drawMe method toggles the arrowheads on and off. How do we let the StdArrowHeadShape object know that the Display object will be its observer? This is done in the main applet. In the main applet, the addIObserver method of the StdArrowHeadShape object called with the Display object as an argument.
The ipl.IRepeat interface So, the Display object will observe the CmpArrowHeadShape object to see if there is any change. Again, how do we let the CmpArrowHeadShape object know that the Display object will be its observer? This is done in the main IllusionApplet class. In the main applet, the addIObserver method of the CmpArrowHeadShape object called with the Display object as an argument. But when do the comparison line arrowheads change? When the comparison line itself either increases or decreases, or changes its vertical position. The object that defines the comparison line, the ComparisonLineShape object, builds the comparison line graphical object in much the same way as the StandardLineShape builds the standard line graphical object. Like the standard line object, it too is an observable object, but its observer is the CmpArrowHeadShape object, not the Display object. When the comparison line object changes, it notifies the CmpArrowHeadShape object. The CmpArrowHeadShape object then changes the position of the arrowheads, and then it notifies the Display object that there has been a change in the display. In the main IllusionApplet class, we tell the ComparisonLineShape object that its observer is the CmpArrowHeadShape object by calling the addIObserver method of the ComparisonLineShape object and sending it the CmpArrowHeadShape object as an argument.
External Button Control and The Comparison Line
Conclusion With these package classes and interfaces, along with the visual illusion applet classes as a tutorial, you can now design interactive applets where the only code you provide is what your graphic objects will look like and how they will interact with each other and the user. Bon courage! The class names for the interactive Muller-Lyer applet are shown in Table 3. In addition, thepackage classand interface names are shown in Table 4.
References Reader Feedback: Page 1 of 1
Enterprise Open Source Magazine Latest Stories . . .
Subscribe to the World's Most Powerful Newsletters
Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
|
SYS-CON Featured Whitepapers
Most Read This Week |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||