IntelliJ插件开发:为自定义模块添加Gradle框架支持
实现IntelliJ插件自动创建带Gradle配置的Spigot Kotlin项目
我刚好做过类似的IntelliJ插件开发,给你梳理一下具体的实现步骤和代码示例,帮你快速搞定Gradle支持和自动生成配置文件的需求:
核心思路
要让你的自定义ModuleBuilder支持Gradle,核心是两个点:
- 集成IntelliJ内置的Gradle模块管理API,把新建的模块标记为Gradle项目
- 动态生成符合需求的
build.gradle(以及可选的settings.gradle),同时创建标准的Gradle项目目录结构
具体实现步骤
1. 先配置插件依赖
首先要确保你的插件项目本身依赖了IntelliJ的Gradle和Java模块,否则会找不到相关API:
- 在
plugin.xml里添加依赖声明:
<depends>com.intellij.modules.gradle</depends> <depends>com.intellij.modules.java</depends>
- 在插件的
build.gradle.kts里指定需要的IntelliJ插件:
intellij { version.set("2023.1") // 请匹配你目标的IntelliJ版本 plugins.set(listOf("java", "gradle")) }
2. 完善自定义ModuleBuilder
你之前的SpigotKtWizard需要补充几个关键部分:收集用户输入的Group/Artifact ID、生成Gradle目录和配置文件、绑定Gradle模块、触发同步。
这里是完整的代码示例:
import com.intellij.ide.util.projectWizard.ModuleBuilder import com.intellij.ide.util.projectWizard.ModuleWizardStep import com.intellij.openapi.project.Project import com.intellij.openapi.roots.ModifiableRootModel import com.intellij.openapi.roots.ui.configuration.JavaModuleType import com.intellij.openapi.roots.ui.configuration.projectRoot.JavaSourceRootType import org.jetbrains.plugins.gradle.service.project.GradleModuleManager import org.jetbrains.plugins.gradle.service.project.GradleSyncInvoker import org.jetbrains.plugins.gradle.util.GradleModuleDataImpl import javax.swing.JComponent import javax.swing.JLabel import javax.swing.JPanel import javax.swing.JTextField import javax.swing.event.DocumentEvent import javax.swing.event.DocumentListener import java.io.File import java.awt.GridLayout class SpigotKtWizard : ModuleBuilder() { // 存储用户输入的配置项 private var groupId: String = "" private var artifactId: String = "" private var version: String = "1.0-SNAPSHOT" // 添加自定义的向导步骤,收集Group/Artifact/Version override fun createWizardSteps( wizardContext: com.intellij.ide.wizard.WizardContext, modulesProvider: com.intellij.ide.util.projectWizard.ModulesProvider ): List<ModuleWizardStep> { return listOf(object : ModuleWizardStep() { override fun getComponent(): JComponent { val panel = JPanel(GridLayout(3, 2, 8, 8)).apply { add(JLabel("Group ID:")) val groupField = JTextField().apply { document.addDocumentListener(object : DocumentListener { override fun insertUpdate(e: DocumentEvent) { groupId = text } override fun removeUpdate(e: DocumentEvent) { groupId = text } override fun changedUpdate(e: DocumentEvent) { groupId = text } }) } add(groupField) add(JLabel("Artifact ID:")) val artifactField = JTextField().apply { document.addDocumentListener(object : DocumentListener { override fun insertUpdate(e: DocumentEvent) { artifactId = text } override fun removeUpdate(e: DocumentEvent) { artifactId = text } override fun changedUpdate(e: DocumentEvent) { artifactId = text } }) } add(artifactField) add(JLabel("Version:")) val versionField = JTextField("1.0-SNAPSHOT").apply { document.addDocumentListener(object : DocumentListener { override fun insertUpdate(e: DocumentEvent) { version = text } override fun removeUpdate(e: DocumentEvent) { version = text } override fun changedUpdate(e: DocumentEvent) { version = text } }) } add(versionField) } return panel } override fun updateDataModel() { // 这里可以做输入验证,比如检查Group/Artifact ID是否符合Maven规范 if (groupId.isBlank() || artifactId.isBlank()) { throw IllegalArgumentException("Group ID和Artifact ID不能为空") } } }) } override fun setupRootModel(modifiableRootModel: ModifiableRootModel) { val project = modifiableRootModel.project val moduleRootDir = modifiableRootModel.moduleFile?.parent ?: return // 1. 创建标准Gradle项目目录结构 val srcMainJava = File(moduleRootDir.path, "src/main/java") val srcMainResources = File(moduleRootDir.path, "src/main/resources") srcMainJava.mkdirs() srcMainResources.mkdirs() // 2. 生成自定义的build.gradle文件 val buildGradleContent = """ plugins { id 'java' id 'org.jetbrains.kotlin.jvm' version '1.9.20' id 'com.github.johnrengelman.shadow' version '8.1.1' // 用于打包Spigot插件 } group '$groupId' version '$version' repositories { mavenCentral() maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' } } dependencies { implementation 'org.spigotmc:spigot-api:1.20.4-R0.1-SNAPSHOT' implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.20' compileOnly 'org.jetbrains:annotations:24.0.1' } java { toolchain { languageVersion = JavaLanguageVersion.of(17) } } tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile) { kotlinOptions { jvmTarget = "17" } } shadowJar { archiveBaseName.set('$artifactId') archiveClassifier.set('') relocate 'org.jetbrains.annotations', '$groupId.$artifactId.lib.annotations' } """.trimIndent() File(moduleRootDir.path, "build.gradle").writeText(buildGradleContent) // 生成settings.gradle File(moduleRootDir.path, "settings.gradle").writeText("rootProject.name = '$artifactId'") // 3. 将模块关联为Gradle项目 val gradleModuleManager = GradleModuleManager.getInstance(project) val gradleModuleData = GradleModuleDataImpl().apply { setLinkedExternalProjectPath(moduleRootDir.path) } gradleModuleManager.linkGradleProject( listOf(modifiableRootModel.module), gradleModuleData, moduleRootDir.path ) // 4. 配置模块的源目录和资源目录 val contentEntry = modifiableRootModel.addContentEntry(moduleRootDir.path) contentEntry.addSourceFolder(srcMainJava.path, JavaSourceRootType.SOURCE) contentEntry.addSourceFolder(srcMainResources.path, JavaSourceRootType.RESOURCE) // 5. 触发Gradle同步,让IntelliJ自动加载Gradle配置 GradleSyncInvoker.getInstance().requestProjectSync(project, GradleSyncInvoker.Request()) } // 指定模块类型为Java模块,确保IntelliJ正确识别 override fun getModuleType(): com.intellij.openapi.module.ModuleType<*> = JavaModuleType.getModuleType() }
3. 关键细节说明
- 输入验证:在
updateDataModel方法里可以添加输入合法性检查,避免用户输入空值或不符合规范的内容 - Gradle同步:最后调用
GradleSyncInvoker触发同步,这样用户创建完项目后就能直接看到Gradle工具栏,不需要手动导入 - 动态配置:
build.gradle的内容是根据用户输入的Group/Artifact ID动态生成的,你可以根据自己的需求调整依赖、插件和打包配置 - 目录结构:自动创建
src/main/java和src/main/resources,符合Java项目的标准结构
测试插件
打包并安装插件后,新建项目时选择你的SpigotKtWizard模块,输入Group/Artifact ID,完成后就能得到一个已经配置好Gradle的Spigot Kotlin项目,IntelliJ会自动同步Gradle依赖。
内容的提问来源于stack exchange,提问作者ChrisUMB
相关产品推荐
相关产品推荐

