亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

JDK1.3中的本地繪制支持

2019-11-18 14:04:54
字體:
來源:轉載
供稿:網友

  作者:Davanum Srinivas

java 技巧 86:JDK1.3 中的本地繪制支持 -- JavaWord
在不犧牲本地 GUI 代碼性能的條件下獲得可移植性并縮短開發周期

(本文選自IBM developerWorks中文網站)

 

摘要
假如您正在使用 JDK1.3,則您可以借助于 Java 2 AWT 本地接口,使用 C 或 C++ 方法來繪制基于 AWT 的 Canvas 對象。因此,本地 GUI 組件可以嵌入到 Java 應用程序中;同時,正像 JDK1.3 以前的其他版本一樣,您可以使用 Java 本地接口從 Java 應用程序中調用本地方法。Davanum Srinivas 解釋了如何在 Java 中使用現有的本地用戶界面庫。他還提供了 Win32 操作系統下的一個具體示例。
在 JDK1.3 出現以前,您僅能將 Java 本地接口用于非用戶界面的工作。JDK 1.3 引入了新的 Java 2 AWT 本地接口,這使您可以在 Java 程序中使用非 Java 的 GUI 組件,盡管這樣做會失去純 Java 解決方案的可移植性。在使用 J2AWT 時,您必須針對要使用它的每個平臺制作本地動態連接庫或共享庫。
下面這段話摘自 JDK1.3 的某個頭文件,它說明了這種新的 API 的開發背景及原因:


AWT 支持使用本地 C 或 C++ 應用程序訪問 AWT 的本地結構。這是為了便于將原有的 C 或 C++ 應用程序移植到 Java 并滿足需要 ... [這些應用程序] 出于性能方面的原因在畫布上自行進行本地繪制
在 JDK1.3 以前,Java 編程沒有明確的方法來訪問基層的同等 GUI 組件的句柄。在 JDK 1.3 中, Sun 公司創建了一種標準機制,通過這種機制,開發人員可以使本地 GUI 應用程序和庫在 Java AWT Canvas 對象中進行繪制。這意味著現在有一種正式的、有保證的方法來獲得支持這一功能的信息。當 JDK 1.3 與其他操作平臺對接時,所有的接口都提供相同的信息 -- 而不管使用的是什么系統。JDK 1.3 的 Windows 版本和 Solaris 版本是首先提供這種支持的實現。

Sun 公司引入這一功能組件有幾方面的原因。首先, JDK 1.3 使得人們可以將依靠第三方產品的復雜原有軟件移植到 Java 上,而不必等到第三方產品本身完成移植以后。第二個原因即性能;假如本地的 GUI 代碼經過人們長時期的努力得到優化,則原樣保留這些軟件具有重要的商業價值。

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



運行中的窗口小部件

分步概覽
第一步,定義一個 Java 類 -- 比如說,Mywindow -- 使其繼續 Canvas 類并重載 paint 方法。您使用 paint 方法執行 AWT 對象的繪制操作,并在覆蓋該方法時加上 native 要害字。覆蓋方法使您能夠使用自己的本地代碼。您必須構建自己的本地代碼并把它編譯成一個動態連接庫,就像我們處理其他的 Java 本地接口應用程序一樣,在本例中,我們將調用 MyWindow.DLL 庫。在 Solaris 和 linux 上則為共享對象或共享庫。您還需要用 System.loadLibrary("MyWindow") 調用將 MyWindow.DLL 庫加載到您的名為 MyWindow 的 Java 類中。

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

第一步: 創建 MyWindow Java 類
J2AWT 用于這種方法時有一個主要的局限性:本地代碼只能對 java.awt.Canvas 類的子類進行操作。這正是 MyWindow 繼續 Canvas 類的原因。在 Java 應用程序中,您可以像使用 Canvas 的其它子類那樣使用 MyWindow;在本例中,我將 MyWindow 添加到 Jwindow 中。

