Java samples

For what i have read in this forum, many people seem to have problems to understand the Java examples. I will try to explain as good as i can what i know about the samples in this post. Hopefully this will help other people when they start.

I used Linux, Java 1.5 (it is also called 5.0) and gcc-4.1.2. $OCC is used for the directory of your OpenCASCADE installtion, e.g. /opt/OpenCASCADE-6.1.

1) Get the samples working out of an IDE:

First of all, copy the hole java source-code from $OCC/samples/standard/java/java into a new project of your favorite IDE. You will notice several errors. You will also need the package jcas, which is not in the samples directories. So create a package jcas and put there all java files from $OCC/ros/src/jcas. In util.ExtensionFileFilter you must correct the name of an Enumeration, since enum is now a keyword in Java (since 1.5). Now you should only have errors in the packages util.x11 and util.win32. Well, simply delete the packages. The stuff there is simply not needed. I think, it was used to get a native window in Java, but the classes used there were never an official part of Java and have been removed since several versions. In ViewCanvas (in the default package) delete the following line:
static GraphicsConfiguration theGraphicsConfiguration = getInternalGraphicsConfiguration();
Also delete the function "getInternalGraphicsConfiguration()". The code is never used and will cause an error, since it tries to create an instance of a class you have deleted before.

To run the samples you will have to set a few environment variables and arguments.

Argumts for the JVM:
-Xss1m -Djava.library.path=$OCC/samples/standard/java/Linux

Environment variables:

Now the samples should work in your IDE and you can start playing with them.

The samples are provided as tabulators of a JTabbedPane in one programm. So, to reduce complexity choose one of this examples and comment out the rest.

2) package-structure:

In the default package, you will find classes, that provide the window, panels, buttons and this stuff. Things that are used by all samples. The program starts in the class SampleStarter. The things, that are only used by one example are in the packages named as the respective sample with a suffix Jni. In the package jcas are manly classes for wrapping variable type from Java to the corresponding OpenCASCADE type. In CASCADESamplesJni you will find many classes with native functions. This stuff simply wraps everything you do to the corresponding functions in C++.

3) Java Native Interfaces (JNI)

Opencascade is written in C++. So if you want to use Java, you need somthing to call C++-Functions from java. JNI provides this possibility.

The keyword "native" in the function declaration incicates, that a C/C++-function should be called. The function has to be in an library wich you can load with System.loadLibrary("libraryName"). In the JDK you will find an programm named javah. With it you can create the C-header-file. Now you can copy the function name and signature to your source file and write down your code and create the library. I suggest that you try it with an nice howto, e.g. [1]. You should also take a look on the JNI-specifications [2].

In the OpenCASCADE samples jcas is used heavily in all JNI stuff. You should definitly look around, what is going on there. All classes in CASCADESamplesJni inherit from jcas.Object. jcas uses the variable HID for storing the address of a C++ object.

As an example look at the source code of the function CreateView() of the class V3d_Viewer in CASCADESamplesJni.

JNIEXPORT jobject JNICALL Java_CASCADESamplesJni_V3d_1Viewer_CreateView (JNIEnv *env, jobject theobj)
So, here you have an function which know only the environment(JNIEnv *env) and the Java-class, it is called from (jobject theobj). First the C++-object is needed.

Handle(V3d_Viewer) the_this = *((Handle(V3d_Viewer)*) jcas_GetHandle(env,theobj));
jcas_GetHandle reads the member variable HID of jcas.Object and cast it to void*.

Handle(V3d_View)* theret = new Handle(V3d_View);
*theret = the_this->CreateView();
Here the V3d_View C++-object is created.

thejret = jcas_CreateObject(env,"CASCADESamplesJni/V3d_View",theret);
jcas_CreateObject searches for the class CASCADESamplesJni and tries to get the empty constructor. The it creates a new instance of the class with the empty constructor and stores the address of theret as a long in HID of jcas.Object from which CASCADESamplesJni/V3d_View inherit.

One pitfall you should know about the JNI-stuff is, that you cannot simply change the package structure. The names are hardcoded in the function names and in the jcas_CreateObject calls. Be aware, that the Jni-Functions of the several samples packages and the SampleNativePaint also make CreateObject calls.

4) The native OpenCASCADE window

In Java you must create a class that inherits from Canvas and override the paint function to get full control of the window. In the samples the class ViewCanvas inherits from Canvas, but surprinsingly it only overrides update but not paint. This is done in CASCADEView3d respectively CASCADEView2d. Since it is an native function, all is done through JNI. To understand the source-code, have a look at [3].

5) Pitfalls of the Java source-code

The Java-source-code is rather complex. Be aware of childclasses overrides functions of their parents. For example SampleImportExportPanel overrides createViewPanel() of SamplePanel and in this function overrides createViewPort() of the new creatade ViewPanel. It seems also, that there is dead-code, that is never used. But be aware of the things in CASCADESamplesJni. Even if some classes are never used within the Java code, it is possible, that the C++-Functions use them. If you delete them, it can result in strange errors.

6) Classes to examine first

Concentrate on one of the samples in the beginning, for me it was SampleImportExport. If you prefer an other sample, change the second and maybe the fifth (if you need an 2D window instead of 3D) class on the list.

- SampleStarter
- SampleImportExportPanel
- SamplePanel
- ViewPanel
- ViewCanvas