亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

SWT行,AWT/Swing也行系列(1)-實現半透明及不規

系統 1760 0
對于Java來說,GUI開發一直都是項比較頭疼的事情。從AWT的功能奇缺,到Swing的臃腫不堪,往如夢魘般困擾著Java開發人員。

于是,有一群人開始走向了邪路……

這群誤入岐途的人(至少Sun是這么認為的……),走出了自己的一條路,名為SWT(Standard Widget Toolkit)的不歸路(Sun,Sun|||)。

說起SWT冒著被詬病為邪惡所換取的,無外以下幾點:

1.徹底摒棄了AWT/Swing,某種意義上甚至架空了JVM,比如其通過dispose()即時釋放資源。(當然,大家也都知道這意味著什么)

2.功能幾乎全用本地系統完成,所以其界面與本地程序界面也高度一致,一改Java GUI的沉悶,令人眼前一亮。

3.支持本地API調用,也就是說無論本地系統能實現什么,都可以通過SWT照樣實現出來。

4.使用"用戶線程"作為唯一線程,只有在這個線程中才能調用對構件或某些圖形API的訪問操作,減少圖形操作時線程錯誤。但也允許間接的在非用戶線程的進行圖形構件的訪問操作。

5.在Windows下運行速度有保證,明顯超越AWT/Swing,且較穩定。

6.目前已有較豐富的組件庫,有JFace等輔助項目,借助于IDE之利,開發GUI程序速度N快……

但是,只所以被稱為邪道,也不是空穴來風,它的缺陷也是顯而易見的,比如:

1.JNI調用耗費的時間是不能忽略的。JNI調用速度要比普通Java方法調用慢好幾倍甚至幾十倍。即便是在Java 6中,這種情況并沒有改善。且Swing絕大部分是用Java平臺模擬出的組件,這個過程都在一個系統平臺內完成。而SWT是部分在本地系統完成,部分在Java平臺完成,進行操作時要在這兩個平臺之間需要進行頻繁的數據交互。SWT并沒有從根本上解決效率問題。

2.Swing可以享受JVM的特殊待遇,進行特殊優化,比如inline,JIT代碼,Swing事件隊列對于事件的預處理(合并Paint事件,批處理Java 2D光柵指令等),這就像本地組件可以利用操作系統進行優化一樣。而SWT由于采用本地操作,無法完成。

3.SWT只能自頂向下地構建GUI。因此,如果沒有父容器,子控件也就不存在,父容器無法在以后任意改變。不如AWT/Swing靈活。

4.在目前來講,SWT還是一個有限的圖形環境(Sun,依舊是Sun)。到目前為止,它對于Java2D和Java3D的支持還不怎么好。

5.SWT在Windows下速度雖快,是占了Microsoft提供的大量API之利,在其他平臺上則持平或較慢于AWT/Swing。

6.與AWT/Swing不同,SWT和JFace并不是Java技術的標準配置,需要在將JAR文件放到Java CLASSPATH中,并將DLL文件放到系統PATH中才能運行,較AWT/Swing更繁瑣,如果某天Sun大神發威,和標準JRE兼容都可能成為問題。

兩種論調勢成水火,各不相下,似乎都要徹底壓到另一方才可罷休。

其實我認為大可不必,使用何種技術,大體上只有開發人員才會關心,技術外的那些才是用戶所關心的。開發人員間再怎么爭辯,其實在外人眼里都是無意義的窩里斗罷了。

比如,SWT可以包含AWT/Swing,而在AWT/Swing下,要實現SWT的功能也是輕而易舉的。

我舉幾個程序的例子。

AWT/Swing與SWT透明窗體實現的比較:

在SWT中,由于高度集成本地環境,能夠完成很多AWT/Swing力所不能及,很Cool的工作,比如半透明的窗體,代碼如下:
package org.loon.framework.dll.test;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.internal.win32.OS;
import org.eclipse.swt.internal.win32.TCHAR;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

