Jul 022000
You need Java to view this applet.
Soooo, this was inspired while waiting for a train that never came. The notice board constantly told me that the train was imminently arriving; though every minute that passed the due time clocked up by one minute. I think I waited for an hour, and the board still said the train was arriving in a minute!
import java.awt.*; import java.applet.*; import java.util.Calendar; import java.util.Date; import java.text.*; public class AtRail extends Applet implements Runnable { private String timeScheduled, timeDue, timeNow="", vMessage1="", vMessage2=""; private static String destination, destDetails; private SimpleDateFormat sdfA, sdfB; private static Font fTime, fDDetail, fDestination; private Thread updateTime, drawGraphics; private static int xWidth, yHeight; private int xCounter, yCounter; private boolean scrolling = true; private Image i_vScroll, i_hScroll, i_time; private Graphics g_vScroll, g_hScroll, g_time; private Dimension d_vScroll, d_hScroll, d_time; public void init(){ System.out.println("AtRail.class, V b1, 29/6/01 by AtPeace, http://www.somedodgywebsite.com"); System.out.println("Email : AtPeace@somedodgywebsite.com"); //Set backgreound this.setBackground(Color.black); //Pull Applet dims & assign ints for dims Rectangle rec= this.getBounds(); yHeight = rec.height; xWidth = rec.width; // DEBUG System.out.println(xWidth+""+yHeight); //pulled from Parmas, but not destDetails = "Calling at London Kings X only."; destination = "Kings X Only"; //Set Font for display fTime = new Font("CourierNew",Font.PLAIN,15); fDDetail = new Font("CourierNew",Font.ITALIC,15); fDestination = new Font("CourierNew",Font.BOLD,20); //Pull font metrics for dim of graphics display FontMetrics fm_time = getFontMetrics(fTime); //Define dimenstions for use with graphics contexts d_time = new Dimension(fm_time.stringWidth("88:88:88"),fm_time.getHeight()); d_vScroll = new Dimension(xWidth,yHeight-d_time.height); d_hScroll = new Dimension(xWidth-d_time.width,d_time.height); // DEBUG System.out.println(d_time.toString());//56 17 //Set format for String display dates sdfA = new SimpleDateFormat ("hh:mm:ss"); sdfB = new SimpleDateFormat ("hh:mm"); //Pull current time, add 3 mins & format string for display. //TODO replace addition of spaces with a metric of font space. Date timer = new Date(); long timeinc = timer.getTime()+120000; Date tempDue = new Date(timeinc); timeScheduled = sdfB.format(tempDue); vMessage1 = destination+" "+timeScheduled; //Create Graphics context for off screen drawing, of the dimentioned size i_time = createImage(d_time.width,d_time.height); i_vScroll = createImage(d_vScroll.width,d_vScroll.height); i_hScroll = createImage(d_hScroll.width,d_hScroll.height); g_time = i_time.getGraphics(); g_vScroll = i_vScroll.getGraphics(); g_hScroll = i_hScroll.getGraphics(); //Create and start Threads updateTime = new Thread(this, "AtTime"); updateTime.start(); drawGraphics = new Thread (this, "AtDraw"); drawGraphics.start(); } public void updateTime(){ //Thread for time monitor do { //Retrive time Date currentTime = new Date(); Date dueTime = new Date(); timeNow=sdfA.format(currentTime); //Add 3 mins & hash time into long long timeDueHash = currentTime.getTime()+180000; dueTime.setTime(timeDueHash); //TODO with Font Metric add pixel distance for additional sapce in use. vMessage2="Due "+sdfB.format(dueTime); try {Thread.sleep(1000);} catch (InterruptedException e){} } while (true); } public void drawGraphics(){ //Thread for calc vertical scrolling message xCounter = xWidth + 10; yCounter = yHeight; Date timer = new Date(); do { // paintOffScreen(); repaint(); try {Thread.sleep(20);} catch (InterruptedException e){} xCounter--; //Destination Details Stops if(xCounter<-230) xCounter = xWidth +10; //Destination Station if (yCounter < 27){ scrolling = false; Date timer2 = new Date(); if (timer2.getTime()>timer.getTime()+5000){ if (yCounter < -3) { scrolling = false; if (timer2.getTime()>timer.getTime()+10000){ yCounter= yHeight; timer = new Date(); } } else {scrolling = true;yCounter--;} } } else {scrolling = true;yCounter--;} } while (true); } public void paintOffScreen(){ repaint(); } public void paint(Graphics g) { update(g); } public synchronized void update(Graphics g){ //Draw Time g_time.setColor(Color.black); g_time.fillRect(0,0,d_time.width,d_time.height); g_time.setColor(Color.green); g_time.setFont(fTime); g_time.drawString(timeNow,0,14); //Draw destDetails times g_vScroll.setColor(Color.black); g_vScroll.fillRect(0,0,d_vScroll.width,d_vScroll.height); g_vScroll.setColor(Color.green); g_vScroll.setFont(fDestination); g_vScroll.drawString(vMessage2,5,yCounter+30); g_vScroll.drawString(vMessage1,5,yCounter); g_vScroll.drawString(vMessage2,5,yCounter-30); //paint(g_vScroll); //Draw destDetails detail g_hScroll.setColor(Color.black); g_hScroll.fillRect(0,0,d_hScroll.width,d_hScroll.height); g_hScroll.setColor(Color.green); g_hScroll.setFont(fDDetail); g_hScroll.drawString(destDetails,xCounter,14); g.drawImage(i_time,xWidth-d_time.width,yHeight-d_time.height,this); g.drawImage(i_vScroll,0,0,this); g.drawImage(i_hScroll,0,yHeight-d_hScroll.height,this); } public void run(){ //Kicks threads into action (Runable) if (Thread.currentThread()==updateTime) updateTime(); if (Thread.currentThread()==drawGraphics) drawGraphics(); } public String getAppletInfo() { //nfo for applete return "AtRail.java, V b1, 29/6/01 by AtPeace, http://somedodgywebsite.com"; } public void destroy(){ updateTime.stop(); updateTime = null; drawGraphics.stop(); drawGraphics=null; } }