Merge branch 'bug/JAL-3003epsWithSelection' into trialMerge
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 31 Aug 2018 08:49:55 +0000 (09:49 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 31 Aug 2018 08:49:55 +0000 (09:49 +0100)
Conflicts:
src/jalview/gui/SeqCanvas.java

1  2 
.settings/org.eclipse.jdt.ui.prefs
src/jalview/gui/SeqCanvas.java

@@@ -1,8 -1,66 +1,67 @@@
  eclipse.preferences.version=1
+ editor_save_participant_org.eclipse.jdt.ui.postsavelistener.cleanup=true
  formatter_profile=_Jalview
  formatter_settings_version=12
  org.eclipse.jdt.ui.ignorelowercasenames=true
  org.eclipse.jdt.ui.importorder=jalview;java;javax;org;com;
  org.eclipse.jdt.ui.ondemandthreshold=99
  org.eclipse.jdt.ui.staticondemandthreshold=99
+ sp_cleanup.add_default_serial_version_id=true
+ sp_cleanup.add_generated_serial_version_id=false
+ sp_cleanup.add_missing_annotations=true
+ sp_cleanup.add_missing_deprecated_annotations=true
+ sp_cleanup.add_missing_methods=false
+ sp_cleanup.add_missing_nls_tags=false
+ sp_cleanup.add_missing_override_annotations=true
+ sp_cleanup.add_missing_override_annotations_interface_methods=true
+ sp_cleanup.add_serial_version_id=false
+ sp_cleanup.always_use_blocks=true
+ sp_cleanup.always_use_parentheses_in_expressions=false
+ sp_cleanup.always_use_this_for_non_static_field_access=false
+ sp_cleanup.always_use_this_for_non_static_method_access=false
+ sp_cleanup.convert_functional_interfaces=false
+ sp_cleanup.convert_to_enhanced_for_loop=false
+ sp_cleanup.correct_indentation=false
+ sp_cleanup.format_source_code=true
+ sp_cleanup.format_source_code_changes_only=true
+ sp_cleanup.insert_inferred_type_arguments=false
+ sp_cleanup.make_local_variable_final=true
+ sp_cleanup.make_parameters_final=false
+ sp_cleanup.make_private_fields_final=true
+ sp_cleanup.make_type_abstract_if_missing_method=false
+ sp_cleanup.make_variable_declarations_final=false
+ sp_cleanup.never_use_blocks=false
+ sp_cleanup.never_use_parentheses_in_expressions=true
 -sp_cleanup.on_save_use_additional_actions=true
++sp_cleanup.on_save_use_additional_actions=false
+ sp_cleanup.organize_imports=true
+ sp_cleanup.qualify_static_field_accesses_with_declaring_class=false
+ sp_cleanup.qualify_static_member_accesses_through_instances_with_declaring_class=true
+ sp_cleanup.qualify_static_member_accesses_through_subtypes_with_declaring_class=true
+ sp_cleanup.qualify_static_member_accesses_with_declaring_class=false
+ sp_cleanup.qualify_static_method_accesses_with_declaring_class=false
+ sp_cleanup.remove_private_constructors=true
 -sp_cleanup.remove_redundant_type_arguments=true
++sp_cleanup.remove_redundant_modifiers=false
++sp_cleanup.remove_redundant_type_arguments=false
+ sp_cleanup.remove_trailing_whitespaces=false
+ sp_cleanup.remove_trailing_whitespaces_all=true
+ sp_cleanup.remove_trailing_whitespaces_ignore_empty=false
+ sp_cleanup.remove_unnecessary_casts=true
+ sp_cleanup.remove_unnecessary_nls_tags=false
 -sp_cleanup.remove_unused_imports=true
++sp_cleanup.remove_unused_imports=false
+ sp_cleanup.remove_unused_local_variables=false
+ sp_cleanup.remove_unused_private_fields=true
+ sp_cleanup.remove_unused_private_members=false
+ sp_cleanup.remove_unused_private_methods=true
+ sp_cleanup.remove_unused_private_types=true
+ sp_cleanup.sort_members=false
+ sp_cleanup.sort_members_all=false
+ sp_cleanup.use_anonymous_class_creation=false
 -sp_cleanup.use_blocks=true
++sp_cleanup.use_blocks=false
+ sp_cleanup.use_blocks_only_for_return_and_throw=false
+ sp_cleanup.use_lambda=true
+ sp_cleanup.use_parentheses_in_expressions=false
+ sp_cleanup.use_this_for_non_static_field_access=false
+ sp_cleanup.use_this_for_non_static_field_access_only_if_necessary=true
+ sp_cleanup.use_this_for_non_static_method_access=false
+ sp_cleanup.use_this_for_non_static_method_access_only_if_necessary=true
  sp_cleanup.use_type_arguments=false
@@@ -32,7 -32,6 +32,6 @@@ import jalview.util.Comparison
  import jalview.viewmodel.ViewportListenerI;
  import jalview.viewmodel.ViewportRanges;
  
- import java.awt.AlphaComposite;
  import java.awt.BasicStroke;
  import java.awt.BorderLayout;
  import java.awt.Color;
@@@ -46,7 -45,7 +45,7 @@@ import java.beans.PropertyChangeEvent
  import java.util.Iterator;
  import java.util.List;
  
 -import javax.swing.JComponent;
 +import javax.swing.JPanel;
  
  /**
   * The Swing component on which the alignment sequences, and annotations (if
@@@ -54,7 -53,7 +53,7 @@@
   * Wrapped mode, but not the scale above in Unwrapped mode.
   * 
   */
 -public class SeqCanvas extends JComponent implements ViewportListenerI
 +public class SeqCanvas extends JPanel implements ViewportListenerI
  {
    private static final String ZEROS = "0000000000";
  
@@@ -89,8 -88,7 +88,8 @@@
  
    private int wrappedVisibleWidths; // number of wrapped widths displayed
  
 -  private Graphics2D gg;
 +  // Don't do this! Graphics handles are supposed to be transient
 +  //private Graphics2D gg;
  
    /**
     * Creates a new SeqCanvas object.
      int yPos = ypos + charHeight;
      int startX = startx;
      int endX = endx;
 -
 +    
      if (av.hasHiddenColumns())
      {
        HiddenColumns hiddenColumns = av.getAlignment().getHiddenColumns();
          }
        }
  
 +      
        /*
         * white fill the space for the scale
         */
          g.drawString(valueAsString, xOffset, y);
        }
      }
 +
    }
  
    /**
     */
    public void fastPaint(int horizontal, int vertical)
    {
 -    if (fastpainting || gg == null || img == null)
 +    if (fastpainting  || img == null)
      {
        return;
      }
        int transX = 0;
        int transY = 0;
        
 +      Graphics gg = img.getGraphics();
        gg.copyArea(horizontal * charWidth, vertical * charHeight,
                img.getWidth(), img.getHeight(), -horizontal * charWidth,
                -vertical * charHeight);
        gg.translate(transX, transY);
        drawPanel(gg, startRes, endRes, startSeq, endSeq, 0);
        gg.translate(-transX, -transY);
 -
 +      gg.dispose();
 +      
        // 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.
    @Override
    public void paintComponent(Graphics g)
    {
 -    super.paintComponent(g);    
 -    
 +    super.paintComponent(g);
 +
      int charHeight = av.getCharHeight();
      int charWidth = av.getCharWidth();
 -    
 +
      ViewportRanges ranges = av.getRanges();
 -    
 +
      int width = getWidth();
      int height = getHeight();
 -    
 +
      width -= (width % charWidth);
      height -= (height % charHeight);
 -    
 -    drawSelectionGroup((Graphics2D) g,
 -            ranges.getStartRes(), ranges.getEndRes(),
 -            ranges.getStartSeq(), ranges.getEndSeq());
 -    
 +
-     // selectImage is the selection group outline image
-     BufferedImage selectImage = drawSelectionGroup(ranges.getStartRes(),
-             ranges.getEndRes(), ranges.getStartSeq(), ranges.getEndSeq());
      if ((img != null) && (fastPaint
              || (getVisibleRect().width != g.getClipBounds().width)
              || (getVisibleRect().height != g.getClipBounds().height)))
      {
-       BufferedImage lcimg = buildLocalImage(selectImage);
-       g.drawImage(lcimg, 0, 0, this);
+       g.drawImage(img, 0, 0, this);
+       drawSelectionGroup((Graphics2D) g, ranges.getStartRes(),
+               ranges.getEndRes(), ranges.getStartSeq(), ranges.getEndSeq());
        fastPaint = false;
      }
-     else if ((width > 0) && (height > 0))
+     else if (width > 0 && height > 0)
      {
-       // img is a cached version of the last view we drew, if any
-       // if we have no img or the size has changed, make a new one
+       /*
+        * img is a cached version of the last view we drew, if any
+        * if we have no img or the size has changed, make a new one
+        */
        if (img == null || width != img.getWidth()
                || height != img.getHeight())
        {
-         img = setupImage();
-         if (img == null)
-         {
-           return;
-         }
+         img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
 -        gg = (Graphics2D) img.getGraphics();
 -        gg.setFont(av.getFont());
        }
 -    
 +      
 +      Graphics2D gg = (Graphics2D) img.getGraphics();
 +      gg.setFont(av.getFont());
 +
        if (av.antiAlias)
        {
          gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                  RenderingHints.VALUE_ANTIALIAS_ON);
        }
 -    
 +
        gg.setColor(Color.white);
        gg.fillRect(0, 0, img.getWidth(), img.getHeight());
 -    
 +
        if (av.getWrapAlignment())
        {
          drawWrappedPanel(gg, getWidth(), getHeight(), ranges.getStartRes());
          drawPanel(gg, ranges.getStartRes(), ranges.getEndRes(),
                  ranges.getStartSeq(), ranges.getEndSeq(), 0);
        }
-       
-       
-       gg.dispose();
  
-       // lcimg is a local *copy* of img which we'll draw selectImage on top of
-       BufferedImage lcimg = buildLocalImage(selectImage);
-       g.drawImage(lcimg, 0, 0, this);
+       drawSelectionGroup(gg, ranges.getStartRes(),
+               ranges.getEndRes(), ranges.getStartSeq(), ranges.getEndSeq());
  
+       g.drawImage(img, 0, 0, this);
      }
  
      if (av.cursorMode)
    {
      drawPanel(g1, startRes, endRes, startSeq, endSeq, 0);
  
-     BufferedImage selectImage = drawSelectionGroup(startRes, endRes,
+     drawSelectionGroup((Graphics2D) g1, startRes, endRes,
              startSeq, endSeq);
-     if (selectImage != null)
-     {
-       ((Graphics2D) g1).setComposite(AlphaComposite
-               .getInstance(AlphaComposite.SRC_OVER));
-       g1.drawImage(selectImage, 0, 0, this);
-     }
    }
  
    /**
    public void drawWrappedPanelForPrinting(Graphics g, int canvasWidth,
            int canvasHeight, int startRes)
    {
-     SequenceGroup group = av.getSelectionGroup();
      drawWrappedPanel(g, canvasWidth, canvasHeight, startRes);
  
+     SequenceGroup group = av.getSelectionGroup();
      if (group != null)
      {
-       BufferedImage selectImage = null;
-       try
-       {
-         selectImage = new BufferedImage(canvasWidth, canvasHeight,
-                 BufferedImage.TYPE_INT_ARGB); // ARGB so alpha compositing works
-       } catch (OutOfMemoryError er)
-       {
-         System.gc();
-         System.err.println("Print image OutOfMemory Error.\n" + er);
-         new OOMWarning("Creating wrapped alignment image for printing", er);
-       }
-       if (selectImage != null)
-       {
-         Graphics2D g2 = selectImage.createGraphics();
-         setupSelectionGroup(g2, selectImage);
-         drawWrappedSelection(g2, group, canvasWidth, canvasHeight,
+       drawWrappedSelection((Graphics2D) g, group, canvasWidth, canvasHeight,
                  startRes);
      }
    }
  
-   /*
-    * Make a local image by combining the cached image img
-    * with any selection
-    */
-   private BufferedImage buildLocalImage(BufferedImage selectImage)
-   {
-     // clone the cached image
-         BufferedImage lcimg = new BufferedImage(img.getWidth(), img.getHeight(),
-                   img.getType());
-     // BufferedImage lcimg = new BufferedImage(img.getWidth(), img.getHeight(),
-     // img.getType());
-     Graphics2D g2d = lcimg.createGraphics();
-     g2d.drawImage(img, 0, 0, null);
-     // overlay selection group on lcimg
-     if (selectImage != null)
-     {
-       g2d.setComposite(
-               AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
-       g2d.drawImage(selectImage, 0, 0, this);
-     }
-     g2d.dispose();
-     return lcimg;
-   }
-   /*
-    * Set up a buffered image of the correct height and size for the sequence canvas
-    */
-   private BufferedImage setupImage()
-   {
-     BufferedImage lcimg = null;
-     int charWidth = av.getCharWidth();
-     int charHeight = av.getCharHeight();
-     
-     int width = getWidth();
-     int height = getHeight();
-     width -= (width % charWidth);
-     height -= (height % charHeight);
-     if ((width < 1) || (height < 1))
-     {
-       return null;
-     }
-     try
-     {
-       lcimg = new BufferedImage(width, height,
-                 BufferedImage.TYPE_INT_ARGB); // ARGB so alpha compositing works
-     } catch (OutOfMemoryError er)
-     {
-       System.gc();
-       System.err.println(
-               "Group image OutOfMemory Redraw Error.\n" + er);
-       new OOMWarning("Creating alignment image for display", er);
-       return null;
-     }
-     return lcimg;
-   }
    /**
     * Returns the visible width of the canvas in residues, after allowing for
     * East or West scales (if shown)
      calculateWrappedGeometry(canvasWidth, canvasHeight);
  
      /*
 -     * draw one width at a time (including any scales or annotation shown),
 +     * draw one width at a time (excluding any scales or annotation shown),
       * until we have run out of either alignment or vertical space available
       */
      int ypos = wrappedSpaceAboveAlignment;
       */
      wrappedRepeatHeightPx = wrappedSpaceAboveAlignment;
      // add sequences
 -    wrappedRepeatHeightPx += av.getRanges().getViewportHeight()
 +    wrappedRepeatHeightPx += av.getAlignment().getHeight()
              * charHeight;
      // add annotations panel height if shown
      wrappedRepeatHeightPx += getAnnotationHeight();
      int xOffset = labelWidthWest
              + ((startColumn - ranges.getStartRes()) % viewportWidth)
              * charWidth;
 +
 +    // BH 2018 note: I have switched to using Graphics.create() here because it is 
 +    // more reliable (and simpler) to reset. The difference seems to be that SwingJS 
 +    // automatically sets a clipping region on an image to be the image dimensions, whereas
 +    // Java sets no clip for an image. (A bug? Go figure!)
 +    // Since we are using an off-screen BufferedImage here, the result is that g.getClip()
 +    // returns non-null in JavaScript but not Java. 
 +    //
 +    // Anyway, this works and, I suggest, is better design anyway. 
 +    // 
 +    // Graphics g = gg.create();
 +    // mc 30/08/18 undone because gnu.jpdf.PDFGraphics doesn't handle
 +    // get/setTransform
 +
      g.translate(xOffset, 0);
  
      // When printing we have an extra clipped region,
      // the Printable page which we need to account for here
      Shape clip = g.getClip();
 -
      if (clip == null)
      {
        g.setClip(0, 0, viewportWidth * charWidth, canvasHeight);
                viewportWidth * charWidth, (int) clip.getBounds().getHeight());
      }
  
 +
      /*
       * white fill the region to be drawn (so incremental fast paint doesn't
       * scribble over an existing image)
                startColumn, endx + 1);
        g.translate(0, -cHeight - ypos - 3);
      }
 -    g.setClip(clip);
 +    // g.dispose();
      g.translate(-xOffset, 0);
 +//    g.setClip(clip);
    }
  
    /**
      int charWidth = av.getCharWidth();
  
      g.setFont(av.getFont());
 +
      g.setColor(Color.black);
  
      int ypos = wrappedSpaceAboveAlignment;
        if (av.getScaleRightWrapped())
        {
          int x = labelWidthWest + viewportWidth * charWidth;
 +        
          g.translate(x, 0);
          drawVerticalScale(g, startCol, endColumn, ypos, false);
          g.translate(-x, 0);
  
      // 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.setColor(Color.RED);
      while ((ypos <= canvasHeight) && (startx < maxwidth))
      {
        // set end value to be start + width, or maxwidth, whichever is smaller
        // update horizontal offset
        startx += cWidth;
      }
+     g.setStroke(new BasicStroke());
    }
  
    int getAnnotationHeight()
  
    }
  
+   /**
+    * Draws the outlines of any groups defined on the alignment (excluding the
+    * current selection group, if any)
+    * 
+    * @param g1
+    * @param startRes
+    * @param endRes
+    * @param startSeq
+    * @param endSeq
+    * @param offset
+    */
    void drawGroupsBoundaries(Graphics g1, int startRes, int endRes,
            int startSeq, int endSeq, int offset)
    {
      Graphics2D g = (Graphics2D) g1;
-     //
-     // ///////////////////////////////////
-     // Now outline any areas if necessary
-     // ///////////////////////////////////
  
      SequenceGroup group = null;
      int groupIndex = -1;
  
      if (group != null)
      {
        do
        {
          g.setColor(group.getOutlineColour());
 -
          drawPartialGroupOutline(g, group, startRes, endRes, startSeq,
                  endSeq, offset);
  
          groupIndex++;
--
-         g.setStroke(new BasicStroke());
          if (groupIndex >= av.getAlignment().getGroups().size())
          {
            break;
          }
--
          group = av.getAlignment().getGroups().get(groupIndex);
--
        } while (groupIndex < av.getAlignment().getGroups().size());
--
      }
--
    }
  
-   /*
-    * Draw the selection group as a separate image and overlay
+   /**
+    * Draws the outline of the current selection group (if any)
+    * 
+    * @param g
+    * @param startRes
+    * @param endRes
+    * @param startSeq
+    * @param endSeq
     */
-   private BufferedImage drawSelectionGroup(int startRes, int endRes,
+   private void drawSelectionGroup(Graphics2D g, int startRes, int endRes,
            int startSeq, int endSeq)
    {
      SequenceGroup group = av.getSelectionGroup();
      if (group == null)
      {
-       // nothing to draw
-       return null;
+       return;
      }
  
-     // set up drawing colour
-     Graphics2D g = (Graphics2D) selectionImage.getGraphics();
-     setupSelectionGroup(g, selectionImage);
+     g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
+             BasicStroke.JOIN_ROUND, 3f, new float[]
+             { 5f, 3f }, 0f));
+     g.setColor(Color.RED);
      if (!av.getWrapAlignment())
      {
        drawUnwrappedSelection(g, group, startRes, endRes, startSeq, endSeq,
        drawWrappedSelection(g, group, getWidth(), getHeight(),
                av.getRanges().getStartRes());
      }
-     g.dispose();
-     return selectionImage;
+     g.setStroke(new BasicStroke());
    }
  
    /**
    }
  
  
-   /*
-    * Set up graphics for selection group
-    */
-   private void setupSelectionGroup(Graphics2D g,
-           BufferedImage selectionImage)
-   {
-     // set background to transparent
-     g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
-     g.fillRect(0, 0, selectionImage.getWidth(), selectionImage.getHeight());
-     // set up foreground to draw red dashed line
-     g.setComposite(AlphaComposite.Src);
-     g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
-             BasicStroke.JOIN_ROUND, 3f, new float[]
-     { 5f, 3f }, 0f));
-     g.setColor(Color.RED);
-   }
-   /*
+   /**
     * Draw a selection group over an unwrapped alignment
-    * @param g graphics object to draw with
-    * @param group selection group
-    * @param startRes start residue of area to draw
-    * @param endRes end residue of area to draw
-    * @param startSeq start sequence of area to draw
-    * @param endSeq end sequence of area to draw
-    * @param offset vertical offset (used when called from wrapped alignment code)
+    * 
+    * @param g
+    *          graphics object to draw with
+    * @param group
+    *          selection group
+    * @param startRes
+    *          start residue of area to draw
+    * @param endRes
+    *          end residue of area to draw
+    * @param startSeq
+    *          start sequence of area to draw
+    * @param endSeq
+    *          end sequence of area to draw
+    * @param offset
+    *          vertical offset (used when called from wrapped alignment code)
     */
    private void drawUnwrappedSelection(Graphics2D g, SequenceGroup group,
            int startRes, int endRes, int startSeq, int endSeq, int offset)
      }
    }
  
