跳转至

Action:菜单、工具栏与快捷入口

Action 是 IntelliJ Platform 中响应用户操作的基本入口。菜单项、工具栏按钮、上下文菜单、快捷键和 Find Action 中的命令通常都由 Action 实现。

最小 Action

package com.example.myplugin

import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.ui.Messages

class ShowProjectInfoAction : AnAction() {
    override fun getActionUpdateThread(): ActionUpdateThread {
        return ActionUpdateThread.BGT
    }

    override fun update(event: AnActionEvent) {
        event.presentation.isEnabledAndVisible = event.project != null
    }

    override fun actionPerformed(event: AnActionEvent) {
        val project = event.project ?: return
        Messages.showInfoMessage(project, "Current project: ${project.name}", "Project Info")
    }
}

注册到菜单

<actions>
  <action
      id="com.example.myplugin.ShowProjectInfoAction"
      class="com.example.myplugin.ShowProjectInfoAction"
      text="Show Project Info"
      description="Show information about the current project">
    <add-to-group group-id="ToolsMenu" anchor="first"/>
  </action>
</actions>

update()actionPerformed()

update() 控制 Action 是否可见、是否可用、显示文本和图标。它会被频繁调用,必须非常快。

适合在 update() 做:

  • 判断是否有打开的项目。
  • 判断当前编辑器、文件类型、选择区是否满足条件。
  • 修改 Presentation 的可见性、可用性、文本。

不适合在 update() 做:

  • 扫描整个项目。
  • 访问网络或磁盘重操作。
  • 复杂索引查询。
  • 修改 PSI、VFS 或项目模型。

actionPerformed() 是用户真正触发后的执行逻辑。耗时工作应放入后台任务,再回到 EDT 更新 UI。

getActionUpdateThread()

面向 2022.3 及之后平台时,Action 需要声明 update() 运行线程:

  • ActionUpdateThread.BGT:后台线程,适合读取 PSI/VFS/项目数据。
  • ActionUpdateThread.EDT:UI 线程,适合访问 Swing 组件。

默认优先考虑 BGT。如果 update() 必须读取 UI 状态,才使用 EDT

Action 中不要保存项目状态

Action 实例生命周期很长,不要在字段中保存 ProjectEditorPsiElement 等上下文对象,否则容易造成内存泄漏。每次调用都从 AnActionEvent 里取当前上下文。

获取上下文数据

val project = event.project
val editor = event.getData(com.intellij.openapi.actionSystem.CommonDataKeys.EDITOR)
val file = event.getData(com.intellij.openapi.actionSystem.CommonDataKeys.PSI_FILE)

如果某个上下文可选,代码应优雅降级;如果是必需条件,在 update() 中禁用 Action。

参考来源