IDEA 插件开发

 

 

 

IDEA 插件开发

----------------------------------------------------------------------------------------

 

一、PropertiesComponent.getInstance(project):临时储存数据,适用于application级别和project级别

1
PropertiesComponent.getInstance(project).setValue("kwy", "value");PropertiesComponent.getInstance(project).getValue("key");

  

二、FileDocumentManager.getInstance().saveAllDocuments():保存文档记录

1
FileDocumentManager.getInstance().saveAllDocuments();

  

三、创建底边toolwindow

复制代码
1、继承Executor类
public class MyExecutor extends Executor{}
2、配置extensions
  <extensions defaultExtensionNs="com.intellij">
    <executor implementation="mybatis.log.action.MyExecutor" id="MyExecutor"/>
  </extensions>
Disposer.register(project, executor)

3、创建RunnerLayoutUi
 final RunnerLayoutUi.Factory factory = RunnerLayoutUi.Factory.getInstance(e.getProject());
        final RunnerLayoutUi layoutUi = factory.create("SQL", "SQL", "SQL", e.getProject());
4、创建RunContentDescriptor:
 return new RunContentDescriptor(new RunProfile() {
            @Nullable
            @Override
            public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment executionEnvironment) throws ExecutionException {
                return null;
            }

            @Override
            public String getName() {
                //第一层名称显示
                return "Sql";
            }

            @Nullable
            @Override
            public Icon getIcon() {
                return null;
            }
        }, new DefaultExecutionResult(), layoutUi);
Disposer.register(descriptor, this);
Disposer.register(content, console);

5、展示工具ExecutionManager.getInstance(e.getProject()).getContentManager().showRunContent(executor, descriptor);
复制代码

 

  

四、在toolwindow添加控制台(打印台)

1
2
3
4
5
6
7
8
9
1、    TextConsoleBuilder consoleBuilder = TextConsoleBuilderFactory.getInstance().createBuilder(e.getProject());
        ConsoleView console = consoleBuilder.getConsole();
        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        panel.add(console.getComponent(), BorderLayout.CENTER);
 
2、    final Content content = layoutUi.createContent("ConsoleContent", panel, "executable sql statements", AllIcons.Debugger.Console, panel);
        content.setCloseable(true);
        layoutUi.addContent(content);3、控制台打印文本:console.print("hello", ConsoleViewContentType.USER_INPUT);

  

五、RunnerLayoutUi添加按钮事件

1
2
3
4
5
6
1、创建按钮组
final DefaultActionGroup actionGroup = new DefaultActionGroup();
        actionGroup.add(new anaction()));
 
2、ui添加按钮
layoutUi.getOptions().setLeftToolbar(actionGroup, "RunnerToolbar");

  

六、控制台过滤器:ConsoleFilterProvider,Filter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
1、实现Filter
public class MyFilter implements Filter {
 
    @Nullable
    @Override
    public Result applyFilter(@NotNull String s, int i) {
        System.out.println("sss=>" + s);
        System.out.println("i=" + i);
        return null;
    }
}
 
2、实现ConsoleFilterProvider,配置过滤器
public class MyConsoleFilterProvider implements ConsoleFilterProvider {
 
    @NotNull
    @Override
    public Filter[] getDefaultFilters(@NotNull Project project) {
        MyFilter filter = new MyFilter();
        return new Filter[]{filter};
    }
}
 
3、plugin.xml配置ConsoleFilterProvider
  <extensions defaultExtensionNs="com.intellij">
    <consoleFilterProvider implementation="com.log.provider.MyConsoleFilterProvider"/>
  </extensions>

  

七、创建选项:ListPopup

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
1、 plugin.xml配置事件组
<actions>
    <group id="Test-Group-id" text="Test-Group" >
    </group>
  </actions>
2、创建一个事件AnAction触发选项ListPopup
public class ProPlug extends AnAction {
    @Override
    public void actionPerformed(@NotNull AnActionEvent e) {
// 获取plugin.xml配置的事件组
        DefaultActionGroup group = (DefaultActionGroup) ActionManager.getInstance().getAction("Test-Group-id");
// 清空所有事件
        group.removeAll();
// 添加一个事件AnAction
        group.add(new AnAction("New-Anaction") {
            @Override
            public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
                System.out.println("this is new Anaction.....");
            }
        });
// 获取工程的选项对象ListPoup
        ListPopup myPopup = JBPopupFactory.getInstance().createActionGroupPopup("MyPopup", group, e.getDataContext(),
                JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, false);
// ListPopub的显示位置,showCenteredInCurrentWindow当前窗口中间弹出,showInCenterOf在一个组件中间弹出
        myPopup.showInBestPositionFor(e.getDataContext());
    }
}

  

八、显示提示框 

1
2
3
4
5
6
7
8
9
Editor editor = e.getData(CommonDataKeys.EDITOR);
ApplicationManager.getApplication().invokeLater(() -> {
    JBPopupFactory factory = JBPopupFactory.getInstance();
    factory.createHtmlTextBalloonBuilder("hello", null,
            new JBColor(new Color(186, 238, 186), new Color(73, 117, 73)), null)
            .setFadeoutTime(5000L)
            .createBalloon()
            .show(factory.guessBestPopupLocation(editor), Balloon.Position.above);
});

  

九、复制文本到剪贴板

1
CopyPasteManager.getInstance().setContents(new StringSelection("this is copy content"));

 

十、创建toolWindow工具

复制代码
1、右键新建GUI Form:MyForm继承SimpleToolWindowPanel
2、初始化构造器,添加根面板到MyForm
3、自定义布局form界面
4、客户端获取JPanel
5、创建ToolWindow工具并注册JPanel

public class MyForm extends SimpleToolWindowPanel {
    private JPanel parentPanel;
    private JTabbedPane tabbedPane1;
    private SimpleTree tree1;
    private JTextField textField1;
    private JTextField textField2;
    private JButton button1;
    private JTextArea textArea1;

    public MyForm(Project project) {
        super(true, true);
         // 初始化构造器,添加根面板到MyForm
        add(parentPanel);
    }
}
public void actionPerformed(AnActionEvent e) {
    // 客户端获取JPanel
    // JPanel jPanel = new OtherForm(e.getProject());
        JPanel jPanel = e.getProject().getComponent(MyForm.class);
        ContentFactory factory = ServiceManager.getService(ContentFactory.class);
        Content content = factory.createContent(jPanel, "New Panel", false);
        ToolWindowManager manager = ToolWindowManager.getInstance(e.getProject());
        ToolWindow toolWindow = manager.registerToolWindow("NewTest", false, ToolWindowAnchor.RIGHT);
        ContentManager contentManager = toolWindow.getContentManager();
        contentManager.addContent(content);
        contentManager.setSelectedContent(content, false);
}
复制代码

 

十一、弹出消息框

1
Messages.showMessageDialog("hello", "New-Message", Messages.getInformationIcon());

  

十二、按钮添加事件

JButton.addActionListener((e)->{ Messages.showMessageDialog("hello", "New-Message", Messages.getInformationIcon()); });

  

十二、动态添加menu

1
2
3
4
5
6
7
8
ActionManager actionManager = ActionManager.getInstance();
     DefaultActionGroup codeMenu = (DefaultActionGroup) actionManager.getAction("EditMenu");
     codeMenu.add(new AnAction("New-Action") {
         @Override
         public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
             Messages.showMessageDialog("hello", "New-Message", Messages.getInformationIcon());
         }
     });

  

十三、导航跳转

1
NavigationItem.navigate(true)

  

十四、JTree树配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
1、创建MyNavigationItem实现NavigationItem,保存PsiElement和NavigationItem
public class MyNavigationItem implements NavigationItem {
    private PsiElement psielment;
    private NavigationItem navigationItem;
    private String name;
    public MyNavigationItem(PsiElement psiElement) {
        this.psielment = psiElement;
        if (psiElement instanceof PsiMethod) {
            PsiMethod method = (PsiMethod) psiElement;
            this.name = method.getName();
        }
        if (psiElement instanceof NavigationItem) {
            this.navigationItem = (NavigationItem) psiElement;
        }
 
    }
 
    @Nullable
    @Override
    public String getName() {
        return name;
    }
 
    @Nullable
    @Override
    public ItemPresentation getPresentation() {
        return new MyItemPresentation(name);
    }
 
    @Override
    public void navigate(boolean b) {
        if (null != navigationItem) {
            navigationItem.navigate(b);
        }
    }
 
    @Override
    public boolean canNavigate() {
        return true;
    }
 
    @Override
    public boolean canNavigateToSource() {
        return true;
    }
}
 
 
 
2、创建树节点MyTreeNode继承CachingSimpleNode
    public class MyTreeNode extends CachingSimpleNode {
 
    private SimpleNode parent;
    private MyNavigationItem myNavigationItem;
    private List<MyTreeNode> children = new ArrayList<>();
    private String name;
 
    protected MyTreeNode(String name, SimpleNode parent, PsiElement psiElement) {
        super(parent);
        this.getTemplatePresentation().setIcon(Module);
        this.setIcon(Module);
        this.parent = parent;
        if (null != psiElement) {
            this.myNavigationItem = new MyNavigationItem(psiElement);
        }
        this.name = name;
    }
 
    @Override
    protected SimpleNode[] buildChildren() {
        return children.parallelStream().toArray(SimpleNode[]::new);
    }
 
    public List<MyTreeNode> children() {
        return children;
    }
 
    @Override
    public String getName() {
        return name;
    }
 
// 双击树节点
 
    @Override
    public void handleDoubleClickOrEnter(SimpleTree tree, InputEvent inputEvent) {
        SimpleNode selectedNode = tree.getSelectedNode();
            if (selectedNode instanceof MyTreeNode) {
            MyTreeNode myTreeNode = (MyTreeNode) selectedNode;
                if (null != myTreeNode.myNavigationItem) {
                    myNavigationItem.navigate(true);
                }
            }
        }
    }
 
