JAL-3446 JAL-3401 from JAL-3253 HoldRepaint and SeqCanvas sizing issues.
authorBobHanson <hansonr@stolaf.edu>
Tue, 2 Jun 2020 23:23:42 +0000 (18:23 -0500)
committerBobHanson <hansonr@stolaf.edu>
Tue, 2 Jun 2020 23:23:42 +0000 (18:23 -0500)
- integrated changes from 0b573ed (gmungoc)

src/jalview/gui/AlignmentPanel.java
src/jalview/gui/IdCanvas.java
src/jalview/gui/PaintRefresher.java
src/jalview/gui/SeqCanvas.java
src/jalview/gui/SeqPanel.java
test/jalview/gui/SeqCanvasTest.java
test/jalview/ws/PDBSequenceFetcherTest.java
test/jalview/ws/jabaws/JalviewJabawsTestUtils.java

index 2b6d5a0..91b773e 100644 (file)
@@ -1068,8 +1068,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
   public int printWrappedAlignment(int pageWidth, int pageHeight, int pageNumber,
           Graphics g) throws PrinterException
   {
-    getSeqPanel().seqCanvas.calculateWrappedGeometry(getWidth(),
-            getHeight());
+    getSeqPanel().seqCanvas.calculateWrappedGeometry();
     int annotationHeight = 0;
     if (av.isShowAnnotation())
     {
@@ -1856,19 +1855,29 @@ public class AlignmentPanel extends GAlignmentPanel implements
 
   private boolean holdRepaint = false;
 
+  /**
+   * Called by IdCanvas and SeqPanel to defer painting until after JVP loading.
+   * 
+   * @return true if holding
+   */
   public boolean getHoldRepaint()
   {
     return holdRepaint;
   }
 
-  public void setHoldRepaint(boolean b)
+  /**
+   * Called by Jalview2xml while loading
+   * 
+   * @param tf
+   */
+  public void setHoldRepaint(boolean tf)
   {
-    if (holdRepaint == b)
+    if (holdRepaint == tf)
     {
       return;
     }
-    holdRepaint = b;
-    if (!b)
+    holdRepaint = tf;
+    if (!tf)
     {
       repaint();
     }
index 10c0787..14ae033 100755 (executable)
  */
 package jalview.gui;
 
+import jalview.datamodel.SequenceI;
+import jalview.viewmodel.ViewportListenerI;
+import jalview.viewmodel.ViewportRanges;
+
 import java.awt.BorderLayout;
 import java.awt.Color;
 import java.awt.Font;
@@ -33,10 +37,6 @@ import java.util.List;
 
 import javax.swing.JPanel;
 
-import jalview.datamodel.SequenceI;
-import jalview.viewmodel.ViewportListenerI;
-import jalview.viewmodel.ViewportRanges;
-
 /**
  * DOCUMENT ME!
  * 
@@ -59,7 +59,7 @@ public class IdCanvas extends JPanel implements ViewportListenerI
 
   int imgHeight = 0;
 
-  boolean fastPaint = false;
+  private boolean fastPaint = false;
 
   List<SequenceI> searchResults;
 
@@ -137,6 +137,7 @@ public class IdCanvas extends JPanel implements ViewportListenerI
     g.drawString(s.getDisplayId(av.getShowJVSuffix()), xPos,
             (((i - starty + 1) * charHeight) + ypos) - (charHeight / 5));
 
+    // JAL-3253-applet was just hiddenRows here. ccfc48e (gmungoc) added getShowHiddenMarkers test
     if (hiddenRows && av.getShowHiddenMarkers())
     {
       drawMarker(g, av, i, starty, ypos);
@@ -221,6 +222,11 @@ public class IdCanvas extends JPanel implements ViewportListenerI
   @Override
   public void paintComponent(Graphics g)
   {
+    if (av.getAlignPanel().getHoldRepaint())
+    {
+      return;
+    }
+
     g.setColor(Color.white);
     g.fillRect(0, 0, getWidth(), getHeight());
     
@@ -244,7 +250,7 @@ public class IdCanvas extends JPanel implements ViewportListenerI
     
     if (oldHeight != imgHeight || image.getWidth(this) != getWidth())
     {
-       image = new BufferedImage(getWidth(), imgHeight,
+      image = new BufferedImage(getWidth(), imgHeight,
                 BufferedImage.TYPE_INT_RGB);
     }
     
@@ -384,20 +390,49 @@ public class IdCanvas extends JPanel implements ViewportListenerI
     int alignmentWidth = alignViewport.getAlignment().getWidth();
     final int alheight = alignViewport.getAlignment().getHeight();
 
-    /*
+    
+//    int annotationHeight = 0;
+
+    /* (former)
      * assumption: SeqCanvas.calculateWrappedGeometry has been called
+     * 
+     * was based on the fact that SeqCanvas was added as a child prior to IdCanvas, 
+     * and children are processed in order of addition.
+     * 
+     * It's probably fine. But...
+     * 
      */
     SeqCanvas seqCanvas = alignViewport.getAlignPanel()
             .getSeqPanel().seqCanvas;
+    // ...better: let's call it now
+    seqCanvas.calculateWrappedGeometry();
 
     final int charHeight = alignViewport.getCharHeight();
 
     AnnotationLabels labels = null;
     if (alignViewport.isShowAnnotation())
     {
+       // BH when was ap == null?
+      if (ap == null)
+      {
+        ap = new AnnotationPanel(alignViewport);
+      }
+//      annotationHeight = ap.adjustPanelHeight();
       labels = new AnnotationLabels(alignViewport);
     }
 
+//    int hgap = charHeight;
+//    if (alignViewport.getScaleAboveWrapped())
+//    {
+//      hgap += charHeight;
+//    }
+//
+//    /*
+//     * height of alignment + gap + annotations (if shown)
+//     */
+//    int cHeight = alheight * charHeight + hgap
+//            + annotationHeight;
+//
     ViewportRanges ranges = alignViewport.getRanges();
 
     int rowSize = ranges.getViewportWidth();
@@ -568,20 +603,34 @@ public class IdCanvas extends JPanel implements ViewportListenerI
   public void propertyChange(PropertyChangeEvent evt)
   {
     String propertyName = evt.getPropertyName();
-    if (propertyName.equals(ViewportRanges.STARTSEQ)
-            || (av.getWrapAlignment()
-                    && propertyName.equals(ViewportRanges.STARTRES)))
+    switch (propertyName)
     {
+    case ViewportRanges.STARTSEQ:
       fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
-    }
-    else if (propertyName.equals(ViewportRanges.STARTRESANDSEQ))
-    {
+      break;
+    case ViewportRanges.STARTRES:
+      if (av.getWrapAlignment())
+      {
+        fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
+      }
+      break;
+    case ViewportRanges.STARTRESANDSEQ:
       fastPaint(((int[]) evt.getNewValue())[1]
               - ((int[]) evt.getOldValue())[1]);
-    }
-    else if (propertyName.equals(ViewportRanges.MOVE_VIEWPORT))
-    {
+      break;
+    case ViewportRanges.MOVE_VIEWPORT:
       repaint();
+      break;
+    default:
     }
   }
+
+  /**
+   * Clears the flag that allows a 'fast paint' on the next repaint, so
+   * requiring a full repaint
+   */
+  public void setNoFastPaint()
+  {
+    fastPaint = false;
+  }
 }
index 953fdc5..326bac0 100755 (executable)
@@ -128,13 +128,13 @@ public class PaintRefresher
       {
         // BH 2019.04.22 fixes JS problem of repaint() consolidation
         // that occurs in JavaScript but not Java [JAL-3226]
-        ((IdCanvas) comp).fastPaint = false;
+        ((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).fastPaint = false;
+        ((SeqCanvas) comp).setNoFastPaint();
       }
       comp.repaint();
     }
index b27208a..f62507a 100755 (executable)
@@ -57,7 +57,8 @@ import javax.swing.JPanel;
 public class SeqCanvas extends JPanel implements ViewportListenerI
 {
   /**
-   * vertical gap in pixels between sequences and annotations when in wrapped mode
+   * vertical gap in pixels between sequences and annotations when in wrapped
+   * mode
    */
   static final int SEQS_ANNOTATION_GAP = 3;
 
@@ -75,7 +76,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
 
   private final SequenceRenderer seqRdr;
 
-  boolean fastPaint = false;
+  private boolean fastPaint = false;
 
   private boolean fastpainting = false;
 
@@ -94,8 +95,12 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
 
   private int wrappedVisibleWidths; // number of wrapped widths displayed
 
+  private int availWidth;
+
+  private int availHeight;
+
   // Don't do this! Graphics handles are supposed to be transient
-  //private Graphics2D gg;
+  // private Graphics2D gg;
 
   /**
    * Creates a new SeqCanvas object.
@@ -116,7 +121,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
 
   public SequenceRenderer getSequenceRenderer()
   {
-    return seqRdr; 
+    return seqRdr;
   }
 
   public FeatureRenderer getFeatureRenderer()
@@ -202,7 +207,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     int yPos = ypos + charHeight;
     int startX = startx;
     int endX = endx;
-    
+
     if (av.hasHiddenColumns())
     {
       HiddenColumns hiddenColumns = av.getAlignment().getHiddenColumns();
@@ -238,7 +243,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
         }
       }
 
-      
       /*
        * white fill the space for the scale
        */
@@ -343,7 +347,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
         }
       }
 
-
       // System.err.println(">>> FastPaint to " + transX + " " + transY + " "
       // + horizontal + " " + vertical + " " + startRes + " " + endRes
       // + " " + startSeq + " " + endSeq);
@@ -352,9 +355,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       gg.copyArea(horizontal * charWidth, vertical * charHeight,
               img.getWidth(), img.getHeight(), -horizontal * charWidth,
               -vertical * charHeight);
-
-      /** @j2sNative xxi = this.img */
-
       gg.translate(transX, transY);
       drawPanel(gg, startRes, endRes, startSeq, endSeq, 0);
       gg.translate(-transX, -transY);
@@ -374,19 +374,14 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
   @Override
   public void paintComponent(Graphics g)
   {
+    if (av.getAlignPanel().getHoldRepaint())
+    {
+      return;
+    }
 
-    int charHeight = av.getCharHeight();
-    int charWidth = av.getCharWidth();
-
-    int width = getWidth();
-    int height = getHeight();
-
-    width -= (width % charWidth);
-    height -= (height % charHeight);
-
-    // BH 2019 can't possibly fastPaint if either width or height is 0
+    getAvailSizes();
 
-    if (width == 0 || height == 0)
+    if (availWidth == 0 || availHeight == 0)
     {
       return;
     }
@@ -436,10 +431,11 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       // img is a cached version of the last view we drew.
       // If we have no img or the size has changed, make a new one.
       //
-      if (img == null || width != img.getWidth()
-              || height != img.getHeight())
+      if (img == null || availWidth != img.getWidth()
+              || availHeight != img.getHeight())
       {
-        img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+        img = new BufferedImage(availWidth, availHeight,
+                BufferedImage.TYPE_INT_RGB);
       }
 
       Graphics2D gg = (Graphics2D) img.getGraphics();
@@ -452,11 +448,11 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       }
 
       gg.setColor(Color.white);
-      gg.fillRect(0, 0, img.getWidth(), img.getHeight());
+      gg.fillRect(0, 0, availWidth, availHeight);
 
       if (av.getWrapAlignment())
       {
-        drawWrappedPanel(gg, width, height, ranges.getStartRes());
+        drawWrappedPanel(gg, availWidth, availHeight, ranges.getStartRes());
       }
       else
       {
@@ -474,7 +470,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       drawCursor(g, startRes, endRes, startSeq, endSeq);
     }
   }