import java.awt.*;
import javax.swing.*;

public class MyWindow extends Canvas {
static {
//加載包含 paint 代碼的庫。
System.loadLibrary("MyWindow");
}

//繪制操作的本地入口點
public native void paint(Graphics g);

public static void main( String[] argv ){
Frame f = new Frame();
f.setSize(300,400);

JWindow w = new JWindow(f);
w.setBackground(new Color(0,0,0,255));
w.getContentPane().setBackground(new Color(0,0,0,255));
w.getContentPane().add(new MyWindow());
w.setBounds(300,300,300,300);
w.setVisible(true);
}
}


請注重:您是在靜態塊中加載 MyWindow.DLL。這正是 Java 應用程序訪問本地代碼的方式。(我稍候就會開發這段本地代碼。)同時還應注重:paint 方法是用 native 要害字聲明的,并且沒有提供任何實現;這樣做是為了讓虛擬機知道,應該從在靜態塊中加載的動態連接庫中調用該本地方法。

第二步:生成該類的 JNI 頭文件
要為以上定義的類生成 Java 本地接口頭文件,需使用 javah MyWindow.class 命令。首先應確保這個類文件在您的 CLASSPATH 中。以下是所生成的 MyWindow.h 的一部分,給出了函數聲明。

/*
* Class: MyWindow
* Method: paint
* Signature: (Ljava/awt/Graphics;)V
*/
JNIEXPORT void JNICALL Java_MyWindow_paint
(JNIEnv *, jobject, jobject);


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

#include <windows.h>
#include <assert.h>
#include "jawt_md.h"
#include "MyWindow.h"

#define X(x) (int)(xLeft + (x)*xScale/100) // 縮放宏
#define Y(y) (int)(yTop + (y)*yScale/100) // 以使尺度在 0-100 之間
#define CX(x) (int)((x)*xScale/100)
#define CY(y) (int)((y)*yScale/100)

void DrawSmiley(HWND hWnd, HDC hdc);
HRGN hrgn = NULL;

JNIEXPORT void JNICALL
Java_MyWindow_paint(JNIEnv* env, jobject canvas, jobject graphics)
{
JAWT awt;
JAWT_DrawingSurface* ds;
JAWT_DrawingSurfaceInfo* dsi;
JAWT_Win32DrawingSurfaceInfo* dsi_win;
jboolean result;
jint lock;

// 獲取 AWT
awt.version = JAWT_VERSION_1_3;
result = JAWT_GetAWT(env, &awt);
assert(result != JNI_FALSE);
// 獲取繪圖界面
ds = awt.GetDrawingSurface(env, canvas);
if(ds == NULL)
return;
// 鎖定繪圖表面
lock = ds->Lock(ds);
assert((lock & JAWT_LOCK_ERROR) == 0);

// 獲取繪圖表面的信息
dsi = ds->GetDrawingSurfaceInfo(ds);

// 獲取特定平臺的繪圖信息
dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;

HDC hdc = dsi_win->hdc;
HWND hWnd = dsi_win->hwnd;
//////////////////////////////
// !!! 在此處進行繪圖 !!! //
//////////////////////////////
if(hrgn == NULL)
{
RECT rcBounds;
GetWindowRect(hWnd,&rcBounds);
long xLeft = 0; // 用于縮放宏
long yTop = 0;
long xScale = rcBounds.right-rcBounds.left;
long yScale = rcBounds.bottom-rcBounds.top;
hrgn = CreateEllipticRgn(X(10), Y(15), X(90), Y(95));
SetWindowRgn(GetParent(hWnd),hrgn,TRUE);
InvalidateRect(hWnd,NULL,TRUE);
} else {
DrawSmiley(hWnd,hdc);
}
// 釋放繪圖表面的信息
ds->FreeDrawingSurfaceInfo(dsi);
// 為繪圖表面解鎖
ds->Unlock(ds);
// 釋放繪圖表面
awt.FreeDrawingSurface(ds);
}

