<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Feeling

        三人行,必有我?guī)熝?/p>

       ::  :: 新隨筆 :: 聯(lián)系 ::  :: 管理 ::
      185 隨筆 :: 0 文章 :: 392 評(píng)論 :: 0 Trackbacks

    #

      最近很多人問(wèn)我SWT Extension 項(xiàng)目上的那個(gè)不需要的JREExample是如何做出來(lái)的。我以前也會(huì)執(zhí)著于這個(gè)問(wèn)題,畢竟如果不依賴于JRE的話,就不需要為用戶準(zhǔn)備一個(gè)容量極大的安裝包,但是這種做法看似有利,實(shí)則有利有弊。

    就我所知,目前把Java程序編譯成本機(jī)可執(zhí)行程序的方法有兩種,一種是GCJ,免費(fèi)的,一種是Excelsior JET,商業(yè)的。我已經(jīng)很久沒(méi)有碰過(guò)GCJ了,因?yàn)楫?dāng)初用起來(lái)實(shí)在是非常麻煩,現(xiàn)在的版本如何,我不太清楚。我自己使用的是Excelsior JET,版本為3.7。有一點(diǎn)要注意的的是,Excelsior JET的后續(xù)版本好像已經(jīng)不支持這個(gè)功能了,3.7是我所知的最后一個(gè)版本,能支持當(dāng)前所有的Win32平臺(tái)和早期的Linux(當(dāng)前比較流行的Ubuntu不支持,因?yàn)閮?nèi)核版本過(guò)高,不過(guò)企業(yè)版Redhat沒(méi)有問(wèn)題)。不過(guò)我是很久以前從0day當(dāng)下來(lái)的,由于0day倉(cāng)儲(chǔ)只保留一年,故現(xiàn)在已經(jīng)找不到了,我自己的機(jī)器上也沒(méi)有安裝包了(有一次大意之下,把整個(gè)Download目錄全給刪掉了,事后悔之晚矣)。

    Excelsior JET無(wú)非就是用自己的Runtime來(lái)代替JRE,只是比JRE更加靈活,根據(jù)Java程序具體的依賴來(lái)生成對(duì)應(yīng)的Runtime。其實(shí)這個(gè)Runtime也挺大的,通常10M左右,不過(guò)比起JRE,那要小很多了。SWT Extension上的那個(gè)例子只有6M,是因?yàn)槲矣?/span>ASPack把所有的DLL文件全部壓縮過(guò)了,體積小了一半。

    就我的感覺(jué),Excelsior JETGCJ更加靈活,也更好用,畢竟是商業(yè)版的東西,它的網(wǎng)站上曾經(jīng)有例子將Eclipse 3.0編譯成本機(jī)程序,不過(guò)我當(dāng)初照著例子試了一遍,沒(méi)有成功。Excelsior JET的編譯過(guò)程極為耗時(shí),我上大學(xué)的時(shí)候,當(dāng)時(shí)機(jī)器只有128M內(nèi)存,編譯了一天JRE也沒(méi)有完成,后來(lái)找同學(xué)借了根256的內(nèi)存,這才得以完成。

    JAVA代碼編譯成本機(jī)程序的弊端也是有的,那意味著你將無(wú)法在線升級(jí),GCJ也許可以,但是Excelsior JET是絕對(duì)不行的,這是因?yàn)樗詈笠徊揭獙?duì)所有DLL進(jìn)行鏈接,如果更換了DLL文件,它會(huì)檢測(cè)出來(lái)并報(bào)錯(cuò)。

    各位看官如果哪位有興趣,可以自行在網(wǎng)上查找Excelsior JET3.7或其他版本。由于安裝包我自己也沒(méi)有,故無(wú)法提供下載,見諒。

    posted @ 2008-05-18 15:38 三人行,必有我?guī)熝?閱讀(6829) | 評(píng)論 (7)編輯 收藏

    在SWT Extension中,引入了Function這個(gè)類。基本上所有的Win32 JNI庫(kù)都有這個(gè)類,用來(lái)直接操縱Win32 的部分API。有了這個(gè)Class,我們不用編寫JNI,就可以實(shí)現(xiàn)某些簡(jiǎn)單的,甚至是較復(fù)雜的Win32 API。這里我們就以EnumWindows這個(gè)API舉例,看看怎么Java來(lái)執(zhí)行這個(gè)Win32 API。
        private static final String FUNTION_ENUMWINDOWS = "EnumWindows";
        
    private static final String USER32_LIB = "user32";
        
    private static List windowsList = new ArrayList();
        
        
    public static int[] enumWindows()
        {
            windowsList.clear();
            Callback callback 
    = new Callback(Windows.class"enumWindowsProc"2);
            
    int address = callback.getAddress();
            
    if (address != 0)
            {
                
    try
                {
                    Function function 
    = new Function(USER32_LIB, FUNTION_ENUMWINDOWS);
                    function.invoke_I(address, 
    0);
                    function.close();
                } 
    catch (Exception e)
                {
                    SWT.error(SWT.ERROR_INVALID_ARGUMENT);
                }
                callback.dispose();
            }
            
    int[] handles = new int[windowsList.size()];
            
    for (int i = 0; i < windowsList.size(); i++)
                handles[i] 
    = ((LONG) windowsList.get(i)).value;
            
    return handles;
        }

        
    private static int enumWindowsProc(int hwnd, int lParam)
        {
            windowsList.add(
    new LONG(hwnd));
            
    return 1;
        }
    EnumWindows是用來(lái)遍歷Windows窗口的API,它需要傳入一個(gè)返回boolean值的callback的地址作為參數(shù)。實(shí)際上在C里面,一個(gè)boolean值無(wú)非就是是否非0,如果為0,則為false,不為0,則為true。我們只需要new 一個(gè)function實(shí)例,傳入這個(gè)API所在的Lib和API名字,然后執(zhí)行invoke方法就OK了,在Function里面,可以最多執(zhí)行含有4個(gè)簡(jiǎn)單類型參數(shù)的API。

    讓我們?cè)賮?lái)看看FindWindowEx這個(gè)API,它需要傳入2個(gè)int變量和2個(gè)字符串指針,根據(jù)SWT的設(shè)計(jì),我們是可以將Java的字符串轉(zhuǎn)換為指針的,因此通過(guò)Function我們也可以實(shí)現(xiàn)這個(gè)API:
        private static final String FUNTION_FINDWINDOWEX = Extension.IsUnicode ? "FindWindowExW"
                : 
    "FindWindowExA";
        
    private static final String USER32_LIB = "user32";
        
        
    public static int findWindowEx(int parent, int hwndChildAfter, String className,
                String windowName)
        {
            
    int result = 0;
            
    int lpClassName = 0;
            
    int lpWindowName = 0;
            
    int hHeap = Extension.GetProcessHeap();

            
    if (className != null)
            {
                TCHAR buffer 
    = new TCHAR(0, className, true);
                
    int byteCount = buffer.length() * TCHAR.sizeof;
                lpClassName 
    = Extension.HeapAlloc(hHeap, Extension.HEAP_ZERO_MEMORY, byteCount);
                Extension.MoveMemory(lpClassName, buffer, byteCount);
            }
            
    if (windowName != null)
            {
                TCHAR buffer 
    = new TCHAR(0, windowName, true);
                
    int byteCount = buffer.length() * TCHAR.sizeof;
                lpWindowName 
    = Extension.HeapAlloc(hHeap, Extension.HEAP_ZERO_MEMORY, byteCount);
                Extension.MoveMemory(lpWindowName, buffer, byteCount);
            }

            
    try
            {
                Function function 
    = new Function(USER32_LIB, FUNTION_FINDWINDOWEX);
                result 
    = function.invoke_I(parent, hwndChildAfter, lpClassName, lpWindowName);
                function.close();
            } 
    catch (Exception e)
            {
                SWT.error(SWT.ERROR_INVALID_ARGUMENT);
            }
            
    if (lpClassName != 0) Extension.HeapFree(hHeap, 0, lpClassName);
            
    if (lpWindowName != 0) Extension.HeapFree(hHeap, 0, lpWindowName);
            
    return result;
        }
    其實(shí)像這種簡(jiǎn)單參數(shù)類型的API,Win32 里還有很多,我們完全不必為其專門編寫JNI,只需使用熟悉的Java即可。雖然不是調(diào)用全部的API,但大部分常用的API都是沒(méi)有問(wèn)題的,關(guān)鍵是如何靈活運(yùn)用。現(xiàn)在的大型商業(yè)RCP應(yīng)用中,其實(shí)多多少少都參和了JNI,用于提升對(duì)用戶的友好性和軟件的執(zhí)行性能,畢竟Java天生就是客戶端開發(fā)的矮子。對(duì)于JNI,我們既不能一味排斥,也不能濫用,要把握一個(gè)平衡點(diǎn),使之成為Java客戶端開發(fā)的利器。
    posted @ 2008-05-11 19:31 三人行,必有我?guī)熝?閱讀(5833) | 評(píng)論 (7)編輯 收藏

    網(wǎng)上有一篇關(guān)于JNI中文問(wèn)題的文章,寫得很詳細(xì),http://www.vckbase.com/document/viewdoc/?id=1611

    我在這里主要是想說(shuō)說(shuō)我碰到的一些問(wèn)題,并且希望能從各位老大身上獲得答案。

    因?yàn)橐恢睆氖翵ava編程,基本上沒(méi)有涉及過(guò)C++的開發(fā),最近因?yàn)殚_源項(xiàng)目SWT Extension,不得已需要用JNI來(lái)實(shí)現(xiàn)一些系統(tǒng)Native功能。但是總是需要一些Java字符串對(duì)應(yīng)C++的字符串的問(wèn)題。一邊情況下我都是使用SWT的TCHAR來(lái)解決問(wèn)題,少部分情況需要傳遞Java String到JNI。然而少部分的這些Case總是在某些問(wèn)題下出現(xiàn)亂碼或者異常。我一直使用的是網(wǎng)上比較流行的中文編碼解決方案:
    char* jstringToNative( JNIEnv  *env, jstring jstr )
    {
      
    int length = env->GetStringLength(jstr );
      
    const jchar* jcstr = env->GetStringChars(jstr, 0 );
      
    char* rtn = (char*)malloc( length*2+1 );
      
    int size = 0;
      size 
    = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)jcstr, length, rtn,(length*2+1), NULL, NULL );
      
    if( size <= 0 )return NULL;
      env
    ->ReleaseStringChars(jstr, jcstr );
      rtn[size] 
    = 0;
      
    return rtn;
    }

    jstring nativeTojstring( JNIEnv
    * env, char* str )
    {
      jstring rtn 
    = 0;
      
    int slen = strlen(str);
      unsigned 
    short * buffer = 0;
      
    if( slen == 0 )
        rtn 
    = env->NewStringUTF( str ); 
      
    else
      {
        
    int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 );
        buffer 
    = (unsigned short *)malloc( length*2 + 1 );
        
    if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length ) >0 )
          rtn 
    = env->NewString(  (jchar*)buffer, length );
      }
      
    if( buffer )
      free( buffer );
      
    return rtn;
    }

    一般情況下,這兩個(gè)函數(shù)能夠很好的工作。但是在讀寫注冊(cè)表時(shí),如果一個(gè)key的名字或者value的名字中包含了中文,jstringToNative的解決方案是不正確的,我在網(wǎng)上查了一下其它的關(guān)于Java訪問(wèn)注冊(cè)表的開源項(xiàng)目,發(fā)現(xiàn)雖然它們都對(duì)字符串進(jìn)行了處理,但依然存在著中文問(wèn)題。我進(jìn)行了數(shù)次嘗試,但都沒(méi)有成功。最后到了已經(jīng)絕望的時(shí)候,用開頭我提到的那篇文章中里說(shuō)的最不可能用到的方法將問(wèn)題成功地解決了:
    char* jstringToNative( JNIEnv  *env, jstring jstr )
    {
      
    const char* pstr = env->GetStringUTFChars(jstr, false);
      
    int nLen = MultiByteToWideChar( CP_UTF8, 0, pstr, -1, NULL, NULL );
      LPWSTR lpwsz 
    = new WCHAR[nLen];    
      MultiByteToWideChar( CP_UTF8, 
    0, pstr, -1, lpwsz, nLen );
      
    int nLen1 = WideCharToMultiByte( CP_ACP, 0, lpwsz, nLen, NULL, NULL, NULL, NULL );    
      LPSTR lpsz 
    = new CHAR[nLen1];
      
    int size = 0;
      size 
    = WideCharToMultiByte( CP_ACP, 0, lpwsz, nLen, lpsz, nLen1, NULL, NULL );
      
    if( size <= 0 ){
          delete [] lpwsz;
          
    return NULL;
      }
      env
    ->ReleaseStringUTFChars(jstr, pstr );
      delete [] lpwsz;
      
    return lpsz;
    }
    問(wèn)題雖然解決了,但是我卻不求甚解,為什么直接通過(guò)env拿到unicode字串,然后轉(zhuǎn)成多字節(jié)串不行,但是通過(guò)env拿到utf-8字串,然后轉(zhuǎn)成unicode字串,再將這個(gè)unicode字串轉(zhuǎn)成多字節(jié)串就能工作?

    如果大家有興趣的話,不妨試試,用JNI調(diào)用RegOpenKeyEx這個(gè)API,就能驗(yàn)證我說(shuō)的這個(gè)Case。哪位老大對(duì)JNI比較在行的話,可以在評(píng)論中告訴我,不甚感激。
    posted @ 2008-05-04 13:17 三人行,必有我?guī)熝?閱讀(4031) | 評(píng)論 (2)編輯 收藏

    Glossy 效果,顧名思義,就是玻璃質(zhì)的光澤透明的效果,在Windows平臺(tái)下的應(yīng)用越來(lái)越廣泛,從Media Player10開始,它的button已經(jīng)運(yùn)用上了此效果。現(xiàn)在但凡是微軟新發(fā)布的軟件,十有八九都帶有g(shù)lossy特效。Glossy 效果使用了Gdi Plus的API,因此在Win98和Win2000下,必須安裝gdiplus.dll才能使用,此動(dòng)態(tài)鏈接庫(kù)不大,只有700多K,但是想要在自己的應(yīng)用程序中畫出絢麗多彩的效果,那是少不了這個(gè)小東西的。關(guān)于Glossy效果的描述,可以參見CodeProject上的一片文章WindowsVistaRenderer,http://www.codeproject.com/KB/vista/WindowsVistaRenderer.aspx

    Glossy特效有一個(gè)重要的組成部分,就是橢圓的光暈,此效果在Linux下可能并沒(méi)有實(shí)現(xiàn)(并未下定論,我還沒(méi)有深入研究過(guò)Linux下的圖形庫(kù)), 所以SWT的Gdip并沒(méi)有將其公開出來(lái),而是放入custom的API里,也就是說(shuō),你可以自行調(diào)用此效果的API,但是SWT并不負(fù)責(zé)為你提供封裝, 因此你并不能使用GC來(lái)實(shí)現(xiàn)該特效,這對(duì)我們的界面開發(fā)極為不利,自己調(diào)用Gdip的API,繁瑣不說(shuō),還很容易導(dǎo)致JVM退出。

    為了能夠方便的使用GC來(lái)畫出此特效,我們不得不采用一些非常規(guī)的手段:反射。利用反射我們可以拿到GC的一些內(nèi)部數(shù)據(jù),在這個(gè)地方,我們只需要拿到GCData就可以,它包含了畫圖所需要具備的元素。Glossy效果需要使用PathGradientBrush,我們把這個(gè)刷子賦給GCData,就可以使用GC來(lái)畫出glossy特效了。
     1 public class GCExtension {
     2 
     3     private GC gc;
     4 
     5     private GCData data;
     6 
     7     public GCExtension(GC gc) {
     8         this.gc = gc;
     9         data = getGCData(gc);
    10     }
    11 
    12     public void fillGradientPath(Path path, float[] centerPoint,
    13             Color centerColor, int centerColorAlpha, Color[] surroundColors,
    14             int[] surroundColorAlphas) {
    15         if (gc == null || gc.handle == 0)
    16             SWT.error(SWT.ERROR_GRAPHIC_DISPOSED);
    17         if (path == null || centerPoint == null || centerColor == null
    18                 || surroundColorAlphas == null)
    19             SWT.error(SWT.ERROR_NULL_ARGUMENT);
    20         if (path.handle == 0 || centerPoint.length < 2
    21                 || centerColor.handle == 0
    22                 || surroundColors.length != surroundColorAlphas.length)
    23             SWT.error(SWT.ERROR_INVALID_ARGUMENT);
    24         for (int i = 0; i < surroundColors.length; i++) {
    25             if (surroundColors[i] == null || surroundColors[i].handle == 0)
    26                 SWT.error(SWT.ERROR_INVALID_ARGUMENT);
    27         }
    28 
    29         int brush = Gdip.PathGradientBrush_new(path.handle);
    30         if (brush == 0)
    31             SWT.error(SWT.ERROR_NO_HANDLES);
    32         PointF point = new PointF();
    33         point.X = centerPoint[0];
    34         point.Y = centerPoint[1];
    35         Gdip.PathGradientBrush_SetCenterPoint(brush, point);
    36 
    37         int colorRef = centerColor.handle;
    38         int rgb = ((colorRef >> 16& 0xFF| (colorRef & 0xFF00)
    39                 | ((colorRef & 0xFF<< 16);
    40         int color = Gdip.Color_new(centerColorAlpha << 24 | rgb);
    41         if (color == 0)
    42             SWT.error(SWT.ERROR_NO_HANDLES);
    43         Gdip.PathGradientBrush_SetCenterColor(brush, color);
    44         Gdip.Color_delete(color);
    45 
    46         int[] colors = new int[surroundColors.length];
    47         for (int i = 0; i < surroundColors.length; i++) {
    48             colorRef = surroundColors[i].handle;
    49             rgb = ((colorRef >> 16& 0xFF| (colorRef & 0xFF00)
    50                     | ((colorRef & 0xFF<< 16);
    51             colors[i] = Gdip.Color_new(surroundColorAlphas[i] << 24 | rgb);
    52             if (colors[i] == 0)
    53                 SWT.error(SWT.ERROR_NO_HANDLES);
    54         }
    55         Gdip.PathGradientBrush_SetSurroundColors(brush, colors,
    56                 new int[] { colors.length });
    57         for (int i = 0; i < surroundColors.length; i++) {
    58             Gdip.Color_delete(colors[i]);
    59         }
    60         data.gdipBrush = brush;
    61         boolean advanced = gc.getAdvanced();
    62         if (!advanced)
    63             gc.setAdvanced(true);
    64         int mode = Extension.GetPolyFillMode(gc.handle) == Extension.WINDING ? Gdip.FillModeWinding
    65                 : Gdip.FillModeAlternate;
    66         Gdip.GraphicsPath_SetFillMode(path.handle, mode);
    67         Gdip.Graphics_FillPath(data.gdipGraphics, data.gdipBrush, path.handle);
    68         if (!advanced)
    69             gc.setAdvanced(false);
    70         if (data.gdipBrush != 0) {
    71             Gdip.PathGradientBrush_delete(data.gdipBrush);
    72             data.gdipBrush = 0;
    73         }
    74     }
    75 
    76     private GCData getGCData(GC gc) {
    77         GCData data = null;
    78         try {
    79             Object obj = null;
    80             Field field = gc.getClass().getDeclaredField("data");
    81             if (field != null) {
    82                 field.setAccessible(true);
    83                 obj = field.get(gc);
    84             }
    85             if (obj != null && obj instanceof GCData)
    86                 data = (GCData) obj;
    87         } catch (Exception e) {
    88 
    89         }
    90         return data;
    91     }
    92 }

    特效截圖:

    posted @ 2008-04-30 15:54 三人行,必有我?guī)熝?閱讀(3547) | 評(píng)論 (3)編輯 收藏

    SWT Win32 Extension寫到現(xiàn)在的狀況,在win32 natvie上面已經(jīng)沒(méi)有太多花樣了,常用的一些功能我都已經(jīng)做得差不多了,現(xiàn)在主要是做一些自定義的控件,就目前的進(jìn)度,還只是完成了Shell,Menu,ToolBar 3個(gè)部分,還有很多內(nèi)容可以慢慢完善。不過(guò)自從發(fā)布了自定義的菜單以后,SWT Win32 Extension的用戶群大增,也對(duì)我提出了更高的要求。不過(guò)現(xiàn)在的主要任務(wù)是實(shí)現(xiàn)功能,因此代碼的質(zhì)量上肯定是差了點(diǎn)。現(xiàn)有的接口都是我自己通過(guò)Example的需求來(lái)加的,以后等功能做的完善上,再將現(xiàn)有的架構(gòu)進(jìn)行較大的重構(gòu),我想應(yīng)該是一個(gè)不錯(cuò)的步驟。畢竟就我一個(gè)人做這個(gè)東西,還要兼職寫Example,Document,測(cè)試,網(wǎng)站維護(hù),雖然每天都在加班加點(diǎn),但還是感覺(jué)時(shí)間不夠用。每天都有用戶發(fā)郵件來(lái)催進(jìn)度,所以維護(hù)這個(gè)項(xiàng)目現(xiàn)在真的是讓我廢寢忘食了,但總體來(lái)說(shuō)還是物有所值,畢竟辛辛苦苦的努力,還是有所回報(bào)的。開源嘛,本來(lái)就是一種奉獻(xiàn)精神,回饋社會(huì),讓所有人都來(lái)分享自己的成果。

    這些天一直忙著寫新的Feature,今天寫的差不多了,于是回過(guò)頭來(lái)整理Example。本來(lái)上個(gè)版本我就想接管Eclipse Native的菜單,不過(guò)沒(méi)能如愿,因?yàn)镋clipse的菜單都是LazyLoad的。今天又嘗試了一下,終于成功的實(shí)現(xiàn)了這個(gè)功能。做完了才知道其實(shí)很簡(jiǎn)單,所遇到的重重障礙只不過(guò)是因?yàn)樽约旱目蚣芾鲜潜某鲂碌腷ug。唉,自己測(cè)試自己開發(fā)的東西總是有盲點(diǎn)存在,實(shí)在是無(wú)能為力呀。

    從本質(zhì)上來(lái)說(shuō),我自定義的菜單和標(biāo)準(zhǔn)菜單控件的代碼及事件上的實(shí)現(xiàn)基本一致,所以接管Eclipse原生的菜單并不是一件很難的事情,當(dāng)自定義的菜單接收到一個(gè)事件的時(shí)候,只需將這個(gè)事件轉(zhuǎn)發(fā)給Eclipse的原生菜單就好了,一切就是這么簡(jiǎn)單。重點(diǎn)就是Notify SWT.Selected 和 SWT.Show 事件,前者用來(lái)觸發(fā)Action的行為,后者用來(lái)觸發(fā)Eclipse原生菜單的LazyLoad。

    截圖如下:
    posted @ 2008-04-20 20:37 三人行,必有我?guī)熝?閱讀(3383) | 評(píng)論 (4)編輯 收藏


    The idea is from DotnetMagic, I copied its style, but different implement methods. DotnetMagic uses shell self message circulation, but I use swt event listener. I want to implement the custom style menu for all platforms initially, but it's impossible. It has to use a lot of advanced OS funcitions. If I use pure swt public functions, I can't implement  some features. For example, if I click the menu, the window shell will be deactivated, I click window shell's titlebar, swt event manager doesn't send messages to me. I must use WND Message hook to deal these messages. So I have to add the feature into SWT Win32 Extension, but not a independent project.

    Some beautiful snapshots:


    Office 2003 Style Menu


    VS 2005 Style Menu


    Project Download: http://www.swtui.cn/downloads/org.eclipse.swt.win32.extension.zip
    JNLP Online Demo: http://www.swtui.cn/jws/example.jnlp

    If you don't have installed Java Runtime, you can access it via http://www.swtui.cn/downloads/org.eclipse.swt.win32.extension.example.independence_native.zip

    Eclipse Plugin Update Site URL: http://www.swtui.cn/update

     

    posted @ 2008-04-02 11:25 三人行,必有我?guī)熝?閱讀(3135) | 評(píng)論 (5)編輯 收藏

    Add Flash Control to SWT Win32 Extension, now you can check out the latest code from CVS and run it.

    Project Main Page: http://www.swtui.cn

    cvs -d:pserver:anonymous@feeling.cvs.sourceforge.net:/cvsroot/feeling login



    Flash Control Listener   


    Flash Control Hook Interceptor

     

    posted @ 2008-03-14 22:00 三人行,必有我?guī)熝?閱讀(2654) | 評(píng)論 (0)編輯 收藏

    在SWT Win32 Extension 中新添加了窗口系統(tǒng)菜單管理功能,現(xiàn)在可以自定義窗口系統(tǒng)菜單了。
    posted @ 2008-03-10 20:38 三人行,必有我?guī)熝?閱讀(2269) | 評(píng)論 (0)編輯 收藏

    窗口是一個(gè)應(yīng)用程序的門面,有一個(gè)好看的窗口,用戶的評(píng)價(jià)自然也會(huì)大大提高,經(jīng)過(guò)幾天的努力,終于在SWT Win32 Extension中加入了自定義的Window Theme,當(dāng)然目前只完成了一些基本的實(shí)現(xiàn),高級(jí)實(shí)現(xiàn)依然有待于研究。


    Windows XP Theme


    Custom Theme

      目前已完成了任意SWT Shell wrapper,系統(tǒng)菜單管理,不規(guī)則邊框的切邊等功能,尚未完成的功能還有很多,比如窗口菜單。未來(lái)準(zhǔn)備加入用戶自定義Theme的接口,只要符合規(guī)范都可以進(jìn)行自動(dòng)切換。由于功能仍然還有很多地方尚未完成,暫時(shí)還沒(méi)有提供打包下載,有興趣的話,可以從項(xiàng)目CVS上Checkout出來(lái)看看效果。

    cvs -d:pserver:anonymous@feeling.cvs.sourceforge.net:/cvsroot/feeling login
    posted @ 2008-01-15 14:25 三人行,必有我?guī)熝?閱讀(2815) | 評(píng)論 (0)編輯 收藏

    做Java UI的人應(yīng)該都很熟悉Look and Feel,Swing擁有的這個(gè)功能的確是相對(duì)于SWT的一個(gè)巨大優(yōu)勢(shì)。不過(guò)SWT的GC也可以畫出自己的UI,前提是這個(gè)控件是Custom的,而不是系統(tǒng)級(jí)的。Eclipse Presentation 就是對(duì)eclipse本身UI提供的一個(gè)擴(kuò)展。本來(lái)我還對(duì)這個(gè)擴(kuò)展很友好的,不過(guò)現(xiàn)在覺(jué)得真是一鍋粥里掉了個(gè)老鼠屎,完全變了味道。

    由于閑來(lái)無(wú)視,把一個(gè)1年半前一個(gè)德國(guó)人寫的Eclipse VS L&F Plugin down了下來(lái),無(wú)奈bug太多,用戶體驗(yàn)也和我個(gè)人感覺(jué)不一致,索性就把代碼check out 出來(lái),作了一些本地修改。不過(guò)讓我吐血的地方就是,如果我從eclipse default L&F 切換到這個(gè)L&F,就問(wèn)題一堆,從其它的L&F切換就沒(méi)有問(wèn)題。Debug了半天,毫無(wú)進(jìn)展,只是發(fā)現(xiàn)很多地方都是Null Exception。于是把Eclipse 2.2 L&F的代碼翻了出來(lái),經(jīng)過(guò)仔細(xì)對(duì)照,還是沒(méi)有找到解決的方案,我就感覺(jué)怪怪的,也不知道哪兒出了問(wèn)題,覺(jué)得大概是自己沒(méi)有把Presentation的代碼吃透的原因。于是又回頭開始一行行的從有問(wèn)題的代碼處開始Debug,看看我的代碼和2.2L&F的代碼在運(yùn)行時(shí)到底有什么區(qū)別,終于功夫不負(fù)有心人,我發(fā)現(xiàn)這個(gè)代碼片斷:
        /**
         * Sets the minimized state for this stack. The part may call this method to
         * minimize or restore itself. The minimized state only affects the view
         * when unzoomed.
         *
         * This implementation is specific to the 3.3 presentation's
         * min/max story; otherwise it just forwards the call.
         
    */

        
    public void setMinimized(boolean minimized) {
            
    // 'Smart' minimize; move the stack to the trim

            Perspective persp = getPage().getActivePerspective();
            
    if (Perspective.useNewMinMax(persp)) 
    {
    原來(lái)3.3的L&F做了專門處理,而我的代碼和3.3是一致的,和 2.2L&F是不一致的,不過(guò)我找了半天,也沒(méi)有在2.2L&F的代碼里找出異樣之處,暈的不行。唯一的線索就是
    boolean useNewMinMax = preferenceStore.getBoolean(IWorkbenchPreferenceConstants.ENABLE_NEW_MIN_MAX);

    可惡的是,IWorkbenchPreferenceConstants.ENABLE_NEW_MIN_MAX 這個(gè)靜態(tài)常量是無(wú)法在項(xiàng)目里找到eclipse自身的引用。2.2L&F plugin里也沒(méi)有,該死的eclipse肯定是寫死在代碼里了。于是翻出editplus,對(duì)eclipse ui workbench的代碼多文件搜索了一把,然后開始吐血,它居然把所有的L&F的配置都寫在UI Workbench的Preference Page里,這還算什么插件,根本就沒(méi)有把擴(kuò)展的接口給出來(lái),還是很重要的一個(gè)配置。其實(shí)2.2L&F以前只是它的一個(gè)內(nèi)部package,后來(lái)重構(gòu)成一個(gè)plugin,3.0L&F到現(xiàn)在依然還是一個(gè)package。不過(guò)我想既然2.2L&F做成插件了,怎么也改和系統(tǒng)獨(dú)立開來(lái)呀,現(xiàn)在這樣就成了一個(gè)半吊子的plugin.

    Eclipse終于被我bs了一把^_^,林子大了,什么鳥都有。


    改過(guò)之后L&F自己覺(jué)得好用了不少

     

    posted @ 2007-12-25 19:19 三人行,必有我?guī)熝?閱讀(3558) | 評(píng)論 (5)編輯 收藏

    僅列出標(biāo)題
    共9頁(yè): 上一頁(yè) 1 2 3 4 5 6 7 8 9 下一頁(yè) 
    GitHub |  開源中國(guó)社區(qū) |  maven倉(cāng)庫(kù) |  文件格式轉(zhuǎn)換 
    主站蜘蛛池模板: 免费AA片少妇人AA片直播| 无码少妇精品一区二区免费动态| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 久久久久久久久久免免费精品| 成全高清在线观看免费| 18女人水真多免费高清毛片| 天天看免费高清影视| 亚洲国产综合精品一区在线播放| 久久久久亚洲AV无码专区首| tom影院亚洲国产一区二区| 青草青草视频2免费观看| 四虎国产精品免费永久在线| 国产精品久久免费| 免费在线视频一区| 亚洲av无码乱码国产精品| 亚洲a视频在线观看| 免费一级做a爰片久久毛片潮| 毛片在线全部免费观看| 猫咪社区免费资源在线观看 | 国产亚洲AV无码AV男人的天堂| 亚洲精品自在线拍| 国产成人亚洲精品播放器下载| 你懂的免费在线观看| 啦啦啦中文在线观看电视剧免费版 | 337p日本欧洲亚洲大胆精品555588 | 成年性午夜免费视频网站不卡| 亚洲一区视频在线播放| 亚洲欧洲日本国产| 一日本道a高清免费播放| 猫咪免费人成网站在线观看| 亚洲&#228;v永久无码精品天堂久久 | 2020国产精品亚洲综合网| 精品无码国产污污污免费网站国产 | 免费无码VA一区二区三区| 午夜毛片不卡高清免费| 亚洲成色999久久网站| 亚洲AV成人无码网天堂| 永久在线免费观看| 色噜噜亚洲精品中文字幕| 最新亚洲精品国偷自产在线| 免费在线看污视频|