-  
+
   /**
    * Draw an alignment panel for printing
    * 
@@ -494,8 +490,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
   {
     drawPanel(g1, startRes, endRes, startSeq, endSeq, 0);
 
-    drawSelectionGroup((Graphics2D) g1, startRes, endRes,
-            startSeq, endSeq);
+    drawSelectionGroup((Graphics2D) g1, startRes, endRes, startSeq, endSeq);
   }
 
   /**
@@ -519,37 +514,36 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     if (group != null)
     {
       drawWrappedSelection((Graphics2D) g, group, canvasWidth, canvasHeight,
-                startRes);
+              startRes);
     }
   }
 
   /**
-   * Returns the visible width of the canvas in residues, after allowing for
-   * East or West scales (if shown)
+   * Using the current font, determine fields labelWidthEast and labelWidthWest,
+   * and return the number of residues that can fill the remaining width
    * 
-   * @param canvasWidth
+   * @param w
    *          the width in pixels (possibly including scales)
    * 
-   * @return
+   * @return the visible width in residues, after allowing for East or West
+   *         scales (if shown)
+   * 
    */
-  public int getWrappedCanvasWidth(int canvasWidth)
+  public int getWrappedCanvasWidth(int w)
   {
     int charWidth = av.getCharWidth();
 
     FontMetrics fm = getFontMetrics(av.getFont());
 
-    int labelWidth = 0;
-    
-    if (av.getScaleRightWrapped() || av.getScaleLeftWrapped())
-    {
-      labelWidth = getLabelWidth(fm);
-    }
+    int labelWidth = (av.getScaleRightWrapped() || av.getScaleLeftWrapped()
+            ? getLabelWidth(fm)
+            : 0);
 
     labelWidthEast = av.getScaleRightWrapped() ? labelWidth : 0;
 
     labelWidthWest = av.getScaleLeftWrapped() ? labelWidth : 0;
 
-    return (canvasWidth - labelWidthEast - labelWidthWest) / charWidth;
+    return (w - labelWidthEast - labelWidthWest) / charWidth;
   }
 
   /**
@@ -575,6 +569,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       maxWidth = Math.max(maxWidth, alignment.getSequenceAt(i).getEnd());
     }
 
+    // quick int log10
     int length = 0;
     for (int i = maxWidth; i > 0; i /= 10)
     {
@@ -589,28 +584,25 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
    * window
    * 
    * @param g
-   * @param canvasWidth
+   * @param availWidth
    *          available width in pixels
-   * @param canvasHeight
+   * @param availHeight
    *          available height in pixels
    * @param startColumn
    *          the first column (0...) of the alignment to draw
    */
