Blog

Java-in-.NET embedding and Java 7 and 8

Embedding Java components in .NET applications, when using Java 7 or 8, doesn’t work the same way it previously did with Java 5 or 6, as the focus handling has changed.

When Java components are embedded in .NET applications, and Java 7 or 8 is being used, focus-related events like keyboard events and mouse wheel events are no longer handled properly — they are no longer directed to the appropriate component, but rather are directed to the wrong place and dropped. (Other mouse events, including clicks, which are not focus-related, still function properly.)

Starting with Java 7, the Windows implementation of the AWT focus subsystem was changed.  Previously, every AWT and Swing component was mapped to an underlying Windows component (a “focus proxy”) that handled focus-related events and dispatched them to the appropriate AWT/Swing component. With Java 7 (and continuing into Java 8), the owning frame acts as the focus proxy for all components that are contained within it. Oracle claims that “the mechanism is transparent for a user,” but the change does dramatically affect the behavior of Java AWT and Swing components that are embedded inside Windows Forms and WPF applications. Our research indicates that the AWT focus subsystem is choosing the wrong Windows component as the focus proxy.

We are currently working on a fix to this problem, but we have no estimate on when that fix will be ready. In the meantime, if you are embedding Java components in .NET applications, we recommend using Java 6 for the moment. Note that if your embedded Java component does not depend on focus-related events (for example, it does not take text input or use keyboard shortcuts or respond to mouse wheel events), then you should be able to use Java 7 or 8.

Also note that embedding .NET UI components inside Java applications still works fine as before, whether Java 5, 6, 7, or 8 is being used.

We thank you for your patience while we work on this issue, and we apologize for the inconvenience.

Embedding Java GUI components in .NET GUIs

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

In my last post, I showed how to embed a .NET GUI component inside a Java GUI. In this post, I’ll show the inverse: how to embed a Java GUI component inside a .NET GUI.  We probably see more requests for this direction than for the other, since more customers have Java GUI components that they want to use in new .NET programming than the other way around.  As in the last post, after showing how to embed the Java component in the .NET GUI, we’ll show how you can have the .NET GUI react to events in the Java component.

Start by downloading the sample code. 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 Java component in JavaComponent.java, that looks like this:

 

Java GUI component

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 an ActionListener that will be called when the button is pressed.  The control has been compiled, and is called jInN.JavaComponent.

The proxies have already been generated and are in the file javaComponentProxies.dll. If you want, you can re-create the proxy dll by launching the proxy generation tool and creating a new .NET-to-Java project. Add jInN.JavaComponent to the classpath, then load jInN.JavaComponent plus supporting classes, and generate proxies for all the classes.

Next, we examine the .NET GUI-based application in Form1.cs. We’ve included a WinForms Panel that will hold the Java component. Note the simple code sequence inside the constructor:

// create the Java GUI component
JavaComponent jcp = new JavaComponent();
// register any callbacks
jcp.addActionListener(new DotNetActionList(jcp.javaTextBox, dotNetTextBox));
// wrap it so it can be embedded
jc = new JavaControl(jcp);
// embed it
javaHolder.Controls.Add(jc);

First, create the Java control by instantiating its proxy. Next, register callbacks; we have a .NET-side implementation of ActionListener that, when fired, will get the contents of the Java textbox and copy it to the .NET textbox. Once the Java control has been set up, we wrap it in a special wrapper class DotNet.JavaControl.  JavaControl is derived from System.Windows.Forms.Control, and contains the linkages necessary to embedding the Java component in the .NET control. We then add it to the enclosing Panel.

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

Open the .NET solution provided and build it.  You may need to adjust the references to jnbshare.dll and jnbsharedmem.dll. In our example, you’ll want to use the .NET 2.0-targeted version of these components. Also make sure that the various file paths in the app.config file are correct for your computer.

Finally, find a copy of jawt.dll in the jrebin folder of your Java development kit or the bin folder of your Java runtime environment and copy it to the folder into which your built project has been placed. Also copy the file jnbtools.dll into that folder.

Running the .NET application, we see this:

 

Java component embedded in .NET GUI

And that’s all there is to embedding a Java componet in a .NET Window. When we fill the Java text box and click on the button, the event fires and the .NET-side callback is executed, copying the text into the .NET 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 JavaControl wrapper class. Once you instantiate the Java component’s proxy and wrap it, you can plug it in wherever a WinForms 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 hear from you about this.  Let us know if you try it, and if you see a use for it in your upcoming projects.

Embedding .NET GUI components in Java GUIs

Update:  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:

 

dotNetControl

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 javaTestMainClass.java. 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 jnbcore_sharedmem.properties. 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:

 

Embedded .NET GUI component in a Java app

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.

Update: that new article, on embedding Java GUI components in .NET GUIs, has been posted.