JAL-2778 try another way to draw sequences with reduced synchronisation
authorkiramt <k.mourao@dundee.ac.uk>
Fri, 26 Jan 2018 16:32:50 +0000 (16:32 +0000)
committerkiramt <k.mourao@dundee.ac.uk>
Fri, 26 Jan 2018 16:32:50 +0000 (16:32 +0000)
src/jalview/datamodel/Alignment.java
src/jalview/datamodel/AlignmentI.java
src/jalview/gui/SeqCanvas.java

index 29e9dc8..baa8e83 100755 (executable)
@@ -36,6 +36,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.Vector;
+import java.util.function.Consumer;
 
 /**
  * Data structure to hold and manipulate a multiple sequence alignment
@@ -1912,4 +1913,11 @@ public class Alignment implements AlignmentI
   {
     hiddenCols = cols;
   }
+
+  @Override
+  public void forEachSequence(Consumer<SequenceI> c, int start, int end)
+  {
+    sequences.subList(start, end).forEach(c);
+  }
+
 }
index 084b80e..b076ea7 100755 (executable)
@@ -24,6 +24,7 @@ import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.function.Consumer;
 
 /**
  * Data structure to hold and manipulate a multiple sequence alignment
@@ -582,4 +583,6 @@ public interface AlignmentI extends AnnotatedCollectionI
 
   public void setHiddenColumns(HiddenColumns cols);
 
+  public void forEachSequence(Consumer<SequenceI> c, int start, int end);
+
 }
index 36ec08f..1be4728 100755 (executable)
@@ -43,6 +43,7 @@ import java.awt.Shape;
 import java.awt.image.BufferedImage;
 import java.beans.PropertyChangeEvent;
 import java.util.List;
+import java.util.function.Consumer;
 
 import javax.swing.JComponent;
 
@@ -1098,71 +1099,97 @@ public class SeqCanvas extends JComponent implements ViewportListenerI
    * @param yOffset
    *          vertical offset at which to draw (for wrapped alignments)
    */
-  private void draw(Graphics g, int startRes, int endRes, int startSeq,
-          int endSeq, int offset)
+  private void draw(final Graphics g, final int startRes, final int endRes,
+          final int startSeq, final int endSeq, final int offset)
   {
-    int charHeight = av.getCharHeight();
-    int charWidth = av.getCharWidth();
-
     g.setFont(av.getFont());
     seqRdr.prepare(g, av.isRenderGaps());
 
-    SequenceI nextSeq;
-
-    // / First draw the sequences
-    // ///////////////////////////
-    for (int i = startSeq; i <= endSeq; i++)
+    // First draw the sequences
+    av.getAlignment().forEachSequence(new Consumer<SequenceI>()
     {
-      nextSeq = av.getAlignment().getSequenceAt(i);
-      if (nextSeq == null)
-      {
-        // occasionally, a race condition occurs such that the alignment row is
-        // empty
-        continue;
-      }
-      seqRdr.drawSequence(nextSeq, av.getAlignment().findAllGroups(nextSeq),
-              startRes, endRes, offset + ((i - startSeq) * charHeight));
+      int i = startSeq;
 
-      if (av.isShowSequenceFeatures())
+      @Override
+      public void accept(SequenceI s)
       {
-        fr.drawSequence(g, nextSeq, startRes, endRes,
-                offset + ((i - startSeq) * charHeight), false);
+        int heightPosition = offset + ((i - startSeq) * av.getCharHeight());
+        drawSequence(s, g, startRes, endRes, heightPosition, i);
+        i++;
       }
+    }, startSeq, endSeq + 1);
 
-      /*
-       * highlight search Results once sequence has been drawn
-       */
-      if (av.hasSearchResults())
+    // now selection groups
+    if (av.getSelectionGroup() != null
+            || av.getAlignment().getGroups().size() > 0)
+    {
+      drawGroupsBoundaries(g, startRes, endRes, startSeq, endSeq, offset);
+    }
+
+  }
+
+  /**
+   * Draw a single sequence
+   * 
+   * @param nextSeq
+   *          the next sequence to draw
+   * @param g
+   *          graphics context
+   * @param startRes
+   *          offset of the first column in the visible region (0..)
+   * @param endRes
+   *          offset of the last column in the visible region (0..)
+   * @param heightPosition
+   *          vertical location of the sequence in the alignment
+   * @param i
+   *          index of sequence
+   */
+  private void drawSequence(SequenceI nextSeq, Graphics g, int startRes,
+          int endRes, int heightPosition, int i)
+  {
+    int charWidth = av.getCharWidth();
+
+    if (nextSeq == null)
+    {
+      // occasionally, a race condition occurs such that the alignment row is
+      // empty
+      // TODO Don't think this will happen any more?
+      return;
+    }
+    seqRdr.drawSequence(nextSeq, av.getAlignment().findAllGroups(nextSeq),
+            startRes, endRes, heightPosition);
+
+    if (av.isShowSequenceFeatures())
+    {
+      fr.drawSequence(g, nextSeq, startRes, endRes, heightPosition, false);
+    }
+
+    /*
+     * highlight search Results once sequence has been drawn
+     */
+    if (av.hasSearchResults())
+    {
+      SearchResultsI searchResults = av.getSearchResults();
+      int[] visibleResults = searchResults.getResults(nextSeq, startRes,
+              endRes);
+      if (visibleResults != null)
       {
-        SearchResultsI searchResults = av.getSearchResults();
-        int[] visibleResults = searchResults.getResults(nextSeq,
-                startRes, endRes);
-        if (visibleResults != null)
+        for (int r = 0; r < visibleResults.length; r += 2)
         {
-          for (int r = 0; r < visibleResults.length; r += 2)
-          {
-            seqRdr.drawHighlightedText(nextSeq, visibleResults[r],
-                    visibleResults[r + 1], (visibleResults[r] - startRes)
-                            * charWidth, offset
-                            + ((i - startSeq) * charHeight));
-          }
+          seqRdr.drawHighlightedText(nextSeq, visibleResults[r],
+                  visibleResults[r + 1],
+                  (visibleResults[r] - startRes) * charWidth,
+                  heightPosition);
         }
       }
-
-      if (av.cursorMode && cursorY == i && cursorX >= startRes
-              && cursorX <= endRes)
-      {
-        seqRdr.drawCursor(nextSeq, cursorX, (cursorX - startRes) * charWidth,
-                offset + ((i - startSeq) * charHeight));
-      }
     }
 
-    if (av.getSelectionGroup() != null
-            || av.getAlignment().getGroups().size() > 0)
+    if (av.cursorMode && cursorY == i && cursorX >= startRes
+            && cursorX <= endRes)
     {
-      drawGroupsBoundaries(g, startRes, endRes, startSeq, endSeq, offset);
+      seqRdr.drawCursor(nextSeq, cursorX, (cursorX - startRes) * charWidth,
+              heightPosition);
     }
-
   }
 
   void drawGroupsBoundaries(Graphics g1, int startRes, int endRes,