/* * Marquee.java v1.0 Nov 10, 1996 * * Copyright (c) 1996-7 H.J. Tsai, Inc. All Rights Reserved. * * Permission to use, copy, modify, and distribute this software * and its documentation for any purposes and without * fee is hereby granted provided that this copyright notice * appears in all copies. * * H.J. Tsai MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. H.J. Tsai SHALL NOT BE LIABLE FOR * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. * * Author: H.J. Tsai hjtsai@cargobay.com * * Version 1.0 Nov 10, 1996 * Initial version * */ /** * Marquee - a class object for a scrolling text marquee. * The scrolling text appears in the container. * * The following Microsoft Explorer's MARQUEE Tag parameters * and description are supported: * * * Parameters * * BEHAVIOR=type * Specifies how the text should behave. * The type can be one of these values: * SCROLL Start completely off one side, * scroll all the way across and completely off, * and then start again. This is the default. * SLIDE Start completely off one side, scroll in, and * stop as soon as the text touches the other margin. * ALTERNATE Bounce back and forth within the marquee. * * BGCOLOR=color * Specifies a background color for the marquee. * * DIRECTION=direction * Specifies in which direction the text should scroll. * The direction can be LEFT or RIGHT. The default is LEFT, * which means scrolling from right to left. * * LOOP=n * Specifies how many times a marquee will loop when activated. * If LOOP=-1, or if LOOP=INFINITE, the marquee will loop indefinitely. * * SCROLLAMOUNT=n * Specifies the number of pixels between each successive draw of the * marquee text. * * SCROLLDELAY=n * Specifies the number of milliseconds between each successive draw of * the marquee text. * * * The following additional parameters are required/supported: * See Marquee() constructor. * * Rectangle r * Sepcifies the bounding rectangle for the marquee. * * Color fgColor * Sepcifies the color used for the text. * * Strng fontName * Specifies the font family used for the text. * * int fontStyle * Specifies the font style used for the text. * * int fontSize * Specifies the font size used for the text. * * String text * Specifies the text to be scrolled. * * Component comp * Specifies the containing component. */ import java.awt.*; public class Marquee implements Runnable { // behaviors public static final int SCROLL = 1; public static final int SLIDE = 2; public static final int ALTERNATE = 3; // directions public static final int LEFT = 1; public static final int RIGHT = 2; // loop public static final int INFINITE = -1; private int loop = INFINITE; private int scrollamount = 10; private int scrolldelay = 100; private int behavior = SCROLL; private int dir = LEFT; private Rectangle rect; private Color foreground; private Color background; private String text; private String fontName = "Helvetica"; private int fontStyle = Font.ITALIC; private int fontSize = 10; private int delta; private char msg[]; private int offset = 0; private int nchar; private int pos = 0; private int msgwidth; private Component comp; public Marquee( Rectangle r, int loop, int amount, int delay, int direction, int behavior, String text, Color bgColor, Color fgColor, Component comp) { this(r, loop, amount, delay, direction, behavior, text, fgColor, bgColor, "Helvetica", Font.ITALIC, 10, comp); } public Marquee( Rectangle r, int loop, int amount, int delay, int direction, int behavior, String text, Color fgColor, Color bgColor, String fontName, int fontStyle, int fontSize, Component comp) { this.rect = r; this.loop = loop; this.dir = direction; this.scrollamount = amount; this.scrolldelay = delay; this.behavior = behavior; this.text = text; this.foreground = fgColor; this.background = bgColor; this.fontName = fontName; this.fontStyle = fontStyle; this.fontSize = fontSize; this.comp = comp; } public void run() { Image img = comp.createImage(rect.width, rect.height); Graphics memg = img.getGraphics(); // clear background memg.setColor(background); memg.fillRect(0, 0, rect.width, rect.height); // create Font Font font = new Font(fontName, fontStyle, fontSize); memg.setFont(font); FontMetrics fm = memg.getFontMetrics(); int maxadvance = fm.getMaxAdvance() < 0 ? 0 : fm.getMaxAdvance(); msgwidth = fm.stringWidth(text) + maxadvance; int height = fm.getAscent(); msg = text.toCharArray(); int y = (rect.height+height)/2; // set the starting x coordinate resetPosition(); Graphics g = comp.getGraphics(); g.clipRect(rect.x, rect.y, rect.width, rect.height); memg.setColor(foreground); while (loop == -1 || loop > 0) { try { memg.setColor(background); memg.fillRect(0, 0, rect.width, rect.height); memg.setColor(foreground); memg.drawChars(msg, offset, nchar, pos, y); g.drawImage(img, rect.x, rect.y, null); Thread.sleep(scrolldelay); if (doneScroll()) { if (loop > 0) loop--; if (behavior == SLIDE) break; if (behavior == ALTERNATE) toggleDirection(); resetPosition(); } else setVisiableText(); } catch (InterruptedException e) { break; } } } private void toggleDirection() { if (dir == LEFT) dir = RIGHT; else dir = LEFT; } private void resetPosition() { if (dir == LEFT) { pos = rect.x + rect.width; delta = -scrollamount; } else { pos = rect.x - msgwidth; delta = scrollamount; } offset = 0; nchar = msg.length; } private boolean doneScroll() { if (behavior == SLIDE) { if ((dir == LEFT && pos <= rect.x) || (dir == RIGHT && pos + msgwidth >= rect.x +rect.width)) return true; else return false; } else if (pos + msgwidth < rect.x || pos > rect.x + rect.width) return true; else return false; } private void setVisiableText() { // set offset, nchar pos += delta; // for SLIDE, we need to stop at the edge if (behavior == SLIDE) { if (dir == LEFT && pos < rect.x) pos = rect.x; else if (dir == RIGHT && pos + msgwidth > rect.x + rect.width) pos = rect.x + rect.width - msgwidth; } offset = 0; nchar = msg.length; } }