Catch null colour exception
[jalview.git] / src / MCview / PDBCanvas.java
index 5ff0f1f..17db1a0 100755 (executable)
@@ -66,33 +66,29 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
     int xmid;\r
     int ymid;\r
     Font font = new Font("Helvetica", Font.PLAIN, 10);\r
-    jalview.gui.SequenceRenderer sr;\r
-    jalview.gui.FeatureRenderer  fr;\r
     jalview.gui.SeqCanvas seqcanvas;\r
     public Sequence sequence;\r
     final StringBuffer mappingDetails = new StringBuffer();\r
     PDBChain mainchain;\r
+    Vector highlightRes;\r
+    boolean pdbAction = false;\r
 \r
     public PDBCanvas(jalview.gui.SeqCanvas seqcanvas, Sequence seq)\r
     {\r
       this.seqcanvas = seqcanvas;\r
       this.sequence = seq;\r
-      sr = seqcanvas.getSequenceRenderer();\r
-      fr = seqcanvas.getFeatureRenderer();\r
-\r
       seqcanvas.setPDBCanvas(this);\r
     }\r
 \r
   public void setPDBFile(PDBfile pdb)\r
    {\r
-        this.sr = sr;\r
-        this.fr = fr;\r
         int max = -10;\r
         int maxchain = -1;\r
         int pdbstart = 0;\r
         int pdbend = 0;\r
         int seqstart = 0;\r
         int seqend = 0;\r
+        AlignSeq maxAlignseq = null;\r
 \r
         for (int i = 0; i < pdb.chains.size(); i++)\r
         {\r
@@ -120,14 +116,17 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
 \r
             as.printAlignment(ps);\r
 \r
-            if (as.maxscore > max) {\r
+\r
+\r
+            if (as.maxscore > max)\r
+            {\r
                 max = as.maxscore;\r
                 maxchain = i;\r
-\r
                 pdbstart = as.seq2start;\r
                 pdbend = as.seq2end;\r
                 seqstart = as.seq1start + sequence.getStart()-1;\r
                 seqend = as.seq1end + sequence.getEnd()-1;\r
+                maxAlignseq = as;\r
             }\r
 \r
             mappingDetails.append("\nPDB start/end "  + pdbstart + " " + pdbend);\r
@@ -141,7 +140,7 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
         mainchain.seqstart = seqstart;\r
         mainchain.seqend = seqend;\r
         mainchain.isVisible = true;\r
-        mainchain.sequence = sequence;\r
+        mainchain.makeExactMapping(maxAlignseq, sequence);\r
 \r
         this.pdb = pdb;\r
         this.prefsize = new Dimension(getWidth(), getHeight());\r
@@ -182,46 +181,45 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
           }\r
        });\r
 \r
-      /*\r
-       SequenceGroup sg = new SequenceGroup("PDB",\r
-                                            null, true,true,false,\r
-                                            sequence.findIndex(seqstart-1),\r
-                                            sequence.findIndex(seqend-1));\r
-       sg.addSequence(sequence, false);\r
-       sg.setOutlineColour(Color.black);\r
-       seqcanvas.getViewport().getAlignment().addGroup(sg);\r
-       */\r
 \r
         findCentre();\r
         findWidth();\r
 \r
-        scale = findScale();\r
+        setupBonds();\r
 \r
+        scale = findScale();\r
 \r
-        updateSeqColours();\r
         ToolTipManager.sharedInstance().registerComponent(this);\r
         ToolTipManager.sharedInstance().setInitialDelay(0);\r
         ToolTipManager.sharedInstance().setDismissDelay(10000);\r
-\r
     }\r
 \r
