/*
* TextScroll.java 2.8.3 15/12/98
*
* Copyright (c) 1997, 1998 by Kevin Swan. All rights reserved.
*
* I reserve all rights to this software. You may use it and
* distribute it freely, provided you do not remove this header
* and attribute partial credit to the author, Kevin Swan.
*
* 24 Feb 1998 Added directives to catch up to the Java 1.1 version.
* 27 Feb 1998 Added setCenter() directive.
* Modified the supportedDirective() to use an array.
* Released as version 2.2.
* 27 Feb 1998 Added setBold() and setItalic() directives.
* Added an element, inset, for the x coordinate
* of text to permit an inset.
* Added directive setInset() to set the inset.
* Released as version 2.3.
* 31 Mar 1998 Modified to permit complete URLs in the "data"
* parameter of the applet.
* Released as version 2.4.
* 01 Apr 1998 Added setURL() directive.
* Added version and credit information to init() method.
* Released as version 2.5.
* 05 Apr 1998 Modified so that if a URL has been set using setURL(),
* then when the user moves their mouse over the applet,
* the target URL is displayed in the status bar, instead
* of "Click to start/stop the applet." If no URL is set,
* it still displays "Click to ..."
* 14 Apr 1998 Modified to display applet info in status bar instead of
* "Click to ..." if no URL is set.
* Released as version 2.5.2.
* 14 Apr 1998 Modified to display messages while loading data, makes
* it a little more professional looking.
* Added the DataLoader class for asynchronous text data
* loading.
* Added the DirectiveManager class to decrease
* responsibility of the main class, and to work towards
* automatic text wrapping.
* Added the LineWrapManager class to take care of the
* line wrapping.
* Released as version 2.6.
* 16 Apr 1998 Modified to permit specification of a target frame as
* well as a target URL.
* Released as version 2.7.
* 20 Apr 1998 Did some major internal rewriting to correct the scrolling
* algorithm. It is now more "correct." Also lengthened
* the offscreen canvas to support font sizes of up to 200
* pixels.
* Added ability to refresh data from server.
* Expanded documentation.
* Released first version offered as Java 1.0 only.
* Released as version 2.8.
* 21 Apr 1998 Added ability to alter the loading/error colors through
* tags.
* Modified to notify DataLoader thread when start() and
* stop() are called.
* Released as version 2.8.1.
* 04 Jun 1998 Added ability to disable automatic line wrapping by
* including a tag.
* Was not officially released yet.
* 06 Jun 1998 Modified setURL () to handle commas in valid URLs.
* Released as version 2.8.2.
* 15 Dec 1998 Made some major modifications to allow a different
* colored panel on the left side to be displayed,
* similar to some other scrollers.
* Released as version 2.8.3.
* 12 Jul 2004 Fixed a bug that caused a NullPointerException when the
* data refreshing failed.
*/
/*
* Commented out for unbundled distribution.
*
* package kevin.applets.textscroll;
*/
import java.util.Vector;
import java.applet.*;
import java.awt.*;
import java.net.*;
import java.io.*;
/**
* This applet is displays a two-paned scrolling text window.
* The separate panes are right next to each other, but can
* have different color schemes, to allow for a headline on
* the left, with content on the right. It is very simple in
* design, but allows for a great deal of configuration. The
* user can specify multiple parameters with the
* <PARAM> tags, such as the following:
*
*
*
| * Name * | ** Description * | ** Example * | *
| leftfontface | *The style of Font to use in the left
* pane. It must be a type supported by Java. If
* an invalid font face is specified,
* SansSerif will be used.
* SansSerif is also the default font face.
* Permitted values are:
*
* |
*
*
* <PARAM NAME="leftfontface"
* VALUE="SansSerif">
*
* |
*
| rightfontface | *The style of Font to use in the right
* pane. It must be a type supported by Java. If
* an invalid font face is specified,
* SansSerif will be used.
* SansSerif is also the default font face.
* Permitted values are:
*
* |
*
*
* <PARAM NAME="rightfontface"
* VALUE="SansSerif">
*
* |
*
| fontface | *The style of Font to use in the right
* pane. This is the same as rightfontface, and was
* left in for backwards compatibility.
* |
*
*
* <PARAM NAME="fontface"
* VALUE="SansSerif">
*
* |
*
| leftfontsize | *The size of Font to use in the left
* pane. If an invalid size is specified, the default
* will be used. The default font size is 10.
* |
*
*
* <PARAM NAME="leftfontsize"
* VALUE="12">
*
* |
*
| rightfontsize | *The size of Font to use in the right
* pane. If an invalid size is specified, the default
* will be used. The default font size is 10.
* |
*
*
* <PARAM NAME="rightfontsize"
* VALUE="12">
*
* |
*
| fontsize | *The size of Font to use in the right
* pane. This is the same as rightfontsize, and was
* left in for backwards compatibility.
* |
*
*
* <PARAM NAME="fontsize"
* VALUE="12">
*
* |
*
| speed | *The speed of scrolling to use. Valid values are all numbers
* from TextScroll.MIN_SPEED (1) to
* TextScroll.MAX_SPEED (100), with
* TextScroll.MIN_SPEED being the slowest and
* TextScroll.MAX_SPEED being the fastest. The
* default is TextScroll.DEFAULT_SPEED (70).
* |
*
*
* <PARAM NAME="speed" VALUE="65">
*
* |
*
| data | *The name of the datafile to use. * In versions 2.4 and above, you can use a complete URL in this * parameter if you wish. If the value of this parameter starts * with "http", it tries to create a new URL from the * string. Otherwise, it treats it as a relative URL from the * location of the HTML document containing the applet. * | *
*
* <PARAM NAME="data" VALUE="scroll.txt">
*
* |
*
| leftforeground | *The foreground color for the left pane of the applet. * This will be the color of the text in the left pane. * The default is white. It must be a trio of integer * values which make up a legal RGB color value. Each * integer value must be between 0 and 255, inclusively. * The example sets the foreground color to a shade of red. * | *
*
* <PARAM NAME="leftforeground"
* VALUE="144, 32, 32">
*
* |
*
| rightforeground | *The foreground color for the right pane of the applet. * This will be the color of the text in the right pane. * The default is white. It must be a trio of integer * values which make up a legal RGB color value. Each * integer value must be between 0 and 255, inclusively. * The example sets the foreground color to a shade of red. * | *
*
* <PARAM NAME="rightforeground"
* VALUE="144, 32, 32">
*
* |
*
| foreground | *The foreground color for the right pane of the applet. * This will be the color of the text in the right pane. * This is the same as rightforeground, and was left in * for backwards compatibility. * |
*
* <PARAM NAME="foreground"
* VALUE="144, 32, 32">
*
* |
*
| leftbackground | *The background color for the left pane of the applet. * The default is black. It must be a trio of integer * values which make up a legal RGB color value. Each * integer value must be between 0 and 255, inclusively. * The example sets the background color to a light blue. * | *
*
* <PARAM NAME="leftbackground"
* VALUE="224, 224, 255">
*
* |
*
| rightbackground | *The background color for the right pane of the applet. * The default is black. It must be a trio of integer * values which make up a legal RGB color value. Each * integer value must be between 0 and 255, inclusively. * The example sets the background color to a light blue. * | *
*
* <PARAM NAME="rightbackground"
* VALUE="224, 224, 255">
*
* |
*
| background | *The background color for the right pane of the applet. * This is the same as rightbackground, and was left in * for backwards compatibility. * | *
*
* <PARAM NAME="background"
* VALUE="224, 224, 255">
*
* |
*
| refresh | *This indicates that the applet should re-request the data
* from the server after the text has been repeated
* n times, where n is the integer argument to
* this parameter. The example to the right will reload the
* text data after it has completely displayed 3 times. Note
* that this is simply when it starts to load the data
* again. The data will most likely not be available
* instantaneously, so it will display the current data again
* before replacing it with the new data. This means it might
* actually display 4 or even 5 times before you'll actually see
* the new data. The benefit of this is that your data will not
* be changed in the middle of a presentation, it will only be
* updated at the end.
* |
*
*
* <PARAM NAME="refresh" VALUE="3">
*
* |
*
| fgloadcolor | *This lets you specify what the applet should use for a * foreground color while it is loading data. The default * is blue. This is the color the "Loading data * ..." string will be displayed in. You generally won't * have to use this unless you are really concerned about it * fitting into your page during loading. The default is blue. * It must be a trio of integer values which make up a legal RGB * color value. Each integer value must be between 0 and 255, * inclusively. The example sets the foreground color to green. * | *
*
* <PARAM NAME="fgloadcolor" VALUE="32, 144, 32">
*
* |
*
| bgloadcolor | *This lets you specify what the applet should use for a background * color while it is loading data. The default is light blue. * It must be a trio of integer values which make up a legal RGB * color value. Each integer value must be between 0 and 255, * inclusively. The example sets the background color to a light * green. * | *
*
* <PARAM NAME="background" VALUE="224, 255, 224">
*
* |
*
| wraptext | *This lets you specify whether the applet should apply
* automatic line wrapping or not. An argument of
* true will apply line wrapping, an argument of
* false will wrap the lines as they appear in
* the data file. This feature was included for users who
* want tight control of where lines are wrapped.
* |
*
*
* <PARAM NAME="wraptext" VALUE="false">
*
* |
*
Note that most of the parameters can be specified in the text file
* itself, with the exception of the name of the text file, and the text
* wrapping. The text wrapping is performed when the data is loaded. Thus,
* the only mandatory <PARAM> tag is the data
* tag. Indeed, this is the only one I usually specify, since the data
* file changes most of the other values several times during the
* presentation.
*
*
If the user clicks on the scrolling text, the scrolling will stop. * If the user clicks again, it will start again, in the same place. * The exception is if a URL is set. If a URL is set, then when the user * clicks on it, that URL will be loaded. * *
More complete documentation can be found at this applet's homepage
* at
* http://kombat.org/Programming/TextScroll.
*
* @version 2.8.4 12 Jul 2004
* @author Kevin Swan, kombat@kombat.org
*/
public class TextScroll extends Applet implements Runnable {
/**
* The current version of this applet.
*/
public static final String VERSION = "2.8.4";
/**
* A constant representing the maximum number of milliseconds
* the applet may sleep. This is the maximum number a user may
* specify as the speed value, and would represent a sleep time
* of MIN_SPEED milliseconds.
*/
public static final int MAX_SPEED = 100;
/**
* A constant representing the minimum number of milliseconds
* the applet may sleep. This is the minimum number a user may
* specify as the speed value, and would represent a sleep time
* of MAX_SPEED milliseconds.
*/
public static final int MIN_SPEED = 1;
/**
* A constant representing the default number of milliseconds
* the applet should sleep. This value is used for the speed
* if the user specifies an invalid value, or none at all.
*/
public static final int DEFAULT_SPEED = 70;
/**
* This is the color to use for a background while the data is
* loading. Default is light blue.
*/
public static final int BG_LOAD_COLOR = (224 << 16) | (224 << 8) | 255;
/**
* This is the color to draw the information in while the data is
* loading. Default is dark blue.
*/
public static final int FG_LOAD_COLOR = (32 << 16) | (32 << 8) | 144;
/**
* This is the color to use for a background if an error occurs.
* Default is light red.
*/
public static final int BG_ERROR_COLOR = (255 << 16) | (224 << 8) | 224;
/**
* This is the color to draw the information in if an error occurs.
* Default is dark red.
*/
public static final int FG_ERROR_COLOR = (144 << 16) | (32 << 8) | 32;
/**
* A constant indicating the text data is ready.
*/
public static final int T_READY = 1;
/**
* A constant used to indicate the text is loading.
*/
public static final int T_LOADING = 2;
/**
* A constant used to indicate the data is being formatted.
*/
public static final int T_FORMATTING = 4;
/**
* A constant used to indicate an error occured in loading the text.
*/
public static final int T_NO_DATA_SPECIFIED = 8;
/**
* A constant used to indicate an error occured in loading the text.
*/
public static final int T_LOAD_ERROR = 16;
/** This is the String displayed when no URL is set. */
public static final String STATUS_MSG = "TextScroll -- Version " +
TextScroll.VERSION;
/** The default Font face to use ("SansSerif.") */
public static final String DEFAULT_FONT_FACE = "SansSerif";
/** The default Font size to use (12). */
public static final int DEFAULT_FONT_SIZE = 12;
/** The default width of the left panel (0). */
public static final int DEFAULT_LEFT_WIDTH = 0;
/** The Image to create and use for buffering. */
private Image buffImage;
/** The Graphics object from the buffer Image that we can draw on. */
private Graphics buffGraphics;
/** The height and width of the buffer canvas. */
private int buffHeight, buffWidth;
/** The Colors to use. */
private Color leftBackgroundColor,
leftForegroundColor,
rightBackgroundColor,
rightForegroundColor,
bgLoadColor,
fgLoadColor;
/** The initial font. This is used for refreshing the data. */
private Font initialFont;
/** The Font to use in the left pane. */
private Font leftFont;
/** The Font to use in the right pane. */
private Font rightFont;
/** The size of the Font to use in the left pane. */
private int leftFontSize;
/** The size of the Font to use in the right pane. */
private int rightFontSize;
/**
* The height in pixels of the font we're using. This is important
* when determining where to draw the next line of text.
*/
private int fontHeight;
/** The name of the file to load. */
private String fileName;
/** The URL of the data file to load. */
private URL dataFileURL;
/** The height and width of the applet/clipping window. */
private int width, height;
/** The width of the left panel. */
private int leftWidth = TextScroll.DEFAULT_LEFT_WIDTH;
/** Whether we should center the text in the left pane or not. */
private boolean leftCenter = false;
/** Whether we should center the text in the right pane or not. */
private boolean rightCenter = false;
/**
* The speed to scroll at. Can be from MIN_SPEED to MAX_SPEED.
* Default is DEFAULT_SPEED.
*/
private int speed;
/**
* This is the target URL the applet should load if the user
* clicks on the applet.
*/
private URL targetURL = null;
/**
* This flag indicates whether or not the apply should apply
* automatic line wrapping to the data. Default is to apply
* line wrapping.
*/
private boolean shouldWrapText = true;
/**
* This is the frame to display the contents of the target URL in
* when the applet is clicked on. If this is null, then the content
* will be displayed in the current frame.
*/
private String targetFrame = null;
/** The x coordinate to start drawing text at. */
private int inset = 3;
/** boolean to flag if the Applet is currently running. */
private boolean running;
/**
* boolean to flag whether or not we should display
* the message in the left panel this time. This is
* set to true when the setLeftText directive is
* invoked, and reset to false when the painting
* routine actually gets around to displaying the
* text.
*/
private boolean showLeftText = false;
/** The text to display in the left panel. */
private String leftText = "";
/**
* This is how many pixels to allow between lines of text.
*/
private int lineSpacing = 5;
/** The actual text to display, one line per entry. */
private String[] text;
/** The "window" we're displaying in, used for scrolling. */
private int frame = 16;
/** The current line to append when we have to add another line. */
private int currLine = 0;
/**
* Keeps a count of how many times we've displayed the data
* completely.
*/
private int iteration = 0;
/**
* This value specifies how many times to display the data before
* refreshing from the server. Values <= 0 indicate not to refresh
* at all.
*/
private int refreshValue = 1;
/** Thread to control the scrolling. */
private Thread scroller;
/**
* This is an undocumented element to allow greater control over
* the positioning of the animation. This is how many pixels to
* move the text when scrolling. The default is 1.
*/
private int offset = 1;
/**
* This variable remembers whether the mouse is inside the applet or
* not. This is important because if it *is*, and we had a URL set,
* then that URL is displayed in the status bar. If the mouse stays
* inside the applet, and the target URL changes, that should be
* reflected in the status bar. So, when setURL() is called, it must
* check this flag to see if it should update the status bar.
*/
private boolean mouseInside = false;
/**
* This flag monitors whether all the necessary data is here yet or not.
*/
private int status;
/**
* The Object responsible for retrieving the text data.
*/
private DataLoader loader = null;
/**
* This flag lets us know that we've tried to refresh the data.
*/
private boolean reloaded = true;
/**
* The Object responsible for managing directives.
*/
private DirectiveManager directiveManager = null;
/**
* Called during initialization. This is where we check all run-time
* flags set by the <PARAM> tags, and load the
* text. We will also prepare the text buffer.
*/
public void init () {
this.status = TextScroll.T_LOADING;
this.text = null;
this.directiveManager = new DirectiveManager (this);
/* Print version info. */
System.err.println ("TextScroll v" + TextScroll.VERSION +
"\nCopyright (C) 1998, 2004 Kevin Swan, kombat@kombat.org");
running = false;
String param = null;
/*
* Get the dimensions of the applet. The buffer image will be exactly
* as wide as the applet, but will be 200 pixels taller, supporting
* a maximum font size of 200.
*/
this.width = this.size ().width;
this.height = this.size ().height;
this.buffWidth = this.width;
this.buffHeight = this.height + 200;
/*
* Get the width of the left text area.
*/
param = getParameter ("leftwidth");
if (param == null)
this.leftWidth = TextScroll.DEFAULT_LEFT_WIDTH;
else
try {
this.leftWidth = Integer.parseInt (param);
} catch (NumberFormatException nfe) {
this.leftWidth = TextScroll.DEFAULT_LEFT_WIDTH;
}
/*
* Get the color parameters for the text areas.
*/
param = getParameter ("leftforeground");
if (param == null)
leftForegroundColor = Color.black;
else
leftForegroundColor = getColorFromString (param);
if (leftForegroundColor == null)
leftForegroundColor = Color.black;
param = getParameter ("leftbackground");
if (param == null)
leftBackgroundColor = Color.white;
else
leftBackgroundColor = getColorFromString (param);
if (leftBackgroundColor == null)
leftBackgroundColor = Color.white;
param = getParameter ("rightforeground");
if (param == null)
rightForegroundColor = Color.black;
else
rightForegroundColor = getColorFromString (param);
if (rightForegroundColor == null)
rightForegroundColor = Color.black;
param = getParameter ("rightbackground");
if (param == null)
rightBackgroundColor = Color.white;
else
rightBackgroundColor = getColorFromString (param);
if (rightBackgroundColor == null)
rightBackgroundColor = Color.white;
param = getParameter ("foreground");
if (param == null)
rightForegroundColor = Color.black;
else
rightForegroundColor = getColorFromString (param);
if (rightForegroundColor == null)
rightForegroundColor = Color.black;
param = getParameter ("background");
if (param == null)
rightBackgroundColor = Color.white;
else
rightBackgroundColor = getColorFromString (param);
if (rightBackgroundColor == null)
rightBackgroundColor = Color.white;
param = getParameter ("fgloadcolor");
if (param == null)
fgLoadColor = new Color (TextScroll.FG_LOAD_COLOR);
else
fgLoadColor = getColorFromString (param);
if (fgLoadColor == null)
fgLoadColor = new Color (TextScroll.FG_LOAD_COLOR);
param = getParameter ("bgloadcolor");
if (param == null)
bgLoadColor = new Color (TextScroll.BG_LOAD_COLOR);
else
bgLoadColor = getColorFromString (param);
if (bgLoadColor == null)
bgLoadColor = new Color (TextScroll.BG_LOAD_COLOR);
/*
* Get the desired Font information.
*/
param = getParameter ("leftfontsize");
if (param == null)
this.leftFontSize = TextScroll.DEFAULT_FONT_SIZE;
else
try {
this.leftFontSize = Integer.parseInt (param);
} catch (NumberFormatException nfe) {
this.leftFontSize = TextScroll.DEFAULT_FONT_SIZE;
}
param = getParameter ("rightfontsize");
if (param == null)
this.rightFontSize = TextScroll.DEFAULT_FONT_SIZE;
else
try {
this.rightFontSize = Integer.parseInt (param);
} catch (NumberFormatException nfe) {
this.rightFontSize = TextScroll.DEFAULT_FONT_SIZE;
}
param = getParameter ("fontsize");
if (param == null)
this.rightFontSize = TextScroll.DEFAULT_FONT_SIZE;
else
try {
this.rightFontSize = Integer.parseInt (param);
} catch (NumberFormatException nfe) {
this.rightFontSize = TextScroll.DEFAULT_FONT_SIZE;
}
String face = null;
param = getParameter ("leftfontface");
if (param == null)
face = TextScroll.DEFAULT_FONT_FACE;
else
face = param;
this.leftFont = new Font (face, Font.PLAIN, this.leftFontSize);
param = getParameter ("rightfontface");
if (param == null)
face = TextScroll.DEFAULT_FONT_FACE;
else
face = param;
this.rightFont = new Font (face, Font.PLAIN, this.rightFontSize);
this.initialFont = new Font (face, Font.PLAIN, this.rightFontSize);
FontMetrics fm = this.getToolkit ().getFontMetrics (this.rightFont);
this.fontHeight =
fm.getMaxAscent () + fm.getMaxDescent () + fm.getLeading ();
frame = this.lineSpacing + this.fontHeight;
param = getParameter ("fontface");
if (param == null)
face = TextScroll.DEFAULT_FONT_FACE;
else
face = param;
this.rightFont = new Font (face, Font.PLAIN, this.rightFontSize);
this.initialFont = new Font (face, Font.PLAIN, this.rightFontSize);
fm = this.getToolkit ().getFontMetrics (this.rightFont);
this.fontHeight =
fm.getMaxAscent () + fm.getMaxDescent () + fm.getLeading ();
frame = this.lineSpacing + this.fontHeight;
/*
* Set the name of the file to load.
*/
param = getParameter ("data");
this.dataFileURL = null;
if (param == null)
this.status = TextScroll.T_NO_DATA_SPECIFIED;
else {
try {
if (!param.startsWith ("http://"))
this.dataFileURL = new URL (getDocumentBase (), param);
else
this.dataFileURL = new URL (param);
} catch (MalformedURLException mue) {
this.status = TextScroll.T_LOAD_ERROR;
}
}
/*
* Check if the user wants line wrapping or not.
*/
param = getParameter ("wraptext");
if (param != null)
this.shouldWrapText = (new Boolean (param)).booleanValue ();
/* Look for a different offset. */
param = getParameter ("offset");
if (param == null)
this.offset = 1;
else
try {
this.offset = Integer.parseInt (param);
} catch (NumberFormatException nfe) {
this.offset = 1;
}
/* Set the speed information. */
param = getParameter ("speed");
if (param == null)
this.speed = TextScroll.DEFAULT_SPEED;
else
try {
this.speed = Integer.parseInt (param);
} catch (NumberFormatException nfe) {
this.speed = TextScroll.DEFAULT_SPEED;
}
if (this.speed > TextScroll.MAX_SPEED ||
this.speed < TextScroll.MIN_SPEED)
this.speed = TextScroll.DEFAULT_SPEED;
/* Set the refresh information. */
param = getParameter ("refresh");
if (param == null)
this.refreshValue = -1;
else
try {
this.refreshValue = Integer.parseInt (param);
} catch (NumberFormatException nfe) {
this.refreshValue = -1;
}
this.resize (this.width, this.height);
/*
* buffGraphics is what we will use to draw on our buffImage, the
* offscreen canvas we will use to write the text to before clipping
* it and copying it to the active Graphics object in paint ().
* We will support a maximum font size of 200.
*/
this.buffImage = this.createImage (this.buffWidth, this.buffHeight);
this.buffGraphics = this.buffImage.getGraphics ();
/* Prepare the offscreen buffer. */
this.buffGraphics.setColor (this.leftBackgroundColor);
this.buffGraphics.fillRect (0, 0, this.leftWidth, this.buffHeight);
this.buffGraphics.setColor (this.rightBackgroundColor);
this.buffGraphics.fillRect (
this.leftWidth, 0, this.buffWidth, this.buffHeight);
// this.buffGraphics.setColor (this.rightForegroundColor);
// this.buffGraphics.setFont (this.rightFont);
loadData (this.dataFileURL);
} /* init () */
/**
* buffGraphics is what we will use to draw on our buffImage, the
* offscreen canvas we will use to write the text to before clipping
* it and copying it to the active Graphics object in paint ().
* We will support a maximum font size of 200.
*
* @return The Graphics object we will draw
* on for a buffer.
*/
private Graphics getBuffGraphics () {
if (this.buffGraphics == null) {
this.buffImage = this.createImage (this.buffWidth, this.buffHeight);
this.buffGraphics = this.buffImage.getGraphics ();
}
return this.buffGraphics;
}
/**
* This method attempts to convert a String numeric
* representation of a color into an actual Color object.
* It expects the given String to be in the format
* "red,green,blue"
*
* @param rgb A comma-separated RGB numeric representation of a
* color, passed as a String.
*
* @return A Color object represented by the given RGB value,
* if the values are legal. If an error occurs, return
* null.
*/
public static Color getColorFromString (String rgb) {
int red, green, blue;
red = green = blue = 0;
if (rgb == null)
return null;
try{
red = Integer.parseInt ((rgb.substring (0, rgb.indexOf (","))).trim ());
green = Integer.parseInt ((rgb.substring(rgb.indexOf (",") + 1, rgb.lastIndexOf (","))).trim ());
blue = Integer.parseInt ((rgb.substring(rgb.lastIndexOf (",") + 1)).trim ());
} catch (NumberFormatException nfe) {
return null;
}
try {
return new Color(red, green, blue);
} catch (IllegalArgumentException iae) {
return null;
}
} /* getColorFromString () */
/**
* The implementation of the run () method, as required by
* implementing the Runnable interface. This method performs
* the actual animation.
*/
public void run () {
while (!this.isReady ()) {
if (this.getStatus () > TextScroll.T_LOADING) {
repaint ();
return;
}
try {
scroller.sleep (200);
} catch (InterruptedException ie) {
return;
}
}
while (running) {
/* Move the area upwards offset pixels. */
this.getBuffGraphics ().copyArea (
0,
offset,
this.buffWidth,
this.height + this.fontHeight + this.lineSpacing,
0, 0 - offset);
frame -= offset;
/* The frame tells us when its time to draw another line of text. */
if (frame < 0) {
/* Get the next line in the source file. */
String line = this.text [this.currLine];
this.currLine++;
/*
* If we've hit the end of the presentation, reset the line
* variable, increment the iteration variable, and test if
* we should refresh our data.
*/
if (this.currLine == this.text.length) {
this.currLine = 0;
this.iteration++;
/* See if we should refresh our data. */
if ((this.refreshValue > 0) &&
(this.iteration >= this.refreshValue)) {
/*
* First, we should check to see if we've already tried to refresh
* the data. If we have, and its ready now, replace the data.
*/
if (this.reloaded) {
if (this.isReady ()) {
String[] tmpArr = this.loader.getData ();
if (this.loader.errorOccurred ()) {
this.loader = null;
System.err.println (
" Error reading data file, creating new dataloader ***");
this.loadData (this.dataFileURL);
} else {
this.text = new String [tmpArr.length];
System.arraycopy (tmpArr, 0, this.text, 0, tmpArr.length);
this.iteration = 0;
this.reloaded = false;
}
}
} else
/* If we haven't started refreshing it yet, do it now. */
this.refreshData ();
}
}
/*
* If the line is a method directive, try to service it.
*/
if (line.startsWith ("^^"))
if (!this.directiveManager.performDirective (line))
System.err.println ("Illegal directive call:\n\t" + line);
else
continue;
/* Treat the line as normal. */
/**
* If we have a left message set, and we haven't
* displayed it yet, now is the time to display it.
*/
FontMetrics fm = this.getToolkit ().getFontMetrics (this.leftFont);
if (this.showLeftText) {
this.getBuffGraphics ().setColor (this.leftForegroundColor);
this.getBuffGraphics ().setFont (this.leftFont);
if (!this.leftCenter) {
this.getBuffGraphics ().drawString (
leftText,
0,
this.height + this.lineSpacing + fm.getMaxAscent ());
} else {
/*
* We must center the text. We will do this in 3 steps:
* 1. Find the length of the text.
* 2. Calculate what x value to start drawing the text at.
* 3. Draw the text.
*/
int length = fm.stringWidth (leftText);
int start = (this.leftWidth / 2) - (length / 2);
start = (start < 0) ? 0 : start;
this.getBuffGraphics ().drawString (
leftText,
start,
this.height + this.lineSpacing + fm.getMaxAscent ());
}
this.getBuffGraphics ().setColor (this.rightForegroundColor);
this.showLeftText = false;
}
this.getBuffGraphics ().setColor (this.rightForegroundColor);
this.getBuffGraphics ().setFont (this.rightFont);
fm = this.getToolkit ().getFontMetrics (this.rightFont);
frame = this.lineSpacing + this.fontHeight;
if (!this.rightCenter) {
this.getBuffGraphics ().drawString (
line,
this.leftWidth + this.inset,
this.height + this.lineSpacing + fm.getMaxAscent ());
} else {
/*
* We must center the text. We will do this in 3 steps:
* 1. Find the length of the text.
* 2. Calculate what x value to start drawing the text at.
* 3. Draw the text.
*/
int length = fm.stringWidth (line);
int start = ((this.width - this.leftWidth) / 2) - (length / 2);
start = (start < this.leftWidth) ? this.leftWidth : start;
this.getBuffGraphics ().drawString (
line,
start + this.leftWidth,
this.height + this.lineSpacing + fm.getMaxAscent ());
}
}
try {
scroller.sleep (TextScroll.MAX_SPEED + 1 - this.speed);
} catch (InterruptedException ie) {
return;
}
this.repaint ();
}
return;
} /* run () */
/**
* This method reloads the text data file from the
* server. Note that by the time this method is
* called, it will probably take some time to
* completely load, and we can't really replace the
* whole data array in the middle of a display. We'll
* simply refresh the DataLoader. The
* next time we get to the end of the presentation,
* we'll check if the data is ready. But, we do have
* to note somehow that we tried to refresh it. We'll
* set a flag.
*/
private void refreshData () {
this.loader.refresh ();
this.reloaded = true;
}
/**
* This method loads data from a URL into
* a DataLoader. The applet should
* periodically check its DataLoader to see
* if the data is ready. It is given the URL of the text
* file to read.
*
* @param url The URL of the text data file to load.
*/
private void loadData (URL url) {
/* If it is null, just ignore it. */
if (url == null)
return;
else
this.loader = new DataLoader (
url,
this.initialFont,
this.width - this.leftWidth,
this.shouldWrapText);
return;
}
/**
* Called to paint the screen.
*/
public void paint (Graphics g) {
if (this.status > TextScroll.T_READY)
this.displayStatus (g);
else
g.drawImage (this.buffImage, 0, 0, this);
}
/**
* Called to update the screen.
*/
public void update (Graphics g) {
if (this.status > TextScroll.T_READY)
this.displayStatus (g);
else
g.drawImage (this.buffImage, 0, 0, this);
}
/**
* Called to print the appropriate status information if the applet
* is not able to begin scrolling yet.
*
* @param g The Graphics object to draw on.
*/
private void displayStatus (Graphics g) {
if (this.status == TextScroll.T_READY)
return;
g.setFont (new Font ("SansSerif", Font.PLAIN, 12));
switch (this.getStatus ()) {
case (TextScroll.T_LOADING):
g.setColor (this.bgLoadColor);
g.fillRect (0, 0, this.width, this.height);
g.setColor (this.fgLoadColor);
g.drawString ("Loading data ...", 5, 15);
return;
case (TextScroll.T_FORMATTING):
g.setColor (this.bgLoadColor);
g.fillRect (0, 0, this.width, this.height);
g.setColor (this.fgLoadColor);
g.drawString ("Formatting data ...", 5, 15);
return;
case (TextScroll.T_NO_DATA_SPECIFIED):
g.setColor (new Color (TextScroll.BG_ERROR_COLOR));
g.fillRect (0, 0, this.width, this.height);
g.setColor (new Color (TextScroll.FG_ERROR_COLOR));
g.drawString ("No \"data\" parameter specified.", 5, 15);
return;
case (TextScroll.T_LOAD_ERROR):
g.setColor (new Color (TextScroll.BG_ERROR_COLOR));
g.fillRect (0, 0, this.width, this.height);
g.setColor (new Color (TextScroll.FG_ERROR_COLOR));
g.drawString ("Couldn't read specified text file.", 5, 15);
return;
}
} /* displayStatus () */
/**
* Called to start this applet. If the applet has been running
* before, we will pick up where we left off.
*/
public void start () {
running = true;
(scroller = new Thread (this)).start ();
if (this.loader != null)
this.loader.start ();
else
System.err.println ("ERROR: DataLoader reference was lost.");
}
/**
* Stop the applet.
*/
public void stop () {
running = false;
if (this.scroller != null)
this.scroller.stop ();
if (this.loader != null)
this.loader.stop ();
}
/**
* If the Applet is running, stop it. If it is stopped, restart it.
*/
private void toggle () {
if (this.running)
this.stop ();
else
this.start ();
}
/**
* Method called when the mouse pointer enters the applet.
*
* @param e The actual event
* @param x The x coordinate the event occurred at.
* @param y The y coordinate the event occurred at.
*
* @return true if the event is handled, false otherwise.
*/
public boolean mouseEnter (Event e, int x, int y) {
this.mouseInside = true;
if (this.getURL () == null)
this.showStatus (TextScroll.STATUS_MSG);
else
this.showStatus (this.getURL ().toString ());
return true;
}
/**
* Method called when the mouse pointer leaves the applet.
*
* @param e The actual event
* @param x The x coordinate the event occurred at.
* @param y The y coordinate the event occurred at.
*
* @return true if the event is handled, false otherwise.
*/
public boolean mouseExit (Event e, int x, int y) {
this.mouseInside = false;
this.showStatus ("");
return true;
}
/**
* Method called when the user clicks.
*
* @param e The actual event.
* @param x The x coordinate the even occurred at.
* @param y The y coordinate the even occurred at.
*
* @return true if the event is handled, false otherwise.
*/
public boolean mouseDown (Event me, int x, int y) {
if (this.getURL () == null)
this.toggle ();
else
try {
if (this.getAppletContext () != null) {
if (this.targetFrame == null)
this.getAppletContext ().showDocument (this.getURL ());
else
this.getAppletContext ().showDocument (this.getURL (),
this.targetFrame);
}
} catch (Exception e) {
this.toggle ();
}
return true;
}
/**
* This method is used to determine whether the data is ready or not.
*
* @return An int value which is one of the constants:
*
T_READY - If the text is ready.
* T_LOADING - If the text is loading.
* T_NO_DATA_SPECIFIED - If the text could
* not be loaded because no "data" value was
* specified in a <PARAM> tag.
* T_LOAD_ERROR - If an error occurred
* during loading of the text data, probably a file
* not found or a permissions problem.
* true if all the necessary data has been loaded,
* false otherwise.
*/
public boolean isReady () {
if (this.text == null) {
if (this.loader.dataReady ()) {
String[] tmpArr = this.loader.getData ();
this.text = new String [tmpArr.length];
System.arraycopy (tmpArr, 0, this.text, 0, tmpArr.length);
this.status = TextScroll.T_READY;
} else {
if (this.loader.errorOccurred ())
this.status = TextScroll.T_LOAD_ERROR;
else
this.status = TextScroll.T_LOADING;
}
}
return ((this.status & TextScroll.T_READY) == TextScroll.T_READY);
}
/**
* This method is used to specify whether the text in the
* left pane should be centered or not. The String argument
* must either be "true" or "false" The
* comparison is case-insensitive.
*
* @param boolStr A String. Must be "true" to specify
* that all further text in the left pane should
* be centered, or "false" to specify
* normal formatting (left align). Any other
* values are ignored, and a quiet message is
* printed to stderr.
*/
public void setLeftCenter (String boolStr) {
if (boolStr.equalsIgnoreCase ("true"))
this.leftCenter = true;
else if (boolStr.equalsIgnoreCase ("false"))
this.leftCenter = false;
else
System.err.println (
"setLeftCenter directive ignored - invalid argument: " +
boolStr);
}
/**
* This method is used to specify whether the text in the
* right pane should be centered or not. The String argument
* must either be "true" or "false" The
* comparison is case-insensitive.
*
* @param boolStr A String. Must be "true" to specify
* that all further text in the right pane should
* be centered, or "false" to specify
* normal formatting (left align). Any other
* values are ignored, and a quiet message is
* printed to stderr.
*/
public void setRightCenter (String boolStr) {
if (boolStr.equalsIgnoreCase ("true"))
this.rightCenter = true;
else if (boolStr.equalsIgnoreCase ("false"))
this.rightCenter = false;
else
System.err.println (
"setRightCenter directive ignored - invalid argument: " +
boolStr);
}
/**
* This method is used to specify whether the text in the
* right pane should be centered or not. The String argument
* must either be "true" or "false" The
* comparison is case-insensitive. This method is left in
* for compatibility reasons.
*
* @param boolStr A String. Must be "true" to specify
* that all further text in the right pane should
* be centered, or "false" to specify
* normal formatting (left align). Any other
* values are ignored, and a quiet message is
* printed to stderr.
*/
public void setCenter (String boolStr) {
if (boolStr.equalsIgnoreCase ("true"))
this.rightCenter = true;
else if (boolStr.equalsIgnoreCase ("false"))
this.rightCenter = false;
else
System.err.println (
"setCenter directive ignored - invalid argument: " +
boolStr);
}
/**
* This method is used to turn bold font styling for the
* left pane on or off. It expects a single String argument
* which must be either "true" or "false".
* The comparison is case-insensitive.
*
* @param boolStr A String. Must be "true" to specify
* that all further text displayed in the left
* pane should be bold, or "false" to
* specify non-bold styling. Any other values are
* ignored, and a quiet message is printed to stderr.
*/
public void setLeftBold (String boolStr) {
int style = this.leftFont.getStyle ();
if (boolStr.equalsIgnoreCase ("true"))
style = style | Font.BOLD;
else if (boolStr.equalsIgnoreCase ("false"))
style = style & ~Font.BOLD;
else {
System.err.println ("setLeftBold directive ignored - invalid argument: " +
boolStr);
return;
}
this.leftFont =
new Font (this.leftFont.getName (), style, this.leftFontSize);
}
/**
* This method is used to turn bold font styling for the
* right pane on or off. It expects a single String argument
* which must be either "true" or "false".
* The comparison is case-insensitive.
*
* @param boolStr A String. Must be "true" to specify
* that all further text displayed in the right
* pane should be bold, or "false" to
* specify non-bold styling. Any other values are
* ignored, and a quiet message is printed to stderr.
*/
public void setRightBold (String boolStr) {
int style = this.rightFont.getStyle ();
if (boolStr.equalsIgnoreCase ("true"))
style = style | Font.BOLD;
else if (boolStr.equalsIgnoreCase ("false"))
style = style & ~Font.BOLD;
else {
System.err.println (
"Error: Invalid int arg for setBold or setRightBold: " +
boolStr);
return;
}
this.rightFont =
new Font (this.rightFont.getName (), style, this.rightFontSize);
FontMetrics fm = this.getToolkit ().getFontMetrics (this.rightFont);
this.fontHeight =
fm.getMaxAscent () + fm.getMaxDescent () + fm.getLeading ();
this.getBuffGraphics ().setFont (this.rightFont);
}
/**
* This method is used to turn bold font styling for the
* right pane on or off. It expects a single String argument
* which must be either "true" or "false".
* The comparison is case-insensitive. This method is left
* in for compatibility purposes.
*
* @param boolStr A String. Must be "true" to specify
* that all further text displayed in the right
* pane should be bold, or "false" to
* specify non-bold styling. Any other values are
* ignored, and a quiet message is printed to stderr.
*/
public void setBold (String boolStr) {
this.setRightBold (boolStr);
}
/**
* This method is used to turn italic font styling for the
* left pane on or off. It expects a single String argument
* which must be either "true" or "false".
* The comparison is case-insensitive.
*
* @param boolStr A String. Must be "true" to specify
* that all further text displayed in the left
* pane should be italic, or "false" to
* specify non-italic styling. Any other values
* are ignored, and a quiet message is printed to
* stderr.
*/
public void setLeftItalic (String boolStr) {
int style = this.leftFont.getStyle ();
if (boolStr.equalsIgnoreCase ("true"))
style = style | Font.ITALIC;
else if (boolStr.equalsIgnoreCase ("false"))
style = style & ~Font.ITALIC;
else {
System.err.println (
"Error: Invalid int arg for setLeftItalic: " +
boolStr);
return;
}
this.leftFont =
new Font (this.leftFont.getName (), style, this.leftFontSize);
}
/**
* This method is used to turn italic font styling for the
* right pane on or off. It expects a single String argument
* which must be either "true" or "false".
* The comparison is case-insensitive.
*
* @param boolStr A String. Must be "true" to specify
* that all further text displayed in the right
* pane should be italic, or "false" to
* specify non-italic styling. Any other values
* are ignored, and a quiet message is printed to
* stderr.
*/
public void setRightItalic (String boolStr) {
int style = this.rightFont.getStyle ();
if (boolStr.equalsIgnoreCase ("true"))
style = style | Font.ITALIC;
else if (boolStr.equalsIgnoreCase ("false"))
style = style & ~Font.ITALIC;
else {
System.err.println (
"Error: Invalid int arg for setItalic or setRightItalic: " +
boolStr);
return;
}
this.rightFont =
new Font (this.rightFont.getName (), style, this.rightFontSize);
FontMetrics fm = this.getToolkit ().getFontMetrics (this.rightFont);
this.fontHeight =
fm.getMaxAscent () + fm.getMaxDescent () + fm.getLeading ();
this.getBuffGraphics ().setFont (this.rightFont);
}
/**
* This method is used to turn italic font styling for the
* right pane on or off. It expects a single String argument
* which must be either "true" or "false".
* The comparison is case-insensitive. This method is left
* in for compatibility purposes.
*
* @param boolStr A String. Must be "true" to specify
* that all further text displayed in the right
* pane should be italic, or "false" to
* specify non-italic styling. Any other values
* are ignored, and a quiet message is printed to
* stderr.
*/
public void setItalic (String boolStr) {
this.setRightItalic (boolStr);
}
/**
* This method is used to set the inset value. The inset is the
* x coordinate where the text will be drawn at. The default is 3.
* The argument must be a String object which can be parsed to an
* int.
*
* @param insetStr A String which can be parsed to an int.
*/
public void setInset (String insetStr) {
int val;
try {
val = Integer.parseInt (insetStr);
} catch (NumberFormatException nfe) {
System.err.println ("setInset directive ignored - invalid argument: " +
insetStr + " (Expected a number)");
return;
}
this.inset = val;
}
/**
* This method sets the currently active URL to the given URL,
* such that if the user clicks anywhere in the applet area
* after this method has been invoked, it will load the named
* URL, unless URLString is "null"
* (case insensitive), in which case clicking will simply
* result in toggling scrolling.
*
* Note that in versions 2.7 and greater, the user can specify * a target frame for the URL to be displayed in as well. The * frame name must be specified, followed by a comma, followed * by the target URL. * *
This method was modified in version 2.8.2 to be more
* intelligent in determining if the user really wants a frame
* or not. Some URLs contain commas. This method now only
* treats it as a frame if there is a comma before the first
* "http://" string.
*
* @param URLString The URL to load. If the string is only a URL,
* then the page will be loaded in the current
* frame. If it consists of a string, followed
* by a comma, followed by another string, the
* first string will be treated as the target
* frame name, and the second will be treated
* as the target URL. If URLString
* is "null." (case insensitive),
* then the target URL and the target frame are
* both set to null.
*/
public void setURL (String URLString) {
/*
* They might want a target frame, see if they've specified one.
*/
if (URLString == null) {
this.setURL ((URL) null);
this.setTargetFrame (null);
}
/*
* If the URL string contains a comma, and that comma appears
* before the http://, then we have a target frame. Otherwise,
* just treat the whole string as a single URL.
*/
if (URLString.indexOf (',') >= 0)
if (URLString.indexOf (',') < URLString.indexOf ("http://")) {
String targetFrame = URLString.substring (0, URLString.indexOf (','));
String targetURL = URLString.substring (URLString.indexOf (',') + 1,
URLString.length ());
this.setURL (targetURL);
this.setTargetFrame (targetFrame);
return;
}
this.setTargetFrame (null);
if (URLString.equalsIgnoreCase ("null")) {
this.setURL ((URL) null);
this.setTargetFrame (null);
} else
try {
this.setURL (new URL (URLString));
} catch (MalformedURLException mue) {
System.err.println ("setURL directive ignored - invalid argument: " +
URLString + "\n(Unsetting clickable link)");
this.setURL ((URL) null);
}
}
/**
* This method sets the name of the target frame to display the
* target URL in. If targetFrame is null, then the
* target URLs will be displayed in the current browser frame.
*
* @param targetFrame A String name of the target
* frame to display the contents of the target
* URL in when the applet is clicked on.
*/
public void setTargetFrame (String targetFrame) {
if (targetFrame != null) {
targetFrame = targetFrame.trim ();
if (targetFrame.equalsIgnoreCase ("null"))
targetFrame = null;
}
this.targetFrame = targetFrame;
}
/**
* An accessor method to get the current value of the target frame.
*
* @return The current target frame.
*/
public String getTargetFrame () {
return this.targetFrame;
}
/**
* This method is used to set the target URL to an actual
* URL object. It is used by the mouse event
* handler.
*
* @param url The URL to load in the page if
* the user clicks on the applet.
*/
public void setURL (URL url) {
this.targetURL = url;
if (this.mouseInside)
if (this.targetURL == null)
this.showStatus (TextScroll.STATUS_MSG);
else
this.showStatus (this.targetURL.toString ());
}
/**
* Display the given string in the left panel.
*
* @param msg The string to display in the left
* panel.
*/
public void setLeftText (String msg) {
this.leftText = msg;
this.showLeftText = true;
}
/**
* Answer the currently set target URL.
*
* @return The current URL target.
*/
public URL getURL () {
return this.targetURL;
}
/**
* Answer a little blurb about this applet.
*
* @return info about this applet.
*/
public String getAppletInfo () {
return
"TextScroll Version " + VERSION +
" Copyright (C) 1998, 2004 by Kevin Swan, kombat@kombat.org";
}
/**
* Answer information about legal parameters.
*
* @return info about the parameters.
*/
public String[][] getParameterInfo () {
String[][] pinfo = {
{ "fontface", "Serif, SansSerif, Monospaced", "The font to use" },
{ "fontsize", "integer", "The size of font to use" },
{ "speed", TextScroll.MIN_SPEED + " - " + TextScroll.MAX_SPEED, "Scroll speed" },
{ "data", "String", "Name of text file to display" },
{ "foreground", "rrr,ggg,bbb", "RGB value to use for foreground color" },
{ "background", "rrr,ggg,bbb", "RGB value to use for background color" }
};
return pinfo;
}
/**
* Sets the left foreground color to the given RGB String.
*
* @param rgb a String representing a comma-seperated RGB value.
*/
public void setLeftForegroundColor (String rgb) {
Color color = getColorFromString (rgb);
if (color != null)
this.leftForegroundColor = color;
this.getBuffGraphics ().setColor (this.leftForegroundColor);
}
/**
* Sets the left background color to the given RGB String.
*
* @param rgb a String representing a comma-seperated RGB value.
*/
public void setLeftBackgroundColor (String rgb) {
Color color = getColorFromString (rgb);
if (color != null)
leftBackgroundColor = color;
this.getBuffGraphics ().setColor (this.leftBackgroundColor);
this.getBuffGraphics ().fillRect (0, 0, this.leftWidth, this.buffHeight);
this.getBuffGraphics ().setColor (this.rightForegroundColor);
}
/**
* Sets the right foreground color to the given RGB String.
*
* @param rgb a String representing a comma-seperated RGB value.
*/
public void setRightForegroundColor (String rgb) {
Color color = getColorFromString (rgb);
if (color != null)
this.rightForegroundColor = color;
this.getBuffGraphics ().setColor (this.rightForegroundColor);
}
/**
* Sets the right foreground color to the given RGB String.
* This method is left in for backwards compatibility.
*
* @param rgb a String representing a comma-seperated RGB value.
*/
public void setForegroundColor (String rgb) {
this.setRightForegroundColor (rgb);
}
/**
* Sets the right background color to the given RGB String.
*
* @param rgb a String representing a comma-seperated RGB value.
*/
public void setRightBackgroundColor (String rgb) {
Color color = getColorFromString (rgb);
if (color != null)
rightBackgroundColor = color;
this.getBuffGraphics ().setColor (this.rightBackgroundColor);
this.getBuffGraphics ().fillRect (this.leftWidth,
0,
this.buffWidth,
this.buffHeight);
this.getBuffGraphics ().setColor (this.rightForegroundColor);
}
/**
* Sets the right background color to the given RGB String.
* This method is left in for backwards compatibility.
*
* @param rgb a String representing a comma-seperated RGB value.
*/
public void setBackgroundColor (String rgb) {
this.setRightBackgroundColor (rgb);
}
/**
* Try and pause for the given number of milliseconds. Note
* that the time is given as a String.
*
* @param time a String that should be able to be converted to an
* Integer.
*/
public void pause (String timeStr) {
Integer time;
try {
time = Integer.valueOf (timeStr);
} catch (NumberFormatException nfe) {
System.err.println (
"Error: Invalid integer specified for pause (): \"" +
timeStr +
"\"");
return;
}
try {
this.scroller.sleep (time.intValue ());
} catch (InterruptedException ie) {
}
return;
}
/**
* This is simply a way for the user to call toggle ()
* as a directive. This was done to relieve confusion, so the user
* can simply use pause () with or without an argument
* to cause the applet to pause scrolling. If it is called with
* no arguments, this method is called, and the scrolling stops
* until the user clicks the text area.
*
*/
public void pause () {
this.toggle ();
}
/**
* Sets the speed of the applet to the given value. Note that the
* speed value should be an integer in the form of a String, between
* MIN_SPEED and MAX_SPEED. If an invalid value is specified,
* the speed value is left at its current setting.
*
* @param speedStr a String representing the integer speed to use for
* this applet.
*/
public void setSpeed (String speedStr) {
Integer speed;
try {
speed = Integer.valueOf (speedStr);
} catch (NumberFormatException nfe) {
System.err.println (
"Error: Invalid integer specified for setSpeed (): \"" +
speedStr +
"\"");
return;
}
if ((speed.intValue () <= TextScroll.MAX_SPEED) &&
(speed.intValue () >= TextScroll.MIN_SPEED))
this.speed = speed.intValue ();
return;
}
/**
* This method allows the user to change fonts in the middle of
* the scrolling. It sets the font to use for the left pane.
*
* @param face The String name of the new
* Font to use in the left pane.
*/
public void setLeftFontFace (String face) {
this.leftFont =
new Font (face, this.leftFont.getStyle (), this.leftFontSize);
}
/**
* This method allows the user to change fonts in the middle of
* the scrolling. It sets the font to use for the right pane.
*
* @param face The String name of the new
* Font to use in the right pane.
*/
public void setRightFontFace (String face) {
this.rightFont =
new Font (face, this.rightFont.getStyle (), this.rightFontSize);
FontMetrics fm = this.getToolkit ().getFontMetrics (this.rightFont);
this.fontHeight =
fm.getMaxAscent () + fm.getMaxDescent () + fm.getLeading ();
this.getBuffGraphics ().setFont (this.rightFont);
}
/**
* This method allows the user to change fonts in the middle of
* the scrolling. It sets the font to use for the right pane.
* This method is left in for backwards compatibility.
*
* @param face The String name of the new
* Font to use in the right pane.
*/
public void setFontFace (String face) {
this.setRightFontFace (face);
}
/**
* This method allows the user to change font size
* in the middle of the scrolling. It sets the
* size of the font to use in the left pane.
*
* @param sizeStr The String representing
* an integer size of the Font to use
* in the left pane.
*/
public void setLeftFontSize (String sizeStr) {
int size;
try {
size = Integer.parseInt (sizeStr);
} catch (NumberFormatException nfe) {
System.err.println (
"Error: Invalid integer specified for setLeftFontSize (): \"" +
sizeStr +
"\"");
return;
}
this.leftFontSize = size;
this.leftFont =
new Font (this.leftFont.getName(),
this.leftFont.getStyle (),
this.leftFontSize);
}
/**
* This method allows the user to change font size
* in the middle of the scrolling. It sets the
* size of the font to use in the right pane.
*
* @param sizeStr The String representing
* an integer size of the Font to use
* in the right pane.
*/
public void setRightFontSize (String sizeStr) {
int size;
try {
size = Integer.parseInt (sizeStr);
} catch (NumberFormatException nfe) {
System.err.println (
"Error: Invalid arg for setFontSize or setRightFontSize (): \"" +
sizeStr +
"\"");
return;
}
this.rightFontSize = size;
this.rightFont =
new Font (this.rightFont.getName(),
this.rightFont.getStyle (),
this.rightFontSize);
FontMetrics fm = this.getToolkit ().getFontMetrics (this.rightFont);
this.fontHeight =
fm.getMaxAscent () + fm.getMaxDescent () + fm.getLeading ();
this.getBuffGraphics ().setFont (this.rightFont);
}
/**
* This method allows the user to change font size
* in the middle of the scrolling. It sets the
* size of the font to use in the right pane.
* It is left in for backwards compatibility.
*
* @param sizeStr The String representing
* an integer size of the Font to use
* in the right pane.
*/
public void setFontSize (String sizeStr) {
this.setRightFontSize (sizeStr);
}
}