How to display method text in an EditorTextField?
Answered
I'm having some trouble displaying the text of a Java method in a EditorTextField that is in a tool window. Below is the code I have now. I am expecting it to display the method body of the first method in the currently opened class in an EditorTextField in the tool window, but it just shows an empty EditorTextField instead. What could I be doing wrong?
public class EditorNodeTest implements ToolWindowFactory {
@Override
public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
JFXPanel fxPanel = new JFXPanel();
DumbService.getInstance(project).smartInvokeLater(() -> Platform.runLater(() -> {
// Create the Java editor node.
PsiClass currentClass = getCurrentClass(project);
PsiMethod method = currentClass.getMethods()[0];
JavaCodeFragmentFactory javaFactory = JavaCodeFragmentFactory.getInstance(project);
PsiExpressionCodeFragment code = javaFactory.createExpressionCodeFragment(method.getBody().getText(), method, null, true);
Document document = ApplicationManager.getApplication().runReadAction((Computable<Document>) () -> PsiDocumentManager.getInstance(project).getDocument(code));
EditorTextField myInput = new EditorTextField(document, project, JavaFileType.INSTANCE);
SwingNode editorNode = new SwingNode();
editorNode.setContent(myInput.getComponent());
// Add the editor node to the scene.
VBox root = new VBox();
root.getChildren().add(editorNode);
Scene scene = new Scene(root);
fxPanel.setScene(scene);
}));
JComponent component = toolWindow.getComponent();
component.getParent().add(fxPanel);
}
protected static PsiClass getCurrentClass(Project p) {
// Get the currently selected file.
FileEditorManager manager = FileEditorManager.getInstance(p);
VirtualFile[] files = manager.getSelectedFiles();
VirtualFile currentFile = files[0];
// Get the PsiClass for the currently selected file.
final PsiClass[] curClass = new PsiClass[1];
ApplicationManager.getApplication().runReadAction(() -> {
PsiFile psiFile = PsiManager.getInstance(p).findFile(currentFile);
PsiJavaFile psiJavaFile = (PsiJavaFile) psiFile;
curClass[0] = psiJavaFile.getClasses()[0];
});
return curClass[0];
}
}
Please sign in to leave a comment.
First of all - is it necessary for you to use JFXPanel and so on?
I have simplified it to use just JPanel and EditorTextField was displayed correctly in the ToolWindow. However, the component that you have created is just a single line, so it displays me the first line of the content:
Yes, I do want to use JavaFX.
I was able to get it to show one line like in that screenshot with JavaFX by just adding the EditorTextField component to a JPanel before adding it to the SwingNode. However I want it to show all lines of the method body.
Do you know if there is a component that is like the EditorTextField but supports multiple lines? I know about the FileEditor component, but that seems to only work on entire files. I want to just show one method.
You can create an Editor using the following method:
It doesn't require the file to be present - just a document, which you can create also with EditorFactory passing the content string.
Thanks, I was able to get it to show the entire method body even without needing a JPanel, although for some reason I have to highlight the top of the tool window to show the method text in the editor. However I can't figure out how to make the editor actually editable. I created the Editor like so:
but it still doesn't let me edit it. Here is the code I have so far for the createToolWindowContent method, and a screenshot. How can I make the Editor editable?
By editing, you mean modifying the source file? Do I understand you correctly, that in ToolWindow you want to present just a part of the Java file and let the user edit it as in a regular editor?
Yes, that is what I want to do. I want it to look exactly like editing the Java source file in the regular editor with auto-complete, syntax highlighting, etc., except it's now in a tool window, and only shows the code for one method.
Syntax highlighting will report errors because your source provided to the editor will not be complete - missing surrounding class, no context, references to the other methods will not be resolved.
Shouldn't the references be resolved by providing the PsiMethod object when creating the PsiExpressionFragment object? Or is there another way to let the tool window editor know the context of the code it contains?
Also I got the editor to be editable by using a JPanel instead of JavaFX.
I'm going to try using the full editor in the tool window, but cover up the parts that don't include the method I want to show. Thanks for the help!