Pluglet Developers Guide
Pluglet Examples
Java Media Player (JMPlayer) Example
Overview
This is an example of a Pluglet that is a media player. It uses the MediaPlayer bean from the Java Media Framework. Note that a similar example could be given for an applet using the MediaPlayer, but there is an advantage here: the Pluglet is installed in the browser and ready to play, whereas the applet would have to download class files, causing considerable delay in playing the media.
Using Java Media Framework
The example uses one bean from the Java Media Framework
(javax.media.bean.playerbean.MediaPlayer
)
and one interface (javax.media.ControllerListener
).
MediaPlayer provides player capability for a range of media types
(.avi
, .mpeg
, .swf
, .
mov
....) Typically the ControllerListener
i
interface is implemented by a class whose objects want to be listeners to
events occurring on objects of another class; it has one method,
controllerUpdate(ControllerEvent event)
that can be used
to respond in some way to a Controller
event. A <
code>ControllerListener is added to a Controller
v
ia the addControllerListener
(ControllerListener listener)
method of the <
code>Controller.
(In our example, MediaPlayer
is a Controller
, s
since it extends javax.media.Controller
, and <
code>Player is the class that implements
ControllerListener
. Thus a Player
object gets notification of events from a MediaPlayer
b
bean.)
For more information about the Java Media Framework, see http://jsp.java.sun.com/products/java-media/jmf/
JMPlayer Pluglet
The following is meant to provide an overview of how this Pluglet works.
Press the button to view the source code:
When the browser encounters a MIME type
for this Pluglet, PlugletEngine
creates an instance o
of JMPlayer
.
(Here the PlugletFactory
implementation is
JMPlayer
; the Pluglet
implementation
is Player
; and the PlugletStreamListener
implementation is JMPlayerStreamListener
.)
The browser then calls the initialize()
method of
JMPlayer
, passing it an instance of
PlugletManager
. Then it calls the createPluglet()
method of JMPlayer
, returning an instance of
Pluglet
, i.e., an instance of Player
.
Note that Player
implements ControllerListener
in addition to Pluglet
.
The browser then initializes the Player
instance, passing
it an instance of PlugletPeer
, provides it with a frame
by calling setWindow(Frame frame)
, and calls start()
. start()
creates the MediaPlayer
object called player
(not to be confused with the
Player
class), creates a new Panel
object
called panel
, and adds player
to panel
. The stage is now set for action.
When data is ready to be read, the browser calls the newStream()
method of Player
, returning listener
,
an instance of JMPlayerStreamListener
. newStream()
also calls listener.setPlayer()
and passes a
reference to the current Player
object to it. (This would
be the new Player
created by the factory.) This method sets
the variable jmp
(of type Player
) of
JMPlayerStreamListener
to the Player
that is
passed.
When the media begins loading and the brower calls onStartBinding()
, jmp.PlayFile()
is called with the URL for the data
stream. (The boolean
returned is checked and an error is
indicated if the value is false
; i.e., if player
is unable to handle the MIME type of the URL.) PlayFile()
sets the location of the media (URL), and if all is well it
then adds the Player
(jmp
of
JMPlayerStreamListener
which called playFile()
)
as a listener to the MediaPlayer
(player
).
Finally, it calls realize()
on player
.
(realize()
constructs the media-dependent portions of the
Controller
.)
(Note that jmp
mentioned above was set in
JMPlayerStreamListener
when the Player
object was passed to listener.setPlayer()
in the
newStream()
method of Player
. Thus
jmp
is the new Player
object created
initially by the factory, JMPlayer
.)
Since the Player
, jmp
, is now a listener
(ControllerListener
) to player
,
jmp
gets notification when RealizeCompleteEvent
occurs, and controllerUpdate()
then calls
player.prefetch()
. When prefetching is complete, a
PrefetchCompleteEvent
is generated, indicating that the
controller has preloaded media data and acquired the exclusive-use
resources it needs to start. When a PrefetchCompleteEvent
occurs, dimensions are set for the Panel
,
player.start()
is called (not to be confused with the
start()
method of Player
), and the frame appears.
If all goes well, the media is played.
Java DOM Viewer Example
Overview
The Java
DOM Viewer (DOMViewer
) Pluglet allows you
to view a document as a tree structure of object nodes that compose
the document. It is an application launched as a Pluglet when a page
is loaded containing an EMBED
or OBJECT
element specifying TYPE="application/dom-viewer"
.
The EMBED
or OBJECT
element is embedded
in the page as the first child element of the BODY
element.
This Pluglet depends on the Java DOM implementation, i.e., it acquires access to the DOM via the
implementation of the w3c Java Bindings to the DOM. Thus you must h
have built the Java DOM for this example to work, and
you must have the org.w3c.dom
classes in your
CLASSPATH
.
The example uses three files with a total of six classes and one interface:
file: DOMViewFactory.java
class DOMViewerFactory
interface DOMTreeNotifier
class DOMTreeModel
class DOMCellRenderer
class DOMViewer
file: DOMAccessPanel.java
class DOMAccessPanel
file: DOMTreeDumper.java
class DOMTreeDumper
To view the source code, select:
Note: The information that follows provides an overview of the code.
DOMViewerFactory.java
The DOMViewerFactory
class, which this file contains,
implements Pluglet Factory
. Thus it creates an instance
of DOMViewer
, which implements Pluglet
.
The initialize()
method of DOMViewer
does
much of the work in two code blocks:
In the first code block, the goal is to set the root node for the
DOM tree. This is accomplished by getting the PlugletTagInfo<
for the PlugletPeer
, next getting the DOM element for
the Pluglet
via the getDOMElement()
method of PlugletTagInfo
, then getting the
Document (doc object)
for the element via the element's
getOwnerDocument()
method. Finally, the element for
Document doc
is obtained via the getDocumentElement()
method of Document
. This element is then set as
the root node (rootNode
).
In the second code block, an instance of DOMTreeModel
is
created with rootNode
passed as node
.
(DOMTreeModel
implements javax.swing.tree.TreeModel
and the DOMTreeNotifier
interface that is defined
in DOMViewerFactory.java
. TreeModel
includes
methods for adding listeners and obtaining basic information about
a tree; DOMTreeNotifier
includes methods for notification
when a tree has changed.) The instance is treeModel
.
treeModel
is then passed to a new instance of
DOMAccessPanel
called elementPanel
, so that
the tree can be manipulated. (DOMAccessPanel
is discussed
in the next section.) It is also passed to a new instance of
JTree
called tree
so that it can be viewed.
tree
adds elementPanel
as a selection listener
and sets a cell renderer. tree
is then added to a new
JScrollPane
and then the JScrollPane
instance
(treePane
) is added to a new JPanel
(panel
).
The setWindow()
method of the Pluglet
then
adds panel
and elementPanel
to a
JFrame
object (frame
) via a vertical
JSplitPane
object, displaying panel
on the
top (with the tree structure) and the various buttons, fields, and
combo boxes of elementPanel
below for manipulation.
Below is the DOMViewer
for test.html
, which is
included in the Pluglet
examples/dom
directory:
Note that the newStream()
method returns a null
object; there is no data stream involved in this example. start()
, stop()
, and destroy()
are included
but have neither variables nor methods defined.
DOMAccessPanel.java
DOMAccessPanel.java
extends JPanel
and
implements three listener interfaces:
ActionListener
ItemListener
TreeSelectionListener
The constructor sets up the various panels, text areas, and buttons used to manipulate the DOM.
An instance of DOMTreeNotifier
is passed to the
constructor, which allows an instance of DOMAccessPanel
to discover if the tree has changed in some way.
ActionListener
To implement ActionListener
, DOMAccessPanel
implements actionPerformed(ActionEvent e)
.
actionPerformed(...)
responds to the various button-
accessible events on the panel (Set, Remove, New,
Insert ...).
ItemListener
To implement ItemListener
, DOMAccessPanel
implements itemStateChanged(ItemEvent e)
. An
ItemEvent
occurs when an item -- in this case a node --
is selected or deselected. itemStateChanged()
then
responds to that event.
If node
is not null
and there is a selected
item in the Attributes combo box (bottom left JComboBox
as shown above highlighted in yellow), then the Set button
(type JButton
) is enabled. If node.getAttributes()
returns a NamedNodeMap
(e.g., not null
)
and the index of the selected named attribute is 0 or greater
(aName.getSelectedIndex() >= 0
), then the value
of the attribute is set as follows:
aValue.setText(attrMap.item(aName.getSelectedIndex()).getNodeValue()
);
where attrMap = node.getAttributes()
Thus the text for the value (aValue
of the
JTextField
) is set by (1) getting the index of the name
(aName
); (2) passing that to the item()
method of the NamedNodeList
(of attributes), which returns
the node (attribute-node); (3) then applying the getNodeValue()
method of node
to the attribute-node. The user
can also enter a new value, and with the Set button enabled,
the actionPerformed()
method will update the value when
Set is pressed.
TreeSelectionListener
To implement TreeSelectionListener
, DOMAccessPanel
implement the valueChanged(TreeSelectionEvent e)
method. Then, when a TreeSelectionEvent
occurs on the tree,
valueChanged()
is passed the event and checks if a path
has been added via e.isAddedPath()
. If so, the node
information for the last node in the path is updated.
valueChanged()
then sets nodePath
to the
new node path, and from the event it sets tree
to the
source of the event.
The DOMAccessPanel
class also contains methods to
update node information, create, insert, append, and remove a node,
as well as save the changes to a document. The saveDoc()
method uses the DOMTreeDumper
class, which is discussed
next.
DOMTreeDumper.java
saveDoc()
in DOMAccessPanel
creates an
instance of DOMTreeDumper
(if there isn't one already)
and calls the dumpToFile()
method of DOMTreeDumper
, passing a file name and the document associated with the
node.
dumpToFile()
then creates a new file output stream
(fos
) and print stream (ps
) and calls
dumpDocument()
, passing to it the document
(doc
). dumpDocument()
then gets the document
element -- i.e., the root element of the document via the
doc.getDocumentElement()
-- and calls dumpNode()
, passing the document element to it.
dumpNode()
then gets the node type, as well as the node
name and value. type is ELEMENT_NODE
(the element is
HTML
element), so control is transferred to case
Node.ELEMENT_NODE
and dumpAttribute(node)
and
dumpChildren(node)
get called.
The first method calls dumpNode()
for each attribute of
the HTML
element; the second method calls
dumpNode()
for the children. If the children have
children, then the children will call dumpNode()
for all their children. Eventually, every node of every type in the
tree will be dumped.
DOM Demo
Below is a demonstation you can run showing how DOMViewer can change
DOM element attribute values on a web page. The demo here uses a
page containing a table with a single row and column that initally
has a background color of red (bgcolor=#ff6666
), no
border (border=0
), table height and width of 125
(height=125
, width=125
, and that is aligned
in the center of the page (align=center
).
The demo shows the table attribute values being changed. First the value is highlighted in yellow as it is changed, then the Set button is highlighted as it is pushed, causing the new valued to take effect in the Mozilla browser. The Description field above the Start Demo button tells you what is happening.