getShortName
[jalview.git] / src / MCview / PDBCanvas.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 PDBCanvas extends JPanel implements MouseListener, MouseMotionListener\r
37 {\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 bysequence = true;\r
57     boolean depthcue = true;\r
58     boolean wire = false;\r
59     boolean bymolecule = false;\r
60     boolean zbuffer = true;\r
61     boolean dragging;\r
62     int xstart;\r
63     int xend;\r
64     int ystart;\r
65     int yend;\r
66     int xmid;\r
67     int ymid;\r
68     Font font = new Font("Helvetica", Font.PLAIN, 10);\r
69     jalview.gui.SequenceRenderer sr;\r
70     jalview.gui.FeatureRenderer  fr;\r
71     jalview.gui.SeqCanvas seqcanvas;\r
72     Sequence sequence;\r
73     final StringBuffer mappingDetails = new StringBuffer();\r
74 \r
75     public PDBCanvas(jalview.gui.SeqCanvas seqcanvas, Sequence seq)\r
76     {\r
77       this.seqcanvas = seqcanvas;\r
78       this.sequence = seq;\r
79       sr = seqcanvas.getSequenceRenderer();\r
80       fr = seqcanvas.getFeatureRenderer();\r
81 \r
82       seqcanvas.setPDBViewer(this);\r
83     }\r
84 \r
85   public void setPDBFile(PDBfile pdb)\r
86    {\r
87         this.sr = sr;\r
88         this.fr = fr;\r
89         int max = -10;\r
90         int maxchain = -1;\r
91         int pdbstart = 0;\r
92         int pdbend = 0;\r
93         int seqstart = 0;\r
94         int seqend = 0;\r
95 \r
96         for (int i = 0; i < pdb.chains.size(); i++)\r
97         {\r
98 \r
99           mappingDetails.append("\n\nPDB Sequence is :\nSequence = " + ((PDBChain) pdb.chains.elementAt(i)).sequence.getSequence());\r
100           mappingDetails.append("\nNo of residues = " + ((PDBChain) pdb.chains.elementAt(i)).residues.size()+"\n\n");\r
101 \r
102             // Now lets compare the sequences to get\r
103             // the start and end points.\r
104             // Align the sequence to the pdb\r
105             AlignSeq as = new AlignSeq(sequence,\r
106                     ((PDBChain) pdb.chains.elementAt(i)).sequence, "pep");\r
107             as.calcScoreMatrix();\r
108             as.traceAlignment();\r
109             PrintStream  ps = new PrintStream(System.out)\r
110            {\r
111               public void print(String x) {\r
112                    mappingDetails.append(x);\r
113                }\r
114                public void println()\r
115                {\r
116                  mappingDetails.append("\n");\r
117                }\r
118             };\r
119 \r
120             as.printAlignment(ps);\r
121 \r
122             if (as.maxscore > max) {\r
123                 max = as.maxscore;\r
124                 maxchain = i;\r
125 \r
126                 pdbstart = as.seq2start;\r
127                 pdbend = as.seq2end;\r
128                 seqstart = as.seq1start + sequence.getStart()-1;\r
129                 seqend = as.seq1end + sequence.getEnd()-1;\r
130             }\r
131 \r
132             mappingDetails.append("\nPDB start/end "  + pdbstart + " " + pdbend);\r
133             mappingDetails.append("\nSEQ start/end "+ seqstart + " " + seqend);\r
134         }\r
135 \r
136         ((PDBChain) pdb.chains.elementAt(maxchain)).pdbstart = pdbstart;\r
137         ((PDBChain) pdb.chains.elementAt(maxchain)).pdbend = pdbend;\r
138         ((PDBChain) pdb.chains.elementAt(maxchain)).seqstart = seqstart;\r
139         ((PDBChain) pdb.chains.elementAt(maxchain)).seqend = seqend;\r
140         ((PDBChain) pdb.chains.elementAt(maxchain)).isVisible = true;\r
141         ((PDBChain) pdb.chains.elementAt(maxchain)).sequence = sequence;\r
142 \r
143         this.pdb = pdb;\r
144         this.prefsize = new Dimension(getWidth(), getHeight());\r
145 \r
146         //Initialize the matrices to identity\r
147         for (int i = 0; i < 3; i++) {\r
148             for (int j = 0; j < 3; j++) {\r
149                 if (i != j) {\r
150                     idmat.addElement(i, j, 0);\r
151                     objmat.addElement(i, j, 0);\r
152                 } else {\r
153                     idmat.addElement(i, j, 1);\r
154                     objmat.addElement(i, j, 1);\r
155                 }\r
156             }\r
157         }\r
158 \r
159         addMouseMotionListener(this);\r
160         addMouseListener(this);\r
161 \r
162         addMouseWheelListener(new MouseWheelListener()\r
163         {\r
164           public void mouseWheelMoved(MouseWheelEvent e)\r
165           {\r
166             if (e.getWheelRotation() > 0)\r
167             {\r
168               scale = (float) (scale * 1.1);\r
169               redrawneeded = true;\r
170               repaint();\r
171             }\r
172 \r
173             else\r
174             {\r
175               scale = (float) (scale * 0.9);\r
176               redrawneeded = true;\r
177               repaint();\r
178             }\r
179           }\r
180        });\r
181 \r
182       /*\r
183        SequenceGroup sg = new SequenceGroup("PDB",\r
184                                             null, true,true,false,\r
185                                             sequence.findIndex(seqstart-1),\r
186                                             sequence.findIndex(seqend-1));\r
187        sg.addSequence(sequence, false);\r
188        sg.setOutlineColour(Color.black);\r
189        seqcanvas.getViewport().getAlignment().addGroup(sg);\r
190        */\r
191 \r
192         findCentre();\r
193         findWidth();\r
194 \r
195         scale = findScale();\r
196 \r
197 \r
198         updateSeqColours();\r
199         ToolTipManager.sharedInstance().registerComponent(this);\r
200         ToolTipManager.sharedInstance().setInitialDelay(0);\r
201         ToolTipManager.sharedInstance().setDismissDelay(10000);\r
202 \r
203     }\r
204 \r
205     public void deleteBonds() {\r
206         scale = 0;\r
207         maxwidth = 0;\r
208 \r
209         width[0] = 0;\r
210         width[1] = 0;\r
211         width[2] = 0;\r
212 \r
213         centre[0] = 0;\r
214         centre[1] = 0;\r
215         centre[2] = 0;\r
216 \r
217         for (int i = 0; i < pdb.chains.size(); i++) {\r
218             ((PDBChain) pdb.chains.elementAt(i)).bonds = null;\r
219         }\r
220     }\r
221 \r
222     public void findWidth() {\r
223         float[] max = new float[3];\r
224         float[] min = new float[3];\r
225 \r
226         max[0] = (float) -1e30;\r
227         max[1] = (float) -1e30;\r
228         max[2] = (float) -1e30;\r
229 \r
230         min[0] = (float) 1e30;\r
231         min[1] = (float) 1e30;\r
232         min[2] = (float) 1e30;\r
233 \r
234         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
235             if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
236                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
237 \r
238                 for (int i = 0; i < bonds.size(); i++) {\r
239                     Bond tmp = (Bond) bonds.elementAt(i);\r
240 \r
241                     if (tmp.start[0] >= max[0]) {\r
242                         max[0] = tmp.start[0];\r
243                     }\r
244 \r
245                     if (tmp.start[1] >= max[1]) {\r
246                         max[1] = tmp.start[1];\r
247                     }\r
248 \r
249                     if (tmp.start[2] >= max[2]) {\r
250                         max[2] = tmp.start[2];\r
251                     }\r
252 \r
253                     if (tmp.start[0] <= min[0]) {\r
254                         min[0] = tmp.start[0];\r
255                     }\r
256 \r
257                     if (tmp.start[1] <= min[1]) {\r
258                         min[1] = tmp.start[1];\r
259                     }\r
260 \r
261                     if (tmp.start[2] <= min[2]) {\r
262                         min[2] = tmp.start[2];\r
263                     }\r
264 \r
265                     if (tmp.end[0] >= max[0]) {\r
266                         max[0] = tmp.end[0];\r
267                     }\r
268 \r
269                     if (tmp.end[1] >= max[1]) {\r
270                         max[1] = tmp.end[1];\r
271                     }\r
272 \r
273                     if (tmp.end[2] >= max[2]) {\r
274                         max[2] = tmp.end[2];\r
275                     }\r
276 \r
277                     if (tmp.end[0] <= min[0]) {\r
278                         min[0] = tmp.end[0];\r
279                     }\r
280 \r
281                     if (tmp.end[1] <= min[1]) {\r
282                         min[1] = tmp.end[1];\r
283                     }\r
284 \r
285                     if (tmp.end[2] <= min[2]) {\r
286                         min[2] = tmp.end[2];\r
287                     }\r
288                 }\r
289             }\r
290         }\r
291         /*\r
292         System.out.println("xmax " + max[0] + " min " + min[0]);\r
293         System.out.println("ymax " + max[1] + " min " + min[1]);\r
294         System.out.println("zmax " + max[2] + " min " + min[2]);*/\r
295 \r
296         width[0] = (float) Math.abs(max[0] - min[0]);\r
297         width[1] = (float) Math.abs(max[1] - min[1]);\r
298         width[2] = (float) Math.abs(max[2] - min[2]);\r
299 \r
300         maxwidth = width[0];\r
301 \r
302         if (width[1] > width[0]) {\r
303             maxwidth = width[1];\r
304         }\r
305 \r
306         if (width[2] > width[1]) {\r
307             maxwidth = width[2];\r
308         }\r
309 \r
310        // System.out.println("Maxwidth = " + maxwidth);\r
311     }\r
312 \r
313     public float findScale() {\r
314         int dim;\r
315         int width;\r
316         int height;\r
317 \r
318         if (getWidth() != 0) {\r
319             width = getWidth();\r
320             height = getHeight();\r
321         } else {\r
322             width = prefsize.width;\r
323             height = prefsize.height;\r
324         }\r
325 \r
326         if (width < height) {\r
327             dim = width;\r
328         } else {\r
329             dim = height;\r
330         }\r
331 \r
332         return (float) (dim / (1.5d * maxwidth));\r
333     }\r
334 \r
335     public void findCentre() {\r
336         float xtot = 0;\r
337         float ytot = 0;\r
338         float ztot = 0;\r
339 \r
340         int bsize = 0;\r
341 \r
342         //Find centre coordinate\r
343         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
344             if (((PDBChain) pdb.chains.elementAt(ii)).isVisible) {\r
345                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
346 \r
347                 bsize += bonds.size();\r
348 \r
349                 for (int i = 0; i < bonds.size(); i++) {\r
350                     xtot = xtot + ((Bond) bonds.elementAt(i)).start[0] +\r
351                         ((Bond) bonds.elementAt(i)).end[0];\r
352 \r
353                     ytot = ytot + ((Bond) bonds.elementAt(i)).start[1] +\r
354                         ((Bond) bonds.elementAt(i)).end[1];\r
355 \r
356                     ztot = ztot + ((Bond) bonds.elementAt(i)).start[2] +\r
357                         ((Bond) bonds.elementAt(i)).end[2];\r
358                 }\r
359             }\r
360         }\r
361 \r
362         centre[0] = xtot / (2 * (float) bsize);\r
363         centre[1] = ytot / (2 * (float) bsize);\r
364         centre[2] = ztot / (2 * (float) bsize);\r
365     }\r
366 \r
367     public void paintComponent(Graphics g) {\r
368 \r
369       super.paintComponent(g);\r
370 \r
371       if(pdb==null)\r
372       {\r
373         g.setColor(Color.black);\r
374         g.setFont(new Font("Verdana", Font.BOLD, 14));\r
375         g.drawString("Retrieving PDB data....", 20, getHeight()/2);\r
376         return;\r
377       }\r
378 \r
379 \r
380         //Only create the image at the beginning -\r
381         //this saves much memory usage\r
382         if ((img == null) || (prefsize.width != getWidth()) ||\r
383                 (prefsize.height != getHeight())) {\r
384             prefsize.width = getWidth();\r
385             prefsize.height = getHeight();\r
386 \r
387             scale = findScale();\r
388             img = createImage(prefsize.width, prefsize.height);\r
389             ig = img.getGraphics();\r
390             Graphics2D ig2 = (Graphics2D) ig;\r
391 \r
392             ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,\r
393                                  RenderingHints.VALUE_ANTIALIAS_ON);\r
394 \r
395 \r
396             redrawneeded = true;\r
397         }\r
398 \r
399 \r
400         if (redrawneeded)\r
401         {\r
402           drawAll(ig, prefsize.width, prefsize.height);\r
403           redrawneeded = false;\r
404         }\r
405 \r
406         g.drawImage(img, 0, 0, this);\r
407     }\r
408 \r
409     public void drawAll(Graphics g, int width, int height)\r
410     {\r
411       g.setColor(Color.black);\r
412       g.fillRect(0, 0, width, height);\r
413       drawScene(g);\r
414       drawLabels(g);\r
415     }\r
416 \r
417 \r
418     public void updateSeqColours()\r
419     {\r
420       if(bysequence && pdb!=null)\r
421       {\r
422         for (int ii = 0; ii < pdb.chains.size(); ii++)\r
423         {\r
424           ( (PDBChain) pdb.chains.elementAt(ii)).colourBySequence(sr, fr);\r
425         }\r
426       }\r
427 \r
428       redrawneeded=true;\r
429       repaint();\r
430 \r
431     }\r
432 \r
433     public void drawScene(Graphics g) {\r
434         // Sort the bonds by z coord\r
435         Vector bonds = new Vector();\r
436 \r
437         for (int ii = 0; ii < pdb.chains.size(); ii++)\r
438         {\r
439           if ( ( (PDBChain) pdb.chains.elementAt(ii)).isVisible)\r
440           {\r
441             Vector tmp = ( (PDBChain) pdb.chains.elementAt(ii)).bonds;\r
442 \r
443             for (int i = 0; i < tmp.size(); i++)\r
444             {\r
445               bonds.addElement(tmp.elementAt(i));\r
446             }\r
447           }\r
448         }\r
449 \r
450         if (zbuffer) {\r
451             Zsort.Zsort(bonds);\r
452         }\r
453 \r
454         for (int i = 0; i < bonds.size(); i++) {\r
455             Bond tmpBond = (Bond) bonds.elementAt(i);\r
456 \r
457             xstart = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
458                 (getWidth() / 2));\r
459             ystart = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
460                 (getHeight() / 2));\r
461 \r
462             xend = (int) (((tmpBond.end[0] - centre[0]) * scale) +\r
463                 (getWidth() / 2));\r
464             yend = (int) (((tmpBond.end[1] - centre[1]) * scale) +\r
465                 (getHeight() / 2));\r
466 \r
467             xmid = (xend + xstart) / 2;\r
468             ymid = (yend + ystart) / 2;\r
469 \r
470             if (depthcue && !bymolecule) {\r
471                 if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {\r
472                     g.setColor(tmpBond.startCol.darker().darker());\r
473                     drawLine(g, xstart, ystart, xmid, ymid);\r
474 \r
475                     g.setColor(tmpBond.endCol.darker().darker());\r
476                     drawLine(g, xmid, ymid, xend, yend);\r
477                 } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
478                     g.setColor(tmpBond.startCol.darker());\r
479                     drawLine(g, xstart, ystart, xmid, ymid);\r
480 \r
481                     g.setColor(tmpBond.endCol.darker());\r
482                     drawLine(g, xmid, ymid, xend, yend);\r
483                 } else {\r
484                     g.setColor(tmpBond.startCol);\r
485                     drawLine(g, xstart, ystart, xmid, ymid);\r
486 \r
487                     g.setColor(tmpBond.endCol);\r
488                     drawLine(g, xmid, ymid, xend, yend);\r
489                 }\r
490             } else if (depthcue && bymolecule) {\r
491                 if (tmpBond.start[2] < (centre[2] - (maxwidth / 6))) {\r
492                     g.setColor(Color.green.darker().darker());\r
493                     drawLine(g, xstart, ystart, xend, yend);\r
494                 } else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6))) {\r
495                     g.setColor(Color.green.darker());\r
496                     drawLine(g, xstart, ystart, xend, yend);\r
497                 } else {\r
498                     g.setColor(Color.green);\r
499                     drawLine(g, xstart, ystart, xend, yend);\r
500                 }\r
501             } else if (!depthcue && !bymolecule) {\r
502                 g.setColor(tmpBond.startCol);\r
503                 drawLine(g, xstart, ystart, xmid, ymid);\r
504                 g.setColor(tmpBond.endCol);\r
505                 drawLine(g, xmid, ymid, xend, yend);\r
506             } else {\r
507                 drawLine(g, xstart, ystart, xend, yend);\r
508             }\r
509         }\r
510     }\r
511 \r
512     public void drawLine(Graphics g, int x1, int y1, int x2, int y2) {\r
513         if (!wire) {\r
514             if (((float) Math.abs(y2 - y1) / (float) Math.abs(x2 - x1)) < 0.5) {\r
515                 g.drawLine(x1, y1, x2, y2);\r
516                 g.drawLine(x1 + 1, y1 + 1, x2 + 1, y2 + 1);\r
517                 g.drawLine(x1, y1 - 1, x2, y2 - 1);\r
518             } else {\r
519                 g.setColor(g.getColor().brighter());\r
520                 g.drawLine(x1, y1, x2, y2);\r
521                 g.drawLine(x1 + 1, y1, x2 + 1, y2);\r
522                 g.drawLine(x1 - 1, y1, x2 - 1, y2);\r
523             }\r
524         } else {\r
525             g.drawLine(x1, y1, x2, y2);\r
526         }\r
527     }\r
528 \r
529     public Dimension minimumsize() {\r
530         return prefsize;\r
531     }\r
532 \r
533     public Dimension preferredsize() {\r
534         return prefsize;\r
535     }\r
536 \r
537     public void keyPressed(KeyEvent evt)\r
538     {\r
539       if (evt.getKeyCode() == KeyEvent.VK_UP)\r
540       {\r
541         scale = (float) (scale * 1.1);\r
542         redrawneeded = true;\r
543         repaint();\r
544       }\r
545       else if (evt.getKeyCode() == KeyEvent.VK_DOWN)\r
546       {\r
547         scale = (float) (scale * 0.9);\r
548         redrawneeded = true;\r
549         repaint();\r
550       }\r
551     }\r
552 \r
553     public void mousePressed(MouseEvent e) {\r
554         myAtom fatom = findAtom(e.getX(), e.getY());\r
555         if(fatom!=null)\r
556         {\r
557           fatom.isSelected = !fatom.isSelected;\r
558           redrawneeded = true;\r
559           repaint();\r
560         }\r
561         mx = e.getX();\r
562         my = e.getY();\r
563         omx = mx;\r
564         omy = my;\r
565         dragging = false;\r
566     }\r
567 \r
568     public void mouseMoved(MouseEvent e) {\r
569 \r
570         myAtom fatom = findAtom(e.getX(), e.getY());\r
571 \r
572         if(foundchain!=-1)\r
573         {\r
574           PDBChain chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
575           int pos = chain.seqstart +\r
576               (fatom.resNumber - chain.pdbstart - chain.offset)+1;\r
577 \r
578           int index = seqcanvas.getViewport().getAlignment().findIndex(sequence);\r
579 \r
580           seqcanvas.highlightSearchResults(new int[]{index, pos, pos});\r
581         }\r
582         else\r
583           seqcanvas.highlightSearchResults(null);\r
584 \r
585         if (fatom != null) {\r
586             this.setToolTipText(fatom.resNumber+" "+ fatom.resName);\r
587         } else {\r
588             this.setToolTipText("");\r
589         }\r
590     }\r
591 \r
592     public void mouseClicked(MouseEvent e) {\r
593     }\r
594 \r
595     public void mouseEntered(MouseEvent e) {\r
596     }\r
597 \r
598     public void mouseExited(MouseEvent e) {\r
599     }\r
600 \r
601     public void mouseDragged(MouseEvent evt) {\r
602         int x = evt.getX();\r
603         int y = evt.getY();\r
604         mx = x;\r
605         my = y;\r
606 \r
607         MCMatrix objmat = new MCMatrix(3, 3);\r
608         objmat.setIdentity();\r
609 \r
610         if ((evt.getModifiers() & Event.META_MASK) != 0) {\r
611             objmat.rotatez((float) ((mx - omx)));\r
612         } else {\r
613             objmat.rotatex((float) ((my - omy)));\r
614             objmat.rotatey((float) ((omx - mx)));\r
615         }\r
616 \r
617         //Alter the bonds\r
618         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
619             Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
620 \r
621             for (int i = 0; i < bonds.size(); i++) {\r
622                 Bond tmpBond = (Bond) bonds.elementAt(i);\r
623 \r
624                 //Translate the bond so the centre is 0,0,0\r
625                 tmpBond.translate(-centre[0], -centre[1], -centre[2]);\r
626 \r
627                 //Now apply the rotation matrix\r
628                 tmpBond.start = objmat.vectorMultiply(tmpBond.start);\r
629                 tmpBond.end = objmat.vectorMultiply(tmpBond.end);\r
630 \r
631                 //Now translate back again\r
632                 tmpBond.translate(centre[0], centre[1], centre[2]);\r
633             }\r
634         }\r
635 \r
636         objmat = null;\r
637 \r
638         omx = mx;\r
639         omy = my;\r
640 \r
641         dragging = true;\r
642 \r
643         redrawneeded = true;\r
644 \r
645         repaint();\r
646     }\r
647 \r
648     public void mouseReleased(MouseEvent evt) {\r
649         dragging = false;\r
650         return;\r
651     }\r
652 \r
653     void drawLabels(Graphics g) {\r
654 \r
655         for (int ii = 0; ii < pdb.chains.size(); ii++)\r
656         {\r
657             PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
658 \r
659             if (chain.isVisible)\r
660             {\r
661                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
662 \r
663                 for (int i = 0; i < bonds.size(); i++)\r
664                 {\r
665                     Bond tmpBond = (Bond) bonds.elementAt(i);\r
666 \r
667                     if (tmpBond.at1.isSelected)\r
668                     {\r
669                         labelAtom(g, tmpBond, 1);\r
670                     }\r
671 \r
672                     if (tmpBond.at2.isSelected)\r
673                     {\r
674 \r
675                         labelAtom(g, tmpBond, 2);\r
676                     }\r
677                 }\r
678             }\r
679         }\r
680     }\r
681 \r
682     public void labelAtom(Graphics g, Bond b, int n) {\r
683         g.setFont(font);\r
684 \r
685         if (n == 1) {\r
686             int xstart = (int) (((b.start[0] - centre[0]) * scale) +\r
687                 (getWidth() / 2));\r
688             int ystart = (int) (((b.start[1] - centre[1]) * scale) +\r
689                 (getHeight() / 2));\r
690 \r
691             g.setColor(Color.red);\r
692             g.drawString(b.at1.resName + "-" + b.at1.resNumber, xstart, ystart);\r
693         }\r
694 \r
695         if (n == 2) {\r
696             int xstart = (int) (((b.end[0] - centre[0]) * scale) +\r
697                 (getWidth() / 2));\r
698             int ystart = (int) (((b.end[1] - centre[1]) * scale) +\r
699                 (getHeight() / 2));\r
700 \r
701             g.setColor(Color.red);\r
702             g.drawString(b.at2.resName + "-" + b.at2.resNumber, xstart, ystart);\r
703         }\r
704     }\r
705 \r
706     int foundchain = -1;\r
707     public myAtom findAtom(int x, int y) {\r
708         myAtom fatom = null;\r
709 \r
710         foundchain = -1;\r
711 \r
712         for (int ii = 0; ii < pdb.chains.size(); ii++) {\r
713             PDBChain chain = (PDBChain) pdb.chains.elementAt(ii);\r
714 \r
715             if (chain.isVisible) {\r
716                 Vector bonds = ((PDBChain) pdb.chains.elementAt(ii)).bonds;\r
717 \r
718                 for (int i = 0; i < bonds.size(); i++) {\r
719                     Bond tmpBond = (Bond) bonds.elementAt(i);\r
720 \r
721                     int truex = (int) (((tmpBond.start[0] - centre[0]) * scale) +\r
722                         (getWidth() / 2));\r
723 \r
724                     if (Math.abs(truex - x) <= 2) {\r
725                         int truey = (int) (((tmpBond.start[1] - centre[1]) * scale) +\r
726                             (getHeight() / 2));\r
727 \r
728                         if (Math.abs(truey - y) <= 2)\r
729                         {\r
730                             fatom = tmpBond.at1;\r
731                             foundchain = ii;\r
732                             break;\r
733                         }\r
734                     }\r
735                 }\r
736             }\r
737 \r
738             if (fatom != null) //)&& chain.ds != null)\r
739              {\r
740                 chain = (PDBChain) pdb.chains.elementAt(foundchain);\r
741             }\r
742         }\r
743 \r
744         return fatom;\r
745     }\r
746 }\r