IDEA插件开发

  • Post author:
  • Post category:其他


插件的用途:

  • 提升开发效率
  • 改变界面显示



plugin.xml文件属性说明

  • id:表示当前插件的唯一id号
  • name:插件的名称
  • version:插件的版本号
  • vendor:填写开发人的邮箱,公司名称
  • description:插件的描述,如果将插件上传到IDEA的仓库后,在进行下载的时候就会显示该描述
  • idea-version:表示当前插件所支持的所有Intellij Idea 的版本
  • extensions:这里一般会放一些我们自己的扩展的东西,比如新增高亮显示,新增语言支持都是需要在这里进行扩展
  • actions:新增的Action类需要在这里注册,用于菜单栏扩展
  • Group:如果想定义一个跟Help同级的菜单,或者是定义包含多个子选项的菜单



Action行为

1.在plugin.xml文件中的写好对应的配置,如下

<actions>
	<action id="com.manling.action.manager.ManagerAction" 	class="com.manling.action.manager.ManagerAction" popup="true" icon="/miniIcon.png" text="漫灵类模板" description="漫灵的类模板组">
     <add-to-group group-id="NewGroup" anchor="first"/>
</action>

2.代码实现对应的逻辑,需要继承 com.intellij.openapi.actionSystem.AnAction 类,然后重写com.manling.action.manager.ManagerAction#actionPerformed 实现自己的逻辑即可

public class ManagerAction extends AnAction {
    @Override
    public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
        System.out.println("MethodAction");
    }
}

3.在Build中点击构建出来一个插件,然后即可在其他的IDEA中安装此插件。



group组

group属性多用于定义包含多个子选项的菜单,然后每个组中可以放入多个Action行为。

 <actions>
	<group id="com.manling.group.MethodGroup" class="com.manling.group.MethodGroup" 				popup="true" text="创建方法" description="漫灵的方法模板组">
        <action id="com.manling.action.method.ListenMethodAction"
                class="com.manling.action.method.ListenMethodAction" text="事件监听"/>
        <action id="com.manling.action.method.MessageMethodAction"
                class="com.manling.action.method.MessageMethodAction" text="消息处理"/>
    </group>
 </actopms>

注意:group组可以在某些情况下显示可用,或者不可显示或不可用需要继承com.intellij.openapi.actionSystem.DefaultActionGroup 然后重写其update()方法。

如下:

public class FilePluginGroup extends DefaultActionGroup {

    @Override
    public void update(@NotNull AnActionEvent e) {
        Presentation presentation = e.getPresentation();
        presentation.setEnabled(true);
        presentation.setVisible(true);
    }
}



extensions扩展

这里一般会放一些我们自己的扩展的东西,比如自定义设置窗口,持久化处理,新增语言支持等都是需要在这里进行扩展。



如下演示我们自定义设置窗口以及自定义存储

存储需要实现com.intellij.openapi.components.PersistentStateComponent接口。

需要实现两个重要的方法:

public interface PersistentStateComponent<T> {
    @Nullable
    //保存的数据
    T getState();
	
	//加载数据
    void loadState(@NotNull T var1);

    default void noStateLoaded() {
    }
}

而在设置中自定义自己的窗口就需要在extends中注册对应的类,并继承自com.intellij.openapi.options.SearchableConfigurable 接口

然后创建对应的Form窗口。

在类中把持久化类以及窗口类都作为其属性变量,然后就可以操作设置了。

public class ConstFilePathConfigurable implements SearchableConfigurable {

	//窗口类
    private ConstPathForm constPathForm = new ConstPathForm();
	//持久化类
    private ConstFilePathSetting setting = ConstFilePathSetting.getInstance();

    @NotNull
    @Override
    public String getId() {
        return "CodeAutoMaker";
    }

    @Nls(capitalization = Nls.Capitalization.Title)
    @Override
    public String getDisplayName() {
        return this.getId();
    }

    @Nullable
    @Override
    public String getHelpTopic() {
        return this.getId();
    }

    /**
     * 创建控件用于显示
     */
    @Nullable
    @Override
    public JComponent createComponent() {
      
    }

    /**
     * 判断是否已经修改 【判断是否可以保存数据,true可以】
     */
    @Override
    public boolean isModified() {

    }

    /**
     * 应用的时候会调用 【一般用于保存设置的数据】
     *
     * @throws ConfigurationException
     */
    @Override
    public void apply() throws ConfigurationException {
       
    }

    /**
     * 撤回reset会调用,【用于撤回时数据处理
     */
    @Override
    public void reset() {
      
    }
}



API操作



常用对象
PsiFile: 对应于应用中的文件,如.Java的文件或者是.xml的文件等;
PsiDirectory: 对应于应用中的目录
PsiJavaFile: 对应于Java源文件,如Test.java
PsiClass: 对应于某个类,其中一个文件中可能会有多个类
PsiMethod: 对应于类中的某个方法
PsiField: 对应于类中的某个属性
PsiAnnotation: 对应于注解


常用方法

获取当前项目:

Project project = anActionEvent.getProject();

获取当前的编辑器对象:

Editor editor = anActionEvent.getData(CommonDataKeys.EDITOR);

获取当前编辑的文件:

PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
或
PsiFile psiFile = PsiUtilBase.getPsiFileInEditor(editor, e.getProject());

如果是Java文件,可以转换成PsiJavaFile

PsiJavaFile javaFile = (PsiJavaFile)psiFile;

获取JavaFile中的Class:

一个文件中可能会定义有多个Class,因此返回的是一个数组

PsiClass[] classes = javaFile.getClasses();

PsiClass的常用方法:

获取所有属性:getFields、getAllFields
查找属性:findFieldByName(),其中第二个参数是是否查找父类的属性;
获取所有方法:getMethods/getAllMethods
查找方法:findMethodsByName

Import某个类:由于引入类操作是在File中进行的,因此在Class类上是没有办法导入的,如果已经获取到了javaFile对象,那么可以这样导入,否则需要先获取到Class所在的File后再进行导入:

javaFile.importClass(aClass);

根据文件名查找路径

FilenameIndex.getFilesByName()

根据class获取所在文件:

(PsiJavaFile) aClass.getContainingFile()

获取类所在包:

String daoPackage = ((PsiJavaFile) aClass.getContainingFile()).getPackageName();

创建文件(包含文件中的类):

javaFile = (PsiJavaFile) PsiFileFactory.getInstance(project).createFileFromText(“Test.java”, JavaFileType.INSTANCE, “public class Test {}”);

使用模板创建文件
getJavaDirectoryService().createClass(mkdirs, "", "GameConstEnum", false, Collections.emptyMap());

获取当前文件所在包:

PsiDirectory containerDirectory = javaFile.getContainingDirectory();

创建子包(子目录):

parentDirectory.createSubdirectory(“test”);

将文件添加到包中去

psiDirectory.add(javaFile);

查找类:

PsiShortNamesCache shortNamesCache = PsiShortNamesCache.getInstance(project);
PsiClass[] classes = shortNamesCache.getClassesByName(“Test”, GlobalSearchScope.allScope(project));



版权声明:本文为huanghailiang_ws原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。