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 while (jmolViewer.isScriptExecuting())
185 } catch (InterruptedException i)
191 * get the distinct structure files modelled
192 * (a file with multiple chains may map to multiple sequences)
194 String[] files = getStructureFiles();
195 if (!waitForFileLoad(files))
200 StringBuilder selectioncom = new StringBuilder(256);
201 // In principle - nSeconds specifies the speed of animation for each
202 // superposition - but is seems to behave weirdly, so we don't specify it.
203 String nSeconds = " ";
204 if (files.length > 10)
206 nSeconds = " 0.005 ";
210 nSeconds = " " + (2.0 / files.length) + " ";
211 // if (nSeconds).substring(0,5)+" ";
214 // see JAL-1345 - should really automatically turn off the animation for
215 // large numbers of structures, but Jmol doesn't seem to allow that.
217 // union of all aligned positions are collected together.
218 for (int a = 0; a < _alignment.length; a++)
220 int refStructure = _refStructure[a];
221 AlignmentI alignment = _alignment[a];
222 HiddenColumns hiddenCols = _hiddenCols[a];
223 if (a > 0 && selectioncom.length() > 0 && !selectioncom
224 .substring(selectioncom.length() - 1).equals("|"))
226 selectioncom.append("|");
228 // process this alignment
229 if (refStructure >= files.length)
232 "Invalid reference structure value " + refStructure);
237 * 'matched' bit j will be set for visible alignment columns j where
238 * all sequences have a residue with a mapping to the PDB structure
240 BitSet matched = new BitSet();
241 for (int m = 0; m < alignment.getWidth(); m++)
243 if (hiddenCols == null || hiddenCols.isVisible(m))
249 SuperposeData[] structures = new SuperposeData[files.length];
250 for (int f = 0; f < files.length; f++)
252 structures[f] = new SuperposeData(alignment.getWidth(), f);
256 * Calculate the superposable alignment columns ('matched'), and the
257 * corresponding structure residue positions (structures.pdbResNo)
259 int candidateRefStructure = findSuperposableResidues(alignment,
260 matched, structures);
261 if (refStructure < 0)
264 * If no reference structure was specified, pick the first one that has
265 * a mapping in the alignment
267 refStructure = candidateRefStructure;
270 String[] selcom = new String[files.length];
271 int nmatched = matched.cardinality();
274 return (MessageManager.formatMessage("label.insufficient_residues",
279 * generate select statements to select regions to superimpose structures
282 // TODO extract method to construct selection statements
283 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
285 String chainCd = ":" + structures[pdbfnum].chain;
288 StringBuilder molsel = new StringBuilder();
291 int nextColumnMatch = matched.nextSetBit(0);
292 while (nextColumnMatch != -1)
294 int pdbResNo = structures[pdbfnum].pdbResNo[nextColumnMatch];
295 if (lpos != pdbResNo - 1)
301 molsel.append(chainCd);
308 // continuous run - and lpos >-1
311 // at the beginning, so add dash
318 nextColumnMatch = matched.nextSetBit(nextColumnMatch + 1);
321 * add final selection phrase
326 molsel.append(chainCd);
329 if (molsel.length() > 1)
331 selcom[pdbfnum] = molsel.toString();
332 selectioncom.append("((");
333 selectioncom.append(selcom[pdbfnum].substring(1,
334 selcom[pdbfnum].length() - 1));
335 selectioncom.append(" )& ");
336 selectioncom.append(pdbfnum + 1);
337 selectioncom.append(".1)");
338 if (pdbfnum < files.length - 1)
340 selectioncom.append("|");
345 selcom[pdbfnum] = null;
349 StringBuilder command = new StringBuilder(256);
350 // command.append("set spinFps 10;\n");
352 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
354 if (pdbfnum == refStructure || selcom[pdbfnum] == null
355 || selcom[refStructure] == null)
359 command.append("echo ");
360 command.append("\"Superposing (");
361 command.append(structures[pdbfnum].pdbId);
362 command.append(") against reference (");
363 command.append(structures[refStructure].pdbId);
364 command.append(")\";\ncompare " + nSeconds);
366 command.append(Integer.toString(1 + pdbfnum));
367 command.append(".1} {");
368 command.append(Integer.toString(1 + refStructure));
369 // conformation=1 excludes alternate locations for CA (JAL-1757)
371 ".1} SUBSET {(*.CA | *.P) and conformation=1} ATOMS ");
373 // for (int s = 0; s < 2; s++)
375 // command.append(selcom[(s == 0 ? pdbfnum : refStructure)]);
377 command.append(selcom[pdbfnum]);
378 command.append(selcom[refStructure]);
379 command.append(" ROTATE TRANSLATE;\n");
381 if (selectioncom.length() > 0)
383 String cmdString = command.toString();
384 executeCommand(cmdString, false);
387 if (selectioncom.length() > 0)
390 * finally, highlight with cartoons the residues that were superposed
392 if (selectioncom.charAt(selectioncom.length() - 1) == '|')
394 selectioncom.setLength(selectioncom.length() - 1);
396 executeCommand("select *; cartoons off; backbone; select ("
397 + selectioncom.toString() + "); cartoons; ", false);
404 public List<String> executeCommand(String command, boolean getReply)
411 if (lastCommand == null || !lastCommand.equals(command))
413 jmolViewer.evalStringQuiet(command + "\n");
416 lastCommand = command;
420 public void createImage(String file, String type, int quality)
422 System.out.println("JMOL CREATE IMAGE");
426 public String createImage(String fileName, String type,
427 Object textOrBytes, int quality)
429 System.out.println("JMOL CREATE IMAGE");
434 public String eval(String strEval)
436 // System.out.println(strEval);
437 // "# 'eval' is implemented only for the applet.";
441 // End StructureListener
442 // //////////////////////////
445 public float[][] functionXY(String functionName, int x, int y)
451 public float[][][] functionXYZ(String functionName, int nx, int ny,
454 // TODO Auto-generated method stub
459 * map between index of model filename returned from getPdbFile and the first
460 * index of models from this file in the viewer. Note - this is not trimmed -
461 * use getPdbFile to get number of unique models.
463 private int _modelFileNameMap[];
466 public synchronized String[] getStructureFiles()
468 List<String> mset = new ArrayList<>();
469 if (jmolViewer == null)
471 return new String[0];
474 if (modelFileNames == null)
476 int modelCount = jmolViewer.ms.mc;
477 String filePath = null;
478 for (int i = 0; i < modelCount; ++i)
480 filePath = jmolViewer.ms.getModelFileName(i);
481 if (!mset.contains(filePath))
486 modelFileNames = mset.toArray(new String[mset.size()]);
489 return modelFileNames;
493 * map from string to applet
496 public Map<String, Object> getRegistryInfo()
498 // TODO Auto-generated method stub
502 // ///////////////////////////////
503 // JmolStatusListener
505 public void handlePopupMenu(int x, int y)
507 // jmolpopup.show(x, y);
508 // jmolpopup.jpiShow(x, y);
512 * Highlight zero, one or more atoms on the structure
515 public void highlightAtoms(List<AtomSpec> atoms)
519 if (resetLastRes.length() > 0)
521 jmolViewer.evalStringQuiet(resetLastRes.toString());
522 resetLastRes.setLength(0);
524 for (AtomSpec atom : atoms)
526 highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(),
527 atom.getChain(), atom.getPdbFile());
533 public void highlightAtom(int atomIndex, int pdbResNum, String chain,
536 if (modelFileNames == null)
541 // look up file model number for this pdbfile
543 // may need to adjust for URLencoding here - we don't worry about that yet.
544 while (mdlNum < modelFileNames.length
545 && !pdbfile.equals(modelFileNames[mdlNum]))
549 if (mdlNum == modelFileNames.length)
556 StringBuilder cmd = new StringBuilder(64);
557 cmd.append("select ").append(String.valueOf(pdbResNum)); // +modelNum
559 resetLastRes.append("select ").append(String.valueOf(pdbResNum)); // +modelNum
562 resetLastRes.append(":");
563 if (!chain.equals(" "))
566 resetLastRes.append(chain);
569 cmd.append(" /").append(String.valueOf(mdlNum + 1));
570 resetLastRes.append("/").append(String.valueOf(mdlNum + 1));
572 cmd.append(";wireframe 100;" + cmd.toString() + " and not hetero;");
574 resetLastRes.append(";wireframe 0;" + resetLastRes.toString()
575 + " and not hetero; spacefill 0;");
577 cmd.append("spacefill 200;select none");
579 jmolViewer.evalStringQuiet(cmd.toString());
584 private boolean debug = true;
586 private void jmolHistory(boolean enable)
588 jmolViewer.evalStringQuiet("History " + ((debug || enable) ? "on" : "off"));
591 public void loadInline(String string)
595 // viewer.loadInline(strModel, isAppend);
597 // construct fake fullPathName and fileName so we can identify the file
599 // Then, construct pass a reader for the string to Jmol.
600 // ((org.jmol.Viewer.Viewer) viewer).loadModelFromFile(fullPathName,
601 // fileName, null, reader, false, null, null, 0);
602 jmolViewer.openStringInline(string);
605 protected void mouseOverStructure(int atomIndex, final String strInfo)
608 int alocsep = strInfo.indexOf("^");
609 int mdlSep = strInfo.indexOf("/");
610 int chainSeparator = strInfo.indexOf(":"), chainSeparator1 = -1;
612 if (chainSeparator == -1)
614 chainSeparator = strInfo.indexOf(".");
615 if (mdlSep > -1 && mdlSep < chainSeparator)
617 chainSeparator1 = chainSeparator;
618 chainSeparator = mdlSep;
621 // handle insertion codes
624 pdbResNum = Integer.parseInt(
625 strInfo.substring(strInfo.indexOf("]") + 1, alocsep));
630 pdbResNum = Integer.parseInt(
631 strInfo.substring(strInfo.indexOf("]") + 1, chainSeparator));
635 if (strInfo.indexOf(":") > -1)
637 chainId = strInfo.substring(strInfo.indexOf(":") + 1,
638 strInfo.indexOf("."));
645 String pdbfilename = modelFileNames[0]; // default is first model
648 if (chainSeparator1 == -1)
650 chainSeparator1 = strInfo.indexOf(".", mdlSep);
652 String mdlId = (chainSeparator1 > -1)
653 ? strInfo.substring(mdlSep + 1, chainSeparator1)
654 : strInfo.substring(mdlSep + 1);
657 // recover PDB filename for the model hovered over.
658 int mnumber = Integer.valueOf(mdlId).intValue() - 1;
659 if (_modelFileNameMap != null)
661 int _mp = _modelFileNameMap.length - 1;
663 while (mnumber < _modelFileNameMap[_mp])
667 pdbfilename = modelFileNames[_mp];
671 if (mnumber >= 0 && mnumber < modelFileNames.length)
673 pdbfilename = modelFileNames[mnumber];
676 if (pdbfilename == null)
678 pdbfilename = new File(jmolViewer.ms.getModelFileName(mnumber))
682 } catch (Exception e)
688 * highlight position on alignment(s); if some text is returned,
689 * show this as a second line on the structure hover tooltip
691 String label = getSsm().mouseOverStructure(pdbResNum, chainId,
695 // change comma to pipe separator (newline token for Jmol)
696 label = label.replace(',', '|');
697 StringTokenizer toks = new StringTokenizer(strInfo, " ");
698 StringBuilder sb = new StringBuilder();
699 sb.append("select ").append(String.valueOf(pdbResNum)).append(":")
700 .append(chainId).append("/1");
701 sb.append(";set hoverLabel \"").append(toks.nextToken()).append(" ")
702 .append(toks.nextToken());
703 sb.append("|").append(label).append("\"");
704 executeCommand(sb.toString(), false);
708 public void notifyAtomHovered(int atomIndex, String strInfo, String data)
710 if (strInfo.equals(lastMessage))
714 lastMessage = strInfo;
717 System.err.println("Ignoring additional hover info: " + data
718 + " (other info: '" + strInfo + "' pos " + atomIndex + ")");
720 mouseOverStructure(atomIndex, strInfo);
724 * { if (history != null && strStatus != null &&
725 * !strStatus.equals("Script completed")) { history.append("\n" + strStatus);
729 public void notifyAtomPicked(int atomIndex, String strInfo,
733 * this implements the toggle label behaviour copied from the original
734 * structure viewer, MCView
738 System.err.println("Ignoring additional pick data string " + strData);
740 int chainSeparator = strInfo.indexOf(":");
742 if (chainSeparator == -1)
744 chainSeparator = strInfo.indexOf(".");
747 String picked = strInfo.substring(strInfo.indexOf("]") + 1,
749 String mdlString = "";
750 if ((p = strInfo.indexOf(":")) > -1)
752 picked += strInfo.substring(p, strInfo.indexOf("."));
755 if ((p = strInfo.indexOf("/")) > -1)
757 mdlString += strInfo.substring(p, strInfo.indexOf(" #"));
759 picked = "((" + picked + ".CA" + mdlString + ")|(" + picked + ".P"
763 if (!atomsPicked.contains(picked))
765 jmolViewer.evalStringQuiet("select " + picked + ";label %n %r:%c");
766 atomsPicked.addElement(picked);
770 jmolViewer.evalString("select " + picked + ";label off");
771 atomsPicked.removeElement(picked);
774 // TODO: in application this happens
776 // if (scriptWindow != null)
778 // scriptWindow.sendConsoleMessage(strInfo);
779 // scriptWindow.sendConsoleMessage("\n");
785 public void notifyCallback(CBK type, Object[] data)
792 notifyFileLoaded((String) data[1], (String) data[2],
793 (String) data[3], (String) data[4],
794 ((Integer) data[5]).intValue());
798 notifyAtomPicked(((Integer) data[2]).intValue(), (String) data[1],
800 // also highlight in alignment
801 // deliberate fall through
803 notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1],
807 notifyScriptTermination((String) data[2],
808 ((Integer) data[3]).intValue());
811 sendConsoleEcho((String) data[1]);
815 (data == null) ? ((String) null) : (String) data[1]);
818 // System.err.println("Ignoring error callback.");
829 "Unhandled callback " + type + " " + data[1].toString());
832 } catch (Exception e)
834 System.err.println("Squashed Jmol callback handler error:");
840 public boolean notifyEnabled(CBK callbackPick)
842 switch (callbackPick)
858 // incremented every time a load notification is successfully handled -
859 // lightweight mechanism for other threads to detect when they can start
860 // referrring to new structures.
861 private long loadNotifiesHandled = 0;
863 public long getLoadNotifiesHandled()
865 return loadNotifiesHandled;
868 public void notifyFileLoaded(String fullPathName, String fileName2,
869 String modelName, String errorMsg, int modelParts)
871 if (errorMsg != null)
873 fileLoadingError = errorMsg;
877 // TODO: deal sensibly with models loaded inLine:
878 // modelName will be null, as will fullPathName.
880 // the rest of this routine ignores the arguments, and simply interrogates
881 // the Jmol view to find out what structures it contains, and adds them to
882 // the structure selection manager.
883 fileLoadingError = null;
884 String[] oldmodels = modelFileNames;
885 modelFileNames = null;
886 boolean notifyLoaded = false;
887 String[] modelfilenames = getStructureFiles();
888 // first check if we've lost any structures
889 if (oldmodels != null && oldmodels.length > 0)
892 for (int i = 0; i < oldmodels.length; i++)
894 for (int n = 0; n < modelfilenames.length; n++)
896 if (modelfilenames[n] == oldmodels[i])
902 if (oldmodels[i] != null)
909 String[] oldmfn = new String[oldm];
911 for (int i = 0; i < oldmodels.length; i++)
913 if (oldmodels[i] != null)
915 oldmfn[oldm++] = oldmodels[i];
918 // deregister the Jmol instance for these structures - we'll add
919 // ourselves again at the end for the current structure set.
920 getSsm().removeStructureViewerListener(this, oldmfn);
924 for (int modelnum = 0; modelnum < modelfilenames.length; modelnum++)
926 String fileName = modelfilenames[modelnum];
927 boolean foundEntry = false;
928 StructureFile pdb = null;
929 String pdbfile = null;
930 // model was probably loaded inline - so check the pdb file hashcode
933 // calculate essential attributes for the pdb data imported inline.
934 // prolly need to resolve modelnumber properly - for now just use our
936 pdbfile = jmolViewer.getData(
937 "" + (1 + _modelFileNameMap[modelnum]) + ".0", "PDB");
939 // search pdbentries and sequences to find correct pdbentry for this
941 for (int pe = 0; pe < getPdbCount(); pe++)
943 boolean matches = false;
944 addSequence(pe, getSequence()[pe]);
945 if (fileName == null)
948 // see JAL-623 - need method of matching pasted data up
950 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
951 pdbfile, DataSourceType.PASTE,
952 getIProgressIndicator());
953 getPdbEntry(modelnum).setFile("INLINE" + pdb.getId());
960 File fl = new File(getPdbEntry(pe).getFile());
961 matches = fl.equals(new File(fileName));
965 // TODO: Jmol can in principle retrieve from CLASSLOADER but
968 // to be tested. See mantis bug
969 // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605
970 DataSourceType protocol = DataSourceType.URL;
975 protocol = DataSourceType.FILE;
977 } catch (Exception e)
982 // Explicitly map to the filename used by Jmol ;
983 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
984 fileName, protocol, getIProgressIndicator());
985 // pdbentry[pe].getFile(), protocol);
991 // add an entry for every chain in the model
992 for (int i = 0; i < pdb.getChains().size(); i++)
994 String chid = pdb.getId() + ":"
995 + pdb.getChains().elementAt(i).id;
996 addChainFile(chid, fileName);
997 getChainNames().add(chid);
1003 if (!foundEntry && associateNewStructs)
1005 // this is a foreign pdb file that jalview doesn't know about - add
1006 // it to the dataset and try to find a home - either on a matching
1007 // sequence or as a new sequence.
1008 String pdbcontent = jmolViewer.getData("/" + (modelnum + 1) + ".1",
1010 // parse pdb file into a chain, etc.
1011 // locate best match for pdb in associated views and add mapping to
1013 // if properly registered then
1014 notifyLoaded = true;
1019 // so finally, update the jmol bits and pieces
1020 // if (jmolpopup != null)
1022 // // potential for deadlock here:
1023 // // jmolpopup.updateComputedMenus();
1025 if (!isLoadingFromArchive())
1027 jmolViewer.evalStringQuiet(
1028 "model *; select backbone;restrict;cartoon;wireframe off;spacefill off");
1030 // register ourselves as a listener and notify the gui that it needs to
1032 getSsm().addStructureViewerListener(this);
1035 FeatureRenderer fr = getFeatureRenderer(null);
1041 loadNotifiesHandled++;
1043 setLoadingFromArchive(false);
1046 protected IProgressIndicator getIProgressIndicator()
1051 public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
1053 notifyAtomPicked(iatom, strMeasure, null);
1056 public abstract void notifyScriptTermination(String strStatus,
1060 * display a message echoed from the jmol viewer
1064 public abstract void sendConsoleEcho(String strEcho); /*
1065 * { showConsole(true);
1067 * history.append("\n" +
1071 // /End JmolStatusListener
1072 // /////////////////////////////
1076 * status message - usually the response received after a script
1079 public abstract void sendConsoleMessage(String strStatus);
1082 public void setCallbackFunction(String callbackType,
1083 String callbackFunction)
1085 System.err.println("Ignoring set-callback request to associate "
1086 + callbackType + " with function " + callbackFunction);
1090 public void showHelp()
1092 showUrl("http://jmol.sourceforge.net/docs/JmolUserGuide/", "jmolHelp");
1096 * open the URL somehow
1100 public abstract void showUrl(String url, String target);
1103 * called to show or hide the associated console window container.
1107 public abstract void showConsole(boolean show);
1110 * @param renderPanel
1112 * - when true will initialise jmol's file IO system (should be false
1113 * in applet context)
1115 * @param documentBase
1117 * @param commandOptions
1119 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1120 String htmlName, URL documentBase, URL codeBase,
1121 String commandOptions)
1123 allocateViewer(renderPanel, jmolfileio, htmlName, documentBase,
1124 codeBase, commandOptions, null, null);
1129 * @param renderPanel
1131 * - when true will initialise jmol's file IO system (should be false
1132 * in applet context)
1134 * @param documentBase
1136 * @param commandOptions
1137 * @param consolePanel
1138 * - panel to contain Jmol console
1139 * @param buttonsToShow
1140 * - buttons to show on the console, in ordr
1142 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1143 String htmlName, URL documentBase, URL codeBase,
1144 String commandOptions, final Container consolePanel,
1145 String buttonsToShow)
1147 if (commandOptions == null)
1149 commandOptions = "";
1151 jmolViewer = (Viewer) JmolViewer.allocateViewer(renderPanel,
1152 (jmolfileio ? new SmarterJmolAdapter() : null),
1153 htmlName + ((Object) this).toString(), documentBase, codeBase,
1154 commandOptions, this);
1156 jmolViewer.setJmolStatusListener(this); // extends JmolCallbackListener
1158 console = createJmolConsole(consolePanel, buttonsToShow);
1159 if (consolePanel != null)
1161 consolePanel.addComponentListener(this);
1167 protected abstract JmolAppConsoleInterface createJmolConsole(
1168 Container consolePanel, String buttonsToShow);
1170 protected org.jmol.api.JmolAppConsoleInterface console = null;
1173 public int[] resizeInnerPanel(String data)
1175 // Jalview doesn't honour resize panel requests
1182 protected void closeConsole()
1184 if (console != null)
1188 console.setVisible(false);
1191 } catch (Exception x)
1200 * ComponentListener method
1203 public void componentMoved(ComponentEvent e)
1208 * ComponentListener method
1211 public void componentResized(ComponentEvent e)
1216 * ComponentListener method
1219 public void componentShown(ComponentEvent e)
1225 * ComponentListener method
1228 public void componentHidden(ComponentEvent e)
1234 protected int getModelNoForFile(String pdbFile)
1236 if (modelFileNames == null)
1240 for (int i = 0; i < modelFileNames.length; i++)
1242 if (modelFileNames[i].equalsIgnoreCase(pdbFile))
1251 protected ViewerType getViewerType()
1253 return ViewerType.JMOL;