Belongs to following categories: Integration, Graphic, ULC5.2, ULC6.1, ULC6.2, UltraLightClient '08,
Project Home
Downloads
Purpose
Many business applications need to display graphs. This contribution
shows how the free graph library
JGraph can be integrated into ULC applications.The
integration is done entirely on the client side. This approach has the
advantages that all functionalities of
JGraph are available on client side and that only a
small and light weighted communication between client and server is
necessary.Since the
JGraph library is only 136 KB big, the download is
done rapidly.
Screenshots
<
Features
Features of the extension
- Implements the graph model event handling of JGraph:
Whenever the graph changes, the UlcGraphModelEvent
stores information about these changes.
- Implements the graph selection event handling of JGraph: Whenever the selection of the graph
changes, the UlcGraphSelectionEvent stores
information about the change in the current selection.
- Supports full Drag & Drop functionality: all graph
elements can easily be moved and resized, edges can be interactively
connected to cells.
- Like JGraph, the extension uses the GraphConstants class to set the properties of the
graph elements. So far, not all of the property settings are supported.
But the most important properties such as colour, border, bounds, dash
pattern, arrow and label are implemented.
- The API strongly depends on the JGraph
API. It also offers many interfaces such as IGraphModel,
IGraphSelectionModel, IGraphCell,
IEdge and IPort. Therefore
one is free to create his own models to implement these interfaces (be
aware that in such a case, one is self responsible for the
client-server communication). Usually, the default models and graph
elements are sufficient.
- Contrary to JGraph, this contribution is
implemented much more type-safe. Instead of parameters of type Object, the contribution methods demand parameters
of type IGraphCell, which is the highest type in
the class hierarchy of the graph elements.
Features of the sample application
- Click "Insert Cell" or "Insert Edge" to insert cells and edges
either with default or random properties (activate or deactivate the
"Random Values" checkbox).
- Connect an edge to a cell by using the Drag & Drop
mechanism: Click the start or the end of an edge and drag it to the
middle of a cell (the cell gets highlighted when the connection is
about to be successful). It is also possible to disconnect an edge from
a cell: Click the start or the end of the edge and unlock the
connection from the cell by dragging the edge to another cell or just
somewhere on the graph.
- Select a cell or an edge and click "Remove" to remove it from
the graph. When you remove a cell, all edges connecting to that cell
are also removed.
- Click "Zoom In" and "Zoom Out" in order to zoom on the graph.
Click "Reset Zoom" to set the zooming factor to the default value.
Resources
How to use
A sample usage of the
JGraph Extension is provided
in
com.canoo.ulc.community.jgraphextension.application.ULCGraphSample.
ULCGraph is an
ULCComponent
containing all required information to create a
JGraph
object within its client counterpart
UIGraph.The
first step is to instantiate a graph model. Then, create an
ULCGraph object that is based on that model. In
addition, a
HashMap object is needed in order to
store all the attributes of the graph and its elements.
IGraphModel model = new DefaultGraphModel();
ULCGraph graph = new ULCGraph(model);
Map attributes = new HashMap();
Now, create some graph cells and edges. Important to mention here is the
fact that all attributes are not stored under the object itself, but in
an
ULCAttributeMap object that is finally saved in
the
HashMap object built above. This is exactly
the same way
JGraph does it. Perform additional
operations using the static methods of the
GraphConstants
class to change the properties of the graph elements.
IGraphCell hello = new ULCGraphCell("Hello");
ULCAttributeMap helloAttribute = new ULCAttributeMap();
GraphConstants.setBounds(helloAttribute, new ULCRectangle(50, 50, 40, 20));
GraphConstants.setBackground(helloAttribute, Color.yellow);
attributes.put(hello, helloAttribute);IEdge edge = new ULCEdge("Hello-World-Edge");
ULCAttributeMap edgeAttribute = new ULCAttributeMap();
GraphConstants.setLineEnd(edgeAttribute, GraphConstants.ARROW_CIRCLE);
GraphConstants.setEndFill(edgeAttribute, true);
attributes.put(edge, edgeAttribute);
Never forget to add at least one port to a cell. Otherwise you are not
able to connect edges to the cell.
IPort helloPort = new ULCPort();
hello.addPort(helloPort);
Now, link the edge to the cells. This happens by instantiating an
ULCConnectionSet object with the three parameters
edge, source port and target port of the edge.
ULCConnectionSet connectionSet = new ULCConnectionSet(edge, helloPort, worldPort);
Eventually, insert the above-created elements into the graph model,
which enforces the graph to repaint itself.
IGraphCell[] cells = {edge, hello, world};
model.insert(cells, attributes, connectionSet);
There are two listeners that can be added to the graph model. One is the
IGraphModelListener, which is always notified
after the graph has changed, and the other is the
IGraphSelectionListener,
which is informed when the current selection has changed. Both listeners
can be added to the graph model as follows:
model.addGraphModelListener(new IGraphModelListener() {
public void graphChanged(UlcGraphModelEvent event) {
System.out.println(event.getInsertedCells());
}
}); graph.getSelectionModel().addGraphSelectionListener(new IGraphSelectionListener() {
public void valueChanged(UlcGraphSelectionEvent event) {
System.out.println(event.getRoots());
}
});
How it is implemented
The core components are
ULCGraph and
UIGraph, as well as
ULCGraphModelAdapter
and
UIGraphModelAdapter.
ULCGraph
provides a small API to set a couple of graph properties. It also holds
a graph model and a graph selection model. You can add an
IGraphModelListener to receive notifications when
the graph has changed and an
IGraphSelectionListener
to receive notifications when the selection of the graph has changed.
The
ULCGraphModelAdapter is responsible for the
communication between the
IGraphModel object on
server side and
JGraph's
GraphModel
on client side. It holds a weak reference to the graph model and it is
at the same an
IGraphModelListener that always
synchronizes the graph's current state to the client when the graph is
changed by code execution on the server side. Its counterpart
UIGraphModelAdapter listens to the changes coming
from interactions with the user and sends those changes to the server.
Moreover, it handles all feedback on the client side. This has the
advantage that no server roundtrip is necessary until the user has
finished moving or dragging the elements, which eventually triggers the
change event.
Important information: At the present
state,
UIGraphModelAdapter delegates all interface
method invocations to
JGraph's
DefaultGraphModel.
The reason for this delegation is due to the improper implementation of
the MVC pattern in
JGraph (
DefaultGraphModel.insert()
does not only change the model but also updates the views). This
prevents a flexible implementation of the
GraphModel
interface (access to inner classes of
JGraph
needed). In order to allow a flexible implementation of e.g.
GraphModel.acceptsSource() or
GraphModel.acceptsTarget(),
UIGraphModelAdapter needs to be implemented as a
decorator instead of using delegation only.
GraphConstants
is used to set the properties of the graph elements. This class does not
communicate directly with the client, but instead invokes the different
put() methods of
ULCAttributeMap,
which then enforces a server push.
Compatibility
- ULC 5.2: JDK 1.4.2
- ULC 6.1: JDK 1.4.2
- ULC 6.2: JDK 1.4.2, Windows XP, Windows Vista, Mac OSX
- UltraLightClient 2008: JDK 1.4.2, JDK 1.5, JDK 1.6, Windows
XP, Windows Vista, Mac OSX
JGraph 5.0.0 has been developed for JDK 1.4. It also works on JDK 5 but
there are some repainting issues when dragging the JGraph components.
Project setup with Eclipse
The project contains all necessary Eclipse project files and can be
directly imported from the repository. The classpath in this project
contains a entry named
ULC Library, which locates
the needed UltraLightClient libraries. For to uses the
ULC
Library entry you have to install the Eclipse Java IDE Integration
Plug-in that can be found at:
http://update.canoo.com/eclipse.
A installation guide how to install plug-ins in Eclipse can be found at
the Eclipse help pages: Workbench User Guide > Tasks > Updating and
installing software.
Project Links
Project Home
Downloads
Authors
marc.hermann
dna
sibylle