import java.awt.*; import java.net.*; /** A class that supports Images as Components that can be repositioned * with the mouse. As with all Components, the effects may be eventually * undone by the layoutManager if it is not off (null) or chosen * appropriately. *
* By default, with FlowLayout the Icon 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 the builtin * Label class and of ImageLabel, upon which Icon is built. If you perform * an explicit resize or * reshape call before adding the ImageLabel to the * Container, this size will override the defaults. *
* This can be used in two ways. In the first, the Component itself * watches the mouse events, and allows the user to drag it around. * This has one major advantage: *
* If the Container does not already have a custom handleEvent method, * insert the following: *
*
* public boolean handleEvent(Event event) {
* if (Icon.handleIconEvent(event, this))
* return(true);
* else
* return(super.handleEvent(event));
* }
*
* If the Container does already have a custom handleEvent method, modify it
* by adding the Icon.handleEvent test at the top, as illustrated
* below:
* *
* public boolean handleEvent(Event event) {
* if (Icon.handleIconEvent(event, this))
* return(true);
* Original handleEvent code here
* }
*
* If instead you want the Icon to handle its own mouse events, simply
* set the Icon's ignoreEvents variable to false. Do not mix these
* two modes in a single program.
* * The original of the Icon source code is at * * http://www.apl.jhu.edu/~hall/java/ImageLabel/Icon.java, * the documentation is at * * .../Icon.html, and a small example program can be found at * * .../IconTest.html. *
* No warranty of any kind is provided. * Permission is granted to use and/or modify * for any purpose. *
* 7/96 Marty Hall: *
* * @version 1.0 (August 1996) * @see ImageButton */ public class Icon extends ImageLabel { //------------------------------------------------------------------------- /** Should the image be highlighted when you click/drag? Default = true. */ public boolean highlightable = true; /** How thick should the highlighting rectangle be? * Default = 3. Ignored if highlightable is false. */ public int highlightThickness = 3; /** The Color to use for the highlight rectangle. * Default is Color.blue. Ignored if highlightable is false. */ public Color highlightColor = Color.blue; /** Can the image be dragged with the mouse? * Default = true. (If it will always be false, use * an ImageLabel instead). */ public boolean draggable = true; // Is it currently being dragged? This is used in the case when // the Container is tracking movement, since the mouse may not // be over the Component. private boolean beingDragged = false; /** The cursor to get when dragging. Default is Frame.MOVE_CURSOR */ public int dragCursor = Frame.MOVE_CURSOR; // The previous cursor, so that it can be changed back private int previousCursor = Frame.DEFAULT_CURSOR; // The Frame that owns the cursor private Frame topFrame = null; // TO DO: Document private boolean ignoreEvents = true; //------------------------------------------------------------------------- /** If the Container was always going to handle the mouse events, * it could simply look up the event type and call a helper method * directly. This, however, allows event handling either locally * (if ignoreEvents is false) or in the Container. * You cannot override this arbitrarily in subclasses. */ public boolean handleEvent(Event event) { if (ignoreEvents) { return(false); } else { return(super.handleEvent(event)); } } //------------------------------------------------------------------------- /** Called from the handleEvent method of the Container if the Container * is to handle the mouse events. See the introduction to this class. */ public static boolean handleIconEvent(Event event, Container container) { int x = event.x; int y = event.y; Icon targetIcon = iconBeingDragged(container); if (targetIcon == null) { // You should be able to use container.locate instead of // Icon.componentUnder(x, y, container), but Netscape // has a bug with locate() and inside(). They work fine // in applications and appletviewer. Component targetComponent = Icon.componentUnder(x, y, container); // Component targetComponent = container.locate(x, y); if (!(targetComponent instanceof Icon)) return(false); else targetIcon = (Icon)targetComponent; } Point iconLocation = targetIcon.location(); int iconX = iconLocation.x; int iconY = iconLocation.y; event.translate(-iconX, -iconY); targetIcon.ignoreEvents = false; boolean result = targetIcon.handleEvent(event); targetIcon.ignoreEvents = true; event.translate(iconX, iconY); return(result); } //------------------------------------------------------------------------- private static Icon iconBeingDragged(Container container) { Component[] components = container.getComponents(); Component current; for(int i=0; i