3、创建MySimpleTreeStrure继承SimpleTreeStructure,重写getRootElement
public class MySimpleTreeStructure extends SimpleTreeStructure {
 
    private MyTreeNode root;
 
    public MySimpleTreeStructure(Project project) {
        root = new MyTreeNode(project.getName(), null, null);
        Module[] modules = ModuleManager.getInstance(project).getModules();
        if (modules != null && modules.length > 0) {
            List<MyTreeNode> children = root.children();
            for (Module module : modules) {
                MyTreeNode moduleNode = new MyTreeNode(module.getName(), root, null);
                List<MyTreeNode> moduleChild = moduleNode.children();
                children.add(moduleNode);
 
                Collection<PsiAnnotation> controller = JavaAnnotationIndex.getInstance().get("Controller", project, GlobalSearchScope.moduleScope(module));
 
                if (null != controller && controller.size() > 0) {
 
                    for (PsiAnnotation psiAnnotation : controller) {
                        PsiClass psiClass = (PsiClass) psiAnnotation.getParent().getParent();
                        PsiMethod[] methods = psiClass.getMethods();
                        if (null != methods && methods.length > 0) {
                            for (PsiMethod method : methods) {
                                moduleChild.add(new MyTreeNode(method.getName(), moduleNode, method));
                            }
                        }
                    }
 
                }
            }
        }
    }
 
    @NotNull
    @Override
    public Object getRootElement() {
        return root;
    }
 
    public SimpleNode getRoot() {
        return root;
    }
}
 
 
 
4、初始化SimpleTreeBuilder
 MySimpleTreeStructure structure = new MySimpleTreeStructure(project);
        SimpleTreeBuilder myTreeBuilder = new SimpleTreeBuilder(tree1, (DefaultTreeModel)tree1.getModel(), structure, null);
        Disposer.register(project, myTreeBuilder);
        myTreeBuilder.initRoot();
        myTreeBuilder.expand(structure.getRoot(), null);

  

十五、搜索框

复制代码
1、新建入口AnAction继承GotoActionBase

public class NewGotoActionBase extends GotoActionBase {

    @Override
    protected void gotoActionPerformed(@NotNull AnActionEvent e) {
        MyChooseByname chooseByname = new MyChooseByname();
        ChooseByNameContributor[] butor = new ChooseByNameContributor[]{chooseByname};
        FilterModel model = new FilterModel(e.getProject(), butor);
        GotoActionCallback callback = new GotoActionCallback() {
            @Override
            public void elementChosen(ChooseByNamePopup chooseByNamePopup, Object o) {
                Messages.showInfoMessage("Hello", "Title");
            }
        };
        showNavigationPopup(e, model, callback);
    }
}



2、创建数据提供者MyChooseByName实现ChooseByNameContributor
public class MyChooseByname implements ChooseByNameContributor {
    List<MyNavigationItem> list = new ArrayList<>();

    public MyChooseByname() {
        for (int i = 0; i < 20; i++) {
            list.add(new MyNavigationItem(i + "", null));
        }
    }

    /**
     * @description: 提供全部选项
     *
     * @author: chenzhiwei
     * @create: 2020/5/16 22:31
     * @return java.lang.String[] 
     */
    @NotNull
    @Override
    public String[] getNames(Project project, boolean b) {
        return list.parallelStream().map(MyNavigationItem::getValue).toArray(String[]::new);
    }

    /**
     * @description: 匹配到符合的项
     *
     * @author: chenzhiwei
     * @create: 2020/5/16 22:31
     * @return com.intellij.navigation.NavigationItem[] 
     */
    @NotNull
    @Override
    public NavigationItem[] getItemsByName(String s, String s1, Project project, boolean b) {
        NavigationItem[] navigationItems = list.parallelStream().filter(
                p -> p.getValue().equals(s)
        )
                .toArray(NavigationItem[]::new);
        System.out.println("array="+ Arrays.toString(navigationItems));
        return navigationItems;
    }
}



3、创建搜索框模型MyFliteringGotoByModel继承FilteringGotoByModel
public class FilterModel extends FilteringGotoByModel {

    protected FilterModel(@NotNull Project project, @NotNull ChooseByNameContributor[] contributors) {
        super(project, contributors);
    }

    /**
     * @description: 命中选项
     *
     * @author: chenzhiwei
     * @create: 2020/5/16 22:32
     * @return java.lang.Object
     */
    @Nullable
    @Override
    protected Object filterValueFor(NavigationItem navigationItem) {
        if (navigationItem instanceof MyNavigationItem) {
            MyNavigationItem myNavigationItem = (MyNavigationItem) navigationItem;
            return myNavigationItem.getValue();
        }
        return null;
    }

    /**
     * @description: 搜索框标题
     *
     * @author: chenzhiwei
     * @create: 2020/5/16 22:32
     * @return java.lang.String
     */
    @Nls(capitalization = Nls.Capitalization.Sentence)
    @Override
    public String getPromptText() {
        return "Enter";
    }

    @NotNull
    @Override
    public String getNotInMessage() {
        return "Not in Message";
    }

    @NotNull
    @Override
    public String getNotFoundMessage() {
        return "Not Found message";
    }

    /**
     * @description: 过滤器是否打开
     *
     * @author: chenzhiwei
     * @create: 2020/5/16 22:33
     * @return java.lang.String
     */
    @Nullable
    @Override
    public String getCheckBoxName() {
        return "New Check";
    }

    @Override
    public boolean loadInitialCheckBoxState() {
        return false;
    }

    @Override
    public void saveInitialCheckBoxState(boolean b) {
    }

    @NotNull
    @Override
    public String[] getSeparators() {
        return new String[]{"/","?"};
    }

    /**
     * @description: 必须重写,返回数据项
     *
     * @author: chenzhiwei
     * @create: 2020/5/16 22:33
     * @return java.lang.String
     */
    @Nullable
    @Override
    public String getFullName(@NotNull Object element) {
        return ((MyNavigationItem)element).getValue();
    }

    @Override
    public boolean willOpenEditor() {
        return true;
    }

}



4、在GotoActionBase中创建回调函数GotoActionCallback
     // 初始化回调函数
        GotoActionCallback callback = new GotoActionCallback() {
            @Override
            public void elementChosen(ChooseByNamePopup chooseByNamePopup, Object o) {
                Messages.showInfoMessage("Hello", "Title");
            }
        };



6、弹出搜索框showNavigationPopup(e,model,callback)

7、添加过滤器,新建过滤器指定类型FilterDemo
public class FilterDemo {
    private String name;
    private String value;

    public FilterDemo(String name, String value) {
        this.name = name;
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}



8、在MyNavigationItem中维护FilterDemo
public class MyNavigationItem implements NavigationItem {
    private PsiElement psielment;
    private NavigationItem navigationItem;
    private String name;
    private FilterDemo demo;

    public MyNavigationItem(String name, PsiElement psiElement) {
        this.psielment = psiElement;
        if (psiElement instanceof PsiMethod) {
            PsiMethod method = (PsiMethod) psiElement;
            this.name = method.getName();
        }
        if (psiElement instanceof NavigationItem) {
            this.navigationItem = (NavigationItem) psiElement;
        }
        this.name = name;
        demo = new FilterDemo(name, name);
    }

    @Nullable
    @Override
    public String getName() {
        return name;
    }

    @Nullable
    @Override
    public ItemPresentation getPresentation() {
        return new MyItemPresentation(name);
    }

    @Override
    public void navigate(boolean b) {
        if (null != navigationItem) {
            navigationItem.navigate(b);
        }
    }

    @Override
    public boolean canNavigate() {
        return true;
    }

    @Override
    public boolean canNavigateToSource() {
        return true;
    }

    public String getValue() {
        return this.name;
    }

    public FilterDemo getDemo() {
        return demo;
    }


9、在MyFilteringGotoByModel添加泛型FilterDemo,如FilteringGotoByModel<FilterDemo>
public class FilterModel extends FilteringGotoByModel<FilterDemo> {

    protected FilterModel(@NotNull Project project, @NotNull ChooseByNameContributor[] contributors) {
        super(project, contributors);
    }

    /**
     * @description: 命中选项
     *
     * @author: chenzhiwei
     * @create: 2020/5/16 22:32
     * @return java.lang.Object
     */
    @Nullable
    @Override
    protected FilterDemo filterValueFor(NavigationItem navigationItem) {
        if (navigationItem instanceof MyNavigationItem) {
            MyNavigationItem myNavigationItem = (MyNavigationItem) navigationItem;
            return myNavigationItem.getDemo();
        }
        return null;
    }

    /**
     * @description: 搜索框标题
     *
     * @author: chenzhiwei
     * @create: 2020/5/16 22:32
     * @return java.lang.String
     */
    @Nls(capitalization = Nls.Capitalization.Sentence)
    @Override
    public String getPromptText() {
        return "Enter";
    }

