JAL-3878 Wire web services logic to UI elements.
[jalview.git] / src / jalview / gui / Desktop.java
index a13a38b..0c3b553 100644 (file)
@@ -1,19 +1,19 @@
 /*
  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
  * Copyright (C) $$Year-Rel$$ The Jalview Authors
- * 
+ *
  * This file is part of Jalview.
- * 
+ *
  * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License 
+ * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation, either version 3
  * of the License, or (at your option) any later version.
- *  
- * Jalview is distributed in the hope that it will be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty 
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  * PURPOSE.  See the GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
  * The Jalview Authors are detailed in the 'AUTHORS' file.
@@ -59,8 +59,11 @@ import java.util.Hashtable;
 import java.util.List;
 import java.util.ListIterator;
 import java.util.Vector;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
 import java.util.concurrent.Semaphore;
 
 import javax.swing.AbstractAction;
@@ -121,16 +124,16 @@ import jalview.util.BrowserLauncher;
 import jalview.util.ImageMaker.TYPE;
 import jalview.util.MessageManager;
 import jalview.util.Platform;
-import jalview.util.ShortcutKeyMaskExWrapper;
 import jalview.util.UrlConstants;
 import jalview.viewmodel.AlignmentViewport;
+import jalview.ws.WSDiscovererI;
 import jalview.ws.params.ParamManager;
 import jalview.ws.utils.UrlDownloadClient;
 
 /**
  * Jalview Desktop
- * 
- * 
+ *
+ *
  * @author $author$
  * @version $Revision: 1.155 $
  */
@@ -163,6 +166,7 @@ public class Desktop extends GDesktop
 
   public static HashMap<String, FileWriter> savingFiles = new HashMap<String, FileWriter>();
 
+  @SuppressWarnings("deprecation")
   private JalviewChangeSupport changeSupport = new JalviewChangeSupport();
 
   /**
@@ -176,6 +180,7 @@ public class Desktop extends GDesktop
    * @param listener
    * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.beans.PropertyChangeListener)
    */
+  @Deprecated
   public void addJalviewPropertyChangeListener(
           PropertyChangeListener listener)
   {
@@ -188,6 +193,7 @@ public class Desktop extends GDesktop
    * @see jalview.gui.JalviewChangeSupport#addJalviewPropertyChangeListener(java.lang.String,
    *      java.beans.PropertyChangeListener)
    */
+  @Deprecated
   public void addJalviewPropertyChangeListener(String propertyName,
           PropertyChangeListener listener)
   {
@@ -200,6 +206,7 @@ public class Desktop extends GDesktop
    * @see jalview.gui.JalviewChangeSupport#removeJalviewPropertyChangeListener(java.lang.String,
    *      java.beans.PropertyChangeListener)
    */
