Clover icon

Coverage Report

  1. Project Clover database Thu Jan 15 2026 16:11:02 GMT
  2. Package mc_view

File PDBCanvas.java

 

Coverage histogram

../img/srcFileCovDistChart0.png
62% of files have more coverage

Code metrics

198
442
37
1
1,223
940
149
0.34
11.95
37
4.03

Classes

Class Line # Actions
PDBCanvas 57 442 149
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ The Jalview Authors
4    *
5    * This file is part of Jalview.
6    *
7    * Jalview is free software: you can redistribute it and/or
8    * modify it under the terms of the GNU General Public License
9    * as published by the Free Software Foundation, either version 3
10    * of the License, or (at your option) any later version.
11    *
12    * Jalview is distributed in the hope that it will be useful, but
13    * WITHOUT ANY WARRANTY; without even the implied warranty
14    * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15    * PURPOSE. See the GNU General Public License for more details.
16    *
17    * You should have received a copy of the GNU General Public License
18    * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19    * The Jalview Authors are detailed in the 'AUTHORS' file.
20    */
21    package mc_view;
22   
23    import java.awt.Color;
24    import java.awt.Dimension;
25    import java.awt.Font;
26    import java.awt.Graphics;
27    import java.awt.Graphics2D;
28    // JBPNote TODO: This class is quite noisy - needs proper log.info/log.debug
29    import java.awt.Image;
30    import java.awt.RenderingHints;
31    import java.awt.event.KeyAdapter;
32    import java.awt.event.KeyEvent;
33    import java.awt.event.MouseEvent;
34    import java.awt.event.MouseListener;
35    import java.awt.event.MouseMotionListener;
36    import java.io.PrintStream;
37    import java.util.List;
38    import java.util.Vector;
39   
40    import javax.swing.JPanel;
41    import javax.swing.ToolTipManager;
42   
43    import jalview.analysis.AlignSeq;
44    import jalview.datamodel.PDBEntry;
45    import jalview.datamodel.SequenceI;
46    import jalview.gui.AlignmentPanel;
47    import jalview.gui.FeatureRenderer;
48    import jalview.gui.SequenceRenderer;
49    import jalview.io.DataSourceType;
50    import jalview.io.StructureFile;
51    import jalview.renderer.seqfeatures.FeatureColourFinder;
52    import jalview.structure.AtomSpec;
53    import jalview.structure.StructureListener;
54    import jalview.structure.StructureMapping;
55    import jalview.structure.StructureSelectionManager;
56   
 