/***/ /**
*<p>
*Title:LoonFramework
*</p>
*<p>
*Description:
*</p>
*<p>
*Copyright:Copyright(c)2007
*</p>
*<p>
*Company:LoonFramework
*</p>
*
*
@author chenpeng
*@email:ceponline@yahoo.com.cn
*
@version 0.1
*/

public class SWTTransTest ... {

/***/ /**
*
@param args
*/

public static void main(String[]args) ... {
Displaydisplay
= new Display();

Shellshell
= new Shell(display,SWT.CLOSE);
shell.setSize(
new Point( 400 , 400 ));
shell.setLayout(
new FillLayout());
shell.setText(
" SWT半透明窗體實現 " );

// 打開shell
shell.open();

// 設置窗體透明
OS.SetWindowLong(shell.handle,OS.GWL_EXSTYLE,OS.GetWindowLong(
shell.handle,OS.GWL_EXSTYLE)
^ 0x80000 );
// loadUser32.dlllib
TCHARlpLibFileName = new TCHAR( 0 , " User32.dll " , true );
int hInst = OS.LoadLibrary(lpLibFileName);
if (hInst != 0 ) ... {
// 設定調用函數名稱
Stringname = " SetLayeredWindowAttributes? " ;
byte []lpProcName = new byte [name.length()];
for ( int i = 0 ;i < lpProcName.length;i ++ ) ... {
lpProcName[i]
= ( byte )name.charAt(i);
}

// 檢索DLL輸出函數地址
int fun = OS.GetProcAddress(hInst,lpProcName);
// 當函數存在
if (fun != 0 ) ... {
// 150為透明度,在0-255之間
OS.CallWindowProc(fun,shell.handle, 0 , 150 , 2 );
}

// 釋放lib
OS.FreeLibrary(hInst);

while ( ! shell.isDisposed()) ... {
if ( ! display.readAndDispatch()) ... {
display.sleep();
}


}


}


}

}


效果如圖:

SWT行,AWT/Swing也行系列(1)-實現半透明及不規則窗體

嗯,很簡單,很方便.

不過,似乎有個問題,這些反復出現的OS,不就是封裝的Win32 API嗎?那么,SWT由于依賴本地平臺能夠實現,那么Swing那種"畫"出來的界面可以實現嗎?答案是肯定的,事實上,沒有一種界面不是系統"畫"來的,只要能獲得窗體的hWnd,也就是句柄,任何窗體的操作都是張飛吃豆芽-小菜一碟罷了.

下面,我用AWT/Swing完成同樣的操作.

package org.loon.framework.dll.test;


import java.awt.Frame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JFrame;


import org.loon.framework.dll.NativeLoader;

/***/ /**
*<p>Title:LoonFramework</p>
*<p>Description:AWT/SWing實現真窗體透明</p>
*<p>Copyright:Copyright(c)2007</p>
*<p>Company:LoonFramework</p>
*
@author chenpeng
*@email:ceponline@yahoo.com.cn
*
@version 0.1
*/

public class TransTest ... {
public static void main( final String[]args) ... {

// 助于SetLayeredWindowAttributes函數,
// 在Windows下,AWT/SWing要實現不規則窗體、半透明窗體是非常容易的
JFrameframe = new JFrame( " 透明窗體測試 " );
// Frameframe=newFrame("透明窗體測試");
/**/ /* frame.addWindowListener(newWindowAdapter(){
publicvoidwindowClosing(WindowEventwe){
System.exit(0);
}
});
*/

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(
true );
// NativeLoader為制作好的本地API集合,0.6f為透明度60%顯示
NativeLoader.getInstance().setTransparence(frame, 0.6f );
frame.setSize(
400 , 400 );
frame.setLocationRelativeTo(
null );

}

}



效果圖:

SWT行,AWT/Swing也行系列(1)-實現半透明及不規則窗體

