Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Embed Java code into your native apps

Integrate a Java user interface with legacy code on Unix

  • Print
  • Feedback

Page 4 of 7

Listing 3: Obtain the underlying windowing information from an AWT Canvas

/** File nativeMethods.c **/
#include <X11/Xlib.h>
#include <jni.h>
#include "jawt_md.h"
#include "SwingMenu.h"
/* The Java object canvas must be  a java.awt.Canvas. */
JNIEXPORT void JNICALL Java_SwingMenu_attachShell(JNIEnv *env, jobject
obj, jobject canvas, jint shellWindow)
{
  JAWT                       awt;  /* defined in jawt.h which is included
in jawt_md.h */
  JAWT_DrawingSurface        *ds;
  JAWT_DrawingSurfaceInfo    *dsi;
  JAWT_X11DrawingSurfaceInfo *dsi_X11;
  jint    lock;
  Window  win;
  Display *dpy;
  awt.version = JAWT_VERSION_1_3;
  if (JAWT_GetAWT(env,&awt) == JNI_FALSE) {
     fprintf(stderr, "Can't get AWT ! Exiting.\n");
     exit(11);
  }
  ds = awt.GetDrawingSurface(env, canvas);
  if (ds == NULL) {
     fprintf(stderr, "Can't get drawind Surface ! Exiting.\n");
     exit(12);
  }
  lock = ds->Lock(ds);
  if ((lock & JAWT_LOCK_ERROR) != 0) {
    fprintf(stderr, "Can't lock drawing surface ! Exiting.\n");
    exit(13);
  }
  dsi = ds->GetDrawingSurfaceInfo(ds);
  if (dsi == NULL) {
    fprintf(stderr, "Can't get drawing Surface Information. Exiting !\n");
    exit(14);
  }
  dsi_X11 = (JAWT_X11DrawingSurfaceInfo*)dsi->platformInfo;
  dpy = dsi_X11->display;
  win = dsi_X11->drawable;
  ds->FreeDrawingSurfaceInfo(dsi);
  ds->Unlock(ds);
  awt.FreeDrawingSurface(ds);
}


The first thing to do is maintain a handle on an AWT structure that contains all the required information to complete the job. Then you can access a JAWT_DrawingSurface, which is the drawing surface. After two switches to a JAWT_DrawingSurfaceInfo and to a JAWT_X11DrawingSurfaceInfo, you obtain the X11 window and the X11 display. Note that before receiving the information, you must lock your drawing surface because Java is multithreaded, and the drawing surface's implementation might not be multithread-safe. In other words, if two separate threads access the drawing surface concurrently, your application may crash. The locking mechanism forces the threads to access the drawing surface one at a time.

Make the architecture more robust

Your Swing menu is now integrated with your legacy application. You have solved the window management issues, and you can call back your legacy application from the Java code. Now you want to create an OpenGL window by pressing one of the Swing buttons. To create such a window on Unix, you need to call OpenGL and glX functions (glX carefully integrates OpenGL with X11). Why can't you proceed like you did before? Simply implement a C function declared native in your Java code and called from the actionPerformed()method. The native function would handle the OpenGL window creation. Don't spend long hours on this approach, as it will most likely fail because of multithreading issues.

Java uses many threads -- one main thread, one for handling events, one for garbage collection, and so forth. That means different threads could concurrently access a function called from Java. Considering your application, for OpenGL and glX functions, the situation is even more complex as functions can also be called from the main thread of the legacy application.

  • Print
  • Feedback

Resources