{ classes = ( { "java name" = "gnu.gnustep.GreatGameLibrary.GGLSprite"; "objective-c name" = GGLSprite; "instance methods" = (speed, "setSpeed:"); initializers = (init); } ); "method name mapping" = { speed = getSpeed; }; }
In this example, we only have the classes and method name mapping sections. We now examine in detail each section of the .jigs file.
classes = ( { "java name" = "gnu.gnustep.GreatGameLibrary.GGLScore"; "objective-c name" = "GGLScore"; "initializers" = ("init"); "instance methods" = ("setPoints:", "points"); "class methods" = ("bestScore", "bestTenScores"); }, { "java name" = "gnu.gnustep.GreatGameLibrary.GGLPlayer"; "objective-c name" = "GGLPlayer"; "class methods" = ("computerPlayer"); "instance methods" = ("name", "score", "addPoints:"); "initializers" = ("init", "initWithName:"); } );In this example, we want to generate wrappers for two classes: GGLScore and GGLPlayer. Information about each class is represented by a dictionary. Any entry in this dictionary (except the `java name' entry) can be omitted, in which case a default value will be used. We briefly now review the use of each entry.
"java name" = "gnu.gnustep.base.NSArray";You can decide to use a different name in Java than the name the class has in Objective-C. It's generally better to avoid this, but it should work fine if you ever need to do it.
"objective-c name" = "NSArray";If this entry is not present, it is guessed by taking the last part of java name. For example, if java name is gnu.gnustep.base.NSArray, then JIGS will use NSArray as Objective-C name if you don't specify an Objective-C name.
"initializers" = ("init", "initWithName:", "initWithArray:", "initWithName:array:");Each method in the initializers list will be exposed as a constructor. The Objective-C name of each initializer is discarded in Java, so you must make sure that these methods have all different signatures.
"class methods" = ( "contentRectForFrameRect:styleMask:", "frameRectForContentRect:styleMask:", "minFrameWidthWithTitle:styleMask:", "removeFrameUsingName:");Each of these methods is exposed as a static method in Java. Unless you use a method mapping (explained below), the Java name of each of these methods will be obtained by removing from the Objective-C name everything which comes after the first `:'. For example, the methods in the example would be wrapped as:
public static native NSRect contentRectForFrameRect (NSRect arg0, long arg1); public static native NSRect frameRectForContentRect (NSRect arg0, long arg1); public static native NSRect minFrameWidthWithTitle (String arg0, long arg1); public static native void removeFrameUsingName (String arg0);
Please make sure you do not include any methods of the new family in the class methods list. new methods can not be wrapped because they allocate and return non-autoreleased objects - it should not be a problem anyway, because if you need that constructor in Java, you can get it by simply wrapping the corresponding init method.
"instance methods" = ( "arguments", "environment", "hostName", "processName", "globallyUniqueString", "setProcessName:");Each of these methods is exposed as an instance method in Java. The Java names for these methods are obtained in the same way as for class methods.
Make sure you do not include any method of the copy and mutableCopy family in this list. Methods of these families can not be wrapped like the other ones because they return newly-created non-autoreleased objects. It is possible that in the future JIGS could provide a way to expose these methods; at present, you can not expose them - except the ones exposed by NSObject: NSObject exposes copy (as clone) and mutableCopy (as mutableClone) to Java, so if your Objective-C class implements copy and mutableCopy, they will automatically be made available to Java by the NSObject wrapper without any need to do anything.
"method declarations" = ( "- (void) setContentView: (NSView*)aView");This is because NSScrollView uses a conflicting declaration for this method, taking a NSClipView * argument.
Please note that, while in Objective-C these problems are harmless, and usually the worst it can happen is that the compiler warns you at compile time, after you expose your methods to Java these problems become first-rate problems, because in Java casts are dramatic and your program can crash if a method expecting a NSClipView argument receives a generic NSView instead.
"hardcoded constants" = ("int NotFound = 0x7fffffff");This hardcoded constants section will generate the following code in the Java class:
public static int NotFound = 0x7fffffff;This example is taken from the wrapping instructions for NSArray; it allows the Java programmer to access this constant simply as NSArray.NotFound. The value of this constant is of course the value of the C constant NSNotFound which is returned by many GNUstep Base Library methods when something is not found.
If your Objective-C library defines some constants, and some methods which you expose to Java return or accept these constants, you may want to make these constants available to Java as well by using the hardcoded constants section. Enumerations are exposed using the enumerations section, as explained in the next paragraphs.
Starting from JIGS 1.5.0, enumeration types are automatically recognized in the header file, and treated by the wrapper tool exactly as if they were simple ints. Usually, that is not enough - you want also to have the enumeration constants available from Java as static integer constants of some class. You can use the hardcoded constants section to manually add them to the class; this is quite clumsy, because you have to enter all the enumeration constants manually in the jigs file, and if you change the enumeration values in the Objective-C code, you have to manually update the jigs file.
Recent versions of JIGS (1.5.0 and newer) offer a new better option, in the form of the enumerations section. For example, the following line inside a class section
enumerations = (NSComparisonResult);will cause the following code to be automatically added to the generated Java class code:
public static int NSOrderedDescending = 1; public static int NSOrderedSame = 0; public static int NSOrderedAscending = -1;
Please notice that the wrapper tool has parsed your Objective-C header file, and extracted the constant values from there automatically! This means that you don't have to enter the constants in the first place, and if you ever change the enumeration, the Java wrappers will be immediately and automatically updated as soon as you recreate them.
For example, to insert a Java method of your own into the generated Java wrapper class, you could use the following entry:
"file to include in java code" = "MyClass.java.add";Then, you need to put the Java code you want to add into the file MyClass.java.add. Here is a trivial example:
/** * Returns the sum of the arguments. */ public int test (int a, int b) { return a + b; }This code would be inserted inside the Java class implementation when the Java wrapper is created.
The combination of this feature with the one to include arbitrary java code into the wrapper allows you to add hand-made wrapped methods to the java wrapper. This is a very advanced feature and is not documented here.
"method name mapping" = { "null" = "nullValue"; "addTimer:forMode:" = "addTimerForMode"; };Try to avoid method mappings, because they are confusing! But sometimes you can't do without, as in the case of null which can't be exposed with this name to Java because null is a reserved keyword in Java. In this case, you use the method mapping. Please note that JIGS needs to keep a global table of method name mappings while running in order to map selectors between Java and Objective-C; for this reason, you need to use the same mappings in all the classes.
"prerequisite libraries" = ("gnustep-base");You will probably usually need at least this line. Please note that the library is specified using the simplest possible name; JIGS at run-time will add the correct prefixes (lib) and suffixes (things like _d for debug version - if needed - and .A for the wrappers) to load in the library.
In the types section you can specify a list of C types specific to your library, and for each of them, a corresponding (known) C type. The wrapper tool will know it has to convert to/from Java the first C type in the same way as it does with the second. For example, in the gnustep-base.jigs file, there is the following line:
types = { NSTimeInterval = double; };This simply tells to the wrapper tool that whenever it finds an argument of type NSTimeInterval in an Objective-C method declaration, it has to treat it in the same way as if it were a double.
Starting from JIGS 1.5.0, the wrapper tool recognizes enumerations when it parses your header file, and it automatically treats them as new types corresponding to int. This means that you don't need to do anything special to have JIGS wrap methods taking or returning enumerations - enumerations should be recognized automatically, and treated automatically as ints.