頭一次注意到,覺得狂搞笑,在游戲中才有的場景居然移植到了IDE中,不知道這是設計者的意圖,還是開發者的惡搞。一般來說,設計者的Mock up都是比較嚴謹的,我想這是開發者自己干的好事吧,呵呵。
擴展SWT功能,實現了Windows下注冊表,磁盤,CPU,內存,目錄訪問,網絡,關機,系統特性等常用API功能。現在可以通過CVS進行訪問該項目,直接下載:http://www.aygfsteel.com/Files/cnfree/swt-extension.zip
SWT Extension under Windows OS can be checked out through CVS now!?
User can access it from:
?
cvs -z3 -d:pserver anonymous@feeling.cvs.sourceforge.net:/cvsroot/feeling co -P org.eclipse.swt.extension ?
?
Add native method:?
public ? static ? final ? native ? void ?GetDiskFreeSpace(String?drive,?DISKFREESPACE?diskFreeSpace);
public ? static ? final ? native ? void ?GetSystemInfo(SYSTEM_INFO?systemInfo);
public ? static ? final ? native ? void ?GlobalMemoryStatus(MEMORYSTATUS?memoryStatus);
public ? static ? final ? native ? int ?GetDriveType(String?drive);
public ? static ? final ? native ?String[]?GetLogicalDrives();
public ? static ? final ? native ?String?GetVolumeLabel(String?drive);
public ? static ? final ? native ? boolean ?SetVolumeLabel(String?drive,?String?label);
public ? static ? final ? native ?String?GetCurrentDirectory();
public ? static ? final ? native ? boolean ?SetCurrentDirectory(String?directory);
public ? static ? final ? native ? boolean ?RegistryKeyIteratorHasNext(KeyIterator?iterator);
public ? static ? final ? native ? void ?DeleteRegistryKey(RegistryKey?key);
public ? static ? final ? native ? boolean ?RegistryKeyHasSubKeys(RegistryKey?key);
public ? static ? final ? native ? boolean ?RegistryKeyHasValue(RegistryKey?key,?String?name);
public ? static ? final ? native ?String?RegistryKeyValueIteratorGetNext(ValueIterator?iterator);
public ? static ? final ? native ? boolean ?RegistryKeyHasValues(RegistryKey?key);
public ? static ? final ? native ?RegistryValue?RegistryKeyGetValue(RegistryKey?key,?String?name);
public ? static ? final ? native ? void ?RegistryKeySetValue(RegistryKey?key,?RegistryValue?value);
public ? static ? final ? native ? void ?RegistryKeyDeleteValue(RegistryKey?key,?String?name);
public ? static ? final ? native ?String?RegistryKeyIteratorGetNext(KeyIterator?iterator);
public ? static ? final ? native ? boolean ?ExistsRegistryKey(RegistryKey?key);
public ? static ? final ? native ? void ?CreateRegistryKey(RegistryKey?key);
public ? static ? final ? native ? boolean ?RegistryKeyValueIteratorHasNext(ValueIterator?iterator);
public ? static ? final ? native ? int ?CreateShortCut(String?sourceFile,?String?linkFile,String?linkDescriptor);
public ? static ? final ? native ? int ?SHFileOperationA(SHFILEOPSTRUCT?shFileOpStruct);
public ? static ? final ? native ? int ?SHFileOperationW(SHFILEOPSTRUCT?shFileOpStruct);
public ? static ? final ? native ? boolean ?FlashWindow( int ?hwnd,? boolean ?bInvert);
public ? static ? final ? native ? boolean ?SetLayeredWindowAttributes( int ?hwnd,? int ?color,? byte ?alpha,? int ?type);
public ? static ? final ? native ?String?GetSystemDirectory();
public ? static ? final ? native ?String?GetWindowsDirectory();
public ? static ? final ? native ?String?GetTempPath();
public ? static ? final ? native ?String?GetLongPathName(String?shortPathName);
public ? static ? final ? native ? boolean ?SetWallPaper( char []?picturePath, int ?style);
public ? static ? final ? native ? int ?Ping(?String?host?,? int ?dateSize?);
public ? static ? final ? native ? int []?GetMACID(?);
public ? static ? final ? native ? int []?GetMACAddress(? int ?MACID);
public ? static ? final ? native ? boolean ?Reboot( boolean ?force);
public ? static ? final ? native ? boolean ?Shutdown( boolean ?force);
public ? static ? final ? native ? boolean ?Logoff( boolean ?force);
public ? static ? final ? native ? boolean ?LockWorkStation();
public ? static ? final ? native ? boolean ?SuspendWorkstation( boolean ?suspend, boolean ?force);
public ? static ? final ? native ? boolean ?InitiateShutdownA( byte []?info, int ?time,? boolean ?force?, boolean ?reboot);
public ? static ? final ? native ? boolean ?InitiateShutdownW( char []?info, int ?time,? boolean ?force?, boolean ?reboot);
snapshot:

