Merge branch 'develop' into update_212_Dec_merge_with_21125_chamges
[jalview.git] / src / jalview / gui / SeqCanvas.java
index d15cdcf..1137153 100755 (executable)
  */
 package jalview.gui;
 
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.SearchResultsI;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.VisibleContigsIterator;
+import jalview.renderer.ScaleRenderer;
+import jalview.renderer.ScaleRenderer.ScaleMark;
+import jalview.util.Comparison;
+import jalview.viewmodel.ViewportListenerI;
+import jalview.viewmodel.ViewportRanges;
+
 import java.awt.BasicStroke;
 import java.awt.BorderLayout;
 import java.awt.Color;
@@ -35,18 +47,6 @@ import java.util.List;
 
 import javax.swing.JPanel;
 
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.HiddenColumns;
-import jalview.datamodel.SearchResultsI;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
-import jalview.datamodel.VisibleContigsIterator;
-import jalview.renderer.ScaleRenderer;
-import jalview.renderer.ScaleRenderer.ScaleMark;
-import jalview.util.Comparison;
-import jalview.viewmodel.ViewportListenerI;
-import jalview.viewmodel.ViewportRanges;
-
 /**
  * The Swing component on which the alignment sequences, and annotations (if
  * shown), are drawn. This includes scales above, left and right (if shown) in
@@ -76,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;
 
@@ -95,6 +95,11 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
 
   private int wrappedVisibleWidths; // number of wrapped widths displayed
 
+  private int availWidth;
+
+  private int availHeight;
+
+  private boolean allowFastPaint;
   // Don't do this! Graphics handles are supposed to be transient
   // private Graphics2D gg;
 
@@ -203,7 +208,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();
@@ -343,6 +348,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
         }
       }
 
+
       // System.err.println(">>> FastPaint to " + transX + " " + transY + " "
       // + horizontal + " " + vertical + " " + startRes + " " + endRes
       // + " " + startSeq + " " + endSeq);
@@ -352,7 +358,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
               img.getWidth(), img.getHeight(), -horizontal * charWidth,
               -vertical * charHeight);
 
-      /** @j2sNative xxi = this.img */
 
       gg.translate(transX, transY);
       drawPanel(gg, startRes, endRes, startSeq, endSeq, 0);
@@ -362,7 +367,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       // Call repaint on alignment panel so that repaints from other alignment
       // panel components can be aggregated. Otherwise performance of the
       // overview window and others may be adversely affected.
-      // System.out.println("SeqCanvas fastPaint() repaint() request...");
       av.getAlignPanel().repaint();
     } finally
     {
@@ -373,19 +377,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;
     }
@@ -419,11 +418,9 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     // }
 
     Rectangle vis, clip;
-    if (img != null
-            && (fastPaint
-                    || (vis = getVisibleRect()).width != (clip = g
-                            .getClipBounds()).width
-                    || vis.height != clip.height))
+    if (allowFastPaint  && img != null
+            && (fastPaint || (vis = getVisibleRect()).width != (clip = g.getClipBounds()).width
+                          || vis.height != clip.height))
     {
       g.drawImage(img, 0, 0, this);
       drawSelectionGroup((Graphics2D) g, startRes, endRes, startSeq,
@@ -432,13 +429,15 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     }
     else
     {
+      allowFastPaint = true;
       // 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();
@@ -451,11 +450,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, getWidth(), getHeight(), ranges.getStartRes());
+        drawWrappedPanel(gg, availWidth, availHeight, ranges.getStartRes());
       }
       else
       {
@@ -473,7 +472,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       drawCursor(g, startRes, endRes, startSeq, endSeq);
     }
   }
-
   /**
    * Draw an alignment panel for printing
    * 
@@ -537,7 +535,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     FontMetrics fm = getFontMetrics(av.getFont());
 
     int labelWidth = 0;
-
+    
     if (av.getScaleRightWrapped() || av.getScaleLeftWrapped())
     {
       labelWidth = getLabelWidth(fm);
@@ -573,6 +571,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)
     {
@@ -587,18 +586,17 @@ 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);
 
@@ -608,7 +606,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     // 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,7 +621,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     {
       int endColumn = Math.min(maxWidth,
               start + wrappedWidthInResidues - 1);
-      drawWrappedWidth(g, ypos, start, endColumn, canvasHeight);
+      drawWrappedWidth(g, ypos, start, endColumn, availHeight);
       ypos += wrappedRepeatHeightPx;
       start += wrappedWidthInResidues;
       currentWidth++;
@@ -632,6 +630,15 @@ 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
@@ -642,11 +649,24 @@ 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();
 
@@ -661,8 +681,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
@@ -690,7 +710,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
      * compute width in residues; this also sets East and West label widths
      */
     int wrappedWidthInResidues = getWrappedCanvasWidth(canvasWidth);