-  public void drawWrappedPanel(Graphics g, int canvasWidth,
-          int canvasHeight, final int startColumn)
+  public void drawWrappedPanel(Graphics g, int availWidth, int availHeight,
+          final int startColumn)
   {
-    int wrappedWidthInResidues = calculateWrappedGeometry(canvasWidth,
-            canvasHeight);
-
+    int wrappedWidthInResidues = calculateWrappedGeometry();
     av.setWrappedWidth(wrappedWidthInResidues);
-
     ViewportRanges ranges = av.getRanges();
     ranges.setViewportStartAndWidth(startColumn, wrappedWidthInResidues);
 
     // we need to call this again to make sure the startColumn +
     // wrappedWidthInResidues values are used to calculate wrappedVisibleWidths
     // correctly.
-    calculateWrappedGeometry(canvasWidth, canvasHeight);
+    calculateWrappedGeometry();
 
     /*
      * draw one width at a time (excluding any scales shown),
@@ -623,9 +615,9 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     int currentWidth = 0;
     while ((currentWidth < wrappedVisibleWidths) && (start < maxWidth))
     {
-      int endColumn = Math
-              .min(maxWidth, start + wrappedWidthInResidues - 1);
-      drawWrappedWidth(g, ypos, start, endColumn, canvasHeight);
+      int endColumn = Math.min(maxWidth,
+              start + wrappedWidthInResidues - 1);
+      drawWrappedWidth(g, ypos, start, endColumn, availHeight);
       ypos += wrappedRepeatHeightPx;
       start += wrappedWidthInResidues;
       currentWidth++;
@@ -634,6 +626,16 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     drawWrappedDecorators(g, startColumn);
   }
 
+  private void getAvailSizes()
+  {
+    int charHeight = av.getCharHeight();
+    int charWidth = av.getCharWidth();
+    availWidth = getWidth();
+    availHeight = getHeight();
+    availWidth -= (availWidth % charWidth);
+    availHeight -= (availHeight % charHeight);
+  }
+
   /**
    * Calculates and saves values needed when rendering a wrapped alignment.
    * These depend on many factors, including
@@ -644,12 +646,26 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
    * <li>whether scales are shown left, right or above the alignment</li>
    * </ul>
    * 
+   * @param availWidth
+   * @param availHeight
+   * @return the number of residue columns in each width
+   */
+  protected int calculateWrappedGeometry()
+  {
+    getAvailSizes();
+    return calculateWrappedGeometry(availWidth, availHeight);
+
+  }
+
+  /**
+   * for test only
    * @param canvasWidth
    * @param canvasHeight
-   * @return the number of residue columns in each width
+   * @return
    */
-  protected int calculateWrappedGeometry(int canvasWidth, int canvasHeight)
+  public int calculateWrappedGeometry(int canvasWidth, int canvasHeight)
   {
+
     int charHeight = av.getCharHeight();
 
     /*
@@ -663,9 +679,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
      * compute height in pixels of the wrapped widths
      * - start with space above plus sequences
      */
-    wrappedRepeatHeightPx = wrappedSpaceAboveAlignment;
-    wrappedRepeatHeightPx += av.getAlignment().getHeight()
-            * charHeight;
+    wrappedRepeatHeightPx = wrappedSpaceAboveAlignment
+            + av.getAlignment().getHeight() * charHeight;
 
     /*
      * add annotations panel height if shown
@@ -736,7 +751,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     int charWidth = av.getCharWidth();
     int xOffset = labelWidthWest
             + ((startColumn - ranges.getStartRes()) % viewportWidth)
-            * charWidth;
+                    * charWidth;
 
     g.translate(xOffset, 0);
 
@@ -803,7 +818,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       if (av.getScaleRightWrapped())
       {
         int x = labelWidthWest + viewportWidth * charWidth;
-        
+
         g.translate(x, 0);
         drawVerticalScale(g, startCol, endColumn, ypos, false);
         g.translate(-x, 0);
@@ -815,8 +830,9 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
        */
       g.translate(labelWidthWest, 0);
       g.setColor(Color.white);
-      g.fillRect(0, ypos - wrappedSpaceAboveAlignment, viewportWidth
-              * charWidth + labelWidthWest, wrappedSpaceAboveAlignment);
+      g.fillRect(0, ypos - wrappedSpaceAboveAlignment,
+              viewportWidth * charWidth + labelWidthWest,
+              wrappedSpaceAboveAlignment);
       g.setColor(Color.black);
       g.translate(-labelWidthWest, 0);
 
@@ -883,18 +899,21 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     }
   }
 
