如何从自定义的ToolWindow调用IntelliJ重命名重构?

问题描述 投票:0回答:1

我正在开发一个IntelliJ插件,它有自己的工具窗口。该插件应该在用户按下按键时调用IntelliJ内置的rename refactor函数来重命名一个变量。当我运行我的例子时,当我按下一个键来调用rename refactor函数时,会抛出以下异常。

2020-05-16 23:03:17,741 [  41062]  ERROR - llij.ide.plugins.PluginManager - EventQueue.isDispatchThread()=false Toolkit.getEventQueue()=com.intellij.ide.IdeEventQueue@574ed46a
Current thread: Thread[JavaFX Application Thread,6,Idea Thread Group] 648578026
Write thread (volatile): Thread[AWT-EventQueue-0,6,Idea Thread Group] 807407917com.intellij.openapi.diagnostic.Attachment@339b1167 
com.intellij.openapi.diagnostic.RuntimeExceptionWithAttachments: EventQueue.isDispatchThread()=false Toolkit.getEventQueue()=com.intellij.ide.IdeEventQueue@574ed46a
Current thread: Thread[JavaFX Application Thread,6,Idea Thread Group] 648578026
Write thread (volatile): Thread[AWT-EventQueue-0,6,Idea Thread Group] 807407917com.intellij.openapi.diagnostic.Attachment@339b1167
    at com.intellij.openapi.application.impl.ApplicationImpl.assertIsWriteThread(ApplicationImpl.java:1068)
    at com.intellij.openapi.application.impl.ApplicationImpl.startWrite(ApplicationImpl.java:1154)
    at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:974)
    at MyToolWindowFactory.handle(MyToolWindowFactory.java:55)
    at MyToolWindowFactory.handle(MyToolWindowFactory.java:17)

我以为调用 setName 作为一个lambda函数在 ApplicationManager.getApplication().runWriteAction 将工作,但显然不是。我怎么才能让它工作呢?

下面是我使用的完整代码。

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.psi.*;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.VBox;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;

public class MyToolWindowFactory implements ToolWindowFactory, EventHandler<KeyEvent> {

    PsiField[] variables;

    @Override
    public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
        final JFXPanel fxPanel = new JFXPanel();
        JComponent component = toolWindow.getComponent();

        ApplicationManager.getApplication().invokeLater(() -> {
            PsiClass currentClass = getCurrentClass(project);
            variables = currentClass.getFields();

            Scene scene = new Scene(new VBox(), 400, 250);
            scene.setOnKeyPressed(this);
            fxPanel.setScene(scene);
            fxPanel.requestFocus();
        });

        component.getParent().add(fxPanel);
    }

    private PsiClass getCurrentClass(Project project) {
        // Get the currently selected file.
        FileEditorManager manager = FileEditorManager.getInstance(project);
        VirtualFile[] files = manager.getSelectedFiles();
        VirtualFile currentFile = files[0];

        // Get the PsiClass for the currently selected file.
        PsiFile psiFile = PsiManager.getInstance(project).findFile(currentFile);
        PsiJavaFile psiJavaFile = (PsiJavaFile)psiFile;
        final PsiClass[] classes = psiJavaFile.getClasses();

        return classes[0];
    }

    @Override
    public void handle(KeyEvent event) {
        ApplicationManager.getApplication().runWriteAction(() -> {
            variables[0].setName("newVariableName");
        });
    }
}
java intellij-idea intellij-plugin
1个回答
0
投票

有一种方法可以让它工作,那就是调用来自于 WriteCommandAction.runWriteCommandAction 方法。此外,只需调用 setName 只对变量声明进行重命名。为了重命名对变量的所有引用,我首先用 ReferencesSearch.search 方法,然后调用 handleElementRename 在每个引用上。

public void handle(KeyEvent event) {
    Runnable r = ()->
    {
        for (PsiReference reference : ReferencesSearch.search(variables[0])) {
            reference.handleElementRename(variableName);
        }
        variables[0].setName(variableName);
    }
    WriteCommandAction.runWriteCommandAction(project, r);
}

得到提示,使用 WriteCommandAction 从这里。https:/intellij-support.jetbrains.comhcen-uscommunityposts206754235。

© www.soinside.com 2019 - 2024. All rights reserved.