CallableSystemAction
and BooleanStateAction
.If you create a new action through the new action wizard your code looks something like:
public final class SomeAction extends CallableSystemAction {
public void performAction() {
// TODO implement action body
}
public String getName() {
return NbBundle.getMessage(SomeAction.class, "CTL_SomeAction");
}
@Override
protected String iconResource() {
return "path/to/your/icon.png";
}
public HelpCtx getHelpCtx() {
return HelpCtx.DEFAULT_HELP;
}
@Override
protected boolean asynchronous() {
return false;
}
}
The action allows you to execute some code (in the
performAction()
method) when the used clicks the button.On the other side, a boolean action is like a toggle button. Imagine a play button, it can be pushed to indicate the music is playing and in normal state (not pushed) indicating the player is stopped. This can be achieved with a
BooleanStateAction
instead of a CallableSystemAction
. Modify the previous code to:
public final class SomeAction extends BooleanStateAction implements PropertyChangeListener
{
public SomeAction()
{
// Set the initial state
setBooleanState(true);
// Register as a property listener
addPropertyChangeListener(this);
}
public String getName()
{
return NbBundle.getMessage(SomeAction.class, "CTL_SomeAction");
}
@Override
protected String iconResource()
{
return "path/to/your/icon.png";
}
public HelpCtx getHelpCtx()
{
return HelpCtx.DEFAULT_HELP;
}
public void propertyChange(PropertyChangeEvent evt)
{
// Check if the boolean state has changed.
if(BooleanStateAction.PROP_BOOLEAN_STATE.equals(evt.getPropertyName())) {
Boolean state = (Boolean) evt.getNewValue();
if (state.equals(Boolean.TRUE)) {
// Button has been pressed
}
else {
// Button has been releases
}
}
}
}
How it works?
Both
CallableSystemAction
and BooleanStateAction
are direct subclasses of org.openide.util.actions.SystemAction
. When a system action is executed its abstract actionPerformed
method is invoked.
// In SystemAction...
public abstract void actionPerformed(ActionEvent ev);
In the case of
CallableSystemAction
, the override method makes some work and finally invokes the performAction
which is the method you need to code.
public void actionPerformed(ActionEvent ev) {
if (isEnabled()) {
org.netbeans.modules.openide.util.ActionsBridge.doPerformAction(
this,
new org.netbeans.modules.openide.util.ActionsBridge.ActionRunnable(ev, this, asynchronous()) {
public void run() {
performAction();
}
}
);
} else {
// Should not normally happen.
Toolkit.getDefaultToolkit().beep();
}
}
In the case of
BooleanStateAction
, this class maintains a property which represents the state of the button. When the override actionPerformed
method is execute it changes the property state and fires a property change event to be cached by the BooleanStateAction
listeners:
public void actionPerformed(java.awt.event.ActionEvent ev) {
setBooleanState(!getBooleanState());
}
public void setBooleanState(boolean value) {
Boolean newValue = value ? Boolean.TRUE : Boolean.FALSE;
Boolean oldValue = (Boolean) putProperty(PROP_BOOLEAN_STATE, newValue);
firePropertyChange(PROP_BOOLEAN_STATE, oldValue, newValue);
}
As you can see in the
SomeAction
code the tip resides in registering the class as its own listener and handle the state change in the propertyChange
method.