对于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的工作,比如半透明的窗体,代码如下:
效果如图:
嗯,很简单,很方便.
不过,似乎有个问题,这些反复出现的OS,不就是封装的Win32 API吗?那么,SWT由于依赖本地平台能够实现,那么Swing那种"画"出来的界面可以实现吗?答案是肯定的,事实上,没有一种界面不是系统"画"来的,只要能获得窗体的hWnd,也就是句柄,任何窗体的操作都是张飞吃豆芽-小菜一碟罢了.
下面,我用AWT/Swing完成同样的操作.
效果图:
事实上,我们只要在 NativeLoader 中通过当前object在jawt.dll中的运行时hWnd,(即AWT窗体的hWnd,因为Swing底层是AWT,两者一至),与SWT是没有任何区别的.
再比如在AWT/Swing中,似乎很难实现真正的不规则窗体,充其量只能做一些"伪不规则窗体",而SWT借助本地支持却能轻易实现.
AWT/Swing与SWT不规则窗体实现的比较:
比如SWT实现不规则窗体.
效果图如下:
但是,AWT/Swing做不到吗?我已经说过了,只要能得到句柄,就没有修改不了的窗体存在.而AWT/Swing显然是可以得到运行时本地句柄的.
下面来个AWT/Swing实现:
效果如下图:
两者有区别吗?
我们可以从此得知,不,可以说确信,在同样利用本地API时,SWT与AWT/Swing相比是没有太大优势的.而且Sun已经开始优化AWT对本地系统的支持,再不久的将来,SWT可能将没有任何优势可言了^^ (我是亲Sun一派~)
其中org.loon.framework.dll包下载路径位于: loonframework-dll
于是,有一群人开始走向了邪路……
这群误入岐途的人(至少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();
}
}
}
}
}
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();
}
}
}
}
}
效果如图:
嗯,很简单,很方便.
不过,似乎有个问题,这些反复出现的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 );
}
}
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 );
}
}
效果图:
事实上,我们只要在 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);
}
}
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);
}
}
效果图如下:
但是,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();
}
}
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();
}
}
效果如下图:
两者有区别吗?
我们可以从此得知,不,可以说确信,在同样利用本地API时,SWT与AWT/Swing相比是没有太大优势的.而且Sun已经开始优化AWT对本地系统的支持,再不久的将来,SWT可能将没有任何优势可言了^^ (我是亲Sun一派~)
其中org.loon.framework.dll包下载路径位于: loonframework-dll