+  private final static BasicStroke dottedStroke = new BasicStroke(1,
+          BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 3f, new float[]
+          { 5f, 3f }, 0f);
+
+  private final static BasicStroke basicStroke = new BasicStroke();
+
   /*
    * Draw a selection group over a wrapped alignment
    */
   private void drawWrappedSelection(Graphics2D g, SequenceGroup group,
-          int canvasWidth,
-          int canvasHeight, int startRes)
+          int canvasWidth, int canvasHeight, int startRes)
   {
     // chop the wrapped alignment extent up into panel-sized blocks and treat
     // each block as if it were a block from an unwrapped alignment
-    g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
-            BasicStroke.JOIN_ROUND, 3f, new float[]
-            { 5f, 3f }, 0f));
+    g.setStroke(dottedStroke);
     g.setColor(Color.RED);
 
     int charWidth = av.getCharWidth();
@@ -902,6 +921,21 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
             / charWidth;
     int startx = startRes;
     int maxwidth = av.getAlignment().getVisibleWidth();
+
+    // JAL-3253-applet had this:
+    // // height gap above each panel
+    // int charHeight = av.getCharHeight();
+    // int hgap = charHeight;
+    // if (av.getScaleAboveWrapped())
+    // {
+    // hgap += charHeight;
+    // }
+    // int dy = getAnnotationHeight() + hgap
+    // + av.getAlignment().getHeight() * charHeight;
+    // int ypos = hgap; // vertical offset
+
+    // this is from 0b573ed (gmungoc)
+    int dy = wrappedRepeatHeightPx;
     int ypos = wrappedSpaceAboveAlignment;
 
     while ((ypos <= canvasHeight) && (startx < maxwidth))
@@ -915,21 +949,24 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       }
 
       g.translate(labelWidthWest, 0);
+
       drawUnwrappedSelection(g, group, startx, endx, 0,
-              av.getAlignment().getHeight() - 1,
-              ypos);
+              av.getAlignment().getHeight() - 1, ypos);
+
       g.translate(-labelWidthWest, 0);
 
-      ypos += wrappedRepeatHeightPx;
+      // update vertical offset
+      ypos += dy;
 
+      // update horizontal offset
       startx += cWidth;
     }
-    g.setStroke(new BasicStroke());
+    g.setStroke(basicStroke);
   }
 
   /**
-   * Answers zero if annotations are not shown, otherwise recalculates and answers
-   * the total height of all annotation rows in pixels
+   * Answers zero if annotations are not shown, otherwise recalculates and
+   * answers the total height of all annotation rows in pixels
    * 
    * @return
    */
@@ -1190,8 +1227,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
    *         the cursor drawn on it, if any
    */
   private void drawCursor(Graphics g, int startRes, int endRes,
-          int startSeq,
-          int endSeq)
+          int startSeq, int endSeq)
   {
     // convert the cursorY into a position on the visible alignment
     int cursor_ypos = cursorY;
@@ -1262,7 +1298,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     }
   }
 