事實上,我們只要在 NativeLoader 中通過當前object在jawt.dll中的運行時hWnd,(即AWT窗體的hWnd,因為Swing底層是AWT,兩者一至),與SWT是沒有任何區別的.

再比如在AWT/Swing中,似乎很難實現真正的不規則窗體,充其量只能做一些"偽不規則窗體",而SWT借助本地支持卻能輕易實現.

AWT/Swing與SWT不規則窗體實現的比較:

比如SWT實現不規則窗體.

package org.loon.framework.dll.test;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;

/***/ /**
*<p>
*Title:LoonFramework
*</p>
*<p>
*Description:
*</p>
*<p>
*Copyright:Copyright(c)2007
*</p>
*<p>
*Company:LoonFramework
*</p>
*
*
@author chenpeng
*@email:ceponline@yahoo.com.cn
*
@version 0.1
*/

public class SWTWindowFrm ... {

private Shellshell;

private Displaydisplay = Display.getDefault();

private Imageimage = null ;

private ImageDataimageData = null ;

public static void main(String[]args) ... {
try ... {
SWTWindowFrmwindow
= new SWTWindowFrm();
window.open();
}
catch (Exceptione) ... {
e.printStackTrace();
}

}


public void open() ... {
createUI();
shell.open();
shell.layout();
while ( ! shell.isDisposed()) ... {
if ( ! display.readAndDispatch())
display.sleep();
}

}


protected void createUI() ... {
shell
= new Shell(display,SWT.NO_TRIM);
shell.setSize(
500 , 375 );
shell.setText(
" SWT實現不規則窗體 " );
createShell();
Listenerlistener
= new Listener() ... {
int startX,startY;

public void handleEvent(Evente) ... {
// 注入鼠標事件
if (e.type == SWT.MouseDown && e.button == 1 ) ... {
startX
= e.x;
startY
= e.y;
}

if (e.type == SWT.MouseMove && (e.stateMask & SWT.BUTTON1) != 0 ) ... {
Pointp
= shell.toDisplay(e.x,e.y);
p.x
-= startX;
p.y
-= startY;
shell.setLocation(p);
}

if (e.type == SWT.Paint) ... {
e.gc.drawImage(image,imageData.x,imageData.y);
}

}

}
;

shell.addListener(SWT.KeyDown,listener);
shell.addListener(SWT.MouseDown,listener);
shell.addListener(SWT.MouseMove,listener);
shell.addListener(SWT.Paint,listener);

}


protected void createShell() ... {

Stringpath
= this .getClass().getResource( " role.gif " ).getPath();
image
= new Image(display, new ImageData(path));
Regionregion
= new Region();
imageData
= image.getImageData();
// 將255(白色)定為透明區域,鏤空
if (imageData.alphaData != null ) ... {
for ( int y = 0 ;y < imageData.height;y ++ ) ... {
for ( int x = 0 ;x < imageData.width;x ++ ) ... {
if (imageData.getAlpha(x,y) == 255 ) ... {
region.add(imageData.x
+ x,imageData.y + y, 1 , 1 );
}

}

}

}
else ... {
ImageDatamask
= imageData.getTransparencyMask();
for ( int y = 0 ;y < mask.height;y ++ ) ... {
for ( int x = 0 ;x < mask.width;x ++ ) ... {
if (mask.getPixel(x,y) != 0 ) ... {
region.add(imageData.x
+ x,imageData.y + y, 1 , 1 );
}

}

}

}

shell.setRegion(region);
shell.setSize(imageData.x
+ imageData.width,imageData.y
+ imageData.height);

}


}


效果圖如下:

SWT行,AWT/Swing也行系列(1)-實現半透明及不規則窗體

但是,AWT/Swing做不到嗎?我已經說過了,只要能得到句柄,就沒有修改不了的窗體存在.而AWT/Swing顯然是可以得到運行時本地句柄的.

下面來個AWT/Swing實現:

package org.loon.framework.dll.test;

import java.awt.Image;
import java.awt.Point;

