Formatting changes
[jalview.git] / src / jalview / gui / SeqCanvas.java
index c442465..841f929 100755 (executable)
  */\r
 package jalview.gui;\r
 \r
+import jalview.datamodel.*;\r
+\r
 import java.awt.*;\r
 import java.awt.image.*;\r
+\r
 import javax.swing.*;\r
 \r
-import jalview.analysis.*;\r
-import jalview.datamodel.*;\r
 \r
-public class SeqCanvas\r
-    extends JComponent\r
+/**\r
+ * DOCUMENT ME!\r
+ *\r
+ * @author $author$\r
+ * @version $Revision$\r
+ */\r
+public class SeqCanvas extends JComponent\r
 {\r
-  FeatureRenderer fr;\r
-  SequenceRenderer sr;\r
-  BufferedImage img;\r
-  Graphics2D gg;\r
-  int imgWidth;\r
-  int imgHeight;\r
-  AlignViewport av;\r
-  boolean showScores = false;\r
-  boolean displaySearch = false;\r
-  int[] searchResults = null;\r
-  int chunkHeight;\r
-  int chunkWidth;\r
-  boolean fastPaint = false;\r
-  int LABEL_WEST;\r
-  int LABEL_EAST;\r
-\r
-\r
-  public SeqCanvas(AlignViewport av)\r
-  {\r
-    this.av = av;\r
-    fr = new FeatureRenderer(av);\r
-    sr = new SequenceRenderer(av);\r
-    setLayout(new BorderLayout());\r
-    PaintRefresher.Register(this, av.alignment);\r
-    setBackground(Color.white);\r
-  }\r
-\r
-  void drawNorthScale(Graphics g, int startx, int endx, int ypos)\r
-  {\r
-    int scalestartx = startx - (startx % 10) + 10;\r
-\r
-    g.setColor(Color.black);\r
-\r
-    // NORTH SCALE\r
-    for (int i = scalestartx; i < endx; i += 10)\r
+    FeatureRenderer fr;\r
+    SequenceRenderer sr;\r
+    BufferedImage img;\r
+    Graphics2D gg;\r
+    int imgWidth;\r
+    int imgHeight;\r
+    AlignViewport av;\r
+    boolean showScores = false;\r
+    boolean displaySearch = false;\r
+    int[] searchResults = null;\r
+    int chunkHeight;\r
+    int chunkWidth;\r
+    boolean fastPaint = false;\r
+    int LABEL_WEST;\r
+    int LABEL_EAST;\r
+\r
+    /**\r
+     * Creates a new SeqCanvas object.\r
+     *\r
+     * @param av DOCUMENT ME!\r
+     */\r
+    public SeqCanvas(AlignViewport av)\r
     {\r
-      String string = String.valueOf(i);\r
-      g.drawString(string, (i - startx - 1) * av.charWidth,\r
-                   ypos - (av.charHeight / 2));\r
-\r
-      g.drawLine( ( (i - startx - 1) * av.charWidth) + (av.charWidth / 2),\r
-                 (ypos + 2) - (av.charHeight / 2),\r
-                 ( (i - startx - 1) * av.charWidth) + (av.charWidth / 2), ypos -\r
-                 2);\r
+        this.av = av;\r
+        fr = new FeatureRenderer(av);\r
+        sr = new SequenceRenderer(av);\r
+        setLayout(new BorderLayout());\r
+        PaintRefresher.Register(this, av.alignment);\r
+        setBackground(Color.white);\r
     }\r
-  }\r
 \r
-  void drawWestScale(Graphics g, int startx, int endx, int ypos)\r
-  {\r
-    FontMetrics fm = getFontMetrics(av.getFont());\r
-    ypos += av.charHeight;\r
+    /**\r
+     * DOCUMENT ME!\r
+     *\r
+     * @param g DOCUMENT ME!\r
+     * @param startx DOCUMENT ME!\r
+     * @param endx DOCUMENT ME!\r
+     * @param ypos DOCUMENT ME!\r
+     */\r
+    void drawNorthScale(Graphics g, int startx, int endx, int ypos)\r
+    {\r
+        int scalestartx = startx - (startx % 10) + 10;\r
+\r
+        g.setColor(Color.black);\r
 \r
-    // EAST SCALE\r
-    for (int i = 0; i < av.alignment.getHeight(); i++)\r
+        // NORTH SCALE\r
+        for (int i = scalestartx; i < endx; i += 10)\r
+        {\r
+            String string = String.valueOf(i);\r
+            g.drawString(string, (i - startx - 1) * av.charWidth,\r
+                ypos - (av.charHeight / 2));\r
+\r
+            g.drawLine(((i - startx - 1) * av.charWidth) + (av.charWidth / 2),\r
+                (ypos + 2) - (av.charHeight / 2),\r
+                ((i - startx - 1) * av.charWidth) + (av.charWidth / 2), ypos -\r
+                2);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * DOCUMENT ME!\r
+     *\r
+     * @param g DOCUMENT ME!\r
+     * @param startx DOCUMENT ME!\r
+     * @param endx DOCUMENT ME!\r
+     * @param ypos DOCUMENT ME!\r
+     */\r
+    void drawWestScale(Graphics g, int startx, int endx, int ypos)\r
     {\r
-      SequenceI seq = av.alignment.getSequenceAt(i);\r
-      int index = startx;\r
-      int value = -1;\r
+        FontMetrics fm = getFontMetrics(av.getFont());\r
+        ypos += av.charHeight;\r
 \r
-      while (index < endx)\r
-      {\r
-        if (jalview.util.Comparison.isGap(seq.getCharAt(index)))\r
+        // EAST SCALE\r
+        for (int i = 0; i < av.alignment.getHeight(); i++)\r
         {\r
-          index++;\r
+            SequenceI seq = av.alignment.getSequenceAt(i);\r
+            int index = startx;\r
+            int value = -1;\r
 \r
-          continue;\r
-        }\r
+            while (index < endx)\r
+            {\r
+                if (jalview.util.Comparison.isGap(seq.getCharAt(index)))\r
+                {\r
+                    index++;\r
 \r
-        value = av.alignment.getSequenceAt(i).findPosition(index);\r
+                    continue;\r
+                }\r
 \r
-        break;\r
-      }\r
+                value = av.alignment.getSequenceAt(i).findPosition(index);\r
 \r
-      if (value != -1)\r
-      {\r
-        int x = LABEL_WEST - fm.stringWidth(value + "");\r
-        g.drawString(value + "", x,\r
-                     (ypos + (i * av.charHeight)) - (av.charHeight / 5));\r
-      }\r
-    }\r
-  }\r
+                break;\r
+            }\r
 \r
-  void drawEastScale(Graphics g, int startx, int endx, int ypos)\r
-  {\r
-    ypos += av.charHeight;\r
+            if (value != -1)\r
+            {\r
+                int x = LABEL_WEST - fm.stringWidth(value + "");\r
+                g.drawString(value + "", x,\r
+                    (ypos + (i * av.charHeight)) - (av.charHeight / 5));\r
+            }\r
+        }\r
+    }\r
 \r
-    // EAST SCALE\r
-    for (int i = 0; i < av.alignment.getHeight(); i++)\r
+    /**\r
+     * DOCUMENT ME!\r
+     *\r
+     * @param g DOCUMENT ME!\r
+     * @param startx DOCUMENT ME!\r
+     * @param endx DOCUMENT ME!\r
+     * @param ypos DOCUMENT ME!\r
+     */\r
+    void drawEastScale(Graphics g, int startx, int endx, int ypos)\r
     {\r
-      SequenceI seq = av.alignment.getSequenceAt(i);\r
-      int index = endx;\r
-      int value = -1;\r
+        ypos += av.charHeight;\r
 \r
-      while (index > startx)\r
-      {\r
-        if (jalview.util.Comparison.isGap(seq.getCharAt(index)))\r
+        // EAST SCALE\r
+        for (int i = 0; i < av.alignment.getHeight(); i++)\r
         {\r
-          index--;\r
+            SequenceI seq = av.alignment.getSequenceAt(i);\r
+            int index = endx;\r
+            int value = -1;\r
 \r
-          continue;\r
-        }\r
+            while (index > startx)\r
+            {\r
+                if (jalview.util.Comparison.isGap(seq.getCharAt(index)))\r
+                {\r
+                    index--;\r
+\r
+                    continue;\r
+                }\r
 \r
-        value = av.alignment.getSequenceAt(i).findPosition(index);\r
+                value = av.alignment.getSequenceAt(i).findPosition(index);\r
 \r
-        break;\r
-      }\r
+                break;\r
+            }\r
 \r
-      if (value != -1)\r
-      {\r
-        g.drawString(value + "", 0,\r
-                     (ypos + (i * av.charHeight)) - (av.charHeight / 5));\r
-      }\r
+            if (value != -1)\r
+            {\r
+                g.drawString(value + "", 0,\r
+                    (ypos + (i * av.charHeight)) - (av.charHeight / 5));\r
+            }\r
+        }\r
     }\r
-  }\r
 \r