-    av.setWrappedWidth(wrappedWidthInResidues); // update model accordingly
+
     /*
      *  limit visibleWidths to not exceed width of alignment
      */
@@ -800,7 +820,6 @@ 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);
@@ -881,6 +900,11 @@ 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
    */
@@ -889,9 +913,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
   {
     // 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();
@@ -899,6 +921,20 @@ 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))
@@ -916,11 +952,13 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
               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);
   }
 
   /**
@@ -1257,6 +1295,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     }
   }
 
+
   /**
    * Draw a selection group over an unwrapped alignment
    * 
@@ -1279,7 +1318,6 @@ 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,
@@ -1472,7 +1510,6 @@ 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
@@ -1488,7 +1525,6 @@ 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
@@ -1665,92 +1701,157 @@ 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))
+    // BH 2019.07.27 removes dead code introduced in aad3650 and simplifies
+    // logic, emphasizing no check for ENDRES or ENDSEQ
+
+    // 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.
+
+    // Make sure we're not trying to draw a panel
+    // larger than the visible window
+    int scrollX = 0;
+    int scrollY = 0;
+    switch (eventName)
     {
+    case SequenceGroup.SEQ_GROUP_CHANGED:
       fastPaint = true;
       repaint();
       return;
-    }
-    else if (eventName.equals(ViewportRanges.MOVE_VIEWPORT))
-    {
+    case 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
+    case ViewportRanges.STARTSEQ:
+      // meaning STARTOREND
+      // typically scroll, but possibly just the end changed
+      fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+      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];
+      if (scrollX != 0 && scrollY != 0)
       {
-        scrollX = ((int[]) evt.getNewValue())[0]
-                - ((int[]) evt.getOldValue())[0];
-      }
-      ViewportRanges vpRanges = av.getRanges();
+        // all sorts of problems in JavaScript if this is commented out.
+        repaint();
+        return;
 
-      int range = vpRanges.getEndRes() - vpRanges.getStartRes() + 1;
-      if (scrollX > range)
-      {
-        scrollX = range;
-      }
-      else if (scrollX < -range)
-      {
-        scrollX = -range;
       }
+      break;
+    default:
+      return;
+    }
+
+    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())
+    {
+      fastPaintWrapped(scrollX);
+    }
+    else
+    {
+      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.
-    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);
-      }
-    }
-    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);
-      }
-    }
+    // 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);
+    // }
+    // }
   }
 
   /**
@@ -1787,10 +1888,8 @@ 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
@@ -1819,7 +1918,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       drawWrappedDecorators(gg, ranges.getStartRes());
 
       gg.dispose();
-
       repaint();
     } finally
     {
@@ -1844,7 +1942,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
     }
 
     Graphics gg = img.getGraphics();
-
     ViewportRanges ranges = av.getRanges();
     int viewportWidth = ranges.getViewportWidth();
     int charWidth = av.getCharWidth();
@@ -1872,7 +1969,6 @@ 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,
@@ -1880,7 +1976,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
       gg.translate(-xOffset, 0);
 
       drawWrappedWidth(gg, ypos, startRes, endRes, canvasHeight);
-
     }
 
     /*
@@ -2044,7 +2139,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
 
     boolean matchFound = false;
 
-    calculateWrappedGeometry(getWidth(), getHeight());
+    calculateWrappedGeometry();
     int wrappedWidth = av.getWrappedWidth();
     int wrappedHeight = wrappedRepeatHeightPx;
 
@@ -2142,7 +2237,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
         }
       }
     }
-
     gg.dispose();
 
     return matchFound;
@@ -2158,4 +2252,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()
+  {
+    allowFastPaint = false;
+  }
+
 }