57    public class PDBCanvas extends JPanel
58    implements MouseListener, MouseMotionListener, StructureListener
59    {
60    boolean redrawneeded = true;
61   
62    int omx = 0;
63   
64    int mx = 0;
65   
66    int omy = 0;
67   
68    int my = 0;
69   
70    public StructureFile pdb;
71   
72    PDBEntry pdbentry;
73   
74    int bsize;
75   
76    Image img;
77   
78    Graphics ig;
79   
80    Dimension prefsize;
81   
82    float[] centre = new float[3];
83   
84    float[] width = new float[3];
85   
86    float maxwidth;
87   
88    float scale;
89   
90    String inStr;
91   
92    String inType;
93   
94    boolean bysequence = true;
95   
96    boolean depthcue = true;
97   
98    boolean wire = false;
99   
100    boolean bymolecule = false;
101   
102    boolean zbuffer = true;
103   
104    boolean dragging;
105   
106    int xstart;
107   
108    int xend;
109   
110    int ystart;
111   
112    int yend;
113   
114    int xmid;
115   
116    int ymid;
117   
118    Font font = new Font("Helvetica", Font.PLAIN, 10);
119   
120    jalview.gui.SeqCanvas seqcanvas;
121   
122    public SequenceI[] sequence;
123   
124    final StringBuffer mappingDetails = new StringBuffer();
125   
126    PDBChain mainchain;
127   
128    Vector<String> highlightRes;
129   
130    boolean pdbAction = false;
131   
132    boolean seqColoursReady = false;
133   
134    jalview.renderer.seqfeatures.FeatureRenderer fr;
135   
136    Color backgroundColour = Color.black;
137   
138    AlignmentPanel ap;
139   
140    StructureSelectionManager ssm;
141   
142    String errorMessage;
143   
 
144  0 toggle void init(PDBEntry pdbentry, SequenceI[] seq, String[] chains,
145    AlignmentPanel ap, DataSourceType protocol)
146    {
147  0 this.ap = ap;
148  0 this.pdbentry = pdbentry;
149  0 this.sequence = seq;
150   
151  0 ssm = ap.av.getStructureSelectionManager();
152   
153  0 try
154    {
155  0 pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol,
156    ap.alignFrame);
157   
158  0 if (protocol.equals(jalview.io.DataSourceType.PASTE))
159    {
160  0 pdbentry.setFile("INLINE" + pdb.getId());
161    }
162   
163    } catch (Exception ex)
164    {
165  0 ex.printStackTrace();
166  0 return;
167    }
168   
169  0 if (pdb == null)
170    {
171  0 errorMessage = "Error loading file: " + pdbentry.getId();
172  0 return;
173    }
174  0 pdbentry.setId(pdb.getId());
175   
176  0 ssm.addStructureViewerListener(this);
177   
178  0 colourBySequence();
179   
180  0 float max = -10;
181  0 int maxchain = -1;
182  0 int pdbstart = 0;
183  0 int pdbend = 0;
184  0 int seqstart = 0;
185  0 int seqend = 0;
186   
187    // JUST DEAL WITH ONE SEQUENCE FOR NOW
188  0 SequenceI sequence = seq[0];
189   
190  0 for (int i = 0; i < pdb.getChains().size(); i++)
191    {
192   
193  0 mappingDetails.append("\n\nPDB Sequence is :\nSequence = "
194    + pdb.getChains().elementAt(i).sequence
195    .getSequenceAsString());
196  0 mappingDetails.append("\nNo of residues = "
197    + pdb.getChains().elementAt(i).residues.size() + "\n\n");
198   
199    // Now lets compare the sequences to get
200    // the start and end points.
201    // Align the sequence to the pdb
202  0 AlignSeq as = new AlignSeq(sequence,
203    pdb.getChains().elementAt(i).sequence, "pep");
204  0 as.calcScoreMatrix();
205  0 as.traceAlignment();
206  0 PrintStream ps = new PrintStream(System.out)
207    {
 
208  0 toggle @Override
209    public void print(String x)
210    {
211  0 mappingDetails.append(x);
212    }
213   
 
214  0 toggle @Override
215    public void println()
216    {
217  0 mappingDetails.append("\n");
218    }
219    };
220   
221  0 as.printAlignment(ps);
222   
223  0 if (as.maxscore > max)
224    {
225  0 max = as.maxscore;
226  0 maxchain = i;
227   
228  0 pdbstart = as.seq2start;
229  0 pdbend = as.seq2end;
230  0 seqstart = as.seq1start + sequence.getStart() - 1;
231  0 seqend = as.seq1end + sequence.getEnd() - 1;
232    }
233   
234  0 mappingDetails.append("\nPDB start/end " + pdbstart + " " + pdbend);
235  0 mappingDetails.append("\nSEQ start/end " + seqstart + " " + seqend);
236    }
237   
238  0 mainchain = pdb.getChains().elementAt(maxchain);
239   
240  0 mainchain.pdbstart = pdbstart;
241  0 mainchain.pdbend = pdbend;
242  0 mainchain.seqstart = seqstart;
243  0 mainchain.seqend = seqend;
244  0 mainchain.isVisible = true;
245   
246  0 this.pdb = pdb;
247  0 this.prefsize = new Dimension(getSize().width, getSize().height);
248   
249  0 addMouseMotionListener(this);
250  0 addMouseListener(this);
251   
252  0 addKeyListener(new KeyAdapter()
253    {
 
254  0 toggle @Override
255    public void keyPressed(KeyEvent evt)
256    {
257  0 keyPressed(evt);
258    }
259    });
260   
261  0 findCentre();
262  0 findWidth();
263   
264  0 setupBonds();
265   
266  0 scale = findScale();
267   
268  0 ToolTipManager.sharedInstance().registerComponent(this);
269  0 ToolTipManager.sharedInstance().setInitialDelay(0);
270  0 ToolTipManager.sharedInstance().setDismissDelay(10000);
271    }
272   
273    Vector<Bond> visiblebonds;
274   
 
275  0 toggle void setupBonds()
276    {
277  0 seqColoursReady = false;
278    // Sort the bonds by z coord
279  0 visiblebonds = new Vector<Bond>();
280   
281  0 for (PDBChain chain : pdb.getChains())
282    {
283  0 if (chain.isVisible)
284    {
285  0 for (Bond bond : chain.bonds)
286    {
287  0 visiblebonds.addElement(bond);
288    }
289    }
290    }
291   
292  0 updateSeqColours();
293  0 seqColoursReady = true;
294  0 redrawneeded = true;
295  0 repaint();
296    }
297   
 
