在 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);
}
}