Package it.tidalwave.ui.javafx
Class JavaFXSafeProxyCreator
java.lang.Object
it.tidalwave.ui.javafx.JavaFXSafeProxyCreator
This facility class create a thread-safe proxy for the JavaFX delegate (controller). Thread-safe means that it can
be called by any thread and the JavaFX UI related stuff will be safely invoked in the JavaFX UI Thread.
It is usually used in this way:
// This is a Spring bean public class JavaFxFooBarPresentation implements FooBarPresentation { private static final String FXML_URL = "/my/package/javafx/FooBar.fxml"; @Inject private FlowController flowController; private final NodeAndDelegate nad = createNodeAndDelegate(getClass(), FXML_URL); private final FooBarPresentation delegate = nad.getDelegate(); public void showUp() { flowController.doSomething(nad.getNode()); } public void showData (final String data) { delegate.showData(data); } }The method
createNodeAndDelegate(java.lang.Class, java.lang.String)
safely invokes the FXMLLoader
and returns a NodeAndDelegate
that contains both the visual Node
and its delegate (controller).
The latter is wrapped by a safe proxy that makes sure that any method invocation (such as showData()
in the
example is again executed in the JavaFX UI Thread. This means that the Presentation object methods can be invoked
in any thread.
For method returning void
, the method invocation is asynchronous; that is, the caller is not blocked waiting
for the method execution completion. If a return value is provided, the invocation is synchronous, and the caller
will correctly wait the completion of the execution in order to get the result value.
A typical JavaFX delegate (controller) looks like:
// This is not a Spring bean - created by the FXMLLoader public class JavaFxFooBarPresentationDelegate implements FooBarPresentation { @FXML private Label label; @FXML private Button button; @Inject // the only thing that can be injected, by means of JavaFXSafeProxyCreator private JavaFxBinder binder; @Override public void bind (final UserAction action) { binder.bind(button, action); } @Override public void showData (final String data) { label.setText(data); } }Not only all the methods invoked on the delegate are guaranteed to run in the JavaFX UI thread, but also its constructor, as per JavaFX requirements. A Presentation Delegate must not try to have dependency injection from Spring (for instance, by means of AOP), otherwise a deadlock could be triggered. Injection in constructors is safe.
- Author:
- Fabrizio Giudici
-
Field Summary
-
Method Summary
Modifier and TypeMethodDescriptionstatic <T> NodeAndDelegate
<T> createNodeAndDelegate
(Class<T> presentationClass) Creates aNodeAndDelegate
for the given presentation class.static <T> NodeAndDelegate
<T> createNodeAndDelegate
(Class<T> presentationClass, String fxmlResourcePath) Creates aNodeAndDelegate
for the given presentation class.static <T> T
createSafeProxy
(T target, Class<T> interfaceClass)
-
Field Details
-
BEANS
-
-
Method Details
-
createNodeAndDelegate
@Nonnull public static <T> NodeAndDelegate<T> createNodeAndDelegate(@Nonnull Class<T> presentationClass) Creates aNodeAndDelegate
for the given presentation class. The FXML resource name is inferred by default, For instance, is the class is namedJavaFXFooBarPresentation
, the resource name isFooBar.fxml
and searched in the same packages as the class.- Parameters:
presentationClass
- the class of the presentation for which the resources must be created.- Since:
- 1.0-ALPHA-13
- See Also:
-
createNodeAndDelegate
@Nonnull public static <T> NodeAndDelegate<T> createNodeAndDelegate(@Nonnull Class<T> presentationClass, @Nonnull String fxmlResourcePath) Creates aNodeAndDelegate
for the given presentation class.- Parameters:
presentationClass
- the class of the presentation for which the resources must be created.fxmlResourcePath
- the path of the FXML resource
-
createSafeProxy
-