298  0 toggle public void findWidth()
299    {
300  0 float[] max = new float[3];
301  0 float[] min = new float[3];
302   
303  0 max[0] = (float) -1e30;
304  0 max[1] = (float) -1e30;
305  0 max[2] = (float) -1e30;
306   
307  0 min[0] = (float) 1e30;
308  0 min[1] = (float) 1e30;
309  0 min[2] = (float) 1e30;
310   
311  0 for (PDBChain chain : pdb.getChains())
312    {
313  0 if (chain.isVisible)
314    {
315  0 for (Bond tmp : chain.bonds)
316    {
317  0 if (tmp.start[0] >= max[0])
318    {
319  0 max[0] = tmp.start[0];
320    }
321   
322  0 if (tmp.start[1] >= max[1])
323    {
324  0 max[1] = tmp.start[1];
325    }
326   
327  0 if (tmp.start[2] >= max[2])
328    {
329  0 max[2] = tmp.start[2];
330    }
331   
332  0 if (tmp.start[0] <= min[0])
333    {
334  0 min[0] = tmp.start[0];
335    }
336   
337  0 if (tmp.start[1] <= min[1])
338    {
339  0 min[1] = tmp.start[1];
340    }
341   
342  0 if (tmp.start[2] <= min[2])
343    {
344  0 min[2] = tmp.start[2];
345    }
346   
347  0 if (tmp.end[0] >= max[0])
348    {
349  0 max[0] = tmp.end[0];
350    }
351   
352  0 if (tmp.end[1] >= max[1])
353    {
354  0 max[1] = tmp.end[1];
355    }
356   
357  0 if (tmp.end[2] >= max[2])
358    {
359  0 max[2] = tmp.end[2];
360    }
361   
362  0 if (tmp.end[0] <= min[0])
363    {
364  0 min[0] = tmp.end[0];
365    }
366   
367  0 if (tmp.end[1] <= min[1])
368    {
369  0 min[1] = tmp.end[1];
370    }
371   
372  0 if (tmp.end[2] <= min[2])
373    {
374  0 min[2] = tmp.end[2];
375    }
376    }
377    }
378    }
379    /*
380    * System.out.println("xmax " + max[0] + " min " + min[0]);
381    * System.out.println("ymax " + max[1] + " min " + min[1]);
382    * System.out.println("zmax " + max[2] + " min " + min[2]);
383    */
384   
385  0 width[0] = Math.abs(max[0] - min[0]);
386  0 width[1] = Math.abs(max[1] - min[1]);
387  0 width[2] = Math.abs(max[2] - min[2]);
388   
389  0 maxwidth = width[0];
390   
391  0 if (width[1] > width[0])
392    {
393  0 maxwidth = width[1];
394    }
395   
396  0 if (width[2] > width[1])
397    {
398  0 maxwidth = width[2];
399    }
400   
401    // System.out.println("Maxwidth = " + maxwidth);
402    }
403   
 
404  0 toggle public float findScale()
405    {
406  0 int dim;
407  0 int width;
408  0 int height;
409   
410  0 if (getWidth() != 0)
411    {
412  0 width = getWidth();
413  0 height = getHeight();
414    }
415    else
416    {
417  0 width = prefsize.width;
418  0 height = prefsize.height;
419    }
420   
421  0 if (width < height)
422    {
423  0 dim = width;
424    }
425    else
426    {
427  0 dim = height;
428    }
429   
430  0 return (float) (dim / (1.5d * maxwidth));
431    }
432   
 
433  0 toggle public void findCentre()
434    {
435  0 float xtot = 0;
436  0 float ytot = 0;
437  0 float ztot = 0;
438   
439  0 int bsize = 0;
440   
441    // Find centre coordinate
442  0 for (PDBChain chain : pdb.getChains())
443    {
444  0 if (chain.isVisible)
445    {
446  0 bsize += chain.bonds.size();
447   
448  0 for (Bond bond : chain.bonds)
449    {
450  0 xtot = xtot + bond.start[0] + bond.end[0];
451  0 ytot = ytot + bond.start[1] + bond.end[1];
452  0 ztot = ztot + bond.start[2] + bond.end[2];
453    }
454    }
455    }
456   
457  0 centre[0] = xtot / (2 * (float) bsize);
458  0 centre[1] = ytot / (2 * (float) bsize);
459  0 centre[2] = ztot / (2 * (float) bsize);
460    }
461   
 
