How can I create a custom right click menu that contains a couple of actions, and attach the menu to each element in a JTree in my plugin?

Answered

In short I want the user to be able to right click any node in the tree and invoke one of the actions with the selected node as a parameter. I have read through the documentation about creating actions, but I don't fully understand how I can create and associate an action menu with each node. I am fairly new to kotlin so any help is appretiated.

7 comments
Comment actions Permalink

Hi Kaiwalya,

Please clarify what tree you mean and describe your use case.

0
Comment actions Permalink

Hi Karol Lewandowski

Thanks for responding. I mean a 

javax.swing.JTree

I am building a JTree object and populating it with 

javax.swing.tree.DefaultMutableTreeNode

 My use case is that I have a ToolWindow that contains the above JTree and want to allow the user to right-click on any of the Tree nodes, which should open a context menu. In the menu, I want to have a few actions, that should be invoked when a user clicks them. Additionally, the actions themselved need to know which node was right-clicked upon. Does this help? Apologies, I am very new to java/kotlin world. Thanks in advance

0
Comment actions Permalink

Thanks for the clarification.

I suggest taking a look at: https://github.com/JetBrains/intellij-community/blob/master/platform/lang-impl/src/com/intellij/packageDependencies/ui/DependenciesPanel.java

Key points:

  • It installs actions popup on the tree in line 335:
    PopupHandler.installPopupMenu(tree, createTreePopupActions(isRightTree), "DependenciesPopup");
  • It implements DataProvider and getData(), returning the data requested from the triggered action based on the selected tree item.

 

0
Comment actions Permalink

Thanks for the help, I could get the popup menu and the invocation of the action working now.

As for the DataProvider implementation - My main plugin tool window class looks something like this :-

class MyToolWindow {
var content: JPanel
private lateinit var myTree: JTree

init{
populateTreeNodes()
PopupHandler.installPopupMenu(myTree, createTreePopupActions(), "My Actions")
...
}
}

However, since `myTree` needs to implement DataProvider, as I understand I can't use JTree as the type anymore and will need to create class `MyTree` similar to the one in the example. Having done that, I now get errors from the corresponding `.form` file saying "Incompatible types. Found 'MyTree', but required 'JTree'". Is there any obvious mistake I am making with respect to the form?

0
Comment actions Permalink

I think I might have figured out how to get my tree class into the form. 

Let me rephrase my question about the data provider part.

Consider the following scenario: I have setup the tool window and the tree. I run the plugin. I right clicked on `node A` in the tree, opened the context menu and invoked MyAction() as expected.

Now I am inside

MyAction.actionPerformed(p0: AnActionEvent)

My question now, is that inside this actionPerformed(), how to I get "node A"  using p0 ? If it helps, all I really care about is getting the string "node A". I don't rally need the node itself.

0
Comment actions Permalink

In your component implementing DataProvider you should implement getData() method that will return the selected element information for a given data key. The data key may be your custom key to retrieve this specific information (see com.intellij.openapi.actionSystem.CommonDataKeys to see common data keys).

Let's say you have MyDataKeys.SELECTED_NODE_TEXT key.

In your DataProvider.getData(dataId: String):

if (MyKeys.SELECTED_NODE_TEXT.`is`(dataId)) {
    return mySelectedNode.text // or whatever you want to return
}

In your AnAction.actionPerformed(event: AnActionEvent) method do something like:

val nodeText = event.getData(MyKeys.SELECTED_NODE_TEXT)
0
Comment actions Permalink

Karol Lewandowski Thanks for the quick response and a simplified explanation. I appreciate it. This works just the way I intended!!

I am still seeing some errors like the getData() method returning a null value when the key isn't my custom key. But I will debug and figure it out.

0

Please sign in to leave a comment.