1 ////////////////////////////////////////////////////////////////////////////// 2 // DX SOURCEFILE // 3 ////////////////////////////////////////////////////////////////////////////// 4 5 /* 6 * $Header: /src/master/dx/src/uipp/java/dx/client/AppletClient.java,v 1.3 2005/12/26 21:33:42 davidt Exp $ 7 */ 8 9 /* 10 * 11 */ 12 13 package dx.client; 14 import java.applet.*; 15 import java.awt.*; 16 import java.net.*; 17 import java.io.*; 18 import java.util.*; 19 20 21 // 22 // 23 // 24 25 public abstract class AppletClient extends Applet 26 { 27 update( Graphics g )28 public void update( Graphics g ) 29 { 30 paint( g ); 31 } 32 33 // 34 // Overriding these gives subclasses a way to control behavior without 35 // implementing loading logic. 36 // getCurrentImage()37 protected Image getCurrentImage() 38 { 39 return current_image; 40 } 41 getCurrentSequence()42 protected int getCurrentSequence() 43 { 44 return current_sequence; 45 } 46 getCurrentLoop()47 protected int getCurrentLoop() 48 { 49 return current_iteration; 50 } 51 getImageHandling()52 protected boolean getImageHandling() 53 { 54 return true; 55 } 56 getIsEmbedded()57 protected boolean getIsEmbedded() 58 { 59 return false; 60 } 61 getNextIter( int i )62 protected int getNextIter( int i ) 63 { 64 return i + 1; 65 } 66 loadNextImage()67 protected boolean loadNextImage() 68 { 69 return initial_loading; 70 } 71 isLoopValid( String gifname, int s, int l )72 protected boolean isLoopValid( String gifname, int s, int l ) 73 { 74 if ( s < current_sequence ) return false; 75 76 if ( s > current_sequence ) return true; 77 78 return ( l >= current_iteration ); 79 } 80 setCurrentImage( Image i, int s, int l )81 protected synchronized void setCurrentImage( Image i, int s, int l ) 82 { 83 current_image = i; current_sequence = s; current_iteration = l; 84 } 85 86 87 private Image current_image; 88 private Vector fclts; 89 private String gifname; 90 private String mostRecentUrl; 91 private int current_iteration; 92 private int current_sequence; 93 getImageUrl()94 protected String getImageUrl() 95 { 96 return this.mostRecentUrl; 97 } 98 99 // 100 // Set to true when initializing so that we'll look for each iteration 101 // of a loop. When running, we'll receive a notification for each iteration. 102 // 103 private boolean initial_loading; 104 AppletClient()105 protected AppletClient() 106 { 107 super(); 108 gifname = null; 109 mostRecentUrl = null; 110 current_image = null; 111 current_iteration = 0; 112 fclts = new Vector( 4 ); 113 } 114 init()115 public void init() 116 { 117 super.init(); 118 fclts.removeAllElements(); 119 120 gifname = getParameter( "INITIAL_IMAGE" ); 121 122 // 123 // If our URL indicates a non-zero loop count then start loading 124 // images earlier in the sequence. 125 // Look for %s_%d.%d.%d.* 126 // 127 initial_loading = true; 128 129 if ( getIsEmbedded() == false ) { 130 current_sequence = 0; 131 132 if ( getLoopCount( gifname ) > 0 ) { 133 String s = getImageName( gifname, 0 ); 134 requestImage ( s, 0, 0 ); 135 } 136 137 else { 138 requestImage ( gifname, 0, 0 ); 139 } 140 141 repaint(); 142 } 143 } 144 stop()145 public void stop() 146 { 147 super.stop(); 148 Enumeration enum1 = this.fclts.elements(); 149 150 while ( enum1.hasMoreElements() ) { 151 AppletLoadThread fclt = ( AppletLoadThread ) enum1.nextElement(); 152 153 if ( ( fclt != null ) && ( fclt.isAlive() ) ) 154 fclt.interrupt(); 155 } 156 157 this.fclts.removeAllElements(); 158 } 159 160 // 161 // This is called in async fashion by AppletLoadThread. 162 // It's possible to have 2 threads running. 163 // The locking is to protect current_image. 164 // 165 imageAvailable( Image i, String s, int sequence, int loop, String urlString )166 public synchronized void imageAvailable 167 ( Image i, String s, int sequence, int loop, String urlString ) 168 { 169 if ( isLoopValid( s, sequence, loop ) == false ) return ; 170 171 // 172 // There isn't any way of knowing if another frame is available. 173 // So we just have to go looking for it in the case where we're 174 // just starting up. 175 // 176 if ( i != null ) { 177 if ( loadNextImage() ) { 178 int cnt = getNextIter( loop ); 179 String gn = getImageName ( s, cnt ); 180 requestImage( gn, sequence, cnt ); 181 } 182 183 if ( sequence > current_sequence ) { 184 Enumeration enum1 = fclts.elements(); 185 Vector deceased = new Vector( 4 ); 186 187 while ( enum1.hasMoreElements() ) { 188 AppletLoadThread fclt = ( AppletLoadThread ) enum1.nextElement(); 189 190 if ( ( fclt != null ) && ( fclt.getSequence() < sequence ) ) { 191 if ( fclt.isAlive() ) 192 fclt.interrupt(); 193 194 deceased.addElement( ( Object ) fclt ); 195 } 196 197 else if ( ( fclt != null ) && ( fclt.isAlive() == false ) ) { 198 deceased.addElement( ( Object ) fclt ); 199 } 200 } 201 202 enum1 = deceased.elements(); 203 204 while ( enum1.hasMoreElements() ) { 205 AppletLoadThread fclt = ( AppletLoadThread ) enum1.nextElement(); 206 fclts.removeElement( ( Object ) fclt ); 207 } 208 } 209 210 this.mostRecentUrl = urlString; 211 setCurrentImage( i, sequence, loop ); 212 } 213 214 else { 215 if ( initial_loading == false ) { 216 System.out.println ( "AppletClient: couldn't load " + s ); 217 } 218 219 else { 220 initial_loading = false; 221 current_sequence = -1; 222 } 223 } 224 225 if ( i != null ) 226 repaint(); 227 } 228 requestImage( String gifname, int sequence, int loop )229 protected void requestImage ( String gifname, int sequence, int loop ) 230 { 231 AppletLoadThread fclt = new AppletLoadThread( this, gifname, sequence, loop ); 232 fclt.start(); 233 fclts.addElement( ( Object ) fclt ); 234 } 235 requestImage( String gifname )236 protected void requestImage ( String gifname ) 237 { 238 int seq = getSequenceCount( gifname ); 239 int loop = getLoopCount( gifname ); 240 requestImage( gifname, seq, loop ); 241 } 242 paint( Graphics g )243 public void paint( Graphics g ) 244 { 245 if ( getIsEmbedded() == false ) { 246 Dimension d = getSize(); 247 248 if ( getCurrentImage() == null ) { 249 g.setColor ( Color.black ); 250 g.fillRect ( 0, 0, d.width, d.height ); 251 } 252 253 else { 254 Image im = getCurrentImage(); 255 g.drawImage( im, 0, 0, d.width, d.height, Color.black, this ); 256 } 257 } 258 } 259 260 // 261 // Pull the loop counter out of the image name 262 // The name looks like: foobar1.0.0.htm or 263 // 1_1.0.0.htm 264 // getLoopCount( String s )265 protected int getLoopCount( String s ) 266 { 267 int slash = s.lastIndexOf( ( int ) /*File.separatorChar*/'/' ); 268 String basename; 269 270 if ( slash >= 0 ) 271 basename = s.substring( slash + 1 ); 272 else 273 basename = s; 274 275 StringTokenizer stok = new StringTokenizer( basename, "." ); 276 277 int loop = 0; 278 279 boolean loop_found = false; 280 281 int tokens = 0; 282 283 boolean parse_error = false; 284 285 while ( ( parse_error == false ) && ( loop_found == false ) && ( stok.hasMoreTokens() ) ) { 286 String tok = stok.nextToken(); 287 288 switch ( tokens ) { 289 case 0: 290 break; 291 case 1: 292 293 try { 294 Integer jidi = new Integer( tok ); 295 int jid = jidi.intValue(); 296 } 297 298 catch ( Exception e ) { 299 parse_error = true; 300 } 301 302 break; 303 case 2: 304 305 try { 306 Integer loopi = new Integer( tok ); 307 loop = loopi.intValue(); 308 loop_found = true; 309 } 310 311 catch ( Exception e ) { 312 parse_error = true; 313 } 314 315 break; 316 default: 317 parse_error = true; 318 break; 319 } 320 321 tokens++; 322 } 323 324 if ( loop_found ) 325 return loop; 326 327 initial_loading = false; 328 329 return -1; 330 } 331 getSequenceCount( String s )332 protected int getSequenceCount( String s ) 333 { 334 int slash = s.lastIndexOf( ( int ) /*File.separatorChar*/'/' ); 335 String basename; 336 337 if ( slash >= 0 ) 338 basename = s.substring( slash + 1 ); 339 else 340 basename = s; 341 342 StringTokenizer stok = new StringTokenizer( basename, "." ); 343 344 int seq = 0; 345 346 boolean seq_found = false; 347 348 int tokens = 0; 349 350 boolean parse_error = false; 351 352 while ( ( parse_error == false ) && ( seq_found == false ) && ( stok.hasMoreTokens() ) ) { 353 String tok = stok.nextToken(); 354 355 switch ( tokens ) { 356 case 0: 357 break; 358 case 1: 359 360 try { 361 Integer seqi = new Integer( tok ); 362 seq = seqi.intValue(); 363 seq_found = true; 364 } 365 366 catch ( Exception e ) { 367 parse_error = true; 368 } 369 370 break; 371 default: 372 parse_error = true; 373 break; 374 } 375 376 tokens++; 377 } 378 379 if ( seq_found ) 380 return seq; 381 382 initial_loading = false; 383 384 return -1; 385 } 386 getImageName( String gifname, int loop )387 protected String getImageName( String gifname, int loop ) 388 { 389 int oldloop = getLoopCount( gifname ); 390 391 int slash = gifname.lastIndexOf( ( int ) /*File.separatorChar*/'/' ); 392 String basename; 393 String fullPath; 394 395 if ( slash >= 0 ) { 396 basename = gifname.substring( slash + 1 ); 397 fullPath = gifname.substring( 0, slash + 1 ); 398 } 399 400 else { 401 basename = gifname; 402 fullPath = null; 403 } 404 405 StringTokenizer stok = new StringTokenizer( basename, "." ); 406 boolean loop_found = false; 407 int tokens = 0; 408 boolean parse_error = false; 409 410 while ( ( parse_error == false ) && ( loop_found == false ) && ( stok.hasMoreTokens() ) ) { 411 String tok = stok.nextToken(); 412 413 switch ( tokens ) { 414 case 0: 415 416 if ( fullPath == null ) fullPath = tok; 417 else fullPath = fullPath + tok; 418 419 break; 420 421 case 1: 422 fullPath = fullPath + "." + tok; 423 424 break; 425 426 case 2: 427 fullPath = fullPath + "." + loop; 428 429 break; 430 431 default: 432 fullPath = fullPath + "." + tok; 433 434 break; 435 } 436 437 tokens++; 438 } 439 440 return fullPath; 441 } 442 443 444 } // end AppletClient 445 446 447