Index: main/trunk/greenstone3/src/java/org/greenstone/applet/GsdlCollageApplet/DisplayImages.java
===================================================================
--- main/trunk/greenstone3/src/java/org/greenstone/applet/GsdlCollageApplet/DisplayImages.java	(revision 38936)
+++ main/trunk/greenstone3/src/java/org/greenstone/applet/GsdlCollageApplet/DisplayImages.java	(revision 38937)
@@ -123,5 +123,12 @@
 	if(screen_buffer_ == null) {
 	    System.err.println("### why is screen_buffer_ null?");
-	}
+	    if(java.awt.GraphicsEnvironment.isHeadless()) {
+		System.err.println("### It's running headless so screen_buffer_ is null");
+	    }
+	    if(!app_.isDisplayable()) {
+		System.err.println("### Collage app is not displayable, that's why screen_buffer_ is null");
+	    }
+	}
+	
 	screen_graphic_ = screen_buffer_.getGraphics();
 	screen_graphic_.setColor(bgcolor_);
@@ -438,5 +445,6 @@
 		    Thread.sleep(1000);		    
 		    continue;
-		}    
+		}
+		//System.err.println("#### DisplayImages.run(): moving to next image");
 		CollageImage collage_image = download_images_.getCollageImage();
  	
Index: main/trunk/greenstone3/src/java/org/greenstone/applet/GsdlCollageApplet/GsdlCollageApplet.java
===================================================================
--- main/trunk/greenstone3/src/java/org/greenstone/applet/GsdlCollageApplet/GsdlCollageApplet.java	(revision 38936)
+++ main/trunk/greenstone3/src/java/org/greenstone/applet/GsdlCollageApplet/GsdlCollageApplet.java	(revision 38937)
@@ -150,8 +150,7 @@
 	super();
 	
-	// status bar that applet has, but we want one also if we run JPhind as application
-	// And in fact, when webswing runs our applet, we never get a status bar. So we
-	// create a custom status bar now even if we're running as an applet.
-	// When this applet is run through the appletviewer we might end up with 2 status bars.
+	// status bar if run as application or as webswing applet,
+	// mimicing running as regular applet which gives us a status bar by default
+	// Useful for Phind, not for Collage where there are layout issues even if hidden
 	//setLayout(new BorderLayout());
 	//if(!isRunAsApplet) {
@@ -176,4 +175,12 @@
     }
 
+    /**
+     * This method is called (by main()) only when this class is run
+     * as an application, not as applet. It prepares the variables and
+     * commandline parameters to be set up, so the rest of the
+     * initialisation can be done in the usual way (with the
+     * Applet.getParameters() method) in the init() method called
+     * hereafter for both application and applet mode.
+     */
     public void applicationPreInit(String[] args) {
 	// I copied the contents of this contructor for my code for the JPhind.java constructor
@@ -204,18 +211,5 @@
 		if(key.equals("xtraParams")) {
 		    value = value.replace("&amp;", "&"); // just in case we have html entities
-		    parseXtraParams(value, "=", "&", appParams);
-		    /*
-		    String[] param_list = value.split("&", 0); // 0 for all occurrences
-		    for(String key_val : param_list) {			
-			String[] paramPair = key_val.split("=", 2); // get first 2 strings, key and val
-			//System.err.println("key_val: " + key_val);
-			if(paramPair.length == 2) {
-			    String xtraParamsKey = paramPair[0];
-			    String xtraParamsVal = paramPair[1];
-			    //System.err.println("key - val: " + xtraParamsKey + " - " + xtraParamsVal);
-			    appParams.put(xtraParamsKey, xtraParamsVal);
-			}
-		    }
-		    */
+		    parseXtraParams(value, "=", "&", appParams);		    
 		}
 		
@@ -223,7 +217,4 @@
 	    }
 	}
-
-	// TODO: we can possibly remove this as it's done in init() now before we need it
-	isWebswing = appParams.getOrDefault("webswing", "0").equals("1") ? true : false;
 	
 	// Need these parameters set before init(), so that the display works
