IDEA插件编写三(AnAction)

1.什么是AnAction

AnAction是IDEA插件里界面里菜单对应的点击事件

2.创建AnActionEvent项目

2.1 pom文件

 定义菜单的归属位置,将在主菜单的Tools里增加测试菜单选项和弹出菜单的Refactoring中增加测试菜单

<idea-plugin>
  <id>com.wangxb.plugin.MyPlugin</id>
  <name>我的插件</name>
  <version>1.0</version>
  <vendor email="wang5525369@sina.com" url="http://www.wangxb.com">wangxb</vendor>

  <description>我的插件我的插件我的插件我的插件我的插件我的插件我的插件说明主要是增加属性的说明</description>

  <change-notes>我的插件我的插件我的插件我的插件我的插件我的插件我的插件说明主要是增加属性的说明</change-notes>

  <!-- please see https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
  <idea-version since-build="193.0"/>

  <!-- please see https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
       on how to target different products -->
  <depends>com.intellij.modules.java</depends>

  <extensions defaultExtensionNs="com.intellij">
    
  </extensions>

  <actions>
    <group id="TestMenu" text="测试菜单" popup="true">
      <add-to-group group-id="ToolsMenu" anchor="last"  />
      <add-to-group group-id="RefactoringMenu" anchor="last"/>
      <action id="defaultAddField" text="我的测试" class="com.wangxb.plugin.MyAnAction"/>
    </group>
  </actions>


</idea-plugin>

2.2 代码文件

代码继承AnAction,update函数中控制菜单是否展现,actionPerformed函数中控制点击后的处理

点击后将在对应的注解的类中增加属性代码

package com.wangxb.plugin;

import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.wangxb.plugin.utils.MyFieldUtils;
import org.jetbrains.annotations.NotNull;

public class MyAnAction extends AnAction {
    String annotaionName = "com.wangxb.annotation.AddField";

    public MyAnAction() {
    }

    public MyAnAction(String text){
        super(text);
    }

    @Override
    public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
        PsiJavaFile psiJavaFile = (PsiJavaFile)anActionEvent.getData(CommonDataKeys.PSI_FILE);

        MyFieldUtils.addField(psiJavaFile,annotaionName);
    }

    @Override
    public void update(@NotNull AnActionEvent anActionEvent) {
        PsiJavaFile psiJavaFile = (PsiJavaFile)anActionEvent.getData(CommonDataKeys.PSI_FILE);
        boolean haveAnnotation = MyFieldUtils.haveAnnotation(psiJavaFile,annotaionName);
        if (haveAnnotation == true) {
            return;
        }

        Editor editor = anActionEvent.getData(PlatformDataKeys.EDITOR);
        // 设置当前 action 菜单的可见性
        anActionEvent.getPresentation().setVisible(editor == null);

        // 设置当前 action 菜单的可用性,
        // 如果不可用,则 actionPreformed() 方法收不到点击事件
        anActionEvent.getPresentation().setEnabled(editor == null);

        // 同时设置当前 action 菜单的可见性和可用性
        anActionEvent.getPresentation().setEnabledAndVisible(editor == null);
    }
}
package com.wangxb.plugin.utils;

import com.intellij.lang.jvm.annotation.JvmAnnotationAttribute;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.impl.light.LightFieldBuilder;
import com.intellij.psi.impl.light.LightModifierList;
import com.intellij.psi.util.CachedValuesManager;

import java.util.List;

public class MyFieldUtils {
    static public void addField(PsiJavaFile psiJavaFile,String annotaionName){

        PsiClass[] psiClasses = psiJavaFile.getClasses();
        if (null == psiClasses) {
            return;
        }
        for(PsiClass psiClass : psiClasses) {
            PsiAnnotation psiAnnotation = psiClass.getAnnotation(annotaionName);
            if (psiAnnotation == null) {
                continue;
            }
            String fieldName = getAnnotationValue(psiAnnotation,"fieldName");

            if ("".equals(fieldName) == true) {
                break;
            }

            boolean add = haveField(psiClass,fieldName);
            if (add) {
                createField(psiClass,fieldName,true);
            }
            break;

        }
    }

    static public boolean haveAnnotation(PsiJavaFile psiJavaFile,String annotaionName){
        boolean bRet = false;
        PsiClass[] psiClasses = psiJavaFile.getClasses();
        if (null == psiClasses) {
            return bRet;
        }
        for(PsiClass psiClass : psiClasses) {
            PsiAnnotation psiAnnotation = getAnnotation(psiClass,annotaionName);
            if (psiAnnotation != null){
                bRet = true;
                break;
            }
        }
        return bRet;
    }

    static public PsiAnnotation getAnnotation(PsiClass psiClass,String annotaionName){
        PsiAnnotation psiAnnotation = psiClass.getAnnotation(annotaionName);
        return psiAnnotation;
    }

    static public PsiField createField(PsiClass psiClass,String fieldName,boolean write){
        Project project = psiClass.getProject();
        PsiElementFactory psiElementFactory = JavaPsiFacade.getElementFactory(project);
        PsiType stringPsiType = psiElementFactory.createTypeFromText("java.lang.String", null);
        PsiField psiField = psiElementFactory.createField(fieldName, stringPsiType);
        psiField.getModifierList().setModifierProperty(PsiModifier.PUBLIC,true);
        if (write) {
            WriteCommandAction.runWriteCommandAction(project, new Runnable() {
                @Override
                public void run() {
                    psiClass.add(psiField);
                }
            });
        }
        return psiField;
    }

    static public PsiField createCacheField(PsiClass psiClass,String fieldName){
        Project project = psiClass.getProject();
        PsiManager psiManager = psiClass.getContainingFile().getManager();
        PsiElementFactory psiElementFactory = JavaPsiFacade.getElementFactory(project);
        PsiType stringPsiType = psiElementFactory.createTypeFromText("java.lang.String", null);
        LightFieldBuilder lightFieldBuilder = new LightFieldBuilder(psiManager,fieldName, stringPsiType);

        LightModifierList modifierList = (LightModifierList) lightFieldBuilder.getModifierList();
        modifierList.addModifier(PsiModifier.PUBLIC);

        lightFieldBuilder.setContainingClass(psiClass);

        return lightFieldBuilder;
    }

    static public String getAnnotationValue(PsiAnnotation psiAnnotation,String name){
        String value = null;
        List<JvmAnnotationAttribute> jvmAnnotationAttributeList = psiAnnotation.getAttributes();
        for (JvmAnnotationAttribute jvmAnnotationAttribute : jvmAnnotationAttributeList) {
            if ((jvmAnnotationAttribute instanceof PsiNameValuePair) == false) {
                continue;
            }
            PsiNameValuePair psiNameValuePair = (PsiNameValuePair) jvmAnnotationAttribute;
            String attributeName = psiNameValuePair.getAttributeName();

            if (attributeName.equals(name) == false) {
                continue;
            }
            value = psiNameValuePair.getLiteralValue();
            break;
        }
        return value;
    }

    static public boolean haveField(PsiClass psiClass,String fieldName){
        boolean bRet = false;
        PsiField[] psiFields = psiClass.getAllFields();
        PsiField lastPsiField = null;
        for (PsiField psiField : psiFields) {
            if (fieldName.equals(psiField.getName())) {
                bRet = true;
                break;
            }
        }
        return bRet;
    }
}

2.3 代码效果

在指定注解的类文件弹出菜单中展现测试菜单

点击菜单后,代码将自动生成注解指定的属性

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值