-
   /**
    * Draw a selection group over an unwrapped alignment
    * 
@@ -1285,7 +1320,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
           int startRes, int endRes, int startSeq, int endSeq, int offset)
   {
     int charWidth = av.getCharWidth();
-          
+
     if (!av.hasHiddenColumns())
     {
       drawPartialGroupOutline(g, group, startRes, endRes, startSeq, endSeq,
@@ -1308,8 +1343,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
         blockStart = region[0];
 
         g.translate(screenY * charWidth, 0);
-        drawPartialGroupOutline(g, group,
-                blockStart, blockEnd, startSeq, endSeq, offset);
+        drawPartialGroupOutline(g, group, blockStart, blockEnd, startSeq,
+                endSeq, offset);
 
         g.translate(-screenY * charWidth, 0);
         screenY += blockEnd - blockStart + 1;
@@ -1478,7 +1513,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       g.drawLine(sx + xwidth, oldY, sx + xwidth, sy);
     }
   }
-  
+
   /**
    * Highlights search results in the visible region by rendering as white text
    * on a black background. Any previous highlighting is removed. Answers true
@@ -1494,7 +1529,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     return highlightSearchResults(results, false);
 
   }
-  
+
   /**
    * Highlights search results in the visible region by rendering as white text
    * on a black background. Any previous highlighting is removed. Answers true
@@ -1652,7 +1687,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       {
         firstCol = alignment.getHiddenColumns()
                 .absoluteToVisibleColumn(firstCol);
-        lastCol = alignment.getHiddenColumns().absoluteToVisibleColumn(lastCol);
+        lastCol = alignment.getHiddenColumns()
+                .absoluteToVisibleColumn(lastCol);
       }
       int transX = (firstCol - ranges.getStartRes()) * av.getCharWidth();
       int transY = (firstSeq - ranges.getStartSeq()) * av.getCharHeight();
@@ -1670,92 +1706,161 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
   public void propertyChange(PropertyChangeEvent evt)
   {
     String eventName = evt.getPropertyName();
-    // System.err.println(">>SeqCanvas propertyChange " + eventName);
-    if (eventName.equals(SequenceGroup.SEQ_GROUP_CHANGED))
-    {
-      fastPaint = true;
-      repaint();
-      return;
-    }
-    else if (eventName.equals(ViewportRanges.MOVE_VIEWPORT))
-    {
-      fastPaint = false;
-      // System.err.println("!!!! fastPaint false from MOVE_VIEWPORT");
-      repaint();
-      return;
-    }
 
-    int scrollX = 0;
-    if (eventName.equals(ViewportRanges.STARTRES)
-            || eventName.equals(ViewportRanges.STARTRESANDSEQ))
-    {
-      // Make sure we're not trying to draw a panel
-      // larger than the visible window
-      if (eventName.equals(ViewportRanges.STARTRES))
-      {
-        scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
-      }
-      else
-      {
-        scrollX = ((int[]) evt.getNewValue())[0]
-                - ((int[]) evt.getOldValue())[0];
-      }
-      ViewportRanges vpRanges = av.getRanges();
+    // BH 2019.07.27 removes dead code introduced in aad3650 and simplifies
+    // logic, emphasizing no check for ENDRES or ENDSEQ
 
-      int range = vpRanges.getEndRes() - vpRanges.getStartRes() + 1;
-      if (scrollX > range)
-      {
-        scrollX = range;
-      }
-      else if (scrollX < -range)
-      {
-        scrollX = -range;
-      }
-    }
     // Both scrolling and resizing change viewport ranges: scrolling changes
     // both start and end points, but resize only changes end values.
     // Here we only want to fastpaint on a scroll, with resize using a normal
     // paint, so scroll events are identified as changes to the horizontal or
     // vertical start value.
-    if (eventName.equals(ViewportRanges.STARTRES))
-    {
-      if (av.getWrapAlignment())
-      {
-        fastPaintWrapped(scrollX);
-      }
-      else
-      {
-        fastPaint(scrollX, 0);
-      }
-    }
-    else if (eventName.equals(ViewportRanges.STARTSEQ))
+
+    // Make sure we're not trying to draw a panel
+    // larger than the visible window
+    int scrollX = 0;
+    int scrollY = 0;
+    switch (eventName)
     {
-      // scroll
+    case SequenceGroup.SEQ_GROUP_CHANGED:
+      fastPaint = true;
+      repaint();
+      return;
+    case ViewportRanges.MOVE_VIEWPORT:
+      fastPaint = false;
+      repaint();
+      return;
+    case ViewportRanges.STARTSEQ:
+      // meaning STARTOREND
+      // typically scroll, but possibly just the end changed
       fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
-    }
-    else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
-    {
-      if (av.getWrapAlignment())
-      {
-        fastPaintWrapped(scrollX);
-      }
-      else
+      return;
+    case ViewportRanges.STARTRES:
+      // meaning STARTOREND
+      scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+      break;
+    case ViewportRanges.STARTRESANDSEQ:
+      scrollX = ((int[]) evt.getNewValue())[0]
+              - ((int[]) evt.getOldValue())[0];
+      scrollY = ((int[]) evt.getNewValue())[1]
+              - ((int[]) evt.getOldValue())[1];
+
+      // System.out.println("SC dx dy " + scrollX + " " + scrollY);
+
+      if (scrollX != 0 && scrollY != 0)
       {
-        fastPaint(scrollX, 0);
+        // all sorts of problems in JavaScript if this is commented out.
+        repaint();
+        return;
+
       }
+      break;
+    default:
+      return;
     }
-    else if (eventName.equals(ViewportRanges.STARTSEQ))
+
+    ViewportRanges vpRanges = av.getRanges();
+    int range = vpRanges.getEndRes() - vpRanges.getStartRes() + 1;
+    scrollX = Math.max(Math.min(scrollX, range), -range);
+    // only STARTRES or STARTRESANDSEQ:
+    if (av.getWrapAlignment())
     {
-      // scroll
-      fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+      fastPaintWrapped(scrollX);
     }
-    else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
+    else
     {
-      if (av.getWrapAlignment())
-      {
-        fastPaintWrapped(scrollX);
-      }
+      fastPaint(scrollX, scrollY);
     }
+
+    // BH 2019.07.27 was:
+    // if (eventName.equals(SequenceGroup.SEQ_GROUP_CHANGED))
+    // {
+    // fastPaint = true;
+    // repaint();
+    // return;
+    // }
+    // else if (eventName.equals(ViewportRanges.MOVE_VIEWPORT))
+    // {
+    // fastPaint = false;
+    // // System.err.println("!!!! fastPaint false from MOVE_VIEWPORT");
+    // repaint();
+    // return;
+    // }
+    //
+    // if (eventName.equals(ViewportRanges.STARTRES)
+    // || eventName.equals(ViewportRanges.STARTRESANDSEQ))
+    // {
+    // // Make sure we're not trying to draw a panel
+    // // larger than the visible window
+    // if (eventName.equals(ViewportRanges.STARTRES))
+    // {
+    // scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+    // }
+    // else
+    // {
+    // scrollX = ((int[]) evt.getNewValue())[0]
+    // - ((int[]) evt.getOldValue())[0];
+    // }
+    // ViewportRanges vpRanges = av.getRanges();
+    //
+    // int range = vpRanges.getEndRes() - vpRanges.getStartRes() + 1;
+    // if (scrollX > range)
+    // {
+    // scrollX = range;
+    // }
+    // else if (scrollX < -range)
+    // {
+    // scrollX = -range;
+    // }
+    // }
+    // Both scrolling and resizing change viewport ranges: scrolling changes
+    // both start and end points, but resize only changes end values.
+    // Here we only want to fastpaint on a scroll, with resize using a normal
+    // paint, so scroll events are identified as changes to the horizontal or
+    // vertical start value.
+    // BH 2019.07.27 was:
+    // if (eventName.equals(ViewportRanges.STARTRES))
+    // {
+    // if (av.getWrapAlignment())
+    // {
+    // fastPaintWrapped(scrollX);
+    // }
+    // else
+    // {
+    // fastPaint(scrollX, 0);
+    // }
+    // }
+    // else if (eventName.equals(ViewportRanges.STARTSEQ))
+    // {
+    // // scroll
+    // fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+    // }
+    // else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
+    // {
+    // if (av.getWrapAlignment())
+    // {
+    // fastPaintWrapped(scrollX);
+    // }
+    // else
+    // {
+    // fastPaint(scrollX, 0);
+    // }
+    // }
+    //
+    // BH oops!
+    //
+    // else if (eventName.equals(ViewportRanges.STARTSEQ))
+    // {
+    // // scroll
+    // fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+    // }
+    // else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
+    // {
+    // if (av.getWrapAlignment())
+    // {
+    // fastPaintWrapped(scrollX);
+    // }
+    // }
   }
 
   /**
@@ -1792,10 +1897,10 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
 
     try
     {
-      
+
       Graphics gg = img.getGraphics();
-      
-      calculateWrappedGeometry(getWidth(), getHeight());
+
+      calculateWrappedGeometry();
 
       /*
        * relocate the regions of the alignment that are still visible
@@ -1810,8 +1915,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       if (scrollX < 0)
       {
         int startRes = ranges.getStartRes();
-        drawWrappedWidth(gg, wrappedSpaceAboveAlignment, startRes, startRes
-                - scrollX - 1, getHeight());
+        drawWrappedWidth(gg, wrappedSpaceAboveAlignment, startRes,
+                startRes - scrollX - 1, getHeight());
       }
       else
       {
@@ -1824,7 +1929,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       drawWrappedDecorators(gg, ranges.getStartRes());
 
       gg.dispose();
-      
+
       repaint();
     } finally
     {
@@ -1849,7 +1954,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     }
 
     Graphics gg = img.getGraphics();
-    
+
     ViewportRanges ranges = av.getRanges();
     int viewportWidth = ranges.getViewportWidth();
     int charWidth = av.getCharWidth();
@@ -1860,7 +1965,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
      */
     int visibleWidths = wrappedVisibleWidths;
     int canvasHeight = getHeight();
