對于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) {
Display display = new Display();

Shell shell = 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);
// load User32.dll lib
TCHAR lpLibFileName = new TCHAR(0, "User32.dll", true);
int hInst = OS.LoadLibrary(lpLibFileName);
if (hInst != 0) {
// 設定調用函數名稱
String name = "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要實現不規則窗體、半透明窗體是非常容易的
JFrame frame = new JFrame("透明窗體測試");
//Frame frame = new Frame("透明窗體測試");
/*frame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent we){
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 Shell shell;

private Display display = Display.getDefault();

private Image image = null;

private ImageData imageData = null;

public static void main(String[] args) {
try {
SWTWindowFrm window = new SWTWindowFrm();
window.open();
} catch (Exception e) {
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();
Listener listener = new Listener() {
int startX, startY;

public void handleEvent(Event e) {
// 注入鼠標事件
if (e.type == SWT.MouseDown && e.button == 1) {
startX = e.x;
startY = e.y;
}
if (e.type == SWT.MouseMove && (e.stateMask & SWT.BUTTON1) != 0) {
Point p = 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() {

String path = this.getClass().getResource("role.gif").getPath();
image = new Image(display, new ImageData(path));
Region region = 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 {
ImageData mask = 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;

Point mousePointer;

public MyJWindow(Image img) {
super(img);
init();

}

public void init() {

addMouseMotionListener(this);
addFocusListener(this);

}

public void focusGained(FocusEvent aFocusEvent) {
Point aPoint = getLocation();
setLocation(15000, 0);

setLocation(aPoint);
}

public void focusLost(FocusEvent aFocusEvent) {
}

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

}

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

public static void main(String[] args) {

String path = MyJWindow.class.getResource("role.gif").getPath();
BufferedImage backgroundImage = null;
try {
backgroundImage = ImageIO.read(new File(path));
} catch (IOException e) {
e.printStackTrace();
}
Window window = 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
于是,有一群人開始走向了邪路……
這群誤入岐途的人(至少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) {
Display display = new Display();
Shell shell = 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);
// load User32.dll lib
TCHAR lpLibFileName = new TCHAR(0, "User32.dll", true);
int hInst = OS.LoadLibrary(lpLibFileName);
if (hInst != 0) {
// 設定調用函數名稱
String name = "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要實現不規則窗體、半透明窗體是非常容易的
JFrame frame = new JFrame("透明窗體測試");
//Frame frame = new Frame("透明窗體測試");
/*frame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent we){
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 Shell shell;
private Display display = Display.getDefault();
private Image image = null;
private ImageData imageData = null;
public static void main(String[] args) {
try {
SWTWindowFrm window = new SWTWindowFrm();
window.open();
} catch (Exception e) {
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();
Listener listener = new Listener() {
int startX, startY;
public void handleEvent(Event e) {
// 注入鼠標事件
if (e.type == SWT.MouseDown && e.button == 1) {
startX = e.x;
startY = e.y;
}
if (e.type == SWT.MouseMove && (e.stateMask & SWT.BUTTON1) != 0) {
Point p = 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() {
String path = this.getClass().getResource("role.gif").getPath();
image = new Image(display, new ImageData(path));
Region region = 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 {
ImageData mask = 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;
Point mousePointer;
public MyJWindow(Image img) {
super(img);
init();
}
public void init() {
addMouseMotionListener(this);
addFocusListener(this);
}
public void focusGained(FocusEvent aFocusEvent) {
Point aPoint = getLocation();
setLocation(15000, 0);
setLocation(aPoint);
}
public void focusLost(FocusEvent aFocusEvent) {
}
public void mouseDragged(MouseEvent aMouseEvent) {
Point aPoint = aMouseEvent.getPoint();
int x = getX() + aPoint.x - mousePointer.x;
int y = getY() + aPoint.y - mousePointer.y;
setLocation(x, y);
}
public void mouseMoved(MouseEvent aMouseEvent) {
mousePointer = aMouseEvent.getPoint();
}
public static void main(String[] args) {
String path = MyJWindow.class.getResource("role.gif").getPath();
BufferedImage backgroundImage = null;
try {
backgroundImage = ImageIO.read(new File(path));
} catch (IOException e) {
e.printStackTrace();
}
Window window = 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

浙公網安備 33010602011771號