Improvements To Current GUI Designs


We write user interfaces using 3 different platforms.

  • Swing (Java emulated)
  • SWT (Java native)
  • GWT (Java to Javascript native)

Each of these platforms has a different programming interface for working with widgets.  In order for us to write code common to all of them, we borrowed their best ideas, and then added lacking features.  Our interfaces consist of simple methods to get and set values, handlers, and state.

Our designs are based on these principals:

EMPTY VALUES

1. Most of the time, a value has the same meaning if set to a null object, an empty string, or an empty list.
2. isEmpty and notEmpty are much clearer than using a combination of ‘!’, ‘== true|false’, NULL checks, and empty checks.
3. These semantics decrease the risk of an unexpected Null Pointer Exception and make code more compact.

ALLOW SETTING WIDGETS TO EMPTY VALUES

4. Widgets should be able to round-trip a null value, without forcing them to be an object.
If a binding engine has a null value, it should be able to set the widget null, and receive a null value if the widget has not been set.  For example, SWT widgets do not allow null values; it is up to the controller or view to manage them.
5. Filters should allow queries to include, exclude, or restrict to only empty values.

UNIFIED VALUE ACCESSORS

6. Every widget should have a single method for setting it’s primary value called setValue() and getValue().

MANAGING STATES FROM THE CONTROLLER

7. States should be managed by the controller, not the view.  We define 5 states:  Enabled, Disabled, ReadOnly, NotApplicable, and Error.

8. There should be only 1 method for setting the state.

INTERMEDIATE VALUE CHANGES

9.  Widgets should be able to have their handlers configured for intermediate value changes.  For example, a text box can send an event when its content changes, when it loses focus, when enter is pressed, or when the field is committed by a save for the widget only or the form.  Current implementations are ambiguous in regards to when events are sent, and often implementations result in duplicate, unclear, and unpredictable code.


Example Classes

class E {

static boolean isEmpty(…){…}

static boolean notEmpty(…){…}

}

Example Interfaces

interface <T> TakesValue {

T getValue();

void setValue(T value);

}

interface NotifyWhen {

MODIFIED, SELECTED, COMMITTED

}

interface <T> HasValueHandler {

HandlerRegistration addValueHandler(ValueHandler handler, NotifyWhen when);

}

interface HasState {

void setState(State state);

}

enum State {

ENABLED, DISABLED, READONLY, NOTAPPLICABLE, ERROR

}

interface ValueWidget extends TakesValue, HasValueHandler, HasState {

}

Leave a comment

Your email address will not be published. Required fields are marked *