-    boolean lastWidthPartHeight = (wrappedVisibleWidths * wrappedRepeatHeightPx) > canvasHeight;
+    boolean lastWidthPartHeight = (wrappedVisibleWidths
+            * wrappedRepeatHeightPx) > canvasHeight;
 
     if (lastWidthPartHeight)
     {
@@ -1876,16 +1982,15 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       /*
        * white fill first to erase annotations
        */
-      
-      
+
       gg.translate(xOffset, 0);
       gg.setColor(Color.white);
-      gg.fillRect(labelWidthWest, ypos,
-              (endRes - startRes + 1) * charWidth, wrappedRepeatHeightPx);
+      gg.fillRect(labelWidthWest, ypos, (endRes - startRes + 1) * charWidth,
+              wrappedRepeatHeightPx);
       gg.translate(-xOffset, 0);
 
       drawWrappedWidth(gg, ypos, startRes, endRes, canvasHeight);
-      
+
     }
 
     /*
@@ -1930,7 +2035,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       gg.fillRect(0, canvasHeight - heightBelow, getWidth(), heightBelow);
     }
     gg.dispose();
- }
+  }
 
   /**
    * Shifts the visible alignment by the specified number of columns - left if
@@ -2018,8 +2123,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
         if (y + wrappedRepeatHeightPx < canvasHeight - wrappedRepeatHeightPx
                 && (xpos + viewportWidth <= xMax))
         {
-          gg.copyArea(labelWidthWest, y + wrappedRepeatHeightPx, -positions
-                  * charWidth, heightToCopy, widthToCopy,
+          gg.copyArea(labelWidthWest, y + wrappedRepeatHeightPx,
+                  -positions * charWidth, heightToCopy, widthToCopy,
                   -wrappedRepeatHeightPx);
         }
         y += wrappedRepeatHeightPx;
@@ -2029,7 +2134,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     gg.dispose();
   }
 
-  
   /**
    * Redraws any positions in the search results in the visible region of a
    * wrapped alignment. Any highlights are drawn depending on the search results
@@ -2050,7 +2154,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
 
     boolean matchFound = false;
 
-    calculateWrappedGeometry(getWidth(), getHeight());
+    calculateWrappedGeometry();
     int wrappedWidth = av.getWrappedWidth();
     int wrappedHeight = wrappedRepeatHeightPx;
 
@@ -2063,8 +2167,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     }
 
     int firstVisibleColumn = ranges.getStartRes();
-    int lastVisibleColumn = ranges.getStartRes() + repeats
-            * ranges.getViewportWidth() - 1;
+    int lastVisibleColumn = ranges.getStartRes()
+            + repeats * ranges.getViewportWidth() - 1;
 
     AlignmentI alignment = av.getAlignment();
     if (av.hasHiddenColumns())
@@ -2077,7 +2181,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
 
     int gapHeight = charHeight * (av.getScaleAboveWrapped() ? 2 : 1);
 
-    
     Graphics gg = img.getGraphics();
 
     for (int seqNo = ranges.getStartSeq(); seqNo <= ranges
@@ -2121,8 +2224,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
                * transX: offset from left edge of canvas to residue position
                */
               int transX = labelWidthWest
