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

Anton V. Tarasov anton.tarasov at oracle.com
Thu Jan 31 03:18:40 PST 2013


On 30.01.2013 20:41, Richard Bair wrote:
> That seems good to me.

Thanks Richard and others for the review!

Anton.

>
> On Jan 30, 2013, at 4:08 AM, "Anton V. Tarasov"<anton.tarasov at oracle.com>  wrote:
>
>> 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