官方文档
https://www.jetbrains.org/intellij/sdk/docs/reference_guide/project_model/project.html
Github
https://github.com/kungyutucheng/my_gradle_plugin
运行环境
macOS 10.14.5
IntelliJ idea 2019.2.4
本文主要讲述和intellJ 工程操作的一些相关示例
以下代码省略action注册
1、获取项目下所有模块的Source Root
效果
Demo
package com.kungyu.project;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.stream.Collectors;
/**
* @author wengyongcheng
* @since 2020/3/17 4:07 下午
* 获取工程下所有模块的Source Root
*/
public class GetContentSourceRootAction extends AnAction {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getProject();
VirtualFile[] virtualFiles = ProjectRootManager.getInstance(project).getContentSourceRoots();
String sourceRoot = Arrays.stream(virtualFiles).map(VirtualFile::getUrl).collect(Collectors.joining("\n"));
Messages.showInfoMessage("Source roots for project: " + project.getName() + " are " + sourceRoot,"Project Properties");
}
}
2、ProjectFileIndex
通过该api可以获取到文件所属到模块、是否属于某个项目、模块目录、模块源码目录等
效果
Demo
package com.kungyu.project;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
/**
* @author wengyongcheng
* @since 2020/3/17 5:16 下午
*/
public class ProjectFileIndexAction extends AnAction {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getProject();
Editor editor = e.getData(CommonDataKeys.EDITOR);
if (project == null || editor == null) {
return;
}
Document document = editor.getDocument();
VirtualFile file = FileDocumentManager.getInstance().getFile(document);
if (file == null) {
Messages.showInfoMessage("Unknown File", "Project File Index");
} else {
ProjectFileIndex fileIndex = ProjectFileIndex.getInstance(project);
Messages.showInfoMessage("Module: " + fileIndex.getModuleForFile(file) + "\n" +
"Is In Source: " + fileIndex.isInSource(file) + "\n" +
"Module content root: " + fileIndex.getContentRootForFile(file) + "\n" +
"Source root: " + fileIndex.getSourceRootForFile(file) + "\n" +
"Is library file: " + fileIndex.isLibraryClassFile(file) + "\n" +
"Is in library classes: " + fileIndex.isInLibraryClasses(file) +
", Is in library source: " + fileIndex.isInLibrarySource(file),
"Main File Info for" + file.getName());
}
}
}
3、修改Project Structure
我们以修改Project SDK为例
效果
Demo
package com.kungyu.project;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.ui.Messages;
import org.jetbrains.annotations.NotNull;
/**
* @author wengyongcheng
* @since 2020/3/17 8:00 下午
* 修改项目的SDK
*/
public class ProjectSdkAction extends AnAction {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getProject();
if (project != null) {
Sdk projectSdk = ProjectRootManager.getInstance(project).getProjectSdk();
if (projectSdk != null) {
String origProjectSdkName = projectSdk.getName();
WriteCommandAction.runWriteCommandAction(project,() ->
ProjectRootManager.getInstance(project).setProjectSdkName("newProjectSdkName")
);
Messages.showInfoMessage("origProjectSdkName:" + origProjectSdkName,"Change Project SDK Name Success");
} else {
Messages.showInfoMessage("Unknown Project SDK", "Change Project SDK Name Fail");
}
} else {
Messages.showInfoMessage("Unknown Project", "Change Project SDK Name Fail");
}
}
}
注意:涉及到
Project Structure
的改动都需要在write action
中进行
除此之外,也可以使用ModuleRootModificationUtil
和ProjectRootUtil
来进行修改,具体此处不展开
4、监听Project Structure
package com.kungyu.project;
import com.intellij.ProjectTopics;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ModuleRootEvent;
import com.intellij.openapi.roots.ModuleRootListener;
import org.jetbrains.annotations.NotNull;
/**
* @author wengyongcheng
* @since 2020/3/17 7:46 下午
* 监听Project Structure改变事件
*/
public class ProjectStructureAction extends AnAction {
@Override
public void actionPerformed(@NotNull AnActionEvent e) {
Project project = e.getProject();
if (project == null) {
return;
}
project.getMessageBus().connect().subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
@Override
public void rootsChanged(@NotNull ModuleRootEvent event) {
System.out.println(event.toString());
}
});
}
}
以第三个例子为基础,我们手动修改SDK,切换到原先的1.8版本,控制台输出:
com.intellij.openapi.roots.impl.ModuleRootEventImpl[source=Project '/Users/wengyongcheng/IdeaProjects/untitled' untitled]
该监听事件只能监听一些改变动作,如需要更加详细的内容,需要持有一份Project Structure
的state
模型的副本,在修改发生之后进行对比