Local drawing support in JDK1.3

zhaozj2021-02-08  375

Before JDK1.3 appears, you can only use Java local interfaces to work in non-user interfaces. JDK 1.3 introduces new Java 2 AWT local interface, allowing you to use non-Java's GUI components in the Java program, although this will lose the portability of pure Java solutions. When using J2AWT, you must make a local dynamic connection library or shared library for each platform you want to use.

The following paragraph is taken from a header file of JDK1.3, which shows the development background and cause of this new API:

AWT supports access to the local structure of AWT using local C or C applications. This is to facilitate porting the original C or C applications to Java and meet the needs ... [These applications] Local drawing on the canvas on the canvas for performance.

Before JDK1.3, Java programming does not have a clear method to access the handle of the equivalent GUI component of the base layer. In JDK 1.3, Sun has created a standard mechanism that developers can draw local GUI applications and libraries in the Java AWT CANVAS object in this mechanism. This means there is now a formal, guaranteed approach to get information that supports this feature. When JDK 1.3 is docked with other operating platform, all interfaces provide the same information - no matter what system is used. The WINDOWS version and Solaris version of JDK 1.3 are the implementation of this support.

SUN has introduced this functional component for several reasons. First, JDK 1.3 enables people to transplant the complex original software of third-party products to Java, without having to wait until the third-party product itself is completed. The second reason is to be performance; if the local GUI code is optimized by people's long-term efforts, they are important to reserve these softwares have important business value.

In this article, I will introduce some basic concepts of this feature. I will gradually develop a widget such that the widget is drawn using the Win32 API. The figure below is a snapshot of the final widget, a circular window with a smiley face.

Running widget

Step the first step in steping, define a Java class - such as MYWINDOW - makes it inherited to the Canvas class and overload the Paint method. You use the PAINT method to perform the drawing of the AWT object and add the native key when overwriting the method. Covering method allows you to use your local code. You must build your local code and compile it into a dynamic connection library, just like other Java local interface applications, in this case, we will call the MyWindow.dll library. It is for a shared object or shared library over Solaris and Linux. You also need to call the MyWindow.dll library into the Java class named myWindow with System.LoadLibrary ("MyWindow").

Completion of this example requires two parts: One is MyWindow.java, which provides a subclass of the Canvas class, which is myWindow.cpp, which contains the entry point of the plotted subroutine based on the Java local interface. In the reference resource section, you can find MyWindow.java, MyWindow.cpp, and automatically perform compilation batch files build.bat.

The first step: Creating a MyWindow Java class J2AWT has a major limitations when using this method: local code can only operate subclasses of Java.awt.canvas classes. This is why MyWindow inherited the CANVAS class. In Java applications, you can use MyWindow like other subclasses using Canvas; in this case, I added myWindow to jwindow.

