////////////////////////////////////////////////////////////////////////////// // DX SOURCEFILE // ////////////////////////////////////////////////////////////////////////////// /* * $Header: /home/gda/dxcvs/dx/src/ui++/java/dx/client/AppletClient.java,v 1.1.1.1 1999/03/24 15:17:30 gda Exp $ */ /* * */ package dx.client; import java.applet.*; import java.awt.*; import java.net.*; import java.io.*; import java.util.*; // // // public abstract class AppletClient extends Applet { public void update(Graphics g) { paint(g); } // // Overriding these gives subclasses a way to control behavior without // implementing loading logic. // protected Image getCurrentImage() { return current_image; } protected int getCurrentSequence() { return current_sequence; } protected int getCurrentLoop() { return current_iteration; } protected boolean getImageHandling() { return true; } protected boolean getIsEmbedded() { return false; } protected int getNextIter(int i) { return i+1; } protected boolean loadNextImage() { return initial_loading; } protected boolean isLoopValid(String gifname, int s, int l) { if (s < current_sequence) return false; if (s > current_sequence) return true; return (l >= current_iteration); } protected synchronized void setCurrentImage(Image i, int s, int l) { current_image = i; current_sequence = s; current_iteration = l; } private Image current_image; private Vector fclts; private String gifname; private String mostRecentUrl; private int current_iteration; private int current_sequence; protected String getImageUrl() { return this.mostRecentUrl; } // // Set to true when initializing so that we'll look for each iteration // of a loop. When running, we'll receive a notification for each iteration. // private boolean initial_loading; protected AppletClient() { super(); gifname = null; mostRecentUrl = null; current_image = null; current_iteration = 0; fclts = new Vector(4); } public void init() { super.init(); fclts.removeAllElements(); gifname = getParameter("INITIAL_IMAGE"); // // If our URL indicates a non-zero loop count then start loading // images earlier in the sequence. // Look for %s_%d.%d.%d.* // initial_loading = true; if (getIsEmbedded() == false) { current_sequence = 0; if (getLoopCount(gifname) > 0) { String s = getImageName(gifname, 0); requestImage (s, 0, 0); } else { requestImage (gifname, 0, 0); } repaint(); } } public void stop() { super.stop(); Enumeration enum = this.fclts.elements(); while (enum.hasMoreElements()) { AppletLoadThread fclt = (AppletLoadThread)enum.nextElement(); if ((fclt != null) && (fclt.isAlive())) fclt.stop(); } this.fclts.removeAllElements(); } // // This is called in async fashion by AppletLoadThread. // It's possible to have 2 threads running. // The locking is to protect current_image. // public synchronized void imageAvailable (Image i, String s, int sequence, int loop, String urlString ) { if (isLoopValid(s, sequence, loop) == false) return ; // // There isn't any way of knowing if another frame is available. // So we just have to go looking for it in the case where we're // just starting up. // if (i != null) { if (loadNextImage()) { int cnt = getNextIter(loop); String gn = getImageName (s, cnt); requestImage(gn, sequence, cnt); } if (sequence > current_sequence) { Enumeration enum = fclts.elements(); Vector deceased = new Vector(4); while (enum.hasMoreElements()) { AppletLoadThread fclt = (AppletLoadThread)enum.nextElement(); if ((fclt != null) && (fclt.getSequence() < sequence)) { if (fclt.isAlive()) fclt.stop(); deceased.addElement((Object)fclt); } else if ((fclt != null) && (fclt.isAlive() == false)) { deceased.addElement((Object)fclt); } } enum = deceased.elements(); while (enum.hasMoreElements()) { AppletLoadThread fclt = (AppletLoadThread)enum.nextElement(); fclts.removeElement((Object)fclt); } } this.mostRecentUrl = urlString; setCurrentImage(i, sequence, loop); } else { if (initial_loading == false) { System.out.println ("AppletClient: couldn't load " + s); } else { initial_loading = false; current_sequence = -1; } } if (i != null) repaint(); } protected void requestImage (String gifname, int sequence, int loop) { AppletLoadThread fclt = new AppletLoadThread(this, gifname, sequence, loop); fclt.start(); fclts.addElement((Object)fclt); } protected void requestImage (String gifname) { int seq = getSequenceCount(gifname); int loop = getLoopCount(gifname); requestImage(gifname, seq, loop); } public void paint(Graphics g) { if (getIsEmbedded() == false) { Dimension d = size(); if (getCurrentImage() == null) { g.setColor (Color.black); g.fillRect (0,0,d.width, d.height); } else { Image im = getCurrentImage(); g.drawImage(im, 0,0,d.width, d.height, Color.black, this); } } } // // Pull the loop counter out of the image name // The name looks like: foobar1.0.0.htm or // 1_1.0.0.htm // protected int getLoopCount(String s) { int slash = s.lastIndexOf((int)/*File.separatorChar*/'/'); String basename; if (slash >= 0) basename = s.substring(slash+1); else basename = s; StringTokenizer stok = new StringTokenizer(basename, "."); int loop = 0; boolean loop_found = false; int tokens = 0; boolean parse_error = false; while ((parse_error==false) && (loop_found==false) && (stok.hasMoreTokens())) { String tok = stok.nextToken(); switch (tokens) { case 0: break; case 1: try { Integer jidi = new Integer(tok); int jid = jidi.intValue(); } catch (Exception e) { parse_error = true; } break; case 2: try { Integer loopi = new Integer(tok); loop = loopi.intValue(); loop_found = true; } catch (Exception e) { parse_error = true; } break; default: parse_error = true; break; } tokens++; } if (loop_found) return loop; initial_loading = false; return -1; } protected int getSequenceCount(String s) { int slash = s.lastIndexOf((int)/*File.separatorChar*/'/'); String basename; if (slash >= 0) basename = s.substring(slash+1); else basename = s; StringTokenizer stok = new StringTokenizer(basename, "."); int seq = 0; boolean seq_found = false; int tokens = 0; boolean parse_error = false; while ((parse_error == false) && (seq_found == false) && (stok.hasMoreTokens())) { String tok = stok.nextToken(); switch (tokens) { case 0: break; case 1: try { Integer seqi = new Integer(tok); seq = seqi.intValue(); seq_found = true; } catch (Exception e) { parse_error = true; } break; default: parse_error = true; break; } tokens++; } if (seq_found) return seq; initial_loading = false; return -1; } protected String getImageName(String gifname, int loop) { int oldloop = getLoopCount(gifname); int slash = gifname.lastIndexOf((int)/*File.separatorChar*/'/'); String basename; String fullPath; if (slash >= 0) { basename = gifname.substring(slash+1); fullPath = gifname.substring(0,slash+1); } else { basename = gifname; fullPath = null; } StringTokenizer stok = new StringTokenizer(basename, "."); boolean loop_found = false; int tokens = 0; boolean parse_error = false; while ((parse_error == false) && (loop_found == false) && (stok.hasMoreTokens())) { String tok = stok.nextToken(); switch (tokens) { case 0: if (fullPath == null) fullPath = tok; else fullPath = fullPath + tok; break; case 1: fullPath = fullPath + "." + tok; break; case 2: fullPath = fullPath + "." + loop; break; default: fullPath = fullPath + "." + tok; break; } tokens++; } return fullPath; } } // end AppletClient