-  public void fastPaint(int horizontal, int vertical)\r
-  {\r
-    if ( ( (horizontal == 0) && (vertical == 0)) || (gg == null))\r
+    /**\r
+     * DOCUMENT ME!\r
+     *\r
+     * @param horizontal DOCUMENT ME!\r
+     * @param vertical DOCUMENT ME!\r
+     */\r
+    public void fastPaint(int horizontal, int vertical)\r
     {\r
-      return;\r
-    }\r
+        if (((horizontal == 0) && (vertical == 0)) || (gg == null))\r
+        {\r
+            return;\r
+        }\r
 \r
-    gg.copyArea(0, 0, imgWidth, imgHeight, -horizontal * av.charWidth,\r
-                -vertical * av.charHeight);\r
+        gg.copyArea(0, 0, imgWidth, imgHeight, -horizontal * av.charWidth,\r
+            -vertical * av.charHeight);\r
 \r
-    int sr = av.startRes;\r
-    int er = av.endRes;\r
-    int ss = av.startSeq;\r
-    int es = av.endSeq;\r
-    int transX = 0;\r
-    int transY = 0;\r
+        int sr = av.startRes;\r
+        int er = av.endRes;\r
+        int ss = av.startSeq;\r
+        int es = av.endSeq;\r
+        int transX = 0;\r
+        int transY = 0;\r
 \r
-    if (horizontal > 0) // scrollbar pulled right, image to the left\r
-    {\r
-      transX = (er - sr - horizontal) * av.charWidth;\r
-      sr = er - horizontal;\r
-    }\r
-    else if (horizontal < 0)\r
-    {\r
-      er = sr - horizontal;\r
-    }\r
-    else if (vertical > 0) // scroll down\r
-    {\r
-      ss = es - vertical;\r
-\r
-      if (ss < av.startSeq)\r
-      { // ie scrolling too fast, more than a page at a time\r
-        ss = av.startSeq;\r
-      }\r
-      else\r
-      {\r
-        transY = imgHeight - (vertical * av.charHeight);\r
-      }\r
-    }\r
-    else if (vertical < 0)\r
-    {\r
-      es = ss - vertical;\r
+        if (horizontal > 0) // scrollbar pulled right, image to the left\r
+        {\r
+            transX = (er - sr - horizontal) * av.charWidth;\r
+            sr = er - horizontal;\r
+        }\r
+        else if (horizontal < 0)\r
+        {\r
+            er = sr - horizontal;\r
+        }\r
+        else if (vertical > 0) // scroll down\r
+        {\r
+            ss = es - vertical;\r
 \r
-      if (es > av.endSeq)\r
-      {\r
-        es = av.endSeq;\r
-      }\r
-    }\r
+            if (ss < av.startSeq)\r
+            { // ie scrolling too fast, more than a page at a time\r
+                ss = av.startSeq;\r
+            }\r
+            else\r
+            {\r
+                transY = imgHeight - (vertical * av.charHeight);\r
+            }\r
+        }\r
+        else if (vertical < 0)\r
+        {\r
+            es = ss - vertical;\r
 \r
-    gg.translate(transX, transY);\r
-\r
-    gg.setColor(Color.white);\r
-    gg.fillRect(0, 0, (er - sr + 1) * av.charWidth,\r
-                (es - ss) * av.charHeight);\r
-    drawPanel(gg, sr, er, ss, es, sr, ss, 0);\r
-    gg.translate( -transX, -transY);\r
-\r
-    fastPaint = true;\r
-    repaint();\r
-  }\r
-\r
-  /**\r
-   * Definitions of startx and endx (hopefully):\r
-   * SMJS This is what I'm working towards!\r
-   *   startx is the first residue (starting at 0) to display.\r
-   *   endx   is the last residue to display (starting at 0).\r
-   *   starty is the first sequence to display (starting at 0).\r
-   *   endy   is the last sequence to display (starting at 0).\r
-   * NOTE 1: The av limits are set in setFont in this class and\r
-   * in the adjustment listener in SeqPanel when the scrollbars move.\r
-   */\r
-\r
-\r
-  // Set this to false to force a full panel paint\r
-  public void paintComponent(Graphics g)\r
-  {\r
-    if (img!=null\r
-        && (fastPaint  ||  getWidth() !=  g.getClipBounds().width\r
-            ||  getHeight() != g.getClipBounds().height))\r
-    {\r
-      g.drawImage(img, 0, 0, this);\r
-      fastPaint = false;\r
-      return;\r
-    }\r
+            if (es > av.endSeq)\r
+            {\r
+                es = av.endSeq;\r
+            }\r
+        }\r
 \r
-    // this draws the whole of the alignment\r
-    imgWidth = getWidth();\r
-    imgHeight = getHeight();\r
+        gg.translate(transX, transY);\r
 \r
-    imgWidth -= (imgWidth % av.charWidth);\r
-    imgHeight -= (imgHeight % av.charHeight);\r
+        gg.setColor(Color.white);\r
+        gg.fillRect(0, 0, (er - sr + 1) * av.charWidth,\r
+            (es - ss) * av.charHeight);\r
+        drawPanel(gg, sr, er, ss, es, sr, ss, 0);\r
+        gg.translate(-transX, -transY);\r
 \r
-    if ( (imgWidth < 1) || (imgHeight < 1))\r
-    {\r
-      return;\r
+        fastPaint = true;\r
+        repaint();\r
     }\r
 \r
-    img = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);\r
-    gg = (Graphics2D) img.getGraphics();\r
-    gg.setFont(av.getFont());\r
-    gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
-                        RenderingHints.VALUE_ANTIALIAS_ON);\r
+    /**\r
+     * Definitions of startx and endx (hopefully):\r
+     * SMJS This is what I'm working towards!\r
+     *   startx is the first residue (starting at 0) to display.\r
+     *   endx   is the last residue to display (starting at 0).\r
+     *   starty is the first sequence to display (starting at 0).\r
+     *   endy   is the last sequence to display (starting at 0).\r
+     * NOTE 1: The av limits are set in setFont in this class and\r
+     * in the adjustment listener in SeqPanel when the scrollbars move.\r
+     */\r
+\r
+    // Set this to false to force a full panel paint\r
+    public void paintComponent(Graphics g)\r
+    {\r
+        if ((img != null) &&\r
+                (fastPaint || (getWidth() != g.getClipBounds().width) ||\r
+                (getHeight() != g.getClipBounds().height)))\r
+        {\r
+            g.drawImage(img, 0, 0, this);\r
+            fastPaint = false;\r
 \r
-    gg.setColor(Color.white);\r
-    gg.fillRect(0, 0, imgWidth, imgHeight);\r
+            return;\r
+        }\r
 \r
-    chunkWidth = getWrappedCanvasWidth(getWidth());\r
-    chunkHeight = (av.getAlignment().getHeight() + 2) * av.charHeight;\r
+        // this draws the whole of the alignment\r
+        imgWidth = getWidth();\r
+        imgHeight = getHeight();\r
 \r
-    av.setChunkHeight(chunkHeight);\r
-    av.setChunkWidth(chunkWidth);\r
+        imgWidth -= (imgWidth % av.charWidth);\r
+        imgHeight -= (imgHeight % av.charHeight);\r
 \r
-    if (av.getWrapAlignment())\r
-    {\r
-      drawWrappedPanel(gg, getWidth(), getHeight(), av.startRes);\r
-    }\r
-    else\r
-    {\r
-      drawPanel(gg, av.startRes, av.endRes, av.startSeq, av.endSeq,\r
-                av.startRes, av.startSeq, 0);\r
-    }\r
+        if ((imgWidth < 1) || (imgHeight < 1))\r
+        {\r
+            return;\r
+        }\r
 \r
-    g.drawImage(img, 0, 0, this);\r
-  }\r
+        img = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);\r
+        gg = (Graphics2D) img.getGraphics();\r
+        gg.setFont(av.getFont());\r
+        gg.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
+            RenderingHints.VALUE_ANTIALIAS_ON);\r
 \r
