Search code examples
intellij-ideapluginsintellij-plugin

How to access components inside a custom ToolWindow from an action?


I have registered an action in the EditorPopupMenu (this is right click menu). I also have a bunch of components inside a ToolWindow (that I designed using the GUI Designer plugin) that I want to update the values of.

There have been some posts on the IntelliJ forums about this, and the typical answer seems to advice using the ToolWindow's ContentManager, and obtain the JPanel containing all your components. E.g. the following:

    Project p = e.getProject();

    ToolWindow toolWindow;
    toolWindow = ToolWindowManager.getInstance(p).getToolWindow("My ToolWindow ID");

    ContentManager contentManager = toolWindow.getContentManager();

    JPanel jp = (JPanel) contentManager.getContent(0).getComponent();

This feels counterintuitive... Having to navigate inside JPanel's to find a bunch of components. What if I decided to put my components inside a different container? Suddenly the way I navigate to my components would break down.

Is it really the most practical way to constrain myself to the way my GUI is built? Can't I access these components in a different way?


Solution

  • I found a way to access my custom myToolWindow. This should help quite some people.

    1. Make sure that your custom MyToolWindow extends the class SimpleToolWindowPanel.
    2. In your custom myToolWindowFactory class, pass your custom MyToolWindow to ContentFactory.createContent() as the first argument. NOT one of the JPanel's inside MyToolWindow as is done in the ToolWindow examples given in the official IntelliJ documentation...
    3. In your MyToolWindow constructor, call the method setContent(<YourJPanelContainingYourComponents>).

    I found the answer by experimenting on example 5 from this link:

    public JBTabbedTerminalWidget getTerminalWidget(ToolWindow window) {
        window.show(null);
        if (myTerminalWidget == null) {
            JComponent parentPanel = window.getContentManager().getContents()[0].getComponent();
            if (parentPanel instanceof SimpleToolWindowPanel) {
                SimpleToolWindowPanel panel = (SimpleToolWindowPanel) parentPanel;
                JPanel jPanel = (JPanel) panel.getComponents()[0];
                myTerminalWidget = (JBTabbedTerminalWidget) jPanel.getComponents()[0];
            } else {
                NotificationUtils.infoNotification("Wait for Freeline to initialize");
            }
        }
        return myTerminalWidget;
    }