Create builders for docking actions

This commit is contained in:
ghidravore 2019-12-23 14:14:02 -05:00
parent 8fbdec4eca
commit 51e0e07edb
8 changed files with 929 additions and 1 deletions

View file

@ -255,7 +255,7 @@ public abstract class ComponentProvider implements HelpDescriptor, ActionContext
* Adds the given action to the system and associates it with this provider.
* @param action The action to add.
*/
protected void addLocalAction(DockingActionIf action) {
public void addLocalAction(DockingActionIf action) {
if (actionSet.contains(action)) {
return;
}

View file

@ -19,6 +19,7 @@ import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;
import javax.swing.*;
@ -72,6 +73,11 @@ public abstract class DockingAction implements DockingActionIf {
private PopupMenuData popupMenuData;
private ToolBarData toolBarData;
private Predicate<ActionContext> enabledPredicate;
private Predicate<ActionContext> popupPredicate;
private Predicate<ActionContext> validContextPredicate;
private Predicate<ActionContext> validGlobalContextPredicate;
public DockingAction(String name, String owner) {
this.name = name;
this.owner = owner;
@ -156,21 +162,33 @@ public abstract class DockingAction implements DockingActionIf {
@Override
public boolean isAddToPopup(ActionContext context) {
if (popupPredicate != null) {
return popupPredicate.test(context);
}
return isEnabledForContext(context);
}
@Override
public boolean isEnabledForContext(ActionContext context) {
if (enabledPredicate != null) {
return enabledPredicate.test(context);
}
return isEnabled();
}
@Override
public boolean isValidContext(ActionContext context) {
if (validContextPredicate != null) {
return validContextPredicate.test(context);
}
return true;
}
@Override
public boolean isValidGlobalContext(ActionContext globalContext) {
if (validGlobalContextPredicate != null) {
return validGlobalContextPredicate.test(globalContext);
}
return isValidContext(globalContext);
}
@ -517,6 +535,54 @@ public abstract class DockingAction implements DockingActionIf {
return this;
}
/**
* Sets a predicate for dynamically determining the action's enabled state. If this
* predicate is not set, the action's enable state must be controlled directly using the
* {@link DockingAction#setEnabled(boolean)} method. See
* {@link DockingActionIf#isEnabledForContext(ActionContext)}
*
* @param predicate the predicate that will be used to dynamically determine an action's
* enabled state.
*/
public void enabledWhen(Predicate<ActionContext> predicate) {
enabledPredicate = predicate;
}
/**
* Sets a predicate for dynamically determining if this action should be included in
* an impending pop-up menu. If this predicate is not set, the action's will be included
* in an impending pop-up, if it is enabled. See
* {@link DockingActionIf#isAddToPopup(ActionContext)}
*
* @param predicate the predicate that will be used to dynamically determine an action's
* enabled state.
*/
public void popupWhen(Predicate<ActionContext> predicate) {
popupPredicate = predicate;
}
/**
* Sets a predicate for dynamically determining if this action is valid for the current
* {@link ActionContext}. See {@link DockingActionIf#isValidContext(ActionContext)}
*
* @param predicate the predicate that will be used to dynamically determine an action's
* validity for a given {@link ActionContext}
*/
public void validContextWhen(Predicate<ActionContext> predicate) {
validContextPredicate = predicate;
}
/**
* Sets a predicate for dynamically determining if this action is valid for the current global
* {@link ActionContext}. See {@link DockingActionIf#isValidGlobalContext(ActionContext)}
*
* @param predicate the predicate that will be used to dynamically determine an action's
* validity for a given global {@link ActionContext}
*/
public void validGlobalContextWhen(Predicate<ActionContext> predicate) {
validGlobalContextPredicate = predicate;
}
//==================================================================================================
// Non-public methods
//==================================================================================================

View file

@ -28,6 +28,10 @@ public abstract class ToggleDockingAction extends DockingAction implements Toggl
super(name, owner);
}
public ToggleDockingAction(String name, String owner, KeyBindingType keyBindingType) {
super(name, owner, keyBindingType);
}
public ToggleDockingAction(String name, String owner, boolean supportsKeyBindings) {
super(name, owner, supportsKeyBindings);
}
@ -61,4 +65,5 @@ public abstract class ToggleDockingAction extends DockingAction implements Toggl
public void actionPerformed(ActionContext context) {
// defined by subclasses
}
}

View file

@ -0,0 +1,513 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package docking.action.builder;
import java.util.function.Consumer;
import java.util.function.Predicate;
import javax.swing.Icon;
import docking.*;
import docking.action.*;
import ghidra.util.HelpLocation;
import resources.ResourceManager;
/**
* Base class for DockingAction builders
*
* @param <T> The type of DockingAction to build
* @param <B> the Type of DockingActionBuilder
*/
public abstract class AbstractActionBuilder<T extends DockingActionIf, B extends AbstractActionBuilder<T, B>> {
/**
* a name for the {@code DockingAction}
*/
protected String name;
/**
* an owner for the {@code DockingAction}
*/
protected String owner;
/**
* the {@code KeyBindingType} for this {@code DockingAction}
*/
protected KeyBindingType keyBindingType = KeyBindingType.INDIVIDUAL;
/**
* The callback to perform when the action is invoked
*/
protected Consumer<ActionContext> actionCallback;
/**
* a description for the {@code DockingAction}
*/
private String description = "";
/**
* whether this {@code DockingAction} is enabled
*/
private boolean isEnabled = true;
/**
* the {@code HelpLocation} for this {@code DockingAction}
*/
private HelpLocation helpLocation;
/**
* The menu bar path. This is the key attribute for including the action on the menu bar
*/
private String[] menuPath;
/**
* The menu bar menu item icon. (optional)
*/
private Icon menuIcon;
/**
* The menu bar menu item sub group. (optional)
*/
private String menuSubGroup;
/**
* The menu bar menu item group. (optional)
*/
private String menuGroup;
/**
* The mnemonic for the menu action (optional)
*/
private int menuMnemonic;
/**
* The icon for the menu item (optional)
*/
private Icon popupIcon;
/**
* The menu path in a pop-up menu. This is the key attribute for pop-up menu actions
*/
private String[] popupPath;
/**
* The menu group for the item in the pop-up menu (optional)
*/
private String popupGroup;
/**
* The menu sub group for the item in the pop-up menu (optional)
*/
private String popupSubGroup;
/**
* The icon for the tool bar action. This is the key attribute for actions in the toolbar.
*/
private Icon toolbarIcon;
/**
* The group for the items on the tool bar (optional)
*/
private String toolBarGroup;
/**
* The menu group for the item in the tool bar menu (optional)
*/
private String toolBarSubGroup;
/**
* Predicate for determining if an action is enabled for a given context
*/
private Predicate<ActionContext> enabledPredicate;
/**
* Predicate for determining if an action should be included on the pop-up menu
*/
private Predicate<ActionContext> popupPredicate;
/**
* Predicate for determining if an action is applicable for a given context
*/
private Predicate<ActionContext> validContextPredicate;
/**
* Predicate for determining if an action is applicable for a given global context
*/
private Predicate<ActionContext> validGlobalContextPredicate;
/**
* Builder constructor
* @param name the name of the action to be built
* @param owner the owner of the action to be build
*/
public AbstractActionBuilder(String name, String owner) {
this.name = name;
this.owner = owner;
}
/**
* returns this (typed for subclass) for chaining
* @return this for chaining
*/
protected abstract B self();
/**
* builds the action
* @return the newly build action
*/
public abstract T build();
/**
* Builds and adds the action globally to the tool
*
* @param tool the tool to add the action to
* @return the newly created action
*/
public T buildAndInstall(DockingTool tool) {
T action = build();
tool.addAction(action);
return action;
}
/**
* Builds and adds the action as a local action for the given provider
*
* @param provider the provider to add the action to
* @return the newly created action
*/
public T buildAndInstallLocal(ComponentProvider provider) {
T action = build();
provider.addLocalAction(action);
return action;
}
/**
* Configure the {@code String} description for this {@code DockingAction}
*
* @param text the description
* @return this builder (for chaining)
*/
public B description(String text) {
this.description = text;
return self();
}
/**
* Configure whether this {@code DockingAction} is enabled
*
* @param b {@code true} if enabled
* @return this builder (for chaining)
*/
public B enabled(boolean b) {
this.isEnabled = b;
return self();
}
/**
* Configure {@link KeyBindingType} for this {@code DockingAction}
* @param type the {@link KeyBindingType} to configure
* @return this builder (for chaining)
*/
public B keyBindingType(KeyBindingType type) {
this.keyBindingType = type;
return self();
}
/**
* Configure {@link HelpLocation} for this {@code DockingAction}
* @param help the {@link HelpLocation} to configure
* @return this builder (for chaining)
*/
public B helpLocation(HelpLocation help) {
this.helpLocation = help;
return self();
}
/**
* Sets the menu bar path for the action. Setting this attribute is what causes the action
* to appear on the tools menu bar
* @param pathElement the menu bar path for the action
* @return this builder (for chaining)
*/
public B menuPath(String... pathElement) {
menuPath = pathElement;
return self();
}
/**
* Sets the group for the action in the menu bar. Actions in the same group will appear
* next to other actions in the same group and actions in different groups will be separated
* by menu dividers
*
* @param group for this action
* @return this builder (for chaining)
*/
public B menuGroup(String group) {
menuGroup = group;
return self();
}
/**
* Sets the group and sub-group for the action in the menu bar. Actions in the same group will appear
* next to other actions in the same group and actions in different groups will be separated
* by menu dividers. The sub-group is used to order the actions withing the group.
*
* @param group the group used to clump actions together.
* @param subGroup the sub-group used to order actions within a group.
* @return this builder (for chaining)
*/
public B menuGroup(String group, String subGroup) {
menuSubGroup = group;
return self();
}
/**
* Sets the icon to use in this action's menu bar item.
*
* @param icon the icon to use in the action's menu bar item.
* @return this builder (for chaining)
*/
public B menuIcon(Icon icon) {
menuIcon = icon;
return self();
}
/**
* Sets the mnemonic to use in this action's menu bar item.
*
* @param mnemonic the mnemonic to use for this action's menu bar item.
* @return this builder (for chaining)
*/
public B menuMnemonic(int mnemonic) {
menuMnemonic = mnemonic;
return self();
}
/**
* Sets the pop-up menu path for the action. Setting this attribute is what causes the action
* to appear on the tools pop-up menu (Assuming it is applicable for the context)
*
* @param pathElement the menu path for the action in the pop-up menu
* @return this builder (for chaining)
*/
public B popupMenuPath(String... pathElement) {
popupPath = pathElement;
return self();
}
/**
* Sets the group for the action in the pop-up menu. Actions in the same group will appear
* next to other actions in the same group and actions in different groups will be separated
* by menu dividers
*
* @param group for this action
* @return this builder (for chaining)
*/
public B popupMenuGroup(String group) {
popupGroup = group;
return self();
}
/**
* Sets the group and sub-group for the action in the pop-up menu. Actions in the same group
* will appear next to other actions in the same group and actions in different groups will
* be separated by menu dividers. The sub-group is used to order the actions within the group
*
* @param group the group used to clump actions together.
* @param subGroup the sub-group used to order actions within a group.
* @return this builder (for chaining)
*/
public B popupMenuGroup(String group, String subGroup) {
popupSubGroup = group;
return self();
}
/**
* Sets the icon to use in this action's pop-up menu item.
*
* @param icon the icon to use in the action's pop-up menu item.
* @return this builder (for chaining)
*/
public B popupMenuIcon(Icon icon) {
popupIcon = icon;
return self();
}
/**
* Sets the icon to use in this action's tool bar button. Setting this attribute is what
* causes the action to appear on the tools or component provider's action tool bar.
*
* @param icon the icon to use in the action's tool bar.
* @return this builder (for chaining)
*/
public B toolBarIcon(Icon icon) {
toolbarIcon = icon;
return self();
}
/**
* Sets the path for the icon to use in this action's tool bar button. Setting this attribute
* causes the action to appear on the tools or component provider's action tool bar.
*
* @param iconFilepath the module relative path for the icon to use in the action's tool bar.
* @return this builder (for chaining)
*/
public B toolBarIcon(String iconFilepath) {
toolbarIcon = ResourceManager.loadImage(iconFilepath);
return self();
}
/**
* Sets the group for the action in the tool bar. Actions in the same group will appear
* next to other actions in the same group and actions in different groups will be separated
* by menu dividers
*
* @param group for this action
* @return this builder (for chaining)
*/
public B toolBarGroup(String group) {
toolBarGroup = group;
return self();
}
/**
* Sets the group and sub-group for the action in the tool bar. Actions in the same group
* will appear next to other actions in the same group and actions in different groups will
* be separated by menu dividers. The sub-group is used to order the actions within the group
*
* @param group the group used to clump actions together.
* @param subGroup the sub-group used to order actions within a group.
* @return this builder (for chaining)
*/
public B toolBarGroup(String group, String subGroup) {
toolBarSubGroup = group;
return self();
}
/**
* Sets the primary callback to be executed when this action is invoked. This builder will
* throw an {@link IllegalStateException} if one of the build methods is called without
* providing this callback
*
* @param action the callback to execute when the action is invoked
* @return this builder (for chaining)
*/
public B onAction(Consumer<ActionContext> action) {
actionCallback = action;
return self();
}
/**
* Sets a predicate for dynamically determining the action's enabled state. If this
* predicate is not set, the action's enable state must be controlled directly using the
* {@link DockingAction#setEnabled(boolean)} method. See
* {@link DockingActionIf#isEnabledForContext(ActionContext)}
*
* @param predicate the predicate that will be used to dynamically determine an action's
* enabled state.
* @return this builder (for chaining)
*/
public B enabledWhen(Predicate<ActionContext> predicate) {
enabledPredicate = predicate;
return self();
}
/**
* Sets a predicate for dynamically determining if this action should be included in
* an impending pop-up menu. If this predicate is not set, the action's will be included
* in an impending pop-up, if it is enabled. See
* {@link DockingActionIf#isAddToPopup(ActionContext)}
*
* @param predicate the predicate that will be used to dynamically determine an action's
* enabled state.
* @return this builder (for chaining)
*/
public B popupWhen(Predicate<ActionContext> predicate) {
popupPredicate = predicate;
return self();
}
/**
* Sets a predicate for dynamically determining if this action is valid for the current
* {@link ActionContext}. See {@link DockingActionIf#isValidContext(ActionContext)}
*
* @param predicate the predicate that will be used to dynamically determine an action's
* validity for a given {@link ActionContext}
* @return this builder (for chaining)
*/
public B validContextWhen(Predicate<ActionContext> predicate) {
validContextPredicate = predicate;
return self();
}
/**
* Sets a predicate for dynamically determining if this action is valid for the current global
* {@link ActionContext}. See {@link DockingActionIf#isValidGlobalContext(ActionContext)}
*
* @param predicate the predicate that will be used to dynamically determine an action's
* validity for a given global {@link ActionContext}
* @return this builder (for chaining)
*/
public B validGlobalContextWhen(Predicate<ActionContext> predicate) {
validGlobalContextPredicate = predicate;
return self();
}
protected void validate() {
if (actionCallback == null) {
throw new IllegalStateException(
"Can't build a DockingAction without an action callback");
}
}
protected void decorateAction(DockingAction action) {
action.setEnabled(isEnabled);
action.setDescription(description);
setMenuData(action);
setToolbarData(action);
setPopupMenuData(action);
if (helpLocation != null) {
action.setHelpLocation(helpLocation);
}
if (enabledPredicate != null) {
action.enabledWhen(enabledPredicate);
}
if (validContextPredicate != null) {
action.validContextWhen(validContextPredicate);
}
if (validGlobalContextPredicate != null) {
action.validGlobalContextWhen(validGlobalContextPredicate);
}
if (popupPredicate != null) {
action.popupWhen(enabledPredicate);
}
}
protected boolean isPopupAction() {
return popupPath != null;
}
protected boolean isToolbarAction() {
return toolbarIcon != null;
}
protected boolean isMenuAction() {
return menuPath != null;
}
private void setPopupMenuData(DockingAction action) {
if (isPopupAction()) {
action.setPopupMenuData(new MenuData(popupPath, popupIcon, popupGroup,
MenuData.NO_MNEMONIC, popupSubGroup));
}
}
private void setToolbarData(DockingAction action) {
if (isToolbarAction()) {
action.setToolBarData(new ToolBarData(toolbarIcon, toolBarGroup, toolBarSubGroup));
}
}
private void setMenuData(DockingAction action) {
if (isMenuAction()) {
action.setMenuBarData(
new MenuData(menuPath, menuIcon, menuGroup, menuMnemonic, menuSubGroup));
}
}
}

View file

@ -0,0 +1,54 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package docking.action.builder;
import docking.ActionContext;
import docking.action.DockingAction;
/**
* Builder for {@link DockingAction}s
*/
public class ActionBuilder
extends AbstractActionBuilder<DockingAction, ActionBuilder> {
/**
* Builder constructor
* @param name the name of the action to be built
* @param owner the owner of the action to be build
*/
public ActionBuilder(String name, String owner) {
super(name, owner);
}
@Override
protected ActionBuilder self() {
return this;
}
@Override
public DockingAction build() {
validate();
DockingAction action =
new DockingAction(name, owner, keyBindingType) {
@Override
public void actionPerformed(ActionContext context) {
actionCallback.accept(context);
}
};
decorateAction(action);
return action;
}
}

View file

@ -0,0 +1,105 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package docking.action.builder;
import java.util.Collections;
import java.util.List;
import docking.ActionContext;
import docking.action.DockingActionIf;
import docking.menu.MultiActionDockingAction;
/**
* Builder for {@link MultiActionDockingAction}
*/
public class MultiActionBuilder
extends AbstractActionBuilder<MultiActionDockingAction, MultiActionBuilder> {
/**
* List of actions for the the MultActionDockingAction
*/
private List<DockingActionIf> actionList = Collections.emptyList();
/**
* determines if the the main action is invokable
*/
private boolean performActionOnButtonClick = true;
/**
* Builder constructor
* @param name the name of the action to be built
* @param owner the owner of the action to be build
*/
public MultiActionBuilder(String name, String owner) {
super(name, owner);
}
@Override
protected MultiActionBuilder self() {
return this;
}
@Override
public MultiActionDockingAction build() {
validate();
MultiActionDockingAction action =
new MultiActionDockingAction(name, owner) {
@Override
public void actionPerformed(ActionContext context) {
actionCallback.accept(context);
}
};
decorateAction(action);
action.setActions(actionList);
action.setPerformActionOnButtonClick(performActionOnButtonClick);
return action;
}
/**
* Configure a {@link List} of {@link DockingActionIf} to provide to the {@link MultiActionDockingAction}
* @param list a {@link List} of {@link DockingActionIf} to provide to the {@link MultiActionDockingAction}
* @return this MultiActionDockingActionBuilder (for chaining)
*/
public MultiActionBuilder withActions(List<DockingActionIf> list) {
this.actionList = list;
for (DockingActionIf action : actionList) {
if (action.getMenuBarData() == null) {
throw new IllegalStateException(
"actions in the actionList must have MenuBarData defined");
}
}
return self();
}
/**
* Configure whether to perform actions on a button click.
* See {@link MultiActionDockingAction#setPerformActionOnButtonClick(boolean)}
*
* @param b true if the main action is invokable
* @return this MultiActionDockingActionBuilder (for chaining)
*/
public MultiActionBuilder performActionOnButtonClick(boolean b) {
this.performActionOnButtonClick = b;
return self();
}
@Override
protected void validate() {
super.validate();
if (actionList == null) {
throw new IllegalStateException("No ActionList has been set");
}
}
}

View file

@ -0,0 +1,113 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package docking.action.builder;
import java.util.function.BiConsumer;
import docking.ActionContext;
import docking.menu.*;
import docking.widgets.EventTrigger;
/**
* Builder for {@link MultiStateDockingAction}
*
* @param <T> The action state type
*/
public class MultiStateActionBuilder<T> extends
AbstractActionBuilder<MultiStateDockingAction<T>, MultiStateActionBuilder<T>> {
private BiConsumer<ActionState<T>, EventTrigger> actionStateChangedCallback;
private boolean performActionOnButtonClick;
/**
* Builder constructor
* @param name the name of the action to be built
* @param owner the owner of the action to be build
*/
public MultiStateActionBuilder(String name, String owner) {
super(name, owner);
}
@Override
protected MultiStateActionBuilder<T> self() {
return this;
}
/**
* Sets the primary callback to be executed when this action changes its action state.
* This builder will throw an {@link IllegalStateException} if one of the build methods is
* called without providing this callback
*
* @param biConsumer the callback to execute when the selected action state is changed.
* @return this builder (for chaining)
*/
public MultiStateActionBuilder<T> onActionStateChanged(
BiConsumer<ActionState<T>, EventTrigger> biConsumer) {
actionStateChangedCallback = biConsumer;
return self();
}
/**
* Configure whether to perform actions on a button click.
* See {@link MultiActionDockingAction#setPerformActionOnButtonClick(boolean)}
*
* @param b true if the main action is invokable
* @return this MultiActionDockingActionBuilder (for chaining)
*/
public MultiStateActionBuilder<T> performActionOnButtonClick(boolean b) {
this.performActionOnButtonClick = b;
return self();
}
@Override
public MultiStateDockingAction<T> build() {
validate();
MultiStateDockingAction<T> action =
new MultiStateDockingAction<T>(name, owner, isToolbarAction()) {
@Override
public void actionStateChanged(ActionState<T> newActionState,
EventTrigger trigger) {
actionStateChangedCallback.accept(newActionState, trigger);
}
@Override
protected void doActionPerformed(ActionContext context) {
if (actionCallback != null) {
actionCallback.accept(context);
}
}
};
decorateAction(action);
action.setPerformActionOnPrimaryButtonClick(performActionOnButtonClick);
return action;
}
@Override
protected void validate() {
if (performActionOnButtonClick) {
super.validate(); // require an action callback has been defined
}
if (actionStateChangedCallback == null) {
throw new IllegalStateException(
"Can't build a MultiStateDockingAction without an action state changed callback");
}
}
}

View file

@ -0,0 +1,72 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package docking.action.builder;
import docking.ActionContext;
import docking.action.ToggleDockingAction;
/**
* Builder for {@link ToggleDockingAction}s
*/
public class ToggleActionBuilder extends
AbstractActionBuilder<ToggleDockingAction, ToggleActionBuilder> {
/**
* The initial toggle state for the action
*/
private boolean select;
/**
* Builder constructor
* @param name the name of the action to be built
* @param owner the owner of the action to be build
*/
public ToggleActionBuilder(String name, String owner) {
super(name, owner);
}
@Override
protected ToggleActionBuilder self() {
return this;
}
@Override
public ToggleDockingAction build() {
validate();
ToggleDockingAction action =
new ToggleDockingAction(name, owner, keyBindingType) {
@Override
public void actionPerformed(ActionContext context) {
actionCallback.accept(context);
}
};
decorateAction(action);
action.setSelected(select);
return action;
}
/**
* Configure the initial select state for the toggle action.
* @param b the initial select state
*
* @return self Builder (for chaining)
*/
public ToggleActionBuilder selected(boolean b) {
this.select = b;
return this;
}
}