Suppose we have two OSGi bundles A and B. A provides a service which will be referenced by B. B is a JavaFX pane which holds a table with data populated from a database. To get data into the table we need the service provided by A.
I am wondering what would be the preferred way to inject the service into B?
If B were an OSGi component I could reference the service via @Reference or xml. But that does not work because B is then instantiated by the OSGi framework which happens before the JavaFX toolkit is initialized. Obviously this would also interfere with the Drombler framework which will initialize the pane also.
How can I solve it without using FrameworkUtils for example.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Currently I am using an abstract class "FXBaseComponent". Every class representing a JavaFX pane must extend it. In FXBaseComponent I have basically some infrastructure stuff like
As this works great using FrameworkUtil seems always like a workaround to me. What I would really like is just a component where my JavaFX stuff can be loaded and any service or bundle is injected:
Yes, unfortunatly, it needs currently some work-arounds to get a service into a JavaFX control such as the one you showed (I don't have currently my sample at hand).
It's a major issue, which I would like to solve. I don't think however that turning a JavaFX control into a Declarative Service will work (as the annotations in your last sample suggests). Declarative Services are instantiated by the Declarative Service framework which uses a different thread than the JavaFX Application Thread. JavaFX controls need to be instantiated on the JavaFX Application Thread however. Correct me if I'm wrong.
Therefore my current proposed solution is to go for CDI (JSR 299) (see [#37]).
Using CDI it should be possible to inject CDI and OSGi services with @Inject (JSR 330) into JavaFX controls.
There doesn't seem to be an official OSGi specification for integration of JSR 330 only. There is one (RFP 146/ RFC-193) for CDI (JSR 299), however, which includes JSR 330, but it still seems to be work in progress. The reference implementation seems to be PAX-CDI.
I planned [#37] for version 0.6, but it might take several follow up issues until everything works as expected.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
MyComponent in the example would act as a controller. When loading fxml the controller would be set in the fxml loader as long with the fxml pane. So controller and pane would be two separate classes. Currently DromblerFX assumes controller and pane is the same class.
I like the idea to integrate CDI into DromblerFX. Looking forward to it.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Please note that Drombler FX does not assume that the controller and the pane are the same class. It only requires the annotated dockable class to extend from Node. Although I haven't tried I don't see any thing stopping you to e.g. extend from BorderPane, load a non-fx-root FXML with another controller and assigned the returned Node to the center property.
That said I still can highly recommend to use the fx-root construct in most cases. You can use/ nest such classes in FXML like the other standard control classes.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Suppose we have two OSGi bundles A and B. A provides a service which will be referenced by B. B is a JavaFX pane which holds a table with data populated from a database. To get data into the table we need the service provided by A.
I am wondering what would be the preferred way to inject the service into B?
If B were an OSGi component I could reference the service via @Reference or xml. But that does not work because B is then instantiated by the OSGi framework which happens before the JavaFX toolkit is initialized. Obviously this would also interfere with the Drombler framework which will initialize the pane also.
How can I solve it without using FrameworkUtils for example.
Just some thoughts..
Currently I am using an abstract class "FXBaseComponent". Every class representing a JavaFX pane must extend it. In FXBaseComponent I have basically some infrastructure stuff like
As this works great using FrameworkUtil seems always like a workaround to me. What I would really like is just a component where my JavaFX stuff can be loaded and any service or bundle is injected:
Yes, unfortunatly, it needs currently some work-arounds to get a service into a JavaFX control such as the one you showed (I don't have currently my sample at hand).
It's a major issue, which I would like to solve. I don't think however that turning a JavaFX control into a Declarative Service will work (as the annotations in your last sample suggests). Declarative Services are instantiated by the Declarative Service framework which uses a different thread than the JavaFX Application Thread. JavaFX controls need to be instantiated on the JavaFX Application Thread however. Correct me if I'm wrong.
Therefore my current proposed solution is to go for CDI (JSR 299) (see [#37]).
Using CDI it should be possible to inject CDI and OSGi services with @Inject (JSR 330) into JavaFX controls.
There doesn't seem to be an official OSGi specification for integration of JSR 330 only. There is one (RFP 146/ RFC-193) for CDI (JSR 299), however, which includes JSR 330, but it still seems to be work in progress. The reference implementation seems to be PAX-CDI.
I planned [#37] for version 0.6, but it might take several follow up issues until everything works as expected.
MyComponent in the example would act as a controller. When loading fxml the controller would be set in the fxml loader as long with the fxml pane. So controller and pane would be two separate classes. Currently DromblerFX assumes controller and pane is the same class.
I like the idea to integrate CDI into DromblerFX. Looking forward to it.
Please note that Drombler FX does not assume that the controller and the pane are the same class. It only requires the annotated dockable class to extend from Node. Although I haven't tried I don't see any thing stopping you to e.g. extend from BorderPane, load a non-fx-root FXML with another controller and assigned the returned Node to the center property.
That said I still can highly recommend to use the fx-root construct in most cases. You can use/ nest such classes in FXML like the other standard control classes.