Popup in IntentionAction

Hello,

I am using Selena build # 7718, and I'm trying to implement an IntentionAction which - after starting the invocation - offers the user a list of available "variants" of the action in a popup list and (depending on the selected variant) then proceeds with the action.

I have tried something like the following:


I had expected the code to wait for the popup to be displayed and for the user to make a selection, but obviously the popup is run in a different thread and the thread running the IntentionAction will proceed immediately (with idx always being 0).
I have tried to synchronize the IntentionAction and popup in by calling PopupChooserBuilder.setItemChooserCallback() and having that runnable communicate with the "intention action thread" via a SynchronousQueue; alternatively I have tried using a CyclicBarrier, but in either case I seem to be running into some sort of locking problems because the application freezes before the popup is shown.
Finally, I have tried to move the "second half" of the intention action code into the callback, and that seems to work at least partially (because the popup is shown as it should), but when I then modify the editor file, I get error messages like "Write access is allowed insode write-action only" or - if I use ApplicationManager.runWriteAction() - the error "Undoable actions allowed insode commands only".

Can somebody give me a hint on how to achieve this - really not so complex - task, or point me to the source of some other plugin doing a thing like that?

Thanks in advance and best regards,
Jens

2 comments
Comment actions Permalink

Hello Jens,

There are no multiple threads involved here: all the processing is done in
the event dispatch thread. Simply put your action code in the callback, and
surround it with ApplicationManager.getApplication().runWriteAction() and
CommandProcessor.getInstance().executeCommand. (Or use WriteCommandAction
helper class to do these two things in one step.)

I am using Selena build # 7718, and I'm trying to implement an
IntentionAction which - after starting the invocation - offers the
user a list of available "variants" of the action in a popup list and
(depending on the selected variant) then proceeds with the action.

I have tried something like the following:

 public void invoke(Project project, Editor editor, PsiFile file) {
> ...
> final JList list = new JList(variantNames);
> PopupChooserBuilder builder = new PopupChooserBuilder(list);
> JBPopup popup = builder.setTitle("Select Variant").createPopup();
> popup.showInBestPositionFor(editor);
> // popup displayed
> 
> int idx = list.getSelectedIndex();
> 
> ... // proceed
> }
> ]]>

I had expected the code to wait for the popup to be displayed and for
the user to make a selection, but obviously the popup is run in a
different thread and the thread running the IntentionAction will
proceed immediately (with idx always being 0).

I have tried to synchronize the IntentionAction and popup in by
calling PopupChooserBuilder.setItemChooserCallback() and having that
runnable communicate with the "intention action thread" via a
SynchronousQueue; alternatively I have tried using a CyclicBarrier,
but in either case I seem to be running into some sort of locking
problems because the application freezes before the popup is shown.

Finally, I have tried to move the "second half" of the intention
action code into the callback, and that seems to work at least
partially (because the popup is shown as it should), but when I then
modify the editor file, I get error messages like "Write access is
allowed insode write-action only" or - if I use
ApplicationManager.runWriteAction() - the error "Undoable actions
allowed insode commands only".

Can somebody give me a hint on how to achieve this - really not so
complex - task, or point me to the source of some other plugin doing a
thing like that?

Thanks in advance and best regards,
Jens

--
Dmitry Jemerov
Development Lead
JetBrains, Inc.
http://www.jetbrains.com/
"Develop with Pleasure!"


0
Comment actions Permalink

Works beautifully; thanks a lot!

(P.S.: Thanks for mentioning the fact that all GUI code is executed in a single Thread; that of course explains why I couldn't synchronize the two code fragments!)

0

Please sign in to leave a comment.