Jalview colour schemes added
[jalview.git] / src / jalview / appletgui / AppletJmol.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 \r
20 package jalview.appletgui;\r
21 \r
22 import java.util.*;\r
23 import java.awt.*;\r
24 import java.awt.event.*;\r
25 \r
26 import jalview.datamodel.*;\r
27 import jalview.structure.*;\r
28 import jalview.io.*;\r
29 \r
30 import org.jmol.api.*;\r
31 import org.jmol.adapter.smarter.SmarterJmolAdapter;\r
32 import org.jmol.popup.*;\r
33 import jalview.schemes.*;\r
34 \r
35 \r
36 public class AppletJmol extends Frame\r
37     implements  StructureListener, JmolStatusListener,\r
38     KeyListener, ActionListener, ItemListener\r
39 \r
40 {\r
41   Menu fileMenu = new Menu("File");\r
42   Menu viewMenu = new Menu("View");\r
43   Menu coloursMenu = new Menu("Colours");\r
44   Menu chainMenu = new Menu("Show Chain");\r
45   Menu helpMenu = new Menu("Help");\r
46   MenuItem mappingMenuItem = new MenuItem("View Mapping");\r
47 \r
48   CheckboxMenuItem seqColour = new CheckboxMenuItem("By Sequence", true);\r
49   MenuItem chain = new MenuItem("By Chain");\r
50   MenuItem charge = new MenuItem("Charge & Cysteine");\r
51   MenuItem zappo = new MenuItem("Zappo");\r
52   MenuItem taylor = new MenuItem("Taylor");\r
53   MenuItem hydro = new MenuItem("Hydrophobicity");\r
54   MenuItem helix = new MenuItem("Helix Propensity");\r
55   MenuItem strand = new MenuItem("Strand Propensity");\r
56   MenuItem turn = new MenuItem("Turn Propensity");\r
57   MenuItem buried = new MenuItem("Buried Index");\r
58   MenuItem user = new MenuItem("User Defined Colours");\r
59 \r
60   MenuItem jmolHelp = new MenuItem("Jmol Help");\r
61 \r
62   JmolViewer viewer;\r
63   JmolPopup jmolpopup;\r
64 \r
65   Panel scriptWindow;\r
66   TextField inputLine;\r
67   TextArea history;\r
68   SequenceI[] sequence;\r
69   StructureSelectionManager ssm;\r
70   RenderPanel renderPanel;\r
71   AlignmentPanel ap;\r
72   String fileLoadingError;\r
73   boolean loadedInline;\r
74   PDBEntry pdbentry;\r
75   boolean colourBySequence = true;\r
76   Vector atomsPicked = new Vector();\r
77 \r
78   public AppletJmol(PDBEntry pdbentry,\r
79                     SequenceI[] seq,\r
80                     AlignmentPanel ap,\r
81                     String protocol)\r
82   {\r
83     this.ap = ap;\r
84     this.sequence = seq;\r
85     this.pdbentry = pdbentry;\r
86 \r
87    String alreadyMapped = StructureSelectionManager\r
88         .getStructureSelectionManager()\r
89         .alreadyMappedToFile(pdbentry.getId());\r
90 \r
91     if (alreadyMapped != null)\r
92     {\r
93        StructureSelectionManager.getStructureSelectionManager()\r
94             .setMapping(seq, pdbentry.getFile(), protocol);\r
95         return;\r
96     }\r
97 \r
98     renderPanel = new RenderPanel();\r
99 \r
100     this.add(renderPanel, BorderLayout.CENTER);\r
101 \r
102     viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter());\r
103 \r
104     viewer.setAppletContext("jalview",\r
105                        ap.av.applet.getDocumentBase(),\r
106                             ap.av.applet.getCodeBase(),\r
107                             null);\r
108 \r
109     viewer.setJmolStatusListener(this);\r
110 \r
111     jmolpopup = JmolPopup.newJmolPopup(viewer);\r
112 \r
113     this.addWindowListener(new WindowAdapter()\r
114         {\r
115           public void windowClosing(WindowEvent evt)\r
116           {\r
117             closeViewer();\r
118           }\r
119         });\r
120 \r
121     MenuBar menuBar = new MenuBar();\r
122     menuBar.add(fileMenu);\r
123     fileMenu.add(mappingMenuItem);\r
124     menuBar.add(viewMenu);\r
125     mappingMenuItem.addActionListener(this);\r
126     viewMenu.add(chainMenu);\r
127     menuBar.add(coloursMenu);\r
128     menuBar.add(helpMenu);\r
129 \r
130     charge.addActionListener(this);\r
131     hydro.addActionListener(this);\r
132     chain.addActionListener(this);\r
133     seqColour.addItemListener(this);\r
134     zappo.addActionListener(this);\r
135     taylor.addActionListener(this);\r
136     helix.addActionListener(this);\r
137     strand.addActionListener(this);\r
138     turn.addActionListener(this);\r
139     buried.addActionListener(this);\r
140     user.addActionListener(this);\r
141 \r
142     jmolHelp.addActionListener(this);\r
143 \r
144     coloursMenu.add(seqColour);\r
145     coloursMenu.add(chain);\r
146     coloursMenu.add(charge);\r
147     coloursMenu.add(zappo);\r
148     coloursMenu.add(taylor);\r
149     coloursMenu.add(hydro);\r
150     coloursMenu.add(helix);\r
151     coloursMenu.add(strand);\r
152     coloursMenu.add(turn);\r
153     coloursMenu.add(buried);\r
154     coloursMenu.add(user);\r
155 \r
156     helpMenu.add(jmolHelp);\r
157 \r
158     this.setMenuBar(menuBar);\r
159 \r
160     if(pdbentry.getFile()!=null)\r
161     {\r
162       if (protocol.equals(AppletFormatAdapter.PASTE))\r
163         loadInline(pdbentry.getFile());\r
164       else\r
165           viewer.openFile(pdbentry.getFile());\r
166     }\r
167 \r
168     this.setBounds(400, 400, 400, 400);\r
169 \r
170     this.setVisible(true);\r
171   }\r
172 \r
173   public void loadInline(String string)\r
174   {\r
175     loadedInline = true;\r
176     viewer.openStringInline(string);\r
177   }\r
178 \r
179 \r
180   void setChainMenuItems(Vector chains)\r
181   {\r
182     chainMenu.removeAll();\r
183 \r
184     MenuItem menuItem = new MenuItem("All");\r
185     menuItem.addActionListener(this);\r
186 \r
187     chainMenu.add(menuItem);\r
188 \r
189     CheckboxMenuItem menuItemCB;\r
190     for (int c = 0; c < chains.size(); c++)\r
191     {\r
192       menuItemCB = new CheckboxMenuItem(chains.elementAt(c).toString(), true);\r
193       menuItemCB.addItemListener(this);\r
194       chainMenu.add(menuItemCB);\r
195     }\r
196   }\r
197 \r
198   boolean allChainsSelected = false;\r
199   void centerViewer()\r
200   {\r
201     StringBuffer cmd = new StringBuffer();\r
202     for (int i = 0; i < chainMenu.getItemCount(); i++)\r
203     {\r
204       if (chainMenu.getItem(i) instanceof CheckboxMenuItem)\r
205       {\r
206         CheckboxMenuItem item = (CheckboxMenuItem) chainMenu.getItem(i);\r
207         if (item.getState())\r
208           cmd.append(":" + item.getLabel() + " or ");\r
209       }\r
210     }\r
211 \r
212     if (cmd.length() > 0)\r
213       cmd.setLength(cmd.length() - 4);\r
214 \r
215     viewer.evalString("select *;restrict "\r
216                       + cmd + ";cartoon;center " + cmd);\r
217   }\r
218 \r
219 \r
220   void closeViewer()\r
221   {\r
222     viewer.setModeMouse(org.jmol.viewer.JmolConstants.MOUSE_NONE);\r
223     viewer.evalStringQuiet("zap");\r
224     viewer.setJmolStatusListener(null);\r
225     viewer = null;\r
226 \r
227     //We'll need to find out what other\r
228     // listeners need to be shut down in Jmol\r
229     StructureSelectionManager\r
230         .getStructureSelectionManager()\r
231         .removeStructureViewerListener(this, pdbentry.getId());\r
232 \r
233     this.setVisible(false);\r
234   }\r
235 \r
236   public void actionPerformed(ActionEvent evt)\r
237   {\r
238     if(evt.getSource()==mappingMenuItem)\r
239     {\r
240       jalview.appletgui.CutAndPasteTransfer cap\r
241           = new jalview.appletgui.CutAndPasteTransfer(false, null);\r
242       Frame frame = new Frame();\r
243       frame.add(cap);\r
244 \r
245       jalview.bin.JalviewLite.addFrame(frame, "PDB - Sequence Mapping", 550,\r
246                                        600);\r
247       cap.setText(\r
248           StructureSelectionManager.getStructureSelectionManager().printMapping(\r
249               pdbentry.getFile())\r
250           );\r
251     }\r
252     else if (evt.getSource() == charge)\r
253     {\r
254       colourBySequence = false;\r
255       seqColour.setState(false);\r
256       viewer.evalStringQuiet("select *;color white;select ASP,GLU;color red;"\r
257                       +"select LYS,ARG;color blue;select CYS;color yellow");\r
258     }\r
259 \r
260     else if (evt.getSource() == chain)\r
261     {\r
262       colourBySequence = false;\r
263       seqColour.setState(false);\r
264       viewer.evalStringQuiet("select *;color chain");\r
265     }\r
266     else if (evt.getSource() == zappo)\r
267     {\r
268       setJalviewColourScheme(new ZappoColourScheme());\r
269     }\r
270     else if (evt.getSource() == taylor)\r
271     {\r
272      setJalviewColourScheme(new TaylorColourScheme());\r
273     }\r
274     else if (evt.getSource() == hydro)\r
275     {\r
276       setJalviewColourScheme(new HydrophobicColourScheme());\r
277     }\r
278     else if (evt.getSource() == helix)\r
279     {\r
280       setJalviewColourScheme(new HelixColourScheme());\r
281     }\r
282     else if (evt.getSource() == strand)\r
283     {\r
284       setJalviewColourScheme(new StrandColourScheme());\r
285     }\r
286     else if (evt.getSource() == turn)\r
287     {\r
288       setJalviewColourScheme(new TurnColourScheme());\r
289     }\r
290     else if (evt.getSource() == buried)\r
291     {\r
292       setJalviewColourScheme(new BuriedColourScheme());\r
293     }\r
294     else if (evt.getSource() == user)\r
295     {\r
296       new UserDefinedColours(this);\r
297     }\r
298     else if(evt.getSource() == jmolHelp)\r
299     {\r
300       try{\r
301         ap.av.applet.getAppletContext().showDocument(\r
302             new java.net.URL("http://jmol.sourceforge.net/docs/JmolUserGuide/"),\r
303             "jmolHelp");\r
304       }catch(java.net.MalformedURLException ex){}\r
305     }\r
306     else\r
307     {\r
308       allChainsSelected = true;\r
309       for (int i = 0; i < chainMenu.getItemCount(); i++)\r
310       {\r
311         if (chainMenu.getItem(i) instanceof CheckboxMenuItem)\r
312           ( (CheckboxMenuItem) chainMenu.getItem(i)).setState(true);\r
313       }\r
314       centerViewer();\r
315       allChainsSelected = false;\r
316     }\r
317   }\r
318 \r
319   public void setJalviewColourScheme(ColourSchemeI cs)\r
320   {\r
321     colourBySequence = false;\r
322     seqColour.setState(false);\r
323 \r
324     if(cs==null)\r
325       return;\r
326 \r
327     String res;\r
328     int index;\r
329     Color col;\r
330 \r
331     Enumeration en = ResidueProperties.aa3Hash.keys();\r
332     StringBuffer command = new StringBuffer("select *;color white;");\r
333     while(en.hasMoreElements())\r
334     {\r
335       res = en.nextElement().toString();\r
336       index = ((Integer) ResidueProperties.aa3Hash.get(res)).intValue();\r
337       if(index>20)\r
338         continue;\r
339 \r
340       col = cs.findColour(ResidueProperties.aa[index].charAt(0));\r
341 \r
342       command.append("select "+res+";color["\r
343                         + col.getRed() + ","\r
344                         + col.getGreen() + ","\r
345                         + col.getBlue() + "];");\r
346     }\r
347 \r
348     viewer.evalStringQuiet(command.toString());\r
349   }\r
350 \r
351   public void itemStateChanged(ItemEvent evt)\r
352   {\r
353     if (evt.getSource() == seqColour)\r
354     {\r
355       colourBySequence = seqColour.getState();\r
356       colourBySequence(ap);\r
357     }\r
358     else if (!allChainsSelected)\r
359       centerViewer();\r
360   }\r
361 \r
362   public void keyPressed(KeyEvent evt)\r
363   {\r
364     if (evt.getKeyCode() == KeyEvent.VK_ENTER\r
365         && scriptWindow.isVisible())\r
366     {\r
367       viewer.evalString(inputLine.getText());\r
368       history.append("\n$ "+inputLine.getText());\r
369       inputLine.setText("");\r
370     }\r
371 \r
372   }\r
373 \r
374   public void keyTyped(KeyEvent evt)\r
375   {  }\r
376 \r
377   public void keyReleased(KeyEvent evt){}\r
378 \r
379   //////////////////////////////////\r
380   ///StructureListener\r
381   public String getPdbFile()\r
382   {\r
383     return "???";\r
384   }\r
385 \r
386 \r
387 \r
388   String lastMessage;\r
389   public void mouseOverStructure(int atomIndex, String strInfo)\r
390   {\r
391       int pdbResNum;\r
392 \r
393       int chainSeparator = strInfo.indexOf(":");\r
394 \r
395       if(chainSeparator==-1)\r
396         chainSeparator = strInfo.indexOf(".");\r
397 \r
398       pdbResNum = Integer.parseInt(\r
399           strInfo.substring(strInfo.indexOf("]")+ 1, chainSeparator));\r
400 \r
401       String chainId;\r
402 \r
403       if (strInfo.indexOf(":") > -1)\r
404         chainId = strInfo.substring\r
405             (strInfo.indexOf(":")+1, strInfo.indexOf("."));\r
406       else\r
407       {\r
408         chainId = " ";\r
409       }\r
410 \r
411       if (lastMessage == null || !lastMessage.equals(strInfo))\r
412         ssm.mouseOverStructure(pdbResNum, chainId, pdbentry.getFile());\r
413 \r
414       lastMessage = strInfo;\r
415   }\r
416 \r
417   StringBuffer resetLastRes = new StringBuffer();\r
418   StringBuffer eval = new StringBuffer();\r
419 \r
420   public void highlightAtom(int atomIndex, int pdbResNum, String chain, String pdbfile)\r
421   {\r
422     if (!pdbfile.equals(pdbentry.getFile()))\r
423       return;\r
424 \r
425     if (resetLastRes.length() > 0)\r
426     {\r
427       viewer.evalStringQuiet(resetLastRes.toString());\r
428     }\r
429 \r
430     eval.setLength(0);\r
431     eval.append("select " + pdbResNum);\r
432 \r
433     resetLastRes.setLength(0);\r
434     resetLastRes.append("select " + pdbResNum);\r
435 \r
436     if (!chain.equals(" "))\r
437     {\r
438       eval.append(":" + chain);\r
439       resetLastRes.append(":" + chain);\r
440     }\r
441 \r
442     eval.append(";color gold;wireframe 100");\r
443 \r
444     Color col = new Color(viewer.getAtomArgb(atomIndex));\r
445 \r
446     resetLastRes.append(";color["\r
447                         + col.getRed() + ","\r
448                         + col.getGreen() + ","\r
449                         + col.getBlue() + "];wireframe 0");\r
450 \r
451     viewer.evalStringQuiet(eval.toString());\r
452 \r
453   }\r
454 \r
455   public void updateColours(Object source)\r
456   {\r
457     colourBySequence( (AlignmentPanel) source);\r
458   }\r
459 \r
460 //End StructureListener\r
461 ////////////////////////////\r
462 \r
463   FeatureRenderer fr;\r
464   public void colourBySequence(AlignmentPanel ap)\r
465   {\r
466     if(!colourBySequence)\r
467       return;\r
468 \r
469 \r
470     StructureMapping[] mapping = ssm.getMapping(pdbentry.getFile());\r
471 \r
472     if (mapping.length < 1)\r
473       return;\r
474 \r
475     SequenceRenderer sr = ap.seqPanel.seqCanvas.getSequenceRenderer();\r
476 \r
477     boolean showFeatures = false;\r
478     if (ap.av.showSequenceFeatures)\r
479     {\r
480       showFeatures = true;\r
481       if (fr == null)\r
482       {\r
483         fr = new jalview.appletgui.FeatureRenderer(ap.av);\r
484       }\r
485 \r
486       fr.transferSettings(ap.seqPanel.seqCanvas.getFeatureRenderer());\r
487     }\r
488 \r
489     StringBuffer command = new StringBuffer();\r
490 \r
491     int lastPos = -1;\r
492     for (int s = 0; s < sequence.length; s++)\r
493     {\r
494       for (int m = 0; m < mapping.length; m++)\r
495       {\r
496         if (mapping[m].getSequence() == sequence[s])\r
497         {\r
498           for (int r = 0; r < sequence[s].getLength(); r++)\r
499           {\r
500             int pos = mapping[m].getPDBResNum(\r
501                 sequence[s].findPosition(r));\r
502 \r
503             if (pos < 1 || pos==lastPos)\r
504               continue;\r
505 \r
506             lastPos = pos;\r
507 \r
508             Color col = sr.getResidueBoxColour(sequence[s], r);\r
509 \r
510             if (showFeatures)\r
511               col = fr.findFeatureColour(col, sequence[s], r);\r
512 \r
513             if (command.toString().endsWith(":" + mapping[m].getChain()+\r
514                                             ";color["\r
515                                             + col.getRed() + ","\r
516                                             + col.getGreen() + ","\r
517                                             + col.getBlue() + "]"))\r
518             {\r
519               command = condenseCommand(command.toString(), pos);\r
520               continue;\r
521             }\r
522 \r
523             command.append(";select " + pos);\r
524 \r
525             if (!mapping[m].getChain().equals(" "))\r
526             {\r
527               command.append(":" + mapping[m].getChain());\r
528             }\r
529 \r
530             command.append(";color["\r
531                              + col.getRed() + ","\r
532                              + col.getGreen() + ","\r
533                              + col.getBlue() + "]");\r
534 \r
535           }\r
536           break;\r
537         }\r
538       }\r
539     }\r
540 \r
541     viewer.evalStringQuiet(command.toString());\r
542   }\r
543 \r
544   StringBuffer condenseCommand(String command, int pos)\r
545   {\r
546 \r
547     StringBuffer sb = new StringBuffer(command.substring(0, command.lastIndexOf("select")+7));\r
548 \r
549     command = command.substring(sb.length());\r
550 \r
551     String start;\r
552 \r
553     if (command.indexOf("-") > -1)\r
554     {\r
555       start = command.substring(0,command.indexOf("-"));\r
556     }\r
557     else\r
558     {\r
559       start = command.substring(0, command.indexOf(":"));\r
560     }\r
561 \r
562     sb.append(start+"-"+pos+command.substring(command.indexOf(":")));\r
563 \r
564     return sb;\r
565   }\r
566 \r
567   /////////////////////////////////\r
568   //JmolStatusListener\r
569 \r
570   public String eval(String strEval)\r
571   {\r
572    // System.out.println(strEval);\r
573    //"# 'eval' is implemented only for the applet.";\r
574     return null;\r
575   }\r
576 \r
577   public void createImage(String file, String type, int quality)\r
578   {}\r
579 \r
580   public void setCallbackFunction(String callbackType,\r
581                                   String callbackFunction)\r
582   {}\r
583 \r
584   public void notifyFileLoaded(String fullPathName, String fileName,\r
585                                String modelName, Object clientFile,\r
586                                String errorMsg)\r
587   {\r
588     if(errorMsg!=null)\r
589     {\r
590       fileLoadingError = errorMsg;\r
591       repaint();\r
592       return;\r
593     }\r
594 \r
595     fileLoadingError = null;\r
596 \r
597     if (fileName != null)\r
598     {\r
599       //FILE LOADED OK\r
600       jmolpopup.updateComputedMenus();\r
601             viewer.evalStringQuiet(\r
602           "select backbone;restrict;cartoon;wireframe off;spacefill off");\r
603 \r
604       ssm = StructureSelectionManager.getStructureSelectionManager();\r
605 \r
606       MCview.PDBfile pdb;\r
607       if (loadedInline)\r
608       {\r
609         pdb = ssm.setMapping(sequence,\r
610                                 pdbentry.getFile(),\r
611                                 AppletFormatAdapter.PASTE);\r
612         pdbentry.setFile("INLINE"+pdb.id);\r
613       }\r
614       else\r
615       {\r
616          pdb = ssm.setMapping(sequence,\r
617                               pdbentry.getFile(),\r
618                               AppletFormatAdapter.URL);\r
619       }\r
620 \r
621       pdbentry.setId(pdb.id);\r
622 \r
623       ssm.addStructureViewerListener(this);\r
624 \r
625       Vector chains = new Vector();\r
626       for (int i = 0; i < pdb.chains.size(); i++)\r
627       {\r
628         chains.addElement( ( (MCview.PDBChain) pdb.chains.elementAt(i)).id);\r
629       }\r
630       setChainMenuItems(chains);\r
631 \r
632       colourBySequence(ap);\r
633 \r
634       StringBuffer title = new StringBuffer(sequence[0].getName() + ":" +\r
635                                             pdbentry.getId());\r
636 \r
637       if (pdbentry.getProperty() != null)\r
638       {\r
639         if (pdbentry.getProperty().get("method") != null)\r
640         {\r
641           title.append(" Method: ");\r
642           title.append(pdbentry.getProperty().get("method"));\r
643         }\r
644         if (pdbentry.getProperty().get("chains") != null)\r
645         {\r
646           title.append(" Chain:");\r
647           title.append(pdbentry.getProperty().get("chains"));\r
648         }\r
649       }\r
650 \r
651       this.setTitle(title.toString());\r
652 \r
653     }\r
654     else\r
655       return;\r
656   }\r
657 \r
658   public void notifyFrameChanged(int frameNo)\r
659   {\r
660     boolean isAnimationRunning = (frameNo <= -2);\r
661   }\r
662 \r
663   public void notifyScriptStart(String statusMessage, String additionalInfo)\r
664   {}\r
665 \r
666   public void sendConsoleEcho(String strEcho)\r
667   {\r
668     if (scriptWindow == null)\r
669       showConsole(true);\r
670 \r
671     history.append("\n"+strEcho);\r
672   }\r
673 \r
674   public void sendConsoleMessage(String strStatus)\r
675   {\r
676     if(history!=null && strStatus!=null\r
677        && !strStatus.equals("Script completed"))\r
678     {\r
679       history.append("\n"+strStatus);\r
680     }\r
681   }\r
682 \r
683   public void notifyScriptTermination(String strStatus, int msWalltime)\r
684   {  }\r
685 \r
686   public void handlePopupMenu(int x, int y)\r
687   {\r
688     jmolpopup.show(x, y);\r
689   }\r
690 \r
691   public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)\r
692   {\r
693     notifyAtomPicked(iatom, strMeasure);\r
694   }\r
695 \r
696   public void notifyNewDefaultModeMeasurement(int count, String strInfo)\r
697   {}\r
698 \r
699   public void notifyAtomPicked(int atomIndex, String strInfo)\r
700   {\r
701 \r
702     int chainSeparator = strInfo.indexOf(":");\r
703 \r
704     if(chainSeparator==-1)\r
705       chainSeparator = strInfo.indexOf(".");\r
706 \r
707     String picked =\r
708         strInfo.substring(strInfo.indexOf("]")+ 1, chainSeparator);\r
709 \r
710 \r
711     if (strInfo.indexOf(":") > -1)\r
712       picked+=strInfo.substring(strInfo.indexOf(":")+1,\r
713                                strInfo.indexOf("."));\r
714 \r
715     picked+=".C";\r
716 \r
717     if (!atomsPicked.contains(picked))\r
718     {\r
719       viewer.evalString("select "+picked+";label %n %r:%c");\r
720       atomsPicked.addElement(picked);\r
721     }\r
722     else\r
723     {\r
724       viewer.evalString("select "+picked+";label off");\r
725       atomsPicked.removeElement(picked);\r
726     }\r
727   }\r
728 \r
729   public void notifyAtomHovered(int atomIndex, String strInfo)\r
730   {\r
731     mouseOverStructure(atomIndex, strInfo);\r
732   }\r
733 \r
734   public void sendSyncScript(String script, String appletName)\r
735   {}\r
736 \r
737   public void showUrl(String url)\r
738   {\r
739     try{\r
740       ap.av.applet.getAppletContext().showDocument(new java.net.URL(url),\r
741           "jmolOutput");\r
742     }catch(java.net.MalformedURLException ex)\r
743     {}\r
744   }\r
745 \r
746   public void showConsole(boolean showConsole)\r
747   {\r
748     if (scriptWindow == null)\r
749     {\r
750       scriptWindow = new Panel(new BorderLayout());\r
751       inputLine = new TextField();\r
752       history = new TextArea(5, 40);\r
753       scriptWindow.add(history, BorderLayout.CENTER);\r
754       scriptWindow.add(inputLine, BorderLayout.SOUTH);\r
755       add(scriptWindow, BorderLayout.SOUTH);\r
756       scriptWindow.setVisible(false);\r
757       history.setEditable(false);\r
758       inputLine.addKeyListener(this);\r
759     }\r
760 \r
761     scriptWindow.setVisible(!scriptWindow.isVisible());\r
762     validate();\r
763   }\r
764 \r
765   public float functionXY(String functionName, int x, int y)\r
766   {\r
767     return 0;\r
768   }\r
769 \r
770   ///End JmolStatusListener\r
771   ///////////////////////////////\r
772 \r
773 \r
774   class RenderPanel\r
775       extends Panel\r
776   {\r
777     Dimension currentSize = new Dimension();\r
778     Rectangle rectClip = new Rectangle();\r
779 \r
780     public void update(Graphics g) {\r
781       paint(g);\r
782     }\r
783     public void paint(Graphics g)\r
784     {\r
785       currentSize = this.getSize();\r
786       rectClip = g.getClipBounds();\r
787 \r
788       if (viewer == null)\r
789       {\r
790         g.setColor(Color.black);\r
791         g.fillRect(0, 0, currentSize.width, currentSize.height);\r
792         g.setColor(Color.white);\r
793         g.setFont(new Font("Verdana", Font.BOLD, 14));\r
794         g.drawString("Retrieving PDB data....", 20, currentSize.height / 2);\r
795       }\r
796       else\r
797       {\r
798         viewer.renderScreenImage(g, currentSize, rectClip);\r
799       }\r
800     }\r
801   }\r
802 \r
803 }\r