Formatted source
[jalview.git] / src / MCview / rotCanvas.java
1 /*\r
2 * Jalview - A Sequence Alignment Editor and Viewer\r
3 * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
4 *\r
5 * This program is free software; you can redistribute it and/or\r
6 * modify it under the terms of the GNU General Public License\r
7 * as published by the Free Software Foundation; either version 2\r
8 * of the License, or (at your option) any later version.\r
9 *\r
10 * This program is distributed in the hope that it will be useful,\r
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
13 * GNU General Public License for more details.\r
14 *\r
15 * You should have received a copy of the GNU General Public License\r
16 * along with this program; if not, write to the Free Software\r
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
18 */\r
19 package MCview;\r
20 \r
21 import jalview.analysis.AlignSeq;\r
22 \r
23 import jalview.datamodel.*;\r
24 \r
25 // JBPNote TODO: This class is quite noisy - needs proper log.info/log.debug\r
26 import java.awt.*;\r
27 import java.awt.event.*;\r
28 \r
29 import java.io.*;\r
30 \r
31 import java.util.*;\r
32 \r
33 import javax.swing.*;\r
34 \r
35 \r
36 public class rotCanvas extends JPanel implements KeyListener, MouseListener,\r
37     MouseMotionListener {\r
38     MCMatrix idmat = new MCMatrix(3, 3);\r
39     MCMatrix objmat = new MCMatrix(3, 3);\r
40     boolean redrawneeded = true;\r
41     int omx = 0;\r
42     int mx = 0;\r
43     int omy = 0;\r
44     int my = 0;\r
45     public PDBfile pdb;\r
46     int bsize;\r
47     Image img;\r
48     Graphics ig;\r
49     Dimension prefsize;\r
50     float[] centre = new float[3];\r
51     float[] width = new float[3];\r
52     float maxwidth;\r
53     float scale;\r
54     String inStr;\r
55     String inType;\r
56     boolean depthcue = true;\r
57     boolean wire = false;\r
58     boolean bymolecule = false;\r
59     boolean zbuffer = true;\r
60     boolean dragging;\r
61     int xstart;\r
62     int xend;\r
63     int ystart;\r
64     int yend;\r
65     int xmid;\r
66     int ymid;\r
67     Font font = new Font("Helvetica", Font.PLAIN, 10);\r
68 \r
69     public rotCanvas(PDBfile pdb, Sequence sequence,\r
70         jalview.gui.AlignViewport av) throws IOException {\r
71         int max = -10;\r
72         int maxchain = -1;\r
73         int pdbstart = 0;\r
74         int pdbend = 0;\r
75         int seqstart = 0;\r
76         int seqend = 0;\r
77 \r
78         for (int i = 0; i < pdb.chains.size(); i++) {\r
79             // Now lets compare the sequences to get\r
80             // the start and end points.\r
81             java.util.StringTokenizer str = new java.util.StringTokenizer(sequence.getSequence(),\r
82                     ".");\r
83             String newString = "";\r
84 \r
85             while (str.hasMoreTokens()) {\r
86                 newString += str.nextToken();\r
87             }\r
88 \r
89             // Align the sequence to the pdb\r
90             AlignSeq as = new AlignSeq(sequence,\r
91                     ((PDBChain) pdb.chains.elementAt(i)).sequence, "pep");\r
92             as.calcScoreMatrix();\r
93             as.traceAlignment();\r
94             as.printAlignment();\r
95 \r
96             if (as.maxscore > max) {\r
97                 max = as.maxscore;\r
98                 maxchain = i;\r
99 \r
100                 pdbstart = as.seq2start;\r
101                 pdbend = as.seq2end;\r
102                 seqstart = as.seq1start - 1;\r
103                 seqend = as.seq1end - 1;\r
104             }\r
105 \r
106             System.out.println("PDB start/end " + pdbstart + " " + pdbend);\r
107             System.out.println("SEQ start/end " + seqstart + " " + seqend);\r
108         }\r
109 \r
110         ((PDBChain) pdb.chains.elementAt(maxchain)).pdbstart = pdbstart;\r
111         ((PDBChain) pdb.chains.elementAt(maxchain)).pdbend = pdbend;\r
112         ((PDBChain) pdb.chains.elementAt(maxchain)).seqstart = seqstart;\r
113         ((PDBChain) pdb.chains.elementAt(maxchain)).seqend = seqend;\r
114         ((PDBChain) pdb.chains.elementAt(maxchain)).isVisible = true;\r
115         ((PDBChain) pdb.chains.elementAt(maxchain)).sequence = sequence;\r
116         ((PDBChain) pdb.chains.elementAt(maxchain)).colourBySequence(av,\r
117             sequence);\r
118 \r
119         this.pdb = pdb;\r
120         this.prefsize = new Dimension(getWidth(), getHeight());\r
121 \r
122         //Initialize the matrices to identity\r
123         for (int i = 0; i < 3; i++) {\r
124             for (int j = 0; j < 3; j++) {\r
125                 if (i != j) {\r
126                     idmat.addElement(i, j, 0);\r
127                     objmat.addElement(i, j, 0);\r
128                 } else {\r
129                     idmat.addElement(i, j, 1);\r
130                     objmat.addElement(i, j, 1);\r
131                 }\r
132             }\r
133         }\r
134 \r
135         addMouseMotionListener(this);\r
136         addMouseListener(this);\r
137         addKeyListener(this);\r
138 \r
139         addPDBfile();\r
140         ToolTipManager.sharedInstance().registerComponent(this);\r
141     }\r
142 \r
143     public void addPDBfile() {\r
144         findCentre();\r
145         findWidth();\r
146 \r
147         scale = findScale();\r
148 \r
149         System.out.println("Scale factor = " + scale);\r
150     }\r
151 \r
152     public void deleteBonds() {\r
153         scale = 0;\r
154         maxwidth = 0;\r
155 \r
156         width[0] = 0;\r
157         width[1] = 0;\r
158         width[2] = 0;\r
159 \r
160         centre[0] = 0;\r
161         centre[1] = 0;\r
162         centre[2] = 0;\r
163 \r
164         for (int i = 0; i < pdb.chains.size(); i++) {\r
165             ((PDBChain) pdb.chains.elementAt(i)).bonds = null;\r
166         }\r
167     }\r
168 \r
169     public void findWidth() {\r
170         float[] max = new float[3];\r
171         float[] min = new float[3];\r
172 \r
173         max[0] = (float) -1e30;\r
174         max[1] = (float) -1e30;\r
175         max[2] = (float) -1e30;\r
176 \r
177         min[0] = (float) 1e30;\r
178         min[1] = (float) 1e30;\r
179         min[2] = (float) 1e30;\r
180 \r
181         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
182             if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
183                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
184 \r
185                 for (int i = 0; i < bonds.size(); i++) {\r
186                     Bond tmp = (Bond) bonds.elementAt(i);\r
187 \r
188                     if (tmp.start[0] >= max[0]) {\r
189                         max[0] = tmp.start[0];\r
190                     }\r
191 \r
192                     if (tmp.start[1] >= max[1]) {\r
193                         max[1] = tmp.start[1];\r
194                     }\r
195 \r
196                     if (tmp.start[2] >= max[2]) {\r
197                         max[2] = tmp.start[2];\r
198                     }\r
199 \r
200                     if (tmp.start[0] <= min[0]) {\r
201                         min[0] = tmp.start[0];\r
202                     }\r
203 \r
204                     if (tmp.start[1] <= min[1]) {\r
205                         min[1] = tmp.start[1];\r
206                     }\r
207 \r
208                     if (tmp.start[2] <= min[2]) {\r
209                         min[2] = tmp.start[2];\r
210                     }\r
211 \r
212                     if (tmp.end[0] >= max[0]) {\r
213                         max[0] = tmp.end[0];\r
214                     }\r
215 \r
216                     if (tmp.end[1] >= max[1]) {\r
217                         max[1] = tmp.end[1];\r
218                     }\r
219 \r
220                     if (tmp.end[2] >= max[2]) {\r
221                         max[2] = tmp.end[2];\r
222                     }\r
223 \r
224                     if (tmp.end[0] <= min[0]) {\r
225                         min[0] = tmp.end[0];\r
226                     }\r
227 \r
228                     if (tmp.end[1] <= min[1]) {\r
229                         min[1] = tmp.end[1];\r
230                     }\r
231 \r
232                     if (tmp.end[2] <= min[2]) {\r
233                         min[2] = tmp.end[2];\r
234                     }\r
235                 }\r
236             }\r
237         }\r
238 \r
239         System.out.println("xmax " + max[0] + " min " + min[0]);\r
240         System.out.println("ymax " + max[1] + " min " + min[1]);\r
241         System.out.println("zmax " + max[2] + " min " + min[2]);\r
242 \r
243         width[0] = (float) Math.abs(max[0] - min[0]);\r
244         width[1] = (float) Math.abs(max[1] - min[1]);\r
245         width[2] = (float) Math.abs(max[2] - min[2]);\r
246 \r
247         maxwidth = width[0];\r
248 \r
249         if (width[1] > width[0]) {\r
250             maxwidth = width[1];\r
251         }\r
252 \r
253         if (width[2] > width[1]) {\r
254             maxwidth = width[2];\r
255         }\r
256 \r
257         System.out.println("Maxwidth = " + maxwidth);\r
258     }\r
259 \r
260     public float findScale() {\r
261         int dim;\r
262         int width;\r
263         int height;\r
264 \r
265         if (getWidth() != 0) {\r
266             width = getWidth();\r
267             height = getHeight();\r
268         } else {\r
269             width = prefsize.width;\r
270             height = prefsize.height;\r
271         }\r
272 \r
273         if (width < height) {\r
274             dim = width;\r
275         } else {\r
276             dim = height;\r
277         }\r
278 \r
279         return (float) (dim / (1.5d * maxwidth));\r
280     }\r
281 \r
282     public void findCentre() {\r
283         float xtot = 0;\r
284         float ytot = 0;\r
285         float ztot = 0;\r
286 \r
287         int bsize = 0;\r
288 \r
289         //Find centre coordinate\r
290         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
291             if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
292                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
293 \r
294                 bsize += bonds.size();\r
295 \r
296                 for (int i = 0; i < bonds.size(); i++) {\r
297                     xtot = xtot + ((Bond) bonds.elementAt(i)).start[0] +\r
298                         ((Bond) bonds.elementAt(i)).end[0];\r
299 \r
300                     ytot = ytot + ((Bond) bonds.elementAt(i)).start[1] +\r
301                         ((Bond) bonds.elementAt(i)).end[1];\r
302 \r
303                     ztot = ztot + ((Bond) bonds.elementAt(i)).start[2] +\r
304                         ((Bond) bonds.elementAt(i)).end[2];\r
305                 }\r
306             }\r
307         }\r
308 \r
309         centre[0] = xtot / (2 * (float) bsize);\r
310         centre[1] = ytot / (2 * (float) bsize);\r
311         centre[2] = ztot / (2 * (float) bsize);\r
312     }\r
313 \r
314     public void paint(Graphics g) {\r
315         //Only create the image at the beginning -\r
316         //this saves much memory usage\r
317         if ((img == null) || (prefsize.width != getWidth()) ||\r
318                 (prefsize.height != getHeight())) {\r
319             prefsize.width = getWidth();\r
320             prefsize.height = getHeight();\r
321 \r
322             scale = findScale();\r
323             img = createImage(prefsize.width, prefsize.height);\r
324             ig = img.getGraphics();\r
325 \r
326             redrawneeded = true;\r
327         }\r
328 \r
329         if (redrawneeded == true) {\r
330             drawBackground(ig, Color.black);\r
331             drawScene(ig);\r
332             redrawneeded = false;\r
333         } else {\r
334             ig = img.getGraphics();\r
335         }\r
336 \r
337         g.drawImage(img, 0, 0, this);\r
338     }\r
339 \r
340     public void drawBackground(Graphics g, Color col) {\r
341         g.setColor(col);\r
342         g.fillRect(0, 0, prefsize.width, prefsize.height);\r
343     }\r
344 \r
345     public void drawScene(Graphics g) {\r
346         // Sort the bonds by z coord\r
347         Vector bonds = new Vector();\r
348 \r
349         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
350             if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
351                 Vector tmp = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
352 \r
353                 for (int i = 0; i < tmp.size(); i++) {\r
354                     bonds.addElement(tmp.elementAt(i));\r
355                 }\r
356             }\r
357         }\r
358 \r
359         if (zbuffer) {\r
360             Zsort.Zsort(bonds);\r
361         }\r
362 \r
363         for (int i = 0; i < bonds.size(); i++) {\r
364             Bond tmpBond = (Bond) bonds.elementAt(i);\r
365 \r
366             xstart = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
367                 (getWidth() / 2));\r
368             ystart = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
369                 (getHeight() / 2));\r
370 \r
371             xend = (int) (((tmpBond.end[0] - centre[0]) * scale) +\r
372                 (getWidth() / 2));\r
373             yend = (int) (((tmpBond.end[1] - centre[1]) * scale) +\r
374                 (getHeight() / 2));\r
375 \r
376             xmid = (xend + xstart) / 2;\r
377             ymid = (yend + ystart) / 2;\r
378 \r
379             if (depthcue && !bymolecule) {\r
380                 if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {\r
381                     g.setColor(tmpBond.startCol.darker().darker());\r
382                     drawLine(g, xstart, ystart, xmid, ymid);\r
383 \r
384                     g.setColor(tmpBond.endCol.darker().darker());\r
385                     drawLine(g, xmid, ymid, xend, yend);\r
386                 } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
387                     g.setColor(tmpBond.startCol.darker());\r
388                     drawLine(g, xstart, ystart, xmid, ymid);\r
389 \r
390                     g.setColor(tmpBond.endCol.darker());\r
391                     drawLine(g, xmid, ymid, xend, yend);\r
392                 } else {\r
393                     g.setColor(tmpBond.startCol);\r
394                     drawLine(g, xstart, ystart, xmid, ymid);\r
395 \r
396                     g.setColor(tmpBond.endCol);\r
397                     drawLine(g, xmid, ymid, xend, yend);\r
398                 }\r
399             } else if (depthcue && bymolecule) {\r
400                 if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {\r
401                     g.setColor(Color.green.darker().darker());\r
402                     drawLine(g, xstart, ystart, xend, yend);\r
403                 } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
404                     g.setColor(Color.green.darker());\r
405                     drawLine(g, xstart, ystart, xend, yend);\r
406                 } else {\r
407                     g.setColor(Color.green);\r
408                     drawLine(g, xstart, ystart, xend, yend);\r
409                 }\r
410             } else if (!depthcue && !bymolecule) {\r
411                 g.setColor(tmpBond.startCol);\r
412                 drawLine(g, xstart, ystart, xmid, ymid);\r
413                 g.setColor(tmpBond.endCol);\r
414                 drawLine(g, xmid, ymid, xend, yend);\r
415             } else {\r
416                 drawLine(g, xstart, ystart, xend, yend);\r
417             }\r
418         }\r
419     }\r
420 \r
421     public void drawLine(Graphics g, int x1, int y1, int x2, int y2) {\r
422         if (!wire) {\r
423             if (((float) Math.abs(y2 - y1) / (float) Math.abs(x2 - x1)) < 0.5) {\r
424                 g.drawLine(x1, y1, x2, y2);\r
425                 g.drawLine(x1 + 1, y1 + 1, x2 + 1, y2 + 1);\r
426                 g.drawLine(x1, y1 - 1, x2, y2 - 1);\r
427             } else {\r
428                 g.setColor(g.getColor().brighter());\r
429                 g.drawLine(x1, y1, x2, y2);\r
430                 g.drawLine(x1 + 1, y1, x2 + 1, y2);\r
431                 g.drawLine(x1 - 1, y1, x2 - 1, y2);\r
432             }\r
433         } else {\r
434             g.drawLine(x1, y1, x2, y2);\r
435         }\r
436     }\r
437 \r
438     public Dimension minimumsize() {\r
439         return prefsize;\r
440     }\r
441 \r
442     public Dimension preferredsize() {\r
443         return prefsize;\r
444     }\r
445 \r
446     public void keyTyped(KeyEvent evt) {\r
447     }\r
448 \r
449     public void keyReleased(KeyEvent evt) {\r
450     }\r
451 \r
452     public void keyPressed(KeyEvent evt) {\r
453         int key = evt.getKeyChar();\r
454 \r
455         if (evt.getKeyCode() == KeyEvent.VK_UP) {\r
456             scale = (float) (scale * 1.1);\r
457             redrawneeded = true;\r
458             repaint();\r
459         } else if (evt.getKeyCode() == KeyEvent.VK_DOWN) {\r
460             scale = (float) (scale * 0.9);\r
461             redrawneeded = true;\r
462             repaint();\r
463         } else if (key == 'w') {\r
464             wire = !wire;\r
465             System.out.println("wireframe " + wire);\r
466             redrawneeded = true;\r
467             repaint();\r
468         } else if (key == 'd') {\r
469             depthcue = !depthcue;\r
470             System.out.println("Depth cueing is " + depthcue);\r
471             redrawneeded = true;\r
472             repaint();\r
473         } else if (key == 'm') {\r
474             bymolecule = !bymolecule;\r
475             System.out.println("Bymolecule is " + bymolecule);\r
476             redrawneeded = true;\r
477             repaint();\r
478         } else if (key == 'z') {\r
479             zbuffer = !zbuffer;\r
480             System.out.println("Z buffering is " + zbuffer);\r
481             redrawneeded = true;\r
482             repaint();\r
483         } else if (key == 'c') {\r
484             bymolecule = false;\r
485             pdb.setChainColours();\r
486             System.out.println("Colouring by chain");\r
487             redrawneeded = true;\r
488             repaint();\r
489         } else if (key == 'h') {\r
490             bymolecule = false;\r
491             pdb.setHydrophobicityColours();\r
492             System.out.println("Colouring by hydrophobicity");\r
493             redrawneeded = true;\r
494             repaint();\r
495         } else if (key == 'q') {\r
496             bymolecule = false;\r
497             pdb.setChargeColours();\r
498             System.out.println("Colouring charges and cysteines");\r
499             redrawneeded = true;\r
500             repaint();\r
501         }\r
502 \r
503         return;\r
504     }\r
505 \r
506     public void mousePressed(MouseEvent e) {\r
507         mx = e.getX();\r
508         my = e.getY();\r
509         omx = mx;\r
510         omy = my;\r
511         dragging = false;\r
512     }\r
513 \r
514     public void mouseMoved(MouseEvent e) {\r
515         myAtom fatom = null;\r
516 \r
517         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
518             PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
519 \r
520             if (chain.isVisible) {\r
521                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
522 \r
523                 for (int i = 0; i < bonds.size(); i++) {\r
524                     Bond tmpBond = (Bond) bonds.elementAt(i);\r
525                     int truex = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
526                         (getWidth() / 2));\r
527 \r
528                     if (Math.abs(truex - e.getX()) <= 2) {\r
529                         int truey = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
530                             (getHeight() / 2));\r
531 \r
532                         if (Math.abs(truey - e.getY()) <= 2) {\r
533                             fatom = tmpBond.at1;\r
534                         }\r
535                     }\r
536                 }\r
537             }\r
538         }\r
539 \r
540         if (fatom != null) {\r
541             this.setToolTipText(fatom.resName);\r
542         } else {\r
543             this.setToolTipText(null);\r
544         }\r
545     }\r
546 \r
547     public void mouseClicked(MouseEvent e) {\r
548     }\r
549 \r
550     public void mouseEntered(MouseEvent e) {\r
551     }\r
552 \r
553     public void mouseExited(MouseEvent e) {\r
554     }\r
555 \r
556     public void mouseDragged(MouseEvent evt) {\r
557         int x = evt.getX();\r
558         int y = evt.getY();\r
559         mx = x;\r
560         my = y;\r
561 \r
562         MCMatrix objmat = new MCMatrix(3, 3);\r
563         objmat.setIdentity();\r
564 \r
565         if ((evt.getModifiers() & Event.META_MASK) != 0) {\r
566             objmat.rotatez((float) ((mx - omx)));\r
567         } else {\r
568             objmat.rotatex((float) ((my - omy)));\r
569             objmat.rotatey((float) ((omx - mx)));\r
570         }\r
571 \r
572         //Alter the bonds\r
573         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
574             Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
575 \r
576             for (int i = 0; i < bonds.size(); i++) {\r
577                 Bond tmpBond = (Bond) bonds.elementAt(i);\r
578 \r
579                 //Translate the bond so the centre is 0,0,0\r
580                 tmpBond.translate(-centre[0], -centre[1], -centre[2]);\r
581 \r
582                 //Now apply the rotation matrix\r
583                 tmpBond.start = objmat.vectorMultiply(tmpBond.start);\r
584                 tmpBond.end = objmat.vectorMultiply(tmpBond.end);\r
585 \r
586                 //Now translate back again\r
587                 tmpBond.translate(centre[0], centre[1], centre[2]);\r
588             }\r
589         }\r
590 \r
591         objmat = null;\r
592 \r
593         omx = mx;\r
594         omy = my;\r
595 \r
596         redrawneeded = true;\r
597 \r
598         paint(this.getGraphics());\r
599 \r
600         dragging = true;\r
601 \r
602         return;\r
603     }\r
604 \r
605     public void mouseReleased(MouseEvent evt) {\r
606         int x = evt.getX();\r
607         int y = evt.getY();\r
608 \r
609         if (!dragging) {\r
610             myAtom tmp = findAtom(x, y);\r
611         }\r
612 \r
613         drawLabels();\r
614 \r
615         return;\r
616     }\r
617 \r
618     public void drawLabels() {\r
619         redrawneeded = true;\r
620         paint(this.getGraphics());\r
621 \r
622         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
623             PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
624 \r
625             if (chain.isVisible) {\r
626                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
627 \r
628                 for (int i = 0; i < bonds.size(); i++) {\r
629                     Bond tmpBond = (Bond) bonds.elementAt(i);\r
630 \r
631                     if (tmpBond.at1.isSelected) {\r
632                         labelAtom(img.getGraphics(), tmpBond, 1);\r
633                     }\r
634 \r
635                     if (tmpBond.at2.isSelected) {\r
636                         labelAtom(img.getGraphics(), tmpBond, 2);\r
637                     }\r
638                 }\r
639             }\r
640         }\r
641 \r
642         this.getGraphics().drawImage(img, 0, 0, this);\r
643 \r
644         dragging = false;\r
645     }\r
646 \r
647     public void labelAtom(Graphics g, Bond b, int n) {\r
648         g.setFont(font);\r
649 \r
650         if (n == 1) {\r
651             int xstart = (int) (((b.start[0] - centre[0]) * scale) +\r
652                 (getWidth() / 2));\r
653             int ystart = (int) (((b.start[1] - centre[1]) * scale) +\r
654                 (getHeight() / 2));\r
655 \r
656             g.setColor(Color.red);\r
657             g.drawString(b.at1.resName + "-" + b.at1.resNumber, xstart, ystart);\r
658         }\r
659 \r
660         if (n == 2) {\r
661             int xstart = (int) (((b.end[0] - centre[0]) * scale) +\r
662                 (getWidth() / 2));\r
663             int ystart = (int) (((b.end[1] - centre[1]) * scale) +\r
664                 (getHeight() / 2));\r
665 \r
666             g.setColor(Color.red);\r
667             g.drawString(b.at2.resName + "-" + b.at2.resNumber, xstart, ystart);\r
668         }\r
669     }\r
670 \r
671     public myAtom findAtom(int x, int y) {\r
672         myAtom fatom = null;\r
673 \r
674         int foundchain = -1;\r
675 \r
676         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
677             PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
678 \r
679             if (chain.isVisible) {\r
680                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
681 \r
682                 for (int i = 0; i < bonds.size(); i++) {\r
683                     Bond tmpBond = (Bond) bonds.elementAt(i);\r
684 \r
685                     int truex = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
686                         (getWidth() / 2));\r
687 \r
688                     if (Math.abs(truex - x) <= 2) {\r
689                         int truey = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
690                             (getHeight() / 2));\r
691 \r
692                         if (Math.abs(truey - y) <= 2) {\r
693                             System.out.println("Found match");\r
694                             System.out.println(x + " " + y);\r
695                             System.out.println(truex + " " + truey);\r
696                             System.out.println(tmpBond.start[0] + " " +\r
697                                 tmpBond.start[1]);\r
698                             System.out.println("Atom 1 = " +\r
699                                 tmpBond.at1.resName + " " +\r
700                                 tmpBond.at1.resNumber + " " +\r
701                                 tmpBond.at1.chain);\r
702                             fatom = tmpBond.at1;\r
703                             fatom.isSelected = !fatom.isSelected;\r
704                             foundchain = ii;\r
705                         }\r
706                     }\r
707                 }\r
708             }\r
709 \r
710             if (fatom != null) //)&& chain.ds != null)\r
711              {\r
712                 chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
713 \r
714                 // SMJS TODO\r
715                 // int tmp = chain.ds.seqstart + fatom.resNumber - chain.offset;\r
716                 // int pos = chain.ds.findIndex(tmp);\r
717                 // System.out.println("Found seq " + chain.ds.name + " "  + tmp + " " + pos);\r
718             }\r
719         }\r
720 \r
721         return fatom;\r
722     }\r
723 \r
724     public void update(Graphics g) {\r
725         paint(g);\r
726     }\r
727 }\r