575c6eca3736dc92cd52348dc43b5cc3ff65a6ee
[jalview.git] / src / jalview / gui / AppJMol.java
1 /*\r
2  * Jalview - A Sequence Alignment Editor and Viewer\r
3  * Copyright (C) 2007 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 jalview.gui;\r
20 \r
21 import java.util.regex.*;\r
22 import java.util.*;\r
23 import java.awt.*;\r
24 import javax.swing.*;\r
25 import javax.swing.event.*;\r
26 import java.awt.event.*;\r
27 import java.io.*;\r
28 \r
29 import jalview.jbgui.GStructureViewer;\r
30 import jalview.datamodel.*;\r
31 import jalview.gui.*;\r
32 import jalview.structure.*;\r
33 import jalview.datamodel.PDBEntry;\r
34 import jalview.io.*;\r
35 import jalview.schemes.*;\r
36 \r
37 import org.jmol.api.*;\r
38 import org.jmol.adapter.smarter.SmarterJmolAdapter;\r
39 import org.jmol.popup.*;\r
40 \r
41 \r
42 public class AppJMol\r
43     extends GStructureViewer\r
44     implements StructureListener, JmolStatusListener, Runnable\r
45 \r
46 {\r
47   JmolViewer viewer;\r
48   JmolPopup jmolpopup;\r
49   ScriptWindow scriptWindow;\r
50   PDBEntry pdbentry;\r
51   SequenceI[] sequence;\r
52   StructureSelectionManager ssm;\r
53   JSplitPane splitPane;\r
54   RenderPanel renderPanel;\r
55   AlignmentPanel ap;\r
56   String fileLoadingError;\r
57   boolean colourBySequence = true;\r
58 \r
59   public AppJMol(String file, String id,\r
60                  SequenceI[] seq,\r
61                  AlignmentPanel ap,\r
62                  String loadStatus,\r
63                  Rectangle bounds)\r
64   {\r
65     pdbentry = new PDBEntry();\r
66     pdbentry.setFile(file);\r
67     pdbentry.setId(id);\r
68     this.sequence = seq;\r
69     this.ap = ap;\r
70     this.setBounds(bounds);\r
71 \r
72     colourBySequence = false;\r
73     seqColour.setSelected(false);\r
74 \r
75     jalview.gui.Desktop.addInternalFrame(this, "Loading File",\r
76                                          bounds.width,bounds.height);\r
77 \r
78     initJmol(loadStatus);\r
79 \r
80     this.addInternalFrameListener(new InternalFrameAdapter()\r
81     {\r
82       public void internalFrameClosing(InternalFrameEvent internalFrameEvent)\r
83       {\r
84         closeViewer();\r
85       }\r
86     });\r
87   }\r
88 \r
89   public AppJMol(PDBEntry pdbentry, SequenceI[] seq, AlignmentPanel ap)\r
90   {\r
91     //////////////////////////////////\r
92     //Is the pdb file already loaded?\r
93     String alreadyMapped = StructureSelectionManager\r
94         .getStructureSelectionManager()\r
95         .alreadyMappedToFile(pdbentry.getId());\r
96 \r
97     if (alreadyMapped != null)\r
98     {\r
99       int option = JOptionPane.showInternalConfirmDialog(Desktop.desktop,\r
100           pdbentry.getId() + " is already displayed."\r
101           + "\nDo you want to map sequences to the visible structure?",\r
102           "Map Sequences to Visible Window: " + pdbentry.getId(),\r
103           JOptionPane.YES_NO_OPTION);\r
104 \r
105       if (option == JOptionPane.YES_OPTION)\r
106       {\r
107         StructureSelectionManager.getStructureSelectionManager()\r
108             .setMapping(seq, alreadyMapped, AppletFormatAdapter.FILE);\r
109         return;\r
110       }\r
111     }\r
112     ///////////////////////////////////\r
113 \r
114     this.ap = ap;\r
115     this.pdbentry = pdbentry;\r
116     this.sequence = seq;\r
117 \r
118     jalview.gui.Desktop.addInternalFrame(this, "Loading File", 400, 400);\r
119 \r
120     if (pdbentry.getFile() != null)\r
121     {\r
122       initJmol("load \""+pdbentry.getFile()+"\"");\r
123     }\r
124     else\r
125     {\r
126       Thread worker = new Thread(this);\r
127       worker.start();\r
128     }\r
129 \r
130     this.addInternalFrameListener(new InternalFrameAdapter()\r
131     {\r
132       public void internalFrameClosing(InternalFrameEvent internalFrameEvent)\r
133       {\r
134         closeViewer();\r
135       }\r
136     });\r
137   }\r
138 \r
139   void initJmol(String command)\r
140   {\r
141     renderPanel = new RenderPanel();\r
142 \r
143     this.getContentPane().add(renderPanel, java.awt.BorderLayout.CENTER);\r
144 \r
145     StringBuffer title = new StringBuffer(sequence[0].getName() + ":" +\r
146                                           pdbentry.getId());\r
147 \r
148     if (pdbentry.getProperty() != null)\r
149     {\r
150       if (pdbentry.getProperty().get("method") != null)\r
151       {\r
152         title.append(" Method: ");\r
153         title.append(pdbentry.getProperty().get("method"));\r
154       }\r
155       if (pdbentry.getProperty().get("chains") != null)\r
156       {\r
157         title.append(" Chain:");\r
158         title.append(pdbentry.getProperty().get("chains"));\r
159       }\r
160     }\r
161 \r
162     this.setTitle(title.toString());\r
163 \r
164     viewer = org.jmol.api.JmolViewer.allocateViewer(renderPanel,\r
165         new SmarterJmolAdapter());\r
166 \r
167 \r
168     viewer.setAppletContext("", null, null, "");\r
169 \r
170     viewer.setJmolStatusListener(this);\r
171 \r
172     jmolpopup = JmolPopup.newJmolPopup(viewer);\r
173 \r
174     viewer.evalStringQuiet(command);\r
175   }\r
176 \r
177 \r
178   void setChainMenuItems(Vector chains)\r
179   {\r
180     chainMenu.removeAll();\r
181 \r
182     JMenuItem menuItem = new JMenuItem("All");\r
183     menuItem.addActionListener(new ActionListener()\r
184         {\r
185           public void actionPerformed(ActionEvent evt)\r
186           {\r
187             allChainsSelected = true;\r
188             for(int i=0; i<chainMenu.getItemCount(); i++)\r
189             {\r
190               if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)\r
191                 ( (JCheckBoxMenuItem) chainMenu.getItem(i)).setSelected(true);\r
192             }\r
193             centerViewer();\r
194             allChainsSelected = false;\r
195           }\r
196         });\r
197 \r
198     chainMenu.add(menuItem);\r
199 \r
200     for (int c = 0; c < chains.size(); c++)\r
201     {\r
202       menuItem = new JCheckBoxMenuItem(chains.elementAt(c).toString(), true);\r
203       menuItem.addItemListener(new ItemListener()\r
204       {\r
205         public void itemStateChanged(ItemEvent evt)\r
206         {\r
207           if (!allChainsSelected)\r
208             centerViewer();\r
209         }\r
210       });\r
211 \r
212       chainMenu.add(menuItem);\r
213     }\r
214   }\r
215 \r
216   boolean allChainsSelected = false;\r
217   void centerViewer()\r
218   {\r
219     StringBuffer cmd = new StringBuffer();\r
220     for(int i=0; i<chainMenu.getItemCount(); i++)\r
221     {\r
222       if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)\r
223       {\r
224        JCheckBoxMenuItem item = (JCheckBoxMenuItem) chainMenu.getItem(i);\r
225        if(item.isSelected())\r
226          cmd.append(":"+item.getText()+" or ");\r
227       }\r
228     }\r
229 \r
230     if (cmd.length() > 0)\r
231       cmd.setLength(cmd.length() - 4);\r
232 \r
233     viewer.evalStringQuiet("select *;restrict "\r
234                       +cmd+";cartoon;center "+cmd);\r
235   }\r
236 \r
237   void closeViewer()\r
238   {\r
239     viewer.setModeMouse(org.jmol.viewer.JmolConstants.MOUSE_NONE);\r
240     viewer.evalStringQuiet("zap");\r
241     viewer.setJmolStatusListener(null);\r
242     viewer = null;\r
243 \r
244     //We'll need to find out what other\r
245     // listeners need to be shut down in Jmol\r
246     StructureSelectionManager\r
247         .getStructureSelectionManager()\r
248         .removeStructureViewerListener(this, pdbentry.getFile());\r
249   }\r
250 \r
251   public void run()\r
252   {\r
253     try\r
254     {\r
255       EBIFetchClient ebi = new EBIFetchClient();\r
256       String query = "pdb:" + pdbentry.getId();\r
257       pdbentry.setFile(ebi.fetchDataAsFile(query, "default", "raw")\r
258                        .getAbsolutePath());\r
259       initJmol("load "+pdbentry.getFile());\r
260     }\r
261     catch (Exception ex)\r
262     {\r
263       ex.printStackTrace();\r
264     }\r
265   }\r
266 \r
267   public void pdbFile_actionPerformed(ActionEvent actionEvent)\r
268   {\r
269     JalviewFileChooser chooser = new JalviewFileChooser(\r
270         jalview.bin.Cache.getProperty(\r
271             "LAST_DIRECTORY"));\r
272 \r
273     chooser.setFileView(new JalviewFileView());\r
274     chooser.setDialogTitle("Save PDB File");\r
275     chooser.setToolTipText("Save");\r
276 \r
277     int value = chooser.showSaveDialog(this);\r
278 \r
279     if (value == JalviewFileChooser.APPROVE_OPTION)\r
280     {\r
281       try\r
282       {\r
283         BufferedReader in = new BufferedReader(new FileReader(pdbentry.getFile()));\r
284         File outFile = chooser.getSelectedFile();\r
285 \r
286         PrintWriter out = new PrintWriter(new FileOutputStream(outFile));\r
287         String data;\r
288         while ( (data = in.readLine()) != null)\r
289         {\r
290           if (\r
291               ! (data.indexOf("<PRE>") > -1 || data.indexOf("</PRE>") > -1)\r
292               )\r
293           {\r
294             out.println(data);\r
295           }\r
296         }\r
297         out.close();\r
298       }\r
299       catch (Exception ex)\r
300       {\r
301         ex.printStackTrace();\r
302       }\r
303     }\r
304   }\r
305 \r
306   public void viewMapping_actionPerformed(ActionEvent actionEvent)\r
307   {\r
308     jalview.gui.CutAndPasteTransfer cap = new jalview.gui.CutAndPasteTransfer();\r
309     jalview.gui.Desktop.addInternalFrame(cap, "PDB - Sequence Mapping", 550,\r
310                                          600);\r
311     cap.setText(\r
312         StructureSelectionManager.getStructureSelectionManager().printMapping(\r
313             pdbentry.getFile())\r
314         );\r
315   }\r
316 \r
317   /**\r
318    * DOCUMENT ME!\r
319    *\r
320    * @param e DOCUMENT ME!\r
321    */\r
322   public void eps_actionPerformed(ActionEvent e)\r
323   {\r
324     makePDBImage(jalview.util.ImageMaker.EPS);\r
325   }\r
326 \r
327   /**\r
328    * DOCUMENT ME!\r
329    *\r
330    * @param e DOCUMENT ME!\r
331    */\r
332   public void png_actionPerformed(ActionEvent e)\r
333   {\r
334     makePDBImage(jalview.util.ImageMaker.PNG);\r
335   }\r
336 \r
337   void makePDBImage(int type)\r
338   {\r
339     int width = getWidth();\r
340     int height = getHeight();\r
341 \r
342     jalview.util.ImageMaker im;\r
343 \r
344     if (type == jalview.util.ImageMaker.PNG)\r
345     {\r
346       im = new jalview.util.ImageMaker(this,\r
347                                        jalview.util.ImageMaker.PNG,\r
348                                        "Make PNG image from view",\r
349                                        width, height,\r
350                                        null, null);\r
351     }\r
352     else\r
353     {\r
354       im = new jalview.util.ImageMaker(this,\r
355                                        jalview.util.ImageMaker.EPS,\r
356                                        "Make EPS file from view",\r
357                                        width, height,\r
358                                        null, this.getTitle());\r
359     }\r
360 \r
361     if (im.getGraphics() != null)\r
362     {\r
363       Rectangle rect = new Rectangle(width, height);\r
364       viewer.renderScreenImage(im.getGraphics(),\r
365                                rect.getSize(), rect);\r
366       im.writeImage();\r
367     }\r
368   }\r
369 \r
370 \r
371   public void seqColour_actionPerformed(ActionEvent actionEvent)\r
372   {\r
373     colourBySequence = seqColour.isSelected();\r
374     colourBySequence(ap);\r
375   }\r
376 \r
377   public void chainColour_actionPerformed(ActionEvent actionEvent)\r
378   {\r
379     colourBySequence = false;\r
380     seqColour.setSelected(false);\r
381     viewer.evalStringQuiet("select *;color chain");\r
382   }\r
383 \r
384   public void chargeColour_actionPerformed(ActionEvent actionEvent)\r
385   {\r
386     colourBySequence = false;\r
387     seqColour.setSelected(false);\r
388     viewer.evalStringQuiet("select *;color white;select ASP,GLU;color red;"\r
389                       +"select LYS,ARG;color blue;select CYS;color yellow");\r
390   }\r
391 \r
392   public void zappoColour_actionPerformed(ActionEvent actionEvent)\r
393   {\r
394     setJalviewColourScheme(new ZappoColourScheme());\r
395   }\r
396 \r
397   public void taylorColour_actionPerformed(ActionEvent actionEvent)\r
398   {\r
399     setJalviewColourScheme(new TaylorColourScheme());\r
400   }\r
401 \r
402   public void hydroColour_actionPerformed(ActionEvent actionEvent)\r
403   {\r
404     setJalviewColourScheme(new HydrophobicColourScheme());\r
405   }\r
406 \r
407   public void helixColour_actionPerformed(ActionEvent actionEvent)\r
408   {\r
409     setJalviewColourScheme(new HelixColourScheme());\r
410   }\r
411 \r
412   public void strandColour_actionPerformed(ActionEvent actionEvent)\r
413   {\r
414     setJalviewColourScheme(new StrandColourScheme());\r
415   }\r
416 \r
417   public void turnColour_actionPerformed(ActionEvent actionEvent)\r
418   {\r
419     setJalviewColourScheme(new TurnColourScheme());\r
420   }\r
421 \r
422   public void buriedColour_actionPerformed(ActionEvent actionEvent)\r
423   {\r
424     setJalviewColourScheme(new BuriedColourScheme());\r
425   }\r
426 \r
427   public void setJalviewColourScheme(ColourSchemeI cs)\r
428   {\r
429     colourBySequence = false;\r
430     seqColour.setSelected(false);\r
431 \r
432     if(cs==null)\r
433       return;\r
434 \r
435     String res;\r
436     int index;\r
437     Color col;\r
438 \r
439     Enumeration en = ResidueProperties.aa3Hash.keys();\r
440     StringBuffer command = new StringBuffer("select *;color white;");\r
441     while(en.hasMoreElements())\r
442     {\r
443       res = en.nextElement().toString();\r
444       index = ((Integer) ResidueProperties.aa3Hash.get(res)).intValue();\r
445       if(index>20)\r
446         continue;\r
447 \r
448       col = cs.findColour(ResidueProperties.aa[index].charAt(0));\r
449 \r
450       command.append("select "+res+";color["\r
451                         + col.getRed() + ","\r
452                         + col.getGreen() + ","\r
453                         + col.getBlue() + "];");\r
454     }\r
455 \r
456     viewer.evalStringQuiet(command.toString());\r
457   }\r
458 \r
459   public void userColour_actionPerformed(ActionEvent actionEvent)\r
460   {\r
461     new UserDefinedColours(this, null);\r
462   }\r
463 \r
464   public void backGround_actionPerformed(ActionEvent actionEvent)\r
465   {\r
466     java.awt.Color col = JColorChooser.showDialog(this,\r
467                                                   "Select Background Colour",\r
468                                                   null);\r
469 \r
470     if (col != null)\r
471     {\r
472       viewer.evalStringQuiet("background ["\r
473                         + col.getRed() + ","\r
474                         + col.getGreen() + ","\r
475                         + col.getBlue() + "];");\r
476     }\r
477   }\r
478 \r
479 \r
480   //////////////////////////////////\r
481   ///StructureListener\r
482   public String getPdbFile()\r
483   {\r
484     return pdbentry.getFile();\r
485   }\r
486 \r
487   Pattern pattern = Pattern.compile(\r
488       "\\[(.*)\\]([0-9]+)(:[a-zA-Z]*)?\\.([a-zA-Z]+)(/[0-9]*)?"\r
489       );\r
490 \r
491   String lastMessage;\r
492   public void mouseOverStructure(int atomIndex, String strInfo)\r
493   {\r
494     Matcher matcher = pattern.matcher(strInfo);\r
495     matcher.find();\r
496     matcher.group(1);\r
497     int pdbResNum = Integer.parseInt(matcher.group(2));\r
498     String chainId = matcher.group(3);\r
499 \r
500     if (chainId != null)\r
501       chainId = chainId.substring(1, chainId.length());\r
502     else\r
503     {\r
504       chainId = " ";\r
505     }\r
506 \r
507     if (lastMessage == null || !lastMessage.equals(strInfo))\r
508       ssm.mouseOverStructure(pdbResNum, chainId, pdbentry.getFile());\r
509 \r
510     lastMessage = strInfo;\r
511   }\r
512 \r
513   StringBuffer resetLastRes = new StringBuffer();\r
514   StringBuffer eval = new StringBuffer();\r
515 \r
516   public void highlightAtom(int atomIndex, int pdbResNum, String chain, String pdbfile)\r
517   {\r
518     if (!pdbfile.equals(pdbentry.getFile()))\r
519       return;\r
520 \r
521     if (resetLastRes.length() > 0)\r
522     {\r
523       viewer.evalStringQuiet(resetLastRes.toString());\r
524     }\r
525 \r
526     eval.setLength(0);\r
527     eval.append("select " + pdbResNum);\r
528 \r
529     resetLastRes.setLength(0);\r
530     resetLastRes.append("select " + pdbResNum);\r
531 \r
532     if (!chain.equals(" "))\r
533     {\r
534       eval.append(":" + chain);\r
535       resetLastRes.append(":" + chain);\r
536     }\r
537 \r
538     eval.append(";color gold;wireframe 100");\r
539 \r
540     Color col = new Color(viewer.getAtomArgb(atomIndex));\r
541 \r
542     resetLastRes.append(";color["\r
543                         + col.getRed() + ","\r
544                         + col.getGreen() + ","\r
545                         + col.getBlue() + "];wireframe 0");\r
546 \r
547     viewer.evalStringQuiet(eval.toString());\r
548 \r
549   }\r
550 \r
551   public void updateColours(Object source)\r
552   {\r
553     colourBySequence( (AlignmentPanel) source);\r
554   }\r
555 \r
556 //End StructureListener\r
557 ////////////////////////////\r
558 \r
559   FeatureRenderer fr;\r
560   public void colourBySequence(AlignmentPanel ap)\r
561   {\r
562     if(!colourBySequence)\r
563       return;\r
564 \r
565 \r
566     StructureMapping[] mapping = ssm.getMapping(pdbentry.getFile());\r
567 \r
568     if (mapping.length < 1)\r
569       return;\r
570 \r
571     SequenceRenderer sr = ap.seqPanel.seqCanvas.getSequenceRenderer();\r
572 \r
573     boolean showFeatures = false;\r
574     if (ap.av.showSequenceFeatures)\r
575     {\r
576       showFeatures = true;\r
577       if (fr == null)\r
578       {\r
579         fr = new jalview.gui.FeatureRenderer(ap.av);\r
580       }\r
581 \r
582       fr.transferSettings(ap.seqPanel.seqCanvas.getFeatureRenderer());\r
583     }\r
584 \r
585     StringBuffer command = new StringBuffer();\r
586 \r
587     int lastPos = -1;\r
588     for (int s = 0; s < sequence.length; s++)\r
589     {\r
590       for (int m = 0; m < mapping.length; m++)\r
591       {\r
592         if (mapping[m].getSequence() == sequence[s])\r
593         {\r
594           for (int r = 0; r < sequence[s].getLength(); r++)\r
595           {\r
596             int pos = mapping[m].getPDBResNum(\r
597                 sequence[s].findPosition(r));\r
598 \r
599             if (pos < 1 || pos==lastPos)\r
600               continue;\r
601 \r
602             lastPos = pos;\r
603 \r
604             Color col = sr.getResidueBoxColour(sequence[s], r);\r
605 \r
606             if (showFeatures)\r
607               col = fr.findFeatureColour(col, sequence[s], r);\r
608 \r
609             if (command.toString().endsWith(":" + mapping[m].getChain()+\r
610                                             ";color["\r
611                                             + col.getRed() + ","\r
612                                             + col.getGreen() + ","\r
613                                             + col.getBlue() + "]"))\r
614             {\r
615               command = condenseCommand(command, pos);\r
616               continue;\r
617             }\r
618 \r
619             command.append(";select " + pos);\r
620 \r
621             if (!mapping[m].getChain().equals(" "))\r
622             {\r
623               command.append(":" + mapping[m].getChain());\r
624             }\r
625 \r
626             command.append(";color["\r
627                              + col.getRed() + ","\r
628                              + col.getGreen() + ","\r
629                              + col.getBlue() + "]");\r
630 \r
631           }\r
632           break;\r
633         }\r
634       }\r
635     }\r
636 \r
637     viewer.evalStringQuiet(command.toString());\r
638   }\r
639 \r
640   StringBuffer condenseCommand(StringBuffer command, int pos)\r
641   {\r
642     StringBuffer sb = new StringBuffer(command.substring(0, command.lastIndexOf("select")+7));\r
643 \r
644     command.delete(0, sb.length());\r
645 \r
646     String start;\r
647 \r
648     if (command.indexOf("-") > -1)\r
649     {\r
650       start = command.substring(0,command.indexOf("-"));\r
651     }\r
652     else\r
653     {\r
654       start = command.substring(0, command.indexOf(":"));\r
655     }\r
656 \r
657     sb.append(start+"-"+pos+command.substring(command.indexOf(":")));\r
658 \r
659     return sb;\r
660   }\r
661 \r
662   /////////////////////////////////\r
663   //JmolStatusListener\r
664 \r
665   public String eval(String strEval)\r
666   {\r
667    // System.out.println(strEval);\r
668    //"# 'eval' is implemented only for the applet.";\r
669     return null;\r
670   }\r
671 \r
672   public void createImage(String file, String type, int quality)\r
673   {\r
674     System.out.println("JMOL CREATE IMAGE");\r
675   }\r
676 \r
677   public void setCallbackFunction(String callbackType,\r
678                                   String callbackFunction)\r
679   {}\r
680 \r
681   public void notifyFileLoaded(String fullPathName, String fileName,\r
682                                String modelName, Object clientFile,\r
683                                String errorMsg)\r
684   {\r
685     if(errorMsg!=null)\r
686     {\r
687       fileLoadingError = errorMsg;\r
688       repaint();\r
689       return;\r
690     }\r
691 \r
692     fileLoadingError = null;\r
693 \r
694     if (fileName != null)\r
695     {\r
696 \r
697       //FILE LOADED OK\r
698       ssm = StructureSelectionManager.getStructureSelectionManager();\r
699       MCview.PDBfile pdbFile = ssm.setMapping(sequence, pdbentry.getFile(), AppletFormatAdapter.FILE);\r
700       ssm.addStructureViewerListener(this);\r
701 \r
702       Vector chains = new Vector();\r
703       for(int i=0; i<pdbFile.chains.size(); i++)\r
704       {\r
705         chains.addElement(((MCview.PDBChain)pdbFile.chains.elementAt(i)).id);\r
706       }\r
707       setChainMenuItems(chains);\r
708 \r
709       jmolpopup.updateComputedMenus();\r
710       viewer.evalStringQuiet(\r
711           "select backbone;restrict;cartoon;wireframe off;spacefill off");\r
712 \r
713       colourBySequence(ap);\r
714     }\r
715     else\r
716       return;\r
717   }\r
718 \r
719   public void notifyFrameChanged(int frameNo)\r
720   {\r
721     boolean isAnimationRunning = (frameNo <= -2);\r
722   }\r
723 \r
724   public void notifyScriptStart(String statusMessage, String additionalInfo)\r
725   {}\r
726 \r
727   public void sendConsoleEcho(String strEcho)\r
728   {\r
729     if (scriptWindow != null)\r
730       scriptWindow.sendConsoleEcho(strEcho);\r
731   }\r
732 \r
733   public void sendConsoleMessage(String strStatus)\r
734   {\r
735     if (scriptWindow != null)\r
736       scriptWindow.sendConsoleMessage(strStatus);\r
737   }\r
738 \r
739   public void notifyScriptTermination(String strStatus, int msWalltime)\r
740   {\r
741     if (scriptWindow != null)\r
742       scriptWindow.notifyScriptTermination(strStatus, msWalltime);\r
743   }\r
744 \r
745   public void handlePopupMenu(int x, int y)\r
746   {\r
747     jmolpopup.show(x, y);\r
748   }\r
749 \r
750   public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)\r
751   {\r
752     notifyAtomPicked(iatom, strMeasure);\r
753   }\r
754 \r
755   public void notifyNewDefaultModeMeasurement(int count, String strInfo)\r
756   {}\r
757 \r
758   public void notifyAtomPicked(int atomIndex, String strInfo)\r
759   {\r
760     if (scriptWindow != null)\r
761     {\r
762       scriptWindow.sendConsoleMessage(strInfo);\r
763       scriptWindow.sendConsoleMessage("\n");\r
764     }\r
765   }\r
766 \r
767   public void notifyAtomHovered(int atomIndex, String strInfo)\r
768   {\r
769     mouseOverStructure(atomIndex, strInfo);\r
770   }\r
771 \r
772   public void sendSyncScript(String script, String appletName)\r
773   {}\r
774 \r
775   public void showUrl(String url)\r
776   {}\r
777 \r
778   public void showConsole(boolean showConsole)\r
779   {\r
780     if (scriptWindow == null)\r
781       scriptWindow = new ScriptWindow(this);\r
782 \r
783     if(showConsole)\r
784     {\r
785       if(splitPane==null)\r
786       {\r
787         splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);\r
788         splitPane.setTopComponent(renderPanel);\r
789         splitPane.setBottomComponent(scriptWindow);\r
790         this.getContentPane().add(splitPane, BorderLayout.CENTER);\r
791       }\r
792 \r
793       splitPane.setDividerLocation(getHeight()-200);\r
794       splitPane.validate();\r
795     }\r
796     else\r
797     {\r
798       if (splitPane != null)\r
799         splitPane.setVisible(false);\r
800 \r
801       splitPane = null;\r
802 \r
803       this.getContentPane().add(renderPanel, BorderLayout.CENTER);\r
804     }\r
805 \r
806     validate();\r
807   }\r
808 \r
809   public float functionXY(String functionName, int x, int y)\r
810   {\r
811     return 0;\r
812   }\r
813 \r
814   ///End JmolStatusListener\r
815   ///////////////////////////////\r
816 \r
817 \r
818   class RenderPanel\r
819       extends JPanel\r
820   {\r
821     final Dimension currentSize = new Dimension();\r
822     final Rectangle rectClip = new Rectangle();\r
823 \r
824     public void paintComponent(Graphics g)\r
825     {\r
826       getSize(currentSize);\r
827       g.getClipBounds(rectClip);\r
828 \r
829       if (viewer == null)\r
830       {\r
831         g.setColor(Color.black);\r
832         g.fillRect(0, 0, currentSize.width, currentSize.height);\r
833         g.setColor(Color.white);\r
834         g.setFont(new Font("Verdana", Font.BOLD, 14));\r
835         g.drawString("Retrieving PDB data....", 20, currentSize.height / 2);\r
836       }\r
837       else if(fileLoadingError!=null)\r
838       {\r
839         g.setColor(Color.black);\r
840         g.fillRect(0, 0, currentSize.width, currentSize.height);\r
841         g.setColor(Color.white);\r
842         g.setFont(new Font("Verdana", Font.BOLD, 14));\r
843         g.drawString("Error loading file..." + pdbentry.getId(), 20,\r
844                      currentSize.height / 2);\r
845       }\r
846       else\r
847       {\r
848         viewer.renderScreenImage(g, currentSize, rectClip);\r
849       }\r
850     }\r
851   }\r
852 \r
853 }\r