How to build Java application with WPF interface
Javonet Quick Start Guide
For more information how to use Javonet in common scenerios like creating objects, invoking methods, getting/setting fields, subscribing events and others please refer to our Javonet Quick Start Guide
Overview
This sample shows how to build .NET WPF window from Java code. If you look for a solution how to embed existing .NET WinForms or WPF user control within Java AWT, Swing or JavaFX window check our guide here: Embedding .NET User Controls in Java
Download Sample Project
Use the links below to download full source code and binaries of the sample project created in this tutorial:
Download Source Code and Binaries
Introduction
In this tutorial you will learn how to build Java application with WPF (Microsoft Windows Presentation Foundation) interface. Using Javonet almost impossible becomes possible. You can create fully functional Java application with rich, interactive user interface prepared in latest Microsoft WPF technology keeping native performance like it was all built in .NET.
Use cases
This solution might be helpful in each situation where you have business logic implemented in Java and just wants to expose the user interface using .NET, when you plan to migrate your Java application to .NET or if you have another system built on Java which forces you to develope user logic in Java but you would like to levarage possiblities of WPF interace.
Prerequisites
To build Java application with WPF interface all you need is Javonet developer license and Javonet desktop license for each end-user workstation.
Step by step instruction
1) Before using Javonet it’s good practice to prepare Javonet XML configuration file first. XML configuration file allows us to provide license details, apartment state and assemblies to be referenced in easy to access and modify way. Using XML config files it’s not required to activate or configure Javonet from code, just by first usage of Javonet API it will configure itself automatically.
Our XML configuration file will look like the one presented below. The only library we reference is “PresentationFramework” where .NET WPF implementation is located. Notice that we provide just name of the library not the full path, this way Javonet will use library located in GAC.
[email protected] your-javonet-license-key PresentationFramework STA v40
One of the most important change is ApartmentState, this value indicates in what kind of apartment state our .NET process main thread will be running, to create WPF window it must be set to STA (Single Thread Application).
Save the XML presented above in “javonet.xml” file.
2) Now we can create our Java Project in Eclipse using menu “File > Java Project”. Give the name “JavonetWpfApp” and press “Finish”.
3) When our project is ready we have to copy there “javonet.jar” and “javonet.xml” (prepared in first step). Next right click on your project go to “New > Class” and in the “New Java Class” window provide name “JavonetWpfAppMain” and check field “public static void main(String[] args)” so the default entry method will be created. Our project should look like this:
4) Next step is to add “javonet.jar” file reference to our project. Right click on the project choose “Build Path > Configure Build Path” and in the new window go to “Add JARs” and choose “javonet.jar” from the our project. Accept all windows and close until you will get back to the project view.
New item in our project should appear called “Referenced Libraries” with javonet library inside.
5) Now we can start creating our WPF interface in our Java application. In general all the steps required are exactly the same as it was done in .NET. Javonet works as bridge between .NET and Java converting any expressions to .NET side exactly as you type them in Java. Therefore we will need to create new “Window” instance and set it’s title. Place this code in your main method:
public static void main(String[] args) throws JavonetException { NObject window = Javonet.New("System.Windows.Window"); window.set("Title", "JavOnet WPF Window"); }
In line 2. we call “Javonet.New” to create new instance of “Window” class providing it’s full path as argument. The result of the method is handle to that Window. We can store instance of this window using special “NObject” variable which is used to store instance of any .NET object.
As you see in line 3. we can operate on any method or property of our “Window” object using our NObject variable. The only difference is that the names of .NET types, properties and methods are provided in string constant as you were using reflection. Calling method “set” we provide new Title for our window by setting new string value on “Title” property in our “Window” object instance. Javonet accepts any Java value-type as arguments or another NObject if we want to pass as argument instance of another .NET object.
6) Our window is ready :) Now we need to initialize WPF application and run the window with message pump like we do it in .NET. First create instance of “System.Windows.Application” class and call “Run” method providing as argument the instance of our “Window” object. Our code will look now like this:
public static void main(String[] args) throws JavonetException { NObject window = Javonet.New("System.Windows.Window"); window.set("Title", "JavOnet WPF Window"); NObject app = Javonet.New("System.Windows.Application"); app.invoke("Run",window); }
And that’s it! Now you can run the application and you will see WPF Window created from Java code. The result will look like this:
7) That was simple, wasn’t it? :) Now let’s add some action to our application. Below you will see how to create new WPF button, add it to the window and associate click event that will update some text on our window.
To add new button we must first create StackPanel and create a Button with some settings which we will add to that panel. We will place this code before creating “Application” instance:
//Create StackPanel NObject stackPanel = Javonet.New("StackPanel"); //Create Button and set it's text, width and height NObject button = Javonet.New("System.Windows.Controls.Button"); button.set("Content", "Dynamic WPF Button"); button.set("Width",300); button.set("Height",150); //Get "Children" property from stack panel and call method "Add" providing our new button as argument stackPanel.<NObject>get("Children").invoke("Add",button);
As you see we create our new Button in the same way as we created the Window object. Next we get “Children” property of the stackpanel and call “Add” method. As you see the generic “T get” was used, to immedietely convert result into “NObject” as the Children collection is instance of another .NET class. Alternatively there could be special get reference field method “getRef(String property)” used.
Before button will be visible in our window the stackpanel must be set as content of our window:
window.set("Content", stackPanel);
The full code will look like this:
public static void main(String[] args) throws JavonetException { NObject window = Javonet.New("System.Windows.Window"); window.set("Title", "JavOnet WPF Window"); NObject stackPanel = Javonet.New("StackPanel"); NObject button = Javonet.New("System.Windows.Controls.Button"); button.set("Content", "Dynamic WPF Button"); button.set("Width",300); button.set("Height",150); stackPanel.<NObject>get("Children").invoke("Add",button); window.set("Content", stackPanel); NObject app = Javonet.New("System.Windows.Application"); app.invoke("Run",window); }
Now after lunching the application you will see WPF window with created and added WPF button:
8) Finally let’s create WPF label, and attach listener to “Click” event for our Button which will set current date on our Label. First we will need to make some small modifications in our code, we will move “Label” creation code before Button creation and mark it as final so we can use it in anonymous class used as implemention for click event. The final code will look like this:
public static void main(String[] args) throws JavonetException { NObject window = Javonet.New("System.Windows.Window"); window.set("Title", "JavOnet WPF Window"); NObject stackPanel = Javonet.New("StackPanel"); final NObject label = Javonet.New("System.Windows.Controls.Label"); label.set("Content", "Press button to show date"); label.set("Width",300); label.set("Height",150); NObject button = Javonet.New("System.Windows.Controls.Button"); button.set("Content", "Press to Show Date and Time"); button.set("Width",300); button.set("Height",150); button.addEventListener("Click",new NEventListener() { public void eventOccurred(Object[] arguments) { try { String currentDate = Javonet.getType("DateTime").getRef("Now").invoke("ToString"); label.set("Content", currentDate); } catch (JavonetException e) { e.printStackTrace(); } } }); stackPanel.<NObject>get("Children").invoke("Add",button); stackPanel.<NObject>get("Children").invoke("Add",label); window.set("Content", stackPanel); NObject app = Javonet.New("System.Windows.Application"); app.invoke("Run",window); }
As you see in lines 7-10 we moved our Label creation code and set label variable as final. Next we added event listener for our button. We create event listener as anonymous class and add it to “Click” event of our button. In the eventOccurred code you will see that we retrieve current Date using .NET implementation of “DateTime” and set it as content of our label. Next in line 29. we added code to append our Label to stackpanel created in previous steps. That’s all what you need. Now after running the application by pressing the “Button” we will trigger logic that displays current date and time in our label.
Enjoy final result with native performance!
Download Sample Project
Use the links below to download full source code and binaries of the sample project created in this tutorial:
Download Source Code and Binaries