+  @Deprecated
   public void removeJalviewPropertyChangeListener(String propertyName,
           PropertyChangeListener listener)
   {
@@ -219,7 +226,7 @@ public class Desktop extends GDesktop
    * Answers an 'application scope' singleton instance of this class. Separate
    * SwingJS 'applets' running in the same browser page will each have a
    * distinct instance of Desktop.
-   * 
+   *
    * @return
    */
   public static Desktop getInstance()
@@ -470,7 +477,7 @@ public class Desktop extends GDesktop
       if (!Platform.isJS())
       /**
        * Java only
-       * 
+       *
        * @j2sIgnore
        */
       {
@@ -487,8 +494,6 @@ public class Desktop extends GDesktop
           // disabled for SeqCanvasTest
           checkURLLinks();
 
-          checkURLLinks();
-
           // Spawn a thread that shows the splashscreen
 
           SwingUtilities.invokeLater(new Runnable()
@@ -574,7 +579,7 @@ public class Desktop extends GDesktop
   /**
    * Answers true if user preferences to enable experimental features is True
    * (on), else false
-   * 
+   *
    * @return
    */
   public boolean showExperimental()
@@ -676,7 +681,7 @@ public class Desktop extends GDesktop
 
   /**
    * recover the last known dimensions for a jalview window
-   * 
+   *
    * @param windowName
    *          - empty string is desktop, all other windows have unique prefix
    * @return null or last known dimensions scaled to current geometry (if last
@@ -776,7 +781,7 @@ public class Desktop extends GDesktop
 //  /**
 //   * Add an internal frame to the Jalview desktop that is allowed to be resized,
 //   * has a minimum size of 300px and might or might not be visible
-//   * 
+//   *
 //   * @param frame
 //   *          Frame to show
 //   * @param title
@@ -802,7 +807,7 @@ public class Desktop extends GDesktop
 //  /**
 //   * Add an internal frame to the Jalview desktop that is visible, has a minimum
 //   * size of 300px, and may or may not be resizable
-//   * 
+//   *
 //   * @param frame
 //   *          Frame to show
 //   * @param title
@@ -827,7 +832,7 @@ public class Desktop extends GDesktop
   /**
    * Adds and opens the given frame to the desktop that is visible, allowed to
    * resize, and has a 300px minimum width.
-   * 
+   *
    * @param frame
    *          Frame to show
    * @param title
@@ -841,14 +846,15 @@ public class Desktop extends GDesktop
           final JInternalFrame frame, String title, int w, int h)
   {
     // 58 classes
-    getInstance().addFrame(frame, title, Desktop.FRAME_MAKE_VISIBLE, w, h,
+
+    addInternalFrame(frame, title, Desktop.FRAME_MAKE_VISIBLE, w, h,
             FRAME_ALLOW_RESIZE, FRAME_SET_MIN_SIZE_300);
   }
 
   /**
    * Add an internal frame to the Jalview desktop that may optionally be
    * visible, resizable, and allowed to be any size
-   * 
+   *
    * @param frame
    *          Frame to show
    * @param title
@@ -869,13 +875,25 @@ public class Desktop extends GDesktop
           final JInternalFrame frame, String title, boolean makeVisible,
           int w, int h, boolean resizable, boolean ignoreMinSize)
   {
-    // 15 classes
-    getInstance().addFrame(frame, title, makeVisible, w, h, resizable,
+    // 15 classes call this method directly.
+
+    // TODO: allow callers to determine X and Y position of frame (eg. via
+    // bounds object).
+    // TODO: consider fixing method to update entries in the window submenu with
+    // the current window title
+
+    frame.setTitle(title);
+    if (frame.getWidth() < 1 || frame.getHeight() < 1)
+    {
+      frame.setSize(w, h);
+    }
+    if (getInstance() != null)
+      getInstance().addFrame(frame, makeVisible, resizable,
             ignoreMinSize);
   }
 
   // These can now by put into a single int flag, if desired:
-  
+
   public final static boolean FRAME_MAKE_VISIBLE = true;
 
   public final static boolean FRAME_NOT_VISIBLE = false;
@@ -888,36 +906,18 @@ public class Desktop extends GDesktop
 
   public final static boolean FRAME_SET_MIN_SIZE_300 = false;
 
-  private void addFrame(JInternalFrame frame, String title,
-          boolean makeVisible, int w, int h, boolean resizable,
+  private void addFrame(JInternalFrame frame,
+          boolean makeVisible, boolean resizable,
           boolean ignoreMinSize)
   {
-    // TODO: allow callers to determine X and Y position of frame (eg. via
-    // bounds object).
-    // TODO: consider fixing method to update entries in the window submenu with
-    // the current window title
-
-    frame.setTitle(title);
-    if (frame.getWidth() < 1 || frame.getHeight() < 1)
-    {
-      frame.setSize(w, h);
-    }
-    // THIS IS A PUBLIC STATIC METHOD, SO IT MAY BE CALLED EVEN IN
-    // A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
-    // IF JALVIEW IS RUNNING HEADLESS
-    // ///////////////////////////////////////////////
-    if (Jalview.isHeadlessMode())
-    {
-      return;
-    }
 
     openFrameCount++;
-    
+
     boolean isEmbedded = (Platform.getEmbeddedAttribute(frame, "id") != null);
     boolean hasEmbeddedSize = (Platform.getDimIfEmbedded(frame, -1, -1) != null);
     // Web page embedding allows us to ignore minimum size
     ignoreMinSize |= hasEmbeddedSize;
-    
+
     if (!ignoreMinSize)
     {
       // Set default dimension for Alignment Frame window.
@@ -931,7 +931,7 @@ public class Desktop extends GDesktop
       } else {
         frame.setMinimumSize(
                 new Dimension(DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT));
-        
+
       }
     }
 
@@ -948,10 +948,10 @@ public class Desktop extends GDesktop
     }
 
     /*
-     * add an entry for the new frame in the Window menu 
+     * add an entry for the new frame in the Window menu
      * (and remove it when the frame is closed)
      */
-    final JMenuItem menuItem = new JMenuItem(title);
+    final JMenuItem menuItem = new JMenuItem(frame.getTitle());
     frame.addInternalFrameListener(new InternalFrameAdapter()
     {
       @Override
@@ -1033,7 +1033,7 @@ public class Desktop extends GDesktop
   /**
    * Add key bindings to a JInternalFrame so that Ctrl-W and Cmd-W will close
    * the window
-   * 
+   *
    * @param frame
    */
   private static void setKeyBindings(JInternalFrame frame)
@@ -1098,7 +1098,7 @@ public class Desktop extends GDesktop
 
   /**
    * DOCUMENT ME!
-   * 
+   *
    * @param evt
    *          DOCUMENT ME!
    */
@@ -1163,7 +1163,7 @@ public class Desktop extends GDesktop
 
   /**
    * DOCUMENT ME!
-   * 
+   *
    * @param e
    *          DOCUMENT ME!
    */
@@ -1216,7 +1216,7 @@ public class Desktop extends GDesktop
 
   /**
    * Shows a dialog for input of a URL at which to retrieve alignment data
-   * 
+   *
    * @param viewport
    */
   @Override
@@ -1244,7 +1244,7 @@ public class Desktop extends GDesktop
     else
     /**
      * Java only
-     * 
+     *
      * @j2sIgnore
      */
     {
@@ -1336,7 +1336,7 @@ public class Desktop extends GDesktop
 
   /**
    * Opens the CutAndPaste window for the user to paste an alignment in to
-   * 
+   *
    * @param viewPanel
    *          - if not null, the pasted alignment is added to the current
    *          alignment; if null, to a new alignment window
@@ -1404,7 +1404,7 @@ public class Desktop extends GDesktop
 
   /**
    * DOCUMENT ME!
-   * 
+   *
    * @param e
    *          DOCUMENT ME!
    */
@@ -1425,7 +1425,7 @@ public class Desktop extends GDesktop
    * Returns the html text for the About screen, including any available version
    * number, build details, author details and citation reference, but without
    * the enclosing {@code html} tags
-   * 
+   *
    * @return
    */
   public String getAboutMessage()
@@ -1489,7 +1489,7 @@ public class Desktop extends GDesktop
       else
       /**
        * Java only
-       * 
+       *
        * @j2sIgnore
        */
       {
@@ -1549,7 +1549,7 @@ public class Desktop extends GDesktop
 
   /*
    * (non-Javadoc)
-   * 
+   *
    * @seejalview.jbgui.GDesktop#garbageCollect_actionPerformed(java.awt.event.
    * ActionEvent)
    */
@@ -1564,7 +1564,7 @@ public class Desktop extends GDesktop
 
   /*
    * (non-Javadoc)
-   * 
+   *
    * @see
    * jalview.jbgui.GDesktop#showMemusage_actionPerformed(java.awt.event.ActionEvent
    * )
@@ -1577,7 +1577,7 @@ public class Desktop extends GDesktop
 
   /*
    * (non-Javadoc)
-   * 
+   *
    * @see
    * jalview.jbgui.GDesktop#showConsole_actionPerformed(java.awt.event.ActionEvent
    * )
@@ -1592,7 +1592,7 @@ public class Desktop extends GDesktop
 
   /**
    * control whether the java console is visible or not
-   * 
+   *
    * @param selected
    */
   void showConsole(boolean selected)
@@ -1615,7 +1615,8 @@ public class Desktop extends GDesktop
       return;
     }
 
-    AlignmentViewport source = null, target = null;
+    AlignViewportI source = null;
+    AlignViewportI target = null;
     if (frames[0] instanceof AlignFrame)
     {
       source = ((AlignFrame) frames[0]).getCurrentView();
@@ -1686,7 +1687,7 @@ public class Desktop extends GDesktop
 
   /**
    * DOCUMENT ME!
-   * 
+   *
    * @param e
    *          DOCUMENT ME!
    */
@@ -1950,7 +1951,7 @@ public class Desktop extends GDesktop
   }
 
   /**
-   * 
+   *
    * @param alignmentId
    *          - if null, all sets are returned
    * @return all AlignmentPanels concerning the alignmentId sequence set
@@ -1990,7 +1991,7 @@ public class Desktop extends GDesktop
 
   /**
    * get all the viewports on an alignment.
-   * 
+   *
    * @param sequenceSetId
    *          unique alignment id (may be null - all viewports returned in that
    *          case)
@@ -2035,7 +2036,7 @@ public class Desktop extends GDesktop
 
   /**
    * Explode the views in the given frame into separate AlignFrame
-   * 
+   *
    * @param af
    */
   public static void explodeViews(AlignFrame af)
@@ -2103,7 +2104,7 @@ public class Desktop extends GDesktop
    * identifier back in to this frame as additional views, and close the
    * expanded views. Note the expanded frames may themselves have multiple
    * views. We take the lot.
-   * 
+   *
    * @param source
    */
   public void gatherViews(AlignFrame source)
@@ -2168,7 +2169,7 @@ public class Desktop extends GDesktop
   /**
    * Checks the given url to see if it gives a response indicating that the user
    * should be informed of a new questionnaire.
-   * 
+   *
    * @param url
    */
   public void checkForQuestionnaire(String url)
@@ -2261,7 +2262,7 @@ public class Desktop extends GDesktop
    * Proxy class for JDesktopPane which optionally displays the current memory
    * usage and highlights the desktop area with a red bar if free memory runs
    * low.
-   * 
+   *
    * @author AMW
    */
   public class MyDesktopPane extends JDesktopPane implements Runnable
@@ -2356,7 +2357,7 @@ public class Desktop extends GDesktop
 
   /**
    * Accessor method to quickly get all the AlignmentFrames loaded.
-   * 
+   *
    * @return an array of AlignFrame, or null if none found
    */
   public static AlignFrame[] getAlignFrames()
@@ -2406,7 +2407,7 @@ public class Desktop extends GDesktop
 
   /**
    * Returns an array of any AppJmol frames in the Desktop (or null if none).
-   * 
+   *
    * @return
    */
   public GStructureViewer[] getJmols()
@@ -2469,7 +2470,7 @@ public class Desktop extends GDesktop
       /*
        * We allow only one console at a time, so that AlignFrame menu option
        * 'Calculate | Run Groovy script' is unambiguous.
-       * Disable 'Groovy Console', and enable 'Run script', when the console is 
+       * Disable 'Groovy Console', and enable 'Run script', when the console is
        * opened, and the reverse when it is closed
        */
       Window window = (Window) groovyConsole.getFrame();
@@ -2522,7 +2523,7 @@ public class Desktop extends GDesktop
 
   /**
    * Enable or disable 'Run Groovy script' in AlignFrame calculate menus
-   * 
+   *
    * @param enabled
    *          true if Groovy console is open
    */
@@ -2553,7 +2554,7 @@ public class Desktop extends GDesktop
 
   /*
    * (non-Javadoc)
-   * 
+   *
    * @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
    */
   @Override
@@ -2582,9 +2583,16 @@ public class Desktop extends GDesktop
     }
   }
 
+  @Override
+  public void removeProgressBar(long id)
+  {
+    //TODO
+    throw new UnsupportedOperationException("not implemented");
+  }
+
   /*
    * (non-Javadoc)
-   * 
+   *
    * @see jalview.gui.IProgressIndicator#registerHandler(long,
    * jalview.gui.IProgressIndicatorHandler)
    */
@@ -2623,7 +2631,7 @@ public class Desktop extends GDesktop
   }
 
   /**
-   * 
+   *
    * @return true if any progress bars are still active
    */
   @Override
@@ -2640,7 +2648,7 @@ public class Desktop extends GDesktop
    * This will return the first AlignFrame holding the given viewport instance.
    * It will break if there are more than one AlignFrames viewing a particular
    * av.
-   * 
+   *
    * @param viewport
    * @return alignFrame for viewport
    */
@@ -2675,7 +2683,7 @@ public class Desktop extends GDesktop
 
   /**
    * check if jalview GUI is being operated programmatically
-   * 
+   *
    * @return inBatchMode
    */
   public boolean isInBatchMode()
@@ -2685,7 +2693,7 @@ public class Desktop extends GDesktop
 
   /**
    * set flag if jalview GUI is being operated programmatically
-   * 
+   *
    * @param inBatchMode
    */
   public void setInBatchMode(boolean inBatchMode)
@@ -2700,10 +2708,13 @@ public class Desktop extends GDesktop
 
   public void startServiceDiscovery(boolean blocking)
   {
-    boolean alive = true;
-    Thread t0 = null, t1 = null, t2 = null;
+    System.out.println("Starting service discovery");
+    var tasks = new ArrayList<Future<?>>();
     // JAL-940 - JALVIEW 1 services are now being EOLed as of JABA 2.1 release
-    if (true)
+
+    System.out.println("loading services");
+
+    /** @j2sIgnore */
     {
       // todo: changesupport handlers need to be transferred
       if (discoverer == null)
@@ -2714,46 +2725,47 @@ public class Desktop extends GDesktop
       }
       // JAL-940 - disabled JWS1 service configuration - always start discoverer
       // until we phase out completely
-      (t0 = new Thread(discoverer)).start();
+      var f = new FutureTask<Void>(discoverer, null);
+      new Thread(f).start();
+      tasks.add(f);
     }
 
     if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
     {
-      t2 = jalview.ws.jws2.Jws2Discoverer.getInstance()
-              .startDiscoverer(changeSupport);
+      tasks.add(jalview.ws.jws2.Jws2Discoverer.getInstance().startDiscoverer());
     }
-    Thread t3 = null;
+    if (Cache.getDefault("SHOW_SLIVKA_SERVICES", true))
     {
-      // TODO: do rest service discovery
+      tasks.add(jalview.ws2.slivka.SlivkaWSDiscoverer.getInstance().startDiscoverer());
     }
     if (blocking)
     {
-      while (alive)
-      {
+      for (Future<?> task : tasks) {
         try
         {
-          Thread.sleep(15);
+          // block until all discovery tasks are done
+          task.get();
         } catch (Exception e)
         {
+          e.printStackTrace();
         }
-        alive = (t1 != null && t1.isAlive()) || (t2 != null && t2.isAlive())
-                || (t3 != null && t3.isAlive())
-                || (t0 != null && t0.isAlive());
       }
     }
   }
 
   /**
    * called to check if the service discovery process completed successfully.
-   * 
+   *
    * @param evt
    */
   protected void JalviewServicesChanged(PropertyChangeEvent evt)
   {
     if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
     {
-      final String ermsg = jalview.ws.jws2.Jws2Discoverer.getInstance()
-              .getErrorMessages();
+      final WSDiscovererI discoverer = jalview.ws.jws2.Jws2Discoverer
+          .getInstance();
+      final String ermsg = discoverer.getErrorMessages();
+      // CONFLICT:ALT:?     final String ermsg = jalview.ws.jws2.Jws2Discoverer.getInstance()
       if (ermsg != null)
       {
         if (Cache.getDefault("SHOW_WSDISCOVERY_ERRORS", true))
@@ -2769,16 +2781,16 @@ public class Desktop extends GDesktop
 
                 /*
                  * JalviewDialog jd =new JalviewDialog() {
-                 * 
+                 *
                  * @Override protected void cancelPressed() { // TODO
                  * Auto-generated method stub
-                 * 
+                 *
                  * }@Override protected void okPressed() { // TODO
                  * Auto-generated method stub
-                 * 
+                 *
                  * }@Override protected void raiseClosed() { // TODO
                  * Auto-generated method stub
-                 * 
+                 *
                  * } }; jd.initDialogFrame(new
                  * JLabel("<html><table width=\"450\"><tr><td>" + ermsg +
                  * "<br/>It may be that you have invalid JABA URLs in your web service preferences,"
@@ -2788,7 +2800,7 @@ public class Desktop extends GDesktop
                  * " Tools->Preferences dialog box to change them.</td></tr></table></html>"
                  * ), true, true, "Web Service Configuration Problem", 450,
                  * 400);
-                 * 
+                 *
                  * jd.waitForInput();
                  */
                 JvOptionPane.showConfirmDialog(desktopPane,
@@ -2823,7 +2835,7 @@ public class Desktop extends GDesktop
    * start a thread to open a URL in the configured browser. Pops up a warning
    * dialog to the user if there is an exception when calling out to the browser
    * to open the URL.
-   * 
+   *
    * @param url
    */
   public static void showUrl(final String url)
@@ -2833,7 +2845,7 @@ public class Desktop extends GDesktop
 
   /**
    * Like showUrl but allows progress handler to be specified
-   * 
+   *
    * @param url
    * @param progress
    *          (null) or object implementing IProgressIndicator
@@ -2886,7 +2898,7 @@ public class Desktop extends GDesktop
 
   /**
    * static hyperlink handler proxy method for use by Jalview's internal windows
-   * 
+   *
    * @param e
    */
   public static void hyperlinkUpdate(HyperlinkEvent e)
@@ -2937,7 +2949,7 @@ public class Desktop extends GDesktop
 
   /**
    * add another dialog thread to the queue
-   * 
+   *
    * @param prompter
    */
   public void addDialogThread(final Runnable prompter)
@@ -2983,7 +2995,7 @@ public class Desktop extends GDesktop
    * Outputs an image of the desktop to file in EPS format, after prompting the
    * user for choice of Text or Lineart character rendering (unless a preference
    * has been set). The file name is generated as
-   * 
+   *
    * <pre>
    * Jalview_snapshot_nnnnn.eps where nnnnn is the current timestamp in milliseconds
    * </pre>
@@ -3020,7 +3032,7 @@ public class Desktop extends GDesktop
    * and location last time the view was expanded (if any). However it does not
    * remember the split pane divider location - this is set to match the
    * 'exploding' frame.
-   * 
+   *
    * @param sf
    */
   public void explodeViews(SplitFrame sf)
@@ -3048,7 +3060,7 @@ public class Desktop extends GDesktop
        * AlignmentPanel objects, including their AlignmentViewports, so the
        * cdna/protein relationships between the viewports is carried over to the
        * new split frames.
-       * 
+       *
        * explodedGeometry holds the (x, y) position of the previously exploded
        * SplitFrame, and the (width, height) of the AlignFrame component
        */
@@ -3098,7 +3110,7 @@ public class Desktop extends GDesktop
    * Gather expanded split frames, sharing the same pairs of sequence set ids,
    * back into the given SplitFrame as additional views. Note that the gathered
    * frames may themselves have multiple views.
-   * 
+   *
    * @param source
    */
   public void gatherViews(GSplitFrame source)
@@ -3170,9 +3182,9 @@ public class Desktop extends GDesktop
 
   /**
    * handles the payload of a drag and drop event.
-   * 
+   *
    * TODO refactor to desktop utilities class
-   * 
+   *
    * @param files
    *          - Data source strings extracted from the drop event
    * @param protocols
@@ -3407,7 +3419,7 @@ public class Desktop extends GDesktop
    * for either Jmol or Chimera) which are currently open. This may optionally
    * be restricted to viewers of a specified class, or viewers linked to a
    * specified alignment panel.
-   * 
+   *
    * @param apanel
    *          if not null, only return viewers linked to this panel
    * @param structureViewerClass