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.
© Copyright 2024