Import java.awt. *; import javax.swing. *; public class myWindow extends canvas {static {// Load contains the library containing the PAINT code. System.loadLibrary ("MyWindow");} // Draw a local entry point 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, 0, 255)); w.GetContentPane ) .add (new myWindow ()); W.SetBounds (300, 300, 300, 300); W.SetVisible (TRUE);}} Please note: You are load myWindow.dll in a static block. This is the way the Java application accesses the local code. (I will develop this local code later.) At the same time, it should also note that the Paint method is declared with the Native keyword and does not provide any implementation; this is to let the virtual machine know, should be loaded from the static block This local method is called in the dynamic connection library.

Step 2: Generate this class's JNI header to generate a Java local interface file for the class defined class, you need to use the javah myWindow.class command. First, make sure this class file is in your classpath. The following is part of the generated MyWindow.h, gives a function declaration.

/ ** Class: MyWindow * Method: Paint * Signature: (Ljava / AWT / Graphics;) V * / jniexport Void JNICALL JAVA_MYWINDOW_PAINT (JNIENV *, JOBJECT, JOBJECT);

Step 3: Develop a complete myWindow.cpp The following is a complete myWindow.cpp, which contains local code for the plot program required in MyWindow.java.

#include #include #include "jawt_md.h" #include "myWindow.h" #define x (x) (xift (x) * xscale / 100) // Zoom Macro #define y (int) (YTOP (Y) * Yscale / 100) // to make the scale between #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 JNICALLJava_MyWindow_paint (JNIEnv * env, jobject canvas, jobject graphics) {JAWT awt; JAWT_DrawingSurface * ds; JAWT_DrawingSurfaceInfo * dsi; JAWT_Win32DrawingSurfaceInfo * dsi_win; jboolean result; jint lock; // get AWT awt.version = JAWT_VERSION_1_3; result = JAWT_GetAWT (env, & awt); assert (! result = JNI_FALSE); // Gets Drawing interface DS = AWT.GETDRAWINGSURFACE (ENV, Canvas); if (DS == NULL) Return; // Lock Drawing Surface Lock = DS-> Lock (DS); Assert ((Lock & Jawt_Lock_ERROR) == 0); / / Get information on the drawing surface DSI = DS-> getDrawingsurfaceInfo (DS); // Get draw information DS of a specific platform i_win = (jawt_win32drawingsurfaceinfo *) DSI-> platformInfo; HDC HDC = DSI_WIN-> HDC; hwnd hwnd = dsi_win-> hwnd; // // !!! here to draw !!! // // if (hrgn = = NULL) {Rect rcbounds; getWindowRect (hwnd, & rcbounds); long xleft = 0; // Used to zoom macro LONG YTOP = 0; long xscale = rcbounds.right-rcbounds.Left; long Yscale = rcbounds.bottom-rcbounds. Top; hrgn = cretellipticRGN (x (10), y (15), x (90), y (95)); setWindowRgn (GetParent (hrgn);

InvalidateRect (HWND, NULL, TRUE);} else {Drawsmiley (HWND, HDC);} // Release the information of the drawing surface DS-> FREEDRAWINGSURFACEINFO (DSI); / / Unlock DS-> Unlock (DS) for the drawing surface; / / Release the drawing surface AWT.FREEDRAWINGSURFACE (DS);} void drawsmiley (hwnd hwnd, hdc HDC) {Rect rcbounds; getWindowRect (hwnd, & rcbounds); long xleft = 0; // Used to zoom macro LONG YTOP = 0; long xscale = rcbounds.right-rcbounds.left; long yscale = rcbounds.bottom-rcbounds.top; // Based on Control Size Brush Width INT IpenWidth = Max (CX (5), CY (5)); Hbrush Brushblack; Hbrush Brushyellow; HPEN PENBLACK = Createpen (PS_SOLID, IPENWIDTH, RGB (0x00, 0x00, 0x00)); // Used to draw an empty brush penn pennull = createpen (ps_null, 0, (colorref) 0); brushblack = createsolidbrush (RGB (RGB (RGB (RGB) 0x00, 0x00, 0x00); brushyellow = createsolidbrush (RGB (0xFF, 0xFF, 0x00)); HPEN PPENSAVE = (HPEN) SelectObject (HDC, Penblack); Hbrush Pbrushsave = (Hbrush) SelectObject (h DC, Brushyellow; Ellipse (HDC, X (10), Y (15), X (90), Y (95)); // Head Arc (HDC, X (25), Y (10), X ( 75), Y (80), // mouth (smile) x (35), y (70), x (65), y (70)); selectObject (HDC, & Pennull); // No drawing width SelectObject ( HDC, & brushblack; Ellipse (HDC, X (57), Y (35), X (65), Y (50)); Ellipse (HDC, X (35), Y (35), X (43), Y (50)); // Right Ellipse (HDC, X (46), Y (50), X (54), Y (65)); // Nose setBkMode (HDC, Transparent); // Using the foreground color SelectObject (HDC, PBRUSHSAVE); SELECTOBJECT (HDC, Ppensave);

The critical data structure here is jawt, which is defined in jawt.h (included by jawt_md.h). It allows the program to access all the information you need to draw on the Java-based GUI component based on Java-based GUI components. The first part of the local approach is a set of jawt structures, obtain a jawt_win32drawingsurfaceInfo structure, lock the surface (please use only one drawing tool once!), Then get a jawt_drawingsurfaceInfo structure, which contains the specific platform to draw a drawing Pointer (in the PlatformInfo field). It also includes a rectangular limit box for the drawing interface and the current shear area. For more information, check out jawt.h and jawt_md.h (see the part below title "Build Environment). Java_myWindow_paint is an entry point, JVM draws MyWindow by calling it. The auxiliary function Drawsmiley uses Win32 call to complete the actual drawing. To include GetDrawingsurfaceInfo in your application, use external library jawt.lib (see "Build Environment").

Step 4: Editing Build.bat first editing it before running Build.bat, as shown below, set the path for your Visual C and JDK1.3. Build.bat compiles myWindow.java to generate MyWindow.h, then compile myWindow.cpp to MyWindow.dll.

Set DevStudio = D: / Program Files / Microsoft Visual Studio / VC98SET JDK13 = D: /JDK1.3

Ok, everything is ready. Before running the sample, make sure that myWindow.dll, / jdk1.3 / bin and /jdk1.3/jre/bin are in PATH, but also guarantee the current directory in the classpath; this will ensure that myWindow.class will be Successfully loaded. After confidential Path and ClassPath are set up, enter Java MyWindow in the command line to run this application. For your convenience, Window.zip contains a batch file run.bat (see Resources). To set PATH and ClassPath for JDK 1.3, edit run.bat.

Build environment

Header file: Added C header file dedicated to Windows in the JDK's Include directory. They are: include / jawt.h. Include / win32 / jawt_md.h. According to the JavaSoft website, these headers are not part of the Java 2 platform formal specification; provide these headers just to use a standardization method to access Developers with local drawing feature provide a convenience. I think this means that manufacturers who port them to other platforms can not provide this API. Library: A new library named by jawt.lib has been added to the library directory of the SDK. As mentioned earlier, this library contains an entry point for the J2AWT to be included in your application. For example, to link to getDrawingsurfaceInfo entry points, you need to include Jawt.lib in your program. Tools: Javah tools are used to generate a C / C header file for the local function of the Java class, and the Javac tool is used to compile the Java source file.

转载请注明原文地址:https://www.9cbs.com/read-849.html

New Post(0)