void DrawSmiley(HWND hWnd, HDC hdc)
{
RECT rcBounds;
GetWindowRect(hWnd,&rcBounds);
long xLeft = 0; // 用于縮放宏
long yTop = 0;
long xScale = rcBounds.right-rcBounds.left;
long yScale = rcBounds.bottom-rcBounds.top;

// 基于控制大小的畫筆寬度
int iPenWidth = max(CX(5), CY(5));
HBRUSH brushBlack;
HBRUSH brushYellow;
HPEN penBlack = CreatePen(PS_SOLID, iPenWidth, RGB(0x00,0x00,0x00));
// 用于繪制填充橢圓的空畫筆
HPEN penNull = CreatePen(PS_NULL, 0, (COLORREF)0);

brushBlack = CreateSolidBrush(RGB(0x00,0x00,0x00));
brushYellow = CreateSolidBrush(RGB(0xff,0xff,0x00));

HPEN pPenSave = (HPEN)SelectObject(hdc, penBlack);
HBRUSH pBrushSave = (HBRUSH)SelectObject(hdc,brushYellow);
Ellipse(hdc,X(10), Y(15), X(90), Y(95)); // 頭部

Arc(hdc,X(25), Y(10), X(75), Y(80), // 嘴部(微笑)
X(35), Y(70), X(65), Y(70));

SelectObject(hdc,&penNull); // 無繪圖寬度
SelectObject(hdc,&brushBlack);

Ellipse(hdc,X(57), Y(35), X(65), Y(50));
Ellipse(hdc,X(35), Y(35), X(43), Y(50)); // 右眼
Ellipse(hdc,X(46), Y(50), X(54), Y(65)); // 鼻子

SetBkMode(hdc,TRANSPARENT); // 使用前景顏色

SelectObject(hdc,pBrushSave);
SelectObject(hdc,pPenSave);
}


這里的要害數據結構是 JAWT,它是在 jawt.h 中定義的(通過 jawt_md.h 包含在內)。它使程序可以訪問本地代碼在基于 Java 的 GUI 組件上繪圖所需的所有信息。本地方法的第一部分是套式:置入 JAWT 結構,獲得一個 JAWT_Win32DrawingSurfaceInfo 結構,鎖定表面(請一次只使用一種繪圖工具!),然后,獲取一個 JAWT_DrawingSurfaceInfo 結構,該結構包含特定平臺下繪圖所必需的指針(在 platformInfo字段中)。它也包含繪圖界面的矩形界限框及當前剪切區域。有關具體信息,請查看 jawt.h 和 jawt_md.h (請參閱下面標題為 “構建環境”的部分)。

Java_MyWindow_paint 是一個入口點,JVM 通過調用它來繪制 MyWindow。輔助函數 DrawSmiley 使用 Win32 調用來完成實際的繪制工作。要在您的應用程序中包含 GetDrawingSurfaceInfo,請使用外部庫 jawt.lib(請參閱 “構建環境”)。

第四步:編輯 BUILD.BAT
在運行 BUILD.BAT 之前首先對它進行編輯,并像如下所示的那樣,為您的 Visual C++ 及 JDK1.3 設置路徑。BUILD.BAT 對 MyWindow.java 進行編譯,生成 MyWindow.h,然后將 MyWindow.CPP 編譯為 MyWindow.DLL。

SET DEVSTUDIO=D:PRogram FilesMicrosoft Visual StudioVC98
SET JDK13=D:JDK1.3


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

構建環境


頭文件:在 JDK 的 include 目錄中新增了專用于 Windows 的 C 頭文件。它們是:
include/jawt.h.
include/win32/jawt_md.h.


依據 JavaSoft 網站的說明,這些頭文件并不是 Java 2 平臺正式規范的組成部分;提供這些頭文件只是為希望用一種標準化方法訪問本地繪圖功能的開發人員提供一種便利。我認為這表示將 JDK 移植到其它平臺的廠商可以不提供這個 API。


