• IDEA 插件开发


     

    IDEA 插件开发

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

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

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

      

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

    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、    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、创建按钮组
    final DefaultActionGroup actionGroup = new DefaultActionGroup();
            actionGroup.add(new anaction()));
    
    2、ui添加按钮
    layoutUi.getOptions().setLeftToolbar(actionGroup, "RunnerToolbar");
    

      

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

    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、 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());
        }
    }
    

      

    八、显示提示框 

            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);
            });
    

      

    九、复制文本到剪贴板

            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);
    }

    十一、弹出消息框

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

      

    十二、按钮添加事件

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

      

    十二、动态添加menu

           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());
                    }
                });
    

      

    十三、导航跳转

    NavigationItem.navigate(true)
    

      

    十四、JTree树配置

    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、创建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、创建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

    右键新建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配置
     <depends optional="true" config-file="plugin_xxx.xml">com.intellij.xxxx</depends>
     

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

      

    四十二:关键字补全:CompletionContributor

    <completion.contributor language="PUML"
                                    implementationClass="org.plantuml.idea.lang.PlantUmlCompletionContributor"/>

    public class PfcCompletionContributor extends CompletionContributor implements DumbAware {
    private static final Logger LOG = Logger.getInstance(PfcCompletionContributor.class);

    public PfcCompletionContributor() {
    extend(CompletionType.BASIC, PlatformPatterns.psiElement(), new PfcCompletionProvider(PfcLanguageDescriptor.INSTANCE.keywords));
    extend(CompletionType.BASIC, PlatformPatterns.psiElement(), new PfcCompletionProvider(PfcLanguageDescriptor.INSTANCE.types));
    extend(CompletionType.BASIC, PlatformPatterns.psiElement(), new PfcCompletionProvider(PfcLanguageDescriptor.INSTANCE.keywordsWithoutHighlight));
    }

    public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
    int offset = parameters.getOffset();
    Document document = parameters.getEditor().getDocument();
    int lineStartOffset = document.getLineStartOffset(document.getLineNumber(offset));
    String text = document.getText(TextRange.create(lineStartOffset, offset));
    Iterator iterator;
    String value;
    if (text.matches("\\s*!\\w*$")) {
    iterator = PfcLanguageDescriptor.INSTANCE.preproc.iterator();
    while (iterator.hasNext()) {
    value = (String) iterator.next();
    result.addElement(LookupElementBuilder.create(value.substring(1)).withPresentableText(value).withCaseSensitivity(true).bold());
    }
    } else if (text.matches("\\s*@\\w*$")) {
    iterator = PfcLanguageDescriptor.INSTANCE.tags.iterator();

    while (iterator.hasNext()) {
    value = (String) iterator.next();
    result.addElement(LookupElementBuilder.create(value.substring(1)).withPresentableText(value).withCaseSensitivity(true).bold());
    }
    } else {
    if (text.endsWith("!")) {
    return;
    }

    super.fillCompletionVariants(parameters, result);
    // if (PlantUmlSettings.getInstance().isAutoComplete()) {
    // WordCompletionContributor.addWordCompletionVariants(result, parameters, Collections.emptySet());
    // }
    WordCompletionContributor.addWordCompletionVariants(result, parameters, Collections.emptySet());
    }
    }

    }


    public class PfcCompletionProvider extends CompletionProvider<CompletionParameters> {

    private final List<String> myItems;

    PfcCompletionProvider(List<String> items) {
    myItems = items;
    }
    @Override
    protected void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext processingContext, @NotNull CompletionResultSet result) {
    if (parameters.getInvocationCount() == 0) {
    return;
    }
    for (String item : myItems) {
    result.addElement(LookupElementBuilder.create(item).withCaseSensitivity(true).withItemTextItalic(true));
    }
    }
    }


    public enum PfcLanguageDescriptor {
    INSTANCE;

    public static final String IDEA_PARTIAL_RENDER = "idea.partialRender";
    public static final String IDEA_DISABLE_SYNTAX_CHECK = "idea.disableSyntaxCheck";

    public static final String TAGS = "uml|dot|jcckit|ditaa|salt|math|latex|mindmap|gantt|wbs";

    public final List<String> types = Collections.unmodifiableList(Arrays.asList(
    "actor",
    "participant",
    "usecase",
    "class",
    "interface",
    "abstract",
    "enum",
    "component",
    "state",
    "object",
    "artifact",
    "folder",
    "rectangle",
    "node",
    "frame",
    "cloud",
    "database",
    "storage",
    "agent",
    "stack",
    "boundary",
    "control",
    "entity",
    "card",
    "file",
    "package",
    "queue",
    "archimate",
    "diamond"

    ));
    public final List<String> tags = Collections.unmodifiableList(Arrays.asList(
    "@startuml",
    "@startdot",
    "@startjcckit",
    "@startditaa",
    "@startsalt",
    "@startmath",
    "@startlatex",
    "@startmindmap",
    "@startgantt",
    "@startwbs",
    "@enduml",
    "@enddot",
    "@endjcckit",
    "@endditaa",
    "@endsalt",
    "@endmath",
    "@endlatex",
    "@endmindmap",
    "@endgantt",
    "@endwbs"

    ));

    public final List<String> keywordsWithoutHighlight = Collections.unmodifiableList(Arrays.asList(
    "as",
    "also",
    "of",
    "on",
    "is"
    ));

    public final List<String> keywords = Collections.unmodifiableList(Arrays.asList(
    "autonumber",
    "caption",
    "title",
    "newpage",
    "box",
    "alt",
    "else",
    "opt",
    "loop",
    "par",
    "break",
    "critical",
    "note",
    "rnote",
    "hnote",
    "legend",
    "group",
    "left",
    "right",
    "link",
    "over",
    "end",
    "activate",
    "deactivate",
    "destroy",
    "create",
    "footbox",
    "hide",
    "show",
    "skinparam",
    "skin",
    "top",
    "bottom",
    "top to bottom direction",
    "package",
    "namespace",
    "page",
    "up",
    "down",
    "if",
    "else",
    "elseif",
    "endif",
    "partition",
    "footer",
    "header",
    "center",
    "rotate",
    "ref",
    "return",
    "repeat",
    "start",
    "stop",
    "while",
    "endwhile",
    "fork",
    "again",
    "kill",
    "order",
    "allow_mixing",
    "allowmixing",
    "mainframe"
    ));

    public final List<String> pluginSettingsPattern = Collections.unmodifiableList(Arrays.asList(
    IDEA_PARTIAL_RENDER,
    IDEA_DISABLE_SYNTAX_CHECK
    ));



    public final List<String> preproc = Collections.unmodifiableList(Arrays.asList(
    "!exit",
    "!include",
    "!pragma",
    "!define",
    "!undef",
    "!if",
    "!ifdef",
    "!endif",
    "!ifndef",
    "!else",
    "!definelong",
    "!enddefinelong"
    ));



    }
    
    

      

    四十三:选择文件夹

    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、实现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、实现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、鼠标右键事件
            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、鼠标滚轮事件
    addMouseWheelListener
    imagePanel.addMouseWheelListener((wheelEvent) -> {
    System.out.println(wheelEvent.getWheelRotation());
    });

      

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

      

    四十八:Tree使用SimpleTree

    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);
    // 设置图标
    tree.setCellRenderer(new ColoredTreeCellRenderer() {
    @Override
    public void customizeCellRenderer(@NotNull JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
    if (tree instanceof SimpleTree) {
    setIcon(PinganIcons.TOOL_WINDOW);
    append(String.valueOf(value));
    }
    }
    });

      

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

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

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



    有志之士,共同学习
  • 相关阅读:
    网页动画
    浮动
    定位
    盒子模型
    表单
    2017年07月05号课堂笔记
    2017年07月07号课堂笔记
    2017年07月03号课堂笔记
    2017年06月30号课堂笔记
    2017年06月28号课堂笔记
  • 原文地址:https://www.cnblogs.com/antlord/p/12863323.html
Copyright © 2020-2023  润新知