-  public int getWrappedCanvasWidth(int cwidth)\r
-  {\r
-    FontMetrics fm = getFontMetrics(av.getFont());\r
+        gg.setColor(Color.white);\r
+        gg.fillRect(0, 0, imgWidth, imgHeight);\r
 \r
-    LABEL_EAST = 0;\r
-    LABEL_WEST = 0;\r
+        chunkWidth = getWrappedCanvasWidth(getWidth());\r
+        chunkHeight = (av.getAlignment().getHeight() + 2) * av.charHeight;\r
 \r
-    if (av.scaleRightWrapped)\r
-    {\r
-      LABEL_EAST = fm.stringWidth(av.alignment.getWidth() + "000");\r
+        av.setChunkHeight(chunkHeight);\r
+        av.setChunkWidth(chunkWidth);\r
+\r
+        if (av.getWrapAlignment())\r
+        {\r
+            drawWrappedPanel(gg, getWidth(), getHeight(), av.startRes);\r
+        }\r
+        else\r
+        {\r
+            drawPanel(gg, av.startRes, av.endRes, av.startSeq, av.endSeq,\r
+                av.startRes, av.startSeq, 0);\r
+        }\r
+\r
+        g.drawImage(img, 0, 0, this);\r
     }\r
 \r
-    if (av.scaleLeftWrapped)\r
+    /**\r
+     * DOCUMENT ME!\r
+     *\r
+     * @param cwidth DOCUMENT ME!\r
+     *\r
+     * @return DOCUMENT ME!\r
+     */\r
+    public int getWrappedCanvasWidth(int cwidth)\r
     {\r
-      LABEL_WEST = fm.stringWidth(av.alignment.getWidth() + "");\r
-    }\r
+        FontMetrics fm = getFontMetrics(av.getFont());\r
 \r
-    return (cwidth - LABEL_EAST - LABEL_WEST) / av.charWidth;\r
-  }\r
+        LABEL_EAST = 0;\r
+        LABEL_WEST = 0;\r
 \r