庫:一個以 jawt.lib 命名的新庫已添加到 SDK 的庫目錄中。如前所述,這個庫包含一個用于把 J2AWT 包含到您的應用程序中所需要的入口點。例如,要鏈接到 GetDrawingSurfaceInfo 入口點,您需要在您的程序中包含 jawt.lib。

工具:javah 工具用來為 Java 類的本地函數生成 C/C++ 頭文件,javac 工具用來編譯 Java 源文件。

小結
將原有軟件系統移植到 Java 中并不輕易,尤其是當原有軟件包含高性能的繪圖器時。Java 2 AWT 本地接口使得分階段移植變得較為輕易,它答應您首先移植對性能要求不高的代碼,然后再移植要害的繪制代碼。它同時使第三方窗口小部件開發廠商更能嚴厲地看待針對 Java 產品的開發。有了 Java 2 AWT 本地應用程序接口,您就可以移植原有的 GUI 代碼,并更快地完成開發,這樣就不會犧牲您為提高本地代碼要害部分的性能而作的投資。

作者簡介
Davanum Srinivas 目前在 Computer Associates 公司從事軟件開發工作。

參考資源

本壓縮文件包含本文章涉及的所有源代碼和一個批處理文件:
window.zip
Sun 公司對 AWT 本地接口的介紹:
http://java.sun.com/prodUCts/jdk/1.3/AWT_Native_Interface.Html
SUN 公司在 Java 2 SDK,版本 1.3 中所作的增強:
http://java.sun.com/products/jdk/1.3/docs/guide/awt/enhancements.html
Sun 公司對本地繪圖 JAWT 接口的改進,post-Kestrel(只需免費注冊):
http://developer.java.sun.com/developer/bugParade/bugs/4281429.html
"Enhance your Java application with Java Native Interface (JNI)," TalLyron(JavaWorld,1999 年 10 月):
http://www.javaworld.com/javaworld/jw-10-1999/jw-10-jni.html
"Java Tip 23: Write native methods," John D. Mitchell (JavaWorld):
http://www.javaworld.com/javaworld/javatips/jw-javatip23.html

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美午夜性色大片在线观看| 2021久久精品国产99国产精品| 国产精品久久久久久久一区探花| 日本精品免费一区二区三区| 91精品国产综合久久香蕉最新版| 日韩视频在线观看免费| 国产精品h片在线播放| 亚洲激情在线观看视频免费| 精品免费在线视频| 日韩成人在线播放| 日本一区二区在线免费播放| 9.1国产丝袜在线观看| 久久精品国产视频| 国产精品jvid在线观看蜜臀| 亚洲美女久久久| 国产v综合ⅴ日韩v欧美大片| 欧美日韩中文字幕在线| 2023亚洲男人天堂| 精品少妇一区二区30p| 欧美性猛交99久久久久99按摩| 国产日韩欧美一二三区| 日韩欧美中文第一页| 日韩美女激情视频| 欧美一区二区三区免费视| 亚洲性夜色噜噜噜7777| 日韩精品中文字幕在线播放| 51视频国产精品一区二区| 亚洲成人激情小说| 中文字幕不卡av| 日韩在线播放一区| 日韩精品极品在线观看播放免费视频| 欧美午夜无遮挡| 欧美大肥婆大肥bbbbb| 日韩精品免费在线| 亚洲成人av在线播放| 亚洲第一页在线| 中文字幕综合一区| 在线观看欧美www| 欧美—级高清免费播放| 亚洲国产精品久久久久秋霞不卡| 国产成人在线一区二区| 国外成人免费在线播放| 日韩欧美黄色动漫| 国产日韩在线一区| 国产亚洲视频在线观看| 色琪琪综合男人的天堂aⅴ视频| 日韩欧美极品在线观看| 91在线观看欧美日韩| 亚洲精品国产精品乱码不99按摩| 日韩在线视频免费观看高清中文| 7777精品视频| 亚洲精品在线观看www| 中文字幕亚洲欧美日韩高清| 久久五月天色综合| 国产免费观看久久黄| 日韩暖暖在线视频| 2019亚洲男人天堂| 日韩av在线精品| 日韩综合视频在线观看| 欧美性一区二区三区| 国产精品大片wwwwww| 伊人久久免费视频| 国产精品久久久久久久9999| 欧美成人精品在线视频| 亚洲a级在线观看| 国产亚洲精品va在线观看| 欧美成人精品三级在线观看| 久久久成人av| 日韩电影在线观看永久视频免费网站| 色婷婷亚洲mv天堂mv在影片| 日韩精品一二三四区| xxx一区二区| 亚洲电影av在线| 日韩色av导航| 国产日韩欧美日韩| 欧美极品少妇与黑人| 欧美一级淫片丝袜脚交| 欧美视频在线免费| 欧美在线精品免播放器视频| 国产精品久久久久久超碰| 国产精品久久9| 97碰碰碰免费色视频| 欧美成人在线免费| 日韩福利在线播放| 精品日韩视频在线观看| 亚洲精品免费av| 亚洲欧洲在线看| 亚洲视频电影图片偷拍一区| 91av视频在线播放| 精品偷拍一区二区三区在线看| 77777亚洲午夜久久多人| 91久久久国产精品| 在线精品高清中文字幕| 亚洲欧美中文字幕在线一区| 91久久在线观看| 中文字幕欧美在线| 精品国产区一区二区三区在线观看| 国产视频观看一区| 国产香蕉一区二区三区在线视频| 国产亚洲aⅴaaaaaa毛片| 国产精品一区二区久久精品| 免费97视频在线精品国自产拍| 亚洲精品久久久久久久久久久| 国产福利视频一区二区| 欧美日韩亚洲激情| 国产精品电影久久久久电影网| 久久久97精品| 成人精品在线观看| 亚洲综合色激情五月| 欧美激情女人20p| 在线精品视频视频中文字幕| 欧美黑人又粗大| 久久久久久国产三级电影| 美日韩丰满少妇在线观看| 亚洲国产成人久久综合| 国产精品美女主播在线观看纯欲| 国产成人97精品免费看片| 欧美性猛交xxxx免费看| 亚洲精品影视在线观看| 国产成人精品电影久久久| 国产精品综合网站| 国产精品 欧美在线| 国产精品xxx视频| 5252色成人免费视频| 欧美大片在线看免费观看| 91精品久久久久久久久久久久久久| 色偷偷9999www| 亚洲人成网站999久久久综合| 国产91色在线免费| 一区二区欧美亚洲| 国产精品亚洲片夜色在线| 日韩欧美在线第一页| 在线播放国产一区中文字幕剧情欧美| 日韩中文字幕视频| 久久综合久久美利坚合众国| 精品国产一区二区三区在线观看| 国产精品普通话| 4444欧美成人kkkk| 亚洲欧美精品在线| 国产在线播放91| 亚洲毛片在线免费观看| 国色天香2019中文字幕在线观看| 欧美日韩一区二区三区| 成人网在线免费观看| 色婷婷av一区二区三区在线观看| 2019日本中文字幕| 琪琪第一精品导航| 欧美美女操人视频| 亚洲人成网站在线播| 欧美极品在线播放| 成人欧美一区二区三区黑人| 日本一欧美一欧美一亚洲视频| 在线视频欧美日韩| 亚洲成色999久久网站| 国产一区二区三区久久精品| 一区二区三区www| 亚洲欧美成人一区二区在线电影| 亚洲香蕉成人av网站在线观看| 久久久99久久精品女同性| 日韩电影中文字幕在线| 亚洲人成网站999久久久综合| 性色av一区二区咪爱| 久久电影一区二区| 国产大片精品免费永久看nba|