Eclipse 是一個很讓人著迷的開發環境,它提供的核心框架和可擴展的插件機制給廣大的程序員提供了無限的想象和創造空間。目前網上流傳相當豐富且全面的開發工具方面的插件,但是Eclipse已經超越了開發環境的概念,可以想象Eclipse將成為未來的集成的桌面環境。目前的Eclipse本身就具備資源管理和外部程序的功能,加上無所不能的插件,將構成一個豐富多彩的工作環境而不僅僅是一個IDE。
1.Eclipse簡介和插件開發
Eclipse 是一個很讓人著迷的開發環境,它提供的核心框架和可擴展的插件機制給廣大的程序員提供了無限的想象和創造空間。目前網上流傳相當豐富且全面的開發工具方面的插件,但是Eclipse已經超越了開發環境的概念,可以想象Eclipse將成為未來的集成的桌面環境。目前的Eclipse本身就具備資源管理和外部程序的功能,加上無所不能的插件,將構成一個豐富多彩的工作環境而不僅僅是一個IDE。對於程序員來說,沒有什麼比可以隨心所欲的定制的工作環境更重要,你的決心,勇氣和創造力在與別人分享成果的過程中一覽無余。好了,你是不是心動了,如果你已經對Eclipse有一定的認識,那麼,和我一起打造自己的個性化工作環境吧,首先我們一起開發一個天氣預報的插件,然後我們打造屬於自己的郵件快速監控功能。
以下的工作基於一定的前提,那就是你是一名Java程序員,你很欣賞並正開始使用Eclipse這個超酷的工作環境,別忘了下載最新版的Eclipse3.0,本文基於Eclipse3.0開發。
2.天氣預報插件
如果你已經厭倦了總是要登錄某些網站從相關網頁上獲取信息,這裡有一個讓你通過Eclipse快速獲取信息的新方法。讓我們從頭開始,做一個屬於自己的天氣預報插件吧,你的Eclipse將具有天氣預報功能,是不是很酷呢?
在這一部分,我們將要實現一個Eclipse插件,他可以在任何我們想知道的時候通過簡單的點擊鼠標告訴我們本地區的天氣預報,這當然很刺激。對於一個程序員而言,事情就應該如此。讓我們開始吧,我們首先要定義一個插件,把他加到菜單和工具欄中。對於沒有插件開發經驗的你,可以參考《開發 Eclipse 插件》,樹立基本的插件開發意識,當然,本文將詳細的輔助你完成這一創造性的工作。
2.1最基礎的插件
打開菜單 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 Editor實現一個Swing對話框,當然只用VE做一個對話框是有點大材小用,但是作為起點,已經合適了。
首先構建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,這一點在全世界數以萬計的開發人員的手中,正一點一點變為現實。