成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

編寫一個IDEA插件之:事件監(jiān)聽

開發(fā) 架構(gòu)
事件監(jiān)聽,我們最熟悉不過的就是開發(fā)APP時,監(jiān)聽按鈕點擊事件、手指觸摸及移動事件、網(wǎng)絡(luò)狀態(tài)事件等等。事件監(jiān)聽大多通過觀察者模式實現(xiàn),首先API調(diào)用者不需要知道后臺是如何檢測出網(wǎng)絡(luò)狀態(tài)不可用的,而只需要向系統(tǒng)注冊一個監(jiān)聽器,當(dāng)網(wǎng)絡(luò)狀態(tài)發(fā)生改變時,由系統(tǒng)回調(diào)給監(jiān)聽器。

[[345643]]

事件監(jiān)聽,我們最熟悉不過的就是開發(fā)APP時,監(jiān)聽按鈕點擊事件、手指觸摸及移動事件、網(wǎng)絡(luò)狀態(tài)事件等等。事件監(jiān)聽大多通過觀察者模式實現(xiàn),首先API調(diào)用者不需要知道后臺是如何檢測出網(wǎng)絡(luò)狀態(tài)不可用的,而只需要向系統(tǒng)注冊一個監(jiān)聽器,當(dāng)網(wǎng)絡(luò)狀態(tài)發(fā)生改變時,由系統(tǒng)回調(diào)給監(jiān)聽器。

本篇內(nèi)容:

  • 項目或模塊事件監(jiān)聽:在模塊或者整個項目發(fā)生改變時,通過事件監(jiān)聽做出反應(yīng),如項目新增了一個模塊或是刪除了某個模塊;
  • 文件編輯事件監(jiān)聽:在Java代碼文件編輯時,通過事件監(jiān)聽能夠知道哪個類的代碼改變了,此時后臺就可以刷新一些數(shù)據(jù)的緩存;

如何監(jiān)聽項目或模塊改變事件

首先是項目級別的事件監(jiān)聽。添加一個項目管理事件監(jiān)聽器,我們需要實現(xiàn)ProjectManagerListener接口,該接口有四個方法,其源碼如下。

  1. public interface ProjectManagerListener extends EventListener { 
  2.   default void projectOpened(@NotNull Project project) { 
  3.   } 
  4.   default void projectClosed(@NotNull Project project) { 
  5.   } 
  6.   default void projectClosing(@NotNull Project project) { 
  7.   } 
  8.   default void projectClosingBeforeSave(@NotNull Project project) { 
  9.   } 
  • projectOpened:該方法在項目打開時被回調(diào);
  • projectClosingBeforeSave:在關(guān)閉項目時,開始保存項目之前被回調(diào),或者說是在調(diào)用FileDocumentManager#saveAllDocuments方法保存所有文件之前被調(diào)用;
  • projectClosing:在projectClosingBeforeSave方法之后被回調(diào);
  • projectClosed:與projectClosing的區(qū)別在于,projectClosed在項目已經(jīng)關(guān)閉時被回調(diào),在ProjectManagerImpl#closeProject方法執(zhí)行到最后一行代碼時被調(diào)用。

有了項目管理事件監(jiān)聽器之后,我們?nèi)绾巫栽摫O(jiān)聽器呢?

有兩種方法,一種是代碼方式注冊,一種是在plugin.xml插件配置文件中注冊。

代碼方式注冊可調(diào)用ProjectManager.getInstance().addProjectManagerListener();方法注冊,但這種方式注冊有一個弊端,就是無法監(jiān)聽到項目打開事件,projectOpened方法不會被調(diào)用,應(yīng)該在我們能夠調(diào)用該方法注冊監(jiān)聽器時,項目實際已經(jīng)打開了。

所以注冊項目管理監(jiān)聽器我們只能通過修改plugin.xml配置文件方式注冊,配置代碼如下:

  1. <applicationListeners> 
  2.     <listener class="com.msyc.ycpay.plugin.listener.MyProjectManagerListener" 
  3.               topic="com.intellij.openapi.project.ProjectManagerListener"/> 
  4. </applicationListeners> 

  • topic:填寫事件主題,類似于消息中間件中的Topic,只不過這里填寫的是事件監(jiān)聽器的接口類名;
  • class:添加接口的實現(xiàn)類名;

