Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Eclipse Platform » [RCP] Loading image from plugin directory
[RCP] Loading image from plugin directory [message #268382] Tue, 24 August 2004 12:00 Go to next message
Marcus Olk is currently offline Marcus OlkFriend
Messages: 130
Registered: July 2009
Senior Member
Hi.

I know that this question has been asked quite frequently here, but I
couldn't find the appropriate solution, yet.

How can I load an image from a file, e.g. located in the plugin's
'icons' subdrectory? One solution I found goes like this:

final Image myImage =
ImageDescriptor
.createFromFile(MyPlugin.class,"icons/myImage.gif")
.createImage();

In my case I haven't had a plugin class. I didn't understand why
the plugin class is optional, but I chose not to create one.
This seems to be one reason why it is better to have one?
So I created a plugin class an tried to execute the code above
but it simply doesn't work. Here's my plugin structure:

com.mycompany.myplugin_0.0.0/
icons/
myImage.gif
myplugin.jar
...

myplugin.jar contains the following classes:

com.mycompany.myplugin.
MyPlugin.class -> extends AbstractUIPlugin
MyPluginApp.class -> implements IPlatformRunnable
MyDialog.class -> extends TitleAreaDialog

MyDialog contains the code to load the image from a file
in the 'icons' directory. At runtime only a small red
square will be displayed telling me that my image could not
be found / loaded.

BTW: where is the right place to dispose the image?
In the finalizer?

I'm quite surprised that it seems to be so hard to load an image
from a file resource. Is there an FAQ entry on this issue yet?
I couldn't find one.

Cheers,
Marcus
Re: [RCP] Loading image from plugin directory [message #268390 is a reply to message #268382] Tue, 24 August 2004 12:54 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: Andrew_Eidsness.ca.ibm.com

Just a guess, but something like this might work:

Bundle bundle = Platform.getBundle("your.bundle.id"); // aka your
plugin's id
IPath imagePath = new Path("icons/image.gif");
URL imageUrl = Platform.find(bundle, imagePath);
ImageDescriptor desc = ImageDescriptor.createFromFile(imageUrl);
Image image = desc.createImage();

-Andrew

On Tue, 24 Aug 2004 14:00:49 +0200, Marcus Olk <molk@comosoft.de> wrote:

> Hi.
>
> I know that this question has been asked quite frequently here, but I
> couldn't find the appropriate solution, yet.
>
> How can I load an image from a file, e.g. located in the plugin's
> 'icons' subdrectory? One solution I found goes like this:
>
> final Image myImage =
> ImageDescriptor
> .createFromFile(MyPlugin.class,"icons/myImage.gif")
> .createImage();
>
> In my case I haven't had a plugin class. I didn't understand why
> the plugin class is optional, but I chose not to create one.
> This seems to be one reason why it is better to have one?
> So I created a plugin class an tried to execute the code above
> but it simply doesn't work. Here's my plugin structure:
>
> com.mycompany.myplugin_0.0.0/
> icons/
> myImage.gif
> myplugin.jar
> ...
>
> myplugin.jar contains the following classes:
>
> com.mycompany.myplugin.
> MyPlugin.class -> extends AbstractUIPlugin
> MyPluginApp.class -> implements IPlatformRunnable
> MyDialog.class -> extends TitleAreaDialog
>
> MyDialog contains the code to load the image from a file
> in the 'icons' directory. At runtime only a small red
> square will be displayed telling me that my image could not
> be found / loaded.
>
> BTW: where is the right place to dispose the image?
> In the finalizer?
>
> I'm quite surprised that it seems to be so hard to load an image
> from a file resource. Is there an FAQ entry on this issue yet?
> I couldn't find one.
>
> Cheers,
> Marcus
Re: [RCP] Loading image from plugin directory [message #268396 is a reply to message #268390] Tue, 24 August 2004 13:20 Go to previous messageGo to next message
Marcus Olk is currently offline Marcus OlkFriend
Messages: 130
Registered: July 2009
Senior Member
Andrew Eidsness wrote:

> Just a guess, but something like this might work:
>
> ImageDescriptor desc = ImageDescriptor.createFromFile(imageUrl);

ImageDescriptor desc = ImageDescriptor.createFromURL(imageUrl);

....is what you meant, I suppose.

Yes. This works. I found some related code in the Eclipse FAQ now.

But: is this the preferred way to load images or is it just *A* way
to do it. And: what do I need the plugin class for?

Cheers,
Marcus
Re: [RCP] Loading image from plugin directory [message #268405 is a reply to message #268382] Tue, 24 August 2004 14:06 Go to previous messageGo to next message
Marcus Olk is currently offline Marcus OlkFriend
Messages: 130
Registered: July 2009
Senior Member
Hi.

As a solution for this issue I added a corresponding class method
to my plugin class:

/** The plugin id. */
public static final String PLUGIN_ID = "myplugin.myplugin";

/** The relative path to the images directory. */
private static final String IMAGES_PATH = "icons/";

...

/**
* Creates an image by loading it from a file in
* the plugin's images directory.
*
* @param imagePath The path to the image file to load.
* The image path must not include the plugin's images
* path location defined in <code>IMAGES_PATH</code>.
* If you want to load <code>IMAGES_PATH/myimage.gif</code>,
* simply pass <code>myimage.gif</code> to this method.
*
* @return The image object loaded from the image file
*/
public static Image createImage(String imagePath)
{
final Bundle pluginBundle =
Platform.getBundle(MyPlugin.PLUGIN_ID);

final Path imageFilePath =
new Path(MyPlugin.IMAGES_PATH + imagePath);

final URL imageFileUrl =
Platform.find(pluginBundle, imageFilePath);

return
ImageDescriptor
.createFromURL(imageFileUrl)
.createImage();
}
/*

// Alternative implementation using the URL file stream:

final Bundle pluginBundle = Platform.getBundle(LagoPlugin.PLUGIN_ID);
final Path imageFilePath = new Path(LagoPlugin.IMAGES_PATH + imagePath);
final URL imageFileUrl = Platform.find(pluginBundle, imageFilePath);

Image image = null;
InputStream imageFileStream = null;

try
{
imageFileStream = imageFileUrl.openStream();
image = new Image(null, imageFileStream);
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
if (imageFileStream != null)
try { imageFileStream.close(); } catch (IOException e) {}
}

return image;
*/

Now every class of my plugin can load a plugin image by simply
calling createImage. e.g. I can set the title image of my
TitleAreaDialog descendant like this now:

setTitleImage(MyPlugin.createImage("logo.gif"));

Considering the fact that loading an image from a file in the plugin
directory is obviously a common requirement I'm wondering why there's
no API support for this issue, yet. Or did I miss something here?
I think this code should be written once to unify the way how plugins
should create Image objects by loading the image data from a file
distributed in an image directory of the plugin.

Marcus
Re: [RCP] Loading image from plugin directory [message #268407 is a reply to message #268396] Tue, 24 August 2004 14:07 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: martin.klinke.xavo.de

Why don't you just use the following code?

AbstractUIPlugin.imageDescriptorFromPlugin(
pluginId,
relativePath).createImage();

"Marcus Olk" <molk@comosoft.de> schrieb im Newsbeitrag
news:cgff1s$8sd$1@eclipse.org...
> Andrew Eidsness wrote:
>
> > Just a guess, but something like this might work:
> >
> > ImageDescriptor desc = ImageDescriptor.createFromFile(imageUrl);
>
> ImageDescriptor desc = ImageDescriptor.createFromURL(imageUrl);
>
> ...is what you meant, I suppose.
>
> Yes. This works. I found some related code in the Eclipse FAQ now.
>
> But: is this the preferred way to load images or is it just *A* way
> to do it. And: what do I need the plugin class for?
>
> Cheers,
> Marcus
Re: [RCP] Loading image from plugin directory [message #268420 is a reply to message #268407] Tue, 24 August 2004 15:05 Go to previous messageGo to next message
Marcus Olk is currently offline Marcus OlkFriend
Messages: 130
Registered: July 2009
Senior Member
Martin Klinke wrote:

> Why don't you just use the following code?

Cool. I wasn't able find this browsing this group and the web...
Have you got an idea where to dispose the created image when
using it in an dialog?

{
final MyDialog dialog = new Dialog(shell);
dialog.open();
if (dialog.getResult() == OK)
...
}

The dialog creates the Image object and is thus responsible
for disposing it. Is it a good idea to dispose it in its
finalizer?

Cheers,
Marcus
Re: [RCP] Loading image from plugin directory [message #268434 is a reply to message #268420] Tue, 24 August 2004 16:05 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: martin.klinke.xavo.de

"Marcus Olk" <molk@comosoft.de> schrieb im Newsbeitrag
news:cgfl6e$m0q$1@eclipse.org...
> Martin Klinke wrote:
>
> > Why don't you just use the following code?
>
> Cool. I wasn't able find this browsing this group and the web...
> Have you got an idea where to dispose the created image when
> using it in an dialog?
>
> {
> final MyDialog dialog = new Dialog(shell);
> dialog.open();
> if (dialog.getResult() == OK)
> ...
> }
>
> The dialog creates the Image object and is thus responsible
> for disposing it. Is it a good idea to dispose it in its
> finalizer?

It is never a good idea to dispose resources in the finalize method since it
is not guaranteed to be called in time respectively at all. For dialogs I do
simply override the close method:

/* (non-javadoc)
* @see org.eclipse.jface.dialogs.Dialog#close()
*/
public boolean close()
{
if (super.close())
{
//dispose image before closing
if (image != null && !image.isDisposed())
{
image.dispose();
image = null;
}
return true;
}
return false;
}

An even better way may be to have a application wide image registry that
initializes the images and disposes them when the application is closed
(RCP) or the plugin is shutdown. Of course that depends on the number of
concurrently loaded images I'd say ;)

>
> Cheers,
> Marcus

Have fun,
Martin
Re: [RCP] Loading image from plugin directory [message #268442 is a reply to message #268434] Tue, 24 August 2004 16:15 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: richkulp.NO.SPAM.us.ibm.com

Usually what I do to make sure they get disposed when I know that the
dialog owns them is to add a dispose listener to the shell created. That
way no matter how it is closed it will be cleaned up.


--
Thanks, Rich Kulp

Re: [RCP] Loading image from plugin directory [message #268444 is a reply to message #268442] Tue, 24 August 2004 16:21 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: martin.klinke.xavo.de

"Rich Kulp" <richkulp@NO.SPAM.us.ibm.com> schrieb im Newsbeitrag
news:cgfpdh$spm$5@eclipse.org...
> Usually what I do to make sure they get disposed when I know that the
> dialog owns them is to add a dispose listener to the shell created. That
> way no matter how it is closed it will be cleaned up.
>
Well, for dialogs that is better than my approach. I will consider this in
my next dialog that needs an image, too.
Thanks!

>
> --
> Thanks, Rich Kulp
> 
>
Re: [RCP] Loading image from plugin directory [message #268555 is a reply to message #268444] Wed, 25 August 2004 07:44 Go to previous messageGo to next message
Marcus Olk is currently offline Marcus OlkFriend
Messages: 130
Registered: July 2009
Senior Member
Martin Klinke wrote:

> Well, for dialogs that is better than my approach. I will consider this in
> my next dialog that needs an image, too.

Right. But which shell do you use? The parent shell the dialog gets passed
in the constructor? This shell usually has a long life time, doesn't it?
The idea to add an DisposeListener is safe but I'd say that it is very
likely that the parent shell gets disposed when the applications is
terminated und thus the allocated images won't be disposed before the
application terminates. Or did you consider this DisposeListener approach
to be an additional safety measure?

Thanks for the good idea anyway!

Marcus
Re: [RCP] Loading image from plugin directory [message #268637 is a reply to message #268555] Wed, 25 August 2004 11:50 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: martin.klinke.xavo.de

"Marcus Olk" <molk@comosoft.de> schrieb im Newsbeitrag
news:cghfng$bbi$1@eclipse.org...
> Martin Klinke wrote:
>
> > Well, for dialogs that is better than my approach. I will consider this
in
> > my next dialog that needs an image, too.
>
> Right. But which shell do you use? The parent shell the dialog gets passed
> in the constructor? This shell usually has a long life time, doesn't it?
> The idea to add an DisposeListener is safe but I'd say that it is very
> likely that the parent shell gets disposed when the applications is
> terminated und thus the allocated images won't be disposed before the
> application terminates. Or did you consider this DisposeListener approach
> to be an additional safety measure?
>

Use the dialog's shell ;) Add the following code in your dialog class:

getShell().addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e)
{
if (image != null && !image.isDisposed())
{
image.dispose();
}
}
});

> Thanks for the good idea anyway!
>
> Marcus

You're welcome ;)
Re: [RCP] Loading image from plugin directory [message #268683 is a reply to message #268637] Wed, 25 August 2004 14:19 Go to previous message
Marcus Olk is currently offline Marcus OlkFriend
Messages: 130
Registered: July 2009
Senior Member
Martin Klinke wrote:

> Use the dialog's shell ;) Add the following code in your dialog class:

I assumed the parent shell passed to the dialog is the same as the
Window shell. That's nonsense, of course. O.k. this works for me now.

A little helper class like this could be reused for connecting
the disposal of images created in a dialog with the disposal
of the dialog's shell:

private static class ImageDisposer
implements DisposeListener {

final Image image;

ImageDisposer(Shell shell, Image image) {
this.image = image;
shell.addDisposeListener(this);
}

public void widgetDisposed(DisposeEvent e) {
if (this.image != null && !this.image.isDisposed())
this.image.dispose();
}
}

....would be used like this:

final Image logoImage = MyPlugin.createImage("logo.gif");

new Disposer(getShell(), logoImage);

setTitleImage(logoImage);

A common utility class would be appropriate here: A disposer that
gets an IDisposeObservable (e.g. the shell) and the IDisposable object.
But there's no IDisposeObservable (demanding addDisposeListener)
nor an IDisposable interface (demanding dispose and isDisposed)
that the Shell class and the disposable SWT objects do implement.
That's a little sad because one of the 'core features' of SWT is
the manual house keeping task a developer has to cope with.
Thus it is surprising to see that IBM didn't use corresponding interfaces
like the ones I suggested above.

Marcus
Previous Topic:Building a jar file with all dependencies
Next Topic:[RCP] Personal Plugins dependencies Problem
Goto Forum:
  


Current Time: Thu Apr 25 10:15:08 GMT 2024

Powered by FUDForum. Page generated in 0.03932 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top