2 * Jalview - A Sequence Alignment Editor and Viewer
3 * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20 package jalview.appletgui;
24 import java.awt.event.*;
26 import jalview.datamodel.*;
27 import jalview.structure.*;
30 import org.jmol.api.*;
31 import org.jmol.adapter.smarter.SmarterJmolAdapter;
33 import org.jmol.popup.*;
34 import jalview.schemes.*;
37 public class AppletJmol extends EmbmenuFrame
38 implements StructureListener, JmolStatusListener,
39 KeyListener, ActionListener, ItemListener
42 Menu fileMenu = new Menu("File");
43 Menu viewMenu = new Menu("View");
44 Menu coloursMenu = new Menu("Colours");
45 Menu chainMenu = new Menu("Show Chain");
46 Menu helpMenu = new Menu("Help");
47 MenuItem mappingMenuItem = new MenuItem("View Mapping");
49 CheckboxMenuItem seqColour = new CheckboxMenuItem("By Sequence", true);
50 MenuItem chain = new MenuItem("By Chain");
51 MenuItem charge = new MenuItem("Charge & Cysteine");
52 MenuItem zappo = new MenuItem("Zappo");
53 MenuItem taylor = new MenuItem("Taylor");
54 MenuItem hydro = new MenuItem("Hydrophobicity");
55 MenuItem helix = new MenuItem("Helix Propensity");
56 MenuItem strand = new MenuItem("Strand Propensity");
57 MenuItem turn = new MenuItem("Turn Propensity");
58 MenuItem buried = new MenuItem("Buried Index");
59 MenuItem user = new MenuItem("User Defined Colours");
61 MenuItem jmolHelp = new MenuItem("Jmol Help");
71 StructureSelectionManager ssm;
72 RenderPanel renderPanel;
74 String fileLoadingError;
77 boolean colourBySequence = true;
78 Vector atomsPicked = new Vector();
80 public AppletJmol(PDBEntry pdbentry,
89 this.pdbentry = pdbentry;
91 String alreadyMapped = StructureSelectionManager
92 .getStructureSelectionManager()
93 .alreadyMappedToFile(pdbentry.getId());
95 if (alreadyMapped != null)
97 StructureSelectionManager.getStructureSelectionManager()
98 .setMapping(seq, chains, pdbentry.getFile(), protocol);
99 //PROMPT USER HERE TO ADD TO NEW OR EXISTING VIEW?
100 //FOR NOW, LETS JUST OPEN A NEW WINDOW
102 MenuBar menuBar = new MenuBar();
103 menuBar.add(fileMenu);
104 fileMenu.add(mappingMenuItem);
105 menuBar.add(viewMenu);
106 mappingMenuItem.addActionListener(this);
107 viewMenu.add(chainMenu);
108 menuBar.add(coloursMenu);
109 menuBar.add(helpMenu);
111 charge.addActionListener(this);
112 hydro.addActionListener(this);
113 chain.addActionListener(this);
114 seqColour.addItemListener(this);
115 zappo.addActionListener(this);
116 taylor.addActionListener(this);
117 helix.addActionListener(this);
118 strand.addActionListener(this);
119 turn.addActionListener(this);
120 buried.addActionListener(this);
121 user.addActionListener(this);
123 jmolHelp.addActionListener(this);
125 coloursMenu.add(seqColour);
126 coloursMenu.add(chain);
127 coloursMenu.add(charge);
128 coloursMenu.add(zappo);
129 coloursMenu.add(taylor);
130 coloursMenu.add(hydro);
131 coloursMenu.add(helix);
132 coloursMenu.add(strand);
133 coloursMenu.add(turn);
134 coloursMenu.add(buried);
135 coloursMenu.add(user);
137 helpMenu.add(jmolHelp);
141 renderPanel = new RenderPanel();
142 embedMenuIfNeeded(renderPanel);
143 this.add(renderPanel, BorderLayout.CENTER);
144 viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter());
146 viewer.setAppletContext("jalview",
147 ap.av.applet.getDocumentBase(),
148 ap.av.applet.getCodeBase(),
151 viewer.setJmolStatusListener(this);
153 jmolpopup = JmolPopup.newJmolPopup(viewer);
155 this.addWindowListener(new WindowAdapter()
157 public void windowClosing(WindowEvent evt)
164 if(pdbentry.getFile()!=null)
166 // import structure data from pdbentry.getFile based on given protocol
167 if (protocol.equals(AppletFormatAdapter.PASTE))
169 loadInline(pdbentry.getFile());
171 if (protocol.equals(AppletFormatAdapter.FILE) || protocol.equals(AppletFormatAdapter.URL)){
172 viewer.openFile(pdbentry.getFile());
176 // probably CLASSLOADER based datasource..
177 // Try and get a reader on the datasource, and pass that to Jmol
179 FileParse fparser = new jalview.io.FileParse(protocol, pdbentry.getFile());
180 if (!fparser.isValid())
182 throw new Exception("Invalid datasource. "+fparser.getWarningMessage());
184 viewer.openReader(pdbentry.getFile(), pdbentry.getId(), fparser.getReader());
185 } catch (Exception e)
188 System.err.println("Couldn't access pdbentry id="+pdbentry.getId()+" and file="+pdbentry.getFile()+" using protocol="+protocol);
194 jalview.bin.JalviewLite.addFrame(this, "Jmol", 400,400);
197 public void loadInline(String string)
200 viewer.openStringInline(string);
204 void setChainMenuItems(Vector chains)
206 chainMenu.removeAll();
208 MenuItem menuItem = new MenuItem("All");
209 menuItem.addActionListener(this);
211 chainMenu.add(menuItem);
213 CheckboxMenuItem menuItemCB;
214 for (int c = 0; c < chains.size(); c++)
216 menuItemCB = new CheckboxMenuItem(chains.elementAt(c).toString(), true);
217 menuItemCB.addItemListener(this);
218 chainMenu.add(menuItemCB);
222 boolean allChainsSelected = false;
225 StringBuffer cmd = new StringBuffer();
226 for (int i = 0; i < chainMenu.getItemCount(); i++)
228 if (chainMenu.getItem(i) instanceof CheckboxMenuItem)
230 CheckboxMenuItem item = (CheckboxMenuItem) chainMenu.getItem(i);
232 cmd.append(":" + item.getLabel() + " or ");
236 if (cmd.length() > 0)
237 cmd.setLength(cmd.length() - 4);
239 viewer.evalString("select *;restrict "
240 + cmd + ";cartoon;center " + cmd);
246 viewer.setModeMouse(org.jmol.viewer.JmolConstants.MOUSE_NONE);
247 viewer.evalStringQuiet("zap");
248 viewer.setJmolStatusListener(null);
251 //We'll need to find out what other
252 // listeners need to be shut down in Jmol
253 StructureSelectionManager
254 .getStructureSelectionManager()
255 .removeStructureViewerListener(this, pdbentry.getId());
257 this.setVisible(false);
260 public void actionPerformed(ActionEvent evt)
262 if(evt.getSource()==mappingMenuItem)
264 jalview.appletgui.CutAndPasteTransfer cap
265 = new jalview.appletgui.CutAndPasteTransfer(false, null);
266 Frame frame = new Frame();
269 jalview.bin.JalviewLite.addFrame(frame, "PDB - Sequence Mapping", 550,
272 StructureSelectionManager.getStructureSelectionManager().printMapping(
276 else if (evt.getSource() == charge)
278 colourBySequence = false;
279 seqColour.setState(false);
280 viewer.evalStringQuiet("select *;color white;select ASP,GLU;color red;"
281 +"select LYS,ARG;color blue;select CYS;color yellow");
284 else if (evt.getSource() == chain)
286 colourBySequence = false;
287 seqColour.setState(false);
288 viewer.evalStringQuiet("select *;color chain");
290 else if (evt.getSource() == zappo)
292 setJalviewColourScheme(new ZappoColourScheme());
294 else if (evt.getSource() == taylor)
296 setJalviewColourScheme(new TaylorColourScheme());
298 else if (evt.getSource() == hydro)
300 setJalviewColourScheme(new HydrophobicColourScheme());
302 else if (evt.getSource() == helix)
304 setJalviewColourScheme(new HelixColourScheme());
306 else if (evt.getSource() == strand)
308 setJalviewColourScheme(new StrandColourScheme());
310 else if (evt.getSource() == turn)
312 setJalviewColourScheme(new TurnColourScheme());
314 else if (evt.getSource() == buried)
316 setJalviewColourScheme(new BuriedColourScheme());
318 else if (evt.getSource() == user)
320 new UserDefinedColours(this);
322 else if(evt.getSource() == jmolHelp)
325 ap.av.applet.getAppletContext().showDocument(
326 new java.net.URL("http://jmol.sourceforge.net/docs/JmolUserGuide/"),
328 }catch(java.net.MalformedURLException ex){}
332 allChainsSelected = true;
333 for (int i = 0; i < chainMenu.getItemCount(); i++)
335 if (chainMenu.getItem(i) instanceof CheckboxMenuItem)
336 ( (CheckboxMenuItem) chainMenu.getItem(i)).setState(true);
339 allChainsSelected = false;
343 public void setJalviewColourScheme(ColourSchemeI cs)
345 colourBySequence = false;
346 seqColour.setState(false);
355 Enumeration en = ResidueProperties.aa3Hash.keys();
356 StringBuffer command = new StringBuffer("select *;color white;");
357 while(en.hasMoreElements())
359 res = en.nextElement().toString();
360 index = ((Integer) ResidueProperties.aa3Hash.get(res)).intValue();
364 col = cs.findColour(ResidueProperties.aa[index].charAt(0));
366 command.append("select "+res+";color["
368 + col.getGreen() + ","
369 + col.getBlue() + "];");
372 viewer.evalStringQuiet(command.toString());
375 public void itemStateChanged(ItemEvent evt)
377 if (evt.getSource() == seqColour)
380 colourBySequence = seqColour.getState();
381 colourBySequence(ap);
383 else if (!allChainsSelected)
387 public void keyPressed(KeyEvent evt)
389 if (evt.getKeyCode() == KeyEvent.VK_ENTER
390 && scriptWindow.isVisible())
392 viewer.evalString(inputLine.getText());
393 history.append("\n$ "+inputLine.getText());
394 inputLine.setText("");
399 public void keyTyped(KeyEvent evt)
402 public void keyReleased(KeyEvent evt){}
404 //////////////////////////////////
406 public String getPdbFile()
414 public void mouseOverStructure(int atomIndex, String strInfo)
418 int chainSeparator = strInfo.indexOf(":");
420 if(chainSeparator==-1)
421 chainSeparator = strInfo.indexOf(".");
423 pdbResNum = Integer.parseInt(
424 strInfo.substring(strInfo.indexOf("]")+ 1, chainSeparator));
428 if (strInfo.indexOf(":") > -1)
429 chainId = strInfo.substring
430 (strInfo.indexOf(":")+1, strInfo.indexOf("."));
436 if (lastMessage == null || !lastMessage.equals(strInfo))
437 ssm.mouseOverStructure(pdbResNum, chainId, pdbentry.getFile());
439 lastMessage = strInfo;
442 StringBuffer resetLastRes = new StringBuffer();
443 StringBuffer eval = new StringBuffer();
445 public void highlightAtom(int atomIndex, int pdbResNum, String chain, String pdbfile)
447 if (!pdbfile.equals(pdbentry.getFile()))
450 if (resetLastRes.length() > 0)
452 viewer.evalStringQuiet(resetLastRes.toString());
456 eval.append("select " + pdbResNum);
458 resetLastRes.setLength(0);
459 resetLastRes.append("select " + pdbResNum);
461 if (!chain.equals(" "))
463 eval.append(":" + chain);
464 resetLastRes.append(":" + chain);
467 eval.append(";wireframe 100;"+eval.toString()+".CA;");
469 resetLastRes.append(";wireframe 0;"+resetLastRes.toString()+".CA;spacefill 0;");
471 eval.append("spacefill 200;select none");
473 viewer.evalStringQuiet(eval.toString());
477 public void updateColours(Object source)
479 colourBySequence( (AlignmentPanel) source);
482 //End StructureListener
483 ////////////////////////////
485 public Color getColour(int atomIndex, int pdbResNum, String chain, String pdbfile)
487 if (!pdbfile.equals(pdbentry.getFile()))
490 return new Color(viewer.getAtomArgb(atomIndex));
494 FeatureRenderer fr=null;
495 public void colourBySequence(AlignmentPanel sourceap)
499 if (!colourBySequence)
502 StructureMapping[] mapping = ssm.getMapping(pdbentry.getFile());
504 if (mapping.length < 1)
507 SequenceRenderer sr = new SequenceRenderer(ap.av);
509 boolean showFeatures = false;
511 if (ap.av.showSequenceFeatures)
516 fr = new jalview.appletgui.FeatureRenderer(ap.av);
519 fr.transferSettings(ap.seqPanel.seqCanvas.getFeatureRenderer());
522 StringBuffer command = new StringBuffer();
525 for (int s = 0; s < sequence.length; s++)
527 for (int sp,m = 0; m < mapping.length; m++)
529 if (mapping[m].getSequence() == sequence[s]
530 && (sp=ap.av.alignment.findIndex(sequence[s])) > -1)
532 SequenceI asp = ap.av.alignment.getSequenceAt(sp);
533 for (int r = 0; r < asp.getLength(); r++)
535 // no mapping to gaps in sequence
536 if (jalview.util.Comparison.isGap(asp.getCharAt(r)))
540 int pos = mapping[m].getPDBResNum(
541 asp.findPosition(r));
544 if (pos < 1 || pos == lastPos)
549 Color col = sr.getResidueBoxColour(sequence[s], r);
552 col = fr.findFeatureColour(col, sequence[s], r);
554 if (command.toString().endsWith(":" + mapping[m].getChain() +
557 + col.getGreen() + ","
558 + col.getBlue() + "]"))
560 command = condenseCommand(command.toString(), pos);
564 command.append(";select " + pos);
566 if (!mapping[m].getChain().equals(" "))
568 command.append(":" + mapping[m].getChain());
571 command.append(";color["
573 + col.getGreen() + ","
574 + col.getBlue() + "]");
581 if (lastCommand == null || !lastCommand.equals(command.toString()))
583 viewer.evalStringQuiet(command.toString());
585 lastCommand = command.toString();
589 StringBuffer condenseCommand(String command, int pos)
592 StringBuffer sb = new StringBuffer(command.substring(0, command.lastIndexOf("select")+7));
594 command = command.substring(sb.length());
598 if (command.indexOf("-") > -1)
600 start = command.substring(0,command.indexOf("-"));
604 start = command.substring(0, command.indexOf(":"));
607 sb.append(start+"-"+pos+command.substring(command.indexOf(":")));
612 /////////////////////////////////
615 public String eval(String strEval)
617 // System.out.println(strEval);
618 //"# 'eval' is implemented only for the applet.";
622 public void createImage(String file, String type, int quality)
625 public void setCallbackFunction(String callbackType,
626 String callbackFunction)
629 public void notifyFileLoaded(String fullPathName, String fileName,
630 String modelName, Object clientFile,
635 fileLoadingError = errorMsg;
640 fileLoadingError = null;
642 if (fileName != null)
645 jmolpopup.updateComputedMenus();
646 viewer.evalStringQuiet(
647 "select backbone;restrict;cartoon;wireframe off;spacefill off");
649 ssm = StructureSelectionManager.getStructureSelectionManager();
654 pdb = ssm.setMapping(sequence,chains,
656 AppletFormatAdapter.PASTE);
657 pdbentry.setFile("INLINE"+pdb.id);
661 pdb = ssm.setMapping(sequence,chains,
663 AppletFormatAdapter.URL);
666 pdbentry.setId(pdb.id);
668 ssm.addStructureViewerListener(this);
670 Vector chains = new Vector();
671 for (int i = 0; i < pdb.chains.size(); i++)
673 chains.addElement( ( (MCview.PDBChain) pdb.chains.elementAt(i)).id);
675 setChainMenuItems(chains);
677 colourBySequence(ap);
679 StringBuffer title = new StringBuffer(sequence[0].getName() + ":" +
682 if (pdbentry.getProperty() != null)
684 if (pdbentry.getProperty().get("method") != null)
686 title.append(" Method: ");
687 title.append(pdbentry.getProperty().get("method"));
689 if (pdbentry.getProperty().get("chains") != null)
691 title.append(" Chain:");
692 title.append(pdbentry.getProperty().get("chains"));
696 this.setTitle(title.toString());
703 public void notifyFrameChanged(int frameNo)
705 boolean isAnimationRunning = (frameNo <= -2);
708 public void notifyScriptStart(String statusMessage, String additionalInfo)
711 public void sendConsoleEcho(String strEcho)
713 if (scriptWindow == null)
716 history.append("\n"+strEcho);
719 public void sendConsoleMessage(String strStatus)
721 if(history!=null && strStatus!=null
722 && !strStatus.equals("Script completed"))
724 history.append("\n"+strStatus);
728 public void notifyScriptTermination(String strStatus, int msWalltime)
731 public void handlePopupMenu(int x, int y)
733 jmolpopup.show(x, y);
736 public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
738 notifyAtomPicked(iatom, strMeasure);
741 public void notifyNewDefaultModeMeasurement(int count, String strInfo)
744 public void notifyAtomPicked(int atomIndex, String strInfo)
747 int chainSeparator = strInfo.indexOf(":");
749 if(chainSeparator==-1)
750 chainSeparator = strInfo.indexOf(".");
753 strInfo.substring(strInfo.indexOf("]")+ 1, chainSeparator);
756 if (strInfo.indexOf(":") > -1)
757 picked+=strInfo.substring(strInfo.indexOf(":")+1,
758 strInfo.indexOf("."));
762 if (!atomsPicked.contains(picked))
764 viewer.evalString("select "+picked+";label %n %r:%c");
765 atomsPicked.addElement(picked);
769 viewer.evalString("select "+picked+";label off");
770 atomsPicked.removeElement(picked);
774 public void notifyAtomHovered(int atomIndex, String strInfo)
776 mouseOverStructure(atomIndex, strInfo);
779 public void sendSyncScript(String script, String appletName)
782 public void showUrl(String url)
785 ap.av.applet.getAppletContext().showDocument(new java.net.URL(url),
787 }catch(java.net.MalformedURLException ex)
791 public void showConsole(boolean showConsole)
793 if (scriptWindow == null)
795 scriptWindow = new Panel(new BorderLayout());
796 inputLine = new TextField();
797 history = new TextArea(5, 40);
798 scriptWindow.add(history, BorderLayout.CENTER);
799 scriptWindow.add(inputLine, BorderLayout.SOUTH);
800 add(scriptWindow, BorderLayout.SOUTH);
801 scriptWindow.setVisible(false);
802 history.setEditable(false);
803 inputLine.addKeyListener(this);
806 scriptWindow.setVisible(!scriptWindow.isVisible());
810 public float functionXY(String functionName, int x, int y)
815 ///End JmolStatusListener
816 ///////////////////////////////
822 Dimension currentSize = new Dimension();
823 Rectangle rectClip = new Rectangle();
825 public void update(Graphics g) {
828 public void paint(Graphics g)
830 currentSize = this.getSize();
831 rectClip = g.getClipBounds();
835 g.setColor(Color.black);
836 g.fillRect(0, 0, currentSize.width, currentSize.height);
837 g.setColor(Color.white);
838 g.setFont(new Font("Verdana", Font.BOLD, 14));
839 g.drawString("Retrieving PDB data....", 20, currentSize.height / 2);
843 viewer.renderScreenImage(g, currentSize, rectClip);