Thread: [Java-gnome-developer] Julian's contributions
Brought to you by:
afcowie
From: Jeffrey M. <ku...@ne...> - 2001-03-30 02:27:32
|
First of all let me say thank you Julian for all of the patches. I appreciate all of the help I can get. All of those who are listening I am looking for volunteers. If you have the time and interest I need you! Sorry it has taken me so long to respond to all of your emails. I will address all of them here. 1) Subject: Freezing on runtime exception within signal handler Great addition. This code has been added and is now in cvs. 2) Subject: GtkContainer::Children() In this email you stated that you don't know where to update the generator to fix this problem. This has been fixed and is now in cvs. Let me explain how I fixed this problem and at the same time explain a nice feature of the code generator. In the src/tools directory you will find a file named JNIProps.txt. This file allows you to define how code is generated for specific scheme types that are used in the defs file. The file is very well commented and is easy to follow. The entry for "GList" was as follows: GList.javaType: gnu.gdk.GListString GList.nativeType: jobject GList.nativeUnwrap: GList *$TO = peerOfGListString (env, $FROM); GList.nativeWrap: \ $CLEANUP \ return makeGListString (env, ($CALL)); GList.rawType: GList * As you can see it assumed that GLists only contained strings. I changed this scheme type to GListString and made the cooresponding changes in the defs file. I then added a new set of entries for GList. The new entries for GList are as follows: GList.javaType: gnu.gtk.GtkWidget[] GList.nativeType: jobjectArray GList.nativeUnwrap: \ GList *$TO = NULL; \ jsize len = (*env)->GetArrayLength(env, $FROM); \ int i; \ \n-\n \ for (i = 0; i < len; i++) { \ GtkWidget *widget = (*env)->GetObjectArrayElement(env, $FROM, i);\ $TO = g_list_append($TO, widget); \ } GList.nativeWrap: \ GList *list = $CALL; \ int childrenLength = g_list_length(list); \ jclass widgetCls = (*env)->FindClass(env, "gnu/gtk/GtkWidget"); \ jobjectArray array = NULL; \ jobject widget; \ GtkWidget *nativeWidget; \ if (childrenLength > 0) { \ int i; \ for (i = 0; i < childrenLength; i++) { \ nativeWidget = (GtkWidget*)g_list_nth_data(list, i); \ widget = makeBaseObjectClass(env, nativeWidget); \ if (array == NULL) \ array = (*env)->NewObjectArray(env, childrenLength, \ widgetCls, widget); \ else \ (*env)->SetObjectArrayElement(env, array, i, widget); \ } \ } \ $CLEANUP \ return array; GList.rawType: GList * This mechanism makes it very simple to extend the capabilities of the generator by defining new scheme types and adding the appropriate code in this text file. 3) Subject: parent missing from GtkWidget This has been fixed and is also in cvs. I will explain how I fixed this problem and also introduce you to another feature of the generator. The generator is far from perfect at this time. There are many instances when the generator is unable to generate the appropriate code. To get around this I added the ability to insert manual code into the generated code. In the src/code directory you will find two additional directories; java and glue. T These directories are where you should place manual code. The code found in these files will be inserted into the end for the code generated by the code generator. I added the file GtkWidget.java to the java directory and GtkWidget.h and GtkWidget.c to the glue directory. These files contain the fix to you reported problem. 4) Subject: parent missing from GtkWidget - > But what I can't quite figure out is why the java objects are > created as GtkWidgets instead of being just returned as GtkWidgets. This is a very good point. I have been meaning to make this change but it hasn't been my highest priority. I have just added a method to BaseObject called makeBaseObjectClass. This method detects the correct Gtk type and builds a peer for it much the same way as the makeBaseObjectSubclass. I will be updating the code generator to use this method where appropriate over the next few days. I hope I have answered you questions and addressed all of you issues. If not please let me know. -Jeff |
From: Julian F. <jul...@be...> - 2001-03-30 03:02:12
|
Thanks a lot, this seems great. I've read it once over but I'll have a= closer look tomorrow and check out the changes in CVS and go back and see= if this addresses all the issues I had. The project I'm using this on is= for a software development course and we're supposed to be packaging it up= over the weekend. If I'm lucky, I may be able to give them an unmodified= version of the java-gtk code. I'll let you know if it's all working or if I had any other changes. I= think I still have an addition to the glade stuff that traverses all the= widgets and loads them into the cache and another that lets you get at the= array of widgets in the glade object. This workaround was at Avi's= suggestion because libglade doesn't seem to provide any way to get the= top-level widget unless you know it's name (I hope I'm remembering the= problem correctly) and I needed to browse the widget tree. Of course,= children() also didn't work at the time so I might be able to just add a= method to get the top-level widget somehow now. This code is currently= too much of a hack to be worth committing I think. Julian On 29/03/01 at 9:30 PM Jeffrey Morgan wrote: >First of all let me say thank you Julian for all of the patches. >I appreciate all of the help I can get. All of those who are >listening I am looking for volunteers. If you have the time and >interest I need you! > >Sorry it has taken me so long to respond to all of your emails. >I will address all of them here. > > >1) Subject: Freezing on runtime exception within signal handler >Great addition. This code has been added and is now in cvs. > > >2) Subject: GtkContainer::Children() >In this email you stated that you don't know where to update the >generator to fix this problem. This has been fixed and is now >in cvs. Let me explain how I fixed this problem and at the same >time explain a nice feature of the code generator. > >In the src/tools directory you will find a file named JNIProps.txt. >This file allows you to define how code is generated for specific >scheme types that are used in the defs file. The file is very well >commented and is easy to follow. The entry for "GList" was as follows: > >GList.javaType: gnu.gdk.GListString >GList.nativeType: jobject >GList.nativeUnwrap: GList *$TO =3D peerOfGListString (env, $FROM); >GList.nativeWrap: \ > $CLEANUP \ > return makeGListString (env, ($CALL)); >GList.rawType: GList * > >As you can see it assumed that GLists only contained strings. I changed >this scheme type to GListString and made the cooresponding changes >in the defs file. I then added a new set of entries for GList. The >new entries for GList are as follows: > >GList.javaType: gnu.gtk.GtkWidget[] >GList.nativeType: jobjectArray >GList.nativeUnwrap: \ > GList *$TO =3D NULL;= \ > jsize len =3D (*env)->GetArrayLength(env, $FROM);= \ > int i; \ > \n-\n \ > for (i =3D 0; i < len; i++) {= \ > GtkWidget *widget =3D (*env)->GetObjectArrayElement(env, $FROM,= i);\ > $TO =3D g_list_append($TO, widget);= \ > } >GList.nativeWrap: \ > GList *list =3D $CALL;= \ > int childrenLength =3D g_list_length(list);= \ > jclass widgetCls =3D (*env)->FindClass(env, "gnu/gtk/GtkWidget");= \ > jobjectArray array =3D NULL;= \ > jobject widget; \ > GtkWidget *nativeWidget; \ > if (childrenLength > 0) { \ > int i; \ > for (i =3D 0; i < childrenLength; i++) {= \ > nativeWidget =3D (GtkWidget*)g_list_nth_data(list, i);= \ > widget =3D makeBaseObjectClass(env, nativeWidget);= \ > if (array =3D=3D NULL)= \ > array =3D (*env)->NewObjectArray(env, childrenLength,= \ > widgetCls, widget); \ > else \ > (*env)->SetObjectArrayElement(env, array, i, widget); \ > } \ > } \ > $CLEANUP \ > return array; >GList.rawType: GList * > >This mechanism makes it very simple to extend the capabilities >of the generator by defining new scheme types and adding the >appropriate code in this text file. > > >3) Subject: parent missing from GtkWidget >This has been fixed and is also in cvs. I will explain how I >fixed this problem and also introduce you to another feature of >the generator. The generator is far from perfect at this time. >There are many instances when the generator is unable to generate >the appropriate code. To get around this I added the ability to >insert manual code into the generated code. In the src/code >directory you will find two additional directories; java and glue. T >These directories are where you should place manual code. The >code found in these files will be inserted into the end for the >code generated by the code generator. I added the file GtkWidget.java >to the java directory and GtkWidget.h and GtkWidget.c to the glue >directory. These files contain the fix to you reported problem. > > >4) Subject: parent missing from GtkWidget - >> But what I can't quite figure out is why the java objects are >> created as GtkWidgets instead of being just returned as GtkWidgets. >This is a very good point. I have been meaning to make this change >but it hasn't been my highest priority. I have just added a method >to BaseObject called makeBaseObjectClass. This method detects the >correct Gtk type and builds a peer for it much the same way as >the makeBaseObjectSubclass. I will be updating the code generator >to use this method where appropriate over the next few days. > >I hope I have answered you questions and addressed all of you >issues. If not please let me know. > >-Jeff > > >_______________________________________________ >java-gnome-developer mailing list >jav...@li... >http://lists.sourceforge.net/lists/listinfo/java-gnome-developer |
From: Julian F. <jul...@be...> - 2001-03-31 05:12:24
|
Ok, I grabbed the newest version out of CVS this afternoon and it now works= with only my patches to the LibGlade stuff which I will include at the= bottom of this email. Hopefully I will now be able to use a version= straight out of the repository. Changes are as follows: - The biggest change in there is changing all the longs to ints. This was= necessary to make it work on Solaris. I would appreciate if someone could= test this on linux or whatever else to see if it breaks it there or if it= still works. - I added a parameter to the LibGlade constructor which takes a widget name= and beings loading the file from that point in the tree. This is a= parameter that the C libglade library already takes, but Avi added it in a= version of the code after you grabbed it from him. - I added some exception handling and error checking code. I suspect this= suffers from the same problem of rethrowing the exception before the= exceptions are cleared or something? In trying to come up with a way to= allow the Java user to decide whether the inability to bind a signal= should kill the file loading (I definitely do not want it to do this) I= came up with the idea of having a method in the Java side of LibGlade= that was called. The user can subclass LibGlade to make the method= display an error message however the user likes. The return value= determines whether the C code throws an exception or not. You can nix= this if you like, it was just the best I could come up with. - And finally, I reenabled some code you had commented out regarding the= target parameter of the signal connection. This functionality is needed= to allow the Gtk objects to send messages to each other (this is allowed= for in Glade). Let me know if anything is unclear or if you'd like me to change something. And finally, you wrote: >4) Subject: parent missing from GtkWidget - >> But what I can't quite figure out is why the java objects are >> created as GtkWidgets instead of being just returned as GtkWidgets. >This is a very good point. I have been meaning to make this change >but it hasn't been my highest priority. I have just added a method >to BaseObject called makeBaseObjectClass. This method detects the >correct Gtk type and builds a peer for it much the same way as >the makeBaseObjectSubclass. I will be updating the code generator >to use this method where appropriate over the next few days. What I don't understand is why you would ever want to use= makeBaseObjectSubclass(). There still dozens of methods using it in the= code and I just can't think of any reason why you would not want to user= to be able to typecast the object back to its proper type. The patch follows immediately below. Thanks, Julian Index: LibGlade.java =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/java-gnome/java-gnome/src/other/LibGlade.java,v retrieving revision 1.2 diff -u -r1.2 LibGlade.java --- LibGlade.java 2001/02/15 09:02:54 1.2 +++ LibGlade.java 2001/03/31 04:56:04 @@ -16,6 +16,7 @@ * * @author Avi Bryant * @author Jean van Wyk + * @author Julian Fitzell * */ @@ -31,11 +32,16 @@ protected Map widgets =3D new Hashtable(); protected Object owner; - - public LibGlade(String file, Object owner) + + public LibGlade(Object owner, String file, String root) { this.owner =3D owner; - glade =3D construct(file); + try { + glade =3D construct(file, root); + } + catch(Exception e) { + System.err.println("LibGlade error: " + e); + } } public GtkWidget getWidget(String name) @@ -44,7 +50,7 @@ if(widget =3D=3D null) { - long nativepeer =3D getNativeWidget(name); + int nativepeer =3D getNativeWidget(name); if(nativepeer !=3D 0) widget =3D getWidget(nativepeer); } @@ -58,20 +64,20 @@ if(widget =3D=3D null) { - long nativepeer =3D getNativeWidgetByLongName(name); + int nativepeer =3D getNativeWidgetByLongName(name); if(nativepeer !=3D 0) widget =3D getWidget(nativepeer); } return widget; } - - protected native long construct(String file); + + protected native long construct(String file, String root); - protected native long getNativeWidget(String name); - protected native long getNativeWidgetByLongName(String longName); - protected native String getWidgetName(long nativepeer); - protected native String getWidgetLongName(long nativepeer); + protected native int getNativeWidget(String name); + protected native int getNativeWidgetByLongName(String longName); + protected native String getWidgetName(int nativepeer); + protected native String getWidgetLongName(int nativepeer); protected void connect(String handler, String signal, String data, GtkWidget source, Object target) @@ -85,10 +91,21 @@ source.signalConnect(signal, handler, target); } - protected GtkWidget getWidget(long nativepeer) + protected boolean connectError(Throwable exc) { + System.err.println("Error connecting Glade signal: " += exc.getMessage()); + + //by default we don't want to abort the LibGlade construction + return false; + } + + protected GtkWidget getWidget(int nativepeer) + { String widgetLongName =3D getWidgetLongName(nativepeer); + if (widgetLongName =3D=3D null) + return null; + GtkWidget widget =3D (GtkWidget) widgets.get(widgetLongName); if(widget =3D=3D null) { @@ -103,5 +120,5 @@ return widget; } - protected native GtkWidget makeWidget(long nativepeer); + protected native GtkWidget makeWidget(int nativepeer); } Index: gnu_glade_LibGlade.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/java-gnome/java-gnome/src/other/gnu_glade_LibGlade.c,v retrieving revision 1.2 diff -u -r1.2 gnu_glade_LibGlade.c --- gnu_glade_LibGlade.c 2001/02/15 09:02:54 1.2 +++ gnu_glade_LibGlade.c 2001/03/31 04:56:04 @@ -33,6 +33,9 @@ jclass cls; jmethodID getWidgetMID; jmethodID connectMID; + jthrowable exc; //exception + jmethodID errorMID; + jboolean errorRet; jstring handler, signal, data; jobject source, target; @@ -51,68 +54,120 @@ data =3D 0L; cls =3D (*env)->GetObjectClass(env, obj); + if (cls =3D=3D 0) + return; + getWidgetMID =3D (*env)->GetMethodID(env, cls, "getWidget", - "(J)Lgnu/gtk/GtkWidget;"); + "(I)Lgnu/gtk/GtkWidget;"); connectMID =3D (*env)->GetMethodID(env, cls, "connect", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lgnu/gtk/Gtk= Widget;Ljava/lang/Object;)V"); + if (getWidgetMID =3D=3D 0 || connectMID =3D=3D 0) + return; + + errorMID =3D (*env)->GetMethodID(env, cls, "connectError",= "(Ljava/lang/Throwable;)Z"); + //no need to return if 0... we just don't use it later source =3D (*env)->CallObjectMethod(env, obj, getWidgetMID, _source); -// We want the class that called the XML file to handle it therefore it -// should be 0L regardless. -// if(_target) -// target =3D (*env)->CallObjectMethod(env, obj, getWidgetMID,= _target); -// else - target =3D NULL; + exc =3D (*env)->ExceptionOccurred(env); + if (exc) + { + if (errorMID) + { + errorRet =3D (*env)->CallBooleanMethod(env, obj, errorMID,= exc); + if (errorRet =3D=3D JNI_TRUE) + (*env)->Throw(env, exc); + } + (*env)->ExceptionClear(env); + } + + if(_target) + { + target =3D (*env)->CallObjectMethod(env, obj, getWidgetMID,= _target); + exc =3D (*env)->ExceptionOccurred(env); + if (exc) + { + if (errorMID) + { + errorRet =3D (*env)->CallBooleanMethod(env, obj, errorMID,= exc); + if (errorRet =3D=3D JNI_TRUE) + (*env)->Throw(env, exc); + } + (*env)->ExceptionClear(env); + } + } + else + target =3D 0L; (*env)->CallVoidMethod(env, obj, connectMID, handler, signal, data,= source, target); + + exc =3D (*env)->ExceptionOccurred(env); + if (exc) + { + if (errorMID) + { + errorRet =3D (*env)->CallBooleanMethod(env, obj, errorMID,= exc); + if (errorRet =3D=3D JNI_TRUE) + (*env)->Throw(env, exc); + } + (*env)->ExceptionClear(env); + } } JNIEXPORT jlong JNICALL Java_gnu_glade_LibGlade_construct - (JNIEnv *env, jobject o, jstring file) + (JNIEnv *env, jobject o, jstring file, jstring root) { GladeXML *xml; struct jglade_info i; char *filename; + char *rootname; i.env =3D env; i.o =3D o; filename =3D (*env)->GetStringUTFChars(env, file, 0); + if(root) + rootname =3D (*env)->GetStringUTFChars(env, root, 0); + else + rootname =3D 0L; + glade_init(); - xml =3D glade_xml_new(filename, 0L); + xml =3D glade_xml_new(filename, rootname); if(xml) { glade_xml_signal_autoconnect_full(xml, xml_connect, &i); } (*env)->ReleaseStringUTFChars(env, file, filename); + if(rootname) + (*env)->ReleaseStringUTFChars(env, root, rootname); return (jlong) xml; } + JNIEXPORT jstring JNICALL Java_gnu_glade_LibGlade_getWidgetName - (JNIEnv *env, jobject o, jlong nativepeer) + (JNIEnv *env, jobject o, jint nativepeer) { - GtkObject *gtk =3D (GtkObject *)nativepeer; + GtkObject *gtk =3D (GtkObject *)(nativepeer); return (*env)->NewStringUTF(env, glade_get_widget_name(gtk)); } JNIEXPORT jstring JNICALL Java_gnu_glade_LibGlade_getWidgetLongName - (JNIEnv *env, jobject o, jlong nativepeer) + (JNIEnv *env, jobject o, jint nativepeer) { - GtkObject *gtk =3D (GtkObject *)nativepeer; + GtkObject *gtk =3D (GtkObject *)(nativepeer); return (*env)->NewStringUTF(env, glade_get_widget_long_name(gtk)); } -JNIEXPORT jlong JNICALL Java_gnu_glade_LibGlade_getNativeWidget +JNIEXPORT jint JNICALL Java_gnu_glade_LibGlade_getNativeWidget (JNIEnv *env, jobject o, jstring namestr) { char *name =3D (*env)->GetStringUTFChars(env, namestr, 0); - jlong result; + jint result; jclass cls; jfieldID fid; GladeXML* xml; @@ -121,18 +176,18 @@ fid =3D (*env)->GetFieldID(env, cls, "glade", "J"); xml =3D (*env)->GetLongField(env, o, fid); - result =3D (jlong) glade_xml_get_widget(xml, name); + result =3D (jint) glade_xml_get_widget(xml, name); (*env)->ReleaseStringUTFChars(env, namestr, name); return result; } -JNIEXPORT jlong JNICALL Java_gnu_glade_LibGlade_getNativeWidgetByLongName +JNIEXPORT jint JNICALL Java_gnu_glade_LibGlade_getNativeWidgetByLongName (JNIEnv *env, jobject o, jstring longnamestr) { char *longname =3D (*env)->GetStringUTFChars(env, longnamestr, 0); - jlong result; + jint result; jclass cls; jfieldID fid; GladeXML* xml; @@ -141,7 +196,7 @@ fid =3D (*env)->GetFieldID(env, cls, "glade", "J"); xml =3D (*env)->GetLongField(env, o, fid); - result =3D (jlong) glade_xml_get_widget_by_long_name(xml, longname); + result =3D (jint) glade_xml_get_widget_by_long_name(xml, longname); (*env)->ReleaseStringUTFChars(env, longnamestr, longname); @@ -149,9 +204,9 @@ } JNIEXPORT jobject JNICALL Java_gnu_glade_LibGlade_makeWidget - (JNIEnv *env, jobject o, jlong nativepeer) + (JNIEnv *env, jobject o, jint nativepeer) { - GtkObject *gtk =3D (GtkObject *)nativepeer; + GtkObject *gtk =3D (GtkObject *)(nativepeer); char classname[100]; jclass cls; |
From: Jeff M. <ku...@ne...> - 2001-03-31 12:26:48
|
> What I don't understand is why you would ever want to use > makeBaseObjectSubclass(). There still dozens of methods using it > in the code and I just can't think of any reason why you would > not want to user to be able to typecast the object back to its > proper type. > You are correct. I just haven't had the time to make all of the changes and test them. I will probably change all of this over the weekend. |