Comments
Richard Davies wrote: The UK has a good crop of technology pioneers in cloud computing - for example ElasticHosts, FlexiScale, Flexiant, OnApp - and also some strong government initiatives such as G-Cloud. We will have to see whether this kind of technical leadership converts into swift mass-market adoption or not.
Cloud Expo on Google News


2008 West
DIAMOND SPONSOR:
Data Direct
SOA, WOA and Cloud Computing: The New Frontier for Data Services
PLATINUM SPONSORS:
Red Hat
The Opening of Virtualization
GOLD SPONSORS:
Appsense
User Environment Management – The Third Layer of the Desktop
Cordys
Cloud Computing for Business Agility
EMC
CMIS: A Multi-Vendor Proposal for a Service-Based Content Management Interoperability Standard
Freedom OSS
Practical SOA” Max Yankelevich
Intel
Architecting an Enterprise Service Router (ESR) – A Cost-Effective Way to Scale SOA Across the Enterprise
Sensedia
Return on Assests: Bringing Visibility to your SOA Strategy
Symantec
Managing Hybrid Endpoint Environments
VMWare
Game-Changing Technology for Enterprise Clouds and Applications
Click For 2008 West
Event Webcasts

2008 West
PLATINUM SPONSORS:
Appcelerator
Get ‘Rich’ Quick: Rapid Prototyping for RIA with ZERO Server Code
Keynote Systems
Designing for and Managing Performance in the New Frontier of Rich Internet Applications
GOLD SPONSORS:
ICEsoft
How Can AJAX Improve Homeland Security?
Isomorphic
Beyond Widgets: What a RIA Platform Should Offer
Oracle
REAs: Rich Enterprise Applications
Click For 2008 Event Webcasts
SYS-CON.TV
Top Links You Must Click On


