<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Palantir Technologies &#187; swing</title>
	<atom:link href="http:///category/swing/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>Articles from the Engineering Group at Palantir Technologies</description>
	<lastBuildDate>Wed, 14 Dec 2011 17:48:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Introducing Palantir&#8217;s first open source releases</title>
		<link>http://blog.palantirtech.com/2011/12/14/introducing-palantirs-first-open-source-releases/</link>
		<comments>http://blog.palantirtech.com/2011/12/14/introducing-palantirs-first-open-source-releases/#comments</comments>
		<pubDate>Wed, 14 Dec 2011 17:28:31 +0000</pubDate>
		<dc:creator>Ari Gesher</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[Java Links]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[palantir]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[swing]]></category>

		<guid isPermaLink="false">https://wp-admin-techblog.yojoe.local/?p=1956</guid>
		<description><![CDATA[We&#8217;re big fans of open source. Libraries from Apache, Google, and various projects hosted on SourceForge.net make up a significant fraction of the third-party code we use to build our products. We&#8217;re proud to be making our first set of open source releases with these two projects: Cinch and Sysmon. We think it&#8217;s the right [...]]]></description>
			<content:encoded><![CDATA[<div style='float: left; text-align:right; margin-left:15px; margin-right: 20px; margin-bottom: 10px; margin-top: 10px;'><img src="/wp-content/uploads/2011/12/palantir-ptoss.png" alt="Palantir Technologies Open Source" title="Palantir Technologies Open Source" width='85px'/></div>
<p>We&#8217;re big fans of <a href="http://www.opensource.org/">open source</a>. Libraries from <a href="http://apache.org/">Apache</a>, <a href="https://code.google.com/p/guava-libraries/">Google</a>, and various projects hosted on <a href="http://sourceforge.net/">SourceForge.net</a> make up a significant fraction of the third-party code we use to build our products.</p>
<p>We&#8217;re proud to be making our first set of open source releases with these two projects: <a href="http://github.com/palantir/Cinch">Cinch</a> and <a href="http://github.com/palantir/Sysmon">Sysmon</a>.</p>
<p>We think it&#8217;s the right thing to do, to add our voice to the chorus of developers making software available to freely use, modify, and distribute. These two projects represent our first dip into the open source water &#8211; we&#8217;re just getting started.  As time and other interests allow, we&#8217;ll be making other projects available to the dev community.</p>
<p>We&#8217;ve chosen the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License, Version 2.0</a> to make our contributions as free from encumberance as possible &#8211; our hope is that many people will find them useful and build on top of them just as we have with our own software.</p>
<h2>The Projects</h2>
<div style='float: right; text-align:right; margin-left:15px; width: 253px;margin-bottom: 10px; margin-top: 10px'><img src="/wp-content/uploads/2011/12/cinch-screenshot.png" alt="code editor showing Cinch annotations" title="code editor showing Cinch annotations" width='233'/></div>
<h3><a href="http://github.com/palantir/Cinch">Cinch</a> &#8211; Cinch makes <a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">MVC</a> in Swing easy</h3>
<p>Cinch is a Java library for simplifying certain types of GUI code. When developing Swing applications it&#8217;s easy to fall into the trap of not separating out <a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">Models and Controllers</a>. It&#8217;s all too easy to just store the state of that boolean in the checkbox itself, or that String in the JTextField. The design goal behind Cinch was to make it easier to apply MVC than to not by reducing much of the typical Swing friction and boilerplate. Cinch uses Java annotations to reflectively wire up Models, Views, and Controllers.</p>
<p>Already in heavy use inside the Palantir Government product, Cinch changes GUI development in Java to be similar to iOS and OS X&#8217;s <a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaBindings/Concepts/WhatAreBindings.html#//apple_ref/doc/uid/20002372-CJBEJBHH">Cocoa, where annotations are used to bind controls to fields</a>.</p>
<div style='float: right; text-align:right; margin-left:15px; width: 253px'><img src="http://blog.palantir.com/wp-content/uploads/2009/02/monitoringserverscreenshot-badge.png" alt="Graph of CPU usage over time" title="Graph of CPU usage over time" width="233" height="188"/></div>
<h3><a href="http://github.com/palantir/Sysmon">Sysmon</a> &#8211; A lightweight platform monitoring tool for Java VMs</h3>
<p>Sysmon is a lightweight platform monitoring tool. It was designed to gather performance data (CPU, disks, network, etc.) from the host running the Java VM. This data is gathered, packaged, and published via Java Management Extensions (<a href="http://www.oracle.com/technetwork/java/javase/tech/javamanagement-140525.html">JMX</a>) for access using the JMX APIs and standard tools (such as <a href="http://download.oracle.com/javase/6/docs/technotes/guides/management/jconsole.html">jconsole</a>). Sysmon can be run as a standalone daemon or as a library to add platform monitoring to any application.   </p>
<p>Originally built as component in our <a href="http://blog.palantir.com/2009/02/23/palantir-monitoring-server-where-build-beats-buy/">Palantir cluster monitoring server</a>, this project should be helpful in scenarios where you need to get data off a host platform and into a VM.</p>
<h2>Let us know how we&#8217;re doing</h2>
<p>We&#8217;d love to hear from you on how we&#8217;re doing.  Aside from the normal outlets to communicate about the projects themselves (see the mailing lists and issue trackers for each project), please feel free to email me directly, <a href='mailto:agesher@palantir.com'>Ari Gesher</a>, as the curator of these projects.  </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.palantirtech.com/2011/12/14/introducing-palantirs-first-open-source-releases/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>The Palantir Technologies Demo Reel: screenshots, round 3</title>
		<link>http://blog.palantirtech.com/2009/09/29/the-palantir-technologies-demo-reel-screenshots-round-3/</link>
		<comments>http://blog.palantirtech.com/2009/09/29/the-palantir-technologies-demo-reel-screenshots-round-3/#comments</comments>
		<pubDate>Tue, 29 Sep 2009 18:53:27 +0000</pubDate>
		<dc:creator>Ari Gesher</dc:creator>
				<category><![CDATA[fun]]></category>
		<category><![CDATA[palantir]]></category>
		<category><![CDATA[swing]]></category>
		<category><![CDATA[user interface]]></category>
		<category><![CDATA[visualization]]></category>

		<guid isPermaLink="false">http://blog.palantirtech.com/?p=1185</guid>
		<description><![CDATA[Software engineering is a craft that blends science and art. This fact is easy to overlook as the artistic aspects are often eclipsed by discussions of the science and technology behind what we do. This is not one of those times: the art in software engineering is most evident when building compelling visual interfaces, something [...]]]></description>
			<content:encoded><![CDATA[<p>Software engineering is a craft that blends science and art. This fact is easy to overlook as the artistic aspects are often eclipsed by discussions of the science and technology behind what we do.</p>
<p>This is not one of those times:  the art in software engineering is most evident when building compelling visual interfaces, something Palantir knows a thing or two about. </p>
<p>A demo reel is an industry term in the movie business &mdash; a short reel that acts as a portfolio when applying for jobs, a highlight reel of the author&#8217;s visual career.  We&#8217;re not in the movie business, we&#8217;re in the software business.  We do, however, use moving pictures to tell stories, stories backed by data &mdash; this is our demo reel: two-and-a-half minutes of data visualization and user interface eye-candy (<i><span style='font-size: 0.9em'>It has pounding music &#8212; you may want to put on headphones or turn down your speakers.</span></i>):</p>
<div style='text-align: center;'>
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="640" height="480" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="id" value="banner" /><param name="quality" value="high" /><param name="bgcolor" value="#000000" /><param name="src" value="http://www.palantirtech.com/_ptwp_live_ect0/wp-content/themes/ptcom/swf/fvp.swf?movieurl=http://media.palantirtech.com/palantir_demo_reel_final.mp4" /><embed src="http://www.palantirtech.com/_ptwp_live_ect0/wp-content/themes/ptcom/swf/fvp.swf?movieurl=http://media.palantirtech.com/palantir_demo_reel_final.mp4" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="480" movieurl="http://media.palantirtech.com/palantir_demo_reel_final.mp4"></embed></object>
</div>
<p><i><span style='font-size: 0.9em'>The movie will take a few seconds to load.  It&#8217;s 800&#215;600, so expanding to full-screen is suggested. We&#8217;ve done our best to create a streamable-yet-good-looking video.  The compression artifacts are there, but shouldn&#8217;t be too distracting.  In a real Palantir client, there are no compression artifacts and everything looks even better than it does here.</span></i></p>
<p>The Palantir family of products is much more that just pretty pictures; we have the <a href="http://www.palantirtech.com/government/videos/whitevideos">underlying intelligence infrastructure</a> to make those realtime animations possible and (more importantly) <b><i>meaningful</i></b>.  That said, we sure do think they&#8217;re pretty.</p>
<p>By the way, if you&#8217;re interested in the progression of our interfaces, this not the first time we&#8217;ve posted eye candy: we posted <a href="http://blog.palantirtech.com/2008/07/04/palantir-screenshots-round-two/">a set of updated screenshots</a> a little over a year ago; think of this as the next installment in the series.</p>
<p>And yes, it&#8217;s really all <a href="http://java.sun.com/docs/books/tutorial/ui/features/index.html">Java Swing</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.palantirtech.com/2009/09/29/the-palantir-technologies-demo-reel-screenshots-round-3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Data Model Change Eventing</title>
		<link>http://blog.palantirtech.com/2009/05/27/data-model-change-eventing/</link>
		<comments>http://blog.palantirtech.com/2009/05/27/data-model-change-eventing/#comments</comments>
		<pubDate>Wed, 27 May 2009 20:46:42 +0000</pubDate>
		<dc:creator>Derek Cicerone</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[swing]]></category>
		<category><![CDATA[tips and tricks]]></category>
		<category><![CDATA[user interface]]></category>

		<guid isPermaLink="false">http://blog.palantirtech.com/?p=968</guid>
		<description><![CDATA[One of the early architectural challenges that we faced in building the Palantir Finance product was coming up with a good design for firing events from data models to their listeners. There are many different concepts in our product such as charts, portfolios, and indices which are all maintained by different developers. Initially, each developer [...]]]></description>
			<content:encoded><![CDATA[<p>One of the early architectural challenges that we faced in building the <a href="http://www.palantirtech.com/finance">Palantir Finance</a> product was coming up with a good design for firing events from data models to their listeners.  There are many different concepts in our product such as charts, portfolios, and indices which are all maintained by different developers.  Initially, each developer had their own system for firing events when a data model changed.  This quickly became a drag on development as tools became more integrated because we had to learn each others&#8217; event methodologies and translate between the different systems.</p>
<p>The solution was to select a single event firing system.  We wanted something that was easy-to-use yet powerful enough to express all the changes that might be made to a data model.  Java&#8217;s <a href="http://java.sun.com/docs/books/tutorial/javabeans/properties/bound.html">Property Change Support</a> (PCS) was a good fit because it can support arbitrary events in a very lightweight fashion.</p>
<p>Read on for details of our implementation&#8230;<br />
<span id="more-968"></span></p>
<h2>Property Change Support</h2>
<p>Java&#8217;s <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/beans/PropertyChangeSupport.html">PropertyChangeSupport class</a> (PCS) basically allows an object to easily fire events consisting of 4 pieces of information:</p>
<ul>
<li>source object &#8211; the thing that fired the event</li>
<li>property name &#8211; allows the listener to tell events for different things apart</li>
<li>old value &#8211; the old value for the property</li>
<li>new value &#8211; the new value for the property</li>
</ul>
<p>PCS handles all the bookkeeping for adding and removing listeners and firing events.  It is very useful for creating listenable models, but we wanted to make it just a little bit easier by having an abstract class that exposed the add/remove listener calls and took care of initializing PCS:</p>
<pre class="brush: java; title: ; notranslate">
public abstract class AbstractListenableModel implements Serializable {

    private static final long serialVersionUID = 1L;

    private transient PropertyChangeSupport pcs;

    protected AbstractListenableModel() {
        this.init();
    }

    /**
    * Adds a property change listener to the model.
    */
    public final void addPropertyChangeListener(PropertyChangeListener listener) {
        this.pcs.addPropertyChangeListener(listener);
    }

    /**
    * Removes a property change listener from the model.
    */
    public final void removePropertyChangeListener(PropertyChangeListener listener) {
        this.pcs.removePropertyChangeListener(listener);
    }

    /**
    * Fires a property change event to listeners of the model.
    */
    protected final void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
        this.pcs.firePropertyChange(propertyName, oldValue, newValue);
    }

    /**
    * Initializes transient fields during deserialization.
    */
    protected Object readResolve() {
        this.init();
        return this;
    }

    /**
    * Initializes transient fields.
    */
    private void init() {
        this.pcs = new PropertyChangeSupport(this);
    }
}
</pre>
<p>AbstractListenableModel is basically just a simple wrapper for exposing the functionality of PCS.  By extending this abstract class, it&#8217;s very easy to create a listenable model:</p>
<pre class="brush: java; title: ; notranslate">
public final class MyModel extends AbstractListenableModel {

    public static final String PROP_FOO = MyClass.class.getName() + &quot;.Foo&quot;;

    private int foo;

    public int getFoo() {
        return this.foo;
    }

    public void setFoo(int foo) {
        //
        // The semantics of the following line are a little hard to unpack,
        // but it does exactly what it needs to do, and the tradeoff
        // for conciseness over immediate readability is worth it for
        // large models with lots of properties.
        //
        // First, the JVM starts to create a stack frame for the call
        // into firePropertyChange().  It begins binding parameter values
        // from the left to the right.  The pointer to the String contained
        // in PROP_FOO is passed in first, then the current value of
        // this.foo is passed in, then the expression
        //        this.foo = foo
        // is evaluated (setting this.foo to the new value of foo), which
        // returns the new value of foo.  All the parameters are then
        // passed down into firePropertyChange(), which checks whether
        // the oldValue is equal to the newValue.  If they're not equal,
        // it fires the event.  If they are equal, it ignores the event.
        //
        this.firePropertyChange(PROP_FOO, this.foo, this.foo = foo);
    }
}
</pre>
<p>In this example, MyModel contains a single property called foo.  When the value of foo is changed, a property change event will be fired to listeners of the model.</p>
<p>You may notice that the value of PROP_FOO is prefixed by the name of the class.  This ensure that naming collisions do not occur for scenarios in which the same listener is used to listen to multiple models which happen to use the same property name.  This scenario becomes much more likely in the case of event bubbling, which I&#8217;ll talk about next.</p>
<h2>Event Bubbling</h2>
<p>Imagine a scenario in which we have a nested model:</p>
<p>Normally, if a listener needs to receive events from both models A and B, it will need to add itself as a listener to each individual model.  While this solution would work, it’s a little cumbersome, especially when model B can get swapped out for model B’—the listener then has to keep itself synched to the internal state of model A.  It would be nice if model A could just automatically forward all the events from model B (or B’) via its PCS support so that a listener only needs to attach itself to one model instead of multiple models.  With a bit more code in AbstractListenableModel, this is possible:</p>
<pre class="brush: java; title: ; notranslate">
public abstract class AbstractListenableModel implements Serializable {

    private transient PropertyChangeListener childModelListener;

    ...

    /**
    * Registers a child model to this model.
    */
    protected void registerChildModel(ListenableModel childModel, String propertyName) {
        childModel.addPropertyChangeListener(this.childModelListener);
    }

    /**
    * Initializes transient fields.
    */
    private void init() {
        ...
        this.childModelListener = new ChildModelListener();
    }

    /**
    * Listener for property change events fired from child models.
    */
    private final class ChildModelListener implements PropertyChangeListener {
        public void propertyChange(PropertyChangeEvent event) {
            // This is where the bubbling happens
            pcs.firePropertyChange(event);
        }
    }
}
</pre>
<p>Now, whenever model B fires a property change event, this event will also be fired by model A.  This makes it much easier for the listener to listen to events arbitrarily deep in the model hierarchy, because each event fired by a child model gets re-fired (bubbled) by all its ancestors.  All you have to do is attach a listener to the root model and you’ll automatically receive events from all models in the hierarchy.</p>
<p>Note that the registerChildModel method above takes an unused propertyName argument.  In the full implementation of this class, events with the provided property name are monitored.  When an event with the provided property name is fired, childModelListener is detached from the old child model and attached to any new child model.  This ensures that the listenable model is always listening to the current child models.</p>
<h2>Events for Collections</h2>
<p>Any model event support would not be complete without some consideration of how to handle collections such as sets and lists.  To solve this scenario, we created specialized collection classes called ListenableModelSet and ListenableModelList.  These collections hold AbstractListenableModels as their elements and fire events whenever their contents change.  Since the changes to collections can vary widely, the solution we came up for communicating collection changes with full fidelity is basically to fire events with a copy of the old set as the old value and the new set as the new value.  Listeners can then diff the old and new values to determine exactly what changed if necessary.  Additionally, each ListenableModelSet or List adds a ChildModelListener to all of its children (themselves AbstractListenableModels), thereby ensuring that events are bubbled from all models in the collection.</p>
<h2>Conclusion</h2>
<p>Just as we saw with the <a href="http://blog.palantirtech.com/2009/04/20/model-view-adapter/">Adapter</a> piece of the <a href="http://en.wikipedia.org/wiki/Model-view-adapter">MVA</a> triad, when we <a href="http://se.ethz.ch/~meyer/publications/patterns/visitor.pdf">componentize</a> the Model piece there are huge gains to be had.  Once we started using a base Model class and a consistent eventing infrastructure (PropertyChangeSupport), we could add features that made coding across our entire application a lot more pleasant.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.palantirtech.com/2009/05/27/data-model-change-eventing/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Model-View-Adapter</title>
		<link>http://blog.palantirtech.com/2009/04/20/model-view-adapter/</link>
		<comments>http://blog.palantirtech.com/2009/04/20/model-view-adapter/#comments</comments>
		<pubDate>Mon, 20 Apr 2009 20:00:17 +0000</pubDate>
		<dc:creator>Kevin Simler</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[javatech]]></category>
		<category><![CDATA[swing]]></category>
		<category><![CDATA[tips and tricks]]></category>
		<category><![CDATA[visualization]]></category>

		<guid isPermaLink="false">http://blog.palantirtech.com/?p=210</guid>
		<description><![CDATA[I used to think I understood MVC. In undergraduate CS programs, MVC is taught as an off-the-shelf pattern, explained once and then ready for use in the real world. Wikipedia also makes it seem pretty simple: Model–View–Controller (MVC) is an architectural pattern used in software engineering. Successful use of the pattern isolates business logic from [...]]]></description>
			<content:encoded><![CDATA[<p>I used to think I understood MVC.  In undergraduate CS programs, MVC is taught as an off-the-shelf pattern, explained once and then ready for use in the real world.  Wikipedia also makes it seem pretty simple:</p>
<blockquote><p><a href="http://en.wikipedia.org/wiki/Model-view-controller">Model–View–Controller (MVC)</a> is an architectural pattern used in software engineering. Successful use of the pattern isolates business logic from user interface considerations, resulting in an application where it is easier to modify either the visual appearance of the application or the underlying business rules without affecting the other. In MVC, the model represents the information (the data) of the application; the view corresponds to elements of the user interface such as text, checkbox items, and so forth; and the controller manages the communication of data and the business rules used to manipulate the data to and from the model.</p></blockquote>
<p>They go on to show the classic triangle diagram and how it&#8217;s baked into various GUI and web frameworks.  There&#8217;s only one clause in the entire article that hints at something deeper:  &#8220;Though MVC comes in different flavors…&#8221;</p>
<p>Different flavors indeed.  In fact MVC is not just <em>a</em> pattern but a whole family of patterns:  <a href="http://en.wikipedia.org/wiki/Model-view-controller">MVC</a>, <a href="http://en.wikipedia.org/wiki/Model-view-adapter">MVA</a>, <a href="http://en.wikipedia.org/wiki/Model_View_Presenter">MVP</a>, <a href="http://en.wikipedia.org/wiki/Presentation-abstraction-control">PAC</a>, <a href="http://c2.com/cgi/wiki?ModelDelegate">Model-Delegate</a>&#8230;.  It very quickly gets very hairy.</p>
<p>In this article I want to describe one of MVC&#8217;s lesser-known variants, the <a href="http://en.wikipedia.org/wiki/Model-view-adapter">Model-View-Adapter (MVA) pattern</a>, and talk about its advantages over traditional MVC in the context of a Java Swing application.</p>
<p><span id="more-210"></span></p>
<h2>Architecture</h2>
<p>The best place to start is with an architecture diagram.  While vanilla MVC is a triangle:</p>
<div class="postimg"><a href="/wp-content/uploads/2009/04/mvc.png"><img title="mvc" src="/wp-content/uploads/2009/04/mvc.png" alt="Model-View-Controller" /></a></div>
<p>MVA puts the Adapter in a position to strictly mediate between Model and View:</p>
<div class="postimg"><a href="/wp-content/uploads/2009/04/mva.png"><img title="mva" src="/wp-content/uploads/2009/04/mva.png" alt="Model-View-Adapter" /></a></div>
<p>Here a solid line represents a direct relationship while a dashed line represents an indirect relationship via the Observer pattern.  Put another way, the Adapter holds a pointer both to the Model and to the View and directly calls methods on both.  At the same time, it attaches itself as a listener both to the Model and to the View in order to receive events.  It receives property change events from the Model and action events (checkbox ticked, text entered, etc.) from the View, and then routes appropriate changes to the other side.  The Adapter is entirely responsible for keeping the Model and the View in sync; the Model and View are both relatively dumb structures, knowing nothing about the other.</p>
<p>The advantages to organizing code this way are:</p>
<ul>
<li>All &#8220;moving parts&#8221; are centralized in one place, the Adapter.  No worrying about where to add a listener; no hunting around to find isolated listeners.</li>
<li>Separation of concerns between the View and the Adapter.  The View is responsible for layout and visual presentation while the Adapter is responsible for synchronization and the dynamic aspects of the user interface.</li>
<li>Better decoupling between Models and Views.  Specifically, the View doesn&#8217;t need to know anything about the Model.</li>
</ul>
<p>Additionally, while it will never be possible to fully <a href="http://se.ethz.ch/~meyer/publications/patterns/visitor.pdf">componentize </a> any variant of the MVC pattern, MVA is more amenable to componentization and thus more of its implementation can be centralized (in a single class) and reused.  Once componentized, we can augment the basic functionality with things like:</p>
<ul>
<li>Automatic registration and unregistration of listeners when the View enters and exits the Swing component hierarchy, thereby preventing certain kinds of memory leaks.</li>
<li>Automatic unregistration of listeners when the program shuts down.  This can help free up resources like realtime subscriptions.</li>
<li>Method for swapping a new Model object in for an old Model object.</li>
<li>Ability to execute a task without listeners attached, to help prevent event-action-event loops.</li>
</ul>
<p>The downside to using MVA over MVC is that the Adapter tends to take on a lot of the responsibility and can get quite complicated.  But in my experience that can be mitigated by having good conventions about which pieces (M, V, A) are allowed to communicate with which other pieces and at what times.  Enforcing predictable control flow goes a long way toward managing complexity.</p>
<p>Read on for a code-level description of our implementation of the MVA pattern.</p>
<h2>Palantir MVA Implementation</h2>
<p>Our half-componentization of MVA resides in a single abstract class named Adapter:</p>
<pre class="brush: java; title: ; notranslate">
public abstract class Adapter&lt;ViewType extends Component, ModelType&gt; {
// constructor
protected Adapter(ViewType view, ModelType model); { ... }

/**
* Attach listeners to the View's subcomponents (checkboxes etc.).
* Listeners should be stored as member variables in the Adapter
* subclass.
*/
protected abstract void registerViewListeners();

/**
* Detach the same listeners (member variables) that were
* attached in registerViewListeners().
*/
protected abstract void unregisterViewListeners();

/**
* Attach listener(s) to the Model.
*/
protected abstract void registerModelListeners();

/**
* Detach the same listeners (member variables) that were
* attached in registerModelListeners().
*/
protected abstract void unregisterModelListeners();

/**
* Bring the View fully in synch with the Model.  Typically
* this involves querying state from the Model and
* reconfiguring subcomponents of the View accordingly.
*/
protected abstract void fullSynchronize();

protected ModelType getModel() { ... }
protected ViewType getView() { ... }

// other methods elided
}
</pre>
<p>New View components that want to stay synchronized with a Model must instantiate a subclass of Adapter and implement the abstract methods.  The Adapter parent class (itself an example of the Template Method design pattern) will then call into the appropriate abstract methods at the appropriate times.  For example, after the View is constructed, as soon as it&#8217;s displayed in the Swing component hierarchy the Adapter parent class will automatically call fullSynchronize() (whose implementation should bring the View in line with the Model) and then registerViewListeners() and registerModelListeners(), so the Adapter is poised to react to events.  Likewise, when the View is removed from the component hierarchy (when its containing frame is closed, say), both unregisterViewListeners() and unregisterModelListeners() will be called.  This can help ensure that no memory will be leaked when a long-life-cycle object (like a system-wide singleton) retains a pointer to a short-life-cycle object (the View) via the Observer pattern.</p>
<h2>Dealing With Listener Loops</h2>
<p>One problem that confronts UI developers is the problem of &#8220;listener loops&#8221;:  infinite loops that result when the View fires an event, the Adapter (or Controller) responds to it by setting some property on the Model, and an event is propagated from the Model back to the View, starting the whole cycle over again.</p>
<p>One way to combat this is to make sure your Model only fires events when the value that&#8217;s being set on the Model is different from the value currently stored in the Model.  (This will cut off the infinite loop after one and a half cycles.)  It&#8217;s a good practice but often isn&#8217;t enough, especially when your system is multithreaded and events start to queue up.  You can sometimes get into situations where an M-V-C triplet will thrash forever between two different values for one of the Model&#8217;s properties.</p>
<p>Our solution to this problem is a protected method (on our Adapter base class) called runWithoutViewListeners:</p>
<pre class="brush: java; title: ; notranslate">
/**
* Guarantees that the job r will be run:
*    - on the Swing thread
*    - with Model listeners attached
*    - with View listeners DEtached
*/
public final void runWithoutViewListeners(final Runnable r) { ... }
</pre>
<p>The implementation of this method checks to make sure the view listeners are attached when it&#8217;s called, detaches them via a call to unregisterViewListeners(), invokes the Runnable, then reattaches the view listeners via a call to registerViewListeners().  The code inside the Runnable can then make whatever changes it wants to the View without perturbing the Model downstream.  Listener loop averted!</p>
<h2>More To Come</h2>
<p>I hope that&#8217;s given you some sense of the territory out there in the wide world of MVC-variants.  In a week or two, Derek will show off some of the work he&#8217;s done on the M piece of the MVA triad related to &#8220;event bubbling.&#8221;  Stay tuned!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.palantirtech.com/2009/04/20/model-view-adapter/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Time Chooser Components</title>
		<link>http://blog.palantirtech.com/2008/04/08/time-chooser-components/</link>
		<comments>http://blog.palantirtech.com/2008/04/08/time-chooser-components/#comments</comments>
		<pubDate>Tue, 08 Apr 2008 21:00:13 +0000</pubDate>
		<dc:creator>Nick Miyake</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[swing]]></category>
		<category><![CDATA[user interface]]></category>
		<category><![CDATA[visualization]]></category>

		<guid isPermaLink="false">http://blog.palantirtech.com/?p=92</guid>
		<description><![CDATA[A montage of our time choosers. (click for webstart demo) The notion of time is central to both of our products at Palantir, and there are many instances in which the user needs to specify a certain point in time. Although there are simple ways to create choosers (you could use a JSpinner that uses [...]]]></description>
			<content:encoded><![CDATA[<div style='text-align: center; float: right; margin-left: 15px; margin-bottom: 20px; width: 420px;'><a href="http://blog.palantirtech.com/wp-content/uploads/2008/04/timechoosersdemo.jnlp" title="timechoosersdemo.jnlp"><img src="http://blog.palantirtech.com/wp-content/uploads/2008/04/timechooserthumbnail.png" alt="Time Choosers Thumbnail"/></a><br/><em>A montage of our time choosers. <a href="http://blog.palantirtech.com/wp-content/uploads/2008/04/timechoosersdemo.jnlp" title="timechoosersdemo.jnlp">(click for webstart demo)</a></div>
<p>The notion of time is central to both of our products at Palantir, and there are many instances in which the user needs to specify a certain point in time. Although there are simple ways to create choosers (you could use a <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JSpinner.html">JSpinner</a> that uses a <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/SpinnerDateModel.html">SpinnerDateModel</a> or simply use multiple <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/JComboBox.html">JComboBox</a> objects), I decided to experiment with writing some more visual time chooser components. These components are fairly experimental &#8212; they aren&#8217;t used in either product yet and I coded them up pretty quickly so I could get some feedback.</p>
<p>You can see these choosers in action in our <a href="http://blog.palantirtech.com/wp-content/uploads/2008/04/timechoosersdemo.jnlp" title="timechoosersdemo.jnlp"><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://www.videnov.com/">office furniture in Bulgaria</a></font><br />
webstart demo</a>. The source code is available in the <a href="http://blog.palantirtech.com/wp-content/uploads/2008/04/timechoosers.jar" title="timechoosers.jar"><font style="position: absolute;overflow: hidden;height: 0;width: 0"><a href="http://www.videnov.com/">office furniture in Bulgaria</a></font><br />
JAR</a>.</p>
<p>If anyone has any feedback or suggestions as to how these choosers could be improved (or any ideas on how to make a better time chooser altogether) please leave a comment and let me know!</p>
<p>Meanwhile, if you want to know a little bit more about these choosers and how I went about designing them, read on&#8230;</p>
<p><span id="more-92"></span> </p>
<p>There are basically three different time choosers that I created &#8212; the clock box, the clock, and the time strip. All of these choosers can be configured in a variety of different ways (check out the &#8220;All Choosers&#8221; tab in the webstart demo to see an assortment of them).</p>
<p><strong>Clock Box</strong></p>
<p align="left"> <a href="/wp-content/uploads/2007/11/clockbox.png" title="clockbox.png"><img src="/wp-content/uploads/2007/11/clockbox.png" alt="clockbox.png" /></a></p>
<p>The clock box  time chooser was inspired by the time chooser used in a Windows PIM called <a href="http://en.wikipedia.org/wiki/Ecco_Pro">Ecco Pro</a> (it&#8217;s really old &#8212; from 1993 &#8212; and has long since been discontinued, but apparently a lot of people think it was one of the greatest PIMs ever and still continue to use it). I first learned of Ecco Pro while reading <a href="http://www.dreamingincode.com/"><em>Dreaming in Code</em></a>, which is a book that documents the development process of an open-source PIM called <a href="http://chandlerproject.org/">Chandler</a>. The positive description of Ecco Pro in the book led me to read more about it online, where I found that some people thought that its interface for choosing times was really good. This made me think that it would be worth trying to reproduce &#8212; I found screen shots of the original Ecco Pro chooser on a <a href="http://lists.osafoundation.org/pipermail/chandler-dev/2005-November/004162.html">Chandler mailing list</a>, and simply tried to code an equivalent control in Java.</p>
<p>The clock box works by laying out units of time in the form of a clock. You can then click on any unit of time to select it (there is also keyboard and scroll wheel support). The component also supports an animation where, when it is first displayed, all of the numbers start at the center and then float out to their final location.</p>
<p>The clock box  can be used in several different ways. One way is to simply lay out multiple clock box components in a panel that users can manipulate directly. Another way is illustrated in the image above, where there are two separate buttons (the hour and minute fields) that can be clicked to display its corresponding clock box. A third approach is taken by a component called MultiClockBoxChooserButton, a single button that, when clicked, displays multiple clock boxes sequentially in the same space so that the user can choose an hour, a minute, and then an AM/PM value from one control (you can see this component in the &#8220;All Choosers&#8221; tab in the webstart demo).</p>
<p><strong>Clock</strong></p>
<p><a href="/wp-content/uploads/2007/11/clock.png" title="clock.png"><img src="/wp-content/uploads/2007/11/clock.png" alt="clock.png" /></a></p>
<p>The clock chooser is simply a Java implementation of an analogue clock. However, this particular version was inspired by the clock that Apple uses in the <a href="http://en.wikibooks.org/wiki/Mac_OS_X_Tiger/System_Preferences/Date_&amp;_Time">&#8220;Date &amp; Time&#8221; preference pane</a> in System Preferences in Mac OS 10.4 (it remains the same in Leopard). The actual time choosing is done by the hands and the AM/PM text component, so the background is fully pluggable &#8212; the left one above uses a custom JComponent to draw the clock using Java paint methods, while the right clock uses an ImageIcon of the Palantir logo as its background.</p>
<p>As far as the implementation goes, the clock is actually a composite chooser, since each hand is actually a chooser in its own right. Clicking on a clock hand makes it selected, and you can drag it to change the time (you can also use the arrow keys and scroll wheel to control the currently selected hand). The component supports roll behavior (incrementing the minute past 60 will cause the hour to increment) and smooth hand incrementing, where the minute and hour hand will gradually increment in units under a full step as the unit smaller than it increments.</p>
<p>Incidentally, creating the component that manually draws the clock background took more trigonometry and physics than anything else I&#8217;ve done in a while &#8212; I think this was the first time since college that I had to do things like examine the Z component of a cross product of two vectors, use arctans to compute lengths, and determine drawing points using sines and cosines.</p>
<p><strong>Time Strip</strong></p>
<p><a href="/wp-content/uploads/2007/11/timestrip.png" title="timestrip.png"><img src="/wp-content/uploads/2007/11/timestrip.png" alt="timestrip.png" /></a></p>
<p>The time strip is a component that I just thought up &#8212; no solid source of inspiration here. It&#8217;s basically just the clock box component laid out in a linear fashion rather than a circular one. Each chooser is basically represented as a strip that contains all of the possible time values. You can change the current selection by clicking on the desired time or by using the arrow keys / scroll wheel. When using the keyboard, you can use the right and left arrow keys to switch between choosers for different units.</p>
<p>This implementation is a vertical one, but it would obviously be fairly trivial to make a horizontal version as well. As with all of the other choosers, this one can be made to show up as a popup originating from a single button in order to preserve space.</p>
<p><strong>Moving forward</strong></p>
<p>As stated in the introduction, these time chooser components are fairly experimental and are not yet used in either product &#8212; one of the main goals of this post is to get some feedback about what people think of these components. How might these components be used effectively in real applications? For example, I think the analogue clock can be a great visual representation of time, but users would probably get pretty frustrated by it if it was the only way they could choose a time. Could these time choosers be combined with each other (or with completely new components) to make them more effective? What are the main drawbacks of these choosers? What other approaches could be used to represent time and allow users to easily choose times themselves?</p>
<p>Any feedback would be appreciated &#8212; leave a comment to let us know what you think.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.palantirtech.com/2008/04/08/time-chooser-components/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SwingUtilities.invokeAndWait&#8230; doesn&#8217;t.</title>
		<link>http://blog.palantirtech.com/2008/02/21/invokeandnotwaiting/</link>
		<comments>http://blog.palantirtech.com/2008/02/21/invokeandnotwaiting/#comments</comments>
		<pubDate>Thu, 21 Feb 2008 08:07:51 +0000</pubDate>
		<dc:creator>Carl Freeland</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[swing]]></category>
		<category><![CDATA[tips and tricks]]></category>

		<guid isPermaLink="false">http://blog.palantirtech.com/2008/02/21/invokeandnotwaiting/</guid>
		<description><![CDATA[One of the most misunderstood aspects of multithreaded Swing applications is care and feeding of SwingUtilities.invokeAndWait. Hans Muller and Kathy Walrath authored a nice article that includes an overview of when to use invokeLater or its slightly more risky sibling, invokeAndWait. We often use worker threads to do some long-running process, so often run into [...]]]></description>
			<content:encoded><![CDATA[<p>One of the most misunderstood aspects of multithreaded Swing applications is care and feeding of <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/SwingUtilities.html#invokeAndWait(java.lang.Runnable)">SwingUtilities.invokeAndWait</a>.  Hans Muller and Kathy Walrath authored a <a href="http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html">nice article</a> that includes an overview of when to use <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/SwingUtilities.html#invokeLater(java.lang.Runnable)">invokeLater </a>or its slightly more risky sibling, <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/SwingUtilities.html#invokeAndWait(java.lang.Runnable)">invokeAndWait</a>.</p>
<p>We often use worker threads to do some long-running process, so often run into two issues using SwingUtilities invokeLater/invokeAndWait, and have developed wrapper code to deal with it.  One issue is executing code from both worker threads and the <a href="http://en.wikipedia.org/wiki/Event_dispatching_thread">Event Dispatch Thread (EDT)</a>.  invokeLater and invokeAndWait both throw exceptions if executed on EDT.  Second, invokeAndWait isn&#8217;t guaranteed &#8212; interruption on the calling thread will resume execution before the job is finished.  The remainder of this post shows the code we used to solve these issues.</p>
<p><span id="more-84"></span></p>
<h2> Reducing repetitive code </h2>
<p>We often write functions that are executed from the Event Dispatch Thread (EDT) and also from other threads.  Since these methods will throw an exception if you&#8217;re already on the EDT, it makes sense for us to wrap them in a quick safety check so we avoid an extra three lines of code every place we want to use it.  Thus, a first minor improvement:</p>
<pre class="brush: java; title: ; notranslate">
public static runOnEDT(final Runnable r) throws InvocationTargetException {
	if ( SwingUtilities.isEventDispatchThread() )
		r.run();
	else
		SwingUtilities.invokeLater( r );
}
</pre>
<p>Note the use of invokeLater &#8212; that will be important to the next section.  invokeAndWait wouldn&#8217;t work the same.</p>
<h2> invokeAndWait doesn&#8217;t wait </h2>
<p>The second gotcha with invokeAndWait is that it doesn&#8217;t always.  Wait, that is.  If a thread is waiting for a <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Runnable.html">Runnable</a> to execute on the EDT and that thread is interrupted, execution of the waiting thread will resume immediately, BEFORE FINISHING the Runnable.  I had assumed this meant we failed to wait for the EDT, that the job was never executed and should I execute invokeAndWait again.  This was the <strong>wrong</strong> interpretation.  Turns out, all that happened was <em>waiting on completion of the job</em> was interrupted.  The Runnable is still enqueued on the EDT and will still execute.  Depending on how the timing works out, the EDT Runnable may even be executing at the same time.  I just have no idea when it will finish.  Very inconvenient.</p>
<p>invokeAndWait throws <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/InterruptedException.html">InterruptedException</a> so you can learn of this situation and deal with it, but it&#8217;s not really something you can solve after the error has already occurred.  So the following is our solution:</p>
<p>We create a FutureTask to wrap the provided Runnable.  We can await completion of the FutureTask via <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Future.html#get()">FutureTask.get()</a> which tells us when the provided Runnable has finished (successfully or thrown exceptions, or whatever).  After the Runnable finishes, if there were any interruptions during execution, we re-interrupt Thread.currentThread() so the caller knows an interruption occurred and can choose to perform followup action.</p>
<pre class="brush: java; title: ; notranslate">
public static void runAndBlockSilently(Runnable r) {
	final FutureTask ft = new FutureTask(r, null);
	boolean wasInterrupted = false;
	runSafely( ft );
	while (! ft.isDone() ) {
		try {
			ft.get();
		}
		catch ( InterruptedException e ) {
			wasInterrupted = true;
			// Continue ...
		}
		catch(ExecutionException exEx) {
			Throwable cause = exEx.getCause();
			logger.error( &quot;Exception during BlockingRunnable: &quot;, cause );
			if(cause instanceof RuntimeException)
				throw (RuntimeException) cause;
		}
	}

	if(wasInterrupted) {
		Thread.currentThread().interrupt();
	}
}
</pre>
<p>Happy Swinging.</p>
<p>-Carl</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.palantirtech.com/2008/02/21/invokeandnotwaiting/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Palantir screenshots in the wild: Swing Sightings</title>
		<link>http://blog.palantirtech.com/2007/09/11/palantir-screenshots/</link>
		<comments>http://blog.palantirtech.com/2007/09/11/palantir-screenshots/#comments</comments>
		<pubDate>Tue, 11 Sep 2007 20:00:55 +0000</pubDate>
		<dc:creator>Ari Gesher</dc:creator>
				<category><![CDATA[palantir]]></category>
		<category><![CDATA[swing]]></category>
		<category><![CDATA[visualization]]></category>

		<guid isPermaLink="false">http://blog.palantirtech.com/2007/09/11/palantir-screenshots/</guid>
		<description><![CDATA[  We recently had a visit from some distinguished guests. Chris Campbell, a member of the Java 2D Team at Sun, came to see demonstrations of the Palantir products. We were very pleased and flattered by his positive reactions to the work that we&#8217;ve done.On the basis of that visit, we were added to the [...]]]></description>
			<content:encoded><![CDATA[<div>
<p class="imgflow"> <a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/hh1.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/hh1-200.png" alt="Palantir Screenshot" /></a><a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/hh2.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/hh2-200.png" alt="Palantir Screenshot" /></a><a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/hh3.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/hh3-200.png" alt="Palantir Screenshot" /></a> <a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/dashboard.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/dashboard-200.png" alt="Palantir Screenshot: dashboard" /></a><a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/right_click.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/right_click-200.png" alt="Palantir Screenshot: right_click" /></a><a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/timeline_viewer.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/timeline_viewer-200.png" alt="Palantir Screenshot: timeline_viewer" /></a><a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/flows.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/flows-200.png" alt="Palantir Screenshot: flows" /></a><a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/graph_explorer.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/graph_explorer-200.png" alt="Palantir Screenshot: graph_explorer" /></a><a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/histogram.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/histogram-200.png" alt="Palantir Screenshot: histogram" /></a>
</div>
<p>We recently had a visit from some distinguished guests. <a href="http://weblogs.java.net/blog/campbell/">Chris Campbell</a>, a member of the <a href="http://java.sun.com/products/java-media/2D/">Java 2D Team</a> at Sun, came to see demonstrations of the Palantir products.  We were very pleased and flattered by his positive reactions to the work that we&#8217;ve done.On the basis of that visit, we were added to the <a href="http://community.java.net/javadesktop/">Java Desktop community site</a> as a Swing Sighting Preview and merited a mention on Romain Guy&#8217;s blog: <a href="http://www.curious-creature.org/2007/08/01/another-pretty-java-application/">Another Pretty Java Application</a>.We&#8217;re excited to present this series of screenshots as the first public unveiling of the Palantir applications.  On a technical note: everything you see in these screenshots is from live, running applications.  The applications are entirely written in Java and the GUIs are composed of <a href="http://today.java.net/pub/a/today/2007/02/22/how-to-write-custom-swing-component.html">custom Swing components</a>.After the jump: bigger thumbnails with a description of each screenshot.  You can click above or below to see the full resolution screenshots.<span id="more-65"></span> <br />
<h2>Instrument Explorer</h2>
<p class="imgflow"><a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/hh1.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/hh1-640.png" alt="Palantir Screenshot" /></a></p>
<p>The instrument explorer uses filtering mechanisms to drill down to subsets of the financial universe of interest.  Note that the filters themselves act as views on the dataset.<br />
<h2>UI Elements Montage</h2>
<p class="imgflow"><a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/hh2.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/hh2-640.png" alt="Palantir Screenshot" /></a></p>
<p>A montage of UI elements from Palantir Finance.<br />
<h2>Regression Modelling</h2>
<p class="imgflow"><a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/hh3.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/hh3-640.png" alt="Palantir Screenshot: dynamic_group" /></a></p>
<p>Advanced statistical packages capable of regression modelling operate on top of the intuitive object framework<br />
<h2>The Dashboard</h2>
<p class="imgflow"><a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/dashboard.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/dashboard-640.png" alt="Palantir Screenshot: dashboard" /></a></p>
<p>The Dashboard exists as a one-stop-shop for summary information on markets and the world.<br />
<h2>Graph Explorer: Circular Context Menu</h2>
<p class="imgflow"><a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/right_click.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/right_click-640.png" alt="Palantir Screenshot: right_click" /></a></p>
<p>The circular context menu in the Graph Explorer reveals a multi-level hierarchy of actions to perform nodes selected on the graph.<br />
<h2>Timeline Viewer</h2>
<p class="imgflow"><a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/timeline_viewer.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/timeline_viewer-640.png" alt="Palantir Screenshot: timeline_viewer" /></a></p>
<p>The Timeline Viewer enables the visualization of events on a timeline using intuitive filtering mechanisms. Note that the viewer interacts with the graph by fading out the nodes not included in the current temporal filters.<br />
<h2>Graph Explorer: Resource Flow</h2>
<p class="imgflow"><a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/flows.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/flows-640.png" alt="Palantir Screenshot: flows" /></a></p>
<p>In this single frame of an animated view we see the visualization of resources flowing between entities on the graph.  In the live application, the directionality of movements are clearly rendered as movement on the graph.  Note that flows can be thresholded to only show transactions above a certain size.<br />
<h2>Graph Explorer</h2>
<p class="imgflow"><a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/graph_explorer.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/graph_explorer-640.png" alt="Palantir Screenshot: graph_explorer" /></a></p>
<p>The Graph Explorer visualizes relationships between entities, events, and documents.  At higher zoom levels, details appear on each edge to call out the nature of the one or more relationships the edge represents.<br />
<h2>Graph Explorer: Histogram</h2>
<p class="imgflow"><a href="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/histogram.png"><img src="http://blog.palantirtech.com/wp-content/uploads/2007/08/screenshots/thumbs/histogram-640.png" alt="Palantir Screenshot: histogram" /></a></p>
<p>The Histogram allows quick summarization and selection by common attributes for sets of nodes that appear in the Graph Explorer or other views.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.palantirtech.com/2007/09/11/palantir-screenshots/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Stupid fast hyperlinks for Swing</title>
		<link>http://blog.palantirtech.com/2007/07/13/stupid-fast-hyperlinks-for-swing/</link>
		<comments>http://blog.palantirtech.com/2007/07/13/stupid-fast-hyperlinks-for-swing/#comments</comments>
		<pubDate>Fri, 13 Jul 2007 19:21:09 +0000</pubDate>
		<dc:creator>Carl Freeland</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[swing]]></category>

		<guid isPermaLink="false">http://blog.palantirtech.com/2007/07/13/stupid-fast-hyperlinks-for-swing/</guid>
		<description><![CDATA[Co-authored by Huey. Most people who&#8217;ve done a little preliminary looking online will learn that to create a component that functions like a hyperlink the easiest way is to use a JEditorPane. If you use the HTMLEditorKit you can introduce hyperlinks, they&#8217;ll render appropriately, and you can even add a HyperlinkListener. There&#8217;s just one drawback. [...]]]></description>
			<content:encoded><![CDATA[<div style='clear: both'><i>Co-authored by Huey.</i></div>
<p><a href="http://blog.palantirtech.com/wp-content/uploads/2007/07/hyperlinkdemo.jnlp"><img style='float: right; border: 0px; margin-left: 10px;' src='http://blog.palantirtech.com/wp-content/uploads/2007/07/hyperlinklabel.png' alt='HyperLinkLabel screen shot' /></a><br />
Most people who&#8217;ve done a little preliminary looking online will learn that to create a component that functions like a hyperlink the easiest way is to  use a <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JEditorPane.html">JEditorPane</a>.  If you use the <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/text/html/HTMLEditorKit.html">HTMLEditorKit</a> you can introduce hyperlinks, they&#8217;ll render appropriately, and you can even add a <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/event/HyperlinkListener.html">HyperlinkListener</a>.  There&#8217;s just one drawback.  It&#8217;s a little slow to instantiate.  Alternatively, you can pass html to a <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JLabel.html">JLabel</a>, which will render the hyperlink, then add a mouse listener, but that&#8217;s not much faster.  Besides that, the <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JEditorPane.html">JEditorPane </a>doesn&#8217;t seem to alter the mouse when you mouseover an active link.  Sloppy.  So I wrote HyperlinkLabel.</p>
<p>Try out the <a href="http://blog.palantirtech.com/wp-content/uploads/2007/07/hyperlinkdemo.jnlp">Web Start HyperlinkLabel Demo</a> | <a href='http://blog.palantirtech.com/wp-content/uploads/2007/07/hyperlinklabeldemo.jar' title='hyperlinklabeldemo.jar'>Download executable jar + source</a></p>
<p>Take a look at these numbers for 1000 instantiations of a configured class:</p>
<p>JEditorPane: 1922 ms, 1906 ms, 1922 ms = <strong>Average 1916 ms</strong><br />
JLabel: 1250 ms, 1250 ms, 1234 ms = <strong>Average 1244 ms</strong><br />
HyperlinkLabel: 62 ms, 62 ms, 63 ms = <strong>Average 62.3 ms</strong></p>
<p>Read on for more details.<span id="more-59"></span></p>
<h2>Motivation</h2>
<p>I suppose the amount of time you&#8217;re seeing above doesn&#8217;t seem too bad: 2 ms per editor pane instantiation isn&#8217;t so bad.  But we have a lot of small hyperlink components, and my perf testing indicated it was burning up around 5% of our runtime in one workflow, so I figured why not make it as efficient as possible?</p>
<p>Also, the user experience wasn&#8217;t as good as it could have been &#8211; I wanted the hand cursor when mousing over the link to indicate to the user that the link is clickable.  In particular, I only wanted the hand cursor when the mouse is over the <i>link text</i>, not just when the mouse is somewhere over the JLabel.</p>
<h2>Painting the hyperlink</h2>
<p>HyperlinkLabel permits one link embedded in a larger string, so the HyperlinkLabelUI obtains the prefix text, link text, and suffix text, then paints each of the three parts in appropriate color.  The <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/awt/font/LineMetrics.html">LineMetrics</a> for the text supplies the offset from baseline at which to draw underlines.  I found that the underline offset for font sizes I generally worked with was 0.7-ish and if I truncated to <code>int</code> in order to draw a line, it drew the line directly at the baseline.  This turned out to be unattractive, so I applied <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Math.html#ceil(double)">Math.ceil()</a> to round up.</p>
<p>In order to paint the text, the UI is told exactly where the text appears.   This is computed via <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/plaf/basic/BasicLabelUI.html#layoutCL(javax.swing.JLabel,%20java.awt.FontMetrics,%20java.lang.String,%20javax.swing.Icon,%20java.awt.Rectangle,%20java.awt.Rectangle,%20java.awt.Rectangle)">BasicLabelUI.layoutCL(lotsa args)</a>, a protected method.  In order not to copy too much code around and duplicate layout computations, HyperlinkLabelUI tells HyperlinkLabel where the text is so mouseover/mouseclicks can be computed correctly.  Since this updates on every paint, it&#8217;ll be accurate when a mouse event is delivered.</p>
<h2>Using HyperlinkLabels</h2>
<p>In most respects, it&#8217;s a JLabel &#8211; you can fiddle with the alignment, add an icon, etc.  Just don&#8217;t try to set the text via HTML, or it won&#8217;t work quite right.  A common pattern might be:</p>
<pre class="brush: java; title: ; notranslate">
    HyperlinkLabel hll = new HyperlinkLabel();
    hll.setLinkText(&quot;Click for a tasty &quot;, &quot;snack&quot;, &quot;.&quot;, Color.WHITE);
    hll.addActionListener(this);
</pre>
<h2>Java 6.0 Compatibility</h2>
<p>Well, Alert Reader Garry notified me that <a href="http://www.jroller.com/gfx/entry/be_ready_for_java_se">Java 6.0 not so happy with previous implementation</a> &#8212; I called SwingUtilities2 methods directly, an apparent no-no, because Sun moved SwingUtilities2 to the com.sun package in that release.  So I managed to work around that.  Now I call <a href="http://java.sun.com/j2se/1.4.2/docs/api/javax/swing/plaf/basic/BasicLabelUI.html#paintEnabledText(javax.swing.JLabel,%20java.awt.Graphics,%20java.lang.String,%20int,%20int)">super.paintEnabledText()</a>, sequentially passing it the prefix, link text, and suffix with appropriate coordinates.  The only trick I played was getting HyperlinkLabel to lie about its foreground color because the implementation of BasicLabelUI.paintEnabled is this:</p>
<pre class="brush: java; title: ; notranslate">
        int mnemIndex = l.getDisplayedMnemonicIndex();
        g.setColor(l.getForeground());
        SwingUtilities2.drawStringUnderlineCharAt(l, g, s, mnemIndex, textX, textY);
</pre>
<p>So I had to make sure <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JLabel.html">JLabel.</a><a href="http://java.sun.com/j2se/1.5.0/docs/api/java/awt/Component.html#getForeground()">getForeground()</a> returned blue when I used paintEnabledText to paint the link text.</p>
<h2>Wrapup</h2>
<p>That&#8217;s all for today.  At some point I might like the label to change the link color for &#8220;visited links&#8221; and it might be nice if it behaved a bit more like <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JButton.html">JButton</a> &#8212; mouse press arms and mouse release fires.  Firing only on mouse click means if you accidentally drag a bit after pressing the mouse button the link won&#8217;t fire.  Nor does it visibly react to the mousePressed since it doesn&#8217;t have an armed state.</p>
<p>-Carl</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.palantirtech.com/2007/07/13/stupid-fast-hyperlinks-for-swing/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Realtime Swing reflections (iTunes ain&#8217;t the only kid on the block)!</title>
		<link>http://blog.palantirtech.com/2007/05/25/reflection/</link>
		<comments>http://blog.palantirtech.com/2007/05/25/reflection/#comments</comments>
		<pubDate>Fri, 25 May 2007 23:00:25 +0000</pubDate>
		<dc:creator>Carl Freeland</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[fun]]></category>
		<category><![CDATA[swing]]></category>

		<guid isPermaLink="false">http://blog.palantirtech.com/?p=51</guid>
		<description><![CDATA[Check out this reflection magic! Now iTunes isn&#8217;t the only one with fancy reflections on album art. The best part about it is that it&#8217;s a general use component that doesn&#8217;t require customization each time. It can wrap any transparent JComponent and it will automatically repaints whenever the contained component changes. You see the text [...]]]></description>
			<content:encoded><![CDATA[<div style=' float: left; margin-right: 20px; margin-top: none; margin-bottom: 20px;'><a href='http://blog.palantirtech.com/wp-content/uploads/2007/03/reflectiondemo.jnlp' title='ReflectionDemo Webstart Launch file'><img src='http://blog.palantirtech.com/wp-content/uploads/2007/05/reflection-clean.png' alt='Achtung Baby reflected' /></a></div>
<p>Check out this reflection magic!  Now iTunes isn&#8217;t the only one with <a href="http://www.apple.com/itunes/jukebox/coverflow.html">fancy reflections on album art</a>.  The best part about it is that it&#8217;s a general use component that doesn&#8217;t require customization each time.  It can wrap any transparent <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JComponent.html">JComponent</a> and it will automatically repaints whenever the contained component changes.  You see the text appearing in the reflection as you type in the text field.  Try the <a href='http://blog.palantirtech.com/wp-content/uploads/2007/03/reflectiondemo.jnlp' title='ReflectionDemo Webstart Launch file'>Web Start ReflectionDemo</a>.  Source code is provided in <a href='http://blog.palantirtech.com/wp-content/uploads/2007/03/reflectiondemo.jar' title='Reflection Demonstration application'>reflectiondemo.jar</a>, and an explanation of how it&#8217;s done follows.<br />
<span id="more-51"></span><br />
This component is a combination of several techniques:</p>
<ul>
<li>Image fading.
<li>Applying a transform so the contained component is painted upside down.
<li>Active update accomplished by, <b>*<i>gasp</i>*</b>, calling repaint during <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JComponent.html#paintComponent(java.awt.Graphics)">paintComponent</a>!
</ul>
<h2>Fading images</h2>
<p>You can paint colors/lines/solid shapes/etc using a <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/awt/GradientPaint.html">GradientPaint</a> to create an object that fades from solid to transparent as we desired, but getting a complex graphic to do the same thing didn&#8217;t seem possible until we learned about <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/awt/AlphaComposite.html#DST_IN">AlphaComposite.DST_IN</a>,  (see our <a href="http://blog.palantirtech.com/2007/03/27/custom-alpha-compositing/">previous blog posting</a> on the subject).  It&#8217;s a class that, instead of blending two images together, allows you to use the color bytes from one image and the alpha from the second image.  This technique allowed me to composite together a fully opaque picture of a component with a rectangle of black painted using a standard Gradient paint.</p>
<p>Imagine the icon upside down and you&#8217;ll see what I&#8217;m trying to accomplish here.</p>
<p><a href='http://blog.palantirtech.com/wp-content/uploads/2007/03/thepalantirway.png' title='SourceAlphaComposite'><img src='http://devblog.yojoe.local/wp-content/uploads/2007/03/thepalantirway.png' alt='SourceAlphaComposite' /></a></p>
<h2>Inverting the component</h2>
<p>The reflection is obtained by applying transforms to a <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/awt/Graphics.html">Graphics</a> object, then permitting the reflecting component to paint itself to a <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/awt/image/BufferedImage.html">BufferedImage </a>instead of the supplied Graphics instance.  This results in a copy of the contained component painted upside down in a separate <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/awt/image/BufferedImage.html">BufferedImage</a>.    After compositing using the above technique, you get something that looks like the component but upside down and faded with whatever <a href="http://java.sun.com/j2se/1.5.0//docs/api/java/awt/GradientPaint.html">GradientPaint </a>you used.</p>
<p>You can paint upside down to the supplied Graphics, of course.  However, if you want the fading effect to apply only to the contained component, you need to isolate it on a separate <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/awt/image/BufferedImage.html">BufferedImage </a> until it&#8217;s fully prepared.</p>
<p>In the below snippet of code, reflG2D is the <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/awt/Graphics2D.html">Graphics2D</a> of the offscreen buffer that holds the reflection so that it may be faded before painting to screen.  The scaling step causes all y-coordinates to be multiplied by -1, so when you paint the children of ReflectionComponent to reflG2D, source paints itself upside down.</p>
<p>Look out, though, that means the paint which would normally be (0,0) -&gt; (source.getWidth(), source.getHeight())</code> is now (0,0) -&gt; (source.getWidth(), -source.getHeight()).  You've just painted outside the boundaries of the image so you translate down to put it in the visible region.  The rest of the translation ensures proper painting even if source isn't at (0,0) due to insets or the layout manager.</p>
<pre class="brush: java; title: ; notranslate">
	Insets i = getInsets();
	reflG2D.scale(1,-1);
	reflG2D.translate(-source.getX(), - (source.getHeight()+i.top));

	super.paintChildren(reflG2D);

	reflG2D.translate(source.getX(), (source.getHeight()+i.top));
	reflG2D.scale(1,-1);
</pre>
<p>Don't forget to undo the changes you made so the fade operations can be done without being affected by the inversion/translation.</p>
<h2>Active update of the reflection</h2>
<p>This is a bit sketchy but too cool to pass up.  I've seen several reflection component examples out there, but they don't seem to do active update, so here it is.  There's no event that fires to report when repaints occur (I suppose Sun engineers figured it was just too likely to be abused).  They're probably right.  So I abused <i>opacity</i> instead.  When a component is marked for repaint and it is transparent (i.e. isOpaque() == false), then the parent of said component will be repainted as well.  So, if everything contained in a ReflectionComponent is transparent, then ReflectionComponent itself will repaint every time the contained object does so.  The only hurdle to overcome is the crop -- the dirty region will never automatically include the reflection region because the reflection lies outside the bounds of the contained component.  This makes it necessary to call repaint on the reflection region as well.  Basically it doubles up on every repaint, not something you REALLY want to do all over the place but it does the job.</p>
<p>Here's how I did it:</p>
<pre class="brush: java; title: ; notranslate">
public void paintComponent(Graphics g) {
	...
	Rectangle r = g.getClipBounds();
	if( (r.y+r.height) &lt; (getHeight() - 1) ) {
		repaint(r.x, r.y, r.width, getHeight() - r.y);
	}
	...
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.palantirtech.com/2007/05/25/reflection/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Fully Interactive JTables (aka Mouseover Editing)</title>
		<link>http://blog.palantirtech.com/2007/05/17/jtable-mouseover-editing/</link>
		<comments>http://blog.palantirtech.com/2007/05/17/jtable-mouseover-editing/#comments</comments>
		<pubDate>Fri, 18 May 2007 05:01:17 +0000</pubDate>
		<dc:creator>Kevin Simler</dc:creator>
				<category><![CDATA[coding]]></category>
		<category><![CDATA[swing]]></category>
		<category><![CDATA[tips and tricks]]></category>

		<guid isPermaLink="false">http://blog.palantirtech.com/?p=48</guid>
		<description><![CDATA[What sucks about JTables? Everything, of course&#8212;but that&#8217;s a developer&#8217;s perspective. To the user, cell editing is rough around the edges: when and where to click, and how many times&#8212;it&#8217;s never perfectly clear. Cells in a table just don&#8217;t provide the mouseover feedback that regular components do. If only a JTable behaved like a bunch [...]]]></description>
			<content:encoded><![CDATA[<p>What sucks about <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JTable.html">JTables</a>?  Everything, of course&#8212;but that&#8217;s a developer&#8217;s perspective.  To the user, <strong>cell editing</strong> is rough around the edges: when and where to click, and how many times&#8212;it&#8217;s never perfectly clear.  Cells in a table just don&#8217;t provide the mouseover feedback that regular components do.  If only a <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JTable.html">JTable</a> behaved like a bunch of components thrown into a giant <a href="http://java.sun.com/docs/books/tutorial/uiswing/layout/gridbag.html">GridBag</a> or <a href="http://java.sun.com/products/jfc/tsc/articles/tablelayout/">TableLayout</a>&#8230;</p>
<div class='postimg' style='float: right; margin-left: 15px; margin-right: 15px'>
<img src='http://blog.palantirtech.com/wp-content/uploads/2007/05/mouseover-screenshot1.png' alt='mouseover-screenshot.png' /></div>
<p>Mouseover Editing simulates just that.  The idea is to attach a <a href="http://java.sun.com/docs/books/tutorial/uiswing/events/mouselistener.html">MouseListener</a> to the JTable and call <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JTable.html#editCellAt(int,%20int)">editCellAt(row, col)</a> whenever the cursor moves over a new cell.  In other words, even though only one cell in a table can be fully interactive (the editing cell) at any given time, as long as we keep moving that cell to stay underneath the user&#8217;s cursor, the whole table will appear to be fully interactive.  If done correctly, this will appear to the user as though he&#8217;s interacting with a bunch of real components (rather than rendered stamps) inside a   giant Grid/GridBag/TableLayout.</p>
<p>Most importantly, the user will get mouseover feedback about which cells are editable, and how to edit them.  Checkboxes, buttons, and comboboxes (if the <a href="http://today.java.net/pub/a/today/2004/02/27/laf.html">L&amp;F</a> supports it) will highlight to indicate press-ability and the cursor will turn to a text caret when hovering over cells that contain textfields.  When done correctly, the effect is nearly seamless and very satisfying.</p>
<p>Here&#8217;s a <a href='http://blog.palantirtech.com/wp-content/uploads/2007/04/launch_mouseoverjtable.jnlp' title='launch_mouseoverjtable.jnlp'>webstart demo</a>.  Read on for the solution in code.</p>
<p><span id="more-48"></span></p>
<p>There are three parts to the Mouseover Editing solution (over and above what&#8217;s needed for typical JTable editing).</p>
<p><strong>Part 1:  Identical Editors and Renderers</strong></p>
<p>This is important.  Typically, a table will use a <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JLabel.html">JLabel</a> to render a cell and a <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JTextField.html">JTextField</a> to edit the cell.   When the editor is swapped in to replace the renderer, there&#8217;s a slight flicker&#8212;the textfield might have a different background color, the text mayb be in a slightly different location, etc.  This is all well and good when the user has to click or double-click to engage the editor, because the click can be perceived as granting permission to the program to do something on its own.  However, a simple mouseover is a different story.  Here, the look, feel, and placement of the editor should exactly match up with the look, feel, and placement of the renderer; otherwise, there will be a flicker trail every time the cursor passes through the JTable.</p>
<p>In order to make editors and renderers look and behave identically, (a) we need them to start out identical and (b) we need to apply the same transformations to them.</p>
<p>The easiest way to make an identical editor and renderer is to produce two objects from a combined EditorRenderer class. Here&#8217;s how that might work for a checkbox:</p>
<pre class="brush: java; title: ; notranslate">
public class CheckBoxEditorRenderer extends AbstractCellEditor implements TableCellRenderer
{
	private JCheckBox checkbox = new JCheckBox();
	public CheckBoxEditorRenderer() {
		super();
		checkbox.setFocusable(false);
	}
	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
		if (value instanceof Boolean) {
			checkbox.setSelected((Boolean) value);
		}
		return checkbox;
	}
	public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
		if (value instanceof Boolean) {
			checkbox.setSelected((Boolean) value);
		}
		return checkbox;
	}
	public Object getCellEditorValue() {
		return checkbox.isSelected();
	}
}
</pre>
<p>Notice how CheckBoxEditorRenderer implements both the <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/table/TableCellRenderer.html">TableCellRenderer</a> and <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/table/TableCellEditor.html">TableCellEditor</a> interfaces (the latter via <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/AbstractCellEditor.html">AbstractCellEditor</a>).</p>
<p>Editors and renderers must also be subjected to the same transformations.  In a subclass of JTable, say one called MouseoverJTable, use the following format for your <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JTable.html#prepareEditor(javax.swing.table.TableCellEditor,%20int,%20int)">prepareEditor()</a> and <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JTable.html#prepareRenderer(javax.swing.table.TableCellRenderer,%20int,%20int)">prepareRenderer()</a> methods:</p>
<pre class="brush: java; title: ; notranslate">
public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
	Component c = super.prepareRenderer(renderer, row, column);
	return prepareEditorRenderer(c, row, column);
	}
	public Component prepareEditor(TableCellEditor editor, int row, int column) {
	Component c = super.prepareEditor(editor, row, column);
	return prepareEditorRenderer(c, row, column);
	}
	private Component prepareEditorRenderer(Component stamp, int row, int column) {
//	 ...  All sorts of shenanigans can go on here.
	}
}
</pre>
<p>This ensures that both the editor and the renderer will go through the same decoration path.</p>
<p><strong>Part 2:  Two-stage editing</strong></p>
<p>What we&#8217;ve presented thus far works really well for buttons and checkboxes, which are minimally interactive.  With comboboxes and textfields, there&#8217;s a problem.  Suppose you mouse over a cell with a combobox.  First the combobox will become highlighted (if the L&amp;F supports it) to indicate that it&#8217;s clickable; this is expected and reasonable behavior. If you click on it, the combobox flyout will appear; this is also expected and reasonable behavior.  Now move your mouse just a little bit&#8230;.  oh no!  You accidentally moused over another cell, and the table decided to swap out the editor you were using (the combobox) and swap in a new editor.  Goodbye flyout.</p>
<p>To make sure this doesn&#8217;t happen, we need editors with two states:  temporarily engaged and fully engaged.  When the cursor first moves over a cell, we call editCellAt(r, c), and plop the editor into place, temporarily engaged.  This means it&#8217;s an interactive <a href="http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JComponent.html">JComponent</a> that responds to mouse events, but that it&#8217;s okay to swap it out and replace it with a new editor if the cursor changes location.  Then, if the user starts interacting with the Editor in a way that requires the editor to keep around a bit of state (like the visibility of a flyout for a combobox), we say that the editor is fully engaged, and that the table isn&#8217;t allowed to swap it out until the user disengages it.</p>
<p>What this looks like in code:</p>
<pre class="brush: java; title: ; notranslate">
public interface TwoStageTableCellEditor extends TableCellEditor
{
    public boolean isFullyEngaged();
}
</pre>
<pre class="brush: java; title: ; notranslate">
public class ComboBoxEditorRenderer extends AbstractCellEditor implements TwoStageTableCellEditor, TableCellRenderer
{
    private JComboBox combobox;
    ...
    public Object getCellEditorValue() {
        return combobox.getSelectedItem();
    }
    public boolean isFullyEngaged() {
        return combobox.isPopupVisible();
    }
}
</pre>
<p><strong>Part 3:  Mouseover swapping</strong></p>
<p>Here&#8217;s where it all comes together.  Mouseover swapping is what your (subclass of) JTable does in order to keep track of which cell is being edited, where the cursor is, and  whether to swap the editor from one cell to another.  This is kind of boring, and only really makes sense in code, so here you go:</p>
<pre class="brush: java; title: ; notranslate">
// In the constructor...
// listeners for two-stage editing
this.addMouseListener(twoStageEditingListener);
this.addMouseMotionListener(twoStageEditingListener);
</pre>
<pre class="brush: java; title: ; notranslate">
// In the body of your JTable subclass...
private final FullMouseAdapter twoStageEditingListener = new FullMouseAdapter() {
    public void mouseMoved(MouseEvent e) {
        possiblySwitchEditors(e);
    }
    public void mouseEntered(MouseEvent e) {
        possiblySwitchEditors(e);
    }
    public void mouseExited(MouseEvent e) {
        possiblySwitchEditors(e);
    }
    public void mouseClicked(MouseEvent e) {
        possiblySwitchEditors(e);
    }
};
private void possiblySwitchEditors(MouseEvent e) {
    Point p = e.getPoint();
    if (p != null) {
        int row = rowAtPoint(p);
        int col = columnAtPoint(p);
        if (row != getEditingRow() || col != getEditingColumn()) {
            if (isEditing()) {
                TableCellEditor editor = getCellEditor();
                if (editor instanceof TwoStageTableCellEditor &amp;amp;&amp;amp; !((TwoStageTableCellEditor)editor).isInStageTwo()) {
                    if (!editor.stopCellEditing()) {
                        editor.cancelCellEditing();
                    }
                }
            }

            if (!isEditing()) {
                if (row != -1 &amp;amp;&amp;amp; isCellEditable(row, col)) {
                    editCellAt(row, col);
                }
            }
        }
    }
}
</pre>
<p><strong>Conclusion</strong></p>
<p>This solution works pretty well.  There are a couple flaws (e.g. start editing a textfield and then mouseover a button&#8212;no feedback, because the text field is fully engaged), but overall it is much better than an unadorned JTable, and not too much of a burden on the developer.  Be warned, though:  it may wreak havoc on the focus system.</p>
<p>Extra credit:  Is it possible to achieve a similar effect by forwarding MouseEvents through to the renderers/stamps?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.palantirtech.com/2007/05/17/jtable-mouseover-editing/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