-    public void deleteBonds() {\r
-        scale = 0;\r
-        maxwidth = 0;\r
 \r
-        width[0] = 0;\r
-        width[1] = 0;\r
-        width[2] = 0;\r
+    Vector visiblebonds;\r
+    void setupBonds()\r
+    {\r
+      // Sort the bonds by z coord\r
+      visiblebonds = new Vector();\r
 \r
-        centre[0] = 0;\r
-        centre[1] = 0;\r
-        centre[2] = 0;\r
+      for (int ii = 0; ii < pdb.chains.size(); ii++)\r
+      {\r
+        if ( ( (PDBChain) pdb.chains.elementAt(ii)).isVisible)\r
+        {\r
+          Vector tmp = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;\r
 \r
-        for (int i = 0; i < pdb.chains.size(); i++) {\r
-            ((PDBChain) pdb.chains.elementAt(i)).bonds = null;\r
+          for (int i = 0; i < tmp.size(); i++)\r
+          {\r
+            visiblebonds.addElement(tmp.elementAt(i));\r
+          }\r
         }\r
+      }\r
+\r
+      updateSeqColours();\r
+      redrawneeded = true;\r
+      repaint();\r
     }\r
 \r
+\r
     public void findWidth() {\r
         float[] max = new float[3];\r
         float[] min = new float[3];\r
@@ -367,11 +365,11 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
         centre[2] = ztot / (2 * (float) bsize);\r
     }\r
 \r
-    public void paintComponent(Graphics g) {\r
-\r
+    public void paintComponent(Graphics g)\r
+    {\r
       super.paintComponent(g);\r
 \r
-      if(pdb==null)\r
+      if(visiblebonds==null)\r
       {\r
         g.setColor(Color.black);\r
         g.setFont(new Font("Verdana", Font.BOLD, 14));\r
@@ -382,8 +380,11 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
 \r
         //Only create the image at the beginning -\r
         //this saves much memory usage\r
-        if ((img == null) || (prefsize.width != getWidth()) ||\r
-                (prefsize.height != getHeight())) {\r
+        if ((img == null)\r
+            || (prefsize.width != getWidth())\r
+            || (prefsize.height != getHeight()))\r
+\r
+      {\r
             prefsize.width = getWidth();\r
             prefsize.height = getHeight();\r
 \r
@@ -395,7 +396,6 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
             ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
                                  RenderingHints.VALUE_ANTIALIAS_ON);\r
 \r
-\r
             redrawneeded = true;\r
         }\r
 \r
@@ -407,6 +407,8 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
         }\r
 \r
         g.drawImage(img, 0, 0, this);\r
+\r
+        pdbAction = false;\r
     }\r
 \r
     public void drawAll(Graphics g, int width, int height)\r
@@ -420,87 +422,115 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
 \r
     public void updateSeqColours()\r
     {\r
+      if(pdbAction)\r
+      {\r
+        return;\r
+      }\r
+\r
+     // System.out.println("update seq colours");\r
       if(bysequence && pdb!=null)\r
       {\r
         for (int ii = 0; ii < pdb.chains.size(); ii++)\r
         {\r
-          colourBySequence( (PDBChain) pdb.chains.elementAt(ii) );\r
+          colourBySequence( (PDBChain) pdb.chains.elementAt(ii));\r
         }\r
       }\r
 \r
       redrawneeded=true;\r
       repaint();\r
+    }\r
+\r
+    int findTrueIndex(int pos)\r
+    {\r
+      // returns the alignment position for a residue\r
+      int j = sequence.getStart();\r
+      int i = 0;\r
 \r
+      while ( (i < sequence.getLength()) && (j <= sequence.getEnd()) && (j <= pos+1))\r
+      {\r
+        if (!jalview.util.Comparison.isGap(sequence.getCharAt(i)))\r
+        {\r
+          j++;\r
+        }\r
+\r
+        i++;\r
+      }\r
+\r
+      if(i>1)\r
+         i--;\r
+\r
+      if ( (j == sequence.getEnd()) && (j < pos))\r
+      {\r
+        return sequence.getEnd() + 1;\r
+      }\r
+      else\r
+      {\r
+        return i;\r
+      }\r
     }\r
 \r
     // This method has been taken out of PDBChain to allow\r
     // Applet and Application specific sequence renderers to be used\r
     void colourBySequence(PDBChain chain)\r
     {\r
+     // System.out.println("colour by seq");\r
       for (int i = 0; i < chain.bonds.size(); i++)\r
       {\r
         Bond tmp = (Bond) chain.bonds.elementAt(i);\r
+        tmp.startCol = Color.lightGray;\r
+        tmp.endCol = Color.lightGray;\r
+\r
+        if(chain!=mainchain)\r
+          continue;\r
 \r
         if ( (tmp.at1.resNumber >= ( (chain.offset + chain.pdbstart) - 1)) &&\r
             (tmp.at1.resNumber <= ( (chain.offset + chain.pdbend) - 1)))\r
         {\r
-          int pos = chain.seqstart +\r
-              (tmp.at1.resNumber - chain.pdbstart - chain.offset);\r
-\r
-          int index = sequence.findIndex(pos);\r
-\r
-          tmp.startCol = sr.findSequenceColour(Color.lightGray, sequence, index);\r
-\r
-          tmp.startCol = fr.findFeatureColour(tmp.startCol, sequence, index);\r
+            int index = findTrueIndex(tmp.at1.alignmentMapping);\r
+                //sequence.findIndex(tmp.at1.alignmentMapping);\r
+            if (index != -1)\r
+            {\r
+              tmp.startCol = seqcanvas.getSequenceRenderer().\r
+                  getResidueBoxColour( sequence, index);\r
+              if(tmp.startCol==null)\r
+                tmp.startCol = Color.white;\r
 \r
-        }\r
-        else\r
-        {\r
-          tmp.startCol = Color.gray;\r
+              tmp.startCol = seqcanvas.getFeatureRenderer().\r
+                  findFeatureColour(tmp.startCol, sequence, index);\r
+            }\r
         }\r
 \r
         if ( (tmp.at2.resNumber >= ( (chain.offset + chain.pdbstart) - 1)) &&\r
             (tmp.at2.resNumber <= ( (chain.pdbend + chain.offset) - 1)))\r
         {\r
-          int pos = chain.seqstart +\r
-              (tmp.at2.resNumber - chain.pdbstart - chain.offset);\r
-          int index = sequence.findIndex(pos);\r
 \r
-          tmp.endCol = sr.findSequenceColour(tmp.endCol, sequence, index);\r
-          tmp.endCol = fr.findFeatureColour(tmp.endCol, sequence, index);\r
-        }\r
-        else\r
-        {\r
-          tmp.endCol = Color.gray;\r
+            int index =  findTrueIndex(tmp.at2.alignmentMapping);\r
+                //sequence.findIndex( tmp.at2.alignmentMapping );\r
+            if (index != -1)\r
+            {\r
+              tmp.endCol = seqcanvas.getSequenceRenderer().\r
+                  getResidueBoxColour( sequence, index);\r
+              if(tmp.endCol==null)\r
+                tmp.endCol = Color.white;\r
+              tmp.endCol = seqcanvas.getFeatureRenderer().\r
+                  findFeatureColour(tmp.endCol, sequence, index);\r
+            }\r
         }\r
       }\r
     }\r
 \r
 \r
-    public void drawScene(Graphics g) {\r
-        // Sort the bonds by z coord\r
-        Vector bonds = new Vector();\r
-\r
-        for (int ii = 0; ii < pdb.chains.size(); ii++)\r
+    public void drawScene(Graphics g)\r
+    {\r
+        if (zbuffer)\r
         {\r
-          if ( ( (PDBChain) pdb.chains.elementAt(ii)).isVisible)\r
-          {\r
-            Vector tmp = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;\r
-\r
-            for (int i = 0; i < tmp.size(); i++)\r
-            {\r
-              bonds.addElement(tmp.elementAt(i));\r
-            }\r
-          }\r
-        }\r
-\r
-        if (zbuffer) {\r
-            Zsort.Zsort(bonds);\r
+            Zsort.Zsort(visiblebonds);\r
         }\r
 \r
         Bond tmpBond=null;\r
-        for (int i = 0; i < bonds.size(); i++) {\r
-            tmpBond = (Bond) bonds.elementAt(i);\r
+        for (int i = 0; i < visiblebonds.size(); i++)\r
+        {\r
+            tmpBond = (Bond) visiblebonds.elementAt(i);\r
 \r
             xstart = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
                 (getWidth() / 2));\r
@@ -515,11 +545,11 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
             xmid = (xend + xstart) / 2;\r
             ymid = (yend + ystart) / 2;\r
 \r
-            if (depthcue && !bymolecule) {\r
+            if (depthcue && !bymolecule)\r
+            {\r
                 if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {\r
                     g.setColor(tmpBond.startCol.darker().darker());\r
                     drawLine(g, xstart, ystart, xmid, ymid);\r
-\r
                     g.setColor(tmpBond.endCol.darker().darker());\r
                     drawLine(g, xmid, ymid, xend, yend);\r
                 } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
@@ -613,13 +643,34 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
       }\r
     }\r
 \r
-    public void mousePressed(MouseEvent e) {\r
+    public void mousePressed(MouseEvent e)\r
+    {\r
+        pdbAction = true;\r
         Atom fatom = findAtom(e.getX(), e.getY());\r
         if(fatom!=null)\r
         {\r
           fatom.isSelected = !fatom.isSelected;\r
+\r
           redrawneeded = true;\r
           repaint();\r
+          if (foundchain != -1)\r
+          {\r
+            PDBChain chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
+            if (chain == mainchain)\r
+            {\r
+              if (fatom.alignmentMapping != -1)\r
+              {\r
+                if (highlightRes == null)\r
+                  highlightRes = new Vector();\r
+\r
+                if (highlightRes.contains(fatom.alignmentMapping+"" + ""))\r
+                  highlightRes.remove(fatom.alignmentMapping + "");\r
+                else\r
+                  highlightRes.add(fatom.alignmentMapping + "");\r
+              }\r
+            }\r
+          }\r
+\r
         }\r
         mx = e.getX();\r
         my = e.getY();\r
@@ -628,7 +679,16 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
         dragging = false;\r
     }\r
 \r
-    public void mouseMoved(MouseEvent e) {\r
+    public void mouseMoved(MouseEvent e)\r
+    {\r
+      pdbAction = true;\r
+      if(highlightBond1!=null)\r
+      {\r
+        highlightBond1.at2.isSelected = false;\r
+        highlightBond2.at1.isSelected = false;\r
+        highlightBond1 = null;\r
+        highlightBond2 = null;\r
+      }\r
 \r
         Atom fatom = findAtom(e.getX(), e.getY());\r
 \r
@@ -638,43 +698,69 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
           chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
           if(chain == mainchain)\r
           {\r
-            int pos = chain.seqstart +\r
-                (fatom.resNumber - chain.pdbstart - chain.offset) + 1;\r
-\r
-            int index = seqcanvas.getViewport().getAlignment().findIndex(\r
-                sequence);\r
-\r
-            seqcanvas.highlightSearchResults(new int[]\r
-                                             {index, pos, pos});\r
+            highlightSeqcanvas( fatom.alignmentMapping );\r
           }\r
         }\r
-        else\r
-          seqcanvas.highlightSearchResults(null);\r
 \r
         if (fatom != null)\r
         {\r
             this.setToolTipText(chain.id+":"+ fatom.resNumber+" "+ fatom.resName);\r
         } else\r
         {\r
-            this.setToolTipText("");\r
+            highlightSeqcanvas( -1);\r
+            this.setToolTipText(null);\r
         }\r
     }\r
 \r
-    public void mouseClicked(MouseEvent e) {\r
-    }\r
 \r
-    public void mouseEntered(MouseEvent e) {\r
-    }\r
+    void highlightSeqcanvas(int pos)\r
+    {\r
+      int index = seqcanvas.getViewport().getAlignment().findIndex(sequence);\r
+\r
+      int size = pos==-1?0:3;\r
 \r
-    public void mouseExited(MouseEvent e) {\r
+      if(highlightRes!=null)\r
+        size += highlightRes.size()*3;\r
+\r
+      int [] array = new int[size];\r
+      int i=0;\r
+      if(highlightRes!=null)\r
+      {\r
+        for (i = 0; i < highlightRes.size(); i++)\r
+        {\r
+          int a = Integer.parseInt(highlightRes.elementAt(\r
+              i).toString())+1;\r
+          array[i * 3] = index;\r
+          array[ (i * 3) + 1] = a;\r
+          array[ (i * 3) + 2] = a;\r
+        }\r
+      }\r
+\r
+      if(pos!=-1)\r
+      {\r
+        array[i * 3] = index;\r
+        array[i * 3 + 1] = pos+1;\r
+        array[i * 3 + 2] = pos+1;\r
+      }\r
+\r
+      seqcanvas.highlightSearchResults(array);\r
     }\r
 \r
-    public void mouseDragged(MouseEvent evt) {\r
+\r
+    public void mouseClicked(MouseEvent e)  { }\r
+\r
+    public void mouseEntered(MouseEvent e) {  }\r
+\r
+    public void mouseExited(MouseEvent e) { }\r
+\r
+    public void mouseDragged(MouseEvent evt)\r
+    {\r
         int x = evt.getX();\r
         int y = evt.getY();\r
         mx = x;\r
         my = y;\r
 \r
+\r
         MCMatrix objmat = new MCMatrix(3, 3);\r
         objmat.setIdentity();\r
 \r
@@ -716,7 +802,8 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
         repaint();\r
     }\r
 \r
-    public void mouseReleased(MouseEvent evt) {\r
+    public void mouseReleased(MouseEvent evt)\r
+    {\r
         dragging = false;\r
         return;\r
     }\r
@@ -729,22 +816,22 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
 \r
             if (chain.isVisible)\r
             {\r
-                Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
+              Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
 \r
-                for (int i = 0; i < bonds.size(); i++)\r
-                {\r
-                    Bond tmpBond = (Bond) bonds.elementAt(i);\r
+              for (int i = 0; i < bonds.size(); i++)\r
+              {\r
+                  Bond tmpBond = (Bond) bonds.elementAt(i);\r
 \r
-                    if (tmpBond.at1.isSelected)\r
-                    {\r
-                        labelAtom(g, tmpBond, 1);\r
-                    }\r
+                  if (tmpBond.at1.isSelected)\r
+                  {\r
+                      labelAtom(g, tmpBond, 1);\r
+                  }\r
 \r
-                    if (tmpBond.at2.isSelected)\r
-                    {\r
+                  if (tmpBond.at2.isSelected)\r
+                  {\r
 \r
-                        labelAtom(g, tmpBond, 2);\r
-                    }\r
+                      labelAtom(g, tmpBond, 2);\r
+                  }\r
                 }\r
             }\r
         }\r
@@ -752,14 +839,14 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
 \r
     public void labelAtom(Graphics g, Bond b, int n) {\r
         g.setFont(font);\r
-\r
-        if (n == 1) {\r
+        g.setColor(Color.red);\r
+        if (n == 1)\r
+        {\r
             int xstart = (int) (((b.start[0] - centre[0]) * scale) +\r
                 (getWidth() / 2));\r
             int ystart = (int) (((b.start[1] - centre[1]) * scale) +\r
                 (getHeight() / 2));\r
 \r
-            g.setColor(Color.red);\r
             g.drawString(b.at1.resName + "-" + b.at1.resNumber, xstart, ystart);\r
         }\r
 \r
@@ -769,7 +856,6 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
             int ystart = (int) (((b.end[1] - centre[1]) * scale) +\r
                 (getHeight() / 2));\r
 \r
-            g.setColor(Color.red);\r
             g.drawString(b.at2.resName + "-" + b.at2.resNumber, xstart, ystart);\r
         }\r
     }\r
@@ -843,23 +929,43 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
    Bond highlightBond1, highlightBond2;\r
    public void highlightRes(int ii)\r
   {\r
-    highlightBond1 = null;\r
-    highlightBond2 = null;\r
 \r
-    int index = ii - mainchain.seqstart;\r
-\r
-    if(index <0 )\r
+    if (highlightRes != null\r
+        && highlightRes.contains((ii-1) + ""))\r
+    {\r
       return;\r
+    }\r
 \r
-    if(index<=mainchain.bonds.size())\r
+    int index = -1;\r
+    Bond tmpBond;\r
+    for(index=0; index<mainchain.bonds.size(); index++)\r
     {\r
-      if(index>0)\r
+      tmpBond = (Bond) mainchain.bonds.elementAt(index);\r
+      if (tmpBond.at1.alignmentMapping == ii - 1)\r
       {\r
-        highlightBond1 = (Bond) mainchain.bonds.elementAt(index - 1);\r
-      }\r
+        if (highlightBond1 != null)\r
+          highlightBond1.at2.isSelected = false;\r
+\r
+        if (highlightBond2 != null)\r
+          highlightBond2.at1.isSelected = false;\r
+\r
+        highlightBond1 = null;\r
+        highlightBond2 = null;\r
 \r
-      if(index!=mainchain.bonds.size())\r
-        highlightBond2 = (Bond) mainchain.bonds.elementAt(index);\r
+        if (index > 0)\r
+        {\r
+          highlightBond1 = (Bond) mainchain.bonds.elementAt(index - 1);\r
+          highlightBond1.at2.isSelected = true;\r
+        }\r
+\r
+        if (index != mainchain.bonds.size())\r
+        {\r
+          highlightBond2 = (Bond) mainchain.bonds.elementAt(index);\r
+          highlightBond2.at1.isSelected = true;\r
+        }\r
+\r
+        break;\r
+      }\r
     }\r
 \r
     redrawneeded = true;\r
@@ -875,5 +981,6 @@ public class PDBCanvas extends JPanel implements MouseListener, MouseMotionListe
       }\r
       mainchain.isVisible = true;\r
       findCentre();\r
+      setupBonds();\r
     }\r
 }\r