偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

JDK1.3中使用非Java的GUI組件

開(kāi)發(fā) 后端
本文介紹JDK1.3中推出的一個(gè)新的本地接口,通過(guò)這個(gè)接口可以Java程序中使用非 Java 的 GUI 組件。

如果您正在使用 JDK1.3,則您可以借助于 Java 2 AWT 本地接口,使用 C 或 C++ 方法來(lái)繪制基于 AWT 的 Canvas 對(duì)象。 

因此,本地 GUI 組件可以嵌入到 Java 應(yīng)用程序中;同時(shí),正像 JDK1.3 以前的其他版本一樣,您可以使用 Java 本地接口從 Java 應(yīng)用程序中調(diào)用本地方法。Davanum Srinivas 解釋了如何在 Java 中使用現(xiàn)有的本地用戶(hù)界面庫(kù)。他還提供了 Win32 操作系統(tǒng)下的一個(gè)具體示例。

在 JDK1.3 出現(xiàn)以前,您僅能將 Java 本地接口用于非用戶(hù)界面的工作。JDK 1.3 引入了新的 Java 2 AWT 本地接口,這使您可以在 Java 程序中使用非 Java 的 GUI 組件,盡管這樣做會(huì)失去純 Java 解決方案的可移植性。在使用 J2AWT 時(shí),您必須針對(duì)要使用它的每個(gè)平臺(tái)制作本地動(dòng)態(tài)連接庫(kù)或共享庫(kù)。

下面這段話摘自 JDK1.3 的某個(gè)頭文件,它說(shuō)明了這種新的 API 的開(kāi)發(fā)背景及原因:

AWT 支持使用本地 C 或 C++ 應(yīng)用程序訪問(wèn) AWT 的本地結(jié)構(gòu)。這是為了便于將原有的 C 或 C++ 應(yīng)用程序移植到 Java 并滿(mǎn)足需要 ... [這些應(yīng)用程序] 出于性能方面的原因在畫(huà)布上自行進(jìn)行本地繪制

在 JDK1.3 以前,Java 編程沒(méi)有明確的方法來(lái)訪問(wèn)基層的同等 GUI 組件的句柄。在 JDK 1.3 中, Sun 公司創(chuàng)建了一種標(biāo)準(zhǔn)機(jī)制,通過(guò)這種機(jī)制,開(kāi)發(fā)人員可以使本地 GUI 應(yīng)用程序和庫(kù)在 Java AWT Canvas 對(duì)象中進(jìn)行繪制。這意味著現(xiàn)在有一種正式的、有保證的方法來(lái)獲得支持這一功能的信息。當(dāng) JDK 1.3 與其他操作平臺(tái)對(duì)接時(shí),所有的接口都提供相同的信息 -- 而不管使用的是什么系統(tǒng)。JDK 1.3 的 Windows 版本和 Solaris 版本是首先提供這種支持的實(shí)現(xiàn)。

Sun 公司引入這一功能組件有幾方面的原因。首先, JDK 1.3 使得人們可以將依賴(lài)第三方產(chǎn)品的復(fù)雜原有軟件移植到 Java 上,而不必等到第三方產(chǎn)品本身完成移植以后。第二個(gè)原因即性能;如果本地的 GUI 代碼經(jīng)過(guò)人們長(zhǎng)時(shí)期的努力得到優(yōu)化,則原樣保留這些軟件具有重要的商業(yè)價(jià)值。

在本文中,我將介紹一些該功能部件的基本概念。我將逐步開(kāi)發(fā)一個(gè)窗口小部件樣例,該窗口小部件使用Win32 API 進(jìn)行繪制。下圖是最終的窗口小部件的快照,一個(gè)帶有笑臉的圓形窗口。

運(yùn)行中的窗口小部件

分步概覽

第一步,定義一個(gè) Java 類(lèi) -- 比如說(shuō),Mywindow -- 使其繼承 Canvas 類(lèi)并重載 paint 方法。您使用 paint 方法執(zhí)行 AWT 對(duì)象的繪制操作,并在覆蓋該方法時(shí)加上 native 關(guān)鍵字。覆蓋方法使您能夠使用自己的本地代碼。您必須構(gòu)建自己的本地代碼并把它編譯成一個(gè)動(dòng)態(tài)連接庫(kù),就像我們處理其他的 Java 本地接口應(yīng)用程序一樣,在本例中,我們將調(diào)用 MyWindow.DLL 庫(kù)。在 Solaris 和 Linux 上則為共享對(duì)象或共享庫(kù)。您還需要用 System.loadLibrary("MyWindow") 調(diào)用將 MyWindow.DLL 庫(kù)加載到您的名為 MyWindow 的 Java 類(lèi)中。

完成這一示例需要二個(gè)部分:其一是 MyWindow.Java ,它提供 Canvas 類(lèi)的子類(lèi),其二是 MyWindow.CPP ,它包含基于 Java 本地接口的繪制子程序的入口點(diǎn)。 在參考資源部分可找到 MyWindow.Java、MyWindow.CPP 及自動(dòng)執(zhí)行編譯的批處理文件 BUILD.BAT。

第一步: 創(chuàng)建 MyWindow Java 類(lèi)

J2AWT 用于這種方法時(shí)有一個(gè)主要的局限性:本地代碼只能對(duì) java.awt.Canvas 類(lèi)的子類(lèi)進(jìn)行操作。這正是 MyWindow 繼承 Canvas 類(lèi)的原因。在 Java 應(yīng)用程序中,您可以像使用 Canvas 的其它子類(lèi)那樣使用 MyWindow;在本例中,我將 MyWindow 添加到 Jwindow 中。

  1. import java.awt.*;  
  2. import javax.swing.*;  
  3.  
  4. public class MyWindow extends Canvas {  
  5. static {  
  6. //加載包含 paint 代碼的庫(kù)。  
  7. System.loadLibrary("MyWindow");  
  8. }  
  9.  
  10. //繪制操作的本地入口點(diǎn)  
  11. public native void paint(Graphics g);  
  12.  
  13. public static void main( String[] argv ){  
  14. Frame f = new Frame();  
  15. f.setSize(300,400);  
  16.  
  17. JWindow w = new JWindow(f);  
  18. w.setBackground(new Color(0,0,0,255));  
  19. w.getContentPane().setBackground(new Color(0,0,0,255));  
  20. w.getContentPane().add(new MyWindow());  
  21. w.setBounds(300,300,300,300);  
  22. w.setVisible(true);  
  23. }  
  24. }  

請(qǐng)注意:您是在靜態(tài)塊中加載 MyWindow.DLL。這正是 Java 應(yīng)用程序訪問(wèn)本地代碼的方式。(我稍候就會(huì)開(kāi)發(fā)這段本地代碼。)同時(shí)還應(yīng)注意:paint 方法是用 native 關(guān)鍵字聲明的,并且沒(méi)有提供任何實(shí)現(xiàn);這樣做是為了讓虛擬機(jī)知道,應(yīng)該從在靜態(tài)塊中加載的動(dòng)態(tài)連接庫(kù)中調(diào)用該本地方法。

第二步:生成該類(lèi)的 JNI 頭文件

要為以上定義的類(lèi)生成 Java 本地接口頭文件,需使用 javah MyWindow.class 命令。首先應(yīng)確保這個(gè)類(lèi)文件在您的 CLASSPATH 中。以下是所生成的 MyWindow.h 的一部分,給出了函數(shù)聲明。

  1. /*  
  2. * Class: MyWindow  
  3. * Method: paint  
  4. * Signature: (Ljava/awt/Graphics;)V  
  5. */ 
  6. JNIEXPORT void JNICALL Java_MyWindow_paint  
  7. (JNIEnv *, jobject, jobject);  
  8.  

第三步:開(kāi)發(fā)完整的 MyWindow.CPP

