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

Richard Bair richard.bair at oracle.com
Wed Jan 30 08:41:51 PST 2013


That seems good to me.

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