Eclipse下的開發因為是插件化的,所以一切都要盡可能的實行標準,而不是直接操作底層,就Tree來說,就需要使用TreeViewer,而不是Tree,但是使用封裝后的組件往往有一些自定義的目標做不到,比如對一個TreeViewer setInput之后,因為input Model的改變,TreeViewer要對每個節點的路徑進行計算,如果得到的element和原來的不一樣,就會進行路徑更新,放棄原有的路徑。而Tree是一個多級化的組件,有折疊的狀態存在,每一個TreeItem可以擁有自己的子節點。如果直接使用TreeViewer,然后想對TreeViewer的Tree直接進行操作實際上是不可能的。TreeViewer的節點是通過ContentProvider動態拿到的,所以當我們想直接操作某一個節點,比如想讓它展開,或者獲得它的子節點數目的時候,得到的結果都會和預期結果完全不一樣,因為那個時候TreeItem的子節點并沒有被自動創建。
那么如何對一個TreeViewer的TreeItem進行操作呢?通過以上的分析得知,我們首先要創建出該節點的子節點才行。TreeViewer里有一個方法:protected void createChildren(Widget widget),該方法是用來創建TreeItem的子節點的,可以看到它是一個protected方法,不允許外界訪問的。我們可以在需要用到TreeViewer的地方,自己繼承TreeViewer,覆寫createChildren方法,把protected改成public。然后通過這個CustromTreeViewer,就可以自由控制子節點了。凡是我們需要操作TreeItem的地方,首先createChildren(item),然后item.setExpanded(true)或者item.getItems[]都可以正常使用了。
一般來說,當需要記錄和恢復一個TreeViewer的狀態的時候,這個方法就會顯得非常有用處。
cvs -d:pserver:anonymous@feeling.cvs.sourceforge.net:/cvsroot/feeling login
由于一直使用的都是Java,對Win32編程并不是非常熟悉。但局限于Java的功能,對我們有相當大的限制,IBM就屢屢向突破這個限制,因此產生了SWT。這里我重點想說的是怎么使用Win32的系統鉤子。SWT里已經包含了大量的Win32函數,不過那都是局限于Eclipse的需要,如果Eclipse不需要,SWT是不予以優先考慮的。通過SWT我們很容易使用線程鉤子監控自己程序的鍵盤鼠標事件,而且封裝的很好。但是想使用系統鉤子確是一件不可能的事情,先看看鉤子的函數原型:

idHook -- 系統鉤子類型,實際上是一個int值,具體的定義請看MSDN
lpfn -- 鉤子回調函數指針,當收到鉤子消息時就執行這個回調函數,回調函數有3個參數,不同類型的鉤子這3個參數有不同的含義,具體請看MSDN。
hMod -- DLL實例句柄(我猜是這樣,我不熟悉Win32API編程),當鉤子為系統鉤子時這個參數是必須的,如果是單個程序或者線程使用的鉤子那么可以不用這個值。
dwThreadId -- 線程ID,如果是單個程序或者線程使用的鉤子這個參數是必須的。
在SWT生成的DLL中,并沒有系統鉤子必須用到的hMod,并不像一般的DLL有DllMain入口可以接受到DLL實例句柄。因此我們只要在JNI下的C代碼里添加這個DLL實例句柄就可以完成系統鉤子的功能了:




















































那么通過SWT來實現系統鉤子有多大難度呢?各位看看代碼就知道了:














很簡單吧^_^
我平日是基本上不會用到Linux的,只是有時候測試Java程序的時候才會想到Linux。最近用公司的機器跑了一下RedHat,Ubunut,SUSE三種Linux,基本結論如下:
1、第一感覺
Ubuntu:安裝光盤就1張CD,下載便捷,界面非常好看,令人耳目一新。
Redhat:安裝速度非常快,雖然3張CD,可是耗時卻比Ubuntu還少。
SUSE:說實話,看別人的介紹挺好,自己用就感覺一無是處。10.1還好,9.2連安裝界面都還有問題,我在虛擬機下居然無法圖形界面安裝,說內存太小,暈,最后只能用英文文本形式安裝,中文亂碼。
2、啟動速度
Ubuntu:啟動速度非常快,很快就進入了系統界面,大概因為安裝的是1張CD的緣故,基本上除了需要的服務,其他的都沒有開啟。
Redhat:我也就安裝了核心部分和KDE界面,基本上什么服務都沒有開啟,感覺還行,虛擬機上啟動一次2分鐘左右吧。
SUSE:慢就一個字,真的是很慢。也許默認安裝的服務太多,不過在虛擬機下感覺卡得很厲害,鼠標挪動都很費勁。應該是很耗資源的。(我在虛擬機下給每個操作系統都分配的是768M內存,內存方面應該沒有什么問題的。)
3、界面及易用性
Ubuntu:Ubuntu的界面的確非常好看,按官方的說法是:KDE要趕超蘋果,Gnome要趕超Windows。易用性也非常不錯,和Redhat企業版有得一拼。在命令行模式下,感覺比Redhat更好用,沒有太多的權限問題。而且apt-get使用起來很便捷,方便我這類的初學者。無法使用root登錄界面。
Redhat:這個使用過多次,感覺還行吧。易用性不錯~
SUSE:除了別人的介紹以外,沒什么印象了。
4、開發環境
Ubuntu:我用的是1CD版的,連基本的編譯環境都沒有,一切都要安裝,到最后也沒能通過,說是不能測試出編譯器的版本,大概是GCC版本太高了,默認都是4.1.1的,不過我卸掉重裝3.3的版本,發現依然不行,太麻煩了。
Redhat:一切都沒有問題,我在Radhat下沒有出現過問題。
SUSE:也沒有什么問題,通過。
5、中文化以及輸入法
Ubuntu:令人頭疼的問題,碰到無數次錯誤,小企鵝輸入法也apt-get不到,默認的輸入法又和Firefox不兼容,暈就一個字。不過官方Wiki還是做的很不錯的,美化界面后,字體很好看,和Window一樣了。
Redhat:使用起來沒有問題,沒有專門另外處理過字體問題。
SUSE:沒有試過,基本上沒有在上面用到過中文。
6、自定義操作系統
Ubuntu:基本上都是自定義的,這樣能夠更加美觀易用,挺不錯的,不過最有搞wine的時候,引起系統崩潰,無法進入系統……
Redhat:不需要額外定義,簡單來說,就是挺好用的,而且沒有崩潰過,畢竟是企業版的Redhat ,追求穩定第一。
SUSE:弄了3次,崩潰過3次,大概它的界面系統和我有仇吧。直接放棄~~~
最后我還是選擇了在Redhat上進行開發和使用,但是無法放棄Ubuntu,感覺它實在是做得很不錯,小而精悍,運行速度也快。SUSE直接的讓我無情拋棄,每次都崩潰,誰還敢用呀。不過怎么說呢,它們再好都還是在易用性上比Windows上差很多,命令行的方式對大多數人來說簡直是摧殘。Ubuntu還好一點,可以通過 apt-get remove 方式自動卸載,還有卸載管理器,不過太多的依賴項,讓我對某些軟件包想刪取無法下手,比如那個該死的openOffice,我可是用不到那玩意的。經歷了一個星期的痛苦折磨,我還是回到我的Windows世界吧。
Eclipse UI Forms without JFace and only dependents SWT. ( version: Eclipse 3.3M2 ).?
?
Modify?
Removed some parts which uses JFace and other Eclipse plugins: ?
1.Package org.eclipse.ui.internal.provisional.forms ?
2.Package org.eclipse.ui.forms.editor and some classes which is dependented Eclipse UI Editor.. ?
3.Some classes which is dependented Eclipse UI Part. ?
4.Some codes which is dependented Eclipse JFace action. ?
?
Moved some other plugins's classes to the UI Forms: ?
1.Some Eclipse JFace Resource package classes. ?
2.Some org.eclipse.equinox.common plugin classes. ?
3.Some org.eclipse.core.runtime plugin classes. ?
?
Replaced com.ibm.icu.text.* to java.text.*.
Snapshot
下載地址:https://sourceforge.net/project/showfiles.php?group_id=182187
連續三個月的工作終于over了,手上有了點閑暇的時間,又開始重回舊路,研究一些小玩意。這年頭不缺乏技術,只缺乏創意。有技術有能力的人多的是,有創意的人卻要少多了,能想到創意并實現之的人更是寥寥無幾了。我就是那種最沒有創意的人了,和我GF簡直就是背道而馳~,大概是做技術做過頭的緣故吧。
回頭重新撿起SWT,至從換了工作以后就再也沒有關注過,一直忙著生活上面的事情,工作上的事情都很少有讓我操心的。好不容易有了點閑暇,當然不能浪費。Eclipse每個版本更新都有一些新的東西,所以總能找到好玩的東西。其實我對Eclipse最期望的地方就是它能夠減少插件之間的依賴性,但偏偏它是越做越大,依賴的東西也越大越多。很奇怪的是,它還用了一些IBM或者其他公司提供的項目,是針對Java版重寫的,方法都一樣,只是實現機制不一樣,不知道是出于什么原因,比如com.ibm.icu這個插件。
話說回來IBM還是蠻有創意的,果然是人多力量大,很多好玩的東西都是他們搞出來的,然后其他人受益,就這一點來說,我還是很欣賞IBM的。最近我的工作就是借鑒了org.eclipse.ui.views.properties.tabbed plugin的樣式和架構,實現了界面架構上的多層重用,而且也美觀了許多。Eclipse做到現在這個地步,包含的東西實在是太多了,還有很多好東西都需要挖掘。由于內部人員眾多,代碼編寫水平參差不齊,糟粕與精華并存,而且因為項目越做越大,重構也越來越困難。尤其是底層業務模塊,真的是十指連心,動哪一塊都要付出很大的代價。
前幾天Eclipse五周年生日,公司組織了一次Party,得知原來還是有那么幾個 Eclipse 項目在國內開發的嘛。Eclipse現在有一個項目叫做technology,就是在收集大家的智慧,只要有好的創意,就可以加入其中,各位誰如果有興趣,可以試試哦:-)
有創意就要去實現!
Eclipse 3.2的What's new 正式推出了“The Eclipse Tabbed Properties View”,這個東西以前就是IBM的一個內部項目,最近由于WTP的緣故給開放了出來。有的時候不得不佩服IBM的創意和能力,人多就是力量大。3.2推出了很多新的Feature,都頗有亮點。不知道IBM為這些新的Feature投入了多少人力物力。
Eclipse Tabbed Properties View實際上是對傳統的PropertySheet的一個替換,在Eclipse3.2的new feature中,可以看到一個共同點,那就是界面變得花梢了,Eclipse Tabbed Properties View也是如此。Tab標簽和UI-Form的結合,界面顯得更加清爽。所有的Property都可以自定義編輯界面,重用性也得到了提高,另外還有完美的MVC架構。
實際上Eclipse Tabbed Properties View的代碼我并不會感到陌生,我手頭上的項目關于Property上的架構和它基本一致,都是Element,setInput,createContent,refresh這一套邏輯。不過這段邏輯不是我寫的,不知道是是誰從IBM抄來的,當時抄的是GEF的架構,說是為了保持架構的一致,實際上非常冗余,挖了無數的坑。現在這個Tabbed Properties View走的還是一樣的套路,由此可見IBM內部項目的架構應當非常一致。
Eclipse官方提供了一篇關于Tabbed Properties View的文章:
http://www.eclipse.org/articles/ Article-Tabbed-Properties/tabbed_properties_view.html
,里面的介紹還算詳細。我這兒只說一些它沒有提到的東西。
Tabbed Properties View 的Tab以及Section都定義在Plugin.xml中,這里包含了一個依賴關系,Section依賴于input object,而Tab依賴于Section,于是當我們選中一個element的時候,系統會判斷哪些Section的input object和這個element類型一致。這些Section將會被Property Page加載,每個Section都對應一個Tab,這個Tab會在Section創建之前先創建出來。當Section創建完畢之后,會進行setInput操作,將Model傳給Section,最后在refresh的時候,給Section賦值。
另外一點,一個Section可以對應多個input,這樣不同的input object可以采用同一個Section,提高了系統的可重用性。
不足的地方是Section的enablefor屬性過于簡單,對上下文支持不夠,只能把上下文寫在Section的邏輯里面了。?