The Source for Java Technology Collaboration


Home | Changes | Index | Search | Go

SwingXActSelectBind

Series on core Swing inconsistencies: the center of interest here are the mechanisms (aka: event notification) around the themes of action, selection and bindable properties and how the diversness hurts SwingX.

Intro

Since a while "ease-of-use" - for desktop developers writing rich desktop applications with the help of the Swing/X framework - is in the midth of turbulent public debate. The paths to reach that goal range from efforts to revamp it into Swing 2.0 to dump it in favour of a new babe in town. Whatever the solution, first step would be to analyse the problem. Swing as a highly flexible can-do-it-all ui framework comes with a high complexity and consequently a steep (and ever-upward-sloping) learning curve. Remove unnecessary complexity (aka: inconsistency and redundancy).

Core Swing is Inconsistent

One aspect of complexity is the myriads of different event notification mechanisms, different even if they serve a very similar requirement, different to an extent that borders on inconsistency. Following is a table of Input-Actors with

  • Input: goal is to get hold of a single value as passed into a component. Could be a toggled boolean, a selection un-/contained in a list, free-style and formatted typed
  • Actor: goal is to do-something (after a user-gesture?)

  act select bind
Core Swing
Button X onKeyBinding, onMouse, onDoClick (-) (-)
ToggleButton X onKeyBinding, onMouse, onDoClick, onDoSelect? X (same as act) - (could use ItemEvent)
ComboBox X onSelectChange, onEdited, onEnter (only if editable) X (same as act) - (could use ItemEvent)
Spinner - - - (could use ChangeEvent)
TextField X onEnter (always if has ActionListener) - - (could use DocumentEvent)
FormattedTF X onEnter (only if edited) - X (value) onChange
SwingX
DatePicker X onCommit (enter), onCancel (esc) (-) X (date) onChange
RadioGroup      
AutoComplete      

The relative amount of both roles differs as might be expected if different components have any right-of-existance at all. What's not expected are

  • the (seemingly) arbitrary mapping of whatever triggers an actionEvent
  • the wide variety of event types to get notified of inputChange: Item-, Change-, Document-, PropertyChange

Semantics of ActionEvent Notification

Nowhere documented, just guessing: user gesture to convey some kind of "readiness". Like "ready with"

  • current input: Formatted/TextFields
  • current navigation, selection (?)
  • current form: triggering DefaultButton's Action
Mostly (not necessarily?) if input happens via keyboard, the gesture is the ENTER key (or equivalent), the input component is focused (or a focused popup's owner). The one end of the variance is the FormattedTextFields which fires only on receiving an enter while it has a pending change. The other end is a JComboBox which multiple actionEvents (with different commands) on a single (even programmatic) change. This indecent verbosity makes it hard to use: the whole point of having an actionEvent notification path orthogonally to the "dataEvent" notification path is to allow developers to differentiate between both.

Further complication arises from the notion of a per-form default action (as implemented JRootPane's DefaultButton). Typically, per-component readiness is signalled by the same user gesture (ENTER) as the per-form readiness. This is a problem if the readiness gesture happens on a ready-aware-component inside of a ready-aware-form. A reasonable approach might be to use it on the component level if needed (aka: there had been a change which requires a ready signal) and let it pass to the (next higher) form level if not. Again the actual implementation vary widely, not only across component types but also across jdk versions

  • simple TextField: always fires and consumes if has actionListener, always triggers default if there are no actionListeners
  • FormattedTextField: fires and consumes if has a pending edit, passes on if not
  • editable ComboBox (jdk1.5): fires and consumes if the selected item had been edited, passes on if not
  • editable ComboBox (jdk1.6): fires on component level and passes on always
  • SwingX DatePicker: always fires and consumes on component level

Semantics of ItemSelectable

Deducting from how ItemSelectable is implemented in Swing, I was rather sure that it belongs into the "DataEvent" category. After that, the addItemListener api doc comes at a surprise:

    /**
     * Adds a listener to receive item events when the state of an item is
     * changed by the user. Item events are not sent when an item's
     * state is set programmatically.  If ...
     */

Semantics of "DataEvent" Notification

Unification

Actually, these thoughts were triggered by a discussion in Issue 974-swingx which was raised because the (obviously rarely used but useful if used, citing Karl) JXRadioGroup doesn't fire (any or no propertyChange?) a per-group notification on setting the its selected value. The original suggestion was to fire a propertyChange event (instead of following the ToggleButton/ComboBox itemSelectable path). Which could well be viewed a higher-level semantic event of what we are after at the end of the day (which here is the input): a value to do something with. Doing that for all those Input-Actors (except for the button with a 100% Actor) could hide the lower-level details most of the time - we often don't really care if the value was selected or input, do we?.

Open question: Text-Input elements (and their clients like ComboBox, DatePicker) have the notion of "commit/cancel" That's a hook for user gestures to denote input-finalization or revert. While the finalization is (mostly) transported via an ActionEvent, the mapping of a user gesture to that finalization is varying, and the cancel mostly missing.

Links

Topic SwingXActSelectBind . { Edit | Ref-By | Printable | Diffs r8 < r7 < r6 < r5 < r4 | More }
 XML java.net RSS

Revision r8 - 19 Mar 2009 - 16:55:55 - KleopatraX
Parents: WebHome > SwingLabs > SwingLabsSwingX