Sung in Blog

                     一些技術文章 & 一些生活雜碎
          Eclipse 是一個很讓人著迷的開發(fā)環(huán)境,它提供的核心框架和可擴展的插件機制給廣大的程序員提供了無限的想象和創(chuàng)造空間。目前網(wǎng)上流傳相當豐富且全面的開發(fā)工具方面的插件,但是Eclipse已經(jīng)超越了開發(fā)環(huán)境的概念,可以想象Eclipse將成為未來的集成的桌面環(huán)境。目前的Eclipse本身就具備資源管理和外部程序的功能,加上無所不能的插件,將構成一個豐富多彩的工作環(huán)境而不僅僅是一個IDE。

            1.Eclipse簡介和插件開發(fā)

            Eclipse 是一個很讓人著迷的開發(fā)環(huán)境,它提供的核心框架和可擴展的插件機制給廣大的程序員提供了無限的想象和創(chuàng)造空間。目前網(wǎng)上流傳相當豐富且全面的開發(fā)工具方面的插件,但是Eclipse已經(jīng)超越了開發(fā)環(huán)境的概念,可以想象Eclipse將成為未來的集成的桌面環(huán)境。目前的Eclipse本身就具備資源管理和外部程序的功能,加上無所不能的插件,將構成一個豐富多彩的工作環(huán)境而不僅僅是一個IDE。對于程序員來說,沒有什么比可以隨心所欲的定制的工作環(huán)境更重要,你的決心,勇氣和創(chuàng)造力在與別人分享成果的過程中一覽無余。好了,你是不是心動了,如果你已經(jīng)對Eclipse有一定的認識,那么,和我一起打造自己的個性化工作環(huán)境吧,首先我們一起開發(fā)一個天氣預報的插件,然后我們打造屬于自己的郵件快速監(jiān)控功能。

            以下的工作基于一定的前提,那就是你是一名Java程序員,你很欣賞并正開始使用Eclipse這個超酷的工作環(huán)境,別忘了下載最新版的Eclipse3.0,本文基于Eclipse3.0開發(fā)。

            2.天氣預報插件

            如果你已經(jīng)厭倦了總是要登錄某些網(wǎng)站從相關網(wǎng)頁上獲取信息,這里有一個讓你通過Eclipse快速獲取信息的新方法。讓我們從頭開始,做一個屬于自己的天氣預報插件吧,你的Eclipse將具有天氣預報功能,是不是很酷呢?

            在這一部分,我們將要實現(xiàn)一個Eclipse插件,他可以在任何我們想知道的時候通過簡單的點擊鼠標告訴我們本地區(qū)的天氣預報,這當然很刺激。對于一個程序員而言,事情就應該如此。讓我們開始吧,我們首先要定義一個插件,把他加到菜單和工具欄中。對于沒有插件開發(fā)經(jīng)驗的你,可以參考《開發(fā) Eclipse 插件》,樹立基本的插件開發(fā)意識,當然,本文將詳細的輔助你完成這一創(chuàng)造性的工作。

            2.1最基礎的插件

            打開菜單 File -> New-> Other ->Plug-in Project,輸入項目名稱,next出現(xiàn)對話框,只要在插件名處輸入"muplugin",next 以后選擇 "Hello,World"的插件模板你可以直接新建一個名為myplugin的最簡單的插件,但其實我們的天氣預報并不比它復雜多少,建完改插件以后的效果如下圖。


            現(xiàn)在,將項目作為運行時工作臺運行(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>

            此時在運行時工作臺,我們的菜單已經(jīng)改變。


            2.2用VisualEditer制作天氣預報對話框

            雖然菜單是天氣預報,但是我們需要的不是hello Eclispe對話框,我們需要的是告訴我們天氣的對話框,當然需要我們從頭開始,于是我們需要重新構建一個對話框,這個就需要 Visual Editor來幫助進行界面的開發(fā)。我們將使用Visual Editor實現(xiàn)一個Swing對話框,當然只用VE做一個對話框是有點大材小用,但是作為起點,已經(jīng)合適了。

            首先構建Visual Editer開發(fā)環(huán)境(讀者可參考相關資料),當一切準備齊全,鼠標右鍵點擊PackgeExpoler中的 "muplugin.actions"java文件,從彈出式菜單中選擇 new->other->VisualClass,新建一個可視化的類,彈出界面如下圖:


            選擇next,然后在name中輸入WeatherDialog,這個就是我們用來顯示天氣預報的dialog

            選擇該對話框的超類為javax.swing.JDiaog,點擊Finish按鈕。等待一段時間后,我們的對話框就基本生成了,鼠標點擊左上角圖標,直接輸入天氣預報就是對話框的標題,同時 我們可以看到左側(cè)的VisualEditor面板。


             然后我們將該對話框于與剛才的天氣預報菜單連接找到SampleAction的run函數(shù),如下所示:

          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,來獲取網(wǎng)絡上的現(xiàn)成的天氣預報信息,根據(jù)上圖,從 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;
          //從輸入流不斷的讀數(shù)據(jù),直到讀完為止
          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 獲取天氣預報信息,表現(xiàn)為Html標記片段,不用解析,直接調(diào)用JEditorPane的setText 方法,就可以將Html格式的信息直接按解析過的方式顯示,也就是天氣預報信息了,

            此時Action中的調(diào)用需要做修改

          public void run(IAction action)
          {
          WeatherDialog wd=new WeatherDialog("北京");
          wd.setSize(400, 335);
          wd.show();
          }

            現(xiàn)在以運行時工作臺的方式運行,點擊天氣預報菜單,可以看到下圖:


            如果你在上海或者其他城市,試著修改city參數(shù)為"上海",再次運行,你將發(fā)現(xiàn),你仍然能夠得到該城市的天氣預報(這里我們從網(wǎng)站上提取的信息,有點投機取巧了)。值得注意的是,Xmethod網(wǎng)站提供了一個天氣預報的WebService,可惜只有美國的城市,不然我們可以使用Web Service調(diào)用獲取天氣預報,將會更酷。

            現(xiàn)在運行是工作臺已經(jīng)具備了天氣預報的功能,還需要更進一步,將改插件導出發(fā)布,拷貝到Eclipse根目錄的plugins目錄中,重新啟動(具體參見Eclipse幫助)?,F(xiàn)在你自己的Eclipse,就具備了天氣預報的功能,只要你點擊鼠標,就可以在編程之余輕松的獲取天氣信息。 除非你的老板認為你在工作時間隨時了解天氣情況不是一個好主意,我認為你完全可以將這個插件納入個人收藏的插件之列。你也可以在此基礎上擴展,增加一些配置文件和屬性設置,定制出滿足自己要求的插件。如果能夠增加信息的自動過濾和篩選,那將是一次很愉快的體驗,如果你有時間和興趣,不妨一試。

           3.郵件快速監(jiān)控插件

            現(xiàn)在你的工作因為Eclipse而更加愜意,更具創(chuàng)造力,那么你還有什么不滿?你是否厭倦了各種郵件客戶端隨時隨地的騷擾你呢?你希望你在高興的時候適時的了解一下郵件的概況?好了,既然想到了為什么猶豫呢,因為你是程序員,你就是要用Eclipse享受完全DIY的樂趣。

            3.1生成插件

            本部分我們將在以上myplugin插件的基礎上增加一個郵件過濾顯示的對話框,類似的我們通過VisualEditer創(chuàng)建一個名為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>

            現(xiàn)在,你知道要創(chuàng)建一個MailAction的Action類,并在在Run中增加如下代碼

          MailConfig mail=new MailConfig();

          String popServer="server";
          String popUser="zhaoyong";
          String popPassword="1234";

          //設置需要過濾的關鍵字:發(fā)件人和郵件主題
          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構建郵件監(jiān)控對話框

            當然你需要建立一個MailConfig類用來表示一個郵箱的具體設置已及相關信息,這里就不在累述說明,詳情參見參考資料中的代碼。需要說明的式MailConfig除了要記錄一個郵箱的地址,用戶名和密碼外,還提供2個關鍵字數(shù)組,如果為空,不加過濾,如果關鍵字有值,系統(tǒng)會根據(jù)發(fā)件人和郵件標題中是否包含關鍵字來進行顯示郵件信息,已保證你的絕對自由。

            首先我們需要實現(xiàn)一個MailConfig類,表示郵件配置,每個MailConfig的對象代表一個郵件帳戶,我們的系統(tǒng)將能顯示多個郵箱的配置,每個MailConfig中使用一個數(shù)組來保存需要過濾的收件人和郵件地址。

            MailConfig類的中的變量如下:

          String popServer;
          String popUser;
          String popPassword;

          //設置需要過濾的關鍵字:發(fā)件人和郵件主題

          String [] strFrom;
          String [] strSubject;

          //是否顯示郵件內(nèi)容
          boolean isViewContent=false;

            同樣,我們將使用一個對話框來顯示郵件信息,MailDialog需要引用javaMail.jar,和activation.jar這兩個類包,確保已經(jīng)有這兩個類包并加入到項目的類路徑中。最后的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
          * 構造函數(shù)
          * @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
          {
          //設定顯示內(nèi)容的面板
          this.setContentPane(getJTextPane());
          //取得所有的新郵件信息
          String s= getAllMailInfo();
          //將信息顯示在對話框中
          this.jTextPane .setText(s);

          this.setTitle("郵件信息");
          this.setSize(251, 100);
          }
          catch (Exception e)
          {
          //發(fā)生錯誤顯示錯誤信息
          this.jTextPane .setText(e.toString());
          e.printStackTrace();
          }

          }
          /**取得所有的郵箱的需要監(jiān)控的郵件信息
          *
          * @return String
          */
          private String getAllMailInfo()
          {
          String allMailInfo="";

          if (mc.length <1)
          allMailInfo="沒有配置郵箱!";
          else
          {
          for(int i=0;i<mc.length;i++)
          {
          //循環(huán)獲取每個郵箱的郵件信息
          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;
          }

          /**
          * 得到一封郵件的信息,需要根據(jù)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+"發(fā)件人 : "+from+"\n";
          mailInfo=mailInfo+"郵件主題 : "+subject+"\n";
          mailInfo=mailInfo+"發(fā)送時間 : "+message.getSentDate() +"\n";

          //如果顯示內(nèi)容,則打印內(nèi)容
          if(mc.isViewContent)
          mailInfo=mailInfo+message.getContent() +"\n";

          mailInfo=mailInfo+"------------------------------------\n";
          }
          return mailInfo;
          }

          private JTextPane getJTextPane()
          {
          if (jTextPane == null)
          {
          jTextPane = new JTextPane();
          }

          return jTextPane;
          }

          /**
          * 判斷目標關鍵字數(shù)組中是否有指定的字符串,進行過濾
          * @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添加的控制信息

            以上代碼的注釋已經(jīng)保證你能夠看清楚,這里就不加累述,有興趣的可以自己試試,體驗一切盡在掌握的快感。當然這個例子做的實在簡單,因此也為你的進一步開發(fā)留有足夠的余地。

            3.3 打包和發(fā)布

            到此,在mypulgin中增加了郵件信息菜單和對話框,系統(tǒng)的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個功能,因此就實現(xiàn)了我們的開發(fā)環(huán)境的自我擴展和定制。同樣,參考Eclipse的幫助,你可以輕松的再次將插件打包導出,并將其加入自己的Eclipse 的plugins目錄(可能需要解壓縮),或通過help菜單的Update選項進行安裝,注意導出時需要選定相關的類包。重新啟動,你將發(fā)現(xiàn)自己的IDE已經(jīng)多了自己的菜單,開發(fā)環(huán)境已經(jīng)隨著自己的意愿在改變了,程序員天生的滿足感油然而生。

            現(xiàn)在,你可以在需要的時候點擊菜單,了解你希望監(jiān)控的郵件情況或者最近的天氣情況,一切輕松的盡在掌握,Eclipse的插件,就是這樣全能。

            4.總結

            那么,聰明的你有沒有發(fā)現(xiàn)什么問題,對,上面的東西太粗糙,太簡單了,你可以做進一步的優(yōu)化設計和功能加強,比如,自己增加郵件配置文件而不是寫在代碼里面,動態(tài)監(jiān)控彈出郵件預警(通過事先設定的緊急狀態(tài)),你也許還會想起來很多的新的主意,比如我為什么不能有個能看電影的插件?或是Eclipse中飄出動聽的音樂?別急,這些不一定需要你親手去做,http://sourceforge.net/projects/rocexwang/ 有一個播放器插件,但是現(xiàn)在僅能播放音樂,國外已經(jīng)有人用Eclipse開發(fā)游戲,也有人用Eclipse來做MIS系統(tǒng)的。http://www.matrix.org.cn/forum_view.asp?forum_id=25&view_id=10510 有一個國人開發(fā)的俄羅斯方塊游戲,雖然簡單了一點。當然,通過網(wǎng)址http://eclipse-plugins.2y.net/eclipse/index.jsp和http://www.eclipseplugincentral.com/你可以找到很多的插件,如果你知道什么更好的插件,請告訴我。

            Eclipse提供了一個純的框架和插件結構,使得開發(fā)任何功能的插件都能成為現(xiàn)實。本文介紹了2個有趣的Eclipse插件的開發(fā),可以使我們的工作環(huán)境增加了兩個可愛的小功能,同時也使得你具備了基礎的插件開發(fā)能力,借助Eclipse的強大功能,從此你可以把你的任何想法變?yōu)楝F(xiàn)實。同時請保持與別人的交流,我會很樂意了解你的新奇的插件,并收藏和學習任何好的插件,打造一個完全屬于自己的個性化的開發(fā)環(huán)境。Eclipse將在不久的將來成為一個全能的Platform,這一點在全世界數(shù)以萬計的開發(fā)人員的手中,正一點一點變?yōu)楝F(xiàn)實。

          posted on 2005-11-02 15:06 Sung 閱讀(404) 評論(0)  編輯  收藏 所屬分類: Eclipse
          主站蜘蛛池模板: 广元市| 东台市| 准格尔旗| 合水县| 江陵县| 革吉县| 长子县| 左权县| 山东| 清原| 白玉县| 乳山市| 南康市| 东山县| 安平县| 迭部县| 株洲县| 平度市| 孟村| 邓州市| 伽师县| 鄂托克前旗| 山东省| 冀州市| 太和县| 班戈县| 多伦县| 三门县| 浪卡子县| 昌平区| 徐水县| 准格尔旗| 荥阳市| 新化县| 清河县| 贡觉县| 大英县| 滕州市| 舒兰市| 桃园市| 贵阳市|