-                      + ((displayColumn - ranges.getStartRes()) % wrappedWidth)
-                      * av.getCharWidth();
+                      + ((displayColumn - ranges.getStartRes())
+                              % wrappedWidth) * av.getCharWidth();
 
               /*
                * transY: offset from top edge of canvas to residue position
@@ -2149,7 +2252,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
         }
       }
     }
-  
+
     gg.dispose();
 
     return matchFound;
@@ -2165,4 +2268,13 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     return labelWidthWest;
   }
 
+  /**
+   * Clears the flag that allows a 'fast paint' on the next repaint, so
+   * requiring a full repaint
+   */
+  public void setNoFastPaint()
+  {
+    fastPaint = false;
+  }
+
 }
index b2149df..4e789b9 100644 (file)
@@ -291,8 +291,7 @@ public class SeqPanel extends JPanel
     int alignmentHeight = av.getAlignment().getHeight();
     if (av.getWrapAlignment())
     {
-      seqCanvas.calculateWrappedGeometry(seqCanvas.getWidth(),
-              seqCanvas.getHeight());
+      seqCanvas.calculateWrappedGeometry();
 
       /*
        * yPos modulo height of repeating width
index e3b1191..78f6cd3 100644 (file)
@@ -22,21 +22,27 @@ package jalview.gui;
 
 import static org.testng.Assert.assertEquals;
 
+import jalview.bin.Cache;
+import jalview.datamodel.AlignmentI;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+import jalview.util.Platform;
+
 import java.awt.Font;
 import java.awt.FontMetrics;
 
-import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
-import jalview.bin.Cache;
-import jalview.datamodel.AlignmentI;
-import jalview.io.DataSourceType;
-import jalview.io.FileLoader;
 import junit.extensions.PA;
 
 public class SeqCanvasTest
 {
-  private AlignFrame af;
+  @BeforeClass(alwaysRun = true)
+  public void setUp()
+  {
+    Cache.initLogger();
+  }
 
   /**
    * Test the method that computes wrapped width in residues, height of wrapped
@@ -45,6 +51,8 @@ public class SeqCanvasTest
   @Test(groups = "Functional")
   public void testCalculateWrappedGeometry_noAnnotations()
   {
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            "examples/uniref50.fa", DataSourceType.FILE);
     AlignViewport av = af.getViewport();
     AlignmentI al = av.getAlignment();
     assertEquals(al.getWidth(), 157);
@@ -57,8 +65,8 @@ public class SeqCanvasTest
     av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
     int charHeight = av.getCharHeight();
     int charWidth = av.getCharWidth();
-    assertEquals(charHeight, 17);
-    assertEquals(charWidth, 12);
+    assertEquals(charHeight, Platform.isMac() ? 17 : 19);
+    assertEquals(charWidth, Platform.isMac() ? 12 : 11);
 
     /*
      * first with scales above, left, right
@@ -69,7 +77,8 @@ public class SeqCanvasTest
     av.setScaleRightWrapped(true);
     FontMetrics fm = testee.getFontMetrics(av.getFont());
     int labelWidth = fm.stringWidth("000") + charWidth;
-    assertEquals(labelWidth, 39); // 3 x 9 + charWidth
+    assertEquals(labelWidth,
+            Platform.isMac() ? 3 * 9 + charWidth : 3 * 8 + charWidth);
 
     /*
      * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
@@ -191,7 +200,7 @@ public class SeqCanvasTest
     canvasWidth += 2;
     wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
             canvasHeight);
-    assertEquals(wrappedWidth, 24); // 2px not enough
+    assertEquals(wrappedWidth, Platform.isMac() ? 24 : 25); // 2px not enough
     canvasWidth += 1;
     wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
             canvasHeight);
@@ -213,6 +222,8 @@ public class SeqCanvasTest
   @Test(groups = "Functional")
   public void testCalculateWrappedGeometry_withAnnotations()
   {
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            "examples/uniref50.fa", DataSourceType.FILE);
     AlignViewport av = af.getViewport();
     AlignmentI al = av.getAlignment();
     assertEquals(al.getWidth(), 157);
@@ -223,9 +234,10 @@ public class SeqCanvasTest
     av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
     int charHeight = av.getCharHeight();
     int charWidth = av.getCharWidth();
-    assertEquals(charHeight, 17);
-    assertEquals(charWidth, 12);
-  
+
+    assertEquals(charHeight, Platform.isMac() ? 17 : 19);
+    assertEquals(charWidth, Platform.isMac() ? 12 : 11);
+
     SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
   
     /*
@@ -235,9 +247,12 @@ public class SeqCanvasTest
     av.setScaleAboveWrapped(true);
     av.setScaleLeftWrapped(true);
     av.setScaleRightWrapped(true);
+
     FontMetrics fm = testee.getFontMetrics(av.getFont());
     int labelWidth = fm.stringWidth("000") + charWidth;
-    assertEquals(labelWidth, 39); // 3 x 9 + charWidth
+    assertEquals(labelWidth,
+            Platform.isMac() ? 3 * 9 + charWidth : 3 * 8 + charWidth);
+
     int annotationHeight = testee.getAnnotationHeight();
 
     /*
@@ -306,25 +321,27 @@ public class SeqCanvasTest
    * endSeq should be unchanged, but the vertical repeat height should include
    * all sequences.
    */
-  @Test(groups = "Functional_Failing")
+  @Test(groups = "Functional")
   public void testCalculateWrappedGeometry_fromScrolled()
   {
+    AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+            "examples/uniref50.fa", DataSourceType.FILE);
     AlignViewport av = af.getViewport();
     AlignmentI al = av.getAlignment();
     assertEquals(al.getWidth(), 157);
     assertEquals(al.getHeight(), 15);
     av.getRanges().setStartEndSeq(0, 3);
-    av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
-    av.setWrapAlignment(true);
     av.setShowAnnotation(false);
     av.setScaleAboveWrapped(true);
 
     SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
-
+    av.setWrapAlignment(true);
+    av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
     int charHeight = av.getCharHeight();
     int charWidth = av.getCharWidth();
-    assertEquals(charHeight, 17);
-    assertEquals(charWidth, 12);
+    // Windows h=19, w=11.
+    assertEquals(charHeight, Platform.isMac() ? 17 : 19);
+    assertEquals(charWidth, Platform.isMac() ? 12 : 11);
 
     int canvasWidth = 400;
     int canvasHeight = 300;
@@ -333,29 +350,7 @@ public class SeqCanvasTest
     assertEquals(av.getRanges().getEndSeq(), 3); // unchanged
     int repeatingHeight = (int) PA.getValue(testee,
             "wrappedRepeatHeightPx");
-    assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
-  }
-
-  @BeforeMethod(alwaysRun = true)
-  public void setUp()
-  {
-    Cache.loadProperties("test/jalview/io/testProps.jvprops");
-    Cache.setPropertyNoSave("SHOW_IDENTITY",
-            Boolean.TRUE.toString());
-    af = new FileLoader().LoadFileWaitTillLoaded("examples/uniref50.fa",
-            DataSourceType.FILE);
-  
-    /*
-     * wait for Consensus thread to complete
-     */
-    do
-    {
-      try
-      {
-        Thread.sleep(50);
-      } catch (InterruptedException x)
-      {
-      }
-    } while (af.getViewport().getCalcManager().isWorking());
+    int h = charHeight * (2 + al.getHeight());
+    assertEquals(repeatingHeight, h);
   }
 }
index 9992137..b14b3b5 100644 (file)
@@ -149,7 +149,7 @@ public class PDBSequenceFetcherTest
         // chains in structure have a mapping to data in the structure
         List<SequenceFeature> prev = null;
         int lastp = -1;
-        for (int col = 1; col <= sq.getLength(); col++)
+        for (int col = 1, ns = sq.getLength(); col <= ns; col++)
         {
           List<SequenceFeature> sf = sq.findFeatures(col, col, "RESNUM");
           if (sf.size() != 1)
index 12f5e1b..9c291c3 100644 (file)
@@ -85,7 +85,7 @@ public class JalviewJabawsTestUtils
   public static Jws2Discoverer getJabawsDiscoverer(boolean localhost)
   {
     jalview.ws.jws2.Jws2Discoverer disc = jalview.ws.jws2.Jws2Discoverer
-            .getDiscoverer();
+            .getInstance();
     String svcurls = "";
     if (localhost)
     {
@@ -97,7 +97,7 @@ public class JalviewJabawsTestUtils
         services.add(url);
       }
       ;
-      Jws2Discoverer.getDiscoverer().setServiceUrls(services);
+      Jws2Discoverer.getInstance().setServiceUrls(services);
     }
     try
     {