2 * Jalview - A Sequence Alignment Editor and Viewer
\r
3 * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
\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
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
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
20 package jalview.appletgui;
\r
24 import java.awt.event.*;
\r
26 import jalview.datamodel.*;
\r
27 import jalview.structure.*;
\r
28 import jalview.io.*;
\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
36 public class AppletJmol extends Frame
\r
37 implements StructureListener, JmolStatusListener,
\r
38 KeyListener, ActionListener, ItemListener
\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
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
60 MenuItem jmolHelp = new MenuItem("Jmol Help");
\r
63 JmolPopup jmolpopup;
\r
66 TextField inputLine;
\r
68 SequenceI[] sequence;
\r
69 StructureSelectionManager ssm;
\r
70 RenderPanel renderPanel;
\r
72 String fileLoadingError;
\r
73 boolean loadedInline;
\r
75 boolean colourBySequence = true;
\r
76 Vector atomsPicked = new Vector();
\r
78 public AppletJmol(PDBEntry pdbentry,
\r
84 this.sequence = seq;
\r
85 this.pdbentry = pdbentry;
\r
87 String alreadyMapped = StructureSelectionManager
\r
88 .getStructureSelectionManager()
\r
89 .alreadyMappedToFile(pdbentry.getId());
\r
91 if (alreadyMapped != null)
\r
93 StructureSelectionManager.getStructureSelectionManager()
\r
94 .setMapping(seq, pdbentry.getFile(), protocol);
\r
98 renderPanel = new RenderPanel();
\r
100 this.add(renderPanel, BorderLayout.CENTER);
\r
102 viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter());
\r
104 viewer.setAppletContext("jalview",
\r
105 ap.av.applet.getDocumentBase(),
\r
106 ap.av.applet.getCodeBase(),
\r
109 viewer.setJmolStatusListener(this);
\r
111 jmolpopup = JmolPopup.newJmolPopup(viewer);
\r
113 this.addWindowListener(new WindowAdapter()
\r
115 public void windowClosing(WindowEvent evt)
\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
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
142 jmolHelp.addActionListener(this);
\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
156 helpMenu.add(jmolHelp);
\r
158 this.setMenuBar(menuBar);
\r
160 if(pdbentry.getFile()!=null)
\r
162 if (protocol.equals(AppletFormatAdapter.PASTE))
\r
163 loadInline(pdbentry.getFile());
\r
165 viewer.openFile(pdbentry.getFile());
\r
168 this.setBounds(400, 400, 400, 400);
\r
170 this.setVisible(true);
\r
173 public void loadInline(String string)
\r
175 loadedInline = true;
\r
176 viewer.openStringInline(string);
\r
180 void setChainMenuItems(Vector chains)
\r
182 chainMenu.removeAll();
\r
184 MenuItem menuItem = new MenuItem("All");
\r
185 menuItem.addActionListener(this);
\r
187 chainMenu.add(menuItem);
\r
189 CheckboxMenuItem menuItemCB;
\r
190 for (int c = 0; c < chains.size(); c++)
\r
192 menuItemCB = new CheckboxMenuItem(chains.elementAt(c).toString(), true);
\r
193 menuItemCB.addItemListener(this);
\r
194 chainMenu.add(menuItemCB);
\r
198 boolean allChainsSelected = false;
\r
199 void centerViewer()
\r
201 StringBuffer cmd = new StringBuffer();
\r
202 for (int i = 0; i < chainMenu.getItemCount(); i++)
\r
204 if (chainMenu.getItem(i) instanceof CheckboxMenuItem)
\r
206 CheckboxMenuItem item = (CheckboxMenuItem) chainMenu.getItem(i);
\r
207 if (item.getState())
\r
208 cmd.append(":" + item.getLabel() + " or ");
\r
212 if (cmd.length() > 0)
\r
213 cmd.setLength(cmd.length() - 4);
\r
215 viewer.evalString("select *;restrict "
\r
216 + cmd + ";cartoon;center " + cmd);
\r
222 viewer.setModeMouse(org.jmol.viewer.JmolConstants.MOUSE_NONE);
\r
223 viewer.evalStringQuiet("zap");
\r
224 viewer.setJmolStatusListener(null);
\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
233 this.setVisible(false);
\r
236 public void actionPerformed(ActionEvent evt)
\r
238 if(evt.getSource()==mappingMenuItem)
\r
240 jalview.appletgui.CutAndPasteTransfer cap
\r
241 = new jalview.appletgui.CutAndPasteTransfer(false, null);
\r
242 Frame frame = new Frame();
\r
245 jalview.bin.JalviewLite.addFrame(frame, "PDB - Sequence Mapping", 550,
\r
248 StructureSelectionManager.getStructureSelectionManager().printMapping(
\r
249 pdbentry.getFile())
\r
252 else if (evt.getSource() == charge)
\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
260 else if (evt.getSource() == chain)
\r
262 colourBySequence = false;
\r
263 seqColour.setState(false);
\r
264 viewer.evalStringQuiet("select *;color chain");
\r
266 else if (evt.getSource() == zappo)
\r
268 setJalviewColourScheme(new ZappoColourScheme());
\r
270 else if (evt.getSource() == taylor)
\r
272 setJalviewColourScheme(new TaylorColourScheme());
\r
274 else if (evt.getSource() == hydro)
\r
276 setJalviewColourScheme(new HydrophobicColourScheme());
\r
278 else if (evt.getSource() == helix)
\r
280 setJalviewColourScheme(new HelixColourScheme());
\r
282 else if (evt.getSource() == strand)
\r
284 setJalviewColourScheme(new StrandColourScheme());
\r
286 else if (evt.getSource() == turn)
\r
288 setJalviewColourScheme(new TurnColourScheme());
\r
290 else if (evt.getSource() == buried)
\r
292 setJalviewColourScheme(new BuriedColourScheme());
\r
294 else if (evt.getSource() == user)
\r
296 new UserDefinedColours(this);
\r
298 else if(evt.getSource() == jmolHelp)
\r
301 ap.av.applet.getAppletContext().showDocument(
\r
302 new java.net.URL("http://jmol.sourceforge.net/docs/JmolUserGuide/"),
\r
304 }catch(java.net.MalformedURLException ex){}
\r
308 allChainsSelected = true;
\r
309 for (int i = 0; i < chainMenu.getItemCount(); i++)
\r
311 if (chainMenu.getItem(i) instanceof CheckboxMenuItem)
\r
312 ( (CheckboxMenuItem) chainMenu.getItem(i)).setState(true);
\r
315 allChainsSelected = false;
\r
319 public void setJalviewColourScheme(ColourSchemeI cs)
\r
321 colourBySequence = false;
\r
322 seqColour.setState(false);
\r
331 Enumeration en = ResidueProperties.aa3Hash.keys();
\r
332 StringBuffer command = new StringBuffer("select *;color white;");
\r
333 while(en.hasMoreElements())
\r
335 res = en.nextElement().toString();
\r
336 index = ((Integer) ResidueProperties.aa3Hash.get(res)).intValue();
\r
340 col = cs.findColour(ResidueProperties.aa[index].charAt(0));
\r
342 command.append("select "+res+";color["
\r
343 + col.getRed() + ","
\r
344 + col.getGreen() + ","
\r
345 + col.getBlue() + "];");
\r
348 viewer.evalStringQuiet(command.toString());
\r
351 public void itemStateChanged(ItemEvent evt)
\r
353 if (evt.getSource() == seqColour)
\r
355 colourBySequence = seqColour.getState();
\r
356 colourBySequence(ap);
\r
358 else if (!allChainsSelected)
\r
362 public void keyPressed(KeyEvent evt)
\r
364 if (evt.getKeyCode() == KeyEvent.VK_ENTER
\r
365 && scriptWindow.isVisible())
\r
367 viewer.evalString(inputLine.getText());
\r
368 history.append("\n$ "+inputLine.getText());
\r
369 inputLine.setText("");
\r
374 public void keyTyped(KeyEvent evt)
\r
377 public void keyReleased(KeyEvent evt){}
\r
379 //////////////////////////////////
\r
380 ///StructureListener
\r
381 public String getPdbFile()
\r
388 String lastMessage;
\r
389 public void mouseOverStructure(int atomIndex, String strInfo)
\r
393 int chainSeparator = strInfo.indexOf(":");
\r
395 if(chainSeparator==-1)
\r
396 chainSeparator = strInfo.indexOf(".");
\r
398 pdbResNum = Integer.parseInt(
\r
399 strInfo.substring(strInfo.indexOf("]")+ 1, chainSeparator));
\r
403 if (strInfo.indexOf(":") > -1)
\r
404 chainId = strInfo.substring
\r
405 (strInfo.indexOf(":")+1, strInfo.indexOf("."));
\r
411 if (lastMessage == null || !lastMessage.equals(strInfo))
\r
412 ssm.mouseOverStructure(pdbResNum, chainId, pdbentry.getFile());
\r
414 lastMessage = strInfo;
\r
417 StringBuffer resetLastRes = new StringBuffer();
\r
418 StringBuffer eval = new StringBuffer();
\r
420 public void highlightAtom(int atomIndex, int pdbResNum, String chain, String pdbfile)
\r
422 if (!pdbfile.equals(pdbentry.getFile()))
\r
425 if (resetLastRes.length() > 0)
\r
427 viewer.evalStringQuiet(resetLastRes.toString());
\r
431 eval.append("select " + pdbResNum);
\r
433 resetLastRes.setLength(0);
\r
434 resetLastRes.append("select " + pdbResNum);
\r
436 if (!chain.equals(" "))
\r
438 eval.append(":" + chain);
\r
439 resetLastRes.append(":" + chain);
\r
442 eval.append(";color gold;wireframe 100");
\r
444 Color col = new Color(viewer.getAtomArgb(atomIndex));
\r
446 resetLastRes.append(";color["
\r
447 + col.getRed() + ","
\r
448 + col.getGreen() + ","
\r
449 + col.getBlue() + "];wireframe 0");
\r
451 viewer.evalStringQuiet(eval.toString());
\r
455 public void updateColours(Object source)
\r
457 colourBySequence( (AlignmentPanel) source);
\r
460 //End StructureListener
\r
461 ////////////////////////////
\r
463 FeatureRenderer fr;
\r
464 public void colourBySequence(AlignmentPanel ap)
\r
466 if(!colourBySequence)
\r
470 StructureMapping[] mapping = ssm.getMapping(pdbentry.getFile());
\r
472 if (mapping.length < 1)
\r
475 SequenceRenderer sr = ap.seqPanel.seqCanvas.getSequenceRenderer();
\r
477 boolean showFeatures = false;
\r
478 if (ap.av.showSequenceFeatures)
\r
480 showFeatures = true;
\r
483 fr = new jalview.appletgui.FeatureRenderer(ap.av);
\r
486 fr.transferSettings(ap.seqPanel.seqCanvas.getFeatureRenderer());
\r
489 StringBuffer command = new StringBuffer();
\r
492 for (int s = 0; s < sequence.length; s++)
\r
494 for (int m = 0; m < mapping.length; m++)
\r
496 if (mapping[m].getSequence() == sequence[s])
\r
498 for (int r = 0; r < sequence[s].getLength(); r++)
\r
500 int pos = mapping[m].getPDBResNum(
\r
501 sequence[s].findPosition(r));
\r
503 if (pos < 1 || pos==lastPos)
\r
508 Color col = sr.getResidueBoxColour(sequence[s], r);
\r
511 col = fr.findFeatureColour(col, sequence[s], r);
\r
513 if (command.toString().endsWith(":" + mapping[m].getChain()+
\r
515 + col.getRed() + ","
\r
516 + col.getGreen() + ","
\r
517 + col.getBlue() + "]"))
\r
519 command = condenseCommand(command.toString(), pos);
\r
523 command.append(";select " + pos);
\r
525 if (!mapping[m].getChain().equals(" "))
\r
527 command.append(":" + mapping[m].getChain());
\r
530 command.append(";color["
\r
531 + col.getRed() + ","
\r
532 + col.getGreen() + ","
\r
533 + col.getBlue() + "]");
\r
541 viewer.evalStringQuiet(command.toString());
\r
544 StringBuffer condenseCommand(String command, int pos)
\r
547 StringBuffer sb = new StringBuffer(command.substring(0, command.lastIndexOf("select")+7));
\r
549 command = command.substring(sb.length());
\r
553 if (command.indexOf("-") > -1)
\r
555 start = command.substring(0,command.indexOf("-"));
\r
559 start = command.substring(0, command.indexOf(":"));
\r
562 sb.append(start+"-"+pos+command.substring(command.indexOf(":")));
\r
567 /////////////////////////////////
\r
568 //JmolStatusListener
\r
570 public String eval(String strEval)
\r
572 // System.out.println(strEval);
\r
573 //"# 'eval' is implemented only for the applet.";
\r
577 public void createImage(String file, String type, int quality)
\r
580 public void setCallbackFunction(String callbackType,
\r
581 String callbackFunction)
\r
584 public void notifyFileLoaded(String fullPathName, String fileName,
\r
585 String modelName, Object clientFile,
\r
590 fileLoadingError = errorMsg;
\r
595 fileLoadingError = null;
\r
597 if (fileName != null)
\r
600 jmolpopup.updateComputedMenus();
\r
601 viewer.evalStringQuiet(
\r
602 "select backbone;restrict;cartoon;wireframe off;spacefill off");
\r
604 ssm = StructureSelectionManager.getStructureSelectionManager();
\r
606 MCview.PDBfile pdb;
\r
609 pdb = ssm.setMapping(sequence,
\r
610 pdbentry.getFile(),
\r
611 AppletFormatAdapter.PASTE);
\r
612 pdbentry.setFile("INLINE"+pdb.id);
\r
616 pdb = ssm.setMapping(sequence,
\r
617 pdbentry.getFile(),
\r
618 AppletFormatAdapter.URL);
\r
621 pdbentry.setId(pdb.id);
\r
623 ssm.addStructureViewerListener(this);
\r
625 Vector chains = new Vector();
\r
626 for (int i = 0; i < pdb.chains.size(); i++)
\r
628 chains.addElement( ( (MCview.PDBChain) pdb.chains.elementAt(i)).id);
\r
630 setChainMenuItems(chains);
\r
632 colourBySequence(ap);
\r
634 StringBuffer title = new StringBuffer(sequence[0].getName() + ":" +
\r
637 if (pdbentry.getProperty() != null)
\r
639 if (pdbentry.getProperty().get("method") != null)
\r
641 title.append(" Method: ");
\r
642 title.append(pdbentry.getProperty().get("method"));
\r
644 if (pdbentry.getProperty().get("chains") != null)
\r
646 title.append(" Chain:");
\r
647 title.append(pdbentry.getProperty().get("chains"));
\r
651 this.setTitle(title.toString());
\r
658 public void notifyFrameChanged(int frameNo)
\r
660 boolean isAnimationRunning = (frameNo <= -2);
\r
663 public void notifyScriptStart(String statusMessage, String additionalInfo)
\r
666 public void sendConsoleEcho(String strEcho)
\r
668 if (scriptWindow == null)
\r
671 history.append("\n"+strEcho);
\r
674 public void sendConsoleMessage(String strStatus)
\r
676 if(history!=null && strStatus!=null
\r
677 && !strStatus.equals("Script completed"))
\r
679 history.append("\n"+strStatus);
\r
683 public void notifyScriptTermination(String strStatus, int msWalltime)
\r
686 public void handlePopupMenu(int x, int y)
\r
688 jmolpopup.show(x, y);
\r
691 public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
\r
693 notifyAtomPicked(iatom, strMeasure);
\r
696 public void notifyNewDefaultModeMeasurement(int count, String strInfo)
\r
699 public void notifyAtomPicked(int atomIndex, String strInfo)
\r
702 int chainSeparator = strInfo.indexOf(":");
\r
704 if(chainSeparator==-1)
\r
705 chainSeparator = strInfo.indexOf(".");
\r
708 strInfo.substring(strInfo.indexOf("]")+ 1, chainSeparator);
\r
711 if (strInfo.indexOf(":") > -1)
\r
712 picked+=strInfo.substring(strInfo.indexOf(":")+1,
\r
713 strInfo.indexOf("."));
\r
717 if (!atomsPicked.contains(picked))
\r
719 viewer.evalString("select "+picked+";label %n %r:%c");
\r
720 atomsPicked.addElement(picked);
\r
724 viewer.evalString("select "+picked+";label off");
\r
725 atomsPicked.removeElement(picked);
\r
729 public void notifyAtomHovered(int atomIndex, String strInfo)
\r
731 mouseOverStructure(atomIndex, strInfo);
\r
734 public void sendSyncScript(String script, String appletName)
\r
737 public void showUrl(String url)
\r
740 ap.av.applet.getAppletContext().showDocument(new java.net.URL(url),
\r
742 }catch(java.net.MalformedURLException ex)
\r
746 public void showConsole(boolean showConsole)
\r
748 if (scriptWindow == null)
\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
761 scriptWindow.setVisible(!scriptWindow.isVisible());
\r
765 public float functionXY(String functionName, int x, int y)
\r
770 ///End JmolStatusListener
\r
771 ///////////////////////////////
\r
777 Dimension currentSize = new Dimension();
\r
778 Rectangle rectClip = new Rectangle();
\r
780 public void update(Graphics g) {
\r
783 public void paint(Graphics g)
\r
785 currentSize = this.getSize();
\r
786 rectClip = g.getClipBounds();
\r
788 if (viewer == null)
\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
798 viewer.renderScreenImage(g, currentSize, rectClip);
\r