/* * Permission to use, copy, modify and distribute this software and its * documentation without fee for NON-COMMERCIAL purposes is hereby granted * provided that this notice with a reference to the original source and * the author appears in all copies or derivatives of this software. * * THE AUTHOR MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF * THIS SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE AUTHOR SHALL NOT BE LIABLE FOR * ANY DAMAGES SUFFERED BY ANYBODY AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. */ import java.awt.*; import java.lang.*; import java.net.URL; import java.util.*; /** * ticker - Scrolling Text with colors, speed, url, timedependant starting and expiring
* Some Ideas from Sven Heinicke, Author of TickerTape
* *

V b1.00, 10/06/95: Creation by Thomas Wendt (thw)
* V b1.01, 11/18/95: Cleaning up the code by thw
* V b1.10, 11/28/95: Fixed mem leakage, synchronized run and update by thw
* V b1.20, 12/31/95: Added new features by thw
* V b1.21, 01/03/96: bugfix: stop thread by thw
* V b1.30, 02/07/96: Added support for multilingual use by thw; netscapes bug in doing this * and a workaround found by Peter Sylvester
* *

origin of ticker.
* * @author Thomas Wendt * @version b1.30, 02/07/96 */ public class ticker extends java.applet.Applet implements Runnable { /** The offscreen image */ public Image im = null; /** The offscreen drawing context */ public Graphics gr = null; /** The message to be displayed. */ public String message; /** The Font to be displayed. */ public Font messageF; /** x-position of message. */ public int messageX; /** y-position of message. */ public int messageY; /** Length of the message. */ public int messageW = 0; /** URL to switch to */ public URL url_ = null; /** How far to skip across the screen. */ int speed; /** The animating thread. */ public Thread t = null; /** The Color of the Text. */ public Color txtCo; /** The textstyle. */ public int txtStyle; /** The Color of the first textshadow. */ public Color shCo1; /** The Color of the second textshadow. */ public Color shCo2; /** The Color of the frame. */ public Color hrefCo; /** The backgroundcolor. */ public Color bgCo; /** True, if to be filled with bgCo after expiration */ public boolean ExFill; /** * The time-dependant state of the applet. * True, if not started or expired */ public boolean expired = false; /** Flag for using shadow */ public boolean useShadow; /** Flag for using frame if url is given */ public boolean useFrame; /** The Size used to calc the Font. */ public Dimension lastS = new Dimension(1,1); /** * Fix a netscape bug: We get 0xffcc, if we should * get 0x00cc. To make it possible to display non-ascii * characters, we need a workaround and forget uni-code.
* Author of the following method is * Peter Sylvester */ public String fixedgetParameter(String s) { char ec[] = s.toCharArray(); for (int i=0; i < ec.length; i++) ec[i] &= 0x00ff ; return(new String(ec)) ; } /** * Initialize: Read Attributes * Resize to (2,2) and do nothing if expired; */ public void init () { Date today = new Date(); Date anyDay; String at = getParameter("msg"); message = (at == null) ? "ticker for beta" : fixedgetParameter(at); // use readColor to read the Date; date and color both have 3 components. bgCo = readColor(getParameter("exp"), Color.white); if (!bgCo.equals(Color.white)) { anyDay = new Date(bgCo.getRed(),bgCo.getGreen()-1,bgCo.getBlue()); expired = today.after(anyDay); } if (!expired) { bgCo = readColor(getParameter("start"), Color.black); if (!bgCo.equals(Color.black)) { anyDay = new Date(bgCo.getRed(),bgCo.getGreen()-1,bgCo.getBlue()); expired = anyDay.after(today); } } // don't show, if expired ExFill = (getParameter("exfill") != null); if (expired && !ExFill) { resize(2,2); return; } speed = ((at = getParameter("speed")) == null) ? 10 : (Integer.valueOf(at).intValue()); if ((at = getParameter("href")) != null) { try { url_ = new URL(getDocumentBase(), at); } catch (Exception e) { url_ = null; } } // use default txtco = blue, if url is given; black otherwise if (url_ == null) { bgCo = Color.black; } else { bgCo = Color.blue; } // get the colors txtCo = readColor(getParameter("txtco"), bgCo); bgCo = readColor(getParameter("bgco"), getBackground()); shCo2 = readColor(getParameter("shco"), bgCo); useShadow = !(shCo2.equals(bgCo)); hrefCo = readColor(getParameter("hrefco"), Color.blue); useFrame = !(hrefCo.equals(bgCo)); txtStyle = useShadow ? Font.PLAIN : Font.BOLD; if (useShadow) { int r = (shCo2.getRed()+txtCo.getRed()) >> 1; int g = (shCo2.getGreen()+txtCo.getGreen()) >> 1; int b = (shCo2.getBlue()+txtCo.getBlue()) >> 1; shCo1 = new Color(r,g,b); } } /** Parameter Info. */ public String[][] getParameterInfo() { String[][] info = { {"msg", "String", "Message to display"}, {"href", "String", "url to switch to"}, {"speed", "int", "animation speed in pixels (10)"}, {"txtco", "int[3]", "RGB-Color of Message (black/blue)"}, {"hrefco", "int[3]", "RGB-Color of Frame (blue)"}, {"bgco", "int[3]", "RGB-Color of background (getBackground)"}, {"shco", "int[3]", "RGB-Color of Message (black/blue)"}, {"start", "int[3]", "Date to start: Y, M, D; if not set, show"}, {"exp", "int[3]", "Date to expire: Y, M, D; if not set, no expiration"}, {"exfill", "", "If exist, fill with bgco, if expired"}, }; return info; } /** Applet Info. */ public String getAppletInfo() { return "ticker.java, V b1.30, 02/07/96 by Thomas Wendt, http://www.uni-kassel.de/fb16/ipm/mt/staff/thwendte.html"; } /** * Convert a ","-delimited String with RGB-Values to Color * Uses aDefault, if no or not enough RGB-Values */ public Color readColor(String aColor, Color aDefault) { if (aColor == null) { return aDefault; } int r, g, b; StringTokenizer st = new StringTokenizer(aColor, ","); try { r = Integer.valueOf(st.nextToken()).intValue(); g = Integer.valueOf(st.nextToken()).intValue(); b = Integer.valueOf(st.nextToken()).intValue(); return new Color(r,g,b); } catch (Exception e) { return aDefault; } } /** * Create the image Parameters. * Called, if just created or size has changed */ public void createParams() { // Init some constants int w = size().width; int h = size().height; lastS.width = w; lastS.height = h; // Calc the font and positions. Message must fit applets area. int refH = 14; Font tf = new Font("TimesRoman", txtStyle, refH); setFont(tf); FontMetrics tfm = getFontMetrics(tf); int fh = tfm.getHeight(); fh = refH*(h-10)/fh; messageF = new Font("TimesRoman", txtStyle, fh); FontMetrics fm = getFontMetrics(messageF); fh = fm.getHeight(); messageX = w; messageY = ((h-fh) >> 1)+fm.getAscent(); messageW = fm.stringWidth(message); // Use double buffering to avoid flicker. if (gr != null) gr.dispose(); im = createImage(lastS.width, lastS.height); gr = im.getGraphics(); } /** Show the stuff, call update */ public void paint(Graphics g) { update(g); } /** Show the stuff */ public synchronized void update(Graphics g) { int w = size().width; int h = size().height; // Exit, if expired if (expired) { if (ExFill) { g.setColor(bgCo); g.fillRect(0,0,w,h); } return; } // Recalc params, if something has changed if ((h != lastS.height) || (w != lastS.width)) createParams(); // fill area with bgcolor gr.setColor(bgCo); gr.fillRect(0,0,w,h); // if url is given, let it look like a link if (url_ != null && useFrame) { gr.setColor(hrefCo); gr.clipRect(0,0,w,h); gr.drawRect(0,0,w,h); gr.drawRect(1,1,w-2,h-2); gr.setColor(bgCo); gr.draw3DRect(2,2,w-4, h-4, true); gr.draw3DRect(3,3,w-6, h-6, true); gr.clipRect(4,4,w-8, h-8); } // draw the text gr.setFont(messageF); if (useShadow) { gr.setColor(shCo2); gr.drawString(message, messageX+2, messageY+1); gr.setColor(shCo1); gr.drawString(message, messageX+1, messageY); } gr.setColor(txtCo); gr.drawString(message, messageX, messageY); // finally show all together on the screen g.drawImage(im,0,0,this); } public void calcPos() { // decrement position messageX -= speed; // and stay in the bounds if ((messageX + messageW) < 0) messageX = size().width; } /** Run the loop. This method is called by class Thread. */ public void run() { // do nothing, if expired if (expired) return; // others might be more important Thread.currentThread().setPriority(Thread.MIN_PRIORITY); while (t != null) { // indirectly call update repaint(); calcPos(); // pause try {Thread.sleep(100);} catch (InterruptedException e){} } } /** Start the applet by forking an animation thread. */ public void start() { if (t == null) { t = new Thread(this); t.start(); } } /** Stop the applet. The thread will exit because run() exits. */ public void stop() { if (t != null) { t.stop(); t = null; } im = null; if (gr != null) { gr.dispose(); gr = null; } lastS = new Dimension(1,1); } /** Switch to url, if url is given. */ public boolean mouseUp(Event evt, int x, int Y) { if (url_ != null) getAppletContext().showDocument(url_); // might not work with some early browsers return true; } /** Status: show URL */ public boolean mouseEnter(Event evt, int x, int y) { if (url_ != null) { showStatus(url_.toExternalForm()); } return true; } /** clear status */ public boolean mouseExit(Event evt, int x, int y) { if (url_ != null) { showStatus(" "); } return true; } }