JDK-8195811 : Support FX Swing interop using public API
  • Type: Enhancement
  • Component: javafx
  • Sub-Component: swing
  • Affected Version: 9,10,openjfx11
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2018-01-19
  • Updated: 2018-09-11
  • Resolved: 2018-07-16
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
openjfx11Fixed
Related Reports
Blocks :  
Blocks :  
Blocks :  
Relates :  
Relates :  
Description
FX Swing interop, which comprises JFXPanel and SwingNode, requires tight coupling between the Swing classes in the java.desktop module and the FX classes in the javafx.swing module.

The following internal packages are exported from java.desktop to javafx.swing:

exports java.awt.dnd.peer to javafx.swing;
exports sun.awt to javafx.swing;
exports sun.awt.dnd to javafx.swing;
exports sun.awt.image to javafx.swing;
exports sun.java2d to javafx.swing;
exports sun.swing to javafx.swing;

As part of an overall effort to reduce or eliminate the use of internal packages from core module by javafx.* modules, we need to limit the use of internal interfaces to those that really are needed, and then formalize these interfaces so we have a more robust solution.
Comments
Btw, Ambarish's pt 3 was valid... not because the class is unused, but because you don't need to import classes in the same package. That can be cleanup for another day. Thanks for getting this in.
16-07-2018

Changeset: 11877faf1ae6 Author: psadhukhan Date: 2018-07-16 14:30 +0530 URL: http://hg.openjdk.java.net/openjfx/jfx-dev/rt/rev/11877faf1ae6
16-07-2018

I guess pt 3 is invalid as DisposerRecord is used in createSwingNodeDisposer(). Rest I will take care during commit.
16-07-2018

+1 with small corrections mentioned below, need not post another webrev. 1. modules/javafx.graphics/src/main/java/com/sun/javafx/util/Utils.java => Update copyright year 2. modules/javafx.swing/src/main/java/com/sun/javafx/embed/swing/oldimpl/SwingNodeInteropO.java : Line 32 => unused import import com.sun.javafx.embed.swing.SwingEvents; 3. modules/javafx.swing/src/main/java/com/sun/javafx/embed/swing/SwingNodeInterop.java : Line 28 => unused import import com.sun.javafx.embed.swing.DisposerRecord;
16-07-2018

I have reviewed the latest updated webrev from: http://cr.openjdk.java.net/~psadhukhan/fxswinterop/webrev.9/ I finished my testing and my review, and it looks good to me. +1 on the .9 version
14-07-2018

>>>>Thread related APIs are mix of Swing & FX. Class SwingNodeHelper is more SwingNode specific >>I had thought of about it but since those are only used for swing package I did not consider creating separate file I had the same thought as Ambarish when I saw these -- they aren't really "Helper" methods, at least not in the sense of being helpers to access package-private methods in public classes from classes in other packages. I came to the same conclusion that Prasanta did, which is why I didn't mention it in my review. They are closely enough related that it didn't seem worth creating a new file.
14-07-2018

Thanks Ambarish for review. I will take care of the unused imports. >>API's type of node parameter is inconsistent across APIs. It is Node for few APIs & SwingNode for few. Whereever SwingNode is required, I have used SwingNode. Some API are override of NodeHelper so there Node is used. >>Thread related APIs are mix of Swing & FX. Class SwingNodeHelper is more SwingNode specific I had thought of about it but since those are only used for swing package I did not consider creating separate file For API, I think those are impl of swingnode, jfxpanel etc so I have used such. For variable name, I would change to camelcase.
13-07-2018

Hi Prasanta, Here are my two cents to the review, General comment, 1. Unused imports. There are unused imports in some files. for example, SwingNodeInteropN has 24 unused imports. By removing the unused imports, using full class name java.awt.event.KeyEvent at line 136 can be avoided. Many of the unused imports must be pre-existing. Using IDE will ease it out to locate. If not all, It would be good to at least change the places wherever it causes conflicts & affects code. => Files with unused imports are, SwingNodeInterop.java SwingNodeInteropN.java SwingNodeInteropO.java FXDnDInteropN.java FXDnDInteropO.java SwingNode.java JFXPanel.java FXDnD.java SwingFXUtils.java CachingTransferable.java SwingDragSource.java 2. Copyright year 2018 should be updated in many files. ----- Some file specific comments, 3. modules/javafx.swing/src/main/java/com/sun/javafx/embed/swing/SwingNodeHelper.java a. API's type of node parameter is inconsistent across APIs. It is Node for few APIs & SwingNode for few. b. Thread related APIs are mix of Swing & FX. Class SwingNodeHelper is more SwingNode specific. I think the Thread APIs should be part of some util class, like it was before in SwingFXUtils.java. But however if it is a time taking work to make modifications now, I would be fine to leave as current. c. Line 238 requires formatting 4. modules/javafx.swing/src/main/java/com/sun/javafx/embed/swing/InteropFactory.java The below APIs name can be altered as, public abstract SwingNodeInterop createSwingNodeImpl(); ->~ createSwingNodeIopImpl public abstract JFXPanelInterop createJFXPanelImpl(); ->~ createJFXPanelIop`Impl public abstract FXDnDInterop createFXDnDImpl(); ->~ createFXDnDIopImpl public abstract SwingFXUtilsImplInterop createSwingFXUtilsImpl(); ->~ createSwingFXUtilsIopImpl 5. modules/javafx.swing/src/main/java/com/sun/javafx/embed/swing/SwingFXUtilsImpl.java The below variable names can be changed as, SwingFXUtilsImplInterop sfuiop ->~ SwingFXUtilsImplInterop swFxUtilIop InteropFactory instance ->~ InteropFactory iopFactory => similar name in various files. Similar change in other files like JFXPanel.java, SwingNode.java InteropFactory instance ->~ InteropFactory iopFactory JFXPanelInterop jfxPaneliop ->~ JFXPanelInterop jfxPanelIop SwingNodeInterop swiop ->~ SwingNodeInterop swIop
13-07-2018