462  0 toggle @Override
463    public void paintComponent(Graphics g)
464    {
465  0 super.paintComponent(g);
466   
467  0 if (!seqColoursReady || errorMessage != null)
468    {
469  0 g.setColor(Color.black);
470  0 g.setFont(new Font("Verdana", Font.BOLD, 14));
471  0 g.drawString(errorMessage == null ? "Retrieving PDB data...."
472    : errorMessage, 20, getHeight() / 2);
473  0 return;
474    }
475   
476    // Only create the image at the beginning -
477    // this saves much memory usage
478  0 if ((img == null) || (prefsize.width != getWidth())
479    || (prefsize.height != getHeight()))
480   
481    {
482  0 prefsize.width = getWidth();
483  0 prefsize.height = getHeight();
484   
485  0 scale = findScale();
486  0 img = createImage(prefsize.width, prefsize.height);
487  0 ig = img.getGraphics();
488  0 Graphics2D ig2 = (Graphics2D) ig;
489   
490  0 ig2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
491    RenderingHints.VALUE_ANTIALIAS_ON);
492   
493  0 redrawneeded = true;
494    }
495   
496  0 if (redrawneeded)
497    {
498  0 drawAll(ig, prefsize.width, prefsize.height);
499  0 redrawneeded = false;
500    }
501   
502  0 g.drawImage(img, 0, 0, this);
503   
504  0 pdbAction = false;
505    }
506   
 
507  0 toggle public void drawAll(Graphics g, int width, int height)
508    {
509  0 g.setColor(backgroundColour);
510  0 g.fillRect(0, 0, width, height);
511  0 drawScene(g);
512  0 drawLabels(g);
513    }
514   
 
515  0 toggle public void updateSeqColours()
516    {
517  0 if (pdbAction)
518    {
519  0 return;
520    }
521   
522  0 colourBySequence();
523   
524  0 redrawneeded = true;
525  0 repaint();
526    }
527   
528    // This method has been taken out of PDBChain to allow
529    // Applet and Application specific sequence renderers to be used
 
530  0 toggle void colourBySequence()
531    {
532  0 SequenceRenderer sr = new SequenceRenderer(ap.av);
533   
534  0 StructureMapping[] mapping = ssm.getMapping(pdbentry.getFile());
535   
536  0 boolean showFeatures = false;
537  0 if (ap.av.isShowSequenceFeatures())
538    {
539  0 if (fr == null)
540    {
541  0 fr = new FeatureRenderer(ap);
542    }
543   
544  0 fr.transferSettings(ap.alignFrame.getFeatureRenderer());
545   
546  0 showFeatures = true;
547    }
548   
549  0 FeatureColourFinder finder = new FeatureColourFinder(fr);
550  0 PDBChain chain;
551  0 if (bysequence && pdb != null)
552    {
553  0 for (int ii = 0; ii < pdb.getChains().size(); ii++)
554    {
555  0 chain = pdb.getChains().elementAt(ii);
556   
557  0 for (int i = 0; i < chain.bonds.size(); i++)
558    {
559  0 Bond tmp = chain.bonds.elementAt(i);
560  0 tmp.startCol = Color.lightGray;
561  0 tmp.endCol = Color.lightGray;
562  0 if (chain != mainchain)
563    {
564  0 continue;
565    }
566   
567  0 for (int s = 0; s < sequence.length; s++)
568    {
569  0 for (int m = 0; m < mapping.length; m++)
570    {
571  0 if (mapping[m].getSequence() == sequence[s])
572    {
573  0 int pos = mapping[m].getSeqPos(tmp.at1.resNumber) - 1;
574  0 if (pos > 0)
575    {
576  0 pos = sequence[s].findIndex(pos);
577  0 tmp.startCol = sr.getResidueColour(sequence[s], pos,
578    finder);
579    }
580  0 pos = mapping[m].getSeqPos(tmp.at2.resNumber) - 1;
581  0 if (pos > 0)
582    {
583  0 pos = sequence[s].findIndex(pos);
584  0 tmp.endCol = sr.getResidueColour(sequence[s], pos,
585    finder);
586    }
587   
588    }
589    }
590    }
591    }
592    }
593    }
594    }
595   
596    Zsort zsort;
597   
 
