在开发Toolkit过程中查阅相关资料和阅读其他开源项目总结的一些常用API. 整体内容来源于网络, 以及自己使用开发Toolkit过程中使用到的. 总结的不到位的地方欢迎指正.

AnAction操作

  1. 创建Action集成AnAction并实现其actionPerformed方法. 在方法中可以获取到AnActionEvent对象. 代码如下:

    1. public class JsonFormatAction extends AnAction {
    2. @Override
    3. public void actionPerformed(AnActionEvent event) {
    4. // 获取当前project对象
    5. Project project = event.getData(PlatformDataKeys.PROJECT);
    6. // 获取当前编辑的文件, 可以进而获取 PsiClass, PsiField 对象
    7. PsiFile psiFile = event.getData(CommonDataKeys.PSI_FILE);
    8. Editor editor = event.getData(CommonDataKeys.EDITOR);
    9. // 获取Java类或者接口
    10. PsiClass psiClass = getTargetClass(editor, psiFile);
    11. // 创建并调起 DialogWrapper
    12. DialogWrapper dialog = new JsonFormat(project, psiFile, editor, psiClass);
    13. dialog.show();
    14. }
  2. 其他方式

    1. // 获取project. 内部调用 getData(CommonDataKeys.PROJECT) = getDataContext().getData(CommonDataKeys.PROJECT)
    2. Project project = e.getProject();
    3. // 获取数据上下文
    4. DataContext dataContext = e.getDataContext();
    5. // context可以也获取到其他信息, 入参为 PlatformDataKeys 定义的字段
    6. Project project1 = dataContext.getData(PlatformDataKeys.PROJECT);
    7. Editor editor = dataContext.getData(PlatformDataKeys.EDITOR);
    8. PsiFile psiFile = dataContext.getData(PlatformDataKeys.PSI_FILE);
    9. PsiElement psiElement = dataContext.getData(PlatformDataKeys.PSI_ELEMENT);
    10. // 虚拟文件
    11. VirtualFile virtualFile = dataContext.getData(PlatformDataKeys.VIRTUAL_FILE);

    获取PsiClass

    PsiClass为java类或者接口

    1. @Nullable
    2. protected PsiClass getTargetClass(Editor editor, PsiFile file) {
    3. int offset = editor.getCaretModel().getOffset();
    4. PsiElement element = file.findElementAt(offset);
    5. if (element == null) {
    6. return null;
    7. } else {
    8. PsiClass target = PsiTreeUtil.getParentOfType(element, PsiClass.class);
    9. return target instanceof SyntheticElement ? null : target;
    10. }
    11. }

    Psixxx操作

    PsiClass操作API

    源码有注释且比较清楚, 此处仅记录我用到的一部分

    1. // 获取全类名
    2. String qualifiedName = aClass.getQualifiedName();
    3. // 获取所有字段
    4. PsiField[] fields = aClass.getFields();

    PsiField操作

    1. // 获取字段名
    2. String name = psiField.getName()

    PsiElement操作

    PsiClass和PsiField都实现了PsiElement

    1. // 删除
    2. element.delete()
    3. // 添加元素, 向一个类中添加方法, 字段等, 也可以调用 addBefore, addAfter
    4. add(PsiElement element)

    PsiType操作

    PsiType支持常用基本类型, 但是当创建对象时则不支持.需要自己创建

    1. PsiElementFactory psiElementFactory = JavaPsiFacade.getElementFactory(project);
    2. // String 类型
    3. PsiType stringPsiType = psiElementFactory.createTypeFromText("java.lang.String", null)
    4. // list
    5. PsiType listPsiType = psiElementFactory.createTypeFromText("java.util.List<String>", null);
    6. // 自定义list
    7. PsiType typeFromText = psiElementFactory.createTypeFromText("java.util.List<" + className + ">", null);

    其他API

    XML 文件操作

    参考地址:https://jetbrains.org/intellij/sdk/docs/reference_guide/frameworks_and_external_apis/xml_dom_api.html
    以 Mapper.xml 举例声明接口,继承 DomElement,并配合 @Attribute、_@_SubTag _@_SubTagsList 注解定义一个 xml model,其中需要注意 _@_SubTagsList 方法要使用复数形式。

    1. public interface Mapper extends DomElement {
    2. /**
    3. * namespace
    4. *
    5. * @return
    6. */
    7. @Attribute("namespace")
    8. GenericAttributeValue<String> getNamespace();
    9. /**
    10. *
    11. * 增删改查对应的节点
    12. *
    13. * @return
    14. */
    15. @SubTagsList({"select", "insert", "update", "delete"})
    16. List<Statement> getStatements();
    17. @SubTagList("select")
    18. List<Select> getSelects();
    19. @SubTagList("insert")
    20. List<Insert> getInserts();
    21. @SubTagList("update")
    22. List<Update> getUpdates();
    23. @SubTagList("delete")
    24. List<Delete> getDeletes();
    25. }

    搜索文件

    比如想搜索项目中的所有 xml 文件,上面使用 Mapper 接口定义了 Mapper.xml 的结构,就可以利用 DomService 搜索所有的 Mapper.xml:

    1. // 当前项目的所有元素 mapper, 分别填入类型, 作用域 GlobalSearchScope
    2. List<DomFileElement<Mapper>> fileElements = DomService.getInstance().getFileElements(Mapper.class, project, GlobalSearchScope.allScope(project));

    写入文件

    需要调用WriteCommandAction进行异步写入.

    1. WriteCommandAction.runWriteCommandAction(project, () -> {
    2. doGenerate(psiClass, jsonObject);
    3. });

    通知

    在操作成功之后,在 IDEA 右下角通知用户,使用 NotificationGroup 类即可。

    1. // 静态属性
    2. private static final NotificationGroup NOTIFICATION_GROUP = new NotificationGroup("Java2Json.NotificationGroup", NotificationDisplayType.BALLOON, true);
    3. public void actionPerformed(@NotNull AnActionEvent e) {
    4. // 在方法中调用
    5. Notification success = NOTIFICATION_GROUP.createNotification(message, NotificationType.INFORMATION);
    6. Notifications.Bus.notify(success, project);
    7. }

    也可以定义为工具类,如下

    1. /**
    2. *
    3. * 进行消息通知工具类
    4. *
    5. * @author liuzhihang
    6. * @date 2020/2/28 18:52
    7. */
    8. public class NotificationUtils {
    9. private static NotificationGroup notificationGroup = new NotificationGroup("ApiDoc.NotificationGroup", NotificationDisplayType.BALLOON, true);
    10. public static void warnNotify(String message, Project project) {
    11. Notifications.Bus.notify(notificationGroup.createNotification(message, NotificationType.WARNING), project);
    12. }
    13. public static void infoNotify(String message, Project project) {
    14. Notifications.Bus.notify(notificationGroup.createNotification(message, NotificationType.INFORMATION), project);
    15. }
    16. public static void errorNotify(String message, Project project) {
    17. Notifications.Bus.notify(notificationGroup.createNotification(message, NotificationType.ERROR), project);
    18. }
    19. }

    总结

    基本上常用的就是这些了,也可以查找官方文档,官方文档现在还是比较全面的,地址在相关资料中。也可以 Clone Toolkit 这个插件源码,源码中有一些注释。在其他优秀的插件中,同样可有相关使用方法。

    相关资料