-  public void drawWrappedPanel(Graphics g, int canvasWidth, int canvasHeight,\r
-                               int startRes)\r
-  {\r
-    AlignmentI al = av.getAlignment();\r
+        if (av.scaleRightWrapped)\r
+        {\r
+            LABEL_EAST = fm.stringWidth(av.alignment.getWidth() + "000");\r
+        }\r
 \r
-    FontMetrics fm = getFontMetrics(av.getFont());\r
+        if (av.scaleLeftWrapped)\r
+        {\r
+            LABEL_WEST = fm.stringWidth(av.alignment.getWidth() + "");\r
+        }\r
 \r
-    int LABEL_EAST = 0;\r
+        return (cwidth - LABEL_EAST - LABEL_WEST) / av.charWidth;\r
+    }\r
 \r
-    if (av.scaleRightWrapped)\r
+    /**\r
+     * DOCUMENT ME!\r
+     *\r
+     * @param g DOCUMENT ME!\r
+     * @param canvasWidth DOCUMENT ME!\r
+     * @param canvasHeight DOCUMENT ME!\r
+     * @param startRes DOCUMENT ME!\r
+     */\r
+    public void drawWrappedPanel(Graphics g, int canvasWidth, int canvasHeight,\r
+        int startRes)\r
     {\r
-      LABEL_EAST = fm.stringWidth(al.getWidth() + "000");\r
-    }\r
+        AlignmentI al = av.getAlignment();\r
 \r