以下是完整的 MyWindow.CPP,其中包含 MyWindow.Java 中所需要的繪圖程序的本地代碼。

  1. #include < windows.h>  
  2. #include < assert.h>  
  3. #include "jawt_md.h" 
  4. #include "MyWindow.h" 
  5.  
  6. #define X(x) (int)(xLeft + (x)*xScale/100// 縮放宏  
  7. #define Y(y) (int)(yTop + (y)*yScale/100// 以使尺度在 0-100 之間  
  8. #define CX(x) (int)((x)*xScale/100)  
  9. #define CY(y) (int)((y)*yScale/100)  
  10.  
  11. void DrawSmiley(HWND hWnd, HDC hdc);  
  12. HRGN hrgn = NULL;  
  13.  
  14. JNIEXPORT void JNICALL  
  15. Java_MyWindow_paint(JNIEnv* env, jobject canvas, jobject graphics)  
  16. {  
  17. JAWT awt;  
  18. JAWT_DrawingSurface* ds;  
  19. JAWT_DrawingSurfaceInfo* dsi;  
  20. JAWT_Win32DrawingSurfaceInfo* dsi_win;  
  21. jboolean result;  
  22. jint lock;  
  23.  
  24. // 獲取 AWT   
  25. awt.version = JAWT_VERSION_1_3;  
  26. result = JAWT_GetAWT(env, &awt);  
  27. assert(result != JNI_FALSE);  
  28. // 獲取繪圖界面  
  29. ds = awt.GetDrawingSurface(env, canvas);  
  30. if(ds == NULL)  
  31. return;  
  32. // 鎖定繪圖表面  
  33. lock = ds->Lock(ds);  
  34. assert((lock & JAWT_LOCK_ERROR) == 0);  
  35.  
  36. // 獲取繪圖表面的信息  
  37. dsi = ds->GetDrawingSurfaceInfo(ds);  
  38.  
  39. // 獲取特定平臺(tái)的繪圖信息  
  40. dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;  
  41.  
  42. HDC hdc = dsi_win->hdc;  
  43. HWND hWnd = dsi_win->hwnd;  
  44. //////////////////////////////  
  45. // !!! 在此處進(jìn)行繪圖 !!! //  
  46. //////////////////////////////  
  47. if(hrgn == NULL)  
  48. {  
  49. RECT rcBounds;  
  50. GetWindowRect(hWnd,&rcBounds);  
  51. long xLeft = 0// 用于縮放宏  
  52. long yTop = 0;  
  53. long xScale = rcBounds.right-rcBounds.left;  
  54. long yScale = rcBounds.bottom-rcBounds.top;  
  55. hrgn = CreateEllipticRgn(X(10), Y(15), X(90), Y(95));  
  56. SetWindowRgn(GetParent(hWnd),hrgn,TRUE);  
  57. InvalidateRect(hWnd,NULL,TRUE);  
  58. else {  
  59. DrawSmiley(hWnd,hdc);  
  60. }  
  61. // 釋放繪圖表面的信息  
  62. ds->FreeDrawingSurfaceInfo(dsi);  
  63. // 為繪圖表面解鎖  
  64. ds->Unlock(ds);  
  65. // 釋放繪圖表面  
  66. awt.FreeDrawingSurface(ds);  
  67. }  
  68.  
  69. void DrawSmiley(HWND hWnd, HDC hdc)  
  70. {  
  71. RECT rcBounds;  
  72. GetWindowRect(hWnd,&rcBounds);  
  73. long xLeft = 0// 用于縮放宏  
  74. long yTop = 0;  
  75. long xScale = rcBounds.right-rcBounds.left;  
  76. long yScale = rcBounds.bottom-rcBounds.top;  
  77.  
  78. // 基于控制大小的畫(huà)筆寬度  
  79. int iPenWidth = max(CX(5), CY(5));  
  80. HBRUSH brushBlack;  
  81. HBRUSH brushYellow;  
  82. HPEN penBlack = CreatePen(PS_SOLID, iPenWidth, RGB(0x00,0x00,0x00));  
  83. // 用于繪制填充橢圓的空畫(huà)筆  
  84. HPEN penNull = CreatePen(PS_NULL, 0, (COLORREF)0);  
  85.  
  86. brushBlack = CreateSolidBrush(RGB(0x00,0x00,0x00));  
  87. brushYellow = CreateSolidBrush(RGB(0xff,0xff,0x00));  
  88.  
  89. HPEN pPenSave = (HPEN)SelectObject(hdc, penBlack);  
  90. HBRUSH pBrushSave = (HBRUSH)SelectObject(hdc,brushYellow);  
  91. Ellipse(hdc,X(10), Y(15), X(90), Y(95)); // 頭部  
  92.  
  93. Arc(hdc,X(25), Y(10), X(75), Y(80), // 嘴部(微笑)  
  94. X(35), Y(70), X(65), Y(70));  
  95.  
  96. SelectObject(hdc,&penNull); // 無(wú)繪圖寬度  
  97. SelectObject(hdc,&brushBlack);  
  98.  
  99. Ellipse(hdc,X(57), Y(35), X(65), Y(50));  
  100. Ellipse(hdc,X(35), Y(35), X(43), Y(50)); // 右眼  
  101. Ellipse(hdc,X(46), Y(50), X(54), Y(65)); // 鼻子  
  102.  
  103. SetBkMode(hdc,TRANSPARENT); // 使用前景顏色  
  104.  
  105. SelectObject(hdc,pBrushSave);  
  106. SelectObject(hdc,pPenSave);  
  107. }  

這里的關(guān)鍵數(shù)據(jù)結(jié)構(gòu)是 JAWT,它是在 jawt.h 中定義的(通過(guò) jawt_md.h 包含在內(nèi))。它使程序可以訪問(wèn)本地代碼在基于 Java 的 GUI 組件上繪圖所需的所有信息。本地方法的第一部分是套式:置入 JAWT 結(jié)構(gòu),獲得一個(gè) JAWT_Win32DrawingSurfaceInfo 結(jié)構(gòu),鎖定表面(請(qǐng)一次只使用一種繪圖工具!),然后,獲取一個(gè) JAWT_DrawingSurfaceInfo 結(jié)構(gòu),該結(jié)構(gòu)包含特定平臺(tái)下繪圖所必需的指針(在 platformInfo字段中)。它也包含繪圖界面的矩形界限框及當(dāng)前剪切區(qū)域。有關(guān)詳細(xì)信息,請(qǐng)查看 jawt.h 和 jawt_md.h (請(qǐng)參閱下面標(biāo)題為 “構(gòu)建環(huán)境”的部分)。

Java_MyWindow_paint 是一個(gè)入口點(diǎn),JVM 通過(guò)調(diào)用它來(lái)繪制 MyWindow。輔助函數(shù) DrawSmiley 使用 Win32 調(diào)用來(lái)完成實(shí)際的繪制工作。要在您的應(yīng)用程序中包含 GetDrawingSurfaceInfo,請(qǐng)使用外部庫(kù) jawt.lib(請(qǐng)參閱 “構(gòu)建環(huán)境”)。

第四步:編輯 BUILD.BAT

在運(yùn)行 BUILD.BAT 之前首先對(duì)它進(jìn)行編輯,并像如下所示的那樣,為您的 Visual C++ 及 JDK1.3 設(shè)置路徑。BUILD.BAT 對(duì) MyWindow.java 進(jìn)行編譯,生成 MyWindow.h,然后將 MyWindow.CPP 編譯為 MyWindow.DLL。

SET DEVSTUDIO=D:Program FilesMicrosoft Visual StudioVC98

SET JDK13=D:JDK1.3

好了,一切準(zhǔn)備就緒。在運(yùn)行該樣例之前,請(qǐng)確保 MyWindow.DLL、JDK1.3BIN 及 JDK1.3JREBIN 都在 PATH 內(nèi),還要保證當(dāng)前目錄在 CLASSPATH 中;這將確保 MyWindow.class 會(huì)被成功加載。在確信 PATH 和 CLASSPATH 都設(shè)置妥當(dāng)后,在命令行輸入 java MyWindow 來(lái)運(yùn)行此應(yīng)用程序。為方便您的使用,window.zip 中包含了一個(gè)批處理文件 RUN.BAT(請(qǐng)參閱參考資源)。要為 JDK 1.3 設(shè)置PATH 和 CLASSPATH,請(qǐng)編輯 RUN.BAT。

構(gòu)建環(huán)境

頭文件:在 JDK 的 include 目錄中新增了專(zhuān)用于 Windows 的 C 頭文件。它們是:

include/jawt.h.

include/win32/jawt_md.h.

依據(jù) JavaSoft 網(wǎng)站的說(shuō)明,這些頭文件并不是 Java 2 平臺(tái)正式規(guī)范的組成部分;提供這些頭文件只是為希望用一種標(biāo)準(zhǔn)化方法訪問(wèn)本地繪圖功能的開(kāi)發(fā)人員提供一種便利。我認(rèn)為這表示將 JDK 移植到其它平臺(tái)的廠商可以不提供這個(gè) API。

庫(kù):一個(gè)以 jawt.lib 命名的新庫(kù)已添加到 SDK 的庫(kù)目錄中。如前所述,這個(gè)庫(kù)包含一個(gè)用于把 J2AWT 包含到您的應(yīng)用程序中所需要的入口點(diǎn)。例如,要鏈接到 GetDrawingSurfaceInfo 入口點(diǎn),您需要在您的程序中包含 jawt.lib。

工具:javah 工具用來(lái)為 Java 類(lèi)的本地函數(shù)生成 C/C++ 頭文件,javac 工具用來(lái)編譯 Java 源文件。

小結(jié)

將原有軟件系統(tǒng)移植到 Java 中并不容易,尤其是當(dāng)原有軟件包含高性能的繪圖器時(shí)。Java 2 AWT 本地接口使得分階段移植變得較為容易,它允許您首先移植對(duì)性能要求不高的代碼,然后再移植關(guān)鍵的繪制代碼。它同時(shí)使第三方窗口小部件開(kāi)發(fā)廠商更能?chē)?yán)肅地看待針對(duì) Java 產(chǎn)品的開(kāi)發(fā)。有了 JDK1.3中的本地應(yīng)用程序接口,您就可以移植原有的 GUI 代碼,并更快地完成開(kāi)發(fā),這樣就不會(huì)犧牲您為提高本地代碼關(guān)鍵部分的性能而作的投資。

