Eclipse 簡介和插件開發
Eclipse 是一個很讓人著迷的開發環境,它提供的核心框架和可擴展的插件機制給廣大的程序員提供了無限的想象和創造空間。目前網上流傳相當豐富且全面的開發工具方面的插件,但是 Eclipse 已經超越了開發環境的概念,可以想象 Eclipse 將成為未來的集成的桌面環境。目前的 Eclipse 本身就具備資源管理和外部程序的功能,加上無所不能的插件,將構成一個豐富多彩的工作環境而不僅僅是一個 IDE。
1?評論:
趙勇?(zy_coding@tom.com), J2EE程序員
2004 年 11 月 03 日
-
內容

在 IBM Bluemix 云平臺上開發并部署您的下一個應用。
開始您的試用
1.Eclipse 簡介和插件開發
Eclipse 是一個很讓人著迷的開發環境,它提供的核心框架和可擴展的插件機制給廣大的程序員提供了無限的想象和創造空間。目前網上流傳相當豐富且全面的開發工具方面的插件,但是 Eclipse 已經超越了開發環境的概念,可以想象 Eclipse 將成為未來的集成的桌面環境。目前的 Eclipse 本身就具備資源管理和外部程序的功能,加上無所不能的插件,將構成一個豐富多彩的工作環境而不僅僅是一個 IDE。對于程序員來說,沒有什么比可以隨心所欲的定制的工作環境更重要,你的決心,勇氣和創造力在與別人分享成果的過程中一覽無余。好了,你是不是心動了,如果你已經對 Eclipse 有一定的認識,那么,和我一起打造自己的個性化工作環境吧,首先我們一起開發一個天氣預報的插件,然后我們打造屬于自己的郵件快速監控功能。
以下的工作基于一定的前提,那就是你是一名 Java 程序員,你很欣賞并正開始使用 Eclipse 這個超酷的工作環境,別忘了下載最新版的 Eclipse3.0,本文基于 Eclipse3.0 開發。
回頁首
2. 天氣預報插件
如果你已經厭倦了總是要登錄某些網站從相關網頁上獲取信息,這里有一個讓你通過 Eclipse 快速獲取信息的新方法。讓我們從頭開始,做一個屬于自己的天氣預報插件吧,你的 Eclipse 將具有天氣預報功能,是不是很酷呢?
在這一部分,我們將要實現一個 Eclipse 插件,他可以在任何我們想知道的時候通過簡單的點擊鼠標告訴我們本地區的天氣預報,這當然很刺激。對于一個程序員而言,事情就應該如此。讓我們開始吧,我們首先要定義一個插件,把他加到菜單和工具欄中。對于沒有插件開發經驗的你,可以參考《?開發 Eclipse 插件》,樹立基本的插件開發意識,當然,本文將詳細的輔助你完成這一創造性的工作。
2.1 最基礎的插件
你可以完全參考《?開發 Eclipse 插件》的插件示例,制作你的第一個 hello Eclipse 插件,幸運的是,Eclipse3.0 完全考慮到你的需求,通過菜單 File -> New-> Other ->Plug-in Project,輸入項目名稱,next 出現對話框,只要在插件名處輸入"muplugin",next 以后選擇 "Hello,World"的插件模板你可以直接新建一個名為 myplugin 的最簡單的插件,但其實我們的天氣預報并不比它復雜多少,建完改插件以后的效果如下圖。
現在,將項目作為運行時工作臺運行(run - run as runtime workbench),在一個全新的 Eclipse 窗口中,通過點擊菜單 sample menu 的 sample Action 或者工具欄中的圓形 Eclipse 圖標,你將看到如下效果的對話框。
到此為止,天氣預報插件的原始版做成了,通過修改 plugin.xml,我們將菜單改成中文形式,需要修改的地方就 2 處,詳見表格。
<actionSet label="Sample Action Set"visible="true"id="myplugin.actionSet"> <menu label="我的空間"id="sampleMenu"> <separator name="sampleGroup"> </separator> </menu> <action label="天氣預報"icon="icons/sample.gif"class="myplugin.actions.SampleAction"tooltip="Hello, Eclipse world"menubarPath="sampleMenu/sampleGroup"toolbarPath="sampleGroup"id="myplugin.actions.SampleAction"> </action>
此時在運行時工作臺,我們的菜單已經改變。
2.2 用 VisualEditer 制作天氣預報對話框
雖然菜單是天氣預報,但是我們需要的不是 hello Eclispe 對話框,我們需要的是告訴我們天氣的對話框,當然需要我們從頭開始,于是我們需要重新構建一個對話框,這個就需要 Visual Editor 來幫助進行界面的開發(關于 Visual Editer 參考《?Build GUIs with the Eclipse Visual Editor project》) 。我們將使用 Visual Editor 實現一個 Swing 對話框,當然只用 VE 做一個對話框是有點大材小用,但是作為起點,已經合適了。
首先參考《?Build GUIs with the Eclipse Visual Editor project》構建 Visual Editer 開發環境,當一切準備齊全,鼠標右鍵點擊 PackgeExpoler 中的 "muplugin.actions"java 文件,從彈出式菜單中選擇 new->other->VisualClass,新建一個可視化的類,彈出界面如下圖:
選擇 next,然后在 name 中輸入 WeatherDialog,這個就是我們用來顯示天氣預報的 dialog
選擇該對話框的超類為 javax.swing.JDiaog, 點擊 Finish 按鈕。 等待一段時間后,我們的對話框就基本生成了,鼠標點擊左上角圖標,直接輸入天氣預報就是對話框的標題,同時 我們可以看到左側的 VisualEditor 面板。
然后我們將該對話框于與剛才的天氣預報菜單連接 找到 SampleAction 的 run 函數,如下所示:
public void run(IAction action) { MessageDialog.openInformation( window.getShell(), "Myplugin Plug-in", "Hello, Eclipse world"); }
替換成如下代碼
public void run(IAction action) { WeatherDialog wd=new WeatherDialog(); wd.setSize(400, 335); wd.show(); }
此時,點擊菜單運行,我們的對話框看起來象這個樣子,在此基礎上我們還要在上面增加天氣預報信息
2.3 增加天氣預報功能
下面的部分是重點,我們將使用具有解析 Html 功能的 Swing 組件 JEditPane,來獲取網絡上的現成的天氣預報信息,根據上圖,從 VisualEditor 的面板中 Swing Components 組點擊 JEditPane,加入到對話框中。并修改對話框代碼使得最終的代碼如下:
/* * Created on 2004-9-23 * */ package myplugin; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import javax.swing.JDialog; import javax.swing.JEditorPane; /** * <p>Title: WatherDialog</p> * <p>Description: 這個是對話框類,用于顯示指定城市的當天的天氣預報 </p>* <p>Copyright: Copyright (c) 2004</p> * <p>Company:UF SOFT</p> * @author 趙勇* @version 1.0 */ public class WatherDialog extends JDialog { String city="北京"; private JEditorPane jEditorPane = null; /** * This method initializes * / public WatherDialog(String city) { super(); this.city=city; initialize(); } /** * This method initializes this * @return void */ private void initialize() { this.setContentPane(getJEditorPane()); try { // 構建 URL 對象URL url = new URL("http://weather.news.sina.com.cn//cgi-bin/figureWeather/simpleSearch.cgi?city=" +city); String temp=""; BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));// 使用 openStream 得到一輸入流并由此構造一個 BufferedReader 對象String inputLine; // 從輸入流不斷的讀數據,直到讀完為止while ((inputLine = in.readLine()) != null) temp=temp+inputLine+"\n"; // 關閉輸入流in.close(); String weather =temp.substring ( temp.indexOf( "<body"), temp.lastIndexOf( "body>")+5); this.jEditorPane .setText(weather); } catch (Exception e) { e.printStackTrace(); } this.setTitle("天氣預報"); this.setSize(400, 166); } /** * This method initializes jEditorPane * * @return javax.swing.JEditorPane */ private JEditorPane getJEditorPane() { if (jEditorPane == null) { jEditorPane = new JEditorPane(); jEditorPane.setContentType( "text/html"); } return jEditorPane; } } // @jve:decl-index=0:visual-constraint="70,19"
以上代碼中最關鍵的部分就是對話框中的 JEditorPane 對象,在初始化時,從一個 URL 獲取天氣預報信息,表現為 Html 標記片段,不用解析,直接調用 JEditorPane 的 setText 方法,就可以將 Html 格式的信息直接按解析過的方式顯示,也就是天氣預報信息了,
此時 Action 中的調用需要做修改
public void run(IAction action) { WeatherDialog wd=new WeatherDialog("北京"); wd.setSize(400, 335); wd.show(); }
現在以運行時工作臺的方式運行,點擊天氣預報菜單,可以看到下圖:
如果你在上海或者其他城市,試著修改 city 參數為"上海",再次運行,你將發現,你仍然能夠得到該城市的天氣預報(這里我們從網站上提取的信息,有點投機取巧了)。值得注意的是,Xmethod 網站提供了一個天氣預報的 WebService,可惜只有美國的城市,不然我們可以使用 Web Service 調用獲取天氣預報,將會更酷。
現在運行是工作臺已經具備了天氣預報的功能,還需要更進一步,將改插件導出發布,拷貝到 Eclipse 根目錄的 plugins 目錄中,重新啟動(具體參見 Eclipse 幫助)。現在你自己的 Eclipse,就具備了天氣預報的功能,只要你點擊鼠標,就可以在編程之余輕松的獲取天氣信息。 除非你的老板認為你在工作時間隨時了解天氣情況不是一個好主意,我認為你完全可以將這個插件納入個人收藏的插件之列。你也可以在此基礎上擴展,增加一些配置文件和屬性設置,定制出滿足自己要求的插件。如果能夠增加信息的自動過濾和篩選,那將是一次很愉快的體驗,如果你有時間和興趣,不妨一試。
回頁首
3. 郵件快速監控插件
現在你的工作因為 Eclipse 而更加愜意,更具創造力,那么你還有什么不滿?你是否厭倦了各種郵件客戶端隨時隨地的騷擾你呢?你希望你在高興的時候適時的了解一下郵件的概況?好了,既然想到了為什么猶豫呢,因為你是程序員,你就是要用 Eclipse 享受完全 DIY 的樂趣。
3.1 生成插件
本部分我們將在以上 myplugin 插件的基礎上增加一個郵件過濾顯示的對話框,類似的我們通過 VisualEditer 創建一個名為 MailDialog 的對話框,并增加一個 JEditPane 用來顯示郵箱中我們關注的信息。
修改 plugin.xml,增加一個"我的郵件"菜單
<action label="郵件信息"icon="icons/sample.gif"class="myplugin.actions.MailAction"tooltip="郵件信息"menubarPath="sampleMenu/sampleGroup"toolbarPath="sampleGroup"id="myplugin.actions.MailAction"> </action>
現在,你知道要創建一個 MailAction 的 Action 類,并在 在 Run 中增加如下代碼
MailConfig mail=new MailConfig(); String popServer="server"; String popUser="zhaoyong"; String popPassword="1234"; // 設置需要過濾的關鍵字:發件人和郵件主題String [] strFrom=new String[] {"zhaoyong"}; String [] strSubject=new String[] {"測試"}; MailConfig[] mc =new MailConfig [] { mail }; MailDialog md=new MailDialog(mc); System.err.println("run run run ") ; md.setSize(400, 335); md.show();
以上的代碼編譯不會通過,但是別著急,慢慢來,很快了。
3.2 構建郵件監控對話框
當然你需要建立一個 MailConfig 類用來表示一個郵箱的具體設置已及相關信息,這里就不在累述說明,詳情參見參考資料中的代碼。需要說明的式 MailConfig 除了要記錄一個郵箱的地址,用戶名和密碼外,還提供 2 個關鍵字數組,如果為空,不加過濾,如果關鍵字有值,系統會根據發件人和郵件標題中是否包含關鍵字來進行顯示郵件信息,已保證你的絕對自由。
首先我們需要實現一個 MailConfig 類,表示郵件配置,每個 MailConfig 的對象代表一個郵件帳戶,我們的系統將能顯示多個郵箱的配置,每個 MailConfig 中使用一個數組來保存需要過濾的收件人和郵件地址。
MailConfig 類的中的變量如下:
String popServer; String popUser; String popPassword; // 設 置 需 要 過 濾 的 關 鍵 字 : 發 件 人 和 郵 件 主 題String [] strFrom; String [] strSubject; // 是 否 顯 示 郵 件 內 容 boolean isViewContent=false;
同樣,我們將使用一個對話框來顯示郵件信息,MailDialog 需要引用 javaMail.jar, 和 activation.jar 這兩個類包,確保已經有這兩個類包并加入到項目的類路徑中。最后的 MailDialog 代碼如下:
package myplugin; import java.io.IOException; import java.util.Properties; import javax.mail.Folder; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.Session; import javax.mail.Store; import javax.mail.internet.InternetAddress; import javax.swing.JDialog; import javax.swing.JEditorPane; import javax.swing.JTextPane; /** * @author zhaoyong * * TODO To change the template for this generated type comment go to * Window - Preferences - Java - Code Style - Code Templates */ public class MailDialog extends JDialog { private JEditorPane jEditorPane = null; private JTextPane jTextPane = null; // 可以顯示多個郵件配置MailConfig[] mc= null; /** * This method initializes * 構造函數* @param mc : 需要顯示的多個郵箱配置對象。*/ public MailDialog(MailConfig[] mc) { super(); if(mc!=null) this.mc = mc; else System.err.println("郵件配置錯誤!") ; initialize(); } /** * This method initializes this * 初始化* @return void */ private void initialize() { try { // 設定顯示內容的面板this.setContentPane(getJTextPane()); // 取得所有的新郵件信息String s= getAllMailInfo(); // 將信息顯示在對話框中this.jTextPane .setText(s); this.setTitle("郵件信息"); this.setSize(251, 100); } catch (Exception e) { // 發生錯誤顯示錯誤信息this.jTextPane .setText(e.toString()); e.printStackTrace(); } } /** 取得所有的郵箱的需要監控的郵件信息* * @return String */ private String getAllMailInfo() { String allMailInfo=""; if (mc.length <1) allMailInfo="沒有配置郵箱!"; else { for(int i=0;i<mc.length;i++) { // 循環獲取每個郵箱的郵件信息allMailInfo=allMailInfo+getMailInfo(mc[i]); } } // 還沒有收到相關的郵件if (allMailInfo.trim().length() ==0) allMailInfo="未檢測到相關新郵件!"; return allMailInfo; } /* * 得到一個郵箱中滿足條件的所有新郵件的字符串形式**/ private String getMailInfo(MailConfig mc) { // 最終輸出的郵件信息String mailInfo=""; // 每個郵箱服務器上的 Store 和 Folder 對象Store store=null; Folder folder=null; try { Properties props = System.getProperties(); // 與郵件服務器生成一個 Session Session session = Session.getDefaultInstance( props,null); // 給出服務器,用戶名,密碼連接服務器store = session.getStore("pop3"); store.connect(mc.getPopServer(), mc.getPopUser(),mc.getPopPassword()); // 取得默認的郵件 Folder folder = store.getDefaultFolder(); if (folder == null) throw new Exception("No default folder"); // 取得收件箱folder = folder.getFolder("INBOX"); if (folder == null) throw new Exception("No POP3 INBOX"); // 以只讀方式打開收件箱folder.open(Folder.READ_ONLY); // 獲取所有新郵件并處理Message[] msgs = folder.getMessages(); for (int i = 0; i < msgs.length; i++) { Message message= msgs[i]; // 取得每封郵件的信息,需要引用 MailConfig 對象進行關鍵字過濾mailInfo = mailInfo+ getMessageInfo( message,mc); } } catch (Exception ex) { ex.printStackTrace(); } finally { // 安全的關閉郵件服務器資源try { if (folder!=null) folder.close(true); if (store!=null) store.close(); } catch (Exception ex2) {ex2.printStackTrace();} } return mailInfo; } /** * 得到一封郵件的信息,需要根據 MailConfig 過濾* @param mailInfo * @param message * @return 郵件信息* @throws MessagingException * @throws IOException */ private String getMessageInfo( final Message message ,final MailConfig mc) throws MessagingException, IOException { // 返回的改郵件信息String mailInfo=""; String from=((InternetAddress)message.getFrom()[0]).getPersonal(); if (from==null) from=((InternetAddress)message.getFrom()[0]).getAddress(); String subject=message.getSubject(); // 如果滿足過濾信息則顯示,否則返回空if(isElementinString(from,mc.getStrFrom()) ||isElementinString(subject,mc.getStrSubject()) ) { mailInfo=mailInfo+"發件人 : "+from+"\n"; mailInfo=mailInfo+"郵件主題 : "+subject+"\n"; mailInfo=mailInfo+"發送時間 : "+message.getSentDate() +"\n"; // 如果顯示內容,則打印內容if(mc.isViewContent) mailInfo=mailInfo+message.getContent() +"\n"; mailInfo=mailInfo+"------------------------------------\n"; } return mailInfo; } private JTextPane getJTextPane() { if (jTextPane == null) { jTextPane = new JTextPane(); } return jTextPane; } /** * 判斷目標關鍵字數組中是否有指定的字符串 , 進行過濾* @param targetStr :* @param keys :* @return 如果有,返回 true, 否則返回 false */ private boolean isElementinString(String targetStr,String [] keys) { // 沒指定過濾條件,顯示所有if (keys==null) return true; // 指定字符串為空,直接返回 false if (targetStr==null) return false; for(int i=0;i<keys.length ;i++) { if (targetStr.indexOf(keys[i])>-1) return true; } return false; } } // @jve:decl-index=0:visual-constraint="10,10"--說明,這是 Visual Editor 添加的控制信息
以上代碼的注釋已經保證你能夠看清楚,這里就不加累述,有興趣的可以自己試試,體驗一切盡在掌握的快感。當然這個例子做的實在簡單,因此也為你的進一步開發留有足夠的余地。
3.3 打包和發布
到此,在 mypulgin 中增加了郵件信息菜單和對話框,系統的 plugin.xml 如下:
<?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.0"?> <plugin id="myplugin"name="Myplugin Plug-in"version="1.0.0"provider-name=""class="myplugin.MypluginPlugin"> <runtime> <library name="myplugin.jar"> <export name="*"/> </library> <library name="lib/javaMail.jar"> <export name="*"/> </library> <library name="lib/activation.jar"> <export name="*"/> </library> </runtime> <requires> <import plugin="org.eclipse.ui"/> <import plugin="org.eclipse.core.runtime"/> </requires> <extension point="org.eclipse.ui.actionSets"> <actionSet label="Sample Action Set"visible="true"id="myplugin.actionSet"> <menu label="我的空間"id="sampleMenu"> <separator name="sampleGroup"> </separator> </menu> <action label="天氣預報"icon="icons/sample.gif"class="myplugin.actions.SampleAction"tooltip="Hello, Eclipse world"menubarPath="sampleMenu/sampleGroup"toolbarPath="sampleGroup"id="myplugin.actions.SampleAction"> </action> <action label="郵件信息"icon="icons/sample.gif"class="myplugin.actions.MailAction"tooltip="郵件信息"menubarPath="sampleMenu/sampleGroup"toolbarPath="sampleGroup"id="myplugin.actions.MailAction"> </action> </actionSet> </extension> </plugin>
實際上,我們在一個插件中加入了 2 個功能,因此就實現了我們的開發環境的自我擴展和定制。 同樣,參考 Eclipse 的幫助,你可以輕松的再次將插件打包導出,并將其加入自己的 Eclipse 的 plugins 目錄(可能需要解壓縮),或通過 help 菜單的 Update 選項進行安裝,注意導出時需要選定相關的類包。重新啟動,你將發現自己的 IDE 已經多了自己的菜單,開發環境已經隨著自己的意愿在改變了,程序員天生的滿足感油然而生。
現在,你可以在需要的時候點擊菜單,了解你希望監控的郵件情況或者最近的天氣情況,一切輕松的盡在掌握,Eclipse 的插件,就是這樣全能。
回頁首
4. 總結
那么,聰明的你有沒有發現什么問題,對,上面的東西太粗糙,太簡單了,你可以做進一步的優化設計和功能加強,比如,自己增加郵件配置文件而不是寫在代碼里面,動態監控彈出郵件預警(通過事先設定的緊急狀態),你也許還會想起來很多的新的主意,比如我為什么不能有個能看電影的插件?或是 Eclipse 中飄出動聽的音樂?別急,這些不一定需要你親手去做,?http://sourceforge.net/projects/rocexwang/有一個播放器插件,但是現在僅能播放音樂,國外已經有人用 Eclipse 開發游戲,也有人用 Eclipse 來做 MIS 系統的。http://www.matrix.org.cn/forum_view.asp?forum_id=25&view_id=10510 有一個國人開發的俄羅斯方塊游戲,雖然簡單了一點。當然,通過網址http://eclipse-plugins.2y.net/eclipse/index.jsp和?http://www.eclipseplugincentral.com/你可以找到很多的插件,如果你知道什么更好的插件,請告訴我。
Eclipse 提供了一個純的框架和插件結構,使得開發任何功能的插件都能成為現實。本文介紹了 2 個有趣的 Eclipse 插件的開發,可以使我們的工作環境增加了兩個可愛的小功能,同時也使得你具備了基礎的插件開發能力,借助 Eclipse 的強大功能,從此你可以把你的任何想法變為現實。同時請保持與別人的交流,我會很樂意了解你的新奇的插件,并收藏和學習任何好的插件,打造一個完全屬于自己的個性化的開發環境。Eclipse 將在不久的將來成為一個全能的 Platform,這一點在全世界數以萬計的開發人員的手中,正一點一點變為現實。
在這里下載代碼:?myplugin.rar,這里打包的是整個 myplugin 項目,解壓縮后導入 Eclipse,你可能需要重新配置類路徑等工作。