598  0 toggle public void drawScene(Graphics g)
599    {
600  0 if (zbuffer)
601    {
602  0 if (zsort == null)
603    {
604  0 zsort = new Zsort();
605    }
606   
607  0 zsort.sort(visiblebonds);
608    }
609   
610  0 Bond tmpBond = null;
611  0 for (int i = 0; i < visiblebonds.size(); i++)
612    {
613  0 tmpBond = visiblebonds.elementAt(i);
614   
615  0 xstart = (int) (((tmpBond.start[0] - centre[0]) * scale)
616    + (getWidth() / 2));
617  0 ystart = (int) (((centre[1] - tmpBond.start[1]) * scale)
618    + (getHeight() / 2));
619   
620  0 xend = (int) (((tmpBond.end[0] - centre[0]) * scale)
621    + (getWidth() / 2));
622  0 yend = (int) (((centre[1] - tmpBond.end[1]) * scale)
623    + (getHeight() / 2));
624   
625  0 xmid = (xend + xstart) / 2;
626  0 ymid = (yend + ystart) / 2;
627  0 if (depthcue && !bymolecule)
628    {
629  0 if (tmpBond.start[2] < (centre[2] - (maxwidth / 6)))
630    {
631   
632  0 g.setColor(tmpBond.startCol.darker().darker());
633  0 drawLine(g, xstart, ystart, xmid, ymid);
634  0 g.setColor(tmpBond.endCol.darker().darker());
635  0 drawLine(g, xmid, ymid, xend, yend);
636   
637    }
638  0 else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6)))
639    {
640  0 g.setColor(tmpBond.startCol.darker());
641  0 drawLine(g, xstart, ystart, xmid, ymid);
642   
643  0 g.setColor(tmpBond.endCol.darker());
644  0 drawLine(g, xmid, ymid, xend, yend);
645    }
646    else
647    {
648  0 g.setColor(tmpBond.startCol);
649  0 drawLine(g, xstart, ystart, xmid, ymid);
650   
651  0 g.setColor(tmpBond.endCol);
652  0 drawLine(g, xmid, ymid, xend, yend);
653    }
654    }
655  0 else if (depthcue && bymolecule)
656    {
657  0 if (tmpBond.start[2] < (centre[2] - (maxwidth / 6)))
658    {
659  0 g.setColor(Color.green.darker().darker());
660  0 drawLine(g, xstart, ystart, xend, yend);
661    }
662  0 else if (tmpBond.start[2] < (centre[2] + (maxwidth / 6)))
663    {
664  0 g.setColor(Color.green.darker());
665  0 drawLine(g, xstart, ystart, xend, yend);
666    }
667    else
668    {
669  0 g.setColor(Color.green);
670  0 drawLine(g, xstart, ystart, xend, yend);
671    }
672    }
673  0 else if (!depthcue && !bymolecule)
674    {
675  0 g.setColor(tmpBond.startCol);
676  0 drawLine(g, xstart, ystart, xmid, ymid);
677  0 g.setColor(tmpBond.endCol);
678  0 drawLine(g, xmid, ymid, xend, yend);
679    }
680    else
681    {
682  0 drawLine(g, xstart, ystart, xend, yend);
683    }
684   
685  0 if (highlightBond1 != null && highlightBond1 == tmpBond)
686    {
687  0 g.setColor(
688    tmpBond.endCol.brighter().brighter().brighter().brighter());
689  0 drawLine(g, xmid, ymid, xend, yend);
690    }
691   
692  0 if (highlightBond2 != null && highlightBond2 == tmpBond)
693    {
694  0 g.setColor(tmpBond.startCol.brighter().brighter().brighter()
695    .brighter());
696  0 drawLine(g, xstart, ystart, xmid, ymid);
697    }
698   
699    }
700   
701    }
702   
 
703  0 toggle public void drawLine(Graphics g, int x1, int y1, int x2, int y2)
704    {
705  0 if (!wire)
706    {
707  0 if (((float) Math.abs(y2 - y1) / (float) Math.abs(x2 - x1)) < 0.5)
708    {
709  0 g.drawLine(x1, y1, x2, y2);
710  0 g.drawLine(x1 + 1, y1 + 1, x2 + 1, y2 + 1);
711  0 g.drawLine(x1, y1 - 1, x2, y2 - 1);
712    }
713    else
714    {
715  0 g.setColor(g.getColor().brighter());
716  0 g.drawLine(x1, y1, x2, y2);
717  0 g.drawLine(x1 + 1, y1, x2 + 1, y2);
718  0 g.drawLine(x1 - 1, y1, x2 - 1, y2);
719    }
720    }
721    else
722    {
723  0 g.drawLine(x1, y1, x2, y2);
724    }
725    }
726   
 
727  0 toggle public Dimension minimumsize()
728    {
729  0 return prefsize;
730    }
731   
 
732  0 toggle public Dimension preferredsize()
733    {
734  0 return prefsize;
735    }
736   
 
737  0 toggle public void keyPressed(KeyEvent evt)
738    {
739  0 if (evt.getKeyCode() == KeyEvent.VK_UP)
740    {
741  0 scale = (float) (scale * 1.1);
742  0 redrawneeded = true;
743  0 repaint();
744    }
745  0 else if (evt.getKeyCode() == KeyEvent.VK_DOWN)
746    {
747  0 scale = (float) (scale * 0.9);
748  0 redrawneeded = true;
749  0 repaint();
750    }
751    }
752   
 
753  0 toggle @Override
754    public void mousePressed(MouseEvent e)
755    {
756  0 pdbAction = true;
757  0 Atom fatom = findAtom(e.getX(), e.getY());
758  0 if (fatom != null)
759    {
760  0 fatom.isSelected = !fatom.isSelected;
761   
762  0 redrawneeded = true;
763  0 repaint();
764  0 if (foundchain != -1)
765    {
766  0 PDBChain chain = pdb.getChains().elementAt(foundchain);
767  0 if (chain == mainchain)
768    {
769  0 if (fatom.alignmentMapping != -1)
770    {
771  0 if (highlightRes == null)
772    {
773  0 highlightRes = new Vector<String>();
774    }
775   
776  0 final String atomString = Integer
777    .toString(fatom.alignmentMapping);
778  0 if (highlightRes.contains(atomString))
779    {
780  0 highlightRes.remove(atomString);
781    }
782    else
783    {
784  0 highlightRes.add(atomString);
785    }
786    }
787    }
788    }
789   
790    }
791  0 mx = e.getX();
792  0 my = e.getY();
793  0 omx = mx;
794  0 omy = my;
795  0 dragging = false;
796    }
797   
 
798  0 toggle @Override
799    public void mouseMoved(MouseEvent e)
800    {
801  0 pdbAction = true;
802  0 if (highlightBond1 != null)
803    {
804  0 highlightBond1.at2.isSelected = false;
805  0 highlightBond2.at1.isSelected = false;
806  0 highlightBond1 = null;
807  0 highlightBond2 = null;
808    }
809   
810  0 Atom fatom = findAtom(e.getX(), e.getY());
811   
812  0 PDBChain chain = null;
813  0 if (foundchain != -1)
814    {
815  0 chain = pdb.getChains().elementAt(foundchain);
816  0 if (chain == mainchain)
817    {
818  0 mouseOverStructure(fatom.resNumber, chain.id);
819    }
820    }
821   
822  0 if (fatom != null)
823    {
824  0 this.setToolTipText(
825    chain.id + ":" + fatom.resNumber + " " + fatom.resName);
826    }
827    else
828    {
829  0 mouseOverStructure(-1, chain != null ? chain.id : null);
830  0 this.setToolTipText(null);
831    }
832    }
833   
 
834  0 toggle @Override
835    public void mouseClicked(MouseEvent e)
836    {
837    }
838   
 
839  0 toggle @Override
840    public void mouseEntered(MouseEvent e)
841    {
842    }
843   
 
844  0 toggle @Override
845    public void mouseExited(MouseEvent e)
846    {
847    }
848   
 
849  0 toggle @Override
850    public void mouseDragged(MouseEvent evt)
851    {
852  0 int x = evt.getX();
853  0 int y = evt.getY();
854  0 mx = x;
855  0 my = y;
856   
857  0 MCMatrix objmat = new MCMatrix(3, 3);
858  0 objmat.setIdentity();
859   
860  0 if ((evt.getModifiersEx() & MouseEvent.META_DOWN_MASK) != 0)
861    {
862  0 objmat.rotatez(((mx - omx)));
863    }
864    else
865    {
866  0 objmat.rotatex(((my - omy)));
867  0 objmat.rotatey(((omx - mx)));
868    }
869   
870    // Alter the bonds
871  0 for (PDBChain chain : pdb.getChains())
872    {
873  0 for (Bond tmpBond : chain.bonds)
874    {
875    // Translate the bond so the centre is 0,0,0
876  0 tmpBond.translate(-centre[0], -centre[1], -centre[2]);
877   
878    // Now apply the rotation matrix
879  0 tmpBond.start = objmat.vectorMultiply(tmpBond.start);
880  0 tmpBond.end = objmat.vectorMultiply(tmpBond.end);
881   
882    // Now translate back again
883  0 tmpBond.translate(centre[0], centre[1], centre[2]);
884    }
885    }
886   
887  0 objmat = null;
888   
889  0 omx = mx;
890  0 omy = my;
891   
892  0 dragging = true;
893   
894  0 redrawneeded = true;
895   
896  0 repaint();
897    }
898   
 
899  0 toggle @Override
900    public void mouseReleased(MouseEvent evt)
901    {
902  0 dragging = false;
903  0 return;
904    }
905   
 
906  0 toggle void drawLabels(Graphics g)
907    {
908   
909  0 for (PDBChain chain : pdb.getChains())
910    {
911  0 if (chain.isVisible)
912    {
913  0 for (Bond tmpBond : chain.bonds)
914    {
915  0 if (tmpBond.at1.isSelected)
916    {
917  0 labelAtom(g, tmpBond, 1);
918    }
919   
920  0 if (tmpBond.at2.isSelected)
921    {
922  0 labelAtom(g, tmpBond, 2);
923    }
924    }
925    }
926    }
927    }
928   
 
929  0 toggle public void labelAtom(Graphics g, Bond b, int n)
930    {
931  0 g.setFont(font);
932  0 g.setColor(Color.red);
933  0 if (n == 1)
934    {
935  0 int xstart = (int) (((b.start[0] - centre[0]) * scale)
936    + (getWidth() / 2));
937  0 int ystart = (int) (((centre[1] - b.start[1]) * scale)
938    + (getHeight() / 2));
939   
940  0 g.drawString(b.at1.resName + "-" + b.at1.resNumber, xstart, ystart);
941    }
942   
943  0 if (n == 2)
944    {
945  0 int xstart = (int) (((b.end[0] - centre[0]) * scale)
946    + (getWidth() / 2));
947  0 int ystart = (int) (((centre[1] - b.end[1]) * scale)
948    + (getHeight() / 2));
949   
950  0 g.drawString(b.at2.resName + "-" + b.at2.resNumber, xstart, ystart);
951    }
952    }
953   
954    int foundchain = -1;
955   
 
956  0 toggle public Atom findAtom(int x, int y)
957    {
958  0 Atom fatom = null;
959   
960  0 foundchain = -1;
961   
962  0 for (int ii = 0; ii < pdb.getChains().size(); ii++)
963    {
964  0 PDBChain chain = pdb.getChains().elementAt(ii);
965  0 int truex;
966  0 Bond tmpBond = null;
967   
968  0 if (chain.isVisible)
969    {
970  0 for (Bond bond : chain.bonds)
971    {
972  0 tmpBond = bond;
973   
974  0 truex = (int) (((tmpBond.start[0] - centre[0]) * scale)
975    + (getWidth() / 2));
976   
977  0 if (Math.abs(truex - x) <= 2)
978    {
979  0 int truey = (int) (((centre[1] - tmpBond.start[1]) * scale)
980    + (getHeight() / 2));
981   
982  0 if (Math.abs(truey - y) <= 2)
983    {
984  0 fatom = tmpBond.at1;
985  0 foundchain = ii;
986  0 break;
987    }
988    }
989    }
990   
991    // Still here? Maybe its the last bond
992   
993  0 truex = (int) (((tmpBond.end[0] - centre[0]) * scale)
994    + (getWidth() / 2));
995   
996  0 if (Math.abs(truex - x) <= 2)
997    {
998  0 int truey = (int) (((tmpBond.end[1] - centre[1]) * scale)
999    + (getHeight() / 2));
1000   
1001  0 if (Math.abs(truey - y) <= 2)
1002    {
1003  0 fatom = tmpBond.at2;
1004  0 foundchain = ii;
1005  0 break;
1006    }
1007    }
1008   
1009    }
1010   
1011  0 if (fatom != null) // )&& chain.ds != null)
1012    { // dead code? value of chain is either overwritten or discarded
1013  0 chain = pdb.getChains().elementAt(foundchain);
1014    }
1015    }
1016   
1017  0 return fatom;
1018    }
1019   
1020    Bond highlightBond1, highlightBond2;
1021   
 
1022  0 toggle public void highlightRes(int ii)
1023    {
1024  0 if (!seqColoursReady)
1025    {
1026  0 return;
1027    }
1028   
1029  0 if (highlightRes != null && highlightRes.contains((ii - 1) + ""))
1030    {
1031  0 return;
1032    }
1033   
1034  0 int index = -1;
1035  0 Bond tmpBond;
1036  0 for (index = 0; index < mainchain.bonds.size(); index++)
1037    {
1038  0 tmpBond = mainchain.bonds.elementAt(index);
1039  0 if (tmpBond.at1.alignmentMapping == ii - 1)
1040    {
1041  0 if (highlightBond1 != null)
1042    {
1043  0 highlightBond1.at2.isSelected = false;
1044    }
1045   
1046  0 if (highlightBond2 != null)
1047    {
1048  0 highlightBond2.at1.isSelected = false;
1049    }
1050   
1051  0 highlightBond1 = null;
1052  0 highlightBond2 = null;
1053   
1054  0 if (index > 0)
1055    {
1056  0 highlightBond1 = mainchain.bonds.elementAt(index - 1);
1057  0 highlightBond1.at2.isSelected = true;
1058    }
1059   
1060  0 if (index != mainchain.bonds.size())
1061    {
1062  0 highlightBond2 = mainchain.bonds.elementAt(index);
1063  0 highlightBond2.at1.isSelected = true;
1064    }
1065   
1066  0 break;
1067    }
1068    }
1069   
1070  0 redrawneeded = true;
1071  0 repaint();
1072    }
1073   
 
1074  0 toggle public void setAllchainsVisible(boolean b)
1075    {
1076  0 for (int ii = 0; ii < pdb.getChains().size(); ii++)
1077    {
1078  0 PDBChain chain = pdb.getChains().elementAt(ii);
1079  0 chain.isVisible = b;
1080    }
1081  0 mainchain.isVisible = true;
1082  0 findCentre();
1083  0 setupBonds();
1084    }
1085   
1086    // ////////////////////////////////
1087    // /StructureListener
 
1088  0 toggle @Override
1089    public String[] getStructureFiles()
1090    {
1091  0 return new String[] { pdbentry.getFile() };
1092    }
1093   
1094    String lastMessage;
1095   
 
1096  0 toggle public void mouseOverStructure(int pdbResNum, String chain)
1097    {
1098  0 if (lastMessage == null || !lastMessage.equals(pdbResNum + chain))
1099    {
1100  0 ssm.mouseOverStructure(pdbResNum, chain, pdbentry.getFile());
1101    }
1102   
1103  0 lastMessage = pdbResNum + chain;
1104    }
1105   
1106    StringBuffer resetLastRes = new StringBuffer();
1107   
1108    StringBuffer eval = new StringBuffer();
1109   
1110    /**
1111    * Highlight the specified atoms in the structure.
1112    *
1113    * @param atoms
1114    */
 
1115  0 toggle @Override
1116    public void highlightAtoms(List<AtomSpec> atoms)
1117    {
1118  0 if (!seqColoursReady)
1119    {
1120  0 return;
1121    }
1122   
1123  0 for (AtomSpec atom : atoms)
1124    {
1125  0 int atomIndex = atom.getAtomIndex();
1126  0 if (highlightRes != null
1127    && highlightRes.contains((atomIndex - 1) + ""))
1128    {
1129  0 continue;
1130    }
1131   
1132  0 highlightAtom(atomIndex);
1133    }
1134   
1135  0 redrawneeded = true;
1136  0 repaint();
1137    }
1138   
1139    /**
1140    * Highlight the atom at the specified index.
1141    *
1142    * @param atomIndex
1143    */
 
1144  0 toggle protected void highlightAtom(int atomIndex)
1145    {
1146  0 int index = -1;
1147  0 Bond tmpBond;
1148  0 for (index = 0; index < mainchain.bonds.size(); index++)
1149    {
1150  0 tmpBond = mainchain.bonds.elementAt(index);
1151  0 if (tmpBond.at1.atomIndex == atomIndex)
1152    {
1153  0 if (highlightBond1 != null)
1154    {
1155  0 highlightBond1.at2.isSelected = false;
1156    }
1157   
1158  0 if (highlightBond2 != null)
1159    {
1160  0 highlightBond2.at1.isSelected = false;
1161    }
1162   
1163  0 highlightBond1 = null;
1164  0 highlightBond2 = null;
1165   
1166  0 if (index > 0)
1167    {
1168  0 highlightBond1 = mainchain.bonds.elementAt(index - 1);
1169  0 highlightBond1.at2.isSelected = true;
1170    }
1171   
1172  0 if (index != mainchain.bonds.size())
1173    {
1174  0 highlightBond2 = mainchain.bonds.elementAt(index);
1175  0 highlightBond2.at1.isSelected = true;
1176    }
1177   
1178  0 break;
1179    }
1180    }
1181    }
1182   
 
1183  0 toggle public Color getColour(int atomIndex, int pdbResNum, String chain,
1184    String pdbfile)
1185    {
1186  0 return Color.white;
1187    // if (!pdbfile.equals(pdbentry.getFile()))
1188    // return null;
1189   
1190    // return new Color(viewer.getAtomArgb(atomIndex));
1191    }
1192   
 
1193  0 toggle @Override
1194    public void updateColours(Object source)
1195    {
1196  0 colourBySequence();
1197  0 redrawneeded = true;
1198  0 repaint();
1199    }
1200   
 
1201  0 toggle @Override
1202    public void releaseReferences(Object svl)
1203    {
1204    // TODO Auto-generated method stub
1205   
1206    }
1207   
 
1208  0 toggle @Override
1209    public boolean isListeningFor(SequenceI seq)
1210    {
1211  0 if (sequence != null)
1212    {
1213  0 for (SequenceI s : sequence)
1214    {
1215  0 if (s == seq)
1216    {
1217  0 return true;
1218    }
1219    }
1220    }
1221  0 return false;
1222    }
1223    }