當(dāng)我們給IDEA注冊自定義的項目管理事件監(jiān)聽器后,我們就可以通過項目管理事件監(jiān)聽器注冊其它的事件監(jiān)聽器,例如注冊模塊監(jiān)聽事件,這是因為模塊的事件觸發(fā)在項目打開事件觸發(fā)之后才會觸發(fā)。因此,在projectOpened方法中可注冊任何其它的事件監(jiān)聽器。

注冊模塊事件監(jiān)聽器代碼如下:

  1. project.getMessageBus().connect() 
  2. .subscribe(ProjectTopics.MODULES, new ModuleListener(){}); 

subscribe方法需要兩個參數(shù):

  • topic:主題,可選值參見ProjectTopics類的源碼,有PROJECT_ROOTS和MODULES;
  • handler:事件處理器、監(jiān)聽器,當(dāng)topic為MODULES時,要求傳遞一個ModuleListener;

ModuleListener接口的定義如下:

  1. public interface ModuleListener extends EventListener { 
  2.   default void moduleAdded(@NotNull Project project, @NotNull Module module) { 
  3.   } 
  4.   default void beforeModuleRemoved(@NotNull Project project, @NotNull Module module) { 
  5.   } 
  6.   default void moduleRemoved(@NotNull Project project, @NotNull Module module) { 
  7.   } 
  8.   default void modulesRenamed(@NotNull Project project, @NotNull List<Module> modules, @NotNull Function<Module, String> oldNameProvider) { 
  9.   } 
  • moduleAdded:添加模塊完成時被調(diào)用;
  • beforeModuleRemoved:模塊被移除之前被調(diào)用;
  • moduleRemoved:模塊被移除時被調(diào)用;
  • modulesRenamed:模塊修改名字時被調(diào)用;

如何監(jiān)聽文件編輯事件

通過前面兩篇的學(xué)習(xí),我們已經(jīng)了解什么是PSI,知道一個文件對應(yīng)一個PsiFile,一個PsiFile本身也是一個PsiElement,由許多的PsiElement構(gòu)成,每個PsiElement也都可以有子PsiElement。

因此,監(jiān)聽文件改變事件其實就是監(jiān)聽PSI樹的結(jié)構(gòu)改變事件,我們需要通過PsiManager注冊PsiTreeChangeListener,代碼如下。

  1. PsiManager.getInstance(project).addPsiTreeChangeListener( 
  2.                 new PsiTreeChangeListener() { 
  3.                     // ..... 
  4.                 }, FILES::clear); 

至于注冊時機,視情況而定,可以在Service初始化時注冊,可以在AnAction觸發(fā)時注冊,也可以在projectOpened事件方法中注冊。

PsiTreeChangeListener接口定義的方法較多,可以分為兩類事件,一類是before事件、一類是after事件,接口源碼如下。

  1. public interface PsiTreeChangeListener extends EventListener { 
  2.   void beforeChildAddition(@NotNull PsiTreeChangeEvent event); 
  3.   void beforeChildRemoval(@NotNull PsiTreeChangeEvent event); 
  4.   void beforeChildReplacement(@NotNull PsiTreeChangeEvent event); 
  5.   void beforeChildMovement(@NotNull PsiTreeChangeEvent event); 
  6.   void beforeChildrenChange(@NotNull PsiTreeChangeEvent event); 
  7.   void beforePropertyChange(@NotNull PsiTreeChangeEvent event); 
  8.  
  9.   void childAdded(@NotNull PsiTreeChangeEvent event); 
  10.   void childRemoved(@NotNull PsiTreeChangeEvent event); 
  11.   void childReplaced(@NotNull PsiTreeChangeEvent event); 
  12.   void childrenChanged(@NotNull PsiTreeChangeEvent event); 
  13.   void childMoved(@NotNull PsiTreeChangeEvent event); 
  14.   void propertyChanged(@NotNull PsiTreeChangeEvent event); 
  • childrenChanged:子元素內(nèi)容改變時被調(diào)用;
  • childReplaced:子元素被替換時被調(diào)用,觸發(fā)childReplaced事件也會伴隨著childrenChanged事件;
  • childAdded:子元素添加時被調(diào)用,觸發(fā)childAdded事件時也會伴隨著childReplaced、childrenChanged或事件;
  • childRemoved:子元素移除時被調(diào)用,觸發(fā)childRemoved事件也會伴隨著childReplaced、childrenChanged事件;
  • propertyChanged:屬性改變時被調(diào)用,例如修改文件名;

最后

“編寫一個IDEA插件”系列暫時就寫這些,因為對這方面感興趣的讀者可能比對匯編語言感興趣的讀者還少。其實這幾篇分析的也是筆者寫插件過程中用到的一些筆者認(rèn)為非常重要的知識點,當(dāng)然還有很多沒分享,如果要繼續(xù)寫,估計還可以寫幾篇,但看到上篇的閱讀量就沒動力繼續(xù)寫下去了。

參考:

  • intellij-platform-plugin-template的項目管理監(jiān)聽器注冊:https://sourcegraph.com/github.com/JetBrains/intellij-platform-plugin-template@main/-/blob/src/main/resources/META-INF/plugin.xml#L17:55
  • 接收有關(guān)項目結(jié)構(gòu)變更的通知:https://jetbrains.org/intellij/sdk/docs/reference_guide/project_model/project.html?search=projectClosingBeforeSave

本文轉(zhuǎn)載自微信公眾號「Java藝術(shù)」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系Java藝術(shù)公眾號。 

 

責(zé)任編輯:武曉燕 來源: Java藝術(shù)
相關(guān)推薦

2020-10-10 06:32:43

IDEA插件環(huán)境

2023-12-12 08:08:17

插件PRPulsar

2023-07-06 14:37:05

2023-10-26 11:22:32

2016-09-21 12:34:10

Chrome瀏覽器插件

2016-03-08 09:52:22

xcode插件開發(fā)

2024-04-16 08:09:36

JavapulsarAPI

2024-09-06 11:02:15

API網(wǎng)關(guān)插件

2024-08-27 12:49:20

2020-09-02 07:22:17

JavaScript插件框架

2011-10-19 09:30:23

jQuery

2021-04-13 06:35:13

Elixir語言編程語言軟件開發(fā)

2021-04-07 13:38:27

Django項目視圖

2023-12-11 08:16:51

工具命令行參數(shù)

2015-08-19 09:29:35

Git協(xié)議編寫

2016-01-06 09:57:23

編寫PHP擴展

2013-09-10 09:54:50

2023-04-30 23:09:50

2024-05-13 08:40:02

Go事件驅(qū)動編程

2009-08-18 17:19:33

C#事件模型
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 91在线看片 | 亚洲一页| 精品国产精品 | www.久久久久久久久久久久 | www.狠狠干 | 一区二区不卡 | 四虎永久在线精品免费一区二 | 欧美一级在线观看 | 黄色一级片视频 | 一区二区在线 | 日韩靠逼| 久草免费在线视频 | 精久久| 欧美一区二区免费 | 欧洲视频一区 | 亚洲福利一区二区 | 久久国产亚洲 | 操亚洲| 一区二区三区免费 | 国产电影一区二区在线观看 | 成人性视频免费网站 | 嫩草视频网 | 狠狠操电影 | 99精品热视频 | 欧美日韩国产在线 | 午夜影院黄 | 国产婷婷色一区二区三区 | 中文字幕一级毛片 | 成人国产一区二区三区精品麻豆 | 国产一二区在线 | 色偷偷噜噜噜亚洲男人 | 成人精品一区二区 | 中文字幕久久久 | 日韩精品中文字幕一区二区三区 | 日韩精品在线观看免费 | 91视频一区二区三区 | 黄色一级大片在线免费看产 | 中文字幕在线一 | 欧美日韩综合 | 久久草在线视频 | 日韩高清一区二区 |