Get Reference to Component in ToolWindow

I've been following along with https://devnet.jetbrains.com/message/5491616 to try to and do something similar where I log output to a console from http request responses.

I've created a toolWindowFactory and inserted the console

public class MyToolWindowFactory implements ToolWindowFactory {          @Override     public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {         ConsoleView consoleView = TextConsoleBuilderFactory.getInstance().createBuilder(project).getConsole();         Content content = toolWindow.getContentManager().getFactory().createContent(consoleView.getComponent(), "", true);         toolWindow.getContentManager().addContent(content);     } }


I've registered it in the plugin xml

<toolWindow id="My Log" icon="/icons/myIcon.png" anchor="bottom" factoryClass="com.example.toolWindow.MyToolWindowFactory"/>



and it shows up properly, but now I can't figure out how to get the reference to the inner consoleView component back out of the toolWindow in order to log to the console.

// Another Class in my Application

ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow("My Log");

// ...?

consoleView.print("Hello World", ConsoleViewContentType.NORMAL_OUTPUT);

7 comments
Comment actions Permalink

I figured out two ways of accomplishing this.

public class MyToolWindowFactory implements ToolWindowFactory {     @Override     public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {         ConsoleView consoleView = TextConsoleBuilderFactory.getInstance().createBuilder(project).getConsole();         Content content = toolWindow.getContentManager().getFactory().createContent(consoleView.getComponent(), "", true);         content.setDisplayName("");         toolWindow.getContentManager().addContent(content);     } }


Then use findContent to retreive the content by displayName. I set it to an empty string so it wouldn't append the name to the console window.

ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow("MyToolWindow"); ContentManager contentManager = toolWindow.getContentManager(); Content content = contentManager.findContent(""); ConsoleView consoleView = (ConsoleView) content.getComponent();


The second way uses an index to get the content, but that sometimes throws an execption if the ConsolveView is not in the right place on start up.

ToolWindow toolWindow = ToolWindowManager.getInstance(project).getToolWindow("MyToolWindow"); ContentManager contentManager = toolWindow.getContentManager(); Content content = contentManager.getContent(0);
assert content != null; ConsoleView consoleView = (ConsoleView) content.getComponent();


The first method using a displayName seems like a bad idea as well as depending on an index. I know there has to be a better way of doing this.

0
Comment actions Permalink

U could make a static field in the ToolWindowFactory class and create a getter for it.

0
Comment actions Permalink

Thanks that seems to work. Although I got a null reference to the consoleView in the logs randomly. I'll have to investigate. My guess is I tried to log to it before it was initialized by the plugin.

0
Comment actions Permalink

I figured out why the null reference happens, The toolWindow is not initialized until it is opened. Is there a way to work around this? I need the project in order to create the console view. Not sure how I can fix this.

0
Comment actions Permalink

I ended up making a project service.

 
public class ConsoleService {
    private final ConsoleView consoleView;

    public
ConsoleService(Project project) {
        consoleView = TextConsoleBuilderFactory.getInstance().createBuilder(project).getConsole();
    
}

    public ConsoleView getConsoleView() {
        return consoleView;
    
}
}


and registering it with:

 
<projectService id="ConsoleView" serviceImplementation="com.example.toolWindow.ConsoleService"/>



That way it's initialized as soon as the project opens and I don't have to worry about whether the toolwindow has been opened or not.

0
Comment actions Permalink

Instead of a service you could also use a project component, but I don't know if this is better than your approach.

0
Comment actions Permalink

Hmmm now I'm curious when you'd want to use one vs. the other.

0

Please sign in to leave a comment.