HEAD PREVIOUS

Chapter 21
The Power User

This chapter details features of JMatter applications' user interfaces, including many subtle features that aim to improve usability and users' productivity.

21.1  Visual Command Interface

JMatter sports a feature inspired by blacktree software's QuickSilver, and more recently, Gnome Do. Briefly, these applications provide a visual command interface for desktops. For a desktop management application, most commands involve launching applications or bringing them up in the terminal or the file manager. The end user composes an instruction by first specifying the target application and second the specific command to invoke on that application. Its primary use is for launching applications. Applications are specified by typing, and identified via a text matching algorithm.
It turns out that these applications adhere to the noun-verb metaphor which is a strong part of JMatter's general philosophy. Every operation in JMatter boils down to the invocation of a command on a target object (and optionally specifying command arguments). JMatter's implementation of a visual command interface now provides an additional, alternative visual mechanism to invoke commands.
I will illustrate how this interface works with an example. Let's take the Sympster demonstration application. Let's say we wish to create a new speaker. We typically do this by right-clicking on the Speaker icon in the class bar (the visual representation of its type) and selecting the command New from its context menu. Now, you can also:
  1. Press Ctrl-I (Cmd-I on the mac) to invoke the visual command interface,
  2. Type Spe, press the tab key, and type New
  3. Press the Enter key
In step 2, we first search for the type Speakers by name, and then we search for the command named New. We don't have to type the full name, just enough characters to match the item (the object) we're looking for. Optionally, you can press the down-arrow key to see other matches and select the appropriate one. The escape key dismisses the visual command interface. In the above case, invoking the command causes the visual command interface to auto-dismiss.
Figure 21.1 shows JMatter's visual command interface in action.
figures/visual-cmd-interface.png
Figure 21.1: JMatter's visual command interface in action
Many desktop users have become habituated to this type of command interface and prefer it. First, this is a testament that noun-verb types of user interfaces are a good match for the way we tend to go about doing things. Second, it provides a uniform way of invoking any command. Finally, you don't have to take your fingers off of the keyboard.
This feature is built-in to JMatter. No work is necessary to enable it. You might however be interested in extending its capabilities further by extending its index, which we discuss next.

21.1.1  Extending the Index

The visual command interface by default matches types. Match a target type, and then invoke a specific command on it, for example: Person Contacts -> Browse.
It would be nice however if we could interact with instances of a given type in addition. For example, with the contact manager, it'd be nice to match a contact by name directly from the visual command interface. Likewise, in MyTunes, it'd be nice to direclty match a song by title. In Sympster, Speakers and Talks are also good candidates.
The visual command interface provides a mechanism for you to add items to its index. The ContactMgr application has recently been enhanced to show you how. Here's how this is done..
First, we subclass com.u2d.app.Application and override the postInitialize() method:
public class Application extends com.u2d.app.Application
{
   public void postInitialize()
   {
      super.postInitialize();
      contributeToIndex(PersonContact.class);
   }
}
The above call to contributeToIndex() instructs the visual interface to include contact instances in its index.
Next we need to revise our spring configuration file to specify our subclass as the application's Application bean. We edit the file src/applicationContext.xml as follows:
 <bean id="application" class="com.u2d.contactmgr.Application">
    <property name="name" value="Contact Manager" />
    <property name="version" value="1.0" />
    <property name="description" 
              value="A simple contact manager" />
    <property name="helpContentsUrl" 
              value="http://jmatter.org/documentation/html/index.html" />
    <property name="pagesize" value="15" />
    <property name="persistenceMechanism" ref="persistor" />
 </bean>
Notice how the bean's class above references our subclass. That's it. Now when we launch the contact manager, assuming we have a contact named John Doe, we can invoke the visual command interface, start typing John and the instance will be matched. We can then invoke any of a number of commands, for example Open or Edit.

21.2  Associations Made Easy

NakedObjects originally introduced a terrific way to establish associations between objects in a user interface. It automatically enabled this via drag and drop.
For some reason, dnd in many ways is not used as much as it used to be. Having to take the hand off the keyboard is admittedly a "productivity mark deduction."
So, in JMatter, I set out to enable associations in more than one way. For starters, dnd works out of the box. But one can also click a "pick" button that will display a listing of entries of the type for a given association, that the user simply picks from.
Let's look at a concrete example: let's say we're working with the Symposium manager demo application in JMatter. And let's further say that we're defining a new talk to be given. Talks have a many-to-one association to the speaker (or presenter) giving the talk.
My favorite way of establishing that association is with the in-place associator widget that's built-in to JMatter. Here's how it works. When editing the talk, click (or tab into) the association field in question, which in this case is Speaker. Simply start typing and a matching list of entries automatically appears. This component dynamically fetches matching entries from the database as you type. The matched items listing also pages by default, so for a scenario with too many matching entires, only the first page will be fetched. In my experience with this component, this is one of the fastest ways of making an association between two objects.
Here's a snapshot of me trying to define a new talk, *In Action*, as it were24:
figures/associator.png
Figure 21.2: Associating a Speaker to a talk
The only detail to tend to is to specify which field of Speaker are we searching by. That's what that little magnifying glass icon to the left of the text field is for. It's a drop-down combobox that dynamically lists the various fields you might want to search by.
The default field that JMatter should use for searching in the context of in-place associations is controlled by the defaultSearchPath metadata, as shown by this example:
public static String defaultSearchPath = "name.first";
See section 8.4.9.

21.3  Paging

We've all had to implement this feature as developers. Today, many frameworks such as Tapestry for example, will provide components out of the box that will automatically take care of paging a listing on your behalf.
JMatter also provides paging out of the box. When I sat down and started to think about this feature, I saw a certain pattern. One's first, naive implementation of paging might consist of a simple forward and back navigation buttons:
< >
Shortly afterwards comes the request for the ability to navigate to the first and last page in a listing, and so the above evolves to:
<< < > >>
Then embellished, like so:
<< < [Page 3] > >>
Over time, paging has evolved to let you navigate to a number of pages in the vicinity of the current page:
1 2 .. 7 [Page 8] 9 .. 13 14
This is what most web-based applications do today.
What I realized is that paging, taken to its eventual limit, is essentially embodied in the behaviour of a scrollbar. Most scrollbars provide continous scrolling. Whereas in the case of paging, the scrolling is discrete. The more pages there are, the less this discrete behaviour is apparent. What's nice about today's scrollbars is that their size is inversely proportional to the length of the list. The larger the list, the smaller they are. Scrollbars have the advantage of giving you more of a visual perspective of where you are in the list. And you can simply drag the scrollbutton to any location along its dimension.
JMatter's Swing-based view mechanism defines a view implementation: a component named PageScrollBar which extends Swing's JScrollBar, shown at the bottom of the following two-page listing:
figures/paging.png
Figure 21.3: Paging a Conference's Sessions
As usual, developers of JMatter applications need not concern themselves with this at all. It's bundled into the framework and it just works. If however you feel the need to customize the way this scrollbar looks or behaves, it's easy enough with a little Swing experience to make whatever enhancements or decorations one might have in mind.

21.4  Exposé

JMatter GUIs are inherently Object Oriented UIs. I like to make the analogy to our operating systems' desktops. There are a number of ways to make such UIs more effective. Sometimes I look to these desktop systems for ideas and features.
One such feature is Apple's Exposé which has since also been copied by the Compiz Fusion project on Linux: the idea of scaling down and fanning out one's windows temporarily for the purpose of easily switching focus to a window that is otherwise hidden by other windows with a higher z-index. JMatter incorporates such a feature. Pressing the F12 key invokes the JExplose 25 feature which does precisely this. This option is also available form the desktop pane's context menu.

21.5  Navigation

21.5.1  Window Placement

JMatter takes a certain strategy relating to the placement of new windows (internal frames) in its Graphical User Interface.
I recall trying various window placement strategies and then realizing something I was doing as a user of my applications: after creating a new view, I'd quickly reach for the window's title bar and place the window where I really wanted it. I don't think there's an algorithm for guessing the user's intent. So I started thinking about what might the next best thing be.
The strategy was to minimize the amount of work one has to do in moving the resulting window. What I do is place new windows such that their title bars are near the current mouse cursor location, thus minimizing the distance one would have to move their mouse to reach for it.
There's a somewhat hidden feature in JMatter which I very much like and that I'd like to share. This feature takes things one step further: it automatically puts the newly created window in placement mode. Allow me to explain..
This feature requires pressing a metakey to communicate your intent to use it: when you're about to invoke a command that creates a new view (e.g. the Open command) , hold down the Control key (on the mac, use the Command key).
The resulting window automatically "binds" to your mouse location. That is, it will follow your mouse. So, the way it works is you invoke the command with the Control key pressed and the new view is created, but it starts following your mouse around. Once you've found that ideal spot, a single left-click is all you need to do to pin it back down onto the desktop.

21.5.2  New View Placement Options

