JAL-3446 from applet -- reload; also fixes some repaint issues
[jalview.git] / src / jalview / gui / PaintRefresher.java
index 4b40df0..7e203b2 100755 (executable)
@@ -1,70 +1,80 @@
 /*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.7)
- * Copyright (C) 2011 J Procter, AM Waterhouse, J Engelhardt, LM Lui, G Barton, M Clamp, S Searle
- *
+ * 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
- * 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
+ * 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 
  * 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/>.
+ * 
+ * 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.
  */
 package jalview.gui;
 
-import java.util.*;
-import java.util.List;
-
-import java.awt.*;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
 
-import jalview.datamodel.*;
+import java.awt.Component;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
 /**
- * DOCUMENT ME!
+ * Route datamodel/view update events for a sequence set to any display
+ * components involved TODO: JV3 refactor to abstract gui/view package
  * 
  * @author $author$
  * @version $Revision$
  */
 public class PaintRefresher
 {
-  static Hashtable components;
+  private static final int ALIGNMENT_CHANGED = 1 << 0;
+  private static final int VALIDATE_SEQUENCES = 1 << 1;
+  
+  static Map<String, List<Component>> components = new HashMap<>();
 
   /**
-   * DOCUMENT ME!
+   * Add the given component to those registered under the given sequence set
+   * id. Does nothing if already added.
    * 
    * @param comp
-   *          DOCUMENT ME!
    * @param al
-   *          DOCUMENT ME!
    */
   public static void Register(Component comp, String seqSetId)
   {
-    if (components == null)
-    {
-      components = new Hashtable();
-    }
-
     if (components.containsKey(seqSetId))
     {
-      Vector comps = (Vector) components.get(seqSetId);
+      List<Component> comps = components.get(seqSetId);
       if (!comps.contains(comp))
       {
-        comps.addElement(comp);
+        comps.add(comp);
       }
     }
     else
     {
-      Vector vcoms = new Vector();
-      vcoms.addElement(comp);
+      List<Component> vcoms = new ArrayList<>();
+      vcoms.add(comp);
       components.put(seqSetId, vcoms);
     }
   }
 
+  /**
+   * Remove this component from all registrations. Also removes a registered
+   * sequence set id if there are no remaining components registered against it.
+   * 
+   * @param comp
+   */
   public static void RemoveComponent(Component comp)
   {
     if (components == null)
@@ -72,15 +82,14 @@ public class PaintRefresher
       return;
     }
 
-    Enumeration en = components.keys();
-    while (en.hasMoreElements())
+    Iterator<String> it = components.keySet().iterator();
+    while (it.hasNext())
     {
-      String id = en.nextElement().toString();
-      Vector comps = (Vector) components.get(id);
+      List<Component> comps = components.get(it.next());
       comps.remove(comp);
-      if (comps.size() == 0)
+      if (comps.isEmpty())
       {
-        components.remove(id);
+        it.remove();
       }
     }
   }
@@ -93,41 +102,50 @@ public class PaintRefresher
   public static void Refresh(Component source, String id,
           boolean alignmentChanged, boolean validateSequences)
   {
-    if (components == null)
-    {
-      return;
-    }
-
-    Component comp;
-    Vector comps = (Vector) components.get(id);
+    List<Component> comps = components.get(id);
 
+    int mode = (alignmentChanged ? ALIGNMENT_CHANGED : 0) | (validateSequences ? VALIDATE_SEQUENCES : 0);
     if (comps == null)
     {
       return;
     }
+    repaintComponents(source, mode, comps.toArray(new Component[comps.size()]));
+  }
 
-    Enumeration e = comps.elements();
-    while (e.hasMoreElements())
+  public static void repaintComponents(Component source, int mode,
+          Component... comps)
+  {
+    for (int i = 0; i < comps.length; i++)
     {
-      comp = (Component) e.nextElement();
-
-      if (comp == source)
+      Component comp = comps[i];
+      if (comp == null)
       {
         continue;
       }
-
-      if (validateSequences && comp instanceof AlignmentPanel
-              && source instanceof AlignmentPanel)
+      if (comp instanceof AlignmentPanel)
       {
-        validateSequences(((AlignmentPanel) source).av.getAlignment(),
-                ((AlignmentPanel) comp).av.getAlignment());
+        if ((mode & VALIDATE_SEQUENCES) != 0 && source instanceof AlignmentPanel)
+        {
+          validateSequences(((AlignmentPanel) source).av.getAlignment(),
+                  ((AlignmentPanel) comp).av.getAlignment());
+        }
+        if ((mode & ALIGNMENT_CHANGED) != 0)
+        {
+          ((AlignmentPanel) comp).alignmentChanged();
+        }
       }
-
-      if (comp instanceof AlignmentPanel && alignmentChanged)
+      else if (comp instanceof IdCanvas)
       {
-        ((AlignmentPanel) comp).alignmentChanged();
+        // BH 2019.04.22 fixes JS problem of repaint() consolidation
+        // that occurs in JavaScript but not Java [JAL-3226]
+        ((IdCanvas) comp).setNoFastPaint();
+      }
+      else if (comp instanceof SeqCanvas)
+      {
+        // BH 2019.04.22 fixes JS problem of repaint() consolidation
+        // that occurs in JavaScript but not Java [JAL-3226]
+        ((SeqCanvas) comp).setNoFastPaint();
       }
-
       comp.repaint();
     }
   }
@@ -186,11 +204,11 @@ public class PaintRefresher
           {
             // raise an implementation warning here - not sure if this situation
             // will ever occur
-            System.err
-                    .println("IMPLEMENTATION PROBLEM: DATASET out of sync due to an insert whilst calling PaintRefresher.validateSequences(AlignmentI, ALignmentI)");
+            System.err.println(
+                    "IMPLEMENTATION PROBLEM: DATASET out of sync due to an insert whilst calling PaintRefresher.validateSequences(AlignmentI, ALignmentI)");
           }
-          List<SequenceI> alsq;
-          synchronized (alsq = comp.getSequences())
+          List<SequenceI> alsq = comp.getSequences();
+          synchronized (alsq)
           {
             alsq.add(i, a1[i]);
           }
@@ -238,30 +256,21 @@ public class PaintRefresher
 
   static AlignmentPanel[] getAssociatedPanels(String id)
   {
-    if (components == null)
-    {
-      return new AlignmentPanel[0];
-    }
-    ;
-    Vector comps = (Vector) components.get(id);
+    List<Component> comps = components.get(id);
     if (comps == null)
     {
       return new AlignmentPanel[0];
     }
-    ;
-    Vector tmp = new Vector();
-    int i, iSize = comps.size();
-    for (i = 0; i < iSize; i++)
+    List<AlignmentPanel> tmp = new ArrayList<>();
+    for (Component comp : comps)
     {
-      if (comps.elementAt(i) instanceof AlignmentPanel)
+      if (comp instanceof AlignmentPanel)
       {
-        tmp.addElement(comps.elementAt(i));
+        tmp.add((AlignmentPanel) comp);
       }
     }
-    AlignmentPanel[] result = new AlignmentPanel[tmp.size()];
-    tmp.toArray(result);
-
-    return result;
+    return tmp.toArray(new AlignmentPanel[tmp.size()]);
   }
 
+  
 }