【編輯推薦】

  1. JDK5.0中一些collection類(lèi)的使用詳解
  2. JDK的概念、組成及JDK常用包
  3. JDK1.4在Windows下的環(huán)境配置
  4. JDK1.6在LINUX下的安裝配置
  5. JDK日志框架之實(shí)例結(jié)合STAF淺析
責(zé)任編輯:yangsai 來(lái)源: IBMDW
相關(guān)推薦

2009-03-20 13:40:15

JDK線程并發(fā)

2021-08-01 07:58:58

Vue 加載組件

2009-04-12 08:46:43

Symbian諾基亞移動(dòng)OS

2017-07-04 19:02:17

ReacRedux 項(xiàng)目

2021-03-08 15:33:50

Java框架開(kāi)發(fā)

2009-07-08 15:31:40

JDK 6.0web service

2009-07-30 14:14:07

非托管COM組件

2022-12-21 16:53:59

LinuxConverterGUI

2010-07-30 08:30:38

VisualVMVisualVM 1.VisualVM 1.

2024-02-05 13:07:00

.NETTable組件

2012-08-10 13:55:56

Java動(dòng)態(tài)代理

2021-07-09 08:33:35

React組件受控

2020-05-11 15:01:16

JavaJKD 15工具

2011-06-09 16:18:25

Qt GUI

2023-10-10 22:24:16

2010-05-20 13:49:34

MySQL GUI工具

2012-07-12 10:22:58

Ubuntu系統(tǒng)菜單

2009-07-30 12:19:32

ASP.NET中使用A

2024-11-25 07:00:00

箭頭函數(shù)JavaScriptReact

2021-03-22 08:45:30

異步編程Java
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)