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

Danno Ferrin danno.ferrin at shemnon.com
Tue Jan 29 08:14:21 PST 2013


Could the API check to see if it is in the Swing EDT, and if not
invokeAndWait or invokeLater?

invokeAndWait presents the possibility of locking the FX ADT.
invokeLater has the possibility that a set followed by a quick get will
return the old value.

Another option would be to have the Swing code that needs to read the
property craft an invoke and wait onto the FX ADT when it needs to read the
value.  You could go crazy with optimistic checks on an AtomicInteger or an
AtomicBoolean for dirty values.

Threading is hard.  Let's go shopping.

--Danno

On Tue, Jan 29, 2013 at 8:53 AM, Tom Schindl <tom.schindl at bestsolution.at>wrote:

> Am 29.01.13 16:45, schrieb Anthony Petrov:
> > IMO this is wrong. I firmly believe that FX APIs should be callable on
> > either the FX Event Thread only, or any thread, depending on the API's
> > specification. Adding an FX API that can only be invoked on a specific
> > thread of another GUI toolkit doesn't seem right to me.
>
> I agree with you and I understood Richards comment like this as well.
> JavaFX APIs must be callable always at least on the FX-Thread.
>
> Tom
>
> >
> > Just expressing my opinion. If other folks agree this is a good idea,
> > then let it be.
> >
> > --
> > best regards,
> > Anthony
> >
> > On 1/29/2013 18:52, Anton V. Tarasov wrote:
> >> Hi All,
> >>
> >> Based on the feedback, I'm modifying the threading contract for the
> >> set/get methods.
> >> Only Swing thread is allowed for them, where JComponent is to be
> >> accessed/modified.
> >>
> >> I'm not adding a contentProperty. My reasoning is as follows:
> >>
> >> - AFAIK, all fx properties are limited to JavaFX App thread, I'm
> >> hesitating to break it...
> >> - there's not a real need in listening to this property, it's more
> >> like ones set and never changed
> >> - at worst, the property can be added lately, without modification to
> >> the set/get methods API
> >>
> >> Here's the updated javadoc:
> >>
> >>     /**
> >>      * Attaches a {@code JComponent} instance to display in this
> >> {@code SwingNode}.
> >>      * The method must be called on the Swing thread, otherwise it
> >> will throw
> >>      * {@code IllegalStateException}.
> >>      *
> >>      * @param content a component to display in this {@code SwingNode}
> >>      *
> >>      * @throws IllegalStateException if this method is called on a
> thread
> >>      *               other than the Swing thread
> >>      * @see java.awt.EventQueue#isDispatchThread()
> >>      */
> >>     public void setContent(final JComponent content);
> >>
> >>
> >>    /**
> >>      * Returns the {@code JComponent} instance attached to this {@code
> >> SwingNode}.
> >>      * The method must be called on the Swing thread, otherwise it
> >> will throw
> >>      * {@code IllegalStateException}.
> >>      *
> >>      * @throws IllegalStateException if this method is called on a
> thread
> >>      *               other than the Swing thread
> >>      * @see java.awt.EventQueue#isDispatchThread()
> >>      *
> >>      * @return the {@code JComponent} instance 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.
> >>>
> >>>
> >>
>
>
> --
> B e s t S o l u t i o n . a t                        EDV Systemhaus GmbH
> ------------------------------------------------------------------------
> tom schindl                 geschäftsführer/CEO
> ------------------------------------------------------------------------
> eduard-bodem-gasse 5-7/1   A-6020 innsbruck     fax      ++43 512 935833
> http://www.BestSolution.at                      phone    ++43 512 935834
>



-- 
There is nothing that will hold me back.  I know who I am....
I remember wher I came from, and I feel stronger for knowing.
Zane, Ninja of Ice.  Ninjago S01E07


More information about the openjfx-dev mailing list