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 代码效果
在指定注解的类文件弹出菜单中展现测试菜单
点击菜单后,代码将自动生成注解指定的属性