Java Reference
In-Depth Information
The constants indicate the name of the shape, the bundle resource file for the shape's
icon, and the bundle class name for the shape's class. The
draw()
method draws the
shape on the canvas,
From the constants, it's fairly straightforward to see how you'll describe a specific
shape implementation. You only need to know the name, an icon, and the class imple-
menting the shape. As an example, for the circle implementation you add the follow-
ing entries to its bundle manifest:
Extension-Name: Circle
Extension-Icon: org/foo/shape/circle/circle.png
Extension-Class: org.foo.shape.circle.Circle
The name is just a string, and the icon
and class refer to a resource file and a
class inside the bundle
JAR
file, respec-
tively. You add similar metadata to the
manifests of all shape implementation
bundles, which converts them all to
extensions. Next, you need to tweak the
architecture of the paint program to
make it cope with dynamic addition and
removal of shapes. Figure 3.18 captures
the updated design.
Comparing the new design to the
original, you add two new classes:
Shape-
Tracker
and
DefaultShape
. They help
you dynamically adapt the paint frame to
deal with
SimpleShape
implementations
dynamically appearing and disappearing. In a nutshell, the
ShapeTracker
is used to
track when extension bundles start or stop, in which case it adds or removes
Default-
Shape
s to/from the
PaintFrame
, respectively.
The concrete implementation of the
ShapeTracker
is a subclass of another class,
called
BundleTracker
. The latter class is a generic class for tracking when bundles are
started or stopped. Because
BundleTracker
is somewhat long, we'll divide it across
multiple listings; the first part is shown next.
Shape
tracker
Default
shape
1
1
1
1
1
Paint
frame
Simple
shape
1
1
1
Shape
component
Circle
Square
Triangle
Figure 3.18
Dynamic paint program class
relationships
Listing 3.14
BundleTracker
class declaration and constructor
package org.foo.paint;
import java.util.*;
import org.osgi.framework.*;
public abstract class BundleTracker {
final Set m_bundleSet = new HashSet();
final BundleContext m_context;
final SynchronousBundleListener m_listener;
boolean m_open;