Another feature of desktop systems, one that has been around for some time, and is specifically related to the file manager, is the idea of giving users options in terms of how to place newly-created views. When navigating a folder hierarchy, one can double-click on a folder, which typically opens a new window with the contents of that folder. Long ago, on ms-windows I recall always turning on the option "re-use existing window"; that is, replacing the existing view with the new one. This can really help with an otherwise rapid proliferation of windows on one's desktop.
Separately, the mozilla project introduced us to another navigation option: tabbed browsing, which is a sort of "middle of the road" approach: don't create a new window, but don't replace the existing view either. Since then, we've seen other applications, such as shell terminals, copy this handy feature.
JMatter now supports both modes of navitgation. A User's default browsing preferences can be specified through the User model object, which has an aggregate property named Preferences. Its first and only option at the moment captures how a user generally prefers to navigate in JMatter: should new views be created by default:
  1. in a new window?
  2. in a new tab?
  3. in-place, replacing the existing view?
Setting your preference is all it takes to change JMatter's default navigation behavior.
In many situations there may be exceptions to the default rule. Say, for example, that we wish to open a new view in a new tab even though the default setting is in-place navigation. To accommodate this, a new gesture has been introduced in JMatter: holding down the Shift key while invoking a command that produces a new view will cause a context menu to appear at the mouse location, for selecting how to create the new view. The choices again are the above three: in a new window, tab, or in-place.
Figure 21.4 captures the invocation of the Open command while holding down the Shift key.
figures/nav1.png
Figure 21.4: Invoking the Open command, holding down the Shift key
Figure 21.5 shows the navigation option pop up. I selected the in new tab option.
figures/nav2.png
Figure 21.5: "Open in new tab" Option
The next figure shows the result of the view created in a new tab.
figures/nav3.png
Figure 21.6: Resulting View
Finally, this last screenshot shows that, with tabs, you have the option of detaching the view onto its own window or closing the tab (Ctrl+w is the corresponding key binding).
figures/nav4.png
Figure 21.7: Tab Detach Option
I believe this to be an important feature, finally producing a desktop with a number of effective navigation instruments:
  1. Fundamentally an OOUI
  2. DnD support
  3. An exposé-like feature
  4. Tabbed, In-Place, or New-window view placement
Another complementary feature that is contemplated for JMatter is support for docking views. I have looked at flexdock, which is a terrific effort. But I'm looking for something that is more transparent: effectively a layout manager designed for JDesktopPane that transparently provides docking support. Let me know what you recommend.

21.6  Copy and Paste

Every Swing application gets for free the ability to use the underlying platform's copy and paste capabilities when working with JTextFields and JTextAreas.
In JMatter you might have noticed that instances also sport their own Copy/Paste commands. You'll find this feature to be a little more powerful and interesting compared to the basic clipboard copy/paste feature.
The main difference is that unlike the clipboard, where you get one temporary area to copy to, JMatter provides a temporary "buffer" area for every distinct type.
So, for example in the Contact Manager demo application, I can go about and copy an Address here, a Contact object there, or an entire Person instance and all three copies exist in memory simultaneously, each in its own buffer. I can then, say, create a new Person instance and right-click "Paste" on the title view for the new instance. All of the information is copied over. This use case may not be very interesting or real.
But there are other situations. Take for example how a Person has a Contact property modeled using composition (or aggregation). Each instance has its own copy. Yet it's very possible for two persons to have the same contact information, or perhaps the same address, with the very real possibility that the two copies will change/diverge over time.
The copy/paste commands on instances are automatically placed by JMatter in a number of context menus for a number of views. You'll find these commands in the title view's context menu, as shown below.
figures/copy_on_instance_title_view.png
Figure 21.8: Copy on Instance Title View
You'll also find it on aggregate objects' nodes as shown in figure 21.9.
figures/copy_on_aggregate_node_view.png
Figure 21.9: Copy on Aggregate Node View
Finally, you'll find it on the context menus for individual tab title views, as shown here:
figures/copy_on_tabtitle.png
Figure 21.10: Copy on Tab Title View
This feature can come in handy and save repetitive data entry tasks, where one might otherwise be forced to invoke copy/paste individually on atomic fields.

21.7  The Restore Desktop Feature

One last feature, though not completely polished, is worth mentioning. JMatter saves and restores end users' desktops between sessions.
That is, the size and positions and other information about open windows is recorded and stored to the database when one logs out or quits the application. Conversely an attempt is made to restore these views on login. What's nice about saving this information to database is that one's desktop configuration is independent of the workstation you log in to. Instead it's tied to your user information in the database.
This feature is at the moment fairly simple. Other than restoring the main window bounds and simple child windows (lists and instances), it does not yet properly restore other types of views at the moment.

HEAD NEXT