-    int LABEL_WEST = 0;\r
+        FontMetrics fm = getFontMetrics(av.getFont());\r
 \r
-    if (av.scaleLeftWrapped)\r
-    {\r
-      LABEL_WEST = fm.stringWidth(al.getWidth() + "0");\r
-    }\r
+        int LABEL_EAST = 0;\r
 \r
-    int cWidth = (canvasWidth - LABEL_EAST - LABEL_WEST) / av.charWidth;\r
-    int cHeight = (av.getAlignment().getHeight() + 2) * av.charHeight;\r
+        if (av.scaleRightWrapped)\r
+        {\r
+            LABEL_EAST = fm.stringWidth(al.getWidth() + "000");\r
+        }\r
 \r
-    av.endRes = av.startRes + cWidth;\r
+        int LABEL_WEST = 0;\r
 \r
-    int endx = (startRes + cWidth) - 1;\r
-    int ypos = 2 * av.charHeight;\r
+        if (av.scaleLeftWrapped)\r
+        {\r
+            LABEL_WEST = fm.stringWidth(al.getWidth() + "0");\r
+        }\r
 \r
-    while ( (ypos <= canvasHeight) && (startRes < av.alignment.getWidth()))\r
-    {\r
-      g.setColor(Color.black);\r
-\r
-      if (av.scaleLeftWrapped)\r
-      {\r
-        drawWestScale(g, startRes, endx, ypos);\r
-      }\r
-\r
-      if (av.scaleRightWrapped)\r
-      {\r
-        g.translate(canvasWidth - LABEL_EAST + av.charWidth, 0);\r
-        drawEastScale(g, startRes, endx, ypos);\r
-        g.translate( - (canvasWidth - LABEL_EAST + av.charWidth), 0);\r
-      }\r
-\r
-      g.translate(LABEL_WEST, 0);\r
-\r
-      if (av.scaleAboveWrapped)\r
-      {\r
-        drawNorthScale(g, startRes, endx, ypos);\r
-      }\r
-\r
-      // When printing we have an extra clipped region,\r
-      // the Printable page which we need to account for here\r
-      Shape clip = g.getClip();\r
-\r
-      if (clip == null)\r
-      {\r
-        g.setClip(0, 0, cWidth * av.charWidth, canvasHeight);\r
-      }\r
-      else\r
-      {\r
-        g.setClip(0, (int) clip.getBounds().getY(),\r
-                  cWidth * av.charWidth, (int) clip.getBounds().getHeight());\r
-      }\r
-\r
-      drawPanel(g, startRes, endx, 0, al.getHeight(), startRes, 0, ypos);\r
-      g.setClip(clip);\r
-      g.translate( -LABEL_WEST, 0);\r
-\r
-      ypos += cHeight;\r
-      startRes += cWidth;\r
-      endx = (startRes + cWidth) - 1;\r
-\r
-      if (endx > al.getWidth())\r
-      {\r
-        endx = al.getWidth();\r
-      }\r
-    }\r
-  }\r
+        int cWidth = (canvasWidth - LABEL_EAST - LABEL_WEST) / av.charWidth;\r
+        int cHeight = (av.getAlignment().getHeight() + 2) * av.charHeight;\r
 \r
