Monday, 30 September 2013

Embedding Swing Content in JavaFX Applications

This article describes how to embed Swing components in JavaFX applications. It discusses the threading restrictions and provides working applications that illustrate Swing buttons with HTML content embedded in a JavaFX application and interoperability between Swing and JavaFX buttons.

The ability to embed JavaFX content in Swing applications has existed since the JavaFX 2.0 release. To enhance the interoperability of JavaFX and Swing, JavaFX 8 introduces a new class that provides reverse integration and enables developers to embed Swing components in JavaFX applications.

Before you run any code from this article, install JDK 8 on your computer.

SwingNode Class

JavaFX 8 introduces the SwingNode class, which is located in the javafx.embed.swing package. This class enables you to embed Swing content in a JavaFX application. To specify the content of the SwingNode object, call the setContent method, which accepts an instance of thejavax.swing.JComponent class. You can call the setContent method on either the JavaFX application thread or event dispatch thread (EDT). However, to access the Swing content, ensure that your code runs on EDT, because the standard Swing threading restrictions apply.

The code shown in Example 1 illustrates the general pattern of using the SwingNode class.

Embedding Swing Content and Handling Events

The ButtonHtmlDemo in the Swing tutorial adds font, color, and other formatting to three buttons shown in Example 2 and Example 3. The buttons respond to mouse and keyboard events as shown in Example 5 and Example 6. Figure 2 shows the three buttons created using Swing in theButtonHtmlDemo now embedded in a JavaFX Application (SwingNodeSample). You will create theSwingNodeSample application and ensure that all events are delivered to an appropriate Swing button and get processed.

The simple format of middle button does not require HTML, so it is initialized with a string label and an image as shown in Example 3.

Example 3

b2 = new JButton("middle button", middleButtonIcon);

All three buttons have the tooltips and mnemonic characters as shown in Example 4.

Example 4

b1.setToolTipText("Click this button to disable the middle button.");
b2.setToolTipText("This middle button does nothing when you click it.");
b3.setToolTipText("Click this button to enable the middle button.");
b1.setMnemonic(KeyEvent.VK_D);
b2.setMnemonic(KeyEvent.VK_M);
b3.setMnemonic(KeyEvent.VK_E);

The left and right buttons are used to disable and enable the middle button respectively. To enable the application to detect and respond to user action on these buttons, attach action listeners and set action commands as shown in Example 5.

Adding Interoperability Between Swing and JavaFX Components

You can provide interoperability between JavaFX buttons and Swing buttons. For example, theEnableFXButton application shown in Figure 3 enables a user to click Swing buttons to disable or enable a JavaFX button. Conversely, the EnableButtons application shown in Figure 4 enables a user to click a JavaFX button to activate a Swing button.

The EnableFXButton application is created by modifying the SwingNodeSample application and making the middle button an instance of the javafx.scene.control.Button class. In the modified application, the Swing buttons (Disable FX button) and (Enable FX button) are used to disable and enable a JavaFX button (FX Button). Figure 3 shows the EnableFXButton application.

Modify the actionPerformed method to implement the disabling and enabling of fxbuttonas shown in Example 16. Note that the disabling and enabling of the JavaFX button must happen on the JavaFX application thread.

Run the application and click the Swing buttons to disable and enable the JavaFX button, as shown in Figure 3.

Using a JavaFX Button to Operate a Swing Button

You can further modify the EnableFXButton application and implement the setOnAction method for the JavaFX button so that clicking the JavaFX button activates the Swing button. The modified application (EnableButtons) is shown in Figure 4.

Conclusion

In this article you learned how to embed existing Swing components in JavaFX applications and provide interoperability between Swing and JavaFX objects. The ability to embed Swing content into JavaFX applications enables developers to migrate Swing applications that use complex third-party Swing components for which they do not have source code or applications that have legacy modules that exist only in maintenance mode.