    @NotNull
    @Override
    public String getNotInMessage() {
        return "Not in Message";
    }

    @NotNull
    @Override
    public String getNotFoundMessage() {
        return "Not Found message";
    }

    /**
     * @description: 过滤器是否打开
     *
     * @author: chenzhiwei
     * @create: 2020/5/16 22:33
     * @return java.lang.String
     */
    @Nullable
    @Override
    public String getCheckBoxName() {
        return "New Check";
    }

    @Override
    public boolean loadInitialCheckBoxState() {
        return false;
    }

    @Override
    public void saveInitialCheckBoxState(boolean b) {
    }

    @NotNull
    @Override
    public String[] getSeparators() {
        return new String[]{"/","?"};
    }

    /**
     * @description: 必须重写,返回数据项
     *
     * @author: chenzhiwei
     * @create: 2020/5/16 22:33
     * @return java.lang.String
     */
    @Nullable
    @Override
    public String getFullName(@NotNull Object element) {
        return ((MyNavigationItem)element).getValue();
    }

    @Override
    public boolean willOpenEditor() {
        return true;
    }

}



10、新建MyChooseByNameFilter过滤器继承ChooseByNameFilter<FilterDemo>
public class MyChooseByNameFilter extends ChooseByNameFilter<FilterDemo> {

    public MyChooseByNameFilter(@NotNull ChooseByNamePopup popup, @NotNull FilteringGotoByModel<FilterDemo> model, @NotNull Project project) {
        super(popup, model, new MyChooseByNameFilterConfiguration(), project);
    }

    @Override
    protected String textForFilterValue(@NotNull FilterDemo filterDemo) {
        return filterDemo.getValue();
    }

    @Nullable
    @Override
    protected Icon iconForFilterValue(@NotNull FilterDemo filterDemo) {
        return null;
    }

    @NotNull
    @Override
    protected Collection<FilterDemo> getAllFilterValues() {

        List<MyNavigationItem> list = MyChooseByname.list;
        List<FilterDemo> collect = list.parallelStream().map(MyNavigationItem::getDemo)
                .collect(Collectors.toList());
        return collect;
    }
}



10、新建MyChooseByNameFilterCondiguration继承ChooseByNameFilterConfiguration<FilterDemo>,并交给plugin.xml维护
public class MyChooseByNameFilterConfiguration extends ChooseByNameFilterConfiguration<FilterDemo> {


    @Override
    protected String nameForElement(FilterDemo filterDemo) {
        return filterDemo.getValue();
    }
}

  <extensions defaultExtensionNs="com.intellij">
    <projectService serviceImplementation="MyChooseByNameFilterConfiguration"/>
  </extensions>

11、在callback中实现createFilter方法,返回实例化的MyChooseByNameFilter对象
public class NewGotoActionBase extends GotoActionBase {

    @Override
    protected void gotoActionPerformed(@NotNull AnActionEvent e) {
        MyChooseByname chooseByname = new MyChooseByname();
        ChooseByNameContributor[] butor = new ChooseByNameContributor[]{chooseByname};
        FilterModel model = new FilterModel(e.getProject(), butor);
        // 初始化回调函数
        GotoActionCallback callback = new GotoActionCallback() {
            @Nullable
            @Override
            protected ChooseByNameFilter createFilter(@NotNull ChooseByNamePopup popup) {
                return new MyChooseByNameFilter(popup, model, e.getProject());
            }

            @Override
            public void elementChosen(ChooseByNamePopup chooseByNamePopup, Object o) {
                Messages.showInfoMessage("Hello", "Title");
            }
        };
        showNavigationPopup(e, model, callback);
    }
}


 12、注意:FilterDemo必须是同一个对象

13、搜索框搜索的时候显示辅助内容,新建MyItemPresentation
public class MyItemPresentation implements ItemPresentation {
    private String name;
    public MyItemPresentation(String name) {
        this.name = name;
    }

    /**
     * @description: 搜索结果最终显示
     *
     * @author: chenzhiwei
     * @create: 2020/5/17 10:16
     * @return java.lang.String 
     */
    @Nullable
    @Override
    public String getPresentableText() {
        return name;
    }

    /**
     * @description: 搜索结果的辅助说明
     *
     * @author: chenzhiwei
     * @create: 2020/5/17 10:16
     * @return java.lang.String 
     */
    @Nullable
    @Override
    public String getLocationString() {
        return "getLocationString";
    }

    /**
     * @description: 搜索结果的图标
     *
     * @author: chenzhiwei
     * @create: 2020/5/17 10:16
     * @return javax.swing.Icon 
     */
    @Nullable
    @Override
    public Icon getIcon(boolean b) {
        return null;
    }
}
复制代码

 

十六、树节点鼠标右键菜单Popup

复制代码
public class NewForm extends SimpleToolWindowPanel {

    private JPanel parentPanel;
    private JTree tree1;

    public NewForm(Project project) {
        super(true, true);
        add(parentPanel);

        MyTreeStructure structure = new MyTreeStructure(project);
        SimpleTreeBuilder builder = new SimpleTreeBuilder(tree1, (DefaultTreeModel) tree1.getModel(), structure, null);
        Disposer.register(project, builder);
        builder.initRoot();
        builder.expand(structure.getRootElement(), null);

        tree1.addMouseListener(new PopupHandler() {
            @Override
            public void invokePopup(Component component, int x, int y) {
                ActionManager manager = ActionManager.getInstance();
                ActionGroup actionGroup = (ActionGroup) manager.getAction("popupMenu");
                JPopupMenu newMyPopup = manager.createActionPopupMenu("NewMyPopup", actionGroup).getComponent();
                newMyPopup.show(component, x, y);
            }
        });
    }
}

plugin.xml配置
  <actions>
    <group id="popupMenu" text="PopupMenus" popup="true">
      <action class="NewPlugin" id="New One" text="New One" icon="AllIcons.Actions.Search"/>
      <action class="NewPlugin" id="New Two" text="New Two" icon="AllIcons.Actions.Refresh"/>
    </group>
  </actions>
复制代码

 

十七、创建toolWindow工具方式二

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
1、创建SimpleToolWindowPanel(JPanel)并布局:如MyForm
public class MyForm extends SimpleToolWindowPanel {
    private JPanel parentPanel;
    private JTabbedPane tabbedPane1;
    private SimpleTree tree1;
    private JTextField textField1;
    private JTextField textField2;
    private JButton button1;
    private JTextArea textArea1;
 
    public MyForm(Project project) {
        super(true, true);
        MySimpleTreeStructure structure = new MySimpleTreeStructure(project);
        SimpleTreeBuilder myTreeBuilder = new SimpleTreeBuilder(tree1, (DefaultTreeModel)tree1.getModel(), structure, null);
        Disposer.register(project, myTreeBuilder);
        myTreeBuilder.initRoot();
        myTreeBuilder.expand(structure.getRoot(), null);
 
 
 
        add(parentPanel);
        button1.addActionListener((e)->{
            ActionManager actionManager = ActionManager.getInstance();
            DefaultActionGroup codeMenu = (DefaultActionGroup) actionManager.getAction("EditMenu");
            codeMenu.add(new AnAction("New-Action") {
                @Override
                public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
                    Messages.showMessageDialog("hello", "New-Message", Messages.getInformationIcon());
                }
            });
        });
    }
}
 
2、创建tool window的工厂:ToolWindowFactory
public class ToolFactory implements ToolWindowFactory {
 
    @Override
    public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
        Content content = toolWindow.getContentManager().getFactory().createContent(project.getComponent(MyForm.class), "New-Panel", false);
        toolWindow.getContentManager().addContent(content);
        toolWindow.setTitle("New Tool");
        toolWindow.setType(ToolWindowType.DOCKED, null);
    }
}
 
3、在配置pugin.xml中配置tool window
 <extensions defaultExtensionNs="com.intellij">
    <toolWindow anchor="bottom" id="NewTool" factoryClass="ToolFactory"/>
  </extensions>
 
4、获取tool window
ToolWindow toolWindow = ToolWindowManager.getInstance(e.getProject()).getToolWindow("NewTool");
        toolWindow.activate(()->{
            System.out.println("show");
        });

  

 十八、JTree配置方式二:待定

 

十九:ToolWindowBar:Panel添加toolBar

复制代码
public class NewForm extends SimpleToolWindowPanel {

    private JPanel parentPanel;
    private JTree tree1;

    public NewForm(Project project) {
        super(true, true);
        add(parentPanel);
        ActionGroup popupMenu = (ActionGroup) ActionManager.getInstance().getAction("popupMenu");
        ActionToolbar newToolBar = ActionManager.getInstance().createActionToolbar("New Tool Bar", popupMenu, false);
        setToolbar(newToolBar.getComponent());

    }
}


plugin.xml配置
  <actions>
    <group id="popupMenu" text="PopupMenus" popup="true">
      <action class="NewPlugin" id="New One" text="New One" icon="AllIcons.Actions.Search"/>
      <action class="NewPlugin" id="New Two" text="New Two" icon="AllIcons.Actions.Refresh"/>
    </group>
  </actions>
复制代码

 

二十:获得当前编辑器

