📄 10.html
字号:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="description" content="Java,JDBC,EJB,Open Source,jdk,rmi">
<meta name="Keywords"
content="Java, servlets, Java servlet, Javascript, ActiveX, VRML,
applet, applets, directory, news, jdbc, applications,
Java applications, Java developer, Java development, developer,
classes, Jars.com, Jars, intranet, Java applet, Javabeans,
Java products, JDK, Java development kit, java development environment, JIT,
JavaPlan, enterprise tools, JVM, Java Virtual Machine, Java resources,
SUN, CGI, Perl, database, network, html,
xml, dhtml, rating, ratings, review, jars, cgi, programming,
software review, software rating">
<title>csdn_JDK1.3 中的本地绘制支持</title>
<style>
.news { BACKGROUND: #007cd3; font-family: "宋体"; font-size: 9pt }
.t { font-family: "宋体"; font-size: 9pt }
.t1 { color:#007cd3; font-family: "宋体"; font-size: 9pt }
.white { font-family: "宋体"; font-size: 9pt;color:#FFFFFF }
.red { font-family: "宋体"; font-size: 9pt;color:#FF0000 }
A:visited {color:#0000FF}
A:hover {color: #ff6666; text-decoration: none}
.text {font-size: 12px; line-height: 160%; font-family: "宋体"}
.text1 {color:#000000; font-size: 12px; line-height: 130%; font-family: "宋体"; text-decoration: none}
.text1:visited {color:#000000}
.text1:hover {color: #000000}
.text2 {color:#000000; font-size: 12px; line-height: 130%; font-family: "宋体"; text-decoration: none}
.text2:visited {color:#000000}
.text2:hover {color: #000000}
.text3 {font-size: 12px; line-height: 100%; font-family: "宋体"; text-decoration: none}
.large {font-size: 14.8px; line-height: 130%}
</style>
</head>
<body
<!--start first table -->
<tr>
<td WIDTH="100%" VALIGN="TOP">
<tr>
<td WIDTH="100%" CLASS="white"></td>
</tr>
<tr>
<td WIDTH="50%" bordercolor="#FFFFFF" CLASS="t1" bgcolor="#F0F0F0" align="center" nowrap>JDK1.3 中的本地绘制支持 </td>
<p> <td WIDTH="50%" bordercolor="#FFFFFF" CLASS="t1" bgcolor="#F0F0F0" align="center" nowrap>作者:Davanum
Srinivas</td></p>
</tr>
<tr>
<td WIDTH="100%" bordercolor="#FFFFFF" CLASS="t" bgcolor="#F0F0F0" colspan="2">
<!-- startindex --><STRONG class=title>Java 技巧
86:JDK1.3 中的本地绘制支持 -- JavaWord</STRONG><BR><STRONG class=subtitle>在不牺牲本地
GUI 代码性能的条件下获得可移植性并缩短开发周期</STRONG><BR>
<p>(本文选自IBM developerWorks中文网站)</p>
<p> </p>
<BLOCKQUOTE><I><STRONG>摘要</STRONG><BR>如果您正在使用 JDK1.3,则您可以借助于 Java 2 AWT
本地接口,使用 C 或 C++ 方法来绘制基于 AWT 的 <CODE>Canvas</CODE> 对象。因此,本地 GUI 组件可以嵌入到
Java 应用程序中;同时,正像 JDK1.3 以前的其他版本一样,您可以使用 Java 本地接口从 Java
应用程序中调用本地方法。Davanum Srinivas 解释了如何在 Java 中使用现有的本地用户界面库。他还提供了 Win32
操作系统下的一个具体示例。<EM></EM></I></BLOCKQUOTE><!-- begin body text -->在 JDK1.3
出现以前,您仅能将 Java 本地接口用于非用户界面的工作。JDK 1.3 引入了新的 Java 2 AWT 本地接口,这使您可以在 Java
程序中使用非 Java 的 GUI 组件,尽管这样做会失去纯 Java 解决方案的可移植性。在使用 J2AWT
时,您必须针对要使用它的每个平台制作本地动态连接库或共享库。
<P>下面这段话摘自 JDK1.3 的某个头文件,它说明了这种新的 API 的开发背景及原因:
<P>
<BLOCKQUOTE>AWT 支持使用本地 C 或 C++ 应用程序访问 AWT 的本地结构。这是为了便于将原有的 C 或 C++
应用程序移植到 Java 并满足需要 ... [这些应用程序] 出于性能方面的原因在画布上自行进行本地绘制 </BLOCKQUOTE>
<P>在 JDK1.3 以前,Java 编程没有明确的方法来访问基层的同等 GUI 组件的句柄。在 JDK 1.3 中, Sun
公司创建了一种标准机制,通过这种机制,开发人员可以使本地 GUI 应用程序和库在 Java AWT <CODE>Canvas</CODE>
对象中进行绘制。这意味着现在有一种正式的、有保证的方法来获得支持这一功能的信息。当 JDK 1.3 与其他操作平台对接时,所有的接口都提供相同的信息
-- 而不管使用的是什么系统。JDK 1.3 的 Windows 版本和 Solaris 版本是首先提供这种支持的实现。
<P>Sun 公司引入这一功能组件有几方面的原因。首先, JDK 1.3 使得人们可以将依赖第三方产品的复杂原有软件移植到 Java
上,而不必等到第三方产品本身完成移植以后。第二个原因即性能;如果本地的 GUI
代码经过人们长时期的努力得到优化,则原样保留这些软件具有重要的商业价值。
<P>在本文中,我将介绍一些该功能部件的基本概念。我将逐步开发一个窗口小部件样例,该窗口小部件使用Win32 API
进行绘制。下图是最终的窗口小部件的快照,一个带有笑脸的圆形窗口。
<P>
<CENTER>
<TBODY>
<TR>
<TD>
<CENTER>
<P><IMG height=350 src="smiley_sml.jpg" tppabs="http://www.chinajavaworld.com/doc/lang/images/smiley_sml.jpg" vspace=3
width=425> <BR><FONT
size=-1><STRONG>运行中的窗口小部件</STRONG></FONT></CENTER></P></TD></TR></TBODY></CENTER>
<P><FONT size=+1><STRONG>分步概览</STRONG></FONT><BR>第一步,定义一个 Java 类 --
比如说,<CODE>Mywindow</CODE> -- 使其继承 <CODE>Canvas</CODE> 类并重载
<CODE>paint</CODE> 方法。您使用 <CODE>paint</CODE> 方法执行 AWT 对象的绘制操作,并在覆盖该方法时加上
<CODE>native</CODE>
关键字。覆盖方法使您能够使用自己的本地代码。您必须构建自己的本地代码并把它编译成一个动态连接库,就像我们处理其他的 Java
本地接口应用程序一样,在本例中,我们将调用 <CODE>MyWindow.DLL</CODE> 库。在 Solaris 和 Linux
上则为共享对象或共享库。您还需要用 <CODE>System.loadLibrary("MyWindow")</CODE> 调用将
MyWindow.DLL 库加载到您的名为 <CODE>MyWindow</CODE> 的 Java 类中。
<P>完成这一示例需要二个部分:其一是 <CODE>MyWindow.Java</CODE> ,它提供 <CODE>Canvas</CODE>
类的子类,其二是 <CODE>MyWindow.CPP</CODE> ,它包含基于 Java 本地接口的绘制子程序的入口点。 在<A
href="http://www.cn.ibm.com/developerWorks/java/jw-tips/tip086/index.shtml#resources">参考资源</A>部分可找到
<CODE>MyWindow.Java</CODE>、<CODE>MyWindow.CPP</CODE> 及自动执行编译的批处理文件
<CODE>BUILD.BAT</CODE>。
<P><FONT size=+1><STRONG>第一步: 创建 MyWindow Java 类 </STRONG></FONT><BR>J2AWT
用于这种方法时有一个主要的局限性:本地代码只能对 <CODE>java.awt.Canvas</CODE> 类的子类进行操作。这正是
<CODE>MyWindow</CODE> 继承 <CODE>Canvas</CODE> 类的原因。在 Java 应用程序中,您可以像使用
<CODE>Canvas</CODE> 的其它子类那样使用 <CODE>MyWindow</CODE>;在本例中,我将
<CODE>MyWindow</CODE> 添加到 <CODE>Jwindow</CODE> 中。
<P><CODE>import java.awt.*;<BR>import javax.swing.*;<BR><BR>public class
MyWindow extends Canvas
{<BR> static
{<BR> //加载包含
paint
代码的库。<BR> System.loadLibrary("MyWindow");<BR> }<BR><BR> //绘制操作的本地入口点<BR> public
native void paint(Graphics
g);<BR><BR> public static
void main( String[] argv
){<BR> Frame
f = new
Frame();<BR> f.setSize(300,400);<BR><BR> JWindow
w = new
JWindow(f);<BR> w.setBackground(new
Color(0,0,0,255));<BR> w.getContentPane().setBackground(new
Color(0,0,0,255));<BR> w.getContentPane().add(new
MyWindow());<BR> w.setBounds(300,300,300,300);<BR> w.setVisible(true);<BR> }<BR>}<BR></CODE>
<P>请注意:您是在静态块中加载 <CODE>MyWindow.DLL</CODE>。这正是 Java
应用程序访问本地代码的方式。(我稍候就会开发这段本地代码。)同时还应注意:<CODE>paint</CODE> 方法是用 native
关键字声明的,并且没有提供任何实现;这样做是为了让虚拟机知道,应该从在静态块中加载的动态连接库中调用该本地方法。
<P><FONT size=+1><STRONG>第二步:生成该类的 JNI 头文件</STRONG></FONT><BR>要为以上定义的类生成
Java 本地接口头文件,需使用 <CODE>javah MyWindow.class</CODE> 命令。首先应确保这个类文件在您的
<CODE>CLASSPATH</CODE> 中。以下是所生成的 <CODE>MyWindow.h</CODE> 的一部分,给出了函数声明。
<P><CODE>/*<BR>* Class: MyWindow<BR>* Method: paint<BR>* Signature:
(Ljava/awt/Graphics;)V<BR>*/<BR>JNIEXPORT void JNICALL
Java_MyWindow_paint<BR> (JNIEnv *, jobject,
jobject);<BR></CODE>
<P><FONT size=+1><STRONG>第三步:开发完整的 MyWindow.CPP</STRONG></FONT><BR>以下是完整的
<CODE>MyWindow.CPP</CODE>,其中包含 <CODE>MyWindow.Java</CODE> 中所需要的绘图程序的本地代码。
<P><CODE>#include <windows.h><BR>#include
<assert.h><BR>#include "jawt_md.h"<BR>#include
"MyWindow.h"<BR><BR>#define X(x) (int)(xLeft + (x)*xScale/100) //
缩放宏<BR>#define Y(y) (int)(yTop + (y)*yScale/100) // 以使尺度在 0-100
之间<BR>#define CX(x) (int)((x)*xScale/100)<BR>#define CY(y)
(int)((y)*yScale/100)<BR><BR>void DrawSmiley(HWND hWnd, HDC hdc);<BR>HRGN
hrgn = NULL;<BR><BR>JNIEXPORT void JNICALL<BR>Java_MyWindow_paint(JNIEnv*
env, jobject canvas, jobject
graphics)<BR>{<BR> JAWT
awt;<BR> JAWT_DrawingSurface*
ds;<BR> JAWT_DrawingSurfaceInfo*
dsi;<BR> JAWT_Win32DrawingSurfaceInfo*
dsi_win;<BR> jboolean
result;<BR> jint
lock;<BR><BR> // 获取 AWT
<BR> awt.version =
JAWT_VERSION_1_3;<BR> result
= JAWT_GetAWT(env,
&awt);<BR> assert(result
!= JNI_FALSE);<BR> //
获取绘图界面<BR> ds =
awt.GetDrawingSurface(env,
canvas);<BR> if(ds ==
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -