Giving an application a window icon in a sensible way

Discussion in 'Java' started by Twisted, Nov 20, 2006.

  1. Twisted

    Twisted Guest

    Hrm. How to go about doing this?

    I want to give a Java application a window icon in a manner that is
    independent of how it is installed, etc.

    The trick is obtaining an Image object for myJFrame.setIconImage().
    Loading it from a URL means it won't work without a working network
    connection, and I need to host the image somewhere. Every copy of the
    app running anywhere in the world will, on startup, hit that host with
    a request for the file(!). Loading it from a file path requires a
    separate installer that sets the image into a specific directory.
    Putting it in a JAR file with the app means learning a big new chunk of
    API, plus it won't work when running in the development environment
    rather than as a standalone executable JAR.

    This suggests doing the ListMessageBundle sort of thing, and somehow
    packaging it as a class -- an Image subclass, presumably. Is there a
    tool for turning a jpeg, gif, or png into Java source code for an Image
    subclass that will, when instantiated, behave as the appropriate jpeg?

    I don't have the google-fu to find this -- searches for queries like
    "image resource class java" didn't do much for me. Damn, we need *real*
    natural language search. :p
    Twisted, Nov 20, 2006
    #1
    1. Advertising

  2. "Twisted" <> wrote in message
    news:...
    > Hrm. How to go about doing this?
    >
    > I want to give a Java application a window icon in a manner that is
    > independent of how it is installed, etc.


    The usual method is to use Class.getResource(), which will work
    whether the class and icon are in a jar file or not.
    Larry Barowski, Nov 20, 2006
    #2
    1. Advertising

  3. Twisted

    Mark Rafn Guest

    Twisted <> wrote:
    >I want to give a Java application a window icon in a manner that is
    >independent of how it is installed, etc.
    >The trick is obtaining an Image object for myJFrame.setIconImage().
    >Loading it from a URL means it won't work without a working network
    >connection, and I need to host the image somewhere.


    Not at all. A URL doesn't always mean http. It could be a file URL, or a
    resource URL inside your jarfile.

    >Putting it in a JAR file with the app means learning a big new chunk of
    >API, plus it won't work when running in the development environment
    >rather than as a standalone executable JAR.


    URL imgURL = getClass().getClassLoader().getResource("img/path");

    Works if the image is in a jarfile OR a directory on the classpath.
    --
    Mark Rafn <http://www.dagon.net/>
    Mark Rafn, Nov 20, 2006
    #3
  4. Twisted

    Twisted Guest

    Larry Barowski wrote:
    > "Twisted" <> wrote in message
    > news:...
    > > Hrm. How to go about doing this?
    > >
    > > I want to give a Java application a window icon in a manner that is
    > > independent of how it is installed, etc.

    >
    > The usual method is to use Class.getResource(), which will work
    > whether the class and icon are in a jar file or not.


    Where does it look, if the class isn't in a jar file? The directory
    with the .class file?
    Twisted, Nov 20, 2006
    #4
  5. Twisted

    Twisted Guest

    Mark Rafn wrote:
    > Twisted <> wrote:
    > >I want to give a Java application a window icon in a manner that is
    > >independent of how it is installed, etc.
    > >The trick is obtaining an Image object for myJFrame.setIconImage().
    > >Loading it from a URL means it won't work without a working network
    > >connection, and I need to host the image somewhere.

    >
    > Not at all. A URL doesn't always mean http. It could be a file URL, or a
    > resource URL inside your jarfile.


    File URL and jar I was considering separately.

    > URL imgURL = getClass().getClassLoader().getResource("img/path");
    >
    > Works if the image is in a jarfile OR a directory on the classpath.


    Hrm.

    Anyway I found something interesting. My google-fu isn't as weak as I
    thought -- I was eventually able to dredge up a way to encode icons
    into a class file.

    It involved exporting the file from photoshop as an XPM, pasting most
    of the result into the declaration of a string array, and feeding it to
    a class named XImageSource. Of course, this turned out not to be a
    standard library class, and tracking it down posed its own challenge
    (during which time Firefox crashed for the second time today -- it hit
    a crapplet on a page somewhere and died the number. It actually
    tottered along sort-of-working until I quit it, but wouldn't load
    anything -- and after being quit I couldn't start a new instance until
    I terminated a bunch of firefox-related processes that were idling in
    the task manager that didn't have any UI or cpu activity!).

    Naturally, the XImageSource class had dependencies to track down as
    well.

    Naturally, one of those dependencies had a bug -- XpmParser. It had

    colors = new int[charsPerPixel*2];

    where it appeared to need

    colors = new int[(charsPerPixel == 2)?65536:256];

    since it actually multiplies one char by 256 and adds a second in the
    latter case, and was throwing ArrayOutOfBoundsExceptions like they were
    going out of style.

    Naturally, the author of those classes included a copyright notice and
    will probably sue me for copyright infringement for fixing their bug
    without permission, too, now that I've copped to this heinous act in a
    public newsgroup posting.

    But it actually works, and the source code is completely
    self-contained, without requiring any extra files besides the .java
    files. Which is what I was hoping to accomplish.

    Thanks anyway. :)
    Twisted, Nov 20, 2006
    #5
  6. Twisted

    Twisted Guest

    Twisted wrote:
    > But it actually works, and the source code is completely
    > self-contained, without requiring any extra files besides the .java
    > files. Which is what I was hoping to accomplish.


    Update: with another hack and more copyright infringement (further
    editing the XImageSource code) I now have working transparency as well
    -- the first color index set to perfectly white (255, 255, 255) in the
    XPM disappears. The thing looks far better in my task list now.
    Twisted, Nov 20, 2006
    #6
  7. Twisted

    Mark Rafn Guest

    >> Twisted <> wrote:
    >> >Loading it from a URL means it won't work without a working network
    >> >connection, and I need to host the image somewhere.


    >Mark Rafn wrote:
    >> Not at all. A URL doesn't always mean http. It could be a file URL, or a
    >> resource URL inside your jarfile.
    >> URL imgURL = getClass().getClassLoader().getResource("img/path");
    >> Works if the image is in a jarfile OR a directory on the classpath.


    Twisted <> wrote:
    >Anyway I found something interesting. My google-fu isn't as weak as I
    >thought -- I was eventually able to dredge up a way to encode icons
    >into a class file.


    It doesn't need to be a class file for the classloader to find it as a
    resource.

    >It involved exporting the file from photoshop as an XPM, pasting most
    >of the result into the declaration of a string array, and feeding it to
    >a class named XImageSource.

    ....
    >Naturally, the XImageSource class had dependencies to track down as
    >well.

    ....
    >But it actually works, and the source code is completely
    >self-contained, without requiring any extra files besides the .java
    >files. Which is what I was hoping to accomplish.


    Wouldn't it be MUCH easier to put gif/jpg/png files directly into the jar,
    then let the classloader find them using getResource or getResourceAsStream?
    --
    Mark Rafn <http://www.dagon.net/>
    Mark Rafn, Nov 20, 2006
    #7
  8. Twisted wrote:
    > Twisted wrote:
    >> But it actually works, and the source code is completely
    >> self-contained, without requiring any extra files besides the .java
    >> files. Which is what I was hoping to accomplish.

    >
    > Update: with another hack and more copyright infringement (further
    > editing the XImageSource code) I now have working transparency as well
    > -- the first color index set to perfectly white (255, 255, 255) in the
    > XPM disappears. The thing looks far better in my task list now.
    >


    What's the advantage of this approach compared to using getResource?

    Patricia
    Patricia Shanahan, Nov 20, 2006
    #8
  9. Twisted

    Twisted Guest

    Patricia Shanahan wrote:
    > What's the advantage of this approach compared to using getResource?


    It's built right into the frame subclass file it applies to?
    It doesn't need to be put in some jar file, then retrieved, then all
    kinds of recovery code written to deal with the IOExceptions that can
    result if Something Goes Wrong(tm)?
    No need to fiddle with classpath?
    Everything is self-contained in the source files?
    Twisted, Nov 20, 2006
    #9
  10. Twisted

    Twisted Guest

    Mark Rafn wrote:
    > Wouldn't it be MUCH easier to put gif/jpg/png files directly into the jar,
    > then let the classloader find them using getResource or getResourceAsStream?


    First of all, I don't *have* a jar, at least not yet.

    Second of all, this is the kind of thing that should really just work
    without being able to bomb with IOExceptions and suchlike, in my
    opinion. Retrieving even the most basic stuff from a bunch of external
    files adds unnecessary points of failure, and gobs of extra recovery
    code to check for and cope with anything that goes wrong. This way, it
    Just Works(tm). :)
    Twisted, Nov 20, 2006
    #10
  11. Twisted wrote:
    > Patricia Shanahan wrote:
    > > What's the advantage of this approach compared to using getResource?

    >
    > It's built right into the frame subclass file it applies to?


    Why would it? It's built into the classloader that
    many different classes use to get paths to resources.

    > It doesn't need to be put in some jar file, then retrieved,


    Why? Where were you intending to put it.. the cookie jar?

    >...then all
    > kinds of recovery code written to deal with the IOExceptions that can
    > result if Something Goes Wrong(tm)?


    Oh, of course, if nothing could conceivably go wrong
    with your own home rolled method* - don't bother with
    all this getResource crap.

    * Such as the image showing 'all white'.

    > No need to fiddle with classpath?


    Nope. You just need to specify it correctly for the application
    (once).

    > Everything is self-contained in the source files?


    Now you're ust being silly. Are you intending to put
    - properties files
    - help text
    - localization data
    - any of many other resources..
    ...'stitched in' to the code?

    Therein lies the path to madness, but (checks sig.)
    'Twisted'.. I see your on your way there, so...

    Go for it! ;-)

    Andrew T.
    Andrew Thompson, Nov 20, 2006
    #11
  12. Twisted

    Twisted Guest

    Andrew Thompson wrote:
    > Twisted wrote:
    > > Patricia Shanahan wrote:
    > > > What's the advantage of this approach compared to using getResource?

    > >
    > > It's built right into the frame subclass file it applies to?

    >
    > Why would it? It's built into the classloader that
    > many different classes use to get paths to resources.


    Eh -- getResource is, but the resource itself isn't.

    > Oh, of course, if nothing could conceivably go wrong
    > with your own home rolled method* - don't bother with
    > all this getResource crap.
    >
    > * Such as the image showing 'all white'.


    It works fine, and doesn't do any I/O to get it. The only way for
    something to go wrong would be if classloading went wrong at a
    fundamental level, rather than some image on disk somewhere not being
    found. If classloading goes that wrong, the image not being loaded is
    the least of my problems.

    > Now you're ust being silly. Are you intending to put
    > - properties files
    > - help text
    > - localization data
    > - any of many other resources..
    > ..'stitched in' to the code?


    If it gets complex enough to involve such, then there will be separate
    files for some of those, and I'll have to worry about how to get a user
    directory in a system-independent way to put the properties files in,
    and how to get the app's directory to look for help and non-English
    localizations in.
    Twisted, Nov 20, 2006
    #12
  13. Twisted wrote:

    > > ...Are you intending to put
    > > - properties files
    > > - help text
    > > - localization data
    > > - any of many other resources..
    > > ..'stitched in' to the code?

    >
    > If it gets complex enough to involve such, then there will be separate
    > files for some of those, and I'll have to worry about how to get a user
    > directory


    Try
    System.getProperty("user.home");

    (then make a subdirectory based on you main's
    package name, to contain the resources - so
    they don't get wiped by other applications)

    >...in a system-independent way to put the properties files in,
    > and how to get the app's directory to look for help and non-English
    > localizations in.


    JWS can handle localisation for you (in the sense
    of delivering the correct files for each locale),
    finding and using those localised resources would
    then most naturally be done using getResource().

    Java access to (internal - program specific) files is
    heavily based around getResource(), I suspect things
    will go a lot quicker for you once you have it working
    for you.

    Note: I never found a way to use getResource() for
    both jar'd and 'loose' resources, but with ant build files
    (or anything else with even half Ant's abilities) it
    is trivial to stamp out a jar(s) of the current project,
    and launch it(/them).

    Andrew T.
    Andrew Thompson, Nov 20, 2006
    #13
  14. Twisted

    Twisted Guest

    Andrew Thompson wrote:
    > Note: I never found a way to use getResource() for
    > both jar'd and 'loose' resources, but with ant build files
    > (or anything else with even half Ant's abilities) it
    > is trivial to stamp out a jar(s) of the current project,
    > and launch it(/them).


    Of course, for that I'd need Ant, and to know how to use it...
    Twisted, Nov 20, 2006
    #14
  15. Twisted

    Chris Smith Guest

    Twisted <> wrote:
    > > Now you're ust being silly. Are you intending to put
    > > - properties files
    > > - help text
    > > - localization data
    > > - any of many other resources..
    > > ..'stitched in' to the code?

    >
    > If it gets complex enough to involve such, then there will be separate
    > files for some of those, and I'll have to worry about how to get a user
    > directory in a system-independent way to put the properties files in,
    > and how to get the app's directory to look for help and non-English
    > localizations in.


    Actually, getResource is exactly the solution to everything you are
    mentioning. Nothing is stored in some directory on some disk somewhere.
    Everything is stored in the same JAR file with all of your code; one
    file that you can distribute around that contains the whole application.
    All this, and you don't have to do kludgy things like build images into
    the source code of your classes.

    (By the way, if exceptions should never happen, as is the case when
    using getResource on a resource that's packaged in a JAR file with your
    application, then it's pretty trivial to add

    try
    {
    ...
    }
    catch (SomeException e)
    {
    throw new RuntimeException(e);
    }

    No information is lost, and you don't have to write any complex error
    reporting code or anything like that. Just be careful that you don't
    catch some exceptions indicating real plausible problems like this.)

    --
    Chris Smith
    Chris Smith, Nov 20, 2006
    #15
  16. Twisted

    Joe Attardi Guest

    On Nov 20, 5:10 am, "Twisted" <> wrote:
    > Of course, for that I'd need Ant, and to know how to use it...


    Learning how to use Ant is a bad thing why? It's a very valuable and
    widely used development tool in the Java world.
    Joe Attardi, Nov 20, 2006
    #16
  17. Twisted

    Daniel Pitts Guest

    Twisted wrote:
    > Mark Rafn wrote:
    > > Wouldn't it be MUCH easier to put gif/jpg/png files directly into the jar,
    > > then let the classloader find them using getResource or getResourceAsStream?

    >
    > First of all, I don't *have* a jar, at least not yet.
    >
    > Second of all, this is the kind of thing that should really just work
    > without being able to bomb with IOExceptions and suchlike, in my
    > opinion. Retrieving even the most basic stuff from a bunch of external
    > files adds unnecessary points of failure, and gobs of extra recovery
    > code to check for and cope with anything that goes wrong. This way, it
    > Just Works(tm). :)


    "It Just Works(TM)" is considered a very bad approach to software
    design. Doing things that "Just Work" versus doing things that "Work
    Right", tends to save a minute now and cost a week later. What happens
    when you have three icons? 10? What happens when you rebrand those 10
    icons? Having them as actual image files rather than converting them.
    Ouch.

    BTW, if you REALLY wanted to go that route, you could do a byte dump of
    the original (png/jpeg/gif) image, and use imageio and a
    ByteArrayInputStream (there is such a thing, right?). Releasing you
    from using the apperantly buggy XImageWhatchamawhosit. Although, I
    wouldn't recommend either approach.
    Daniel Pitts, Nov 20, 2006
    #17
  18. Twisted

    Twisted Guest

    I find the phenomenon of topic drift curious. There seems to be a
    recurrent pattern in this group in which a person creates an initial
    topic of some Java related sort or another and the topic quickly drifts
    to criticism and "bashing" of the person that started the thread.

    This does nothing to encourage people to seek information here.

    Perhaps some people need to leave their egos at home when they visit?

    Re: the most recent round of (universally hostile-toned) replies, I'd
    already mentioned that bundling stuff in a jar is not a complication I
    wish to handle just yet. Particularly as it means the app has to look
    for resources in two places: in a jar with the app (where they'd be
    when the app's been packaged and installed somewhere) and in my
    computer's specific directory structure somewhere (where they'd be
    during development). Someone mentioned putting them along the class
    path and their being found automatically if they're there or in a jar
    with the app; but then I need to set my class path on my development
    machine to include the source directory for every project that has
    resources, don't I? Ouch. Or I can track down, download, study, and use
    a new build tool (when Eclipse has been serving me well so far)...it
    sounds to me like if I'd gone that route I'd still be fiddling with
    something merely preliminary to getting the icon to work *now*, around
    48 hours later. When there's a lot more resources, and
    optional/switchable ones like internationalization resources, then that
    looks like a wise investment of time; when there's only the one little
    32x32 gif, it seems more like a *waste* of time.
    Twisted, Nov 20, 2006
    #18
  19. Twisted wrote on 21.11.2006 00:06:
    > Re: the most recent round of (universally hostile-toned) replies, I'd
    > already mentioned that bundling stuff in a jar is not a complication I
    > wish to handle just yet. Particularly as it means the app has to look
    > for resources in two places: in a jar with the app (where they'd be
    > when the app's been packaged and installed somewhere) and in my
    > computer's specific directory structure somewhere (where they'd be
    > during development). Someone mentioned putting them along the class
    > path and their being found automatically if they're there or in a jar
    > with the app; but then I need to set my class path on my development
    > machine to include the source directory for every project that has
    > resources, don't I?


    Hmm. Netbeans does that automatically for me. I have all my resource in my Java
    source directory (gif, properties, xml and txt files). When I build my project,
    NetBeans compiles my Java classes (of course) and then copies all non-Java files
    to the classpath (according to their location in the Source path).

    I use getClassLoader().getResourceAsStream() in several places and this approach
    has never given me any headaches. It works fine from within NetBeans and as well
    when I distribute my (Swing) application as a jar file.

    Maybe you can convince Eclipse to copy the non-Java files as well?

    My 0.02€

    Thomas
    Thomas Kellerer, Nov 20, 2006
    #19
  20. Twisted

    Ian Wilson Guest

    Twisted wrote:
    > I find the phenomenon of topic drift curious. There seems to be a
    > recurrent pattern in this group in which a person creates an initial
    > topic of some Java related sort or another and the topic quickly drifts
    > to criticism and "bashing" of the person that started the thread.


    I suspect it is proportional to the amount of good advice previously
    ignored.

    > Perhaps some people need to leave their egos at home when they visit?


    True, have you considered whether your own ego might be getting in the
    way of your accepting good advice?

    > Re: the most recent round of (universally hostile-toned) replies, I'd
    > already mentioned that bundling stuff in a jar is not a complication I
    > wish to handle just yet.


    You must be aware that Eclipse has a wizard for creating Jars. I find it
    a lot less complex than your method of encoding image data within
    class files seems.

    > Particularly as it means the app has to look
    > for resources in two places: in a jar with the app (where they'd be
    > when the app's been packaged and installed somewhere) and in my
    > computer's specific directory structure somewhere (where they'd be
    > during development). Someone mentioned putting them along the class
    > path and their being found automatically if they're there or in a jar
    > with the app; but then I need to set my class path on my development
    > machine to include the source directory for every project that has
    > resources, don't I? Ouch. Or I can track down, download, study, and use
    > a new build tool (when Eclipse has been serving me well so far)...it
    > sounds to me like if I'd gone that route I'd still be fiddling with
    > something merely preliminary to getting the icon to work *now*, around
    > 48 hours later. When there's a lot more resources, and
    > optional/switchable ones like internationalization resources, then that
    > looks like a wise investment of time; when there's only the one little
    > 32x32 gif, it seems more like a *waste* of time.


    I use Eclipse, I have an image for my app in a subdirectory of my
    project. I have this code (and this code only) to load the image:

    setIconImage(new ImageIcon(MainForm.class
    .getResource("/resources/logo32.png")).getImage());

    When I run the app from Eclipse it finds the image from the subdirectory
    in the filesystem.

    After getting Eclipse to make a jar that includes the image, running the
    jar causes the image to be loaded from the jar instead. No change to the
    above code.

    I just don't see the problem you seem to be struggling against. I didn't
    need to do anything with my classpath or change my build tool (I use
    plain old Eclipse without Ant etc)

    Maybe I'm missing something, but it looks like you've spent more time
    thinking up arguments why you shouldn't try the suggestions offered than
    you would have spent simply trying them.
    Ian Wilson, Nov 21, 2006
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Miro Durcik

    app.rc resource's icon to .net Icon

    Miro Durcik, Oct 9, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    1,381
    Miro Durcik
    Oct 9, 2004
  2. Dan Polansky
    Replies:
    3
    Views:
    789
    Larry Barowski
    Feb 12, 2007
  3. David C

    sensible way to pass around values

    David C, Aug 6, 2007, in forum: ASP .Net
    Replies:
    3
    Views:
    325
    Ross Culver
    Aug 7, 2007
  4. sixteenmillion

    The giving that keeps on giving

    sixteenmillion, Nov 19, 2007, in forum: C Programming
    Replies:
    0
    Views:
    418
    sixteenmillion
    Nov 19, 2007
  5. Bodi
    Replies:
    1
    Views:
    274
    Lasse Reichstein Nielsen
    Nov 18, 2003
Loading...

Share This Page