复制代码
new AnAction("AddAction","Nothing", AllIcons.Actions.Back) {
            @Override
            public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
                Editor editor = anActionEvent.getData(CommonDataKeys.EDITOR);
                WriteCommandAction.runWriteCommandAction(anActionEvent.getProject(),()->{
                    // 插入的位置:当前光标的位置
            int position = editor.getCaretModel().getOffset(); editor.getDocument().insertString(position,
"Hello"); }); } });
复制代码


二十一:定位到行列

复制代码
new AnAction("AddAction","Nothing", AllIcons.Actions.Back) {
            @Override
            public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
                Editor editor = anActionEvent.getData(CommonDataKeys.EDITOR);
                // 行数,从0开始
                int line = 11;
                // 列数,从1开始
                int column = 12;
                LogicalPosition position = new LogicalPosition(line, column);
                editor.getCaretModel().moveToLogicalPosition(position);
                editor.getScrollingModel().scrollToCaret(ScrollType.CENTER);
            }
        }
复制代码

 二十二、添加控制台方式二

1
2
3
4
5
6
7
8
9
10
1、创建console组件:   
    ConsoleView console = TextConsoleBuilderFactory.getInstance().createBuilder(project).getConsole();
2、初始化console到SimpleToolWindowPanel面板:
 jpanel.setLayout(new BorderLayout());
        jpanel.add(console.getComponent(), "Center");
3、在控制台打印数据:
        console.print("hello world", ConsoleViewContentType.NORMAL_OUTPUT);
 
注意:console先在panel中初始化,再初l始化toolWindowBar组件
将console放在JPanel中,则需要设置边框laout和位置Center

  

二十三、新建窗口弹窗

复制代码
1、右键新建Frame继承JFrame

2、构造函数添加顶层组件 add(parentPanel)

3、实例化JFrame 

public class NewFrame extends JFrame {
    private JTextField textField1;
    private JTextField textField2;
    private JPanel rootPanel;

    public NewFrame() {
        add(rootPanel);
    }
}

public class MyPlugin extends AnAction {

    @Override
    public void actionPerformed(AnActionEvent e) {
        NewFrame frame = new NewFrame();
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setSize(500, 300);
        frame.setVisible(true);

    }
}
复制代码

 

二十四、新建对话框弹框JDialog

1
2
3
4
5
6
7
8
9
右键新建Dialog并进行布局
@Override
    public void actionPerformed(AnActionEvent e) {
        MyDialog dialog = new MyDialog();
        dialog.pack();
        dialog.setSize(500, 300);
        dialog.setVisible(true);
        System.exit(0);
    }

   

二十五、图标跳转

复制代码
1、新建MyLineMarkerProvider实现LineMarkerProvider重写collectSlowLineMarkers方法

public class MyLineMarkerProvider implements LineMarkerProvider {

    @Nullable
    @Override
    public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement psiElement) {
        return null;
    }

    @Override
    public void collectSlowLineMarkers(@NotNull List<PsiElement> elements, @NotNull Collection<LineMarkerInfo> result) {
        for (PsiElement element : elements) {
            if (element instanceof PsiMethod) {
                NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder
                        // 图标显示
                        .create(AllIcons.Actions.Scratch)
                        .setAlignment(GutterIconRenderer.Alignment.CENTER)
                        // 跳转目标
                        .setTarget(element)
                        .setTooltipTitle("");
                // 跳转源头
                result.add(builder.createLineMarkerInfo(element));
            }
        }
    }
}

plugin.xml配置
<extensions defaultExtensionNs="com.intellij"> <codeInsight.lineMarkerProvider language="JAVA" implementationClass="MyLineMarkerProvider"/> </extensions>
复制代码

 

 二十六、右键new创建文件

复制代码
1、新建事件继承CreateElementActionBase,重写invokeDialog,create

public class MyCreateElementActionBase extends CreateElementActionBase {
    public MyCreateElementActionBase() {
        // 菜单显示名称,描述,图标
        super("MyCreateElementActionBaseShow", "Create new XML File", AllIcons.Actions.Refresh);
    }

    @NotNull
    @Override
    protected PsiElement[] invokeDialog(Project project, PsiDirectory directory) {
        MyInputValidator validator = new MyInputValidator( project, directory);
        Messages.showInputDialog(project, "输入", "New", AllIcons.Actions.Scratch, "", validator);
        return validator.getCreatedElements();
    }

    @NotNull
    @Override
    protected PsiElement[] create(@NotNull String s, PsiDirectory psiDirectory) throws Exception {
        String text = "<idea-plugin>\n" +
                "</idea-plugin>";
        // 创建文件
        PsiFile f = PsiFileFactory.getInstance(psiDirectory.getProject()).createFileFromText(s + ".xml", new MyFileTypeIdentifiableByVirtualFile(), text);
        // 添加到当前文件夹
        psiDirectory.add(f);
        PsiElement lastChild = f.getLastChild();

        return new PsiElement[]{lastChild, f};
    }

    @Nls(capitalization = Nls.Capitalization.Title)
    @Override
    protected String getErrorTitle() {
        return "出现异常";
    }

    @Nls
    @Override
    protected String getActionName(PsiDirectory psiDirectory, String s) {
        return null;
    }

}


2、添加到new菜单NewGroup
<actions>
    <action id="  MyCreateElementActionBase " class="MyCreateElementActionBase" text="MyCreateElementActionBase" description="MyCreateElementActionBase">
      <add-to-group group-id="NewGroup" anchor="last"/>
    </action>
  </actions>


3|设置文件类型:FileTypeIdentifiableByVirtualFile
public class MyFileTypeIdentifiableByVirtualFile implements FileTypeIdentifiableByVirtualFile {
    @Override
    public boolean isMyFileType(@NotNull VirtualFile virtualFile) {
        return false;
    }

    @NotNull
    @Override
    public String getName() {
        return "xml";
    }

    @Nls(capitalization = Nls.Capitalization.Sentence)
    @NotNull
    @Override
    public String getDescription() {
        return "xml";
    }

    @NotNull
    @Override
    public String getDefaultExtension() {
        return "xml";
    }

    @Nullable
    @Override
    public Icon getIcon() {
        return AllIcons.Actions.Scratch;
    }

    @Override
    public boolean isBinary() {
        return false;
    }

    @Override
    public boolean isReadOnly() {
        return false;
    }

    @Nullable
    @Override
    public String getCharset(@NotNull VirtualFile virtualFile, @NotNull byte[] bytes) {
        return null;
    }
}
复制代码

 

二十七:弹出输入框

 String input = Messages.showInputDialog(e.getProject(), "Input", "New", AllIcons.Actions.Scratch, "", null);
        Messages.showInfoMessage(input, "New Title");

 

 二十八,控制台日志着色

复制代码
1、创建MyFilter实现Filter
public class MyFilter implements Filter {
    private static Integer offset = 0;

    @Nullable
    @Override
    public Result applyFilter(@NotNull String s, int i) {
        offset += s.length();
        Result result = null;
        if (s.length() > 5) {
            TextAttributes textAttributes = new TextAttributes();
            textAttributes.setBackgroundColor(JBColor.WHITE);
            textAttributes.setForegroundColor(JBColor.RED);

            TextAttributes textAttributes2 = new TextAttributes();
            textAttributes2.setBackgroundColor(JBColor.YELLOW);
            textAttributes2.setForegroundColor(JBColor.GREEN);

            // 点击日志跳转
            HyperlinkInfo info = new HyperlinkInfo() {
                @Override
                public void navigate(Project project) {
                    navigate(project);
                }
            };
            
            List<ResultItem> list = new ArrayList<>();
            // 前段白底红字
            ResultItem item = new ResultItem(offset - s.length(), offset - 5, info, textAttributes);
            // 最后5个字符黄底绿字
            ResultItem item2 = new ResultItem(offset - 5, offset, info, textAttributes2);
            list.add(item);
            list.add(item2);
            result = new Result(list);
        }

        return result;
    }
}

2、新建MyConsoleFilterProvider实现ConsoleFilterProvider
public class MyConsoleFilterProvider implements ConsoleFilterProvider {

    @NotNull
    @Override
    public Filter[] getDefaultFilters(@NotNull Project project) {
        return new Filter[]{new MyFilter()};
    }
}

3、plugin.xml
  <extensions defaultExtensionNs="com.intellij">
    <consoleFilterProvider implementation="MyConsoleFilterProvider" />
  </extensions>
复制代码

 

二十六:日志折叠

复制代码
1、新建MyConsoleFolding实现接口ConsoleFolding
public class MyConsoleFolding extends ConsoleFolding {

    @Override
    public boolean shouldFoldLine(@NotNull Project project, @NotNull String line) {
        // 如果包含hello字符则折叠
        return line.contains("hello");
    }

    @Nullable
    @Override
    public String getPlaceholderText(@NotNull Project project, @NotNull List<String> lines) {
        return "< line" + lines.size() + ">";
    }
}

2、plugin.xml配置
  <extensions defaultExtensionNs="com.intellij">
    <console.folding implementation="MyConsoleFolding"/>
  </extensions>
复制代码

 

二十七:全局设置页添加面板

复制代码
1、新建MyConfigurable实现接口Configurable
public class MyConfigurable implements Configurable {

    @Nls(capitalization = Nls.Capitalization.Title)
    @Override
    public String getDisplayName() {
        return "设置面板";
    }

    @Nullable
    @Override
    public JComponent createComponent() {
        return new ConfigFrame();
    }

    @Override
    public boolean isModified() {
        return false;
    }

    @Override
    public void apply() throws ConfigurationException {

    }
}

