Skip to Main Content

Java HotSpot Virtual Machine

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Getting HWND to Swing component with C++ as main

843829Feb 7 2006 — edited Feb 7 2006
I've ran into another issue with the Native interface , it occurs when mixing it with JNI.

Anyone know why the class load fails on the Native Invocatuon side if I include a JNI call on the Java side??


Here's the sequence

1 .Main.cpp -> 2 . MainNativeWindow.cpp (Native Interface) -> 3 . MyWindow.java (create Swing and call Native) -> 4. MyNativeWindow.cpp (get HWND and edit)

1. So the main app is C++.
2. The creates a JVM through the native interface
3. The Java Sides paint is overridden on the C++ side, this gives me a HWND to the Java Canvas.
4. The C++ side then writes to the Java Canvas.

My problem is the combination of the Native invocation and the JNI, if I include the JNI call on the Java side then the Native call to access the Java class fails (it works if I remove the JNI function) !!

Anyone know why the class load fails on the Native Invocatuon side if I include a JNI call on the Java side??

Is there an easier way to get access to the Java Canvas from the C++ side, besides using the Java Paint function to give me access , I've given snippets of the code below


1. and 2. C++ main
#include "MainNativeWindow.h"


//Native Interface
#include <stdio.h>
#include <jni.h>
JavaVM *jvm; /* Pointer to a Java VM */
JNIEnv *env; /* Pointer to native method interface */ 
int verbose = 1; /* Debugging flag */

int MainNativeWindow::InitJava()
{

  JavaVMInitArgs  vm_args;
  jclass cls; 
  jmethodID main_methodID, test_methodID = NULL;
  jint res;

  JavaVMOption options[4];

  options[0].optionString = "-Djava.compiler=NONE"; /* disable JIT */
  options[1].optionString = "-Djava.class.path=${JDK_HOME}/lib;C:/jsdk1.4.2/_jvm/lib;."; /* user classes */
  options[2].optionString = "-Djava.library.path=lib"; /* set native library path */
  options[3].optionString = "-verbose:jni"; /* print JNI-related messages */


  /* Setup the environment */
  vm_args.version = JNI_VERSION_1_4;
  vm_args.options = options;
  vm_args.nOptions = 4;
  vm_args.ignoreUnrecognized = 1;


  JNI_GetDefaultJavaVMInitArgs(&vm_args);//REPLACE THIS
   res = JNI_CreateJavaVM(&jvm,(void **) &env, &vm_args );//REPLACE THIS


  cls = env->FindClass("MyWindow");

  if(cls)
  {
    main_methodID = env->GetStaticMethodID(cls, "main", "([Ljava/lang/String;)V");//"([Ljava/lang/String;)V" indicates that the Java mehtod takes an array "[" pf Strings and returns void "V"

  if(main_methodID)
  {
	jstring first_str = env->NewStringUTF("The First String");//create string
	jobjectArray args = (jobjectArray)env->NewObjectArray(2,env->FindClass("java/lang/String"), first_str);//new array with 2 elements
						env->SetObjectArrayElement(args, 1, first_str);//insert the second string into index 1 of the array
						
	jstring second_str = env->NewStringUTF("The Second String");//create string
						env->SetObjectArrayElement(args, 2, second_str);//insert the second string into index 1 of the array
					env->CallStaticVoidMethod(cls, main_methodID, args);//pass the array to the Java main method
						
						
		
    
  }
  jvm->DestroyJavaVM( );
  
    return 1;
   
}
	

int main(int argc, char *argv[])
{
	MainNativeWindow *nativewin = new MainNativeWindow();
	 return nativewin->InitJava();    
}
3. JAVA side
import java.awt.*;
import javax.swing.*;

public class MyWindow extends Canvas {

	static {
		// Load the library that contains the paint code.
		System.loadLibrary("MyNativeWindow");
	}
	
	// native entry point for Painting
	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);
	}
}
4. C++ AWT interface (doesn't get here with the JNI in the Java class)
//AWT Native Interface
#include <windows.h>
#include <assert.h>
#include "jawt_md.h"
#include "MyWindow.h"

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;

	// Get the AWT
	awt.version = JAWT_VERSION_1_4;
	result = JAWT_GetAWT(env, &awt);
	assert(result != JNI_FALSE);
	// Get the drawing surface
	ds = awt.GetDrawingSurface(env, canvas);
	if(ds == NULL)
 	    return;
	// Lock the drawing surface
	lock = ds->Lock(ds);
	assert((lock & JAWT_LOCK_ERROR) == 0);

	// Get the drawing surface info
	dsi = ds->GetDrawingSurfaceInfo(ds);

	// Get the platform-specific drawing info
	dsi_win = (JAWT_Win32DrawingSurfaceInfo*)dsi->platformInfo;

	HDC hdc = dsi_win->hdc;
	HWND hWnd = dsi_win->hwnd;
	//////////////////////////////
	// !!! DO PAINTING HERE !!! //
	//////////////////////////////
	if(hrgn == NULL)
	{
		RECT rcBounds;
		GetWindowRect(hWnd,&rcBounds);
		long xLeft = 0;         // Use with scaling macros
		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);
	}
	// Free the drawing surface info
	ds->FreeDrawingSurfaceInfo(dsi);
	// Unlock the drawing surface
	ds->Unlock(ds);
	// Free the drawing surface
	awt.FreeDrawingSurface(ds);
}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Mar 7 2006
Added on Feb 7 2006
1 comment
733 views