Add command support for actionable controls

Michael Strauß michaelstrau2 at
Tue Jan 21 19:59:25 UTC 2020

1. Abstract:
Controls that are derived from ButtonBase generally represent an operation
that is triggered by the control.
In many cases, the control also reflects whether the operation can
currently be invoked (i.e. whether the control is enabled or disabled), or
whether the operation is currently running.
Software patterns like MVVM often encapsulate this behavior for the purpose
of decoupling business logic from UI code.

2. Implementation:
I propose adding the following interface that represents the entirety of
such an operation:

interface Command<T> {
    ReadOnlyBooleanProperty canExecuteProperty();
    ReadOnlyBooleanProperty executingProperty();
    void execute();
    void execute(T parameter);

An application's business logic can expose operations as implementations of
the Command interface, and define the conditions when the operation can be

Additionally, ButtonBase should be extended by adding the following two

 * The button's command, which is invoked whenever the button is fired.
 * If a command is set on the button, {@link Node#disableProperty()} is
 * bound to {@link Command#canExecuteProperty()}. Any previous binding is
ObjectProperty<Command<?>> commandProperty();

 * The button's command parameter.
 * When the command is invoked, this parameter will be passed to the
command implementation.
ObjectProperty<Object> commandParameterProperty();

These two properties are lazily instantiated to prevent allocations if an
application doesn't use commands.
In general, Commands are an opt-in feature, so existing code that makes no
use of commands is not impacted.

The command is invoked whenever the control fires an ActionEvent. This can
be achieved by overriding Node.fireEvent(Event) in ButtonBase and checking
for the presence of an ActionEvent.

I can provide a PR with an implementation of this feature.


More information about the openjfx-dev mailing list