[API Review] RT-27887: introduce a node to embed Swing into JavaFX

Anton V. Tarasov anton.tarasov at oracle.com
Wed Jan 30 04:08:02 PST 2013


Ok, I see your severe concern about the FX API consistency and I can't 
disagree with that a user
expects to access FX entities at least on the FX thread. Still I tend to 
think that in this particular
case, for this swing-bridge component, it's more naturally to call the 
setter on the Swing thread.
And so, with your permission, I'm preserving this option.

Below is the version with two-threaded access.

I'm not sure we have to mention that the setter delegates its execution 
to the Swing thread when
it's called on the FX thread, because this is just implementation 
details. Also, I think it's assumed
be default that the set/get ops are synchronized by the 'content' value, 
that is the value is accessible
for 'get' right after the 'set', regardless of which thread is used to 
call the methods. (and thus we can
omit such descriptions)

    /**
      * Attaches a {@code JComponent} instance to display in this {@code 
SwingNode}.
      * <p>
      * The method can be called either on the JavaFX Application thread 
or the Swing thread.
      * Note however, that access to a Swing component must occur from 
the Swing thread according
      * to the Swing threading restrictions.
      *
      * @param content a Swing component to display in this {@code 
SwingNode}
      *
      * @see java.awt.EventQueue#isDispatchThread()
      * @see javafx.application.Platform#isFxApplicationThread()
      */
     public void setContent(final JComponent content);

    /**
      * Returns the {@code JComponent} instance attached to this {@code 
SwingNode}.
      * <p>
      * The method can be called either on the JavaFX Application thread 
or the Swing thread.
      * Note however, that access to a Swing component must occur from 
the Swing thread according
      * to the Swing threading restrictions.
      *
      * @see java.awt.EventQueue#isDispatchThread()
      * @see javafx.application.Platform#isFxApplicationThread()
      *
      * @return the Swing component attached to this {@code SwingNode}
      */
     public JComponent getContent();


Thanks,
Anton.

On 1/24/13 10:49 PM, Anton V. Tarasov wrote:
> Hi All,
>
> Please, review a request to add a new SwingNode class:
>
> http://javafx-jira.kenai.com/browse/RT-27887
>
> /**
>  * This class is used to embed a Swing content into a JavaFX application.
>  * The content to be displayed is specified with the {@link 
> #setContent} method
>  * that accepts an instance of Swing {@code JComponent}. The hierarchy 
> of components
>  * contained in the {@code JComponent} instance should not contain any 
> heavyweight
>  * components, otherwise {@code SwingNode} may fail to paint it. The 
> content gets
>  * repainted automatically. All the input and focus events are 
> forwarded to the
>  * {@code JComponent} instance transparently to the developer.
>  * <p>
>  * Here is a typical pattern which demonstrates how {@code SwingNode} 
> can be used:
>  * <pre>
>  *     public class SwingFx extends Application {
>  *
>  *         private SwingNode swingNode;
>  *
>  * &#064;Override
>  *         public void start(Stage stage) {
>  *             swingNode = new SwingNode();
>  *
>  *             createAndSetSwingContent();
>  *
>  *             StackPane pane = new StackPane();
>  *             pane.getChildren().add(swingNode);
>  *
>  *             stage.setScene(new Scene(pane, 100, 50));
>  *             stage.show();
>  *         }
>  *
>  *         private void createAndSetSwingContent() {
>  *             SwingUtilities.invokeLater(new Runnable() {
>  * &#064;Override
>  *                 public void run() {
>  *                     swingNode.setContent(new JButton("Click me!"));
>  *                 }
>  *             });
>  *         }
>  *     }
>  * </pre>
>  */
> public class SwingNode extends Node {
>    /**
>      * Constructs a new instance of {@code SwingNode}.
>      */
>     public SwingNode();
>
>     /**
>      * Attaches a {@code JComponent} instance to display in this 
> {@code SwingNode}.
>      * The method can be called either on the event dispatch thread or 
> the JavaFX
>      * application thread.
>      *
>      * @param content a component to display in this {@code SwingNode}
>      *
>      * @see java.awt.EventQueue#isDispatchThread()
>      * @see javafx.application.Platform#isFxApplicationThread()
>      */
>     public void setContent(final JComponent content);
>
>     /**
>      * Returns the {@code JComponent} instance attached to this {@code 
> SwingNode}.
>      *
>      * @return the {@code JComponent} instance attached to this {@code 
> SwingNode}
>      */
>     public JComponent getContent();
> }
>
> Additional question is about disposing. When SwingNode is removed from 
> a Scene its underlying
> resources (on the AWT toolkit side) should be released. An option is 
> to add a "dispose" method to
> the node and leave it to a user's discretion when to call it. However, 
> having this managed
> automatically would be preferable. For that, a node should be able to 
> be notified when it is no
> longer a part of a rendering process. This is an issue and it is 
> tracked separately as RT-129.
>
> Thanks,
> Anton.
>
>



More information about the openjfx-dev mailing list