2、plugin.xml配置
  <extensions defaultExtensionNs="com.intellij">
    <applicationConfigurable id="myConfigurable" displayName="新面板" implementation="MyConfigurable"/>
  </extensions>

3、添加panel
public class ConfigFrame extends SimpleToolWindowPanel {
    private JTree tree1;
    private JPanel rootPanel;

    public ConfigFrame() {
        super(true, true);
        add(rootPanel);
    }
}
复制代码

 

 二十八:日志输入过滤器实现接口ConsoleInputFilterProvider

plugin.xml配置consolInputFilterProvider

 

二十九:JEditorPanel组件添加超链接 

复制代码
1、将JEditorPane设置为不可编辑
        editorPane1.setEditable(false);

2、将JEditorPane设置为网页格式
        editorPane1.setContentType("text/html");

3、JEditorPane中添加a标签
        editorPane1.setText("<a href=\"http://www.baidu.com\">百度</a>");

4、添加超链接监听器HyperlinkListener
        editorPane1.addHyperlinkListener(e -> {
            if (Desktop.isDesktopSupported() && e.getEventType() != HyperlinkEvent.EventType.ACTIVATED) {
                try {
                    Desktop.getDesktop().browse(e.getURL().toURI());
                } catch (IOException ioException) {
                    ioException.printStackTrace();
                } catch (URISyntaxException uriSyntaxException) {
                    uriSyntaxException.printStackTrace();
                }
            }
        });
复制代码


三十:插件更新提示

复制代码
public class MyPlugin extends AnAction {

    @Override
    public void actionPerformed(AnActionEvent e) {
        NotificationGroup group = new NotificationGroup("MyNotifyId", NotificationDisplayType.BALLOON, true);
        Notification notification = group.createNotification("MyTitle", "省略...", "内容", NotificationType.INFORMATION);
        NotificationAction actions = new NotificationAction("点击按钮") {
            @Override
            public void actionPerformed(@NotNull AnActionEvent anActionEvent, @NotNull Notification notification) {
                Messages.showInfoMessage("提示内容", "提示标题");
            }
        };
        notification.addAction(actions);
        notification.notify(e.getProject());

    }
复制代码


三十一:配置数据持久化:@State,
PersistentStateComponent
复制代码
1、新建配置类,用来持久化数据StorageConfig
public class StorageConfig {
    private String name;
    private String value;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }
}

2、新建数据持久化state类MyState
@State(name = "MyStorage",storages = {@Storage("my-config.xml")})
public class MyState implements PersistentStateComponent<MyState> {

    private StorageConfig config;

    public static MyState getInstance(){
        return ServiceManager.getService(MyState.class);
    }

    @Nullable
    @Override
    public MyState getState() {
        return this;
    }

    @Override
    public void loadState(@NotNull MyState myState) {
        if (null == myState) {
            return;
        }
        XmlSerializerUtil.copyBean(myState, this);
    }

    public StorageConfig getConfig() {
        if (null == config) {
            config = new StorageConfig();
        }
        return config;
    }

    public void setConfig(StorageConfig config) {
        this.config = config;
    }
}


3、新建面板JFrame:ConfigFrame
public class ConfigFrame extends SimpleToolWindowPanel {
    private JTree tree1;
    private JPanel rootPanel;
    private JTextField textField1;
    private JButton button1;

    public ConfigFrame() {
        super(true, true);
        add(rootPanel);
        button1.addActionListener(e -> apply());
    }

    public void apply() {
        StorageConfig config = MyState.getInstance().getConfig();
        if (null == config) {
            config = new StorageConfig();
        }
        config.setName(textField1.getText());
        config.setValue(textField1.getText() + "-new");
    }
}

4、新建设置面板类MyConfig
public class MyConfig implements SearchableConfigurable {

    private ConfigFrame frame;

    @NotNull
    @Override
    public String getId() {
        return "MyConfig";
    }

    @Nls(capitalization = Nls.Capitalization.Title)
    @Override
    public String getDisplayName() {
        return "设置面板";
    }

    @Nullable
    @Override
    public JComponent createComponent() {
        return frame = new ConfigFrame();
    }

    @Override
    public boolean isModified() {
        return false;
    }

    @Override
    public void apply() throws ConfigurationException {
        frame.apply();
    }
}

5、plugin.xml配置
  <extensions defaultExtensionNs="com.intellij">
    <applicationConfigurable id="MyConfig" displayName="新面板" implementation="MyConfig"/>
    <applicationService serviceImplementation="MyState"/>
  </extensions>

6、获取持久化配置的数据
 StorageConfig config = MyState.getInstance().getConfig();
        Messages.showInfoMessage(config.getName(), config.getValue()+"---");
复制代码

 

三十一:在IDEA主窗口菜单栏添加菜单选项=>MainMenu

添加菜单组到IDEA主窗口菜单栏中:MainMenu
<actions>
    <group id="NewGroupId" text="MyMenu" popup="true">
      <add-to-group group-id="MainMenu" anchor="last"/>
      <action class="MyPlugin" text="MyPlugin" id="MyPluginss"/>
    </group>
  </actions>

 

三十二:新建项目继承NewProjectAction

复制代码
public class MyCreateProjectAction extends NewProjectAction {
    
}

2、配置plugin.xml
 <group id="NewGroupId" text="MyMenu" popup="true">
      <action id="MyCreateProjectActionId" class="MyCreateProjectAction" text="MyCreateProjectAction"/>
      <add-to-group group-id="MainMenu" anchor="last"/>
    </group>
复制代码

 

三十三:XML标签与java函数互相跳转

复制代码
1、XML跳转java,plugin.xml的language="XML"
新建MyRelatedItemLineMarkerProvider 继承RelatedItemLineMarkerProvider实现collectNavigationMarkers
public class MyRelatedItemLineMarkerProvider extends RelatedItemLineMarkerProvider {

    private List<String> list = new ArrayList<>(Arrays.asList("select", "update", "insert", "delete"));

