2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
21 package jalview.ext.jmol;
23 import jalview.api.FeatureRenderer;
24 import jalview.datamodel.AlignmentI;
25 import jalview.datamodel.HiddenColumns;
26 import jalview.datamodel.PDBEntry;
27 import jalview.datamodel.SequenceI;
28 import jalview.gui.IProgressIndicator;
29 import jalview.gui.StructureViewer.ViewerType;
30 import jalview.io.DataSourceType;
31 import jalview.io.StructureFile;
32 import jalview.structure.AtomSpec;
33 import jalview.structure.StructureCommandsI.SuperposeData;
34 import jalview.structure.StructureSelectionManager;
35 import jalview.structures.models.AAStructureBindingModel;
36 import jalview.util.MessageManager;
38 import java.awt.Container;
39 import java.awt.event.ComponentEvent;
40 import java.awt.event.ComponentListener;
43 import java.util.ArrayList;
44 import java.util.BitSet;
45 import java.util.List;
47 import java.util.StringTokenizer;
48 import java.util.Vector;
50 import org.jmol.adapter.smarter.SmarterJmolAdapter;
51 import org.jmol.api.JmolAppConsoleInterface;
52 import org.jmol.api.JmolSelectionListener;
53 import org.jmol.api.JmolStatusListener;
54 import org.jmol.api.JmolViewer;
55 import org.jmol.c.CBK;
56 import org.jmol.viewer.Viewer;
58 public abstract class JalviewJmolBinding extends AAStructureBindingModel
59 implements JmolStatusListener, JmolSelectionListener,
62 private String lastMessage;
65 * when true, try to search the associated datamodel for sequences that are
66 * associated with any unknown structures in the Jmol view.
68 private boolean associateNewStructs = false;
70 private Vector<String> atomsPicked = new Vector<>();
72 private String lastCommand;
74 private boolean loadedInline;
76 private StringBuffer resetLastRes = new StringBuffer();
78 public Viewer jmolViewer;
80 public JalviewJmolBinding(StructureSelectionManager ssm,
81 PDBEntry[] pdbentry, SequenceI[][] sequenceIs,
82 DataSourceType protocol)
84 super(ssm, pdbentry, sequenceIs, protocol);
85 setStructureCommands(new JmolCommands());
87 * viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter(),
88 * "jalviewJmol", ap.av.applet .getDocumentBase(),
89 * ap.av.applet.getCodeBase(), "", this);
91 * jmolpopup = JmolPopup.newJmolPopup(viewer, true, "Jmol", true);
95 public JalviewJmolBinding(StructureSelectionManager ssm,
96 SequenceI[][] seqs, Viewer theViewer)
100 jmolViewer = theViewer;
101 jmolViewer.setJmolStatusListener(this);
102 jmolViewer.addSelectionListener(this);
103 setStructureCommands(new JmolCommands());
107 * construct a title string for the viewer window based on the data jalview
112 public String getViewerTitle()
114 return getViewerTitle("Jmol", true);
117 public void closeViewer()
119 // remove listeners for all structures in viewer
120 getSsm().removeStructureViewerListener(this, this.getStructureFiles());
121 jmolViewer.dispose();
124 releaseUIResources();
128 * superpose the structures associated with sequences in the alignment
129 * according to their corresponding positions.
131 * @deprecated not used - remove?
134 public void superposeStructures(AlignmentI alignment)
136 superposeStructures(alignment, -1, null);
140 * superpose the structures associated with sequences in the alignment
141 * according to their corresponding positions. ded)
143 * @param refStructure
144 * - select which pdb file to use as reference (default is -1 - the
145 * first structure in the alignment)
146 * @deprecated not used - remove?
149 public void superposeStructures(AlignmentI alignment, int refStructure)
151 superposeStructures(alignment, refStructure, null);
155 * superpose the structures associated with sequences in the alignment
156 * according to their corresponding positions. ded)
158 * @param refStructure
159 * - select which pdb file to use as reference (default is -1 - the
160 * first structure in the alignment)
163 * @deprecated not used - remove?
166 public void superposeStructures(AlignmentI alignment, int refStructure,
167 HiddenColumns hiddenCols)
169 superposeStructures(new AlignmentI[] { alignment },
171 { refStructure }, new HiddenColumns[] { hiddenCols });
177 public String superposeStructures(AlignmentI[] _alignment,
178 int[] _refStructure, HiddenColumns[] _hiddenCols)
180 // TODO delete method
181 while (jmolViewer.isScriptExecuting())
186 } catch (InterruptedException i)
192 * get the distinct structure files modelled
193 * (a file with multiple chains may map to multiple sequences)
195 String[] files = getStructureFiles();
196 if (!waitForFileLoad(files))
201 StringBuilder selectioncom = new StringBuilder(256);
202 // In principle - nSeconds specifies the speed of animation for each
203 // superposition - but is seems to behave weirdly, so we don't specify it.
204 String nSeconds = " ";
205 if (files.length > 10)
207 nSeconds = " 0.005 ";
211 nSeconds = " " + (2.0 / files.length) + " ";
212 // if (nSeconds).substring(0,5)+" ";
215 // see JAL-1345 - should really automatically turn off the animation for
216 // large numbers of structures, but Jmol doesn't seem to allow that.
218 // union of all aligned positions are collected together.
219 for (int a = 0; a < _alignment.length; a++)
221 int refStructure = _refStructure[a];
222 AlignmentI alignment = _alignment[a];
223 HiddenColumns hiddenCols = _hiddenCols[a];
224 if (a > 0 && selectioncom.length() > 0 && !selectioncom
225 .substring(selectioncom.length() - 1).equals("|"))
227 selectioncom.append("|");
229 // process this alignment
230 if (refStructure >= files.length)
233 "Invalid reference structure value " + refStructure);
238 * 'matched' bit j will be set for visible alignment columns j where
239 * all sequences have a residue with a mapping to the PDB structure
241 BitSet matched = new BitSet();
242 for (int m = 0; m < alignment.getWidth(); m++)
244 if (hiddenCols == null || hiddenCols.isVisible(m))
250 SuperposeData[] structures = new SuperposeData[files.length];
251 for (int f = 0; f < files.length; f++)
253 structures[f] = new SuperposeData(alignment.getWidth(), f);
257 * Calculate the superposable alignment columns ('matched'), and the
258 * corresponding structure residue positions (structures.pdbResNo)
260 int candidateRefStructure = findSuperposableResidues(alignment,
261 matched, structures);
262 if (refStructure < 0)
265 * If no reference structure was specified, pick the first one that has
266 * a mapping in the alignment
268 refStructure = candidateRefStructure;
271 String[] selcom = new String[files.length];
272 int nmatched = matched.cardinality();
275 return (MessageManager.formatMessage("label.insufficient_residues",
280 * generate select statements to select regions to superimpose structures
283 // TODO extract method to construct selection statements
284 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
286 String chainCd = ":" + structures[pdbfnum].chain;
289 StringBuilder molsel = new StringBuilder();
292 int nextColumnMatch = matched.nextSetBit(0);
293 while (nextColumnMatch != -1)
295 int pdbResNo = structures[pdbfnum].pdbResNo[nextColumnMatch];
296 if (lpos != pdbResNo - 1)
302 molsel.append(chainCd);
309 // continuous run - and lpos >-1
312 // at the beginning, so add dash
319 nextColumnMatch = matched.nextSetBit(nextColumnMatch + 1);
322 * add final selection phrase
327 molsel.append(chainCd);
330 if (molsel.length() > 1)
332 selcom[pdbfnum] = molsel.toString();
333 selectioncom.append("((");
334 selectioncom.append(selcom[pdbfnum].substring(1,
335 selcom[pdbfnum].length() - 1));
336 selectioncom.append(" )& ");
337 selectioncom.append(pdbfnum + 1);
338 selectioncom.append(".1)");
339 if (pdbfnum < files.length - 1)
341 selectioncom.append("|");
346 selcom[pdbfnum] = null;
350 StringBuilder command = new StringBuilder(256);
351 // command.append("set spinFps 10;\n");
353 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
355 if (pdbfnum == refStructure || selcom[pdbfnum] == null
356 || selcom[refStructure] == null)
360 command.append("echo ");
361 command.append("\"Superposing (");
362 command.append(structures[pdbfnum].pdbId);
363 command.append(") against reference (");
364 command.append(structures[refStructure].pdbId);
365 command.append(")\";\ncompare " + nSeconds);
367 command.append(Integer.toString(1 + pdbfnum));
368 command.append(".1} {");
369 command.append(Integer.toString(1 + refStructure));
370 // conformation=1 excludes alternate locations for CA (JAL-1757)
372 ".1} SUBSET {(*.CA | *.P) and conformation=1} ATOMS ");
374 // for (int s = 0; s < 2; s++)
376 // command.append(selcom[(s == 0 ? pdbfnum : refStructure)]);
378 command.append(selcom[pdbfnum]);
379 command.append(selcom[refStructure]);
380 command.append(" ROTATE TRANSLATE;\n");
382 if (selectioncom.length() > 0)
384 String cmdString = command.toString();
385 executeCommand(cmdString, false);
388 if (selectioncom.length() > 0)
391 * finally, highlight with cartoons the residues that were superposed
393 if (selectioncom.charAt(selectioncom.length() - 1) == '|')
395 selectioncom.setLength(selectioncom.length() - 1);
397 executeCommand("select *; cartoons off; backbone; select ("
398 + selectioncom.toString() + "); cartoons; ", false);
405 public List<String> executeCommand(String command, boolean getReply)
412 if (lastCommand == null || !lastCommand.equals(command))
414 jmolViewer.evalStringQuiet(command + "\n");
417 lastCommand = command;
421 public void createImage(String file, String type, int quality)
423 System.out.println("JMOL CREATE IMAGE");
427 public String createImage(String fileName, String type,
428 Object textOrBytes, int quality)
430 System.out.println("JMOL CREATE IMAGE");
435 public String eval(String strEval)
437 // System.out.println(strEval);
438 // "# 'eval' is implemented only for the applet.";
442 // End StructureListener
443 // //////////////////////////
446 public float[][] functionXY(String functionName, int x, int y)
452 public float[][][] functionXYZ(String functionName, int nx, int ny,
455 // TODO Auto-generated method stub
460 * map between index of model filename returned from getPdbFile and the first
461 * index of models from this file in the viewer. Note - this is not trimmed -
462 * use getPdbFile to get number of unique models.
464 private int _modelFileNameMap[];
467 public synchronized String[] getStructureFiles()
469 List<String> mset = new ArrayList<>();
470 if (jmolViewer == null)
472 return new String[0];
475 if (modelFileNames == null)
477 int modelCount = jmolViewer.ms.mc;
478 String filePath = null;
479 for (int i = 0; i < modelCount; ++i)
481 filePath = jmolViewer.ms.getModelFileName(i);
482 if (!mset.contains(filePath))
487 modelFileNames = mset.toArray(new String[mset.size()]);
490 return modelFileNames;
494 * map from string to applet
497 public Map<String, Object> getRegistryInfo()
499 // TODO Auto-generated method stub
503 // ///////////////////////////////
504 // JmolStatusListener
506 public void handlePopupMenu(int x, int y)
508 // jmolpopup.show(x, y);
509 // jmolpopup.jpiShow(x, y);
513 * Highlight zero, one or more atoms on the structure
516 public void highlightAtoms(List<AtomSpec> atoms)
520 if (resetLastRes.length() > 0)
522 jmolViewer.evalStringQuiet(resetLastRes.toString());
523 resetLastRes.setLength(0);
525 for (AtomSpec atom : atoms)
527 highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(),
528 atom.getChain(), atom.getPdbFile());
534 public void highlightAtom(int atomIndex, int pdbResNum, String chain,
537 if (modelFileNames == null)
542 // look up file model number for this pdbfile
544 // may need to adjust for URLencoding here - we don't worry about that yet.
545 while (mdlNum < modelFileNames.length
546 && !pdbfile.equals(modelFileNames[mdlNum]))
550 if (mdlNum == modelFileNames.length)
557 StringBuilder cmd = new StringBuilder(64);
558 cmd.append("select ").append(String.valueOf(pdbResNum)); // +modelNum
560 resetLastRes.append("select ").append(String.valueOf(pdbResNum)); // +modelNum
563 resetLastRes.append(":");
564 if (!chain.equals(" "))
567 resetLastRes.append(chain);
570 cmd.append(" /").append(String.valueOf(mdlNum + 1));
571 resetLastRes.append("/").append(String.valueOf(mdlNum + 1));
573 cmd.append(";wireframe 100;" + cmd.toString() + " and not hetero;");
575 resetLastRes.append(";wireframe 0;" + resetLastRes.toString()
576 + " and not hetero; spacefill 0;");
578 cmd.append("spacefill 200;select none");
580 jmolViewer.evalStringQuiet(cmd.toString());
585 private boolean debug = true;
587 private void jmolHistory(boolean enable)
589 jmolViewer.evalStringQuiet("History " + ((debug || enable) ? "on" : "off"));
592 public void loadInline(String string)
596 // viewer.loadInline(strModel, isAppend);
598 // construct fake fullPathName and fileName so we can identify the file
600 // Then, construct pass a reader for the string to Jmol.
601 // ((org.jmol.Viewer.Viewer) viewer).loadModelFromFile(fullPathName,
602 // fileName, null, reader, false, null, null, 0);
603 jmolViewer.openStringInline(string);
606 protected void mouseOverStructure(int atomIndex, final String strInfo)
609 int alocsep = strInfo.indexOf("^");
610 int mdlSep = strInfo.indexOf("/");
611 int chainSeparator = strInfo.indexOf(":"), chainSeparator1 = -1;
613 if (chainSeparator == -1)
615 chainSeparator = strInfo.indexOf(".");
616 if (mdlSep > -1 && mdlSep < chainSeparator)
618 chainSeparator1 = chainSeparator;
619 chainSeparator = mdlSep;
622 // handle insertion codes
625 pdbResNum = Integer.parseInt(
626 strInfo.substring(strInfo.indexOf("]") + 1, alocsep));
631 pdbResNum = Integer.parseInt(
632 strInfo.substring(strInfo.indexOf("]") + 1, chainSeparator));
636 if (strInfo.indexOf(":") > -1)
638 chainId = strInfo.substring(strInfo.indexOf(":") + 1,
639 strInfo.indexOf("."));
646 String pdbfilename = modelFileNames[0]; // default is first model
649 if (chainSeparator1 == -1)
651 chainSeparator1 = strInfo.indexOf(".", mdlSep);
653 String mdlId = (chainSeparator1 > -1)
654 ? strInfo.substring(mdlSep + 1, chainSeparator1)
655 : strInfo.substring(mdlSep + 1);
658 // recover PDB filename for the model hovered over.
659 int mnumber = Integer.valueOf(mdlId).intValue() - 1;
660 if (_modelFileNameMap != null)
662 int _mp = _modelFileNameMap.length - 1;
664 while (mnumber < _modelFileNameMap[_mp])
668 pdbfilename = modelFileNames[_mp];
672 if (mnumber >= 0 && mnumber < modelFileNames.length)
674 pdbfilename = modelFileNames[mnumber];
677 if (pdbfilename == null)
679 pdbfilename = new File(jmolViewer.ms.getModelFileName(mnumber))
683 } catch (Exception e)
689 * highlight position on alignment(s); if some text is returned,
690 * show this as a second line on the structure hover tooltip
692 String label = getSsm().mouseOverStructure(pdbResNum, chainId,
696 // change comma to pipe separator (newline token for Jmol)
697 label = label.replace(',', '|');
698 StringTokenizer toks = new StringTokenizer(strInfo, " ");
699 StringBuilder sb = new StringBuilder();
700 sb.append("select ").append(String.valueOf(pdbResNum)).append(":")
701 .append(chainId).append("/1");
702 sb.append(";set hoverLabel \"").append(toks.nextToken()).append(" ")
703 .append(toks.nextToken());
704 sb.append("|").append(label).append("\"");
705 executeCommand(sb.toString(), false);
709 public void notifyAtomHovered(int atomIndex, String strInfo, String data)
711 if (strInfo.equals(lastMessage))
715 lastMessage = strInfo;
718 System.err.println("Ignoring additional hover info: " + data
719 + " (other info: '" + strInfo + "' pos " + atomIndex + ")");
721 mouseOverStructure(atomIndex, strInfo);
725 * { if (history != null && strStatus != null &&
726 * !strStatus.equals("Script completed")) { history.append("\n" + strStatus);
730 public void notifyAtomPicked(int atomIndex, String strInfo,
734 * this implements the toggle label behaviour copied from the original
735 * structure viewer, MCView
739 System.err.println("Ignoring additional pick data string " + strData);
741 int chainSeparator = strInfo.indexOf(":");
743 if (chainSeparator == -1)
745 chainSeparator = strInfo.indexOf(".");
748 String picked = strInfo.substring(strInfo.indexOf("]") + 1,
750 String mdlString = "";
751 if ((p = strInfo.indexOf(":")) > -1)
753 picked += strInfo.substring(p, strInfo.indexOf("."));
756 if ((p = strInfo.indexOf("/")) > -1)
758 mdlString += strInfo.substring(p, strInfo.indexOf(" #"));
760 picked = "((" + picked + ".CA" + mdlString + ")|(" + picked + ".P"
764 if (!atomsPicked.contains(picked))
766 jmolViewer.evalStringQuiet("select " + picked + ";label %n %r:%c");
767 atomsPicked.addElement(picked);
771 jmolViewer.evalString("select " + picked + ";label off");
772 atomsPicked.removeElement(picked);
775 // TODO: in application this happens
777 // if (scriptWindow != null)
779 // scriptWindow.sendConsoleMessage(strInfo);
780 // scriptWindow.sendConsoleMessage("\n");
786 public void notifyCallback(CBK type, Object[] data)
793 notifyFileLoaded((String) data[1], (String) data[2],
794 (String) data[3], (String) data[4],
795 ((Integer) data[5]).intValue());
799 notifyAtomPicked(((Integer) data[2]).intValue(), (String) data[1],
801 // also highlight in alignment
802 // deliberate fall through
804 notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1],
808 notifyScriptTermination((String) data[2],
809 ((Integer) data[3]).intValue());
812 sendConsoleEcho((String) data[1]);
816 (data == null) ? ((String) null) : (String) data[1]);
819 // System.err.println("Ignoring error callback.");
830 "Unhandled callback " + type + " " + data[1].toString());
833 } catch (Exception e)
835 System.err.println("Squashed Jmol callback handler error:");
841 public boolean notifyEnabled(CBK callbackPick)
843 switch (callbackPick)
859 // incremented every time a load notification is successfully handled -
860 // lightweight mechanism for other threads to detect when they can start
861 // referrring to new structures.
862 private long loadNotifiesHandled = 0;
864 public long getLoadNotifiesHandled()
866 return loadNotifiesHandled;
869 public void notifyFileLoaded(String fullPathName, String fileName2,
870 String modelName, String errorMsg, int modelParts)
872 if (errorMsg != null)
874 fileLoadingError = errorMsg;
878 // TODO: deal sensibly with models loaded inLine:
879 // modelName will be null, as will fullPathName.
881 // the rest of this routine ignores the arguments, and simply interrogates
882 // the Jmol view to find out what structures it contains, and adds them to
883 // the structure selection manager.
884 fileLoadingError = null;
885 String[] oldmodels = modelFileNames;
886 modelFileNames = null;
887 boolean notifyLoaded = false;
888 String[] modelfilenames = getStructureFiles();
889 // first check if we've lost any structures
890 if (oldmodels != null && oldmodels.length > 0)
893 for (int i = 0; i < oldmodels.length; i++)
895 for (int n = 0; n < modelfilenames.length; n++)
897 if (modelfilenames[n] == oldmodels[i])
903 if (oldmodels[i] != null)
910 String[] oldmfn = new String[oldm];
912 for (int i = 0; i < oldmodels.length; i++)
914 if (oldmodels[i] != null)
916 oldmfn[oldm++] = oldmodels[i];
919 // deregister the Jmol instance for these structures - we'll add
920 // ourselves again at the end for the current structure set.
921 getSsm().removeStructureViewerListener(this, oldmfn);
925 for (int modelnum = 0; modelnum < modelfilenames.length; modelnum++)
927 String fileName = modelfilenames[modelnum];
928 boolean foundEntry = false;
929 StructureFile pdb = null;
930 String pdbfile = null;
931 // model was probably loaded inline - so check the pdb file hashcode
934 // calculate essential attributes for the pdb data imported inline.
935 // prolly need to resolve modelnumber properly - for now just use our
937 pdbfile = jmolViewer.getData(
938 "" + (1 + _modelFileNameMap[modelnum]) + ".0", "PDB");
940 // search pdbentries and sequences to find correct pdbentry for this
942 for (int pe = 0; pe < getPdbCount(); pe++)
944 boolean matches = false;
945 addSequence(pe, getSequence()[pe]);
946 if (fileName == null)
949 // see JAL-623 - need method of matching pasted data up
951 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
952 pdbfile, DataSourceType.PASTE,
953 getIProgressIndicator());
954 getPdbEntry(modelnum).setFile("INLINE" + pdb.getId());
961 File fl = new File(getPdbEntry(pe).getFile());
962 matches = fl.equals(new File(fileName));
966 // TODO: Jmol can in principle retrieve from CLASSLOADER but
969 // to be tested. See mantis bug
970 // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605
971 DataSourceType protocol = DataSourceType.URL;
976 protocol = DataSourceType.FILE;
978 } catch (Exception e)
983 // Explicitly map to the filename used by Jmol ;
984 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
985 fileName, protocol, getIProgressIndicator());
986 // pdbentry[pe].getFile(), protocol);
992 // add an entry for every chain in the model
993 for (int i = 0; i < pdb.getChains().size(); i++)
995 String chid = pdb.getId() + ":"
996 + pdb.getChains().elementAt(i).id;
997 addChainFile(chid, fileName);
998 getChainNames().add(chid);
1000 notifyLoaded = true;
1004 if (!foundEntry && associateNewStructs)
1006 // this is a foreign pdb file that jalview doesn't know about - add
1007 // it to the dataset and try to find a home - either on a matching
1008 // sequence or as a new sequence.
1009 String pdbcontent = jmolViewer.getData("/" + (modelnum + 1) + ".1",
1011 // parse pdb file into a chain, etc.
1012 // locate best match for pdb in associated views and add mapping to
1014 // if properly registered then
1015 notifyLoaded = true;
1020 // so finally, update the jmol bits and pieces
1021 // if (jmolpopup != null)
1023 // // potential for deadlock here:
1024 // // jmolpopup.updateComputedMenus();
1026 if (!isLoadingFromArchive())
1028 jmolViewer.evalStringQuiet(
1029 "model *; select backbone;restrict;cartoon;wireframe off;spacefill off");
1031 // register ourselves as a listener and notify the gui that it needs to
1033 getSsm().addStructureViewerListener(this);
1036 FeatureRenderer fr = getFeatureRenderer(null);
1042 loadNotifiesHandled++;
1044 setLoadingFromArchive(false);
1047 protected IProgressIndicator getIProgressIndicator()
1052 public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
1054 notifyAtomPicked(iatom, strMeasure, null);
1057 public abstract void notifyScriptTermination(String strStatus,
1061 * display a message echoed from the jmol viewer
1065 public abstract void sendConsoleEcho(String strEcho); /*
1066 * { showConsole(true);
1068 * history.append("\n" +
1072 // /End JmolStatusListener
1073 // /////////////////////////////
1077 * status message - usually the response received after a script
1080 public abstract void sendConsoleMessage(String strStatus);
1083 public void setCallbackFunction(String callbackType,
1084 String callbackFunction)
1086 System.err.println("Ignoring set-callback request to associate "
1087 + callbackType + " with function " + callbackFunction);
1091 public void showHelp()
1093 showUrl("http://jmol.sourceforge.net/docs/JmolUserGuide/", "jmolHelp");
1097 * open the URL somehow
1101 public abstract void showUrl(String url, String target);
1104 * called to show or hide the associated console window container.
1108 public abstract void showConsole(boolean show);
1111 * @param renderPanel
1113 * - when true will initialise jmol's file IO system (should be false
1114 * in applet context)
1116 * @param documentBase
1118 * @param commandOptions
1120 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1121 String htmlName, URL documentBase, URL codeBase,
1122 String commandOptions)
1124 allocateViewer(renderPanel, jmolfileio, htmlName, documentBase,
1125 codeBase, commandOptions, null, null);
1130 * @param renderPanel
1132 * - when true will initialise jmol's file IO system (should be false
1133 * in applet context)
1135 * @param documentBase
1137 * @param commandOptions
1138 * @param consolePanel
1139 * - panel to contain Jmol console
1140 * @param buttonsToShow
1141 * - buttons to show on the console, in ordr
1143 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1144 String htmlName, URL documentBase, URL codeBase,
1145 String commandOptions, final Container consolePanel,
1146 String buttonsToShow)
1148 if (commandOptions == null)
1150 commandOptions = "";
1152 jmolViewer = (Viewer) JmolViewer.allocateViewer(renderPanel,
1153 (jmolfileio ? new SmarterJmolAdapter() : null),
1154 htmlName + ((Object) this).toString(), documentBase, codeBase,
1155 commandOptions, this);
1157 jmolViewer.setJmolStatusListener(this); // extends JmolCallbackListener
1159 console = createJmolConsole(consolePanel, buttonsToShow);
1160 if (consolePanel != null)
1162 consolePanel.addComponentListener(this);
1168 protected abstract JmolAppConsoleInterface createJmolConsole(
1169 Container consolePanel, String buttonsToShow);
1171 protected org.jmol.api.JmolAppConsoleInterface console = null;
1174 public int[] resizeInnerPanel(String data)
1176 // Jalview doesn't honour resize panel requests
1183 protected void closeConsole()
1185 if (console != null)
1189 console.setVisible(false);
1192 } catch (Exception x)
1201 * ComponentListener method
1204 public void componentMoved(ComponentEvent e)
1209 * ComponentListener method
1212 public void componentResized(ComponentEvent e)
1217 * ComponentListener method
1220 public void componentShown(ComponentEvent e)
1226 * ComponentListener method
1229 public void componentHidden(ComponentEvent e)
1235 protected int getModelNoForFile(String pdbFile)
1237 if (modelFileNames == null)
1241 for (int i = 0; i < modelFileNames.length; i++)
1243 if (modelFileNames[i].equalsIgnoreCase(pdbFile))
1252 protected ViewerType getViewerType()
1254 return ViewerType.JMOL;