An annoying problem I had this week involved the CallbackSystemAction class.
Basically
the general ideea of this type of action is this: you have the Action
implementation, but the "#actionPerformed code" is deferred.
What was my problem: depending on the user selection in an explorer, my
action was supposed to become enabled or not (plus some othe
conditions).
So, the javadoc says that way to do it is by setting an action in the
ActionMap of the TopComponent.
TopComponent tc = ...; javax.swing.Action yourCopyAction = ...; // the action to invoke instead of Copy
CopyAction globalCopyAction = SystemAction.get (CopyAction.class); Object key = globalCopyAction.getActionMapKey(); // key is a special value defined by all CallbackSystemActions
// and finally: tc.getActionMap ().put (key, yourCopyAction);
The problem is that there is no listener on the action map. So if I want later to disable my action and I do a tc.getActionMap().remove(key) -- it won't
work ! I mean, it will work if you change the current TopComponent and
come back to the original (I guess there are some event thrown there
that CallbackSystemAction catches and does a refresh).
So, using the ActionMap.put and #remove doesn't work !
Ok, I said to myself, I'll just use the deprecated #setActionPerformer
, which seems to work better. Only it is deprecated, which is not good.
I went and complained on the dev@openide mailing list and I got a tip
that I should change my TopComponent's lookup in order to fire the
events that CallbackSystemAction might catch to refresh itself.
But you can't call #associateLookup twice ! Arr.
So I just started reading carefully the CallbackSystemAction source
code and I've noticed that it does put a listener on the
enabled/disable state of the TopComponent's action (ie. yourCopyAction
in the example above).
So -- what's the solution ? Dead simple: call getActionMap().put(...) once and then just do a #setEnabled on your Action. Simple -- but very non-intuitive.
Actually in this situation I would say that the Javadoc was more confusing than useful because it says
The action will be automatically disabled when it has no performer.
and removing your action from the ActionMap means exactly that: no performer...
|