001 package com.croftsoft.apps.ads; 002 003 import java.applet.Applet; 004 import java.awt.*; 005 import java.io.*; 006 import java.net.*; 007 import java.util.*; 008 009 /********************************************************************* 010 * Rotating ad banner applet. 011 * 012 * @version 013 * 2001-07-18 014 * @since 015 * 1997 016 * @author 017 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 018 *********************************************************************/ 019 020 public final class Ads extends Applet implements Runnable 021 ////////////////////////////////////////////////////////////////////// 022 ////////////////////////////////////////////////////////////////////// 023 { 024 025 private static final String APPLET_TITLE 026 = "Ads \u00A9 2001 David Wallace Croft"; 027 028 private static final String APPLET_INFO 029 = "\n" + APPLET_TITLE + "\n" 030 + "croft@alumni.caltech.edu\n" 031 + "http://www.alumni.caltech.edu/~croft/\n" 032 + "Version 2001-07-18\n"; 033 034 private static final String PARAM_DATA_FILENAME = "dataFilename"; 035 036 /** 037 * Modify to redirect control of what ads are displayed. 038 * 039 * The link is relative to the CodeBase although this may be modified 040 * as well. 041 */ 042 private static final String DEFAULT_DATA_FILENAME = "ads.dat"; 043 044 /** 045 * How long each image is displayed, in milliseconds. 046 */ 047 private static final long AIR_TIME = 15000; 048 049 // 050 051 private static Random random = new Random ( ); 052 053 // 054 055 private String dataFilename; 056 057 private Vector imageURL_StringVector; 058 059 private Vector site_URL_StringVector; 060 061 private Hashtable imageUrlStringToImageHashtable; 062 063 private Graphics g; 064 065 private Dimension size; 066 067 private Image offscreenImage; 068 069 private Graphics offscreenGraphics; 070 071 private boolean shouldRun; 072 073 private Thread thread; 074 075 private int index; 076 077 ////////////////////////////////////////////////////////////////////// 078 ////////////////////////////////////////////////////////////////////// 079 080 public String getAppletInfo ( ) 081 ////////////////////////////////////////////////////////////////////// 082 { 083 return APPLET_INFO; 084 } 085 086 public synchronized void init ( ) 087 ////////////////////////////////////////////////////////////////////// 088 { 089 setCursor ( Cursor.getPredefinedCursor ( Cursor.HAND_CURSOR ) ); 090 091 imageURL_StringVector = new Vector ( ); 092 093 site_URL_StringVector = new Vector ( ); 094 095 imageUrlStringToImageHashtable = new Hashtable ( ); 096 097 dataFilename = getParameter ( PARAM_DATA_FILENAME ); 098 099 if ( dataFilename == null ) 100 { 101 dataFilename = DEFAULT_DATA_FILENAME; 102 } 103 104 loadData ( ); 105 } 106 107 public synchronized void destroy ( ) 108 ////////////////////////////////////////////////////////////////////// 109 { 110 if ( g != null ) 111 { 112 g.dispose ( ); 113 } 114 115 if ( offscreenGraphics != null ) 116 { 117 offscreenGraphics.dispose ( ); 118 } 119 } 120 121 public synchronized void start ( ) 122 ////////////////////////////////////////////////////////////////////// 123 { 124 g = getGraphics ( ); 125 126 size = size ( ); 127 128 offscreenImage = createImage ( size.width, size.height ); 129 130 offscreenGraphics = offscreenImage.getGraphics ( ); 131 132 shouldRun = true; 133 134 ( thread = new Thread ( this ) ).start ( ); 135 } 136 137 public synchronized void stop ( ) 138 ////////////////////////////////////////////////////////////////////// 139 { 140 shouldRun = false; 141 142 if ( thread != null ) 143 { 144 thread.interrupt ( ); 145 } 146 } 147 148 public void run ( ) 149 ////////////////////////////////////////////////////////////////////// 150 { 151 int count = imageURL_StringVector.size ( ); 152 153 while ( shouldRun ) 154 { 155 int [ ] random_order = random_order_list ( count ); 156 157 for ( int i = 0; shouldRun && i < count; i++ ) 158 { 159 index = random_order [ i ]; 160 161 try 162 { 163 String imageUrlString 164 = ( String ) imageURL_StringVector.elementAt ( index ); 165 166 Image image = ( Image ) 167 imageUrlStringToImageHashtable.get ( imageUrlString ); 168 169 if ( image == null ) 170 { 171 image = getImage ( 172 new URL ( getCodeBase ( ), imageUrlString ) ); 173 174 imageUrlStringToImageHashtable.put ( imageUrlString, image ); 175 } 176 177 if ( prepareImage ( image, size.width, size.height, this ) ) 178 { 179 offscreenGraphics.drawImage ( 180 image, 0, 0, size.width, size.height, this ); 181 182 paint ( g ); 183 } 184 } 185 catch ( Exception e ) 186 { 187 e.printStackTrace ( ); 188 189 showStatus ( e.getMessage ( ) ); 190 } 191 192 try 193 { 194 thread.sleep ( AIR_TIME ); 195 } 196 catch ( InterruptedException e ) { } 197 } 198 } 199 } 200 201 public boolean imageUpdate ( 202 Image image, int flags, int x, int y, int w, int h ) 203 ////////////////////////////////////////////////////////////////////// 204 { 205 if ( flags == 32 ) 206 { 207 offscreenGraphics.drawImage ( 208 image, 0, 0, size.width, size.height, this ); 209 210 paint ( g ); 211 } 212 213 return super.imageUpdate ( image, flags, x, y, w, h ); 214 } 215 216 public boolean mouseMove ( Event evt, int x, int y ) 217 ////////////////////////////////////////////////////////////////////// 218 { 219 if ( site_URL_StringVector == null ) return true; 220 221 if ( site_URL_StringVector.size ( ) <= index ) return true; 222 223 showStatus ( ( String ) site_URL_StringVector.elementAt ( index ) ); 224 225 return true; 226 } 227 228 public boolean mouseUp ( Event evt, int x, int y ) 229 ////////////////////////////////////////////////////////////////////// 230 { 231 if ( site_URL_StringVector == null ) return true; 232 233 if ( site_URL_StringVector.size ( ) <= index ) return true; 234 235 try 236 { 237 getAppletContext ( ).showDocument ( new URL ( 238 ( String ) site_URL_StringVector.elementAt ( index ) ) ); 239 240 } 241 catch ( MalformedURLException e ) 242 { 243 e.printStackTrace ( ); 244 245 showStatus ( e.getMessage ( ) ); 246 } 247 248 return true; 249 } 250 251 public void paint ( Graphics graphics ) 252 ////////////////////////////////////////////////////////////////////// 253 { 254 if ( offscreenImage == null ) return; 255 256 graphics.drawImage ( offscreenImage, 0, 0, this ); 257 } 258 259 public void update ( Graphics graphics ) 260 ////////////////////////////////////////////////////////////////////// 261 { 262 paint ( graphics ); 263 } 264 265 public void repaint ( ) 266 ////////////////////////////////////////////////////////////////////// 267 { 268 paint ( g ); 269 } 270 271 ////////////////////////////////////////////////////////////////////// 272 // private methods 273 ////////////////////////////////////////////////////////////////////// 274 275 private synchronized boolean loadData ( ) 276 ////////////////////////////////////////////////////////////////////// 277 { 278 try 279 { 280 URL dataURL = new URL ( getCodeBase ( ), dataFilename ); 281 282 InputStream conn = dataURL.openStream ( ); 283 284 DataInputStream data = new DataInputStream ( conn ); 285 286 while ( true ) 287 { 288 String line = data.readLine ( ); 289 290 if ( line == null ) break; 291 292 imageURL_StringVector.addElement ( line ); 293 294 site_URL_StringVector.addElement ( data.readLine ( ) ); 295 296 if ( data.readLine ( ) == null ) break; 297 } 298 } 299 catch ( Exception e ) 300 { 301 e.printStackTrace ( ); 302 303 showStatus ( e.getMessage ( ) ); 304 305 return false; 306 } 307 308 return true; 309 } 310 311 private static int [ ] random_order_list ( int count ) { 312 ////////////////////////////////////////////////////////////////////// 313 Vector vector = new Vector ( count ); 314 for ( int i = 0; i < count; i++ ) { 315 vector.addElement ( new Integer ( i ) ); 316 } 317 int [ ] random_order = new int [ count ]; 318 for ( int i = 0; i < count; i++ ) { 319 Integer lucky = ( Integer ) vector.elementAt ( 320 ( int ) roll ( 1, count - i, -1 ) ); 321 vector.removeElement ( lucky ); 322 random_order [ i ] = lucky.intValue ( ); 323 } 324 return random_order; 325 } 326 327 private static long roll ( 328 long multiplier, 329 long base, 330 long offset ) 331 ////////////////////////////////////////////////////////////////////// 332 { 333 long temp = 0; 334 335 for ( long index_roll = 0; index_roll < multiplier; index_roll++ ) 336 { 337 temp += 1 + Math.round ( 338 ( double ) ( base - 1 ) * random.nextDouble ( ) ); 339 } 340 341 return temp + offset; 342 } 343 344 ////////////////////////////////////////////////////////////////////// 345 ////////////////////////////////////////////////////////////////////// 346 }