@@ -318,5 +309,5 @@
 	for(String key_val : param_list) {
 	    String[] paramPair = key_val.split(kvSeparator, 2); // get first 2 strings, key and val
-	    System.err.println("key_val: " + key_val);
+	    //System.err.println("key_val: " + key_val);
 	    if(paramPair.length == 2) {
 		String xtraParamsKey = paramPair[0];
@@ -328,5 +319,5 @@
 		}
 
-		if (verbosity_ >= 3) { 
+		if (verbosity_ >= 4) {
 		    System.err.println("*** xtraParams key - val: " + xtraParamsKey + " - " + xtraParamsVal);
 		}
@@ -530,12 +521,14 @@
 	}
 
-	// This block was a nice idea if it worked, but it doesn't work. It's here for syntax.
-	// Handle getting called by webswing JavaScript (but only if run in webswing mode):
-	// when the user navigates away from the webswing app's web page, do cleanup
+	// This block was a nice idea had it worked, but it doesn't
+	// work. It's here as sample syntax.  Handle getting called by
+	// webswing JavaScript (but only if run in webswing mode):
+	// when the user navigates away from the webswing app's web
+	// page, do cleanup
 	// https://www.webswing.org/docs/23.2/integrate/jslink.html#invoking-java-from-javascript
 	// https://vaadin.com/directory/component/webswing-vaadin1
 	if(isWebswing) {
 
-	    System.err.println("#### isWebswing, about to add listeners");
+	    //System.err.println("#### isWebswing, about to add listeners");
 	    
 	    WebswingUtil.getWebswingApi().addBrowserActionListener(new WebActionListener() {
@@ -543,5 +536,5 @@
 		    public void actionPerformed(WebActionEvent actionEvent) {
 
-			System.err.println("******** JavaScript to Java: actionPerformed called.");
+			System.err.println("***JavaScript to Java comms: actionPerformed called");
 			//System.err.println("actionEvent = ");
 			
@@ -566,20 +559,23 @@
 	    // shutdown the way we'd like on the javascript kill()
 	    // command when the user navigates away from the collage
-	    // page as that only generates a Java WindowClosingEvent
-	    // by default if not shutdown handlers registered. And a
+	    // page, as that only generates a Java WindowClosingEvent
+	    // by default if no shutdown handlers registered. And a
 	    // WindowClosingEvent only has any effect on applications,
 	    // not applets. But we can write our own custom handler to
-	    // mimic the applet shutdown sequence: refer to
+	    // mimic the applet shutdown sequence of stop() then
+	    // destroy() see
 	    // https://www.webswing.org/docs/20.2/integrate/api.html
-	    // This code also written with the help of the source code
-	    // to know the methods in interface WebswingShutdownListener
-	    // and the import statements required for the methods.
-	    // and then call System.exit(0) on top of usual applet
-	    // behaviour to make sure we get rid of the applet
-	    // "application" that webswing launched for us (it took
-	    // the applet code and ran it, presumably like a java
-	    // program, so a System.exit call may be warranted).
+	    // This code also written with the help of webswing's
+	    // source code to know the methods in interface
+	    // WebswingShutdownListener and the import statements
+	    // required for these methods.
+	    // After stop() and destroy(), we call System.exit(0) on
+	    // top of usual applet behaviour to make sure we get rid
+	    // of the applet "application" that webswing launched for
+	    // us (it took the applet code and ran it, presumably like
+	    // a java program, so a System.exit call may be warranted,
+	    // whereas System.exit() isn't called on a regular applet).
 	    WebswingUtil.getWebswingApi().addShutdownListener(new WebswingShutdownListener() {
-		    // These are official API comments for info
+		    // These are official webswing API comments for info
 		    /**
 		     * Invoked before Webswing requests application to exit.
@@ -614,6 +610,13 @@
 			// We're like the browser now and so we should
 			// honour the above contract.
-
-			System.err.println("------- WebswingShutdownListener.onShutdown() - our custom behaviour");
+			if (verbosity_ >= 3) {
+			    System.err.println("------- GsdlCollageApplet WebswingShutdownListener.onShutdown() - our custom behaviour");
+			    
+			    // This message is sent to JavaScript too late: webpage has already
+			    // finished unloading and the JS webswingInstance can't receive msgs.
+			    // if(isWebswing && isRunAsApplet) {
+			    //    WebswingUtil.getWebswingApi().sendActionEvent("javaToWebswingJSConsoleLog", "GsdlCollageApplet running as webswing applet - quitting now", null);
+			    // }
+			}
 			stop();
 			destroy();
@@ -623,7 +626,7 @@
 			// webswing.  And this handler/webswing stands
 			// in place of a browser and controls what
-			// Ought to happen if a browser doesn't take
+			// *ought* to happen if a browser doesn't take
 			// care of the applet life cycle and we ought
-			// to do it.
+			// to do it (here in the webswing handler).
 			System.exit(0);
 		    }
@@ -631,28 +634,4 @@
 	}
 	
-	/*
-	System.err.println("XXX App width: " + this.getWidth());
-	System.err.println("XXX App height: " + this.getHeight());
-
-	
-	// webswing applet doesn't have dimensions set because there's no applet element setting it
-	// so we need to set the size on the Collage Applet if launched with webswing and run in applet mode
-	if(isWebswing && isRunAsApplet) {	    
-	    //this.setPreferredSize(new Dimension(X_DIM(), Y_DIM()));
-	    this.setSize(X_DIM(), Y_DIM());
-	    this.resize(X_DIM(), Y_DIM());
-
-	    System.err.println("@@@@ App width: " + this.getWidth());
-	    System.err.println("@@@@ App height: " + this.getHeight());
-	    
-	    if(!this.isShowing()) {
-		System.err.println("@@@@ The webswing Applet isn't showing!");
-		this.setVisible(true);
-	    }
-	    if(!this.isShowing()) {
-		System.err.println("@@@@ The webswing Applet is STILL not showing!");
-	    }
-	}
-	*/
 	    
 	MediaTracker trk = new  MediaTracker(this);
@@ -665,12 +644,20 @@
 					    image_url, href_musthave, image_mustnothave, 
 					    image_ignore, imageType_,document_root,verbosity_,trk);
-
-	if(isShowing() && isDisplayable()) { //The case if(!(isRunAsApplet && isWebswing)) {
-	    System.err.println("**** Creating display thread");
+	// If GsdlCollageApplet is launched as a *webswing applet*, it
+	// doesn't have dimensions, isn't showing nor is it even
+	// displayable at this point in the code. Only when webswing
+	// resizes the GsdlCollageApplet Component, does it have
+	// dimensions and do we know for sure it is showing.
+	if(isShowing() && isDisplayable()) { // case of: if(!(isRunAsApplet && isWebswing)) {
+	    if (verbosity_ >= 4) {
+		System.err.println("**** Creating display thread");
+	    }
 	    // starts the display image thread with the currently downloaded images
 	    display_thread_ = new DisplayImages(this, download_images_,isJava2_, bgcolor_);
 	} else {
-	    System.err.println("**** GsdlCollageApplet.init() - display_thread_ not yet showing.");
-	    System.err.println("**** Will create and start display_thread_ later, in ComponentListener.resize()");
+	    if (verbosity_ >= 4) {
+		System.err.println("**** GsdlCollageApplet.init() - display_thread_ not yet showing.");
+		System.err.println("**** Will create and start display_thread_ later, in ComponentListener.resize()");
+	    }
 	}
 	// The display_thread_ needs the component showing before it can be started up.
@@ -688,15 +675,21 @@
 
     public void componentHidden(ComponentEvent e) {
-        System.err.println(e.getComponent().getClass().getName() + " --- Hidden");
+	if (verbosity_ >= 4) {
+	    System.err.println(e.getComponent().getClass().getName() + " --- Hidden");
+	}
     }
 
     public void componentMoved(ComponentEvent e) {
-	System.err.println(e.getComponent().getClass().getName() + " --- Moved");
+	if (verbosity_ >= 4) {
+	    System.err.println(e.getComponent().getClass().getName() + " --- Moved");
+	}
     }
 
     public void componentResized(ComponentEvent e) {
-	System.err.println(e.getComponent().getClass().getName() + " --- Resized");
-	
 	if(display_thread_ == null) {
+	    if (verbosity_ >= 4) {
+		System.err.println(e.getComponent().getClass().getName() + " --- Resized");
+		System.err.println("Ready to instantiate display thread");
+	    }
 	    display_thread_ = new DisplayImages(this, download_images_,isJava2_, bgcolor_);
 	    display_thread_.start();
@@ -704,7 +697,10 @@
     }
 
-    public void componentShown(ComponentEvent e) {
-	System.err.println("XXXXX" + e.getComponent().getClass().getName() + " --- Shown");
+    public void componentShown(ComponentEvent e) {	
 	if(display_thread_ == null) {
+	    if (verbosity_ >= 4) {
+		System.err.println("@@@ " + e.getComponent().getClass().getName() + " --- Shown");
+		System.err.println("GsdlCollageApplet ready to instantiate display thread");
+	    }
 	    display_thread_ = new DisplayImages(this, download_images_,isJava2_, bgcolor_);
 	    display_thread_.start();
@@ -718,4 +714,8 @@
     // TODO: Do I need to follow
     // https://stackoverflow.com/questions/5861894/how-to-synchronize-or-lock-upon-variables-in-java
+    // I just followed the Java API's recommendations about what to do
+    // as replacement around Thread.stop() and Thread.destroy() being
+    // deprecated (note: not Applet.stop() and
+    // Applet.destroy(). https://docs.oracle.com/javase/8/docs/api/java/lang/Thread.html#stop--
     public void stopRunning() {
 	if(verbosity_ >= 3) {
@@ -741,4 +741,5 @@
     }
 
+    // Applet's mouseDown() is deprecated, so we implement mousePressed
     protected class CollageMouseAdapter extends MouseAdapter {
  
@@ -748,6 +749,4 @@
     public void mousePressed(MouseEvent e)
     {
-
-	System.err.println("Mouse pressed");
 	int x = e.getX();
 	int y = e.getY();
@@ -782,5 +781,5 @@
 		    System.err.println("@@@GsdlCollageApplet.CollageMouseAdapter.mousePressed()"
 		       + "\n\topening url " + from_url + "\n\t"
-		       + "for non-applet and non-webswing application is not yet implemented.");
+		       + "for non-applets and non-webswing applications is not yet implemented.");
 		}
 	    } 
@@ -790,5 +789,4 @@
 
 	}
-        //return true;
     }
     }
@@ -797,7 +795,4 @@
     public void start() 
     {
-	// starts the display image thread with the currently downloaded images
-	//display_thread_ = new DisplayImages(this, download_images_,isJava2_, bgcolor_);
-	//this.setVisible(true);	
 	download_thread_.start();	
 
@@ -838,25 +833,27 @@
     public void stop() 
     {
-	System.err.println("\n\n*** Stopping collage Applet: stopping threads...");
+	if(verbosity_ >= 3) {
+	    System.err.println("\n\n@@@ GsdlCollageApplet.stop() called: stopping threads...");
+	}
 	//download_thread_.stop();
 	//display_thread_.stop();
 	stopRunning();
 	// TODO: maybe we want to unset the interrupt variable on the threads to restart
-	// on start() getting called? No: we system.exit() in the webswing shutdown handler
-	
-	//download_thread_ = null;
-	//display_thread_ = null;
-	
-    }
-
-    /** Destroys threads for downloading and displaying images */
+	// on start() getting called? No: because we system.exit() in the webswing
+	// shutdown handler we implemented.	
+    }
+
+    /** Destroys threads for downloading and displaying images Java
+     * API method specification for destroy(): "Called by the browser
+     * or applet viewer to inform this applet that it is being
+     * reclaimed and that it should destroy any resources that it has
+     * allocated. The stop method will always be called before
+     * destroy."
+     */
     public void destroyed() 
     {
-
-	System.err.println("@@@@@@@@@ GsdlCollageApplet.destroy() called");
-
-	// Let's be sure to have stopped running
-	//stopRunning();
-	
+	if(verbosity_ >= 3) {
+	    System.err.println("@@@@@@@@@ GsdlCollageApplet.destroy() called");
+	}
 	download_thread_ = null;
 	
@@ -887,9 +884,6 @@
 		System.err.println("Applet still trying to paint!!");
 	    }
-
-	
-	
-    }
-
+	
+    }
   
     
Index: main/trunk/greenstone3/src/java/org/greenstone/applet/phind/JPhind.java
===================================================================
--- main/trunk/greenstone3/src/java/org/greenstone/applet/phind/JPhind.java	(revision 38936)
+++ main/trunk/greenstone3/src/java/org/greenstone/applet/phind/JPhind.java	(revision 38937)
@@ -350,8 +350,11 @@
 	add(resultPanel, BorderLayout.CENTER);
 
-	// status bar that applet has, but we want one also if we run JPhind as application
-	// And in fact, when webswing runs our applet, we never get a status bar. So we
-	// create a custom status bar now even if we're running as an applet.
-	// When this applet is run through the appletviewer we might end up with 2 status bars.
+	// Manual status bar to mimic applet's default one, in case we
+	// want one if we run Collage as application And in fact, when
+	// webswing runs our applet, we never get a status bar. So we
+	// can create a custom status bar now even if we're running as
+	// an applet.  When this applet is run through the
+	// appletviewer we might end up with 2 status bars.
+	
 	//if(!isRunAsApplet) {
 	    statusBar = new JLabel();
