We tried to implement (backoffice) screens with entity properties representing an image which is not hosted by the Jmix application (e.g. an avatar image of a user).
Unfortunately ImageImpl
does not cover resource objects of the types java.net.URL
or java.net.URI
. So I implemented an extension of ImageImpl
which is not a big deal:
public class ExtImageImpl<V> extends ImageImpl<V>
{
//...
@Nullable
@Override
protected Resource createImageResource(@Nullable final Object aResourceObject)
{
final Resource result;
if (aResourceObject instanceof URL)
{
final URL url = (URL) aResourceObject;
final UrlResource urlResource = new UrlResourceImpl();
urlResource.setUrl(url);
result = urlResource;
}
else if (aResourceObject instanceof URI)
{
final URI url = (URI) aResourceObject;
UrlResource urlResource;
try
{
urlResource = new UrlResourceImpl();
urlResource.setUrl(url.toURL());
}
catch (final MalformedURLException ex)
{
urlResource = null;
if (LOGGER.isDebugEnabled())
{
// should never happen
LOGGER.debug(String.format("Could not create image resource from malformed URL: %s. %s", url,
ex.getLocalizedMessage()), ex);
}
}
result = urlResource;
}
else
{
result = super.createImageResource(aResourceObject);
}
return result;
}
}
But using this implementation seemed to be tough. The only way which worked so far is pretty hacky:
@Subscribe
protected void onInit(final InitEvent anEvent)
{
usersTable.addGeneratedColumn("avatar", entity -> {
/*
* uiComponents.create(ExtImageImpl.class)
* Does not help because it's simple ignored and the standard implementation is created.
* So we create the instance ourselves and post-process the creation it manually.
*/
final Image<FileRef> image = new ExtImageImpl<>();
UiComponentUtils.processApplicationContext(image, getApplicationContext());
image.setValueSource(new ContainerValueSource<>(usersTable.getInstanceContainer(entity), "avatar"));
return image;
});
}
In UiComponentUtils
we copied some code from UiComponentsImpl
. Of course, that is not a sustainable approach.
- Is there a clean/proper way to implement own components?
- I there a reason for not supporting image components with non-application URLs?