• IDEA-插件开发踩坑记录-第三坑-自定义事件



    前言

    做IDEA插件,发现一个数据变动好几处需要配合改动。感觉好麻烦,总不能每次改动都在修改数据的地方加上处理吧。想起来有个监听器模式,想必IDEA肯定也是有相应机制的。官网手册➹


    一、IDEA的消息传递简介

    事件组成元素:

    1. TOPIC:消息主题
    2. Listener:消息监听器
      IDEA消息主要组成部分
      消息广播:ProjectBus是ApplicationBus的子集,每个topic都可以有多个监听器;
    3. 消息通过ApplicationBus发送到topic1;
    4. Handler1收到消息通知;
    5. 消息传递给ProjectBus中topic1的订阅者(handler2和handler3);
      在这里插入图片描述

    二、发布消息与处理消息

    1. 创建Listener
    public interface DateRefreshListener {
        void refresh(String date,Project fireProject);
    }
    
    • 1
    • 2
    • 3
    1. 创建Publisher及其Topic
    public class DateRefreshMessagePublisher {
    
        public static final Topic<DateRefreshListener> TOPIC = new Topic<>("date refresh events", DateRefreshListener.class);
    
        public static DateRefreshMessagePublisher getInstance(Project project) {
            return (DateRefreshMessagePublisher) project.getPicoContainer().getComponentInstanceOfType(DateRefreshMessagePublisher.class);
        }
    
        /**
         * 推送刷新事件
         */
        public void fireDateRefreshExecute(String date, Project project) {
            getPublisher(project).refresh(date, project);
        }
    
        @NotNull
        private static DateRefreshListener getPublisher(Project project) {
            return project.getMessageBus().syncPublisher(TOPIC);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    1. 在Plugin.xml注册Service、Listener
    public class DateRefreshNotifyListener implements DateRefreshListener {
    
        @Override
        public void refresh(String date, Project fireProject) {
            Notification notify = NotifyGroupConstants.NOTIFICATION_GROUP
                    .createNotification("通过plugin.xml定义的-Listener给" + fireProject.getName() + "发通知" + date, NotificationType.INFORMATION);
            notify.notify(fireProject);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
        <extensions defaultExtensionNs="com.intellij">
    
            <projectService serviceImplementation="org.intellij.sdk.service.DateRefreshNotifyListener"/>
            <projectService serviceImplementation="org.intellij.sdk.listener.DateRefreshMessagePublisher"/>
    
            <toolWindow id="Sample Calendar" secondary="true" icon="AllIcons.General.Modified" anchor="right"
                        factoryClass="org.intellij.sdk.toolWindow.MyToolWindowFactory"/>
        extensions>
    
        <projectListeners>
            <listener class="org.intellij.sdk.service.DateRefreshNotifyListener"
                      topic="org.intellij.sdk.listener.DateRefreshListener"/>
        projectListeners>
        <idea-version since-build="193.0"/>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    1. 【演示用】在toolwindow创建时,增加监听方法
    public class MyToolWindowFactory implements ToolWindowFactory {
        AtomicBoolean icon = new AtomicBoolean(true);
    
        @Override
        public void createToolWindowContent(@NotNull Project project, @NotNull ToolWindow toolWindow) {
            MyToolWindow myToolWindow = new MyToolWindow(toolWindow, project);
            ContentFactory contentFactory = ContentFactory.SERVICE.getInstance();
            Content content = contentFactory.createContent(myToolWindow.getContent(), "", false);
            toolWindow.getContentManager().addContent(content);
    
            project.getMessageBus().connect().subscribe(DateRefreshMessagePublisher.TOPIC, (date, fireProject) -> {
                if (icon.get()) {
                    toolWindow.setIcon(AllIcons.Actions.Cancel);
                    icon.set(false);
                } else {
                    toolWindow.setIcon(AllIcons.Actions.Refresh);
                    icon.set(true);
                }
    
                Notification notify = NotifyGroupConstants.NOTIFICATION_GROUP
                        .createNotification("修改toolWindow图标的同时,给" + fireProject.getName() + "发通知" + date, NotificationType.INFORMATION);
                notify.notify(fireProject);
            });
        }
    }
    
    • 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

    效果图

    在这里插入图片描述


    系列文章

    第一坑-创建gradle工程编译失败
    第二坑-Action的Icon死活加不上去

  • 相关阅读:
    【C++ Primer Plus】第11章 使用类
    Java开发自学教程!这里有份超全Java体系化进阶学习图谱
    【深度学习】《动手学深度学习》环境配置
    DTD和XSD的区别
    前端基础知识点
    边写代码边学习之mlflow
    Day06-Python文件和数据格式化
    电视盒子什么品牌好?内行分享权威电视盒子品牌排行榜
    户外景区亲子儿童剧本杀小程序系统开发搭建
    C++知识精讲12——取整方式及实战讲解【全网最详细取整“集合”】
  • 原文地址:https://blog.csdn.net/u013205724/article/details/125878476