import java.awt.*; import java.net.*; // This appears in Core Web Programming from // Prentice Hall Publishers, and may be freely used // or adapted. 1997 Marty Hall, hall@apl.jhu.edu. //====================================================== /** * A class for displaying images. It places the Image * into a canvas so that it can moved around by layout * managers, will get repainted automatically, etc. * No mouseXXX or action events are defined, so it is * most similar to the Label Component. *
* By default, with FlowLayout the ImageLabel takes * its minimum size (just enclosing the image). The * default with BorderLayout is to expand to fill * the region in width (North/South), height * (East/West) or both (Center). This is the same * behavior as with the builtin Label class. If you * give an explicit resize or * reshape call before adding the * ImageLabel to the Container, this size will * override the defaults. *
* Here is an example of its use: *
*
* public class ShowImages extends Applet {
* private ImageLabel image1, image2;
*
* public void init() {
* image1 = new ImageLabel(getCodeBase(),
* "some-image.gif");
* image2 = new ImageLabel(getCodeBase(),
* "other-image.jpg");
* add(image1);
* add(image2);
* }
* }
*
*
* @author Marty Hall (hall@apl.jhu.edu)
* @see Icon
* @see ImageButton
* @version 1.0 (1997)
*/
public class ImageLabel extends Canvas {
//----------------------------------------------------
// Instance variables.
// The actual Image drawn on the canvas.
private Image image;
// A String corresponding to the URL of the image
// you will get if you call the constructor with
// no arguments.
private static String defaultImageString
= "http://java.sun.com/lib/images/" +
"logo.java.color-transp.55x60.gif";
// The URL of the image. But sometimes we will use
// an existing image object (e.g. made by
// createImage) for which this info will not be
// available, so a default string is used here.
private String imageString = "* Note: The effects of this could be undone * by the LayoutManager of the parent Container, if * it is using one. So this is normally only used * in conjunction with a null LayoutManager. * * @param x The X coord of center of the image * (in parent's coordinate system) * @param y The Y coord of center of the image * (in parent's coordinate system) * @see java.awt.Component#move */ public void centerAt(int x, int y) { debug("Placing center of " + imageString + " at (" + x + "," + y + ")"); move(x - width/2, y - height/2); } //---------------------------------------------------- /** Determines if the x and y (in the ImageLabel's * own coordinate system) is inside the * ImageLabel. Put here because Netscape 2.02 has * a bug in which it doesn't process inside() and * locate() tests correctly. */ public synchronized boolean inside(int x, int y) { return((x >= 0) && (x <= width) && (y >= 0) && (y <= height)); } //---------------------------------------------------- /** Draws the image. If you override this in a * subclass, be sure to call super.paint. */ public void paint(Graphics g) { if (!doneLoading) waitForImage(true); else { if (explicitSize) g.drawImage(image, border, border, width-2*border, height-2*border, this); else g.drawImage(image, border, border, this); drawRect(g, 0, 0, width-1, height-1, border, borderColor); } } //---------------------------------------------------- /** Used by layout managers to calculate the usual * size allocated for the Component. Since some * layout managers (e.g. BorderLayout) may * call this before paint is called, you need to * make sure that the image is done loading, which * will force a resize, which determines the values * returned. */ public Dimension preferredSize() { if (!doneLoading) waitForImage(false); return(super.preferredSize()); } //---------------------------------------------------- /** Used by layout managers to calculate the smallest * size allocated for the Component. Since some * layout managers (e.g. BorderLayout) may * call this before paint is called, you need to * make sure that the image is done loading, which * will force a resize, which determines the values * returned. */ public Dimension minimumSize() { if (!doneLoading) waitForImage(false); return(super.minimumSize()); } //---------------------------------------------------- // LayoutManagers (such as BorderLayout) might call // resize or reshape with only 1 dimension of // width/height non-zero. In such a case, you still // want the other dimension to come from the image // itself. /** Resizes the ImageLabel. If you don't resize the * label explicitly, then what happens depends on * the layout manager. With FlowLayout, as with * FlowLayout for Labels, the ImageLabel takes its * minimum size, just enclosing the image. With * BorderLayout, as with BorderLayout for Labels, * the ImageLabel is expanded to fill the * section. Stretching GIF/JPG files does not always * result in clear looking images. So just as * with builtin Labels and Buttons, don't * use FlowLayout if you don't want the Buttons to * get resized. If you don't use any * LayoutManager, then the ImageLabel will also * just fit the image. *
* Note that if you resize explicitly, you must do * it before the ImageLabel is added to the * Container. In such a case, the explicit size * overrides the image dimensions. * * @see #reshape */ public void resize(int width, int height) { if (!doneLoading) { explicitSize=true; if (width > 0) explicitWidth=width; if (height > 0) explicitHeight=height; } super.resize(width, height); } /** Resizes the ImageLabel. If you don't resize the * label explicitly, then what happens depends on * the layout manager. With FlowLayout, as with * FlowLayout for Labels, the ImageLabel takes its * minimum size, just enclosing the image. With * BorderLayout, as with BorderLayout for Labels, * the ImageLabel is expanded to fill the * section. Stretching GIF/JPG files does not always * result in clear looking images. So just as * with builtin Labels and Buttons, don't * use FlowLayout if you don't want the Buttons to * get resized. If you don't use any * LayoutManager, then the ImageLabel will also * just fit the image. *
* Note that if you resize explicitly, you must do
* it before the ImageLabel is added to the
* Container. In such a case, the explicit size
* overrides the image dimensions.
*
* @see #resize
*/
public void reshape(int x, int y,
int width, int height) {
if (!doneLoading) {
explicitSize=true;
if (width > 0)
explicitWidth=width;
if (height > 0)
explicitHeight=height;
}
super.reshape(x, y, width, height);
}
//----------------------------------------------------
// You can't just set the background color to
// the borderColor and skip drawing the border,
// since it messes up transparent gifs. You
// need the background color to be the same as
// the container.
/** Draws a rectangle with the specified OUTSIDE
* left, top, width, and height.
* Used to draw the border.
*/
protected void drawRect(Graphics g,
int left, int top,
int width, int height,
int lineThickness,
Color rectangleColor) {
g.setColor(rectangleColor);
for(int i=0; i