Many types exhibit fields such as time spans: sessions, appointments,
meetings, visits and more. Likewise many pieces of information have
location information: a latitude and longitude. Such information is
more naturally interpreted visually.
We saw an example of scheduling in the Sympster demo application.
JMatter supports both a simple and a fancy model for integrating scheduling
visually into its graphical user interface.
For mapping, JMatter integrates Swingx-ws for viewing entities on
a map, in a fashion similar to what we've become accustomed to with
Google maps.
13.1 Calendars
Section discussed a way to expose a fully-functional
calendar view into the Sympster sample application. This calendar
view has some attractive features such as the ability to view multiple
schedules (we saw different schedules for distinct locations at a
conference). It took only abiding by a few simple conventions to do
this integration. JMatter now calls this form of calendaring integration
its fancy calendaring model.
JMatter now exposes a second, simpler calendaring integration model
that makes almost no requirements on your model and yet in some ways
is even more powerful than the former. Let's say we need to model
a meeting. All we need to do is define a field of type TimeSpan
and extend the base type CalEvent. This base type is now only
a marker base class. We are not required to provide any metadata,
there's no need to implement or override any methods, and we're free
to name the model object's timespan field however we see fit.
JMatter will detect the type in question and automatically identify
the timespan field in question. JMatter then exposes a command on
the type named Browse in Calendar, which brings up a calendar
view with both custom week and day views. You can navigate this view
in time. What's special is that this custom calendar view is nothing
but a list view. It lists instances of a given type.
As you already know, the default list view that appears as a consequence
of invoking the Browse command is always adorned with a query
panel at the top. This means that the list can be dynamically filtered.
This calendar view sports the same query panel. So, not only can we
browse information in time, but this feature is further combined with
search capabilities. So if we're looking at a calendar that's too
crowded with meetings or talks, and we're looking for a meeting at
a specific location, we can filter the listing.
In figure we see a calendar view with
four talks. Note the query panel at the top.
Figure 13.1: Calendar view with four talks
The next figure shows the same listing filtered by title (we're looking
for talks with the word 'Swing' in their title, just as an example).
Figure 13.2: Filtered Calendar View
Separately, one enhancement to this calendaring view worth noting
is that durations can now be edited directly from within this view
by simply dragging the bottom edge of event views to the desired end
time.
So calendaring is even simpler than it used to be, the integration
is dead simple, requiring only the extension of a marker base type,
and the features are more compelling, with search being pre-integrated
into calendaring views.
Analogous to having integrated custom views for types with a time
component, JMatter has begun providing custom views for types with
a location component.
For this feature, JMatter integrates the work done by the Sun Swing
team on the project named Swingx-ws (where ws stands for web
services).
This implementation is a little less mature compared to calendaring
but has come along nicely.
Figure 13.3 shows an example route for a flight
itinerary that leverages JMatter's mapping support.
Figure 13.3: A Flight Route
In this particular implementation I embellished the default map view
with an additional layer using curved paths to delineate the route's
segments. The waypoints on the map represent actual model objects.
We can right-click on one and edit it if we wish.
The basic contract is that a type extend AbstractComplexMappableEObject
and implement the single method specified in the contract with the
interface MappableEO:
-
public GeoPoint geoPosition();
You guessed it: a GeoPoint is a JMatter type, which means that,
among other things, it knows how to persist itself to database. A
GeoPoint encapsulates a latitude and longitude.
The specific flight support application from which the previous screenshot
was taken has a model object named Airport which implements
this contract. In return, each instance will bear the command View
on Map, which will automatically bring up a map view and add the
waypoint in question. From there, users can further interact with
the map.
Further, list views for Airports automatically bear the list
command View on Map as shown in figure 13.4.
Figure 13.4: List Command: View on Map
This particular list happens to be the search results of a save query
for Airports (and Heliports) in the vicinity of Austin, Texas. The
next figure shows the resulting map view with the waypoints in question.
A map view is again nothing but a list view.
Figure 13.5: List Command: View on Map
The map is zoomable of course. This means that if we wish to, we can
take a closer look at the Lakeway airfield, as shown in the next figure.
Figure 13.6: Zooming in on a Waypoint
Future enhancements to mapping support will likely be in the area
of enhancing the map view with a query panel. In addition, we're considering
tying panning a map with fetching all waypoints bounded by the geographical
rectangle that the map represents, which will make feasible browsing
large amounts of information on a map.
I would like to thank Andres Almiray for suggesting and prototyping
this integration into JMatter.
13.2.1 Maps: An atlernative to view embedding
As nice as it is to be able to embed map views directly in a JMatter
application, sometimes a simpler solution may be the more elegant
in a particular context. For example, I've recently been working on
a client application for persons who need to service a specific address.
In that context, I decided to add the ability for the end user to
plot the given address directly in google maps by launching a web
browser:
-
public static final String googleMapsUrlPattern = "http://maps.google.com/maps?q=%s";
@Cmd
public void ViewInGoogleMaps(CommandInfo cmdInfo)
{
String address = String.format("%s, %s %s %s", street, city, stateCode, zip);
String url = String.format(googleMapsUrlPattern, EmailMessage.htmlEscape(address));
Launcher.openInBrowser(url);
}
All we're doing above is constructing the proper url to bring up an
address using google maps, and finally launching the url in a browser.
It's that easy.