国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院

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

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院
在线观看的av网站| 国产a级网站| www.成人.com| 日本在线观看| 交视频在线观看国产| 青青艹在线视频| 国内自拍视频在线看免费观看| 在线免费国产| 91在线中文| 夜夜操com| 国产成人亚洲欧美电影| 91www在线观看| 91xxx在线观看| 天天草天天干| 97一区二区三区| 国产亚洲精品久久久久久移动网络| 国产黄色在线播放| 国产日韩欧美精品一区二区三区 | 国产高清自拍视频在线观看| 蜜桃av网站| 永久免费av片在线观看全网站| 国产高清自拍视频在线观看 | 国产一级影片| 丁香视频五月| 黄色在线视频观看网站| 欧美日韩亚洲第一页| 9999在线视频| 性网站在线看| 欧美性xxxx交| 交换国产精品视频一区| 欧美性猛交p30| 国产在线观看网站| 国产在线观看a| 五月婷婷视频在线观看| 国产亚洲依依| 精品176二区| 国产成人综合亚洲欧美在| 国产美女视频一区二区三区| 黄色片免费在线| 久热国产视频| 国产美女在线看| av在线网页| 中文字幕一区免费| 国产高潮又爽又无遮挡又免费| 国产91在线视频蝌蚪| 亚洲国产aⅴ精品| 成人欧美亚洲| 国产黄色在线观看| 在线久久视频| 国产免费电影网站入口| 精品乱码一区二区三四区视频| 国产盗摄一区二区| eeuss影影院www在线播放| 黄色网址在线免费播放| 精品卡一卡卡2卡3网站| 玖玖在线视频| 中文资源在线网| 99视频免费在线观看| 在线观看国产福利视频| 最好看更新中文字幕| www在线播放| 99热免费在线观看| 国产一二区视频| 国产原创在线播放| 91九色在线看| 激情六月婷婷| 最新超碰在线| 麻豆国产在线播放| www.操操操| 在线免费看av| 2018中文字幕在线观看| 狠狠干五月天| 老司机在线视频二区| 午夜影院在线免费观看| 精品国产免费观看一区| 国产激情视频一区二区三区| 免费久久网站| 欧美xxxxx性| 亚洲а∨精品天堂在线| 国产xxxxx| 精品视频三区| 国产精品入口免费麻豆| 国产性一级片| 国产精品一区二区资源| 天堂亚洲精品| 亚洲网站一区| 在线免费观看污| 国产免费高清| 国产激情在线视频| 国产精品被窝福利一区| 精品视频二区| 午夜在线不卡| 久热精品视频在线播放| 开心婷婷激情| 五月婷婷在线观看| 国产成人va亚洲电影| 国产黄色高清在线| 亚洲综合在线网| 九九热免费视频| 国产黄色免费网| 香蕉视频网站在线观看| 欧美成人精品福利网站| 天天操天天曰| 91这里只有精品| 羞羞视频在线免费看| 九九精品视频在线观看九九| 免费看黄视频网站| 国产亚洲精品拍拍拍拍拍| 中文资源在线网| 国产在线三区| 国产jizz| 欧美性猛交xxxx免费看蜜桃| 国产毛片毛片毛片| 精品国产免费观看一区| 黄色电影网站在线观看| 国产盗摄精品一区二区酒店| 亚洲欧美精品日韩欧美| 国产伦精品一区二区三区高清版禁| 国产精品69一区二区三区| 欧美性猛交xxxxbbbb| 国产日本在线视频| eeuss影影院www在线播放| 国产鲁鲁视频在线观看特色| 国产黄在线观看免费观看不卡| www.狠狠色.com| 国产盗摄一区二区| 尤物视频在线观看| 国产福利在线看| 黄色片免费在线| 亚洲尤物在线视频| 国产精品入口麻豆免费观看| 免费中文字幕| 亚洲免费网站在线观看| 黄色电影网站在线观看| 999在线视频| 国产女王在线**视频 | 最好看更新中文字幕| 午夜在线视频| 亚洲欧美精品日韩欧美| 一区二区免费播放| 中文字幕av在线播放| 91青青在线视频| 999福利在线视频| 国产无遮挡在线视频免费观看| 青青草原国产在线| 老鸭窝av在线| 麻豆av在线| 国产在线观看91| 黄色片大全在线观看| 日本成a人片在线观看| 99久热re在线精彩视频| 国产一区二区三区不卡在线| 成人av小说网| 国产高清在线观看| 欧美在线中文| 尤物视频在线观看| 国产香蕉视频在线观看| 99色在线观看| 国产高清av| 日本福利在线观看| 国产九九九九| 999精品网| 日本卡一卡2卡3卡4精品卡网站| 日本高清不卡中文字幕| 丁香婷婷在线观看| 国产福利在线免费观看| 亚洲综合在线不卡| 中文字幕在线免费| 在线一区二区三区精品| 欧美aaa一级片| 国产精品久久久久一区二区国产 | 亚洲精品xxxxx| 国产尤物视频在线| 精品视频三区| 国产乱妇乱子在线播视频播放网站| 18 激情视频在线| 国产麻豆麻豆| 免费看的av| 99爱在线观看| 国产网红女主播精品视频| jlzzjlzz欧美| 精品一区二区91| jlzzjlzz欧美| 国产盗摄一区二区| 国产乱子伦三级在线播放| 亚洲精品男人| 伊人网在线视频| 国产欧美日韩第一页| 国产在线视频福利| 亚洲va国产日韩欧美精品色婷婷| 日本中文字幕在线2020| 四虎成人精品在永久免费| 天天爱天天色| 不卡av免费观看| 国产伦精品一区二区三区高清版禁 | 天天草天天干| 国产国产人免费人成免费视频 | 中文字幕日本三级| 国产中文字幕在线| 黄色一级片视频|