Set an image from a URL in a Swing component
This occured a while ago to me when I had to build an application that
was showing a logo on every single dialog. The logo was supposed to be shown
in each dialog in the upper-right corner and it was supposed to be an
"offer of the day" image (i.e. changing every day or so).I thought first
about using the technique described in the previous paragraph
and actually use the HTML capabilities of the Swing components. However,
the problem with that was that the image stayed the same throughout the
a typical execution cycle of the program, and it did make sense to refresh
the image on each startup of the program, by embedding an <image>
tag in each dialog, it meant that every time a new window was opened in
my application, the underlying code would make a new HTTP request to the
server to fetch the image -- not the best idea, as it was delaying the
window from appearing and it was also wasting bandwidth (and memory)!
So instead of that I opted for creating an Image object
from that URL when the application started and using that Image
in all the windows that my application was opening. The code to create
such an Image from an URL is as follows:
...
URL url = new URL( "http://server/image.jpg" );
Image image = Toolkit.getDefaultToolkit().createImage( url );
...
Once the image is created, you will have to build an ImageIcon
based on it, as the Swing components normally take instances of Icon
as parameters for their Icon property:
...
ImageIcon icon = new ImageIcon( image );
...
Having done that,
you can build as many JLabels as you need and set their
Icon property to the newly-created ImageIcon object.
Download the source.
Read our download disclaimer.
|
Creating a JPanel with a background image
Now I'm not sure why somebody would still be using the (slow) Swing framework for
GUI nowadays, but for those who are, occasionally, it is cool to have a nice background
image in your panels. This might be to either give a consistent look to your application
windows or perhaps to just brand your product. Unfortunately, the "good" (?!?!) ole'
JPanel class doesn't offer support for this -- what a surprise :D
There is though an easy way to do this. And what's even cool about it is that your
image in this case can even be an animated one (e.g. GIF or PNG)! In fact, if you download
the full sample project (below) you will see that I am using an animated GIF for that
and it is shown in the background animated. Even more, the image will actually stretch
to the whole area covered by your panel.
So the trick is to extend the JPanel class and write your own panel class
that overrides the paintComponent() function. Note that we are talking
about the paintComponent() (and not paint() !) function
here! The only thing you have to do in that function is to place a call to
Graphics.drawImage() using the Graphics object passed as a parameter
to the function and the image you want to use as a background. For coordinates, you have quite
a choice:
- If you want just a background image that spans over the whole panel, then use the full
width and height of the panel, starting at 0,0
- If you want the picture to be centered and only take half the width and height of the
panel then simply start at
getWidth() / 4 and getHeight() / 4
and go up to 3 * getWidth() / 4 and 3 * getHeight() / 4.
- If you want an image placed in the top left corner which only takes half the space,
then start at (0, 0) and go only up to
getWidth() / 2 and getHeight() / 2
I'm sure you get the picture. Here's the snippet of code that is actually used in the code:
protected void paintComponent( Graphics g )
{
super.paintComponent( g );
if( backgroundImage == null )
return;
g.drawImage( backgroundImage, 0, 0, getWidth(), getHeight(), this );
}
There's only one last thing to be mentioned here: the usage of this in the above
snippet of code: we are using the version of drawImage() that accepts as a last
parameter an ImageObserver! And JPanel does implement this interface,
so it will get notified as "more of the image becomes available" (or, if it is an animated
one, as we switch from frame to frame), and based on this notifications it will update
the image in the background. You will notice that if you remove this, the code will still
work for static images but as soon as you pass an animated one, only the first frame
will be shown. Of course, there's a downsize to that -- extra processing, but you didn't expect
to trade off anything, did you? After all, you're using Swing, for God's sake! :P
So, as an optimization tip: if you are planning to use static images, or don't want to take
the extra hit due to animated images used (wrongly!) by your users, pass in the last parameter
as null in the above call to drawImage() -- otherwise, leave it as
it is and enjoy your animated GUI. (Note to self: Thank God they removed
<blink> from HTML at least!)
Download the source.
Download the whole project (including the test class
and the background animated GIF). Note that this is an Eclipse project so you will need
Eclipse to run it.
Read our download disclaimer.
|