package COM.xinit.demon.co.uk.3tier.tickertape;
import java.awt.*;
import java.applet.*;
import java.io.*;
import java.net.*;
// TickerTape class
// This class borrows heavily from Ticker class applet in
// "Java by example", Jackson & McClellan, SunSoft Press, 1996.
//
public class TickerTape extends Canvas implements Runnable {
char currChar;
int strIndex = 0;
String tape;
// Keep arrays of the current symbols and their current price
String symbols[];
float currPrices[];
// Constants.
private static final int TEXTMARGIN = 3;
private static final int RECTMARGIN = 1;
private static final int SCROLLPAUSE = 15;
private static final int TICKERHOSTPORT = 5432;
private Thread scrollThread; // Thread that scrolls the text.
private Image offscreenImage = null; // The offscreen image we write
// text into before displaying it.
private Font textFont; // The displayed font.
private int tapeIndex; // The current index into the text.
private int totalTapeSteps; // The number of steps required to
// to traverse a complete scroll.
private int textWidth; // The width of the text in pixels.
private int textHeight; // The height of the text in pixels.
private int textDescent; // How far the text goes below the
// font's baseline in pixels.
private int previousWidth = -1; // How wide the Ticker was the last
// time we drew it.
FontMetrics metrics;
// The ticker object, which manages the connection to the ticker
// port and the display of the information
TickerReader tickerHost;
// Constructor
public TickerTape (String hostname, int width) {
// Create an instance of TickerReader with the hostname and
// port number we expect the host to be on
tickerHost = new TickerReader (hostname, TICKERHOSTPORT);
// Read from the Ticker host regardless of whether or not
// there actually is a connection
tape = getNextString();
// Use a 12 point Helvetica font
textFont = new Font("Helvetica", Font.PLAIN, 12);
// We use the font height and font descent to draw the text
// centered in the scrolling area. The width is used to
// determine how far to scroll before starting over.
//FontMetrics metrics = getFontMetrics(textFont);
metrics = getFontMetrics(textFont);
textHeight = metrics.getHeight();
textDescent = metrics.getDescent();
// Get the next char and its width
//currChar = getNextChar();
textWidth = metrics.stringWidth(tape);
// Create the canvas size
resize (width, 50);
// Create a thread and start it
scrollThread = new Thread(this);
scrollThread.start();
} // end TickerTape constructor
// Read the next available string from the host
public String getNextString () {
String tickerStr;
// Attempt to read the current ticker port
tickerStr = tickerHost.readData();
// If the string returned was null, use some kind of default
if (tickerStr == null) {
tickerStr = "Data connection to ticker tape host is down....Attempting reconnection....";
System.out.println ("Ticker Reader readData failed.");
}
return (tickerStr);
}
// The paint() method first checks if the Ticker has grown wider or
// taller. If it has grown taller, it is resized back to the right
// height for the font. If it has grown wider, setupTape() will
// create a new wider offscreen image and reset the number of steps
// required to scroll all the way across.
//
// After checking for resize, paint() draws the string into the
// offscreen image at the current scroll position then draws the
// image on the display.
public void paint(Graphics g) {
// Adjust for resize if necessary.
setupTape();
// Draw the string into the offscreen image.
Graphics offg = offscreenImage.getGraphics();
offg.setColor(getBackground());
offg.fillRect(0, 0, size().width - (RECTMARGIN * 2), textHeight);
offg.setColor(getForeground());
offg.setFont(textFont);
// previousWidth is the width of the displayed area in pixels.
// The text starts at the right edge of the Ticker at a position
// previousWidth pixels from the left. Each time it is repainted
// it is drawn one pixel farther to the left.
offg.drawString(tape, previousWidth - tapeIndex,
textHeight - textDescent);
// totalTapeSteps is set to the width of the display area +
// the width of the text. After the text has scrolled the
// width of the display area it is at the left end of the
// display and it must scroll its own width to complete
// one traversal.
tapeIndex = (tapeIndex + 1) % totalTapeSteps;
// When tapeIndex has reached 0, get a new string
if (tapeIndex == 0) {
tape = getNextString ();
return;
}
// Draw a 3D rectangle just within the display area for a border.
g.draw3DRect(RECTMARGIN, RECTMARGIN,
size().width - RECTMARGIN,
size().height - RECTMARGIN,
false);
// Draw the offscreen image within the rectangle.
g.drawImage(offscreenImage, RECTMARGIN + 1,
RECTMARGIN + TEXTMARGIN + 1,
this);
} // end paint
public void close() {
tickerHost.closePort();
}
// The stop() method stops the scrolling thread.
public void stop() {
scrollThread.stop();
}
// The Ticker update() method just calls paint() since we are covering the
// background with our offscreen image.
public void update(Graphics g) {
paint(g);
}
// The run() method just pauses briefly between repaints.
public void run() {
while (true) {
try {
scrollThread.sleep(SCROLLPAUSE);
} catch (InterruptedException e) {
}
repaint();
}
}
// The setupTape() method adjusts the state of the Ticker after a resize.
// If the height has changed, it is reset to the appropriate height for
// the selected font. If the width has changed, the number of steps
// required for a complete scroll traversal is reset and a new offscreen
// image is created to draw into.
private void setupTape() {
Dimension dim = size();
// resize() does nothing if the size hasn't changed.
resize(dim.width, textHeight + (TEXTMARGIN * 2) + (RECTMARGIN * 2));
// If the width hasn't changed, we're done.
if (dim.width == previousWidth) {
return;
}
// Save the width to compare against next time.
previousWidth = dim.width;
// Reset the tape to the beginning.
tapeIndex = 0;
// The total steps required for a scroll traversal is the width
// of the display area + the width of the text.
totalTapeSteps = dim.width + textWidth;
// If there is already an existing offscreen image, destroy it.
if (offscreenImage != null) {
offscreenImage.flush();
}
offscreenImage = createImage(dim.width - (RECTMARGIN * 2), textHeight);
} // end setupTape
} // end class TickerTape
Last Updated