Closed mokun closed 4 years ago
I'm peeking inside the FileResource
class. Looks like when I do this new FileResource(f2)
, it will go look for the absolute path of the lander_hab.svg.
/**
* Constructs new {@link FileResource}.
*
* @param file resource {@link File}
*/
public FileResource ( @NotNull final File file )
{
this ( file.getAbsolutePath () );
}
According to this discussion, the easiest way to reconcile the differences in eclipse and in jarfile is to use InputStream
.
Note that I use String s2 = CrewEditor.class.getResource(LANDER_SVG).getPath();
to get the absolute path first.
Then I use File f2 = new File(s2)
to get the File instance to be passed into the FileResource(final File file)
constructor.
/**
* Constructs new {@link FileResource}.
*
* @param path resource file path
*/
public FileResource ( @NotNull final String path )
{
this.path = path;
}
If I skip converting the s2 into f2 and get s2 directly passed into the FileResource(final String path)
constructor, again the eclipse has no problem with it.
But even this way, I still cannot acesss the svg file in jarfile.
Also, the duplicated path issue is wrong and the FileNotFoundException
is gone.
But I have a new ResourceException` as follows :
Caused by: com.alee.api.resource.ResourceException: Unable to open FileResource stream for path: file:/D:/Data/msp%20binary/5348/5348.jar!/svg/icons/lander_hab.svg
See more below :
Exception in thread "AWT-EventQueue-0" com.alee.managers.icon.IconException: Unable to load icon: lander
at com.alee.managers.icon.set.AbstractIconSet.findIcon(AbstractIconSet.java:140)
at com.alee.managers.icon.IconManager.findIcon(IconManager.java:313)
at com.alee.managers.icon.IconManager.findIcon(IconManager.java:286)
at com.alee.managers.icon.IconManager.getIcon(IconManager.java:261)
at com.alee.managers.icon.LazyIcon.getIcon(LazyIcon.java:96)
at org.mars_sim.msp.ui.swing.MainWindow.initIconManager(MainWindow.java:328)
at org.mars_sim.msp.ui.swing.configeditor.SimulationConfigEditor.<init>(SimulationConfigEditor.java:140)
at org.mars_sim.main.MarsProject.lambda$handleNewSimulation$1(MarsProject.java:701)
at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:316)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Caused by: com.alee.managers.icon.IconException: Unable to load Icon: lander
at com.alee.managers.icon.data.AbstractIconSource.loadIcon(AbstractIconSource.java:145)
at com.alee.managers.icon.set.AbstractIconSet.findIcon(AbstractIconSet.java:125)
... 20 more
Caused by: java.lang.RuntimeException: Unable to load SVG from resource: com.alee.api.resource.FileResource@6710bc90
at com.alee.extended.svg.SvgIcon.<init>(SvgIcon.java:101)
at com.alee.extended.svg.SvgIconSource.loadIcon(SvgIconSource.java:147)
at com.alee.extended.svg.SvgIconSource.loadIcon(SvgIconSource.java:41)
at com.alee.managers.icon.data.AbstractIconSource.loadIcon(AbstractIconSource.java:133)
... 21 more
Caused by: com.alee.api.resource.ResourceException: Unable to open FileResource stream for path: file:/D:/Data/msp%20binary/5348/5348.jar!/svg/icons/lander_hab.svg
at com.alee.api.resource.FileResource.getInputStream(FileResource.java:85)
at com.alee.extended.svg.SvgIcon.<init>(SvgIcon.java:86)
... 24 more
Caused by: java.io.FileNotFoundException: file:\D:\Data\msp%20binary\5348\5348.jar!\svg\icons\lander_hab.svg (The filename, directory name, or volume label syntax is incorrect)
at java.base/java.io.FileInputStream.open0(Native Method)
at java.base/java.io.FileInputStream.open(FileInputStream.java:212)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:154)
at java.base/java.io.FileInputStream.<init>(FileInputStream.java:109)
at com.alee.api.resource.FileResource.getInputStream(FileResource.java:81)
... 25 more
The answer to all three questions is that you're using FileResource
incorrectly in this case. FileResource
exists exclusively for files available in the file system. Files that are packed into the JAR aren't really present in the file system.
For loading icons from JAR simply use ClassResource
instead:
IconSet iconSet = new RuntimeIconSet ( "mars-sim-set" );
iconSet.addIcon ( new SvgIconSource (
"lander",
new ClassResource ( CrewEditor.class, LANDER_SVG ),
new Dimension ( 16, 16 )
) );
IconManager.addIconSet ( iconSet );
There is also UrlResource
implementation of Resource
interface for loading remote icons.
And just a side note - be careful with retrieving icons like you do in the last line:
ImageIcon landerIcon = new LazyIcon ( "lander" ).getIcon ();
Because in the example above you will have SvgIcon
and not an ImageIcon
. And although you can cast SvgIcon
to ImageIcon
, there might changes coming in the future or different Icon
implementations that won't be extending ImageIcon
.
My general recommendation is to use Icon
whenever possible and not the exact type (unless you actually need the exact type). Icon
should be accepted by most Swing components, so it shouldn't cause any issues.
Actually, maybe not all three questions, I'm not exactly sure about this one:
Q2: is there a way to reconcile the differences in terms of classpath between initializing the IconManager when running my app in Eclipse and when running it in jarfile ?
It might still work with ClassResource
, but you'll need to try it - it mostly depends on how Eclipse handles resources when you're running your application in it.
For loading icons from JAR simply use ClassResource instead:
It's great that after switching to ClassResource
, my app works in both Eclipse and jarfile !
Thanks a lot !
Because in the example above you will have SvgIcon and not an ImageIcon. And although you can cast SvgIcon to ImageIcon, there might changes coming in the future or different Icon implementations that won't be extending ImageIcon.
Sure. I'll just create it as an Icon
instead.
Glad that helped! I'll close this issue, but feel free to reopen if you have more related questions.
Q1: How do you gain the access to the svg icon resource when running my app in the form of a jarfile ?
I have no issue in gaining the access to the svg icon currently being resided in the resource folder when I run my app in Eclipse as follows :
Note that
The example for loading a svg in the wiki is for fetching an svg online, but loading it from the application itself seems more complicated.
I pretty much using
new FileResource(new File(s2))
to point to the location of the resource folder.Q2: is there a way to reconcile the differences in terms of classpath between initializing the IconManager when running my app in Eclipse and when running it in jarfile ?
Q3: why would the
FileResource
classs repeated the first segment of the file directory, namely, theD:\Data\msp binary\5348\
duplicate part inD:\Data\msp binary\5348\file:\D:\Data\msp%20binary\5348\5348.jar!\svg\icons\lander_hab.svg
?See below, if I unzip the 5348.jar to look inside this jarfile, I have no problem finding the 'lander_hab.svg
residing in the directory '\svg\icons\
:Q4 : Can the
FileResource
class be streamlined to automatically resolve this classpath issue, without having to mess withInputStream
class ?