-  synchronized public void drawPanel(Graphics g1, int x1, int x2, int y1,\r
-                                     int y2, int startx, int starty, int offset)\r
-  {\r
-    Graphics2D g = (Graphics2D) g1;\r
-    g.setFont(av.getFont());\r
-    sr.renderGaps(av.renderGaps);\r
+        av.endRes = av.startRes + cWidth;\r
 \r
-    SequenceI nextSeq;\r
+        int endx = (startRes + cWidth) - 1;\r
+        int ypos = 2 * av.charHeight;\r
 \r
-    /// First draw the sequences\r
-    /////////////////////////////\r
-    for (int i = y1; i < y2; i++)\r
-    {\r
-      nextSeq = av.alignment.getSequenceAt(i);\r
-\r
-      sr.drawSequence(g, nextSeq, av.alignment.findAllGroups(nextSeq),\r
-                      x1, x2, (x1 - startx) * av.charWidth,\r
-                      offset +\r
-                      AlignmentUtil.getPixelHeight(starty, i, av.charHeight),\r
-                      av.charWidth, av.charHeight);\r
-\r
-      if (av.showSequenceFeatures)\r
-      {\r
-        fr.drawSequence(g, nextSeq,\r
-                        av.alignment.findAllGroups(nextSeq), x1, x2,\r
-                        (x1 - startx) * av.charWidth,\r
-                        offset +\r
-                        AlignmentUtil.getPixelHeight(starty, i, av.charHeight),\r
-                        av.charWidth, av.charHeight);\r
-      }\r
-    }\r
+        while ((ypos <= canvasHeight) && (startRes < av.alignment.getWidth()))\r
+        {\r
+            g.setColor(Color.black);\r
 \r
-    //\r
-    /////////////////////////////////////\r
-    // Now outline any areas if necessary\r
-    /////////////////////////////////////\r
-    SequenceGroup group = av.getSelectionGroup();\r
-    java.util.Vector groups = av.alignment.getGroups();\r
+            if (av.scaleLeftWrapped)\r
+            {\r
+                drawWestScale(g, startRes, endx, ypos);\r
+            }\r
 \r
-    int sx = -1;\r
-    int sy = -1;\r
-    int ex = -1;\r
-    int groupIndex = -1;\r
+            if (av.scaleRightWrapped)\r
+            {\r
+                g.translate(canvasWidth - LABEL_EAST + av.charWidth, 0);\r
+                drawEastScale(g, startRes, endx, ypos);\r
+                g.translate(-(canvasWidth - LABEL_EAST + av.charWidth), 0);\r
+            }\r
 \r
-    if ( (group == null) && (groups.size() > 0))\r
-    {\r
-      group = (SequenceGroup) groups.elementAt(0);\r
-      groupIndex = 0;\r
-    }\r
+            g.translate(LABEL_WEST, 0);\r
 \r
-    if (group != null)\r
-    {\r
-      do\r
-      {\r
-        int oldY = -1;\r
-        int i = 0;\r
-        boolean inGroup = false;\r
-        int top = -1;\r
-        int bottom = -1;\r
-\r
-        for (i = y1; i < y2; i++)\r
-        {\r
-          sx = (group.getStartRes() - startx) * av.charWidth;\r
-          sy = offset +\r
-              AlignmentUtil.getPixelHeight(starty, i, av.charHeight);\r
-          ex = ( ( (group.getEndRes() + 1) - group.getStartRes()) *\r
-                av.charWidth) -\r
-              1;\r
-\r
-          if ( (sx < getWidth()) && (ex > 0) &&\r
-              group.sequences.contains(av.alignment.getSequenceAt(\r
-                  i)))\r
-          {\r
-            if ( (bottom == -1) &&\r
-                !group.sequences.contains(\r
-                    av.alignment.getSequenceAt(i + 1)))\r
+            if (av.scaleAboveWrapped)\r
             {\r
-              bottom = sy + av.charHeight;\r
+                drawNorthScale(g, startRes, endx, ypos);\r
             }\r
 \r
-            if (!inGroup)\r
+            // When printing we have an extra clipped region,\r
+            // the Printable page which we need to account for here\r
+            Shape clip = g.getClip();\r
+\r
+            if (clip == null)\r
             {\r
-              if ( ( (top == -1) && (i == 0)) ||\r
-                  !group.sequences.contains(\r
-                      av.alignment.getSequenceAt(i - 1)))\r
-              {\r
-                top = sy;\r
-              }\r
-\r
-              oldY = sy;\r
-              inGroup = true;\r
-\r
-              if (group == av.getSelectionGroup())\r
-              {\r
-                g.setStroke(new BasicStroke(1,\r
-                                            BasicStroke.CAP_BUTT,\r
-                                            BasicStroke.JOIN_ROUND, 3f,\r
-                                            new float[]\r
-                                            {5f, 3f}, 0f));\r
-                g.setColor(Color.RED);\r
-              }\r
-              else\r
-              {\r
-                g.setStroke(new BasicStroke());\r
-                g.setColor(group.getOutlineColour());\r
-              }\r
+                g.setClip(0, 0, cWidth * av.charWidth, canvasHeight);\r
             }\r
-          }\r
-          else\r
-          {\r
-            if (inGroup)\r
+            else\r
             {\r
-              g.drawLine(sx, oldY, sx, sy);\r
-              g.drawLine(sx + ex, oldY, sx + ex, sy);\r
-\r
-              if (top != -1)\r
-              {\r
-                g.drawLine(sx, top, sx + ex, top);\r
-                top = -1;\r
-              }\r
-\r
-              if (bottom != -1)\r
-              {\r
-                g.drawLine(sx, bottom, sx + ex, bottom);\r
-                bottom = -1;\r
-              }\r
-\r
-              inGroup = false;\r
+                g.setClip(0, (int) clip.getBounds().getY(),\r
+                    cWidth * av.charWidth, (int) clip.getBounds().getHeight());\r
+            }\r
+\r
+            drawPanel(g, startRes, endx, 0, al.getHeight(), startRes, 0, ypos);\r
+            g.setClip(clip);\r
+            g.translate(-LABEL_WEST, 0);\r
+\r
+            ypos += cHeight;\r
+            startRes += cWidth;\r
+            endx = (startRes + cWidth) - 1;\r
+\r
+            if (endx > al.getWidth())\r
+            {\r
+                endx = al.getWidth();\r
             }\r
-          }\r
         }\r
+    }\r
+\r
+    /**\r
+     * DOCUMENT ME!\r
+     *\r
+     * @param g1 DOCUMENT ME!\r
+     * @param x1 DOCUMENT ME!\r
+     * @param x2 DOCUMENT ME!\r
+     * @param y1 DOCUMENT ME!\r
+     * @param y2 DOCUMENT ME!\r
+     * @param startx DOCUMENT ME!\r
+     * @param starty DOCUMENT ME!\r
+     * @param offset DOCUMENT ME!\r
+     */\r
+    synchronized public void drawPanel(Graphics g1, int x1, int x2, int y1,\r
+        int y2, int startx, int starty, int offset)\r
+    {\r
+        Graphics2D g = (Graphics2D) g1;\r
+        g.setFont(av.getFont());\r
+        sr.renderGaps(av.renderGaps);\r
 \r
-        if (inGroup)\r
+        SequenceI nextSeq;\r
+\r
+        /// First draw the sequences\r
+        /////////////////////////////\r
+        for (int i = y1; i < y2; i++)\r
         {\r
-          if (top != -1)\r
-          {\r
-            g.drawLine(sx, top, sx + ex, top);\r
-            top = -1;\r
-          }\r
-\r
-          if (bottom != -1)\r
-          {\r
-            g.drawLine(sx, bottom - 1, sx + ex, bottom - 1);\r
-            bottom = -1;\r
-          }\r
-\r
-          sy = offset +\r
-              AlignmentUtil.getPixelHeight(starty, i, av.charHeight);\r
-          g.drawLine(sx, oldY, sx, sy);\r
-          g.drawLine(sx + ex, oldY, sx + ex, sy);\r
-          inGroup = false;\r
+            nextSeq = av.alignment.getSequenceAt(i);\r
+\r
+            sr.drawSequence(g, nextSeq, av.alignment.findAllGroups(nextSeq),\r
+                x1, x2, (x1 - startx) * av.charWidth,\r
+                offset + ((i - starty) * av.charHeight), av.charWidth,\r
+                av.charHeight);\r
+\r
+            if (av.showSequenceFeatures)\r
+            {\r
+                fr.drawSequence(g, nextSeq,\r
+                    av.alignment.findAllGroups(nextSeq), x1, x2,\r
+                    (x1 - startx) * av.charWidth,\r
+                    offset + ((i - starty) * av.charHeight), av.charWidth,\r
+                    av.charHeight);\r
+            }\r
         }\r
 \r
-        groupIndex++;\r
+        //\r
+        /////////////////////////////////////\r
+        // Now outline any areas if necessary\r
+        /////////////////////////////////////\r
+        SequenceGroup group = av.getSelectionGroup();\r
+        java.util.Vector groups = av.alignment.getGroups();\r
+\r
+        int sx = -1;\r
+        int sy = -1;\r
+        int ex = -1;\r
+        int groupIndex = -1;\r
 \r
-        if (groupIndex >= groups.size())\r
+        if ((group == null) && (groups.size() > 0))\r
         {\r
-          break;\r
+            group = (SequenceGroup) groups.elementAt(0);\r
+            groupIndex = 0;\r
         }\r
 \r
-        group = (SequenceGroup) groups.elementAt(groupIndex);\r
-      }\r
-      while (groupIndex < groups.size());\r
-    }\r
 \r
-    /// Highlight search Results once all sequences have been drawn\r
-    //////////////////////////////////////////////////////////\r
-    if (displaySearch)\r
-    {\r
-      for (int r = 0; r < searchResults.length; r += 3)\r
-      {\r
-        int searchSeq = searchResults[r];\r
+        if (group != null)\r
+        {\r
+            do\r
+            {\r
+                int oldY = -1;\r
+                int i = 0;\r
+                boolean inGroup = false;\r
+                int top = -1;\r
+                int bottom = -1;\r
+\r
+                for (i = y1; i < y2; i++)\r
+                {\r
+                    sx = (group.getStartRes() - startx) * av.charWidth;\r
+                    sy = offset + ((i - starty) * av.charHeight);\r
+                    ex = (((group.getEndRes() + 1) - group.getStartRes()) * av.charWidth) -\r
+                        1;\r
+\r
+\r
+                    if ((sx < (x2-x1)*av.charWidth) &&\r
+                            group.sequences.contains(av.alignment.getSequenceAt(\r
+                                    i)))\r
+                    {\r
+                        if ((bottom == -1) &&\r
+                                !group.sequences.contains(\r
+                                    av.alignment.getSequenceAt(i + 1)))\r
+                        {\r
+                            bottom = sy + av.charHeight;\r
+                        }\r
+\r
+                        if (!inGroup)\r
+                        {\r
+                            if (((top == -1) && (i == 0)) ||\r
+                                    !group.sequences.contains(\r
+                                        av.alignment.getSequenceAt(i - 1)))\r
+                            {\r
+                                top = sy;\r
+                            }\r
+\r
+                            oldY = sy;\r
+                            inGroup = true;\r
+\r
+                            if (group == av.getSelectionGroup())\r
+                            {\r
+                                g.setStroke(new BasicStroke(1,\r
+                                        BasicStroke.CAP_BUTT,\r
+                                        BasicStroke.JOIN_ROUND, 3f,\r
+                                        new float[] { 5f, 3f }, 0f));\r
+                                g.setColor(Color.RED);\r
+                            }\r
+                            else\r
+                            {\r
+                                g.setStroke(new BasicStroke());\r
+                                g.setColor(group.getOutlineColour());\r
+                            }\r
+                        }\r
+                    }\r
+                    else\r
+                    {\r
+                        if (inGroup)\r
+                        {\r
+                            g.drawLine(sx, oldY, sx, sy);\r
+                            g.drawLine(sx + ex, oldY, sx + ex, sy);\r
+\r
+                            if (top != -1)\r
+                            {\r
+                                g.drawLine(sx, top, sx + ex, top);\r
+                                top = -1;\r
+                            }\r
+\r
+                            if (bottom != -1)\r
+                            {\r
+                                g.drawLine(sx, bottom, sx + ex, bottom);\r
+                                bottom = -1;\r
+                            }\r
+\r
+                            inGroup = false;\r
+                        }\r
+                    }\r
+                }\r
+\r
+\r
+                if (inGroup)\r
+                {\r
+                    if (top != -1)\r
+                    {\r
+                        g.drawLine(sx, top, sx + ex, top);\r
+                        top = -1;\r
+                    }\r
+\r
+                    if (bottom != -1)\r
+                    {\r
+                        g.drawLine(sx, bottom - 1, sx + ex, bottom - 1);\r
+                        bottom = -1;\r
+                    }\r
+\r
+                    sy = offset + ((i - starty) * av.charHeight);\r
+                    g.drawLine(sx, oldY, sx, sy);\r
+                    g.drawLine(sx + ex, oldY, sx + ex, sy);\r
+                    inGroup = false;\r
+                }\r
+\r
+                groupIndex++;\r
+\r
+                if (groupIndex >= groups.size())\r
+                {\r
+                    break;\r
+                }\r
+\r
+                group = (SequenceGroup) groups.elementAt(groupIndex);\r
+            }\r
+            while (groupIndex < groups.size());\r
+        }\r
 \r
-        if ( (searchSeq >= y1) && (searchSeq < y2))\r
+        /// Highlight search Results once all sequences have been drawn\r
+        //////////////////////////////////////////////////////////\r
+        if (displaySearch)\r
         {\r
-          SequenceI seq = av.getAlignment().getSequenceAt(searchSeq);\r
+            for (int r = 0; r < searchResults.length; r += 3)\r
+            {\r
+                int searchSeq = searchResults[r];\r
+\r
+                if ((searchSeq >= y1) && (searchSeq < y2))\r
+                {\r
+                    SequenceI seq = av.getAlignment().getSequenceAt(searchSeq);\r
 \r
-          int searchStart = seq.findIndex(searchResults[r + 1]) - 1;\r
-          int searchEnd = seq.findIndex(searchResults[r + 2]) - 1;\r
+                    int searchStart = seq.findIndex(searchResults[r + 1]) - 1;\r
+                    int searchEnd = seq.findIndex(searchResults[r + 2]) - 1;\r
 \r
-          SequenceRenderer ssr = (SequenceRenderer) sr;\r
+                    SequenceRenderer ssr = (SequenceRenderer) sr;\r
 \r
-          if (searchStart < x1)\r
-          {\r
-            searchStart = x1;\r
-          }\r
+                    if (searchStart < x1)\r
+                    {\r
+                        searchStart = x1;\r
+                    }\r
 \r
-          if (searchEnd > x2)\r
-          {\r
-            searchEnd = x2;\r
-          }\r
+                    if (searchEnd > x2)\r
+                    {\r
+                        searchEnd = x2;\r
+                    }\r
 \r
-          ssr.drawHighlightedText(seq, searchStart, searchEnd,\r
-                                  (searchStart - startx) * av.charWidth,\r
-                                  offset +\r
-                                  AlignmentUtil.getPixelHeight(starty,\r
-              searchSeq,\r
-              av.charHeight), av.charWidth, av.charHeight);\r
+                    ssr.drawHighlightedText(seq, searchStart, searchEnd,\r
+                        (searchStart - startx) * av.charWidth,\r
+                        offset + ((searchSeq - starty) * av.charHeight),\r
+                        av.charWidth, av.charHeight);\r
+                }\r
+            }\r
         }\r
-      }\r
     }\r
-  }\r
 \r
-  public void highlightSearchResults(int[] results)\r
-  {\r
-    // results are in the order sequence, startRes, endRes\r
-    if (results == null)\r
+    /**\r
+     * DOCUMENT ME!\r
+     *\r
+     * @param results DOCUMENT ME!\r
+     */\r
+    public void highlightSearchResults(int[] results)\r
     {\r
-      displaySearch = false;\r
-    }\r
-    else\r
-    {\r
-      displaySearch = true;\r
-    }\r
+        // results are in the order sequence, startRes, endRes\r
+        if (results == null)\r
+        {\r
+            displaySearch = false;\r
+        }\r
+        else\r
+        {\r
+            displaySearch = true;\r
+        }\r
 \r
-    searchResults = results;\r
+        searchResults = results;\r
 \r
-    repaint();\r
-  }\r
+        repaint();\r
+    }\r
 }\r