📄 imagelabel.java
字号:
package ergo.ui;
// $Id: ImageLabel.java,v 1.4 1999/08/13 01:20:08 sigue Exp $
/*
* Copyright (C) 1999 Carl L. Gay and Antranig M. Basman.
* See the file copyright.txt, distributed with this software,
* for further information.
*/
import java.awt.*;
import java.net.URL;
import java.net.MalformedURLException;
// 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.
* <P>
* 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 <B>before</B> adding the
* ImageLabel to the Container, this size will
* override the defaults.
* <P>
* Here is an example of its use:
* <P>
* <PRE>
* 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);
* }
* }
* </PRE>
*
* @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 = "<Existing Image>";
// Turn this on to get verbose debugging messages.
private static boolean debug = false;
/** Amount of extra space around the image. */
private int border = 0;
/** If there is a non-zero border, what color should
* it be? Default is to use the background color
* of the Container.
*/
private Color borderColor = null;
// Width and height of the Canvas. This is the
// width/height of the image plus twice the border.
private int width, height;
/** Determines if it will be sized automatically.
* If the user issues a resize() or reshape()
* call before adding the label to the Container,
* or if the LayoutManager resizes before
* drawing (as with BorderLayout), then those sizes
* override the default, which is to make the label
* the same size as the image it holds (after
* reserving space for the border, if any).
* This flag notes this, so subclasses that
* override ImageLabel need to check this flag, and
* if it is true, and they draw modified image,
* then they need to draw them based on the width
* height variables, not just blindly drawing them
* full size.
*/
private boolean explicitSize = false;
private int explicitWidth = 0, explicitHeight = 0;
// The MediaTracker that can tell if image has been
// loaded before trying to paint it or resize
// based on its size.
private MediaTracker tracker;
// Used by MediaTracker to be sure image is loaded
// before paint & resize, since you can't find out
// the size until it is done loading.
private static int lastTrackerID = 0;
private int currentTrackerID;
private boolean doneLoading = false;
private Container parentContainer;
//----------------------------------------------------
/** Create an ImageLabel with the default image.
*
* @see #getDefaultImageString
* @see #setDefaultImageString
*/
// Remember that the funny "this()" syntax calls
// constructor of same class
public ImageLabel() {
this(defaultImageString);
}
/** Create an ImageLabel using the image at URL
* specified by the string.
*
* @param imageURLString A String specifying the
* URL of the image.
*/
public ImageLabel(String imageURLString) {
this(makeURL(imageURLString));
}
/** Create an ImageLabel using the image at URL
* specified.
*
* @param imageURL The URL of the image.
*/
public ImageLabel(URL imageURL) {
this(loadImage(imageURL));
imageString = imageURL.toExternalForm();
}
/** Create an ImageLabel using the image in the file
* in the specified directory.
*
* @param imageDirectory Directory containing image
* @param file Filename of image
*/
public ImageLabel(URL imageDirectory, String file) {
this(makeURL(imageDirectory, file));
imageString = file;
}
/** Create an ImageLabel using the image specified.
* The other constructors eventually call this one,
* but you may want to call it directly if you
* already have an image (e.g. created via
* createImage).
*
* @param image The image
*/
public ImageLabel(Image image) {
this.image = image;
tracker = new MediaTracker(this);
currentTrackerID = lastTrackerID++;
tracker.addImage(image, currentTrackerID);
}
//----------------------------------------------------
/** Makes sure that the Image associated with the
* Canvas is done loading before returning, since
* loadImage spins off a separate thread to do the
* loading. Once you get around to drawing the
* image, this will make sure it is loaded,
* waiting if not. The user does not need to call
* this at all, but if several ImageLabels are used
* in the same Container, this can cause
* several repeated layouts, so users might want to
* explicitly call this themselves before adding
* the ImageLabel to the Container. Another
* alternative is to start asynchronous loading by
* calling prepareImage on the ImageLabel's
* image (see getImage).
*
* @param doLayout Determines if the Container
* should be re-laid out after you are finished
* waiting. <B>This should be true when called
* from user functions</B>, but is set to false
* when called from preferredSize to avoid an
* infinite loop. This is needed when
* using BorderLayout, which calls preferredSize
* <B>before</B> calling paint.
*/
public void waitForImage(boolean doLayout) {
if (!doneLoading) {
debug("[waitForImage] - Resizing and waiting for "
+ imageString);
try {
tracker.waitForID(currentTrackerID);
}
catch (InterruptedException ie) {}
catch (Exception e) {
System.out.println("Error loading "
+ imageString + ": "
+ e.getMessage());
e.printStackTrace();
}
if (tracker.isErrorID(0))
new Throwable("Error loading image "
+ imageString).printStackTrace();
doneLoading = true;
if (explicitWidth != 0)
width = explicitWidth;
else
width = image.getWidth(this) + 2*border;
if (explicitHeight != 0)
height = explicitHeight;
else
height = image.getHeight(this) + 2*border;
setSize(width, height);
debug("[waitForImage] - " + imageString + " is "
+ width + "x" + height + ".");
// If no parent, you are OK, since it will have
// been resized before being added. But if
// parent exists, you have already been added,
// and the change in size requires re-layout.
if (((parentContainer = getParent()) != null)
&& doLayout) {
setBackground(parentContainer.getBackground());
parentContainer.doLayout();
}
}
}
//----------------------------------------------------
/** Moves the image so that it is <I>centered</I> at
* the specified location, as opposed to the move
* method of Component which places the top left
* corner at the specified location.
* <P>
* <B>Note:</B> 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 + ")");
setLocation(x - width/2, y - height/2);
}
//----------------------------------------------------
/** Determines if the x and y <B>(in the ImageLabel's
* own coordinate system)</B> 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 contains(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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -