nullpointer bug fix on consensus thread
[jalview.git] / src / jalview / gui / AlignmentPanel.java
index 2451a96..b11838c 100755 (executable)
@@ -1,6 +1,6 @@
 /*\r
  * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
+ * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
  *\r
  * This program is free software; you can redistribute it and/or\r
  * modify it under the terms of the GNU General Public License\r
  */\r
 package jalview.gui;\r
 \r
-import jalview.datamodel.*;\r
-\r
-import jalview.jbgui.*;\r
-\r
-import jalview.schemes.*;\r
+import java.beans.*;\r
+import java.io.*;\r
 \r
 import java.awt.*;\r
 import java.awt.event.*;\r
 import java.awt.print.*;\r
-\r
-import java.io.*;\r
-\r
 import javax.swing.*;\r
 \r
+import jalview.datamodel.*;\r
+import jalview.jbgui.*;\r
+import jalview.schemes.*;\r
 \r
 /**\r
  * DOCUMENT ME!\r
@@ -39,8 +36,8 @@ import javax.swing.*;
  * @author $author$\r
  * @version $Revision$\r
  */\r
-public class AlignmentPanel extends GAlignmentPanel\r
-    implements AdjustmentListener, Printable\r
+public class AlignmentPanel\r
+    extends GAlignmentPanel implements AdjustmentListener, Printable\r
 {\r
   public AlignViewport av;\r
   OverviewPanel overviewPanel;\r
@@ -81,165 +78,48 @@ public class AlignmentPanel extends GAlignmentPanel
     annotationPanel = new AnnotationPanel(this);\r
     alabels = new AnnotationLabels(this);\r
 \r
-\r
     annotationScroller.setViewportView(annotationPanel);\r
     annotationSpaceFillerHolder.add(alabels, BorderLayout.CENTER);\r
 \r
-    fontChanged();\r
-\r
     scalePanelHolder.add(scalePanel, BorderLayout.CENTER);\r
     seqPanelHolder.add(seqPanel, BorderLayout.CENTER);\r
 \r
     setScrollValues(0, 0);\r
 \r
-    adjustAnnotationHeight();\r
-\r
     setAnnotationVisible(av.getShowAnnotation());\r
 \r
     hscroll.addAdjustmentListener(this);\r
     vscroll.addAdjustmentListener(this);\r
 \r
-    af.addKeyListener(new KeyAdapter()\r
+    final AlignmentPanel ap = this;\r
+    av.addPropertyChangeListener(new PropertyChangeListener()\r
     {\r
-      public void keyPressed(KeyEvent evt)\r
+      public void propertyChange(PropertyChangeEvent evt)\r
       {\r
-        if(av.cursorMode\r
-           && evt.getKeyCode()>=KeyEvent.VK_0\r
-           && evt.getKeyCode()<=KeyEvent.VK_9)\r
+        if (evt.getPropertyName().equals("alignment"))\r
         {\r
-          seqPanel.numberPressed(evt.getKeyChar());\r
+          PaintRefresher.Refresh(ap,\r
+                                 av.getSequenceSetId(),\r
+                                 true,\r
+                                 true);\r
+          alignmentChanged();\r
         }\r
+      }\r
+    });\r
 \r
-        switch (evt.getKeyCode())\r
-        {\r
-          case 27: // escape key\r
-            alignFrame.deselectAllSequenceMenuItem_actionPerformed(null);\r
-\r
-            break;\r
-\r
-          case KeyEvent.VK_DOWN:\r
-            if(av.cursorMode)\r
-            {\r
-              seqPanel.moveCursor(0,1);\r
-            }\r
-            else\r
-              alignFrame.moveSelectedSequences(false);\r
-            break;\r
-\r
-          case KeyEvent.VK_UP:\r
-            if (av.cursorMode)\r
-            {\r
-              seqPanel.moveCursor(0,-1);\r
-            }\r
-            else\r
-              alignFrame.moveSelectedSequences(true);\r
-            break;\r
-\r
-          case KeyEvent.VK_LEFT:\r
-            if(av.cursorMode)\r
-            {\r
-              seqPanel.moveCursor(-1,0);\r
-            }\r
-            break;\r
-\r
-          case KeyEvent.VK_RIGHT:\r
-            if (av.cursorMode)\r
-            {\r
-              seqPanel.moveCursor(1,0);\r
-            }\r
-            break;\r
-\r
-          case KeyEvent.VK_SPACE:\r
-            if(av.cursorMode)\r
-            {\r
-              seqPanel.insertGapAtCursor(evt.isControlDown() || evt.isShiftDown());\r
-            }\r
-            break;\r
-\r
-          case KeyEvent.VK_DELETE:\r
-          case KeyEvent.VK_BACK_SPACE:\r
-            if(!av.cursorMode)\r
-            {\r
-              alignFrame.cut_actionPerformed(null);\r
-              seqPanel.seqCanvas.repaint();\r
-            }\r
-            else\r
-              seqPanel.deleteGapAtCursor(evt.isControlDown() || evt.isShiftDown());\r
-\r
-            break;\r
+    fontChanged();\r
+    adjustAnnotationHeight();\r
 \r
-          case KeyEvent.VK_S:\r
-            if(av.cursorMode)\r
-            {\r
-              seqPanel.setCursorRow();\r
-            }\r
-            break;\r
-          case KeyEvent.VK_C:\r
-            if(av.cursorMode && !evt.isControlDown())\r
-            {\r
-              seqPanel.setCursorColumn();\r
-            }\r
-            break;\r
-          case KeyEvent.VK_P:\r
-            if(av.cursorMode)\r
-            {\r
-              seqPanel.setCursorPosition();\r
-            }\r
-            break;\r
+  }\r
 \r
-          case KeyEvent.VK_ENTER:\r
-          case KeyEvent.VK_COMMA:\r
-            if(av.cursorMode)\r
-            {\r
-              seqPanel.setCursorRowAndColumn();\r
-            }\r
-            break;\r
+  public void alignmentChanged()\r
+  {\r
+    av.alignmentChanged(this);\r
 \r
-          case KeyEvent.VK_Q:\r
-            if(av.cursorMode)\r
-            {\r
-              seqPanel.setSelectionAreaAtCursor(true);\r
-            }\r
-            break;\r
-          case KeyEvent.VK_M:\r
-            if(av.cursorMode)\r
-            {\r
-              seqPanel.setSelectionAreaAtCursor(false);\r
-            }\r
-            break;\r
-\r
-         case KeyEvent.VK_F2:\r
-           av.cursorMode = ! av.cursorMode;\r
-           alignFrame.statusBar.setText("Keyboard editing mode is "+\r
-               (av.cursorMode ? "on" : "off"));\r
-           if(av.cursorMode)\r
-           {\r
-             seqPanel.seqCanvas.cursorX = av.startRes;\r
-             seqPanel.seqCanvas.cursorY = av.startSeq;\r
-           }\r
-           seqPanel.seqCanvas.repaint();\r
-           break;\r
-\r
-          case KeyEvent.VK_F1:\r
-            try\r
-            {\r
-              ClassLoader cl = jalview.gui.Desktop.class.getClassLoader();\r
-              java.net.URL url = javax.help.HelpSet.findHelpSet(cl, "help/help");\r
-              javax.help.HelpSet hs = new javax.help.HelpSet(cl, url);\r
+    alignFrame.updateEditMenuBar();\r
 \r
-              javax.help.HelpBroker hb = hs.createHelpBroker();\r
-              hb.setCurrentID("home");\r
-              hb.setDisplayed(true);\r
-            }\r
-            catch (Exception ex)\r
-            {\r
-              ex.printStackTrace();\r
-            }\r
-            break;\r
+    paintAlignment(true);\r
 \r
-        }\r
-      }\r
-    });\r
   }\r
 \r
   /**\r
@@ -265,21 +145,10 @@ public class AlignmentPanel extends GAlignmentPanel
     idPanel.idCanvas.setPreferredSize(d);\r
     hscrollFillerPanel.setPreferredSize(d);\r
 \r
-    if (av.getWrapAlignment())\r
-    {\r
-      int max = av.alignment.getWidth() /\r
-          seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
-      vscroll.setMaximum(max);\r
-      vscroll.setUnitIncrement(1);\r
-      vscroll.setVisibleAmount(1);\r
-    }\r
-    else\r
-    {\r
-      setScrollValues(av.getStartRes(), av.getStartSeq());\r
-    }\r
-\r
     if (overviewPanel != null)\r
+    {\r
       overviewPanel.setBoxPosition();\r
+    }\r
 \r
     repaint();\r
   }\r
@@ -293,7 +162,9 @@ public class AlignmentPanel extends GAlignmentPanel
   {\r
     Container c = new Container();\r
 \r
-    FontMetrics fm = c.getFontMetrics(av.font);\r
+    FontMetrics fm = c.getFontMetrics(\r
+        new Font(av.font.getName(), Font.ITALIC, av.font.getSize()));\r
+\r
     AlignmentI al = av.getAlignment();\r
 \r
     int i = 0;\r
@@ -354,10 +225,10 @@ public class AlignmentPanel extends GAlignmentPanel
       int start = seq.findIndex(results.getResultStart(0)) - 1;\r
       int end = seq.findIndex(results.getResultEnd(0)) - 1;\r
 \r
-      if(!av.wrapAlignment)\r
+      if (!av.wrapAlignment)\r
       {\r
-        if ( (av.getStartRes() > end)  || (av.getEndRes() < start) ||\r
-           ( (av.getStartSeq() > seqIndex) || (av.getEndSeq() < seqIndex)))\r
+        if ( (av.getStartRes() > end) || (av.getEndRes() < start) ||\r
+            ( (av.getStartSeq() > seqIndex) || (av.getEndSeq() < seqIndex)))\r
         {\r
           setScrollValues(start, seqIndex);\r
         }\r
@@ -367,12 +238,15 @@ public class AlignmentPanel extends GAlignmentPanel
         scrollToWrappedVisible(start);\r
       }\r
     }\r
+\r
+    paintAlignment(true);\r
   }\r
 \r
   void scrollToWrappedVisible(int res)\r
   {\r
-    int cwidth = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());\r
-    if( res<=av.getStartRes() || res>=(av.getStartRes()+cwidth) )\r
+    int cwidth = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.\r
+        getWidth());\r
+    if (res <= av.getStartRes() || res >= (av.getStartRes() + cwidth))\r
     {\r
       vscroll.setValue(res / cwidth);\r
       av.startRes = vscroll.getValue() * cwidth;\r
@@ -416,33 +290,33 @@ public class AlignmentPanel extends GAlignmentPanel
 \r
   public void adjustAnnotationHeight()\r
   {\r
-    javax.swing.SwingUtilities.invokeLater(new Runnable()\r
+    if (alignFrame.getHeight() == 0)\r
     {\r
-      public void run()\r
-      {\r
-          while(alignFrame.getHeight()==0)\r
-          {\r
-            Thread.yield();\r
-          }\r
+      System.out.println("NEEDS FIXING");\r
+    }\r
 \r
-        int height = annotationPanel.adjustPanelHeight();\r
+    int height = annotationPanel.adjustPanelHeight();\r
 \r
-        if (height > alignFrame.getHeight() / 2)\r
-        {\r
-          height = alignFrame.getHeight() / 2;\r
-        }\r
+    if (hscroll.isVisible())\r
+    {\r
+      height += hscroll.getPreferredSize().height;\r
+    }\r
+    if (height > alignFrame.getHeight() / 2)\r
+    {\r
+      height = alignFrame.getHeight() / 2;\r
+    }\r
 \r
-        annotationScroller.setPreferredSize(\r
-            new Dimension(annotationScroller.getWidth(),\r
-                          height));\r
+    hscroll.addNotify();\r
 \r
-        annotationSpaceFillerHolder.setPreferredSize(new Dimension(\r
-            annotationSpaceFillerHolder.getWidth(),\r
-            height));\r
+    annotationScroller.setPreferredSize(\r
+        new Dimension(annotationScroller.getWidth(), height));\r
 \r
-        annotationPanel.repaint();\r
-      }\r
-    });\r
+\r
+    annotationSpaceFillerHolder.setPreferredSize(new Dimension(\r
+        annotationSpaceFillerHolder.getWidth(),\r
+        height));\r
+\r
+    repaint();\r
   }\r
 \r
   /**\r
@@ -549,10 +423,12 @@ public class AlignmentPanel extends GAlignmentPanel
     int width = av.alignment.getWidth();\r
     int height = av.alignment.getHeight();\r
 \r
-    if(av.hasHiddenColumns)\r
-     width = av.getColumnSelection().findColumnPosition(width);\r
+    if (av.hasHiddenColumns)\r
+    {\r
+      width = av.getColumnSelection().findColumnPosition(width);\r
+    }\r
 \r
-    av.setEndRes( (x + (seqPanel.seqCanvas.getWidth() / av.charWidth)) -1);\r
+    av.setEndRes( (x + (seqPanel.seqCanvas.getWidth() / av.charWidth)) - 1);\r
 \r
     hextent = seqPanel.seqCanvas.getWidth() / av.charWidth;\r
     vextent = seqPanel.seqCanvas.getHeight() / av.charHeight;\r
@@ -616,7 +492,7 @@ public class AlignmentPanel extends GAlignmentPanel
 \r
       if (av.getWrapAlignment())\r
       {\r
-        if(offy>-1)\r
+        if (offy > -1)\r
         {\r
           int rowSize = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.\r
               seqCanvas.getWidth());\r
@@ -629,12 +505,12 @@ public class AlignmentPanel extends GAlignmentPanel
           //was wrapped when saved and user has wrap alignment true\r
           //as preference setting\r
           SwingUtilities.invokeLater(new Runnable()\r
-              {\r
-                public void run()\r
-                {\r
-                  setScrollValues(av.getStartRes(), av.getStartSeq());\r
-                }\r
-              });\r
+          {\r
+            public void run()\r
+            {\r
+              setScrollValues(av.getStartRes(), av.getStartSeq());\r
+            }\r
+          });\r
         }\r
       }\r
       else\r
@@ -661,12 +537,16 @@ public class AlignmentPanel extends GAlignmentPanel
     {\r
       // Make sure we're not trying to draw a panel\r
       // larger than the visible window\r
-      if(scrollX>av.endRes-av.startRes)\r
-        scrollX = av.endRes-av.startRes;\r
-      else if(scrollX<av.startRes-av.endRes)\r
+      if (scrollX > av.endRes - av.startRes)\r
+      {\r
+        scrollX = av.endRes - av.startRes;\r
+      }\r
+      else if (scrollX < av.startRes - av.endRes)\r
+      {\r
         scrollX = av.startRes - av.endRes;\r
+      }\r
 \r
-      if(scrollX!=0 || scrollY!=0)\r
+      if (scrollX != 0 || scrollY != 0)\r
       {\r
         idPanel.idCanvas.fastPaint(scrollY);\r
         seqPanel.seqCanvas.fastPaint(scrollX,\r
@@ -681,6 +561,22 @@ public class AlignmentPanel extends GAlignmentPanel
     }\r
   }\r
 \r
+  public void paintAlignment(boolean updateOverview)\r
+  {\r
+    repaint();\r
+\r
+    if(updateOverview)\r
+    {\r
+      jalview.structure.StructureSelectionManager.getStructureSelectionManager()\r
+          .sequenceColoursChanged(this);\r
+\r
+      if (overviewPanel != null)\r
+      {\r
+        overviewPanel.updateOverviewImage();\r
+      }\r
+    }\r
+  }\r
+\r
   /**\r
    * DOCUMENT ME!\r
    *\r
@@ -700,26 +596,27 @@ public class AlignmentPanel extends GAlignmentPanel
       int maxwidth = av.alignment.getWidth();\r
 \r
       if (av.hasHiddenColumns)\r
+      {\r
         maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;\r
+      }\r
 \r
-      int max = maxwidth /\r
-          seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth()) +\r
-          1;\r
-\r
-\r
-      vscroll.setMaximum(max);\r
-      vscroll.setUnitIncrement(1);\r
-      vscroll.setVisibleAmount(1);\r
+      int canvasWidth = seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.\r
+          seqCanvas.getWidth());\r
+      if (canvasWidth > 0)\r
+      {\r
+        int max = maxwidth /\r
+            seqPanel.seqCanvas.getWrappedCanvasWidth(seqPanel.seqCanvas.\r
+            getWidth()) +\r
+            1;\r
+        vscroll.setMaximum(max);\r
+        vscroll.setUnitIncrement(1);\r
+        vscroll.setVisibleAmount(1);\r
+      }\r
     }\r
     else\r
     {\r
       setScrollValues(av.getStartRes(), av.getStartSeq());\r
     }\r
-\r
-    if( this.getVisibleRect().getBounds() == g.getClipBounds()\r
-        && overviewPanel != null)\r
-        overviewPanel.updateOverviewImage();\r
-\r
   }\r
 \r
   /**\r
@@ -766,7 +663,7 @@ public class AlignmentPanel extends GAlignmentPanel
   public int printUnwrapped(Graphics pg, int pwidth, int pheight, int pi)\r
       throws PrinterException\r
   {\r
-    int idWidth = calculateIdWidth().width + 4;\r
+    int idWidth = getVisibleIdWidth();\r
     FontMetrics fm = getFontMetrics(av.getFont());\r
     int scaleHeight = av.charHeight + fm.getDescent();\r
 \r
@@ -838,21 +735,21 @@ public class AlignmentPanel extends GAlignmentPanel
     Color currentColor = null;\r
     Color currentTextColor = null;\r
 \r
-    pg.setFont(new Font(av.getFont().getName(),\r
-                        Font.ITALIC,\r
-                        av.getFont().getSize()));\r
+    pg.setFont(idPanel.idCanvas.idfont);\r
+\r
+    SequenceI seq;\r
     for (int i = startSeq; i < endSeq; i++)\r
     {\r
+      seq = av.getAlignment().getSequenceAt(i);\r
       if ( (av.getSelectionGroup() != null) &&\r
-          av.getSelectionGroup().getSequences(false).contains(\r
-              av.getAlignment().getSequenceAt(i)))\r
+          av.getSelectionGroup().getSequences(null).contains(seq))\r
       {\r
         currentColor = Color.gray;\r
         currentTextColor = Color.black;\r
       }\r
       else\r
       {\r
-        currentColor = av.getAlignment().getSequenceAt(i).getColor();\r
+        currentColor = av.getSequenceColour(seq);\r
         currentTextColor = Color.black;\r
       }\r
 \r
@@ -862,10 +759,17 @@ public class AlignmentPanel extends GAlignmentPanel
 \r
       pg.setColor(currentTextColor);\r
 \r
-      String string = av.getAlignment().getSequenceAt(i).getDisplayId\r
-          ( av.getShowJVSuffix());\r
+      int xPos = 0;\r
+      if (av.rightAlignIds)\r
+      {\r
+        fm = pg.getFontMetrics();\r
+        xPos = idWidth - fm.stringWidth(\r
+            seq.getDisplayId(av.getShowJVSuffix())\r
+            ) - 4;\r
+      }\r
 \r
-      pg.drawString(string, 0,\r
+      pg.drawString(seq.getDisplayId(av.getShowJVSuffix()),\r
+                    xPos,\r
                     ( ( (i - startSeq) * av.charHeight) + av.getCharHeight()) -\r
                     (av.getCharHeight() / 5));\r
     }\r
@@ -878,9 +782,9 @@ public class AlignmentPanel extends GAlignmentPanel
 \r
     if (av.showAnnotation && (endSeq == av.alignment.getHeight()))\r
     {\r
-      pg.translate( -idWidth-3, (endSeq - startSeq) * av.charHeight + 3);\r
+      pg.translate( -idWidth - 3, (endSeq - startSeq) * av.charHeight + 3);\r
       alabels.drawComponent( (Graphics2D) pg, idWidth);\r
-      pg.translate(idWidth+3, 0);\r
+      pg.translate(idWidth + 3, 0);\r
       annotationPanel.drawComponent( (Graphics2D) pg, startRes, endRes +\r
                                     1);\r
     }\r
@@ -915,18 +819,21 @@ public class AlignmentPanel extends GAlignmentPanel
 \r
     int hgap = av.charHeight;\r
     if (av.scaleAboveWrapped)\r
+    {\r
       hgap += av.charHeight;\r
+    }\r
 \r
     int cHeight = av.getAlignment().getHeight() * av.charHeight\r
         + hgap\r
         + annotationHeight;\r
 \r
-    int idWidth = calculateIdWidth().width + 4;\r
+    int idWidth = getVisibleIdWidth();\r
 \r
     int maxwidth = av.alignment.getWidth();\r
     if (av.hasHiddenColumns)\r
+    {\r
       maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;\r
-\r
+    }\r
 \r
     int resWidth = seqPanel.seqCanvas.getWrappedCanvasWidth(pwidth -\r
         idWidth);\r
@@ -946,31 +853,33 @@ public class AlignmentPanel extends GAlignmentPanel
     pg.setClip(0, pi * pheight, pwidth, pheight);\r
 \r
     int ypos = hgap;\r
-    Font italic = new Font(av.getFont().getName(), Font.ITALIC,\r
-                           av.getFont().getSize());\r
-    pg.setFont(italic);\r
 \r
     do\r
     {\r
       for (int i = 0; i < av.alignment.getHeight(); i++)\r
       {\r
+        pg.setFont(idPanel.idCanvas.idfont);\r
         SequenceI s = av.alignment.getSequenceAt(i);\r
-        String string = s.getDisplayId( av.getShowJVSuffix());\r
-\r
-        pg.drawString(string, 0,\r
+        String string = s.getDisplayId(av.getShowJVSuffix());\r
+        int xPos = 0;\r
+        if (av.rightAlignIds)\r
+        {\r
+          FontMetrics fm = pg.getFontMetrics();\r
+          xPos = idWidth - fm.stringWidth(string) - 4;\r
+        }\r
+        pg.drawString(string, xPos,\r
                       ( (i * av.charHeight) + ypos + av.charHeight) -\r
                       (av.charHeight / 5));\r
       }\r
       if (labels != null)\r
       {\r
-        pg.translate(-3,\r
+        pg.translate( -3,\r
                      ypos +\r
                      (av.getAlignment().getHeight() * av.charHeight));\r
 \r
         pg.setFont(av.getFont());\r
         labels.drawComponent(pg, idWidth);\r
-        pg.setFont(italic);\r
-        pg.translate(+3,\r
+        pg.translate( +3,\r
                      -ypos -\r
                      (av.getAlignment().getHeight() * av.charHeight));\r
       }\r
@@ -994,29 +903,40 @@ public class AlignmentPanel extends GAlignmentPanel
     }\r
   }\r
 \r
+  int getVisibleIdWidth()\r
+  {\r
+    return\r
+        idPanel.getWidth() > 0 ? idPanel.getWidth() :\r
+        calculateIdWidth().width + 4;\r
+  }\r
+\r
   void makeAlignmentImage(int type, File file)\r
   {\r
     int maxwidth = av.alignment.getWidth();\r
     if (av.hasHiddenColumns)\r
-      maxwidth = av.getColumnSelection().findColumnPosition(maxwidth);\r
-\r
-    int height = ( (av.alignment.getHeight() + 1) * av.charHeight) + 30;\r
-    int width = idPanel.getWidth() + (maxwidth * av.charWidth);\r
-    if (idPanel.getWidth() == 0)\r
     {\r
-      width += calculateIdWidth().getWidth() + 4;\r
+      maxwidth = av.getColumnSelection().findColumnPosition(maxwidth);\r
     }\r
 \r
+    int height = ( (av.alignment.getHeight() + 1) * av.charHeight)\r
+        + scalePanel.getHeight();\r
+    int width = getVisibleIdWidth() + (maxwidth * av.charWidth);\r
+\r
     if (av.getWrapAlignment())\r
     {\r
       height = getWrappedHeight();\r
       if (System.getProperty("java.awt.headless") != null\r
           && System.getProperty("java.awt.headless").equals("true"))\r
       {\r
-        width = alignFrame.getWidth() - 22;\r
+        width = alignFrame.getWidth()\r
+            - vscroll.getPreferredSize().width\r
+            - alignFrame.getInsets().left\r
+            - alignFrame.getInsets().right;\r
       }\r
       else\r
-        width = seqPanel.getWidth() + idPanel.getWidth();\r
+      {\r
+        width = seqPanel.getWidth() + getVisibleIdWidth();\r
+      }\r
 \r
     }\r
     else if (av.getShowAnnotation())\r
@@ -1024,23 +944,29 @@ public class AlignmentPanel extends GAlignmentPanel
       height += annotationPanel.adjustPanelHeight() + 3;\r
     }\r
 \r
-    jalview.util.ImageMaker im;\r
-    if(type==jalview.util.ImageMaker.PNG)\r
-      im  = new jalview.util.ImageMaker(this,\r
-                                        jalview.util.ImageMaker.PNG,\r
-                                        "Create PNG image from alignment",\r
-                                        width, height, file, null);\r
-    else\r
-      im = new jalview.util.ImageMaker(this,\r
-                                        jalview.util.ImageMaker.EPS,\r
-                                       "Create EPS file from alignment",\r
-                                        width, height, file, alignFrame.getTitle() );\r
-\r
     try\r
     {\r
+\r
+      jalview.util.ImageMaker im;\r
+      if (type == jalview.util.ImageMaker.PNG)\r
+      {\r
+        im = new jalview.util.ImageMaker(this,\r
+                                         jalview.util.ImageMaker.PNG,\r
+                                         "Create PNG image from alignment",\r
+                                         width, height, file, null);\r
+      }\r
+      else\r
+      {\r
+        im = new jalview.util.ImageMaker(this,\r
+                                         jalview.util.ImageMaker.EPS,\r
+                                         "Create EPS file from alignment",\r
+                                         width, height, file,\r
+                                         alignFrame.getTitle());\r
+      }\r
+\r
       if (av.getWrapAlignment())\r
       {\r
-        if(im.getGraphics()!=null)\r
+        if (im.getGraphics() != null)\r
         {\r
           printWrappedAlignment(im.getGraphics(), width, height, 0);\r
           im.writeImage();\r
@@ -1048,7 +974,7 @@ public class AlignmentPanel extends GAlignmentPanel
       }\r
       else\r
       {\r
-        if(im.getGraphics()!=null)\r
+        if (im.getGraphics() != null)\r
         {\r
           printUnwrapped(im.getGraphics(), width, height, 0);\r
           im.writeImage();\r
@@ -1076,6 +1002,7 @@ public class AlignmentPanel extends GAlignmentPanel
       ex.printStackTrace();\r
     }\r
   }\r
+\r
   /**\r
    * DOCUMENT ME!\r
    */\r
@@ -1096,7 +1023,7 @@ public class AlignmentPanel extends GAlignmentPanel
   {\r
     ///////ONLY WORKS WITH NONE WRAPPED ALIGNMENTS\r
     //////////////////////////////////////////////\r
-    int idWidth = calculateIdWidth().width + 4;\r
+    int idWidth = getVisibleIdWidth();\r
     FontMetrics fm = getFontMetrics(av.getFont());\r
     int scaleHeight = av.charHeight + fm.getDescent();\r
 \r
@@ -1120,92 +1047,107 @@ public class AlignmentPanel extends GAlignmentPanel
           sy = s * av.charHeight + scaleHeight;\r
 \r
           SequenceI seq = av.alignment.getSequenceAt(s);\r
-          SequenceFeature [] features = seq.getDatasetSequence().getSequenceFeatures();\r
+          SequenceFeature[] features = seq.getDatasetSequence().\r
+              getSequenceFeatures();\r
           SequenceGroup[] groups = av.alignment.findAllGroups(seq);\r
-          for(res =0; res<alwidth; res++)\r
+          for (res = 0; res < alwidth; res++)\r
           {\r
             text = new StringBuffer();\r
             Object obj = null;\r
-            if(av.alignment.isNucleotide())\r
-              obj = ResidueProperties.nucleotideName.get(seq.getCharAt(res)+"" );\r
+            if (av.alignment.isNucleotide())\r
+            {\r
+              obj = ResidueProperties.nucleotideName.get(seq.getCharAt(res) +\r
+                  "");\r
+            }\r
             else\r
+            {\r
               obj = ResidueProperties.aa2Triplet.get(\r
-                    seq.getCharAt(res) + "");\r
+                  seq.getCharAt(res) + "");\r
+            }\r
 \r
-              if (obj == null)\r
-                  continue;\r
+            if (obj == null)\r
+            {\r
+              continue;\r
+            }\r
 \r
             String triplet = obj.toString();\r
             int alIndex = seq.findPosition(res);\r
             gSize = groups.length;\r
             for (g = 0; g < gSize; g++)\r
             {\r
-              if(text.length()<1)\r
+              if (text.length() < 1)\r
               {\r
                 text.append("<area shape=\"rect\" coords=\""\r
-                  + (idWidth + res * av.charWidth) + ","\r
-                  + sy + ","\r
-                  + (idWidth + (res + 1) * av.charWidth) + ","\r
-                  + (av.charHeight + sy) + "\""\r
-                  + " onMouseOver=\"toolTip('"\r
-                  + alIndex + " " + triplet );\r
+                            + (idWidth + res * av.charWidth) + ","\r
+                            + sy + ","\r
+                            + (idWidth + (res + 1) * av.charWidth) + ","\r
+                            + (av.charHeight + sy) + "\""\r
+                            + " onMouseOver=\"toolTip('"\r
+                            + alIndex + " " + triplet);\r
               }\r
 \r
-              if(groups[g].getStartRes()<res && groups[g].getEndRes()>res)\r
+              if (groups[g].getStartRes() < res && groups[g].getEndRes() > res)\r
+              {\r
                 text.append("<br><em>" + groups[g].getName() + "</em>");\r
+              }\r
             }\r
 \r
             if (features != null)\r
             {\r
-              if(text.length()<1)\r
+              if (text.length() < 1)\r
               {\r
                 text.append("<area shape=\"rect\" coords=\""\r
-                  + (idWidth + res * av.charWidth) + ","\r
-                  + sy + ","\r
-                  + (idWidth + (res + 1) * av.charWidth) + ","\r
-                  + (av.charHeight + sy) + "\""\r
-                  + " onMouseOver=\"toolTip('"\r
-                  + alIndex + " " + triplet );\r
+                            + (idWidth + res * av.charWidth) + ","\r
+                            + sy + ","\r
+                            + (idWidth + (res + 1) * av.charWidth) + ","\r
+                            + (av.charHeight + sy) + "\""\r
+                            + " onMouseOver=\"toolTip('"\r
+                            + alIndex + " " + triplet);\r
               }\r
-                fSize = features.length;\r
-                for (f = 0; f < fSize; f++)\r
-                {\r
+              fSize = features.length;\r
+              for (f = 0; f < fSize; f++)\r
+              {\r
 \r
-                  if ( (features[f].getBegin() <= seq.findPosition(res)) &&\r
-                      (features[f].getEnd() >= seq.findPosition(res)))\r
+                if ( (features[f].getBegin() <= seq.findPosition(res)) &&\r
+                    (features[f].getEnd() >= seq.findPosition(res)))\r
+                {\r
+                  if (features[f].getType().equals("disulfide bond"))\r
                   {\r
-                    if (features[f].getType().equals("disulfide bond"))\r
+                    if (features[f].getBegin() == seq.findPosition(res)\r
+                        || features[f].getEnd() == seq.findPosition(res))\r
                     {\r
-                      if (features[f].getBegin() == seq.findPosition(res)\r
-                          || features[f].getEnd() == seq.findPosition(res))\r
-                      {\r
-                        text.append("<br>disulfide bond " + features[f].getBegin() + ":" +\r
-                                       features[f].getEnd());\r
-                      }\r
+                      text.append("<br>disulfide bond " + features[f].getBegin() +\r
+                                  ":" +\r
+                                  features[f].getEnd());\r
                     }\r
-                    else\r
+                  }\r
+                  else\r
+                  {\r
+                    text.append("<br>");\r
+                    text.append(features[f].getType());\r
+                    if (features[f].getDescription() != null &&\r
+                        !features[f].\r
+                        getType().equals(features[f].getDescription()))\r
                     {\r
-                      text.append("<br>");\r
-                      text.append(features[f].getType());\r
-                      if (features[f].getDescription() != null && !features[f].getType().equals(features[f].getDescription()))\r
-                        text.append(" " + features[f].getDescription());\r
-\r
-                      if (features[f].getValue("status") != null )\r
-                      {\r
-                        text.append(" (" + features[f].getValue("status") + ")");\r
-                      }\r
+                      text.append(" " + features[f].getDescription());\r
                     }\r
-                  }\r
 \r
+                    if (features[f].getValue("status") != null)\r
+                    {\r
+                      text.append(" (" + features[f].getValue("status") + ")");\r
+                    }\r
+                  }\r
                 }\r
-              }\r
-              if(text.length()>1)\r
-              {\r
-                text.append("')\"; onMouseOut=\"toolTip()\";  href=\"#\">");\r
-                out.println(text.toString());\r
+\r
               }\r
             }\r
+            if (text.length() > 1)\r
+            {\r
+              text.append("')\"; onMouseOut=\"toolTip()\";  href=\"#\">");\r
+              out.println(text.toString());\r
+            }\r
           }\r
+        }\r
         out.println("</map></body></html>");\r
         out.close();\r
 \r
@@ -1222,21 +1164,25 @@ public class AlignmentPanel extends GAlignmentPanel
   {\r
     int seqPanelWidth = seqPanel.seqCanvas.getWidth();\r
 \r
-    //If headless, seqPanel will have 0 width\r
     if (System.getProperty("java.awt.headless") != null\r
-              && System.getProperty("java.awt.headless").equals("true"))\r
+        && System.getProperty("java.awt.headless").equals("true"))\r
     {\r
-      int idWidth = calculateIdWidth().width + 4;\r
-      seqPanelWidth = alignFrame.getWidth() - idWidth;\r
+      seqPanelWidth = alignFrame.getWidth()\r
+          - getVisibleIdWidth()\r
+          - vscroll.getPreferredSize().width\r
+          - alignFrame.getInsets().left\r
+          - alignFrame.getInsets().right;\r
     }\r
 \r
     int chunkWidth = seqPanel.seqCanvas.getWrappedCanvasWidth(\r
         seqPanelWidth\r
-          );\r
+        );\r
 \r
     int hgap = av.charHeight;\r
     if (av.scaleAboveWrapped)\r
+    {\r
       hgap += av.charHeight;\r
+    }\r
 \r
     int annotationHeight = 0;\r
     if (av.showAnnotation)\r
@@ -1250,76 +1196,12 @@ public class AlignmentPanel extends GAlignmentPanel
 \r
     int maxwidth = av.alignment.getWidth();\r
     if (av.hasHiddenColumns)\r
+    {\r
       maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;\r
-\r
+    }\r
 \r
     int height = ( (maxwidth / chunkWidth) + 1) * cHeight;\r
 \r
     return height;\r
   }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @author $author$\r
-   * @version $Revision$\r
-   */\r
-  class Preview\r
-      extends JFrame\r
-  {\r
-    /**\r
-     * Creates a new Preview object.\r
-     *\r
-     * @param image DOCUMENT ME!\r
-     */\r
-    public Preview(Image image)\r
-    {\r
-      setResizable(true);\r
-      setSize(image.getWidth(this), image.getHeight(this));\r
-      setVisible(true);\r
-      getContentPane().setLayout(new BorderLayout());\r
-      getContentPane().add(new PreviewPanel(image), BorderLayout.CENTER);\r
-      validate();\r
-      repaint();\r
-    }\r
-  }\r
-\r
-  /**\r
-   * DOCUMENT ME!\r
-   *\r
-   * @author $author$\r
-   * @version $Revision$\r
-   */\r
-  class PreviewPanel\r
-      extends JPanel\r
-  {\r
-    Image image;\r
-\r
-    /**\r
-     * Creates a new PreviewPanel object.\r
-     *\r
-     * @param image DOCUMENT ME!\r
-     */\r
-    public PreviewPanel(Image image)\r
-    {\r
-      this.image = image;\r
-    }\r
-\r
-    /**\r
-     * DOCUMENT ME!\r
-     *\r
-     * @param g DOCUMENT ME!\r
-     */\r
-    public void paintComponent(Graphics g)\r
-    {\r
-      if (image != null)\r
-      {\r
-        g.drawImage(image, 0, 0, this);\r
-      }\r
-      else\r
-      {\r
-        System.out.println("DEBUG:image is null");\r
-      }\r
-    }\r
-  }\r
 }\r