Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » e(fx)clipse » OSGi: loading an FXML file from another bundle(What's the best way to provide a centralised mechanism for loading FXML files that can be used from another bundle?)
OSGi: loading an FXML file from another bundle [message #1131453] Thu, 10 October 2013 10:40 Go to next message
Uwe San is currently offline Uwe San
Messages: 70
Registered: January 2012
Member
Hi,

I'm working in an OSGi environment where I would like to have a bundle A that provides a central service for loading FXML files. This service should be used by bundle B to load (and do validation, error handling,...) an FXML file from bundle B.

Is that possible with the current implementation of the FXMLLoaderFactory class? The loadRequestorRelative() method does not work as the requesting class is my service from bundle A, but the FXML is located in bundle B.

As a workaround, I'm using the InjectingFXMLLoader class which allows me to specify the requester class.

Of course, it may not be advised to provide a central service like this. Maybe each bundle should have its own utility for loading FXML files. Are there any best practices?

Thanks,
Uwe
Re: OSGi: loading an FXML file from another bundle [message #1132561 is a reply to message #1131453] Fri, 11 October 2013 04:22 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas Schindl
Messages: 5013
Registered: July 2009
Senior Member
On 10.10.13 16:40, Uwe San wrote:
> Hi,
>
> I'm working in an OSGi environment where I would like to have a bundle A
> that provides a central service for loading FXML files. This service
> should be used by bundle B to load (and do validation, error
> handling,...) an FXML file from bundle B.
>
> Is that possible with the current implementation of the
> FXMLLoaderFactory class? The loadRequestorRelative() method does not
> work as the requesting class is my service from bundle A, but the FXML
> is located in bundle B.

No it is not. FXMLLoaderFactory is simply a convenience instance where
the DI-System prefills:
* IEclipseContext
* Classloader

>
> As a workaround, I'm using the InjectingFXMLLoader class which allows me
> to specify the requester class.
>
> Of course, it may not be advised to provide a central service like this.
> Maybe each bundle should have its own utility for loading FXML files.
> Are there any best practices?
>

Can you give me some (pseudo)code how your stuff works as of now with
InjectingFXMLLoader.

If I get your right what you want looks like this:

---------8<---------
@PostConstruct
void initUI(FXMLService service) {
Node node = service.load("my/bundle/MyUI.fxml");
}
---------8<---------

The FXMLServiceImpl looks like this:

---------8<---------
FXMLServiceImpl {
@Inject
@FXMLLoader
FXMLLoaderFactory loaderFactory;

public Node load(String filePath) {
try {
return loaderFactory.loadBundleRelative(file);
} catch( Exception e ) {
return createErrorUI();
}
}
}
---------8<---------

and now the trick. You register an IContextFunction which creates an
instance of the FXMLServiceImpl on request.

Now that I've written this whole stuff I think all you want is that
FXMLBuilder provides you with a way to register error handlers so that
you use it like this:

@Inject
@FXMLLoader
FXMLLoaderFactory factory;

factory.<Node>loadRequestorRelative("MyUI.fxml").errorHandler(MyErrorHandler.class).load()


where MyErrorHandler looks like this:

MyErrorHandler {
@Execute
Node errorHandler(Throwable loadingException) {
}
}

I'm not sure what you mean with validation, ... but IIRC they could all
be added similar to the error handler. I really like this ErrorHandler
stuff so I will implement it anyways.

Tom
Re: OSGi: loading an FXML file from another bundle [message #1132615 is a reply to message #1132561] Fri, 11 October 2013 05:14 Go to previous messageGo to next message
Uwe San is currently offline Uwe San
Messages: 70
Registered: January 2012
Member
Hi Tom,

I mentioned the validation and error handling simply to give you some context for why we want a centralised FXML loader. But these details are not relevant for the actual problem. Sorry if that was misleading.


Our current implementation looks similar to this:

public class FXMLLoaderService {

   @Inject
   private IEclipseContext context;

   public Node load(final Class<?> requester, final String filePath) {

      FXMLBuilder<Node> builder = InjectingFXMLLoader.create(context, requester, filePath);
      Node node = builder.load();
      return node;
   }
}


The file path is a location within the bundle that contains the requester class.

In your FXMLService example, the loaderFactory.loadBundleRelative() method would use a path relative to the bundle in which the FXMLService is located, I believe. As a consequence, all the FXML files would need to be stored in the same bundle as the FXMLService class. But we want to specify a relative path for the bundle that uses this service such that the FXML files can distributed among multiple bundles.

Apart from that, your error handler extension would be a nice new feature. Smile

Thanks,
Uwe

Re: OSGi: loading an FXML file from another bundle [message #1132634 is a reply to message #1132615] Fri, 11 October 2013 05:26 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas Schindl
Messages: 5013
Registered: July 2009
Senior Member
On 11.10.13 11:14, Uwe San wrote:
> Hi Tom,
>
> I mentioned the validation and error handling simply to give you some
> context for why we want a centralised FXML loader. But these details are
> not relevant for the actual problem. Sorry if that was misleading.
>
>
> Our current implementation looks similar to this:
>
>
> public class FXMLLoaderService {
>
> @Inject
> private IEclipseContext context;
>
> public Node load(final Class<?> requester, final String filePath) {
>
> FXMLBuilder<Node> builder = InjectingFXMLLoader.create(context,
> requester, filePath);
> Node node = builder.load();
> return node;
> }
> }
>
>
> The file path is a location within the bundle that contains the
> requester class.
>
> In your FXMLService example, the loaderFactory.loadBundleRelative()
> method would use a path relative to the bundle in which the FXMLService
> is located, I believe. As a consequence, all the FXML files would need
> to be stored in the same bundle as the FXMLService class. But we want to
> specify a relative path for the bundle that uses this service such that
> the FXML files can distributed among multiple bundles.

No this is the IContextFunction trick, the loadFactory is created in the
correct context (IEclipseContext wise) and OSGi-BundleContext wise so it
would load from the requestor bundle!

Please note that each requestor would get its distinct instance of
FXMLLoaderService, that's what IContextFunctions are good for ;-)

>
> Apart from that, your error handler extension would be a nice new
> feature. :)
>

I still ask myself if FXMLLoaderBuilder could not serve as what you try
to do with the service, or how we'd have to modify it to suite your needs.

Tom
Re: OSGi: loading an FXML file from another bundle [message #1132701 is a reply to message #1132634] Fri, 11 October 2013 06:32 Go to previous messageGo to next message
Uwe San is currently offline Uwe San
Messages: 70
Registered: January 2012
Member
Thomas Schindl wrote on Fri, 11 October 2013 05:26
On 11.10.13 11:14,
No this is the IContextFunction trick, the loadFactory is created in the
correct context (IEclipseContext wise) and OSGi-BundleContext wise so it
would load from the requestor bundle!

Please note that each requestor would get its distinct instance of
FXMLLoaderService, that's what IContextFunctions are good for Wink


That's good to know. Smile What you describe is exactly what we need. Thanks!

Uwe
Re: OSGi: loading an FXML file from another bundle [message #1137096 is a reply to message #1132634] Mon, 14 October 2013 04:56 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas Schindl
Messages: 5013
Registered: July 2009
Senior Member
On 11.10.13 11:26, Tom Schindl wrote:
> On 11.10.13 11:14, Uwe San wrote:
>> Hi Tom,
>>
>> I mentioned the validation and error handling simply to give you some
>> context for why we want a centralised FXML loader. But these details are
>> not relevant for the actual problem. Sorry if that was misleading.
>>
>>
>> Our current implementation looks similar to this:
>>
>>
>> public class FXMLLoaderService {
>>
>> @Inject
>> private IEclipseContext context;
>>
>> public Node load(final Class<?> requester, final String filePath) {
>>
>> FXMLBuilder<Node> builder = InjectingFXMLLoader.create(context,
>> requester, filePath);
>> Node node = builder.load();
>> return node;
>> }
>> }
>>
>>
>> The file path is a location within the bundle that contains the
>> requester class.
>>
>> In your FXMLService example, the loaderFactory.loadBundleRelative()
>> method would use a path relative to the bundle in which the FXMLService
>> is located, I believe. As a consequence, all the FXML files would need
>> to be stored in the same bundle as the FXMLService class. But we want to
>> specify a relative path for the bundle that uses this service such that
>> the FXML files can distributed among multiple bundles.
>
> No this is the IContextFunction trick, the loadFactory is created in the
> correct context (IEclipseContext wise) and OSGi-BundleContext wise so it
> would load from the requestor bundle!

I have to correct myself, I think this information was wrong the
OSGi-Context might be the wrong one :-( because the requestor is the
service impl :-(

Tom
Re: OSGi: loading an FXML file from another bundle [message #1137234 is a reply to message #1137096] Mon, 14 October 2013 06:53 Go to previous messageGo to next message
Uwe San is currently offline Uwe San
Messages: 70
Registered: January 2012
Member
That's too bad, but thanks for this correction.

So is using the InjectingFXMLLoader class the only option we have? Or is there a better way to provide the requesting class/bundle?
Re: OSGi: loading an FXML file from another bundle [message #1137242 is a reply to message #1137234] Mon, 14 October 2013 06:57 Go to previous messageGo to next message
Thomas Schindl is currently offline Thomas Schindl
Messages: 5013
Registered: July 2009
Senior Member
Your own annotation and an object supplier, this is the only one having
access to the requestor (==object/requesting class).

Tom

On 14.10.13 12:53, Uwe San wrote:
> That's too bad, but thanks for this correction.
>
> So is using the InjectingFXMLLoader class the only option we have? Or is
> there a better way to provide the requesting class/bundle?
Re: OSGi: loading an FXML file from another bundle [message #1137253 is a reply to message #1137242] Mon, 14 October 2013 07:07 Go to previous message
Uwe San is currently offline Uwe San
Messages: 70
Registered: January 2012
Member
Well, we'll try that then. Thanks!
Previous Topic:RCP e4 SWT/JavaFX application with Kepler
Next Topic:InjectionException at runtime of SWT/JavaFX product build with Maven
Goto Forum:
  


Current Time: Sat Apr 19 06:08:44 EDT 2014

Powered by FUDForum. Page generated in 0.02075 seconds