Why do it?
Radio buttons are graphical elements that present users with a choice between multiple options. By convention, users can only select one radio button at a time, so they are added to a UI when users are allowed to choose only one option.
Lucy also represents user choices with radio buttons. For example, in the Lucy menu you use radio buttons to select a formatting option for the unit of speed. Lucy sets the formatting of the speed unit for the entire application, so only one format can be active at a time. You can display speed in kilometers per hour (km/h), in meters per second (m/s), or in other units.
How to do it?
Adding radio buttons to the UI can be done by creating and inserting ILcyActiveSettable
implementations. You must however take care of two things:
-
Make sure that the
ILcyActiveSettable
instances can de-activate themselves. For example, when the default speed format is changed to m/s, the km/h active settable must become inactive.Example: Active settable implementation to change the speed format.
When yourILcyActiveSettable
objects are represented by radio buttons, their "state" is typically stored outside the active settables. In the speed unit selection example, the active settable state is the speed format stored at the Lucy back-end. Our m/s active settable is considered to be active when the speed format at the back-end formats speeds in m/s, and is considered inactive when the speed format on the Lucy back-end uses a different formatting.Whenever the speed format changes at the Lucy back-end, the back-end fires an event. Our active settables need to listen for those events, and de-activate if necessary. This is what an example implementation of such an
ILcyActiveSettable
could look like:ILcyActiveSettable implementation to change the speed formatpublic class SpeedFormatActiveSettable extends ALcyActiveSettable{ private final TLcdSpeedFormat fFormat; private final ILcyLucyEnv fLucyEnv; public SpeedFormatActiveSettable(TLcdSpeedFormat aFormat, ILcyLucyEnv aLucyEnv) { fFormat = aFormat; fLucyEnv = aLucyEnv; fLucyEnv.addPropertyChangeListener(new SpeedFormatListener(this)); } @Override public boolean isActive() { return fLucyEnv.getDefaultSpeedFormat() == fFormat; } @Override public void setActive(boolean aActive) { if ( aActive ){ fLucyEnv.setDefaultSpeedFormat(fFormat); } // do nothing when !aActive // this active settable can only be activated, not de-activated // de-activation happens automatically when the speed format on the back-end changes } /** * Each time the default format at the Lucy back-end changes, we need to see whether the "active" * state of our active settable changed, and fire an event if needed. */ private static class SpeedFormatListener extends ALcdWeakPropertyChangeListener<SpeedFormatActiveSettable>{ public SpeedFormatListener(SpeedFormatActiveSettable aObjectToModify) { super(aObjectToModify); } @Override protected void propertyChangeImpl(SpeedFormatActiveSettable aActiveSettable, PropertyChangeEvent aPropertyChangeEvent) { if ("defaultSpeedFormat".equals(aPropertyChangeEvent.getPropertyName()) ){ aActiveSettable.firePropertyChange("active", aPropertyChangeEvent.getOldValue() == aActiveSettable.fFormat, aActiveSettable.isActive()); } } } }
Note that:
-
The active state of the
ILcyActiveSettable
is not stored inside the active settable. Instead, it is determined by comparing the current speed format at the Lucy back-end with thefFormat
field in the active settable. The active settable is considered to be active when those twojava.text.Format
instances match. -
When the active settable is activated, by a user clicking the radio button for example,
fFormat
will be set as the d default speed format at the back-end. -
The
SpeedFormatListener
class is responsible for listening to change events in the speed format at the back-end. It transforms those events intoPropertyChangeEvent
instances for the active state of theILcyActiveSettable
. That way we make sure that the changes in the active state of theILcyActiveSettable
are correctly communicated to all listeners. -
The
setActive
method only allows activating theILcyActiveSettable
. CallingsetActive( false )
has no effect. Normally there is never any need to make such a call, because de-activating the active settable happens by clicking the radio button of another active settable.
-
-
When you insert the active settable, specify that it should look like a radio button. You must do that explicitly, because there is nothing on the
ILcyActiveSettable
interface that distinguishes radio button active settables from regular active settables. You can indicate that an active settable is a radio button through theTLcyActionBarUtil#insertInConfiguredActionBars(ILcyActiveSettable, Object, TLcyActionBarManager, ALcyProperties, boolean)
method. If the last boolean parameter is set tofalse
, the action bar will style the UI element as a radio button.Example: Inserting the speed format active settablesSpeedFormatActiveSettable kmH = new SpeedFormatActiveSettable(new TLcdSpeedFormat(TLcdSpeedUnit.KmH), aLucyEnv); kmH.putValue(TLcyActionBarUtil.ID_KEY, "SpeedFormatAddOn.kmhActiveSettable"); // By using false as last parameter, the UI will use a radio button TLcyActionBarUtil.insertInConfiguredActionBars(kmH, null, actionBarManager, getPreferences(), false); SpeedFormatActiveSettable ms = new SpeedFormatActiveSettable(new TLcdSpeedFormat(TLcdSpeedUnit.MS), aLucyEnv); ms.putValue(TLcyActionBarUtil.ID_KEY, "SpeedFormatAddOn.msActiveSettable"); // By using false as last parameter, the UI will use a radio button TLcyActionBarUtil.insertInConfiguredActionBars(ms, null, actionBarManager, getPreferences(), false )
You don’t always need to go through the API to customize Lucy tool bars. You can set up many commonly needed tool bar changes through the Lucy configuration files. For more information, see the available action bar configuration options. |