GT-1 fixing action enablement bug

This commit is contained in:
ghidravore 2020-09-22 17:30:32 -04:00
parent 56dd9f02cf
commit 3c289e8816
2 changed files with 30 additions and 2 deletions

View file

@ -52,7 +52,14 @@ import utilities.util.reflection.ReflectionUtilities;
* method is used to determine if an action if applicable to the current context. Overriding this * method is used to determine if an action if applicable to the current context. Overriding this
* method allows actions to manage their own enablement. Otherwise, the default behavior for this * method allows actions to manage their own enablement. Otherwise, the default behavior for this
* method is to return the current enabled property of the action. This allows for the possibility * method is to return the current enabled property of the action. This allows for the possibility
* for plugins to manage the enablement of its actions. * for plugins to externally manage the enablement of its actions.
* <P>
* NOTE: If you wish to do your own external enablement management for an action (which is highly
* discouraged), it is very important that you don't use any of the internal enablement mechanisms
* by setting the predicates {@link #enabledWhen(Predicate)}, {@link #validContextWhen(Predicate)}
* or overriding {@link #isValidContext(ActionContext)}. These predicates and methods trigger
* internal enablement management which will interfere with you own calls to
* {@link DockingAction#setEnabled(boolean)}.
*/ */
public abstract class DockingAction implements DockingActionIf { public abstract class DockingAction implements DockingActionIf {

View file

@ -516,7 +516,8 @@ public abstract class AbstractActionBuilder<T extends DockingActionIf, C extends
* *
* <p>If this predicate is not set, the action's enable state must be controlled * <p>If this predicate is not set, the action's enable state must be controlled
* directly using the {@link DockingAction#setEnabled(boolean)} method. We do not recommend * directly using the {@link DockingAction#setEnabled(boolean)} method. We do not recommend
* controlling enablement directly. * controlling enablement directly. And, of course, if you do set this predicate, you should
* not later call {@link DockingAction#setEnabled(boolean)} to manually manage enablement.
* *
* @param predicate the predicate that will be used to dynamically determine an action's * @param predicate the predicate that will be used to dynamically determine an action's
* enabled state * enabled state
@ -556,6 +557,9 @@ public abstract class AbstractActionBuilder<T extends DockingActionIf, C extends
* *
* <p>Note: most actions will not use this method, but rely instead on * <p>Note: most actions will not use this method, but rely instead on
* {@link #enabledWhen(Predicate)}. * {@link #enabledWhen(Predicate)}.
*
* <p>Note: this triggers automatic action enablement so you should not later call
* {@link DockingAction#setEnabled(boolean)} to manually manage action enablement.
* *
* @param predicate the predicate that will be used to dynamically determine an action's * @param predicate the predicate that will be used to dynamically determine an action's
* validity for a given {@link ActionContext} * validity for a given {@link ActionContext}
@ -563,6 +567,13 @@ public abstract class AbstractActionBuilder<T extends DockingActionIf, C extends
*/ */
public B validContextWhen(Predicate<C> predicate) { public B validContextWhen(Predicate<C> predicate) {
validContextPredicate = Objects.requireNonNull(predicate); validContextPredicate = Objects.requireNonNull(predicate);
// automatic enablement management triggered, make sure there is a existing enablement
// predicate. The default behavior of manual management interferes with automatic management.
if (enabledPredicate == null) {
enabledPredicate = ALWAYS_TRUE;
}
return self(); return self();
} }
@ -614,6 +625,10 @@ public abstract class AbstractActionBuilder<T extends DockingActionIf, C extends
* {@literal builder.enabledWhen(context -> return context.isAwesome() }} * {@literal builder.enabledWhen(context -> return context.isAwesome() }}
* </pre> * </pre>
* *
* <p>Note: this triggers automatic action enablement so you should not later call
* {@link DockingAction#setEnabled(boolean)} to manually manage action enablement.
*
* @param newActionContextClass the more specific ActionContext type. * @param newActionContextClass the more specific ActionContext type.
* @param <AC2> The new ActionContext type (as determined by the newActionContextClass) that * @param <AC2> The new ActionContext type (as determined by the newActionContextClass) that
* the returned builder will have. * the returned builder will have.
@ -629,6 +644,12 @@ public abstract class AbstractActionBuilder<T extends DockingActionIf, C extends
throw new IllegalStateException("Can't set the ActionContext type more than once"); throw new IllegalStateException("Can't set the ActionContext type more than once");
} }
// automatic enablement management triggered, make sure there is a existing enablement
// predicate. The default behavior of manual management interferes with automatic management.
if (enabledPredicate == null) {
enabledPredicate = ALWAYS_TRUE;
}
// To make this work, we need to return a builder whose ActionContext is AC2 and not AC // To make this work, we need to return a builder whose ActionContext is AC2 and not AC
// (which is what this builder is now) // (which is what this builder is now)
// //