import java.awt.Window;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.loon.framework.dll.win32.UIWindow;

/***/ /**
*<p>
*Title:LoonFramework
*</p>
*<p>
*Description:
*</p>
*<p>
*Copyright:Copyright(c)2007
*</p>
*<p>
*Company:LoonFramework
*</p>
*
*
@author chenpeng
*@email:ceponline@yahoo.com.cn
*
@version 0.1
*/

// UIWindow為本人提供類,內部已設置255為鏤空色
public class MyJWindow extends UIWindow implements MouseMotionListener,
FocusListener
... {

private static final long serialVersionUID = 1L ;

PointmousePointer;

public MyJWindow(Imageimg) ... {
super (img);
init();

}


public void init() ... {

addMouseMotionListener(
this );
addFocusListener(
this );

}


public void focusGained(FocusEventaFocusEvent) ... {
PointaPoint
= getLocation();
setLocation(
15000 , 0 );

setLocation(aPoint);
}


public void focusLost(FocusEventaFocusEvent) ... {
}


public void mouseDragged(MouseEventaMouseEvent) ... {
PointaPoint
= aMouseEvent.getPoint();
int x = getX() + aPoint.x - mousePointer.x;
int y = getY() + aPoint.y - mousePointer.y;
setLocation(x,y);

}


public void mouseMoved(MouseEventaMouseEvent) ... {
mousePointer
= aMouseEvent.getPoint();
}


public static void main(String[]args) ... {

Stringpath
= MyJWindow. class .getResource( " role.gif " ).getPath();
BufferedImagebackgroundImage
= null ;
try ... {
backgroundImage
= ImageIO.read( new File(path));
}
catch (IOExceptione) ... {
e.printStackTrace();
}

Windowwindow
= new MyJWindow(backgroundImage);
window.setBounds(
0 , 0 ,backgroundImage.getWidth( null ),backgroundImage
.getHeight(
null ));
window.setLocationRelativeTo(
null );
window.setVisible(
true );
window.validate();
}

}


效果如下圖:

SWT行,AWT/Swing也行系列(1)-實現半透明及不規則窗體

兩者有區別嗎?

我們可以從此得知,不,可以說確信,在同樣利用本地API時,SWT與AWT/Swing相比是沒有太大優勢的.而且Sun已經開始優化AWT對本地系統的支持,再不久的將來,SWT可能將沒有任何優勢可言了^^ (我是親Sun一派~)

其中org.loon.framework.dll包下載路徑位于: loonframework-dll

SWT行,AWT/Swing也行系列(1)-實現半透明及不規則窗體


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 人人操天天射 | 亚洲欧美日韩国产精品26u | 欧美一级毛片免费看高清 | 大乳女做爰中文字幕 | 综合九九| 九九草在线观看 | 99ri精品视频在线观看播放 | 免费视频爱爱 | 玖玖精品视频在线 | 在线日韩亚洲 | 奇米777视频 | 狠狠色噜噜狠狠狠狠色综合网 | 一级a俄罗斯毛片免费 | 天天视频入口 | 精品国产一区二区三区久久影院 | 不卡视频在线播放 | 国产精品123区 | 国产永久一区二区三区 | 四虎成人www国产精品 | 97久久综合精品久久久综合 | 中文字幕五月天 | 久久精品视频8 | 成人私人影院在线版 | 久久精品久 | 国产精品亚洲精品观看不卡 | 四虎精品免费视频 | 狠狠狠色丁香婷婷综合久久88 | 97久久人人爽人人爽人人 | 色偷偷亚洲| 97影院九七影院理论片 | 日日日操 | 国产dvd毛片在线视频 | 国产精品久久精品牛牛影视 | 波多野结衣一二三区 | 51毛片| 精品久久免费视频 | 一区二区不卡不卡一卡 | 自拍亚洲午夜伦li片影院 | 九九精品视频在线免费观看 | 国产精品久久久久久久久久妇女 | 国产 magnet |