/* guestbook.java * * 23rd May 1996 * * * * simple applet to display contents of a guestbook text file * * * * If you use this code, please let me know: * * http://www.max.tc * * mail@max.tc */ /* Note that this code expects the guestbook file to be of * a certain format; I have a CGI script that generates this * file from user comments which I can supply. */ import java.awt.*; import java.awt.event.*; import java.lang.Character; import java.io.*; import java.net.*; import java.lang.System; public class guestbook extends java.applet.Applet implements Runnable { // Constants String COPYRIGHT_INFO = "GuestBook Applet"; String FONT_NAME = "Helvetica"; int FONT_SIZE = 12; boolean userPause = false; // Off-screen graphics buffer Image OffBuff; Graphics gOffBuff; // Other stuff int appletWidth; int appletHeight; Thread displayThread = null; Font boldFont, plainFont; FontMetrics fm; public void init() { appletWidth = size().width; appletHeight = size().height; ReadParameters(); InitDisplayData(); } URL guestbookURL; private void ReadParameters() { String tFile; tFile = getParameter("file"); if (tFile == null) tFile = "GuestBook.shtml"; try { guestbookURL = new URL(getCodeBase(), tFile); } catch (MalformedURLException e) { System.out.println("e2"); } } private void InitDisplayData() { showStatus(COPYRIGHT_INFO); plainFont = new Font(FONT_NAME,Font.PLAIN,FONT_SIZE-2); boldFont = new Font(FONT_NAME,Font.BOLD,FONT_SIZE); OffBuff = createImage(size().width,size().height); gOffBuff = OffBuff.getGraphics(); } public String getAppletInfo() { return COPYRIGHT_INFO; } public String[][] getParameterInfo() { String pinfo[][] = { {"file", "string", "File from whch to read; defaults to GuestBook.shtml"} }; return pinfo; } public void start() { if (displayThread == null) { displayThread = new Thread(this); displayThread.start(); } } public void stop() { if (displayThread != null && displayThread.isAlive()) displayThread.stop(); displayThread = null; } public boolean handleEvent(Event evt) { if (evt.id == Event.MOUSE_DOWN) { if (displayThread != null && displayThread.isAlive()) { if (userPause) { displayThread.resume(); } else { displayThread.suspend(); } userPause = !userPause; } else { userPause = false; displayThread = new Thread(this); displayThread.start(); } return true; } else { return super.handleEvent(evt); } } public void run() { long startTime; int charDelayTime = 50; while (Thread.currentThread() == displayThread) { startTime = System.currentTimeMillis(); repaint(); updateBuffer(); try { Thread.sleep(Math.max(20,startTime+charDelayTime-System.currentTimeMillis())); } catch (InterruptedException e) { ; } } } public void update(Graphics g) { g.drawImage(OffBuff,0,0,this); } int cx, cy; boolean ubinit = false; int colMod; /* String testString = "Go placidly amid the noise & haste & remember what peace there may be in silence.\n" + "As far as possible be on good terms with all persons. Speak your truth quietly & clearly & listen to " + "others, even the dull & ignorant; they too have their story. Avoid loud & agressive persons they are " + "vexations to the spirit.\nIf you compare yourself with others you may become vain & bitter; for always " + "there will be greater & lesser persons than yourself.\nEnjoy your achievements as well as your plans. " + "Keep interested in your own career however humble; it is a real possession in the changing fortunes of " + "time.\nExcercise caution in your business affairs; for the world is full of trickery. But let this not " + "blind you to what virtue there is. Many persons strive for high ideals & everywhere life is full of " + "heroism.\nBe yourself. Especially do not feign affection. Neither be cynical about love, for in the " + "face of aridity & disenchantment, it is perenial as the grass.\nTake kindly the counsel of years, " + "gracefully surrendering the things of youth.\nNurture strength of spirit to shield you in sudden misfortune. " + "But do not distress yourself with imaginings. Many fears are born of fatigue & loneliness.\nBeyond a " + "wholesome discipline, be gentle with yourself. You are a child of the universe no less than the trees " + "and stars.\nYou have a right to be here. And whether or not it is clear to you, no doubt the universe " + "is unfolding as it should.\nTherefore be at peace with God whatever you conceive Him to be & whatever " + "your labours & aspirations in the noisy confusion of life. Keep peace with your soul.\nWith all its " + "sham & drudgery & broken dreams, it is still a beautiful world.\nBe careful.\nStrive to be happy.\n\n\n"; */ BufferedReader bFileRdr; Color curCol = Color.blue; boolean inMsg = true; private void updateBuffer() { try { int i, ncx, inchar, fc; char c[] = new char[1]; char ch; final Color bkgCol = Color.black; final int MaxWordLength = 100; boolean f, realAmpersand; if (!ubinit) // this code executes once only { cx = 0; cy = appletHeight / 2; gOffBuff.setColor(Color.yellow); gOffBuff.fillRect(0,0,appletWidth,appletHeight); gOffBuff.setColor(Color.black); try { bFileRdr = new BufferedReader(new InputStreamReader(guestbookURL.openStream())); } catch (FileNotFoundException e) { System.out.println("File " + guestbookURL + " not found"); } catch (IOException e) { System.out.println("Exception on opening " + guestbookURL); } ubinit = true; } gOffBuff.setColor(Color.black); inchar = bFileRdr.read(); // HTML parsing realAmpersand = false; do { f = false; if (inchar == '<') { fc = bFileRdr.read(); while (bFileRdr.read() != '>') ; switch (fc) { case 'A': inchar = '\n'; break; case '!': inchar = ' '; if (curCol == Color.red) curCol = Color.blue; else curCol = Color.red; inMsg = true; break; case '/': inMsg = false; default: inchar = bFileRdr.read(); break; } f = true; } if (inchar == '&' && !realAmpersand) { bFileRdr.mark(10); bFileRdr.read(); bFileRdr.read(); if (bFileRdr.read() == ';') { inchar = bFileRdr.read(); realAmpersand = false; } else { bFileRdr.reset(); realAmpersand = true; } f = true; } else { realAmpersand = false; } } while (f); if (inMsg) { gOffBuff.setFont(boldFont); fm = getFontMetrics(boldFont); } else { gOffBuff.setFont(plainFont); fm = getFontMetrics(plainFont); } if (inchar == -1) { // End of file; output a newline and re-open the file bFileRdr = new BufferedReader(new InputStreamReader(guestbookURL.openStream())); c[0] = '\n'; } else { c[0] = (char)inchar; } if (java.lang.Character.isSpace(c[0]) && c[0] != '\n') c[0] = ' '; if (!java.lang.Character.isISOControl(c[0])) { // Print character providing it's not a control gOffBuff.setColor(curCol); gOffBuff.drawChars(c, 0, 1, cx, cy); cx += fm.charWidth(c[0]); } // Code to handle word-wrapping if (java.lang.Character.isSpace(c[0]) && c[0] != '\n') { ncx=cx; bFileRdr.mark(MaxWordLength); while (ncx= appletWidth - fm.getMaxAdvance()) cx = appletWidth - fm.getMaxAdvance(); } // Move to next line if (cx >= (appletWidth - fm.getMaxAdvance()) || c[0]=='\n') { cx = 0; cy += (fm.getMaxAscent() + fm.getMaxDescent()) * (c[0]=='\n'? 1.0f : 1.0f); } // Code to handle scrolling // (not very good -- need to run scrolling through animation loop!) while (cy + fm.getMaxDescent() >= appletHeight) { // g.setColor(Color.yellow); gOffBuff.setColor(Color.yellow); // for (i=1; i<=fm.getMaxAscent() + fm.getMaxDescent(); i++) { // g.drawImage(OffBuff,0,-i,this); // g.fillRect(0,appletHeight-i,appletWidth,appletHeight); // } i = fm.getMaxAscent() + fm.getMaxDescent(); gOffBuff.drawImage(OffBuff,0,-i,this); gOffBuff.fillRect(0,appletHeight-i,appletWidth,appletHeight); cy -= fm.getMaxAscent() + fm.getMaxDescent(); } } catch (IOException e) { System.out.println("e1"); } } }