Please review an enhancement to support openjfx swing interoperability once the dependancy of internal jdk classes are removed. JDK-8202199 <https://bugs.openjdk.java.net/browse/JDK-8202199> provided a new "jdk.unsupported.desktop" module in JDK 11 that exports public API that is intended to be used by the javafx.swing module and unbundled OpenJFX is now made to depend on these APIs to support interoperation between Swing and JavaFX components to replace previous use of internal APIs when it was part of Oracle JDK. Bug: https://bugs.openjdk.java.net/browse/JDK-8195811 webrev: http://cr.openjdk.java.net/~psadhukhan/fxswinterop/webrev.3/
05-07-2018

WORKAROUND: Until this RFE is implemented, the workaround is to add the following 6 qualified exports on the 'java' command line or in an args file referred to with an '@' argument passed to the 'java' command line. --add-exports=java.desktop/java.awt.dnd.peer=javafx.swing --add-exports=java.desktop/sun.awt=javafx.swing --add-exports=java.desktop/sun.awt.dnd=javafx.swing --add-exports=java.desktop/sun.awt.image=javafx.swing --add-exports=java.desktop/sun.java2d=javafx.swing --add-exports=java.desktop/sun.swing=javafx.swing
27-04-2018

This will require new API in Swing to provide a supported solution using public API, so changing it to an RFE. Note that we will eventually need a separate RFE in client-libs/swing for the JDK portion of this fix.
13-04-2018

We will need a new approach as the above approach is not acceptable. We will explore some degree of formalization of the interface.
22-03-2018

Initial webrev: http://cr.openjdk.java.net/~kcr/8195811/webrev.00/ [not quite ready for formal review] This implements the approach suggested above by having the java.desktop export the 6 needed internal packages to the javafx.swing module. We use the existing Toolkit.getDesktopProperty method to initiate the qualified exports if the propertyName is "javafx.swing.initialize". The method checks that for an internal AWT permission (if a security manager is running) and also checks that the caller is a class in the "javafx.swing" module. Four comments: 1. We are still discussing with Mandy whether there is a better way to have the java.desktop module provide these qualified exports to the javafx.swing module 2. For testing purposes, so I could verify correct functionality when running with a JDK that doesn't export the 6 packages in it's module-info, I removed those entries from the dependencies/java.desktop/module-info.java.extra file in FX. This allows testing it by compiling a local JDK using the local FX bits, such that the qualified exports are gone, and then running all of our tests and apps using that built JDK. As noted in that file in the webrev, I will revert this change before integrating the fix so that we can continue to build, test, and run using a local JDK 10 repo. 3. This ideally needs regression tests on the JDK side to verify that qualified exports are only granted when the module name is "javafx.swing" and when the proper permission is set. Existing Swing interop tests on the FX side will verify correct functionality in the normal case. 4. I will file a follow-on RFE in JBS to formalize the API needed to implement Swing interop, but it seems unlikely we will do this if the only user is JavaFX-Swing interop.
01-03-2018

My initial thought is to use something similar to what we did for SWT interop given that javafx.swt needs qualified exports from javafx.graphics and we cannot do this at compile time, because javafx.swt is a modular jar not linked into the runtime. The basic idea is that we will identify the private interfaces in java.desktop needed by javafx.swing and provide some sort of registration mechanism that FX can use to tell Swing to make the qualified exports available to javafx.swing module at runtime. As with the qualified exports from javafx.graphics to javafx.swt, these qualified exports from java.desktop to javafx.graphics will require a RuntimePermission so that an untrusted application with no permissions can't gain access to the Swing packages that will be exported to javafx.swing.
20-01-2018