In 2019 we’re getting Microsoft Edge on Chromium, which means the end of another browser engine, and another step in a trend to consolidation around open source. In this article we look further to the state of embedded browsers for Swing, SWT, JavaFX and Microsoft's WPF and how engine consolidation is affecting these desktop-oriented frameworks.
Embedded browsers have long been an effective way of achieving a controlled and phased migration of existing desktop applications to Vaadin web applications. The latest version of Vaadin places more demands on the browsers’ compliance with W3C specifications, and accommodating these demands in an embedded browser isn’t always directly obvious. As we’ll see in this article, for all these desktop frameworks (Swing, SWT, JavaFX and WPF), the checklist to get Vaadin 14 working is still fairly straightforward.
Checking compatibility
Vaadin 14 has a number of APIs you can use to understand embedded browsers and determine their characteristics and capabilities. The VaadinSession.getCurrent().getBrowser()
invocation is back since Vaadin 10 and gives you access to a WebBrowser object containing numerous helpful methods, including
getBrowserApplication()
, to get the user-agent string of the browser client- Methods that test whether a browser is of a known type like
isSafari()
,isEdge()
orisChrome()
- Methods that test what OS the browser is running on like
isAndroid()
,isWindows()
orisIOS()
Since embedded browsers tend to rely on engines most commonly used in regular browsers, the Vaadin framework will categorize embedded browsers according to the regular browser they best match. We’ll look at four examples:
JavaFX
The browser included with JavaFX (javafx.scene.web.WebView
) is based on Webkit, a browser engine used in Safari and a number of other browsers. The defaults included with the versions of Java 8 we tested are not compatible with Vaadin 14 however and the Vaadin framework may flag them as “too old”. Upgrading your project to Java 11 and JavaFX 11 did the trick to run Vaadin 14. Vaadin will recognize the WebView component as Safari.
Swing
With Swing, the easiest thing is to leverage JavaFX Swing interop in order to embed the JavaFX WebView. If you’re on Swing you might be used to JavaFX being pre-bundled in the same JDK and not needing extra JARs in order to get it to work. Vaadin 14 requires the embedded browser in JavaFX 11 or higher however, JavaFX 11 is built for Java 11, and in Java 11 JavaFX was removed from the standard JDK.
Now it’s gone, you’ll have to get it back: Upgrade your Swing project to Java 11, acquire the now separately distributed JARs of JavaFX 11 and include them in your Swing project.
Step 1
Download the JavaFX SDK from the site at which they are hosted (currently Gluon at https://gluonhq.com/products/javafx/)
Step 2
Add these JavaFX JARs to the build path and distribution of your Swing application:
- javafx.base.jar
- javafx.controls.jar
- javafx.graphics.jar
- javafx.media.jar
- javafx.swing.jar
- javafx.web.jar
- javafx-swt.jar
- javafx.fxml.jar
Step 3
As needed, either introduce new Vaadin views or swap existing views of your application out JPanel by JPanel. For example, if your application was built with a JTabbedPane which served different views on each tab, you might have added your view as follows:
myTabbedPane.addTab(“Customer Messages”, new CustomerMessagesView());
Once you have reimplemented CustomerMessagesView in Vaadin and hosted it, you can swap out the Swing view panel for an embedded browser. Considering CustomerMessagesView was a subclass of JPanel, you can reimplement with a JavaFX interop JFXPanel:
import javafx.application.Platform; import javafx.embed.swing.JFXPanel; import javafx.scene.Scene; import javafx.scene.web.WebView; class CustomerMessagesView extends JFXPanel { CustomerMessagesView() { Platform.runLater(() -> { WebView webView = new WebView(); this.setScene(new Scene(webView)); this.show(); webView.getEngine().load(CUSTOMER_MESSAGES_URL); }); } }
SWT
SWT has its own browser component org.eclipse.swt.browser.Browser
. Like the one in JavaFX it is based on WebKit and will register in Vaadin as Safari.
Browser swtBrowser = new Browser(shell, SWT.NONE); swtBrowser.setUrl(CUSTOMER_MESSAGES_URL);
The latest version we got while downloading the project was WebKit 605.1.15 which was capable of running a Vaadin 14 application and not flagged as “too old” by the Vaadin framework.
Depending on which version of SWT and JavaFX you are comparing you might find one or the other has a more recent WebKit version. If you’re after the slightly higher WebKit version included in JavaFX you can use the SWT variant of JavaFX’s interop also. Follow the same process as with Swing:
Step 1
Get the JavaFX JDK same as with Swing, described above
Step 2
Add these JavaFX JARs to your build path and distribution of your SWT application (key difference is you do include the -swt
JAR but not the .swing
JAR:
- javafx-swt.jar
- javafx.base.jar
- javafx.controls.jar
- javafx.graphics.jar
- javafx.media.jar
- javafx.web.jar
- javafx.fxml.jar
- javafx.swing.jar
Step 3
Start swapping the views of your application out Canvas by Canvas. You’ll swap the SWT Canvasses out for the JavaFX interop FXCanvases and include the WebView:
FXCanvas jfxCanvas = new FXCanvas(shell, SWT.NONE); Platform.runLater(() -> { WebView webView = new WebView(); jfxCanvas.setScene(new Scene(webView)); webView.getEngine().load(CUSTOMER_MESSAGES_URL); });
WPF
The browser included with WPF (System.Windows.Controls.WebBrowser) is based on IE and will be detected as IE by Vaadin. Confusingly, the user-agent of the WebBrowser component in the WPF Toolbox of even the latest VisualStudio 2019 identifies itself as “MSIE 7.0; Windows NT 6.2.”
You have to take this user-agent string with a grain of salt, since both IE7 and Windows NT 6.2 have been unsupported for years. On the systems we tested with IE11 installed, Vaadin detects the default WPF browser of .NET 4.7.2 as IE11, does not flag it as “too old”, and a Vaadin 14 application will run inside it.
The code is trivial:
In XAML:<WebBrowser Name=”webBrowser” />In C#
this.webBrowser.Navigate(CUSTOMER_MESSAGES_URL);
However since Vaadin 14 is the last Vaadin version to support IE11 you may, as Edge has done, want to start considering an alternative such as embedded Chromium.
The state of dev-friendly WPF wrappers for Chromium is more precarious than that of the WebKit support in Java desktop frameworks. A number of open-source projects supported it in past versions of Visual Studio, but the latest Visual Studio 2019 is not yet supported by open source project CefSharp without workarounds, and the alternative project Awesomium is no longer maintained as a .NET-oriented, open-source component.
Conclusion
Despite the ever-shifting dynamics of web browsers and consolidation towards open-source engines, there is still a high availability of embedded browser solutions to enable phased migrations of existing desktop applications to Vaadin 14.
Since the Java licensing changes, JavaFX updates have been happening frequently (JavaFX 11 in 2018, and JavaFX 12 in 2019). If JavaFX also continues to update to the latest WebKit versions on release, JavaFX applications or those on frameworks with interop compatibility will be reasonably updated to get support coverage by Vaadin.