CON3173_Northover-Integrating Swing With JavaFX

Integrating Swing with JavaFX
Steve Northover (Client Architect)
Kevin Rushforth (Consulting Member of Technical Staff)
Java Client Platform
Sept, 2014
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
Safe Harbor Statement
The following is intended to outline our general product direction. It is intended for
information purposes only, and may not be incorporated into any contract. It is not a
commitment to deliver any material, code, or functionality, and should not be relied upon
in making purchasing decisions. The development, release, and timing of any features or
functionality described for Oracle’s products remains at the sole discretion of Oracle.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
Program Agenda
1
Introduction
2
FX and Swing Working Together
3
The Threading Model
4
Implementation Details
5
Conclusion / Summary
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
The Importance of Interop
• Large number of existing AWT/Swing Applications
• Don’t want or cannot rewrite legacy applications
• Enable third-party AWT/Swing components
• Allow people to “get their feet wet” with JavaFX
• Provides a browser component for AWT/Swing
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
Goals
• Provide a simple migration path for legacy applications
• Provide full FX capability in the embedded application
• Provide two way embedding for AWT/Swing
• Ensure reasonable performance versus non-embedding
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
History
• Oct 2011: JavaFX 2.0 (JFXPanel – FX in AWT/Swing)
• Nov 2011: JavaFX 2.0.2 (FXCanvas – FX in SWT)
• Aug 2012: JavaFX 2.2 (Drag and drop, performance, threading)
• Mar 2014: JavaFX 8.0 (SwingNode – AWT/Swing in FX)
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
FX and Swing Working Together
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
Embedding Works Both Ways
• JFXPanel is used to embed FX in AWT/Swing
• SwingNode is used to embed AWT/Swing in JFX
What happens when a SwingNode is embedded
in a JFXPanel in a SwingNode in a JFXPanel …?
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
JFXPanel: A Swing Component
• JFXPanel is a lightweight JComponent
• Multiple JFXPanels supported in a single application
• Overrides event handlers and forwards to JavaFX
• Performance is comparable to stand alone JavaFX
• Supports accelerated painting, drag and drop, etc.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
JFXPanel: A Complete Example
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("AWT/Swing");
frame.setBounds(100, 100, 200, 225);
JFXPanel fxPanel = new JFXPanel();
frame.add(fxPanel);
frame.setVisible(true);
Platform.runLater(() -> {
Group group = new Group(new Circle(100, 100, 100, Color.RED));
Scene scene = new Scene(group, 200, 200);
fxPanel.setScene(scene);
});
});
}
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Oracle Confidential – Internal/Restricted/Highly Restricted
10
JFXPanel: SwingBrowser Example
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
SwingNode: A JavaFX Node
• SwingNode is a regular JavaFX node
• Multiple SwingNode supported in a single application
• Overrides event handlers and forwards to AWT/Swing
• Performance is comparable to stand alone AWT/Swing (*)
• Supports accelerated painting, drag and drop, etc. (*)
(*) Many problems in these areas have been fixed in 8u40
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
SwingNode: A Complete Example
public void start(Stage stage) {
SwingNode swingNode = new SwingNode();
SwingUtilities.invokeLater(() -> {
swingNode.setContent(new JButton("Click me!"));
});
StackPane pane = new StackPane();
pane.getChildren().add(swingNode);
stage.setScene(new Scene(pane, 100, 50));
stage.show();
}
Copyright © 2014, Oracle and/or its affiliates. All rights reserved. Oracle Confidential – Internal/Restricted/Highly Restricted
13
SwingNode: SwingSet and JFreeChart Example
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
Current Limitations
• Must turn off implicit exit (RT-29926, RT-30536)
– WORK AROUND: Use Platform.setImplictExit(false)
• Cannot traverse out of an embedding (RT-10919, RT-31462)
• Cannot show modal window as owner window (RT-26080)
– WORK AROUND: Wrap JFXPanel in a JDialog
• SwingNode performance / painting (RT-37046, RT-37810 …)
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
The Threading Model
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
The Interop Threading Model
• AWT/Swing has its own threading model and event loop
– AWT is “free threaded” (not really, it doesn’t work well)
– Swing is apartment threaded (a single UI-thread, called EDT)
– The event loop is native and runs in another thread (not the EDT)
• JavaFX also has its own threading model and event loop
– JavaFX is apartment threaded (a single UI-thread)
– The event loop is native and runs in the single UI-thead
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
The Interop Threading Model
Event Queue
JavaFX
invokeLater()
Operating
System
Event Queue
AWT
Swing
runLater()
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
Problems with the Current Model
• Must never use invokeAndWait() or risk deadlock
• Forces asynchronous programming (similar to the web)
• Applications become more complex for no good reason
• Threading is not consistently enforced
– JavaFX contains thread checks in many places but not everywhere
– Accessing data from the wrong thread can cause intermittent errors
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
Towards a Unified Threading Model
• Both JavaFX and Swing are apartment threaded
• Both toolkits run in separate apartments
• Neither toolkit should wait when running application code
– If JavaFX waits, GUI input is (correctly) blocked
– Swing code should never wait in an event handler
• The JavaFX apartment is the same as the native GUI-thread
– This cannot be changed, FX must run in this thread
Could Swing code run in the FX GUI-thread?
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
Unified Threading: Marry the Threads
“Why not make the JavaFX platform GUI thread be
the EDT thread for AWT/Swing? It is required that
the EDT be non-GUI for AWT/Swing, but there is
nothing that says it can’t be a GUI thread for
someone else.”
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
The Unified Threading Model
Event Queue
JavaFX
Operating
System
Event Queue
AWT
Swing
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
Unified Threading: It works but …
• The code has been released in JDK8
• Turned off by default
– Use -Djavafx.embed.singleThread=true
• The approach requires more testing
– Threading is complex so there be dragons
Try it out and let us know how you get on!
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
Implementation Details
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
Two Possible Approaches
• Heavyweight
– “easy” to implement, harder to use
– Limited set of interoperability features (*)
• No translucency, no effects, no transformation, etc.
• Lightweight
– “harder” to implement, easier to use
– Provides better integration with the embedding toolkit
• Full translucency, full effects, optimized scrolling etc.
(*) Suffers from the same problems as mixing lightweight/heavyweight in AWT/Swing
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
Lightweight Implementations
• Many different advantages over heavyweight
• Really, the only viable alternative to remain full featured
• One serious disadvantage
– Embedding toolkit must implement all new low level features
– Glass native code cannot be used
• Example:
– JavaFX Drag and drop must be implemented using AWT/Swing drag and drop
– JavaFX Touch must (but cannot) be implemented using AWT/Swing
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
JFXPanel: A Lightweight Implementation
Swing input events converted
to JavaFX input events
Swing
JavaFX textures converted
to image data for painting
by Swing
JavaFX
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
SwingNode: A Lightweight Implementation
JavaFX input events converted
to Swing input events
Swing
Swing images converted
to textures for painting
by JavaFX
JavaFX
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
Conclusions / Summary
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
Conclusions / Summary
• AWT/Swing and JavaFX interoperate (almost) freely
• The Unified Thread Model holds great promise
• Both Embedding directions are supported
• JFXPanel is mature and stable
• SwingNode is newer with a few problem areas
• AWT/Swing interop, although not preferred, is a viable
way to build JavaFX applications
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.
Safe Harbor Statement
The preceding is intended to outline our general product direction. It is intended for
information purposes only, and may not be incorporated into any contract. It is not a
commitment to deliver any material, code, or functionality, and should not be relied upon
in making purchasing decisions. The development, release, and timing of any features or
functionality described for Oracle’s products remains at the sole discretion of Oracle.
Copyright © 2014, Oracle and/or its affiliates. All rights reserved.