Interactive Graphics-Based Applets
Interactive Graphics-Based Applets

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
Writing interactive, graphics-based applets requires, at a minimum, creating both graphic objects and a display object. More work is required if you want to implement double buffering to eliminate flashing and if you want to implement some sort of notification scheme, because a change in one graphical object will require a change in another graphical object. Furthermore, keeping track of many graphical objects usually requires the implementation of some sort of a management scheme.

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
We are going to create an applet that will let users explore a visual illusion known as MŸller-Lyer (see Figure 1).

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:

  • the two standard line arrowheads to toggle on and off if a mouse down event is detected near either end of the standard line
  • the two comparison line arrowheads to toggle on and off if a mouse down event is detected near either end of the comparison line
  • the comparison line to change its length in response to a set of buttons
  • the two comparison line arrowheads to change the angle in response to a set of buttons
  • the comparison line to turn green if it is equal in length to the standard line or red if it is not
  • the comparison line to move up and down when "dragged" by a mouse
  • the comparison line to reset to a "random" length in response to a button

    Observer-Observable Notification Design Pattern
    The above interactivity is achieved through the creation of Observer and Observable objects. Most of your graphical objects will be observable objects. A canvas object will be an observer object. This observer object will "observe" the graphical objects (i.e., "observable" objects). As each graphical object responds to external events (i.e., the mouse, a GUI button), they will change themselves and then "notify" the canvas object that it must update (re-draw all the graphical objects) to reflect the change.

    The ipl.graphics.Shape Class
    The first thing you will do is design your graphical objects, how they will look and how they will act. All graphic objects will be an extension of an abstract ipl.graphics.Shape class. Therefore, you will need to define the methods in Table 1.

    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
    At this point, you need to understand two ipl.graphics classes and an interface. The first, ipl.graphics.Display, handles all double buffering to avoid any flicker and it calls the drawMe method of each graphical object. (It is sensitive to mouse events because it uses an event listener, ipl.graphics.DisplayListener). It also implements the ipl.IObserver interface, which means it is the observer for all the observables (i.e., the graphical objects). Observables notify observers if they change. The second class, ipl.graphics.ShapeMrg, simply maintains a vector of Shape objects (The ShapeMrg object also passes mouse events and external button events along to all the graphical objects. You'll read more about this below). While these objects sound complicated, all you need to do in your main applet is instantiate them. Specifically, after you create all your graphical objects, simply hand them off to the ShapeMrg object. After that, instantiate the Display object (providing the desired width and height for the canvas), and hand the ShapeMrg off to the Display object.

    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
    The StdArrowHeadShape class extends the abstract Shape class and implements the ipl.IObservable interface. Recall that we want to toggle the arrowheads on and off if a mouse down event is detected near either end of the standard line (which is where the arrowheads are attached). If the arrowheads are visible and if a mouse down event is detected near either end of the standard line, the StdArrowHeadShape object must "turn off" its arrowhead and then inform the canvas object that a change has occurred and that the display must be updated. In order for this to happen, StdArrowHeadShape must implement the 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
    Whenever the "Increase line" or "Decrease line" button is pressed, not only will the comparison line change its length, its arrowheads will change their location in the display. This means that the comparison line object must notify NOT the Display object, but rather it needs to notify the comparison line arrowheads object! This object (CmpArrowHeadShape) then repositions the arrowheads and then the CmpArrowHeadShape object notifies the Display object. The ipl.IRepeat interface is used to make sure that the applet is not updated until ALL the graphical objects have changed themselves. In short, by implementing the ipl.IRepeat interface, the CmpArrowHeadShape object is both an Observable and an Observer. So how do you implement the methods of this interface? Easy! Just use the code in Listing 3 in any Shape class that implements this interface (see CmpArrowHeadShape class).

    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
    The ComparisonLineShape object will respond to both a mouse and an external button. The external button that controls the length of the comparison line is an independent applet (LengthButtonApplet), and it uses the standard applet-to-applet communication mechanism provided by Java to establish communication with your main applet. I'll assume that you know about this technique so I won't go into it here. If a mouse event is detected by a button applet, it will contact the main IllusionApplet applet by calling a ButtonDetect method in the main IllusionApplet. The main IllusionApplet then passes the button label to the ShapeMrg object. The ShapeMrg object dispatches the button label to all the graphical objects. A graphical object then either responds the button event, changes itself and notifies the Display object, or it ignores the event. Note that all the other buttons work similarly. So how does the ComparisonLineShape object receive the button event? Through the implement abstract Shape method buttonDetect.

    Conclusion
    The package classes and interfaces reviewed in this article facilitate the construction of interactive graphics based applets by:

  • incorporating the notification design pattern by using observable and observer objects in order to coordinate and control dynamic interaction between the graphical objects
  • incorporating objects that define areas of activation in your graphic objects and the means of detecting mouse activity in those areas
  • incorporating a canvas object that uses double buffering to eliminate flicker and a manager to keep track of your graphics objects

    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
    1. IObservable, IObserver and IRepeat interface from Java Design: Building Better Apps & Applets by P. Coad & M. Mayfield, Yourdon Press Computer Series, Prentice Hall, 1997.
    2. Public Point intersect(LineSegment Line 1 and line 2) method in the Toolbox class from "Faster LIne Segment Intersection" by Franklin Antonio from Graphics Gems, Academic Press, 1990.
    3. Public pointUsOnLineSegement in the LineSegment Class from "A Fast 2D Point-On-Line Test" by Alan Paeth from Graphics Gems, Academic Press, 1990.

    About Christopher Currie
    Christopher Currie is a doctoral candidate in the Experimental Psychology
    Program, Human Perception and Performance Group in the Beckman Institute For Advanced Science and Technology at the University of Illinois, Urbana-Champaign. In addition to his research involving eye-movements and scene perception, he is involved in a Web-based project designed to provide laboratory experience to complement psychology lecture courses and to educate the general public about sensation, perception and cognition. Support of the development of the package classes presented in this article was provided by the "Internet Psychology Laboratory" project (http://kahuna.psych.uiuc.edu/ipl2) and the University of Illinois at Urbana-Champaign

  • In order to post a comment you need to be registered and logged in.

    Register | Sign-in

    Reader Feedback: Page 1 of 1

    Enterprise Open Source Magazine Latest Stories . . .
    Apache Deltacloud, the Red Hat-contributed ReSTful API that abstracts differences between clouds so services on any cloud can be managed – provided of course there’s a driver – has graduated from the Apache Foundation’s incubator and is now a full-fledged Top-Level Project (TLP). The...
    With Cloud Expo 2012 New York (10th Cloud Expo) just four months away, what better time to start introducing you in greater detail to the distinguished individuals in our incredible Speaker Faculty for the technical and strategy sessions at the conference... We have technical and st...
    AMD said late Tuesday that its chief sales officer Emilio Ghilardi had left the company and that CEO and president Rory Read is going to do his job while a replacement is sought. AMD didn’t say why Ghilardi left but it’s assumed Read wants his own people. Read is relatively new to th...
    During the lifespan of M3 (Monitis Monitor Manager) there has always been something lacking – timers. M3 execution procedure was outlined in this previous article. The execution mentioned in the latter was a one-time-execution, whereas server monitoring requires periodic invocati...
    Red Hat is putting its bought-in Gluster scale-out NAS storage technology, acquired in October, on the Amazon cloud. It’s styled Red Hat Virtual Storage Appliance for Amazon Web Services and other clouds are supposed to follow in short order.
    A new episode of the screencast series is now available at the OpenNebula YouTube Channel. This screencast demonstrates the new easily-customizable self-service portal for cloud consumers. Its aim is to offer a simplified access to shared infrastructure for non-IT end users. The scree...
    Subscribe to the World's Most Powerful Newsletters
    Subscribe to Our Rss Feeds & Get Your SYS-CON News Live!
    Click to Add our RSS Feeds to the Service of Your Choice:
    Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
    myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
    Publish Your Article! Please send it to editorial(at)sys-con.com!

    Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021


    SYS-CON Featured Whitepapers
    ADS BY GOOGLE