Dec 22, 2006

Embedding .NET GUI components in Java GUIs

We’ve released JNBridgePro v3.1, which incorporates the support libraries described below, which makes embedding .NET GUI components in Java GUIs even simpler. See the announcement here. The 3.1 installer includes a version of this example targeted toward 3.1.

One feature request we frequently get is for a way to embed .NET GUI components in Java GUIs, or, conversely, to embed Java GUI components in .NET GUIs. In this post, we’ll show you how to put a .NET component inside a Java GUI, and to have the Java GUI react to events in the .NET component.

Start by downloading the sample code. Unpack the zip file. In addition to the sample code, there are a couple of dlls and jar files containing helper classes that assist in the interop. These helper classes will eventually be included in the JNBridgePro runtime components themselves, but in the meantime, you can use these assemblies when creating your own GUI interop projects.

We’ll start with a .NET control in JNBControl.cs, that looks like this:

Note that the control has several parts, including a label, a text box, and a button. The text box and its contents can be accessed through a field, and there is a method to register a delegate that will be called when the button is pressed. The control has been compiled, is called JNBTest.JNBControl and is in the assembly JNBTest.dll.

The proxies have already been generated, and are in the file dotNetControlProxies.jar. If you want, you can re-create the proxy jar file by launching the proxy generation tool and creating a new Java-to-.NET. Add JNBTest.dll to the assembly list, plus the assemblies System and System.Windows.Forms from the GAC (either the .NET 1.1 or 2.0 versions, depending on which version you’re using). Then, load JNBTest.JNBControl plus supporting classes, and generate proxies for all the classes.

Next, we examine the Java GUI-based application in javaTest\ This is a simple AWT-based application. Note the simple code sequence in the middle of the main() method:

// create the .NET control
JNBControl c = new JNBControl();
// register any callbacks
c.registerClickDelegate(new ClickEventHandler());
// wrap it so it can be embedded
DotNetControl dnc = new DotNetControl(c);
// size it
dnc.setSize(224, 104);
// embed it
f.add(dnc, dncConstraints);

First, create the .NET control by instantiating its proxy. Next, register callbacks; we have a Java-side event handler that, when fired, will get the contents of the .NET textbox and copy it to the Java text box. Once the .NET control has been set up, we wrap it in a special wrapper class com.jnbridge.embedding.DotNetControl. DotNetControl is derived from java.awt.Component (actually, java.awt.Canvas, which is a subclass of Component), and contains the linkages necessary to allow embedding of the .NET control in the Java component. We then size it like any other AWT component, and add it to the enclosing frame using graphical constraints that have already been prepared.

This is all that’s needed to embed a .NET component inside a Java GUI.

When compiling, make sure the build classpath contains the proxy jar file and the helper jar file jnbtools.jar, as well as the usual jnbcore.jar and bcel-5.1-jnbridge.jar.

Finally, let’s run the program. Note that GUI component embedding will only work with shared memory communications. Make sure that jnbshare.dll, jnbsharedmem.dll, and jnbjavaentry2.dll are in the GAC. Also, make sure that jnbtools.dll and jnbtools.jar are together in the same file. Finally, examine Note that we are loading JNBTest.dll and JNBTools2.dll, as well as System.Windows.Forms. Make sure that all paths in the file are correct for your machine.

To run the application, make sure that the classpath contains all the files in the build classpath. You can use runJava.bat, but first make sure that all the paths are correct for your machine.

Running the application, we see this:

Yes, that’s really a .NET control inside a Java AWT window! When we fill in the .NET text box and click on the button, the event fires and the Java-side callback is executed, copying the text into the Java text box. You can make more complex interactions, and even have bidirectional communications between the .NET and Java GUI elements.

The key to the interop is the DotNetControl wrapper class. Once you instantiate the .NET control’s proxy and wrap it, you can plug it in wherever an AWT component would go.

As I mentioned before, to do any embedding now, use the helper assemblies and jar files; in the future, they will be incorporated into the JNBridgePro runtime components.

We’d love to get your feedback on this. How many of you see a use for it?

In an upcoming article, we’ll go in the other direction and show how to embed Java GUI components in WinForms.