    @Override
    protected void collectNavigationMarkers(@NotNull PsiElement element, @NotNull Collection<? super RelatedItemLineMarkerInfo> result) {
        PsiFile containingFile = element.getContainingFile();
        if (containingFile instanceof XmlFile && element instanceof XmlTag) {
            XmlFile xmlFile = (com.intellij.psi.xml.XmlFile) containingFile;
            XmlTag rootTag = xmlFile.getRootTag();
            Project project = element.getProject();
            if ("mapper".equals(rootTag.getName())) {
                XmlAttribute namespace = rootTag.getAttribute("namespace");
                String substring = namespace.getValue().substring(namespace.getValue().lastIndexOf(".") + 1);
                XmlTag xmlTag = (XmlTag) element;
                if (StringUtils.isNotBlank(xmlTag.getName()) &&list.contains(xmlTag.getName())) {
                    XmlAttribute id = xmlTag.getAttribute("id");
                    if (StringUtils.isNotBlank(id.getValue())) {
                      // 查找文件
                        PsiFile psiFile = FilenameIndex.getFilesByName(project, substring + ".java", GlobalSearchScope.projectScope(project))[0];
                        PsiElement[] children = psiFile.getChildren();
                        List<PsiElement> collect = Stream.of(children).parallel()
                                .filter(p -> p instanceof PsiClass)
                                .collect(Collectors.toList());
                        if (CollectionUtils.isNotEmpty(collect)) {
                            PsiClass psiElement = (PsiClass) collect.get(0);
                            PsiMethod[] methods = psiElement.getMethods();
                            if (null != methods && methods.length > 0) {
                                for (PsiMethod method : methods) {
                                    if (method.getName().equals(id.getValue())) {
                                        NavigationGutterIconBuilder<PsiElement> builder = NavigationGutterIconBuilder
                                                .create(AllIcons.Actions.Back)
                                                .setTarget(method)
                                                .setTooltipTitle("go to method");
                                        result.add(builder.createLineMarkerInfo(element));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }    
    }
}


plugin.xml配置
<extensions defaultExtensionNs="com.intellij">
    <codeInsight.lineMarkerProvider implementationClass="MyRelatedItemLineMarkerProvider" language="XML"/>
  </extensions>

2、java跳转xml,plugin.xml的language="JAVA"
新建MyRelatedItemLineMarkerProvider2继承RelatedItemLineMarkerProvider
public class MyRelatedItemLineMarkerProvider2 extends RelatedItemLineMarkerProvider {

    @Override
    protected void collectNavigationMarkers(@NotNull PsiElement element, @NotNull Collection<? super RelatedItemLineMarkerInfo> result) {

        if (element instanceof PsiMethod) {
            PsiMethod method = (PsiMethod) element;
            String packageName = ((PsiJavaFileImpl) method.getContainingFile()).getPackageName();
            PsiClass PsiClass = (PsiClass) method.getParent();
            String nameSpace = packageName + "." + PsiClass.getName();
            // PsiShortNamesCache.getInstance(element.getProject()).getAllFileNames() 获取所有文件名
            List<String> collect = Stream.of(PsiShortNamesCache.getInstance(element.getProject()).getAllFileNames())
                    .filter(p -> p.contains(".xml"))
                    .collect(Collectors.toList());
            // FilenameIndex.getFilesByName(element.getProject(), p, GlobalSearchScope.projectScope(element.getProject()))获取指定文件名的文件
            List<XmlFile> xmlFileList = collect.parallelStream().flatMap(p ->
                    Stream.of(FilenameIndex.getFilesByName(element.getProject(), p, GlobalSearchScope.projectScope(element.getProject()))))
                    .filter(p -> p instanceof XmlFile)
                    .map(p -> {
                        XmlFile file = (XmlFile) p;
                        return file;
                    })
                    .filter(p -> p.getRootTag().getAttribute("namespace") != null && p.getRootTag().getAttribute("namespace").getValue().equals(nameSpace))
                    .collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(xmlFileList)) {
                for (XmlFile xmlFile : xmlFileList) {
                    XmlTag rootTag = xmlFile.getRootTag();
                    XmlTag[] children = rootTag.getSubTags();
                    if (null != children && children.length > 0) {
                        List<XmlTag> id = Stream.of(children).parallel()
                                .filter(p -> p.getAttribute("id").getValue()!=null &&p.getAttribute("id").getValue().equals(method.getName()))
                                .collect(Collectors.toList());
                        if (CollectionUtils.isNotEmpty(id)) {
                            XmlTag xmlTag = id.get(0);
                            NavigationGutterIconBuilder<PsiElement> builder=NavigationGutterIconBuilder
                                    .create(AllIcons.Actions.Close)
                                    .setTarget(xmlTag)
                                    .setTooltipTitle("go to mapper");
                            result.add(builder.createLineMarkerInfo(element));
                        }
                    }
                }
            }
        }

    }

}

plugin.xml配置
<extensions defaultExtensionNs="com.intellij">
    <codeInsight.lineMarkerProvider implementationClass="MyRelatedItemLineMarkerProvider2" language="JAVA"/>
  </extensions>
复制代码


三十四:新建项目自定义模板,核心类是ModuleBuilder
复制代码
1、新建第一步的面板Frame:StepForm1 继承SimpleToolWindowPanel
public class StepForm1 extends SimpleToolWindowPanel {
    private JPanel panel;
    private JLabel label;

    public StepForm1() {
        super(true, true);
        add(panel);
        label.setText("第一步");
    }
}

2、新建第一步配置步骤,MyModuleWizardStep1继承ModuleWizardStep
public class MyModuleWizardStep1 extends ModuleWizardStep {

    @Override
    public JComponent getComponent() {
        return new StepForm1();
    }

    @Override
    public void updateDataModel() {

    }
}

3、新建第一二步面板:StepForm2继承SimpleToolWindowPanel
public class StepForm2 extends SimpleToolWindowPanel {
    private JPanel panel;
    private JLabel label;

    public StepForm2() {
        super(true, true);
        add(panel);
        label.setText("第二步");
    }
}

4、新建第二步配置步骤:MyModuleWizardStep2继承ModuleWizardStep
public class MyModuleWizardStep2 extends ModuleWizardStep {
    @Override
    public JComponent getComponent() {
        return new StepForm2();
    }

    @Override
    public void updateDataModel() {

    }
}


5、新建最后一步SDK配置步骤:MyModuleWizardStep3继承SdkSettingsStep
public class MyModuleWizardStep3 extends SdkSettingsStep {

    public MyModuleWizardStep3(SettingsStep settingsStep, @NotNull ModuleBuilder moduleBuilder, @NotNull Condition<? super SdkTypeId> sdkTypeIdFilter) {
        super(settingsStep, moduleBuilder, sdkTypeIdFilter);
    }
}

6、初始化新模块属性:MyModuleBuilder继承ModuleBuilder
public class MyModuleBuilder extends ModuleBuilder {

    /**
     * @description: 模块描述
     *
     * @author: chenzhiwei
     * @create: 2020/5/31 11:46
     * @return java.lang.String 
     */
    @Nls(capitalization = Nls.Capitalization.Sentence)
    @Override
    public String getDescription() {
        return "GetDescription";
    }

    /**
     * @description: 模块名称
     *
     * @author: chenzhiwei
     * @create: 2020/5/31 11:47
     * @return java.lang.String 
     */
    @Override
    public String getName() {
        return "newModule";
    }

    /**
     * @description: 模块名称显示
     *
     * @author: chenzhiwei
     * @create: 2020/5/31 11:47
     * @return java.lang.String 
     */
    @Nls(capitalization = Nls.Capitalization.Title)
    @Override
    public String getPresentableName() {
        return "新模块";
    }

    @Override
    public String getParentGroup() {
        return "JAVA";
    }

    @Override
    public String getGroupName() {
        return "GroupName";
    }

    @Nullable
    @Override
    public String getBuilderId() {
        return getClass().getName();
    }

    @Override
    public ModuleWizardStep modifyProjectTypeStep(@NotNull SettingsStep settingsStep) {
        return new EmptyStep();
    }

    @Override
    public ModuleType<?> getModuleType() {
        ModuleType moduleType = new ModuleType("MyModuleIdss") {
            @NotNull
            @Override
            public ModuleBuilder createModuleBuilder() {
                return MyModuleBuilder.this;
            }

            @Nls(capitalization = Nls.Capitalization.Title)
            @NotNull
            @Override
            public String getName() {
                return "NewModuleType";
            }

            @Nls(capitalization = Nls.Capitalization.Sentence)
            @NotNull
            @Override
            public String getDescription() {
                return "ModuleType";
            }

            @NotNull
            @Override
            public Icon getNodeIcon(boolean b) {
                return AllIcons.Actions.Refresh;
            }
        };
        return moduleType;
    }


    /**
     * @description: 配置步骤一
     *
     * @author: chenzhiwei
     * @create: 2020/5/31 11:47
     * @return com.intellij.ide.util.projectWizard.ModuleWizardStep 
     */
    @Nullable
    @Override
    public ModuleWizardStep getCustomOptionsStep(WizardContext context, Disposable parentDisposable) {
        return new MyModuleWizardStep1();
    }

    /**
     * @description: 配置步骤二
     *
     * @author: chenzhiwei
     * @create: 2020/5/31 11:48
     * @return com.intellij.ide.util.projectWizard.ModuleWizardStep[] 
     */
    @Override
    public ModuleWizardStep[] createWizardSteps(@NotNull WizardContext wizardContext, @NotNull ModulesProvider modulesProvider) {
        return new ModuleWizardStep[]{new MyModuleWizardStep2()};
    }

    /**
     * @description: 配置最后步骤
     *
     * @author: chenzhiwei
     * @create: 2020/5/31 11:48
     * @return com.intellij.ide.util.projectWizard.ModuleWizardStep 
     */
    @Nullable
    @Override
    public ModuleWizardStep modifySettingsStep(@NotNull SettingsStep settingsStep) {
        Condition<SdkTypeId> condition = sdkTypeId -> sdkTypeId == JavaSdk.getInstance();

        return  new MyModuleWizardStep3(settingsStep, this, condition);
    }

    /**
     * @description: finish完成回调函数
     *
     * @author: chenzhiwei
     * @create: 2020/5/31 11:48
     * @return void 
     */
    @Override
    public void setupRootModel(@NotNull ModifiableRootModel modifiableRootModel) {
        Messages.showInfoMessage("111", "22");
    }
}


7、plugin.xml配置
 <extensions defaultExtensionNs="com.intellij">
    <moduleBuilder builderClass="MyModuleBuilder" id="moduleIds"/>
  </extensions>
复制代码



WriteCommandAction.wri

String cintent
VirtualFile pomfile=root.findOrCreateChildData(this,pom.xml)
VfsUtil.saveText(pomfile,content)
Document doc=FileDocumentManager.getInstance().getDocument(pomfile)
PsiDocumentManager.getInstance(project).doPostponedOperationAndUnblockDocument(doc)
FileDocumentManager.getinstance().reloadFromDisk(doc)

三十五:代码提示并修复
复制代码
public class MyAbstractBaseJavaLocalInspectionTool2 extends AbstractBaseJavaLocalInspectionTool {

    @NotNull
    @Override
    public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {

        JavaElementVisitor visitor = new JavaElementVisitor() {
            @Override
            public void visitField(PsiField field) {
                super.visitField(field);
                holder.registerProblem(field, "hello world");
            }
        };
        return visitor;
    }

    @NotNull
    @Override
    public SuppressQuickFix[] getBatchSuppressActions(@Nullable PsiElement element) {
        SuppressQuickFix suppressQuickFix = new SuppressQuickFix() {
            @Nls(capitalization = Nls.Capitalization.Sentence)
            @NotNull
            @Override
            public String getFamilyName() {
                return "QuickFix2222";
            }

            @Override
            public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor problemDescriptor) {
                System.out.println("==========");
            }

            @Override
            public boolean isAvailable(@NotNull Project project, @NotNull PsiElement psiElement) {
                return psiElement instanceof PsiField;
            }

            @Override
            public boolean isSuppressAll() {
                return false;
            }
        };
        return new SuppressQuickFix[]{suppressQuickFix};

    }
    
}



<extensions defaultExtensionNs="com.intellij">
    <localInspection  language="JAVA"
                      displayName="Test field error11"
                      groupPath="Java"
                      groupBundle="messages.InspectionsBundle"
                      groupKey="group.names.probable.bugs"
                      enabledByDefault="true"
                      level="ERROR" implementationClass="MyAbstractBaseJavaLocalInspectionTool2"/>
  </extensions>
复制代码

 三十六:添加到右键菜单

<action id="EditorBasics.EditorIllustrationAction"
        class="org.intellij.sdk.editor.EditorIllustrationAction"
        text="Editor Replace Text"
        description="Replaces selected text with 'Replacement'."
        icon="SdkIcons.Sdk_default_icon">
  <add-to-group group-id="EditorPopupMenu" anchor="first"/>
</action>

 

三十七:是否显示action

复制代码
public class EditorIllustrationAction extends AnAction {
  @Override
  public void update(@NotNull final AnActionEvent e) {
    // Get required data keys
    final Project project = e.getProject();
    final Editor editor = e.getData(CommonDataKeys.EDITOR);
    
    // Set visibility only in case of existing project and editor and if a selection exists
    e.getPresentation().setEnabledAndVisible( project != null 
                                              && editor != null 
                                              && editor.getSelectionModel().hasSelection() );
  }
}
复制代码

 

三十七:代码元素前添加图标操作RunLineMarkerContributor

复制代码
public class MyRunLineMarkerContributor extends RunLineMarkerContributor {
    @Nullable
    @Override
    public Info getInfo(@NotNull PsiElement psiElement) {

        if (psiElement instanceof PsiMethod) {

            AnAction[] array = new AnAction[3];
            array[0] = new AnAction("11111") {
                @Override
                public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
                    Messages.showInfoMessage("1", "1");
                }
            };
            array[1] = new AnAction("22222") {
                @Override
                public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
                    Messages.showInfoMessage("2", "2");
                }
            };
            array[2] = new AnAction("333333") {
                @Override
                public void actionPerformed(@NotNull AnActionEvent anActionEvent) {
                    Messages.showInfoMessage("3", "3");
                }
            };
            return new Info(AllIcons.RunConfigurations.TestState.Run, array, psiElement1 -> "hello");
        }
        return null;
    }
}

      <runLineMarkerContributor language="JAVA" 

plugin.xml配置
implementationClass="MyRunLineMarkerContributor"/>
复制代码

 

 

三十八:自定义文件语言:Language

复制代码
public class PfcLanguage extends Language {
public static final PfcLanguage INSTANCE = new PfcLanguage();
protected PfcLanguage() {
super("pfc");
}
}

public class PfcFile extends PsiFileBase {

public PfcFile(@NotNull FileViewProvider viewProvider) {
super(viewProvider, PfcLanguage.INSTANCE);
}

@NotNull
@Override
public FileType getFileType() {
return PfcLanguageFileType.INSTANCE;
}

@Override
public String toString() {
return "Pfc File";
}
}

public class PfcLanguageFileType extends LanguageFileType {
public static final PfcLanguageFileType INSTANCE = new PfcLanguageFileType();

protected PfcLanguageFileType() {
super(PfcLanguage.INSTANCE);
}

@NotNull
@Override
public String getName() {
return "Pfc file";
}

@NotNull
@Override
public String getDescription() {
return "pfc language file";
}

@NotNull
@Override
public String getDefaultExtension() {
return "pfc";
}

@Nullable
@Override
public Icon getIcon() {
// return PinganIcons.API_FILE;
return AllIcons.Actions.Back;
}
}




public class PfcFileTypeFactory extends FileTypeFactory {

@Override
public void createFileTypes(@NotNull FileTypeConsumer fileTypeConsumer) {
fileTypeConsumer.consume(PfcLanguageFileType.INSTANCE);
}
}



public class PfcParserDefinition implements ParserDefinition {

private static final IFileElementType PLANTUML_FILE_ELEMENT_TYPE = new IFileElementType(PfcLanguage.INSTANCE) {
@Override
public ASTNode parseContents(ASTNode chameleon) {
final CharSequence chars = chameleon.getChars();
return ASTFactory.leaf(PlainTextTokenTypes.PLAIN_TEXT, chars);
}
};

@NotNull
@Override
public Lexer createLexer(Project project) {
return new EmptyLexer();
}

@NotNull
@Override
public TokenSet getWhitespaceTokens() {
return TokenSet.EMPTY;
}

@NotNull
@Override
public TokenSet getCommentTokens() {
return TokenSet.EMPTY;
}

@NotNull
@Override
public TokenSet getStringLiteralElements() {
return TokenSet.EMPTY;
}

@NotNull
@Override
public PsiParser createParser(final Project project) {
throw new UnsupportedOperationException("Not supported1111");
}

@Override
public IFileElementType getFileNodeType() {
return PLANTUML_FILE_ELEMENT_TYPE;
}

@Override
public PsiFile createFile(FileViewProvider viewProvider) {
return new PfcFile(viewProvider);
}

@Override
public SpaceRequirements spaceExistenceTypeBetweenTokens(ASTNode left, ASTNode right) {
return SpaceRequirements.MAY;
}

@NotNull
@Override
public PsiElement createElement(ASTNode node) {
return PsiUtilCore.NULL_PSI_ELEMENT;
}
}

<fileTypeFactory implementation="com.pingan.core.language.pfc.PfcFileTypeFactory"/>
<lang.parserDefinition language="pfc" implementationClass="com.pingan.core.language.pfc.PfcParserDefinition"/>
复制代码

 

三十九:自定义文件类型并添加图标执行

四十:添加到主界面的按钮:
<add-to-group group-id="NavBarToolBar"/>

四十一:plugin.xml引用外部xml配置
1
<depends optional="true" config-file="plugin_xxx.xml">com.intellij.xxxx</depends>
 

四十二:ctrl+鼠标左键
1
2
3
4
5
XmlTagGotoDeclarationHandler implements GotoDeclarationHandler
 
 
 
    <gotoDeclarationHandler implementation="com.pingan.contributor.XmlTagGotoDeclarationHandler"/>

  

四十二:关键字补全:CompletionContributor

1
2
<completion.contributor language="PUML"
                                implementationClass="org.plantuml.idea.lang.PlantUmlCompletionContributor"/><br><br>public class PfcCompletionContributor extends CompletionContributor implements DumbAware {<br>    private static final Logger LOG = Logger.getInstance(PfcCompletionContributor.class);<br><br>    public PfcCompletionContributor() {<br>        extend(CompletionType.BASIC, PlatformPatterns.psiElement(), new PfcCompletionProvider(PfcLanguageDescriptor.INSTANCE.keywords));<br>        extend(CompletionType.BASIC, PlatformPatterns.psiElement(), new PfcCompletionProvider(PfcLanguageDescriptor.INSTANCE.types));<br>        extend(CompletionType.BASIC, PlatformPatterns.psiElement(), new PfcCompletionProvider(PfcLanguageDescriptor.INSTANCE.keywordsWithoutHighlight));<br>    }<br><br>    public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {<br>        int offset = parameters.getOffset();<br>        Document document = parameters.getEditor().getDocument();<br>        int lineStartOffset = document.getLineStartOffset(document.getLineNumber(offset));<br>        String text = document.getText(TextRange.create(lineStartOffset, offset));<br>        Iterator iterator;<br>        String value;<br>        if (text.matches("\\s*!\\w*$")) {<br>            iterator = PfcLanguageDescriptor.INSTANCE.preproc.iterator();<br>            while (iterator.hasNext()) {<br>                value = (String) iterator.next();<br>                result.addElement(LookupElementBuilder.create(value.substring(1)).withPresentableText(value).withCaseSensitivity(true).bold());<br>            }<br>        } else if (text.matches("\\s*@\\w*$")) {<br>            iterator = PfcLanguageDescriptor.INSTANCE.tags.iterator();<br><br>            while (iterator.hasNext()) {<br>                value = (String) iterator.next();<br>                result.addElement(LookupElementBuilder.create(value.substring(1)).withPresentableText(value).withCaseSensitivity(true).bold());<br>            }<br>        } else {<br>            if (text.endsWith("!")) {<br>                return;<br>            }<br><br>            super.fillCompletionVariants(parameters, result);<br>//            if (PlantUmlSettings.getInstance().isAutoComplete()) {<br>//                WordCompletionContributor.addWordCompletionVariants(result, parameters, Collections.emptySet());<br>//            }<br>            WordCompletionContributor.addWordCompletionVariants(result, parameters, Collections.emptySet());<br>        }<br>    }<br><br>}<br><br><br>public class PfcCompletionProvider extends CompletionProvider<CompletionParameters> {<br><br>    private final List<String> myItems;<br><br>    PfcCompletionProvider(List<String> items) {<br>        myItems = items;<br>    }<br>    @Override<br>    protected void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext processingContext, @NotNull CompletionResultSet result) {<br>        if (parameters.getInvocationCount() == 0) {<br>            return;<br>        }<br>        for (String item : myItems) {<br>            result.addElement(LookupElementBuilder.create(item).withCaseSensitivity(true).withItemTextItalic(true));<br>        }<br>    }<br>}<br><br><br>public enum PfcLanguageDescriptor {<br>    INSTANCE;<br><br>    public static final String IDEA_PARTIAL_RENDER = "idea.partialRender";<br>    public static final String IDEA_DISABLE_SYNTAX_CHECK = "idea.disableSyntaxCheck";<br><br>    public static final String TAGS = "uml|dot|jcckit|ditaa|salt|math|latex|mindmap|gantt|wbs";<br>    <br>    public final List<String> types = Collections.unmodifiableList(Arrays.asList(<br>            "actor",<br>            "participant",<br>            "usecase",<br>            "class",<br>            "interface",<br>            "abstract",<br>            "enum",<br>            "component",<br>            "state",<br>            "object",<br>            "artifact",<br>            "folder",<br>            "rectangle",<br>            "node",<br>            "frame",<br>            "cloud",<br>            "database",<br>            "storage",<br>            "agent",<br>            "stack",<br>            "boundary",<br>            "control",<br>            "entity",<br>            "card",<br>            "file",<br>            "package",<br>            "queue",<br>            "archimate",<br>            "diamond"<br><br>    ));<br>    public final List<String> tags = Collections.unmodifiableList(Arrays.asList(<br>            "@startuml",<br>            "@startdot",<br>            "@startjcckit",<br>            "@startditaa",<br>            "@startsalt",<br>            "@startmath",<br>            "@startlatex",<br>            "@startmindmap",<br>            "@startgantt",<br>            "@startwbs",<br>            "@enduml",<br>            "@enddot",<br>            "@endjcckit",<br>            "@endditaa",<br>            "@endsalt",<br>            "@endmath",<br>            "@endlatex",<br>            "@endmindmap",<br>            "@endgantt",<br>            "@endwbs"<br><br>    ));<br><br>    public final List<String> keywordsWithoutHighlight = Collections.unmodifiableList(Arrays.asList(<br>            "as",<br>            "also",<br>            "of",<br>            "on",<br>            "is"<br>    ));<br>    <br>    public final List<String> keywords = Collections.unmodifiableList(Arrays.asList(<br>            "autonumber",<br>            "caption",<br>            "title",<br>            "newpage",<br>            "box",<br>            "alt",<br>            "else",<br>            "opt",<br>            "loop",<br>            "par",<br>            "break",<br>            "critical",<br>            "note",<br>            "rnote",<br>            "hnote",<br>            "legend",<br>            "group",<br>            "left",<br>            "right",<br>            "link",<br>            "over",<br>            "end",<br>            "activate",<br>            "deactivate",<br>            "destroy",<br>            "create",<br>            "footbox",<br>            "hide",<br>            "show",<br>            "skinparam",<br>            "skin",<br>            "top",<br>            "bottom",<br>            "top to bottom direction",<br>            "package",<br>            "namespace",<br>            "page",<br>            "up",<br>            "down",<br>            "if",<br>            "else",<br>            "elseif",<br>            "endif",<br>            "partition",<br>            "footer",<br>            "header",<br>            "center",<br>            "rotate",<br>            "ref",<br>            "return",<br>            "repeat",<br>            "start",<br>            "stop",<br>            "while",<br>            "endwhile",<br>            "fork",<br>            "again",<br>            "kill",<br>            "order",<br>            "allow_mixing",<br>            "allowmixing",<br>            "mainframe"<br>    ));<br><br>    public final List<String> pluginSettingsPattern = Collections.unmodifiableList(Arrays.asList(<br>            IDEA_PARTIAL_RENDER,<br>            IDEA_DISABLE_SYNTAX_CHECK<br>    ));<br><br><br><br>    public final List<String> preproc = Collections.unmodifiableList(Arrays.asList(<br>            "!exit",<br>            "!include",<br>            "!pragma",<br>            "!define",<br>            "!undef",<br>            "!if",<br>            "!ifdef",<br>            "!endif",<br>            "!ifndef",<br>            "!else",<br>            "!definelong",<br>            "!enddefinelong"<br>    ));<br><br><br><br>}

  

四十三:选择文件夹

1
2
3
4
FileSaverDescriptor fsd = new FileSaverDescriptor("Save diagram", "Please choose where to save diagram");
        VirtualFile baseDir = ProjectUtil.guessProjectDir(anActionEvent.getProject());
        final VirtualFileWrapper wrapper = FileChooserFactory.getInstance().createSaveFileDialog(fsd, anActionEvent.getProject()).save(baseDir, "defaultFileName");
        

  

四十四:监听文件修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
1、实现DocumentListener接口
 
public class PfcDocumentListener implements DocumentListener {
 
    @Override
    public void documentChanged(@NotNull DocumentEvent event) {
        FileDocumentManager instance = FileDocumentManager.getInstance();
        VirtualFile file = instance.getFile(event.getDocument());
        EditorFactory editorFactory = EditorFactory.getInstance();
        Editor[] editors = editorFactory.getEditors(event.getDocument());
        System.out.println("=========");
    }
}
 
 
2、注册监听器
EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster();
        eventMulticaster.addDocumentListener(plantUmlDocumentListener);
移除监听器
  EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster();
        eventMulticaster.removeDocumentListener(plantUmlDocumentListener);
 
示例:
public class PlantUmlApplicationComponent implements ApplicationComponent {
    private DocumentListener plantUmlDocumentListener = new PfcDocumentListener();
 
    public PlantUmlApplicationComponent() {
        PlantUmlApplicationComponent.class.getClassLoader().setDefaultAssertionStatus(false);
    }
 
    @Override
    public void initComponent() {
        EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster();
        eventMulticaster.addDocumentListener(plantUmlDocumentListener);
    }
 
    @Override
    public void disposeComponent() {
        EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster();
        eventMulticaster.removeDocumentListener(plantUmlDocumentListener);
    }
 
    @Override
    @NotNull
    public String getComponentName() {
        return "PlantUmlApplicationComponent";
    }
 
}
 
  <application-components>
    <!-- Add your application components here -->
    <component>
      <implementation-class>com.pingan.core.PlantUmlApplicationComponent</implementation-class>
    </component>
  </application-components>

  

四十五:监听字符变化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
1、实现CaretListener接口
public class PfcCaretListener implements CaretListener {
 
    @Override
    public void caretPositionChanged(@NotNull CaretEvent event) {
        System.out.println("========");
    }
 
    @Override
    public void caretAdded(@NotNull CaretEvent event) {
        System.out.println("=========");
    }
}
 
2、注册监听
public class PlantUmlApplicationComponent implements ApplicationComponent {
    private DocumentListener plantUmlDocumentListener = new PfcDocumentListener();
    private CaretListener pfcCaretListener = new PfcCaretListener();
 
    public PlantUmlApplicationComponent() {
        PlantUmlApplicationComponent.class.getClassLoader().setDefaultAssertionStatus(false);
    }
 
    @Override
    public void initComponent() {
        EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster();
        eventMulticaster.addDocumentListener(plantUmlDocumentListener);
        eventMulticaster.addCaretListener(pfcCaretListener);
    }
 
    @Override
    public void disposeComponent() {
        EditorEventMulticaster eventMulticaster = EditorFactory.getInstance().getEventMulticaster();
        eventMulticaster.removeDocumentListener(plantUmlDocumentListener);
        eventMulticaster.removeCaretListener(pfcCaretListener);
    }
 
    @Override
    @NotNull
    public String getComponentName() {
        return "PlantUmlApplicationComponent";
    }
 
}
 
    <application-components>
      <!-- Add your application components here -->
      <component>
        <implementation-class>com.pingan.core.PlantUmlApplicationComponent</implementation-class>
      </component>
    </application-components>

  

四十六:添加鼠标事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1、鼠标右键事件
        panel.addMouseListener(new PopupHandler() {
            @Override
            public void invokePopup(Component component, int x, int y) {
                ActionManager.getInstance().createActionPopupMenu("hello", new ActionGroup() {
                    @NotNull
                    @Override
                    public AnAction[] getChildren(@Nullable AnActionEvent anActionEvent) {
                        return new AnAction[]{new DownloadImageAction()};
                    }
                }).getComponent().show(component, x, y);
            }
        });
 
2、鼠标滚轮事件
addMouseWheelListenerimagePanel.addMouseWheelListener((wheelEvent) -> {<br>    System.out.println(wheelEvent.getWheelRotation());<br>});

  

四十七:如果运行是报ClassNOtFoundException,考虑添加以下内容
1
2
3
4
<depends>com.intellij.modules.java</depends>
<depends>com.intellij.properties</depends>
<depends>org.jetbrains.plugins.yaml</depends>
<depends>org.jetbrains.kotlin</depends>

  

四十八:Tree使用SimpleTree

1
2
3
4
5
6
7
8
9
JTree tree = new SimpleTree();
DefaultTreeModel   model = (DefaultTreeModel) tree.getModel();
        DefaultTreeCellRenderer cellRenderer = (DefaultTreeCellRenderer) tree.getCellRenderer();
        cellRenderer.setLeafIcon(PinganIcons.TOOL_WINDOW);
        cellRenderer.setClosedIcon(PinganIcons.TOOL_WINDOW);
        cellRenderer.setOpenIcon(PinganIcons.TOOL_WINDOW);
        JBScrollPane scrollPane = new JBScrollPane(tree);
DefaultMutableTreeNode rootTreeNode = new DefaultMutableTreeNode(rootNode);
        model.setRoot(rootTreeNode);<br>// 设置图标tree.setCellRenderer(new ColoredTreeCellRenderer() {<br>    @Override<br>    public void customizeCellRenderer(@NotNull JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {<br>        if (tree instanceof SimpleTree) {<br>            setIcon(PinganIcons.TOOL_WINDOW);<br>            append(String.valueOf(value));<br>        }<br>    }<br>});

  

四十九:修改过的文件
ChangeListManager changeListManager = ChangeListManager.getInstance(project);

五十:plugin.xml添加图标方式:使用相对路劲引入

五十一:多个窗口共用一个window时,不能将组件进行单例化,否则多个项目面板会错乱



posted @   antlord  阅读(5944)  评论(2编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
点击右上角即可分享
微信分享提示