-   /*
-    * Draw the selection group as a separate image and overlay
+   /**
+    * Draws part of a selection group outline
+    * 
+    * @param g
+    * @param group
+    * @param startRes
+    * @param endRes
+    * @param startSeq
+    * @param endSeq
+    * @param verticalOffset
     */
    private void drawPartialGroupOutline(Graphics2D g, SequenceGroup group,
            int startRes, int endRes, int startSeq, int endSeq,
     * Highlights search results in the visible region by rendering as white text
     * on a black background. Any previous highlighting is removed. Answers true
     * if any highlight was left on the visible alignment (so status bar should be
 +   * set to match), else false. This method does _not_ set the 'fastPaint' flag,
 +   * so allows the next repaint to update the whole display.
 +   * 
 +   * @param results
 +   * @return
 +   */
 +  public boolean highlightSearchResults(SearchResultsI results)
 +  {
 +    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
 +   * if any highlight was left on the visible alignment (so status bar should be
     * set to match), else false.
     * <p>
 -   * Currently fastPaint is not implemented for wrapped alignments. If a wrapped
 -   * alignment had to be scrolled to show the highlighted region, then it should
 -   * be fully redrawn, otherwise a fast paint can be performed. This argument
 -   * could be removed if fast paint of scrolled wrapped alignment is coded in
 -   * future (JAL-2609).
 +   * Optionally, set the 'fastPaint' flag for a faster redraw if only the
 +   * highlighted regions are modified. This speeds up highlighting across linked
 +   * alignments.
 +   * <p>
 +   * Currently fastPaint is not implemented for scrolled wrapped alignments. If
 +   * a wrapped alignment had to be scrolled to show the highlighted region, then
 +   * it should be fully redrawn, otherwise a fast paint can be performed. This
 +   * argument could be removed if fast paint of scrolled wrapped alignment is
 +   * coded in future (JAL-2609).
     * 
     * @param results
 -   * @param noFastPaint
 +   * @param doFastPaint
 +   *          if true, sets a flag so the next repaint only redraws the modified
 +   *          image
     * @return
     */
    public boolean highlightSearchResults(SearchResultsI results,
 -          boolean noFastPaint)
 +          boolean doFastPaint)
    {
      if (fastpainting)
      {
      boolean wrapped = av.getWrapAlignment();
      try
      {
 -      fastPaint = !noFastPaint;
 +      fastPaint = doFastPaint;
        fastpainting = fastPaint;
  
        /*
     */
    protected boolean drawMappedPositions(SearchResultsI results)
    {
 -    if ((results == null) || (gg == null)) // JAL-2784 check gg is not null
 +    if ((results == null) || (img == null)) // JAL-2784 check gg is not null
      {
        return false;
      }
        }
        int transX = (firstCol - ranges.getStartRes()) * av.getCharWidth();
        int transY = (firstSeq - ranges.getStartSeq()) * av.getCharHeight();
 +      Graphics gg = img.getGraphics();
        gg.translate(transX, transY);
        drawPanel(gg, firstCol, lastCol, firstSeq, lastSeq, 0);
        gg.translate(-transX, -transY);
 +      gg.dispose();
      }
  
      return matchFound;
        return;
      }
  
 -    if (fastpainting || gg == null)
 +    if (fastpainting || img == null)
      {
        return;
      }
  
      try
      {
 +      
 +      Graphics gg = img.getGraphics();
 +      
        calculateWrappedGeometry(getWidth(), getHeight());
  
        /*
         */
        drawWrappedDecorators(gg, ranges.getStartRes());
  
 +      gg.dispose();
 +      
        repaint();
      } finally
      {
        return;
      }
  
 +    Graphics gg = img.getGraphics();
 +    
      ViewportRanges ranges = av.getRanges();
      int viewportWidth = ranges.getViewportWidth();
      int charWidth = av.getCharWidth();
        /*
         * white fill first to erase annotations
         */
 +      
 +      
        gg.translate(xOffset, 0);
        gg.setColor(Color.white);
        gg.fillRect(labelWidthWest, ypos,
        gg.translate(-xOffset, 0);
  
        drawWrappedWidth(gg, ypos, startRes, endRes, canvasHeight);
 +      
      }
  
      /*
        gg.setColor(Color.white);
        gg.fillRect(0, canvasHeight - heightBelow, getWidth(), heightBelow);
      }
 -  }
 +    gg.dispose();
 + }
  
    /**
     * Shifts the visible alignment by the specified number of columns - left if
      {
        return;
      }
 +
 +    Graphics gg = img.getGraphics();
 +
      int charWidth = av.getCharWidth();
  
      int canvasHeight = getHeight();
                    * charWidth, heightToCopy, widthToCopy,
                    -wrappedRepeatHeightPx);
          }
 -
          y += wrappedRepeatHeightPx;
          xpos += viewportWidth;
        }
      }
 +    gg.dispose();
    }
  
    
     */
    protected boolean drawMappedPositionsWrapped(SearchResultsI results)
    {
 -    if ((results == null) || (gg == null)) // JAL-2784 check gg is not null
 +    if ((results == null) || (img == null)) // JAL-2784 check gg is not null
      {
        return false;
      }
  
      int gapHeight = charHeight * (av.getScaleAboveWrapped() ? 2 : 1);
  
 +    
 +    Graphics gg = img.getGraphics();
 +
      for (int seqNo = ranges.getStartSeq(); seqNo <= ranges
              .getEndSeq(); seqNo++)
      {
        }
      }
    
 +    gg.dispose();
 +
      return matchFound;
    }