Here is a possible way to match java canvas and cocoa nsview
I use that technique in gl4java’s MAC OS X
(JDK 1.4.1) implementation.
- we need to find location of the canvas relative to the top frame
maybe there is a shorter way I’d be very graceful if somebody can show me that shorter way.
Component component = c;//canvas
Point globalLocation = component.getLocation();
while(!(component instanceof Frame) && component != null){
component = component.getParent();
if(component != null && !(component instanceof Frame)){
globalLocation.x+=component.getLocation().x;
globalLocation.y+=component.getLocation().y;
}
}
if(component instanceof Frame){
Frame frame = (Frame)component;
Insets insets = frame.getInsets();
if(insets != null){
globalLocation.y -= (insets.top + insets.bottom);
globalLocation.x -= (insets.left + insets.right);
}
}
so after that manipulation we have relative coordinate of our canvas to the top frame.
- now we have to find NSView with the same location and size in the contentView view hierarchy
(contentView could be obtained from JAWT via cocoaViewRef)
NSView *findAppropriateView(NSView *contentView,NSRect needRect)
{
NSView *finalView = NULL;
NSRect contentViewBound = [contentView bounds];
int titleHeight = contentViewBound.origin.y;
NSRect viewRect = NSOffsetRect (needRect , 0 , titleHeight);
finalView = findSubView(contentView,contentView,viewRect);
return finalView;
}
NSView *findSubView(NSView *contentView,NSView *view,NSRect viewRect){
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSView *retView = nil;
NSArray *subviews = [view subviews];
int i=0;
if(subviews != NULL){
int count = [subviews count];
for(i = 0; i < count; i++){
id object = [subviews objectAtIndex:i];
if ( [object isKindOfClass:[NSView class]] ){
NSView *subView = (NSView *)object;
if([[subView subviews] count] == 0){
NSRect subViewRect = [contentView convertRect : [subView frame] fromView : [subView superview]];
if(NSEqualRects(subViewRect,viewRect)){
retView = subView;
}
}else{
retView=findSubView(contentView,subView,viewRect);
}
if(retView != nil) break;
}
}
}
[pool release];
return retView;
}
NSRect GetViewRect(JNIEnv *env,jobject component,int xoffset,int yoffset)
{
NSRect viewRect;
Rect compBound;
GetComponentBounds(env, component,&compBound);
OffsetRect(&compBound, xoffset - compBound.left, yoffset - compBound.top);
viewRect = NSMakeRect(compBound.left,compBound.top,compBound.right - compBound.left,compBound.bottom - compBound.top);
return viewRect;
}
void GetComponentBounds(JNIEnv *env, jobject component,Rect *rect){
if(env == NULL || component == NULL) return;
rect->left = rect->top = rect->right = rect->bottom = 0;
jclass clazz = (*env)->GetObjectClass(env,component);
if(clazz == NULL) return;
jmethodID mID = (*env)->GetMethodID(env,clazz,“getBounds”,JRISigMethod(JRISigNoArgs) JRISigClass(“java/awt/Rectangle”));
if(mID == 0) return;
jobject rectangle = (*env)->CallObjectMethod(env,component,mID);
if(rectangle != NULL){
int width = 0,height = 0;
jclass rclazz = (*env)->GetObjectClass(env,rectangle);
if(rclazz == NULL) return;
jfieldID fieldID = (*env)->GetFieldID(env,rclazz,“x”,JRISigInt);
if(fieldID != NULL){
rect->left = (short)(*env)->GetIntField(env,rectangle,fieldID);
}
fieldID = (*env)->GetFieldID(env,rclazz,“y”,JRISigInt);
if(fieldID != NULL){
rect->top = (short)(*env)->GetIntField(env,rectangle,fieldID);
}
fieldID = (*env)->GetFieldID(env,rclazz,“width”,JRISigInt);
if(fieldID != NULL){
width = (short)(*env)->GetIntField(env,rectangle,fieldID);
}
fieldID = (*env)->GetFieldID(env,rclazz,“height”,JRISigInt);
if(fieldID != NULL){
height = (short)(*env)->GetIntField(env,rectangle,fieldID);
}
rect->right = rect->left + width;
rect->bottom = rect->top + height;
}
}