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.io.DataSourceType;
30 import jalview.io.StructureFile;
31 import jalview.structure.AtomSpec;
32 import jalview.structure.StructureSelectionManager;
33 import jalview.structures.models.AAStructureBindingModel;
34 import jalview.util.MessageManager;
36 import java.awt.Container;
37 import java.awt.event.ComponentEvent;
38 import java.awt.event.ComponentListener;
41 import java.util.ArrayList;
42 import java.util.BitSet;
43 import java.util.List;
45 import java.util.StringTokenizer;
46 import java.util.Vector;
48 import org.jmol.adapter.smarter.SmarterJmolAdapter;
49 import org.jmol.api.JmolAppConsoleInterface;
50 import org.jmol.api.JmolSelectionListener;
51 import org.jmol.api.JmolStatusListener;
52 import org.jmol.api.JmolViewer;
53 import org.jmol.c.CBK;
54 import org.jmol.viewer.Viewer;
56 public abstract class JalviewJmolBinding extends AAStructureBindingModel
57 implements JmolStatusListener, JmolSelectionListener,
60 private String lastMessage;
63 * when true, try to search the associated datamodel for sequences that are
64 * associated with any unknown structures in the Jmol view.
66 private boolean associateNewStructs = false;
68 private Vector<String> atomsPicked = new Vector<>();
70 private String lastCommand;
72 private boolean loadedInline;
74 private StringBuffer resetLastRes = new StringBuffer();
76 public Viewer jmolViewer;
78 public JalviewJmolBinding(StructureSelectionManager ssm,
79 PDBEntry[] pdbentry, SequenceI[][] sequenceIs,
80 DataSourceType protocol)
82 super(ssm, pdbentry, sequenceIs, protocol);
83 setStructureCommands(new JmolCommands());
85 * viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter(),
86 * "jalviewJmol", ap.av.applet .getDocumentBase(),
87 * ap.av.applet.getCodeBase(), "", this);
89 * jmolpopup = JmolPopup.newJmolPopup(viewer, true, "Jmol", true);
93 public JalviewJmolBinding(StructureSelectionManager ssm,
94 SequenceI[][] seqs, Viewer theViewer)
98 jmolViewer = theViewer;
99 jmolViewer.setJmolStatusListener(this);
100 jmolViewer.addSelectionListener(this);
101 setStructureCommands(new JmolCommands());
105 * construct a title string for the viewer window based on the data jalview
110 public String getViewerTitle()
112 return getViewerTitle("Jmol", true);
115 public void closeViewer()
117 // remove listeners for all structures in viewer
118 getSsm().removeStructureViewerListener(this, this.getStructureFiles());
119 jmolViewer.dispose();
122 releaseUIResources();
126 * superpose the structures associated with sequences in the alignment
127 * according to their corresponding positions.
129 * @deprecated not used - remove?
132 public void superposeStructures(AlignmentI alignment)
134 superposeStructures(alignment, -1, null);
138 * superpose the structures associated with sequences in the alignment
139 * according to their corresponding positions. ded)
141 * @param refStructure
142 * - select which pdb file to use as reference (default is -1 - the
143 * first structure in the alignment)
144 * @deprecated not used - remove?
147 public void superposeStructures(AlignmentI alignment, int refStructure)
149 superposeStructures(alignment, refStructure, null);
153 * superpose the structures associated with sequences in the alignment
154 * according to their corresponding positions. ded)
156 * @param refStructure
157 * - select which pdb file to use as reference (default is -1 - the
158 * first structure in the alignment)
161 * @deprecated not used - remove?
164 public void superposeStructures(AlignmentI alignment, int refStructure,
165 HiddenColumns hiddenCols)
167 superposeStructures(new AlignmentI[] { alignment },
169 { refStructure }, new HiddenColumns[] { hiddenCols });
176 public String superposeStructures(AlignmentI[] _alignment,
177 int[] _refStructure, HiddenColumns[] _hiddenCols)
179 while (jmolViewer.isScriptExecuting())
184 } catch (InterruptedException i)
190 * get the distinct structure files modelled
191 * (a file with multiple chains may map to multiple sequences)
193 String[] files = getStructureFiles();
194 if (!waitForFileLoad(files))
199 StringBuilder selectioncom = new StringBuilder(256);
200 // In principle - nSeconds specifies the speed of animation for each
201 // superposition - but is seems to behave weirdly, so we don't specify it.
202 String nSeconds = " ";
203 if (files.length > 10)
205 nSeconds = " 0.005 ";
209 nSeconds = " " + (2.0 / files.length) + " ";
210 // if (nSeconds).substring(0,5)+" ";
213 // see JAL-1345 - should really automatically turn off the animation for
214 // large numbers of structures, but Jmol doesn't seem to allow that.
216 // union of all aligned positions are collected together.
217 for (int a = 0; a < _alignment.length; a++)
219 int refStructure = _refStructure[a];
220 AlignmentI alignment = _alignment[a];
221 HiddenColumns hiddenCols = _hiddenCols[a];
222 if (a > 0 && selectioncom.length() > 0 && !selectioncom
223 .substring(selectioncom.length() - 1).equals("|"))
225 selectioncom.append("|");
227 // process this alignment
228 if (refStructure >= files.length)
231 "Invalid reference structure value " + refStructure);
236 * 'matched' bit j will be set for visible alignment columns j where
237 * all sequences have a residue with a mapping to the PDB structure
239 BitSet matched = new BitSet();
240 for (int m = 0; m < alignment.getWidth(); m++)
242 if (hiddenCols == null || hiddenCols.isVisible(m))
248 SuperposeData[] structures = new SuperposeData[files.length];
249 for (int f = 0; f < files.length; f++)
251 structures[f] = new SuperposeData(alignment.getWidth());
255 * Calculate the superposable alignment columns ('matched'), and the
256 * corresponding structure residue positions (structures.pdbResNo)
258 int candidateRefStructure = findSuperposableResidues(alignment,
259 matched, structures);
260 if (refStructure < 0)
263 * If no reference structure was specified, pick the first one that has
264 * a mapping in the alignment
266 refStructure = candidateRefStructure;
269 String[] selcom = new String[files.length];
270 int nmatched = matched.cardinality();
273 return (MessageManager.formatMessage("label.insufficient_residues",
278 * generate select statements to select regions to superimpose structures
281 // TODO extract method to construct selection statements
282 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
284 String chainCd = ":" + structures[pdbfnum].chain;
287 StringBuilder molsel = new StringBuilder();
290 int nextColumnMatch = matched.nextSetBit(0);
291 while (nextColumnMatch != -1)
293 int pdbResNo = structures[pdbfnum].pdbResNo[nextColumnMatch];
294 if (lpos != pdbResNo - 1)
300 molsel.append(chainCd);
307 // continuous run - and lpos >-1
310 // at the beginning, so add dash
317 nextColumnMatch = matched.nextSetBit(nextColumnMatch + 1);
320 * add final selection phrase
325 molsel.append(chainCd);
328 if (molsel.length() > 1)
330 selcom[pdbfnum] = molsel.toString();
331 selectioncom.append("((");
332 selectioncom.append(selcom[pdbfnum].substring(1,
333 selcom[pdbfnum].length() - 1));
334 selectioncom.append(" )& ");
335 selectioncom.append(pdbfnum + 1);
336 selectioncom.append(".1)");
337 if (pdbfnum < files.length - 1)
339 selectioncom.append("|");
344 selcom[pdbfnum] = null;
348 StringBuilder command = new StringBuilder(256);
349 // command.append("set spinFps 10;\n");
351 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
353 if (pdbfnum == refStructure || selcom[pdbfnum] == null
354 || selcom[refStructure] == null)
358 command.append("echo ");
359 command.append("\"Superposing (");
360 command.append(structures[pdbfnum].pdbId);
361 command.append(") against reference (");
362 command.append(structures[refStructure].pdbId);
363 command.append(")\";\ncompare " + nSeconds);
365 command.append(Integer.toString(1 + pdbfnum));
366 command.append(".1} {");
367 command.append(Integer.toString(1 + refStructure));
368 // conformation=1 excludes alternate locations for CA (JAL-1757)
370 ".1} SUBSET {(*.CA | *.P) and conformation=1} ATOMS ");
372 // for (int s = 0; s < 2; s++)
374 // command.append(selcom[(s == 0 ? pdbfnum : refStructure)]);
376 command.append(selcom[pdbfnum]);
377 command.append(selcom[refStructure]);
378 command.append(" ROTATE TRANSLATE;\n");
380 if (selectioncom.length() > 0)
382 String cmdString = command.toString();
383 executeCommand(cmdString, false);
386 if (selectioncom.length() > 0)
389 * finally, highlight with cartoons the residues that were superposed
391 if (selectioncom.charAt(selectioncom.length() - 1) == '|')
393 selectioncom.setLength(selectioncom.length() - 1);
395 executeCommand("select *; cartoons off; backbone; select ("
396 + selectioncom.toString() + "); cartoons; ", false);
403 public List<String> executeCommand(String command, boolean getReply)
410 if (lastCommand == null || !lastCommand.equals(command))
412 jmolViewer.evalStringQuiet(command + "\n");
415 lastCommand = command;
419 public void createImage(String file, String type, int quality)
421 System.out.println("JMOL CREATE IMAGE");
425 public String createImage(String fileName, String type,
426 Object textOrBytes, int quality)
428 System.out.println("JMOL CREATE IMAGE");
433 public String eval(String strEval)
435 // System.out.println(strEval);
436 // "# 'eval' is implemented only for the applet.";
440 // End StructureListener
441 // //////////////////////////
444 public float[][] functionXY(String functionName, int x, int y)
450 public float[][][] functionXYZ(String functionName, int nx, int ny,
453 // TODO Auto-generated method stub
458 * map between index of model filename returned from getPdbFile and the first
459 * index of models from this file in the viewer. Note - this is not trimmed -
460 * use getPdbFile to get number of unique models.
462 private int _modelFileNameMap[];
465 public synchronized String[] getStructureFiles()
467 List<String> mset = new ArrayList<>();
468 if (jmolViewer == null)
470 return new String[0];
473 if (modelFileNames == null)
475 int modelCount = jmolViewer.ms.mc;
476 String filePath = null;
477 for (int i = 0; i < modelCount; ++i)
479 filePath = jmolViewer.ms.getModelFileName(i);
480 if (!mset.contains(filePath))
485 modelFileNames = mset.toArray(new String[mset.size()]);
488 return modelFileNames;
492 * map from string to applet
495 public Map<String, Object> getRegistryInfo()
497 // TODO Auto-generated method stub
501 // ///////////////////////////////
502 // JmolStatusListener
504 public void handlePopupMenu(int x, int y)
506 // jmolpopup.show(x, y);
507 // jmolpopup.jpiShow(x, y);
511 * Highlight zero, one or more atoms on the structure
514 public void highlightAtoms(List<AtomSpec> atoms)
518 if (resetLastRes.length() > 0)
520 jmolViewer.evalStringQuiet(resetLastRes.toString());
521 resetLastRes.setLength(0);
523 for (AtomSpec atom : atoms)
525 highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(),
526 atom.getChain(), atom.getPdbFile());
532 public void highlightAtom(int atomIndex, int pdbResNum, String chain,
535 if (modelFileNames == null)
540 // look up file model number for this pdbfile
542 // may need to adjust for URLencoding here - we don't worry about that yet.
543 while (mdlNum < modelFileNames.length
544 && !pdbfile.equals(modelFileNames[mdlNum]))
548 if (mdlNum == modelFileNames.length)
555 StringBuilder cmd = new StringBuilder(64);
556 cmd.append("select ").append(String.valueOf(pdbResNum)); // +modelNum
558 resetLastRes.append("select ").append(String.valueOf(pdbResNum)); // +modelNum
561 resetLastRes.append(":");
562 if (!chain.equals(" "))
565 resetLastRes.append(chain);
568 cmd.append(" /").append(String.valueOf(mdlNum + 1));
569 resetLastRes.append("/").append(String.valueOf(mdlNum + 1));
571 cmd.append(";wireframe 100;" + cmd.toString() + " and not hetero;");
573 resetLastRes.append(";wireframe 0;" + resetLastRes.toString()
574 + " and not hetero; spacefill 0;");
576 cmd.append("spacefill 200;select none");
578 jmolViewer.evalStringQuiet(cmd.toString());
583 private boolean debug = true;
585 private void jmolHistory(boolean enable)
587 jmolViewer.evalStringQuiet("History " + ((debug || enable) ? "on" : "off"));
590 public void loadInline(String string)
594 // viewer.loadInline(strModel, isAppend);
596 // construct fake fullPathName and fileName so we can identify the file
598 // Then, construct pass a reader for the string to Jmol.
599 // ((org.jmol.Viewer.Viewer) viewer).loadModelFromFile(fullPathName,
600 // fileName, null, reader, false, null, null, 0);
601 jmolViewer.openStringInline(string);
604 protected void mouseOverStructure(int atomIndex, final String strInfo)
607 int alocsep = strInfo.indexOf("^");
608 int mdlSep = strInfo.indexOf("/");
609 int chainSeparator = strInfo.indexOf(":"), chainSeparator1 = -1;
611 if (chainSeparator == -1)
613 chainSeparator = strInfo.indexOf(".");
614 if (mdlSep > -1 && mdlSep < chainSeparator)
616 chainSeparator1 = chainSeparator;
617 chainSeparator = mdlSep;
620 // handle insertion codes
623 pdbResNum = Integer.parseInt(
624 strInfo.substring(strInfo.indexOf("]") + 1, alocsep));
629 pdbResNum = Integer.parseInt(
630 strInfo.substring(strInfo.indexOf("]") + 1, chainSeparator));
634 if (strInfo.indexOf(":") > -1)
636 chainId = strInfo.substring(strInfo.indexOf(":") + 1,
637 strInfo.indexOf("."));
644 String pdbfilename = modelFileNames[0]; // default is first model
647 if (chainSeparator1 == -1)
649 chainSeparator1 = strInfo.indexOf(".", mdlSep);
651 String mdlId = (chainSeparator1 > -1)
652 ? strInfo.substring(mdlSep + 1, chainSeparator1)
653 : strInfo.substring(mdlSep + 1);
656 // recover PDB filename for the model hovered over.
657 int mnumber = Integer.valueOf(mdlId).intValue() - 1;
658 if (_modelFileNameMap != null)
660 int _mp = _modelFileNameMap.length - 1;
662 while (mnumber < _modelFileNameMap[_mp])
666 pdbfilename = modelFileNames[_mp];
670 if (mnumber >= 0 && mnumber < modelFileNames.length)
672 pdbfilename = modelFileNames[mnumber];
675 if (pdbfilename == null)
677 pdbfilename = new File(jmolViewer.ms.getModelFileName(mnumber))
681 } catch (Exception e)
687 * highlight position on alignment(s); if some text is returned,
688 * show this as a second line on the structure hover tooltip
690 String label = getSsm().mouseOverStructure(pdbResNum, chainId,
694 // change comma to pipe separator (newline token for Jmol)
695 label = label.replace(',', '|');
696 StringTokenizer toks = new StringTokenizer(strInfo, " ");
697 StringBuilder sb = new StringBuilder();
698 sb.append("select ").append(String.valueOf(pdbResNum)).append(":")
699 .append(chainId).append("/1");
700 sb.append(";set hoverLabel \"").append(toks.nextToken()).append(" ")
701 .append(toks.nextToken());
702 sb.append("|").append(label).append("\"");
703 executeCommand(sb.toString(), false);
707 public void notifyAtomHovered(int atomIndex, String strInfo, String data)
709 if (strInfo.equals(lastMessage))
713 lastMessage = strInfo;
716 System.err.println("Ignoring additional hover info: " + data
717 + " (other info: '" + strInfo + "' pos " + atomIndex + ")");
719 mouseOverStructure(atomIndex, strInfo);
723 * { if (history != null && strStatus != null &&
724 * !strStatus.equals("Script completed")) { history.append("\n" + strStatus);
728 public void notifyAtomPicked(int atomIndex, String strInfo,
732 * this implements the toggle label behaviour copied from the original
733 * structure viewer, MCView
737 System.err.println("Ignoring additional pick data string " + strData);
739 int chainSeparator = strInfo.indexOf(":");
741 if (chainSeparator == -1)
743 chainSeparator = strInfo.indexOf(".");
746 String picked = strInfo.substring(strInfo.indexOf("]") + 1,
748 String mdlString = "";
749 if ((p = strInfo.indexOf(":")) > -1)
751 picked += strInfo.substring(p, strInfo.indexOf("."));
754 if ((p = strInfo.indexOf("/")) > -1)
756 mdlString += strInfo.substring(p, strInfo.indexOf(" #"));
758 picked = "((" + picked + ".CA" + mdlString + ")|(" + picked + ".P"
762 if (!atomsPicked.contains(picked))
764 jmolViewer.evalStringQuiet("select " + picked + ";label %n %r:%c");
765 atomsPicked.addElement(picked);
769 jmolViewer.evalString("select " + picked + ";label off");
770 atomsPicked.removeElement(picked);
773 // TODO: in application this happens
775 // if (scriptWindow != null)
777 // scriptWindow.sendConsoleMessage(strInfo);
778 // scriptWindow.sendConsoleMessage("\n");
784 public void notifyCallback(CBK type, Object[] data)
791 notifyFileLoaded((String) data[1], (String) data[2],
792 (String) data[3], (String) data[4],
793 ((Integer) data[5]).intValue());
797 notifyAtomPicked(((Integer) data[2]).intValue(), (String) data[1],
799 // also highlight in alignment
800 // deliberate fall through
802 notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1],
806 notifyScriptTermination((String) data[2],
807 ((Integer) data[3]).intValue());
810 sendConsoleEcho((String) data[1]);
814 (data == null) ? ((String) null) : (String) data[1]);
817 // System.err.println("Ignoring error callback.");
828 "Unhandled callback " + type + " " + data[1].toString());
831 } catch (Exception e)
833 System.err.println("Squashed Jmol callback handler error:");
839 public boolean notifyEnabled(CBK callbackPick)
841 switch (callbackPick)
857 // incremented every time a load notification is successfully handled -
858 // lightweight mechanism for other threads to detect when they can start
859 // referrring to new structures.
860 private long loadNotifiesHandled = 0;
862 public long getLoadNotifiesHandled()
864 return loadNotifiesHandled;
867 public void notifyFileLoaded(String fullPathName, String fileName2,
868 String modelName, String errorMsg, int modelParts)
870 if (errorMsg != null)
872 fileLoadingError = errorMsg;
876 // TODO: deal sensibly with models loaded inLine:
877 // modelName will be null, as will fullPathName.
879 // the rest of this routine ignores the arguments, and simply interrogates
880 // the Jmol view to find out what structures it contains, and adds them to
881 // the structure selection manager.
882 fileLoadingError = null;
883 String[] oldmodels = modelFileNames;
884 modelFileNames = null;
885 boolean notifyLoaded = false;
886 String[] modelfilenames = getStructureFiles();
887 // first check if we've lost any structures
888 if (oldmodels != null && oldmodels.length > 0)
891 for (int i = 0; i < oldmodels.length; i++)
893 for (int n = 0; n < modelfilenames.length; n++)
895 if (modelfilenames[n] == oldmodels[i])
901 if (oldmodels[i] != null)
908 String[] oldmfn = new String[oldm];
910 for (int i = 0; i < oldmodels.length; i++)
912 if (oldmodels[i] != null)
914 oldmfn[oldm++] = oldmodels[i];
917 // deregister the Jmol instance for these structures - we'll add
918 // ourselves again at the end for the current structure set.
919 getSsm().removeStructureViewerListener(this, oldmfn);
923 for (int modelnum = 0; modelnum < modelfilenames.length; modelnum++)
925 String fileName = modelfilenames[modelnum];
926 boolean foundEntry = false;
927 StructureFile pdb = null;
928 String pdbfile = null;
929 // model was probably loaded inline - so check the pdb file hashcode
932 // calculate essential attributes for the pdb data imported inline.
933 // prolly need to resolve modelnumber properly - for now just use our
935 pdbfile = jmolViewer.getData(
936 "" + (1 + _modelFileNameMap[modelnum]) + ".0", "PDB");
938 // search pdbentries and sequences to find correct pdbentry for this
940 for (int pe = 0; pe < getPdbCount(); pe++)
942 boolean matches = false;
943 addSequence(pe, getSequence()[pe]);
944 if (fileName == null)
947 // see JAL-623 - need method of matching pasted data up
949 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
950 pdbfile, DataSourceType.PASTE,
951 getIProgressIndicator());
952 getPdbEntry(modelnum).setFile("INLINE" + pdb.getId());
959 File fl = new File(getPdbEntry(pe).getFile());
960 matches = fl.equals(new File(fileName));
964 // TODO: Jmol can in principle retrieve from CLASSLOADER but
967 // to be tested. See mantis bug
968 // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605
969 DataSourceType protocol = DataSourceType.URL;
974 protocol = DataSourceType.FILE;
976 } catch (Exception e)
981 // Explicitly map to the filename used by Jmol ;
982 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
983 fileName, protocol, getIProgressIndicator());
984 // pdbentry[pe].getFile(), protocol);
990 // add an entry for every chain in the model
991 for (int i = 0; i < pdb.getChains().size(); i++)
993 String chid = pdb.getId() + ":"
994 + pdb.getChains().elementAt(i).id;
995 addChainFile(chid, fileName);
996 getChainNames().add(chid);
1002 if (!foundEntry && associateNewStructs)
1004 // this is a foreign pdb file that jalview doesn't know about - add
1005 // it to the dataset and try to find a home - either on a matching
1006 // sequence or as a new sequence.
1007 String pdbcontent = jmolViewer.getData("/" + (modelnum + 1) + ".1",
1009 // parse pdb file into a chain, etc.
1010 // locate best match for pdb in associated views and add mapping to
1012 // if properly registered then
1013 notifyLoaded = true;
1018 // so finally, update the jmol bits and pieces
1019 // if (jmolpopup != null)
1021 // // potential for deadlock here:
1022 // // jmolpopup.updateComputedMenus();
1024 if (!isLoadingFromArchive())
1026 jmolViewer.evalStringQuiet(
1027 "model *; select backbone;restrict;cartoon;wireframe off;spacefill off");
1029 // register ourselves as a listener and notify the gui that it needs to
1031 getSsm().addStructureViewerListener(this);
1034 FeatureRenderer fr = getFeatureRenderer(null);
1040 loadNotifiesHandled++;
1042 setLoadingFromArchive(false);
1045 protected IProgressIndicator getIProgressIndicator()
1050 public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
1052 notifyAtomPicked(iatom, strMeasure, null);
1055 public abstract void notifyScriptTermination(String strStatus,
1059 * display a message echoed from the jmol viewer
1063 public abstract void sendConsoleEcho(String strEcho); /*
1064 * { showConsole(true);
1066 * history.append("\n" +
1070 // /End JmolStatusListener
1071 // /////////////////////////////
1075 * status message - usually the response received after a script
1078 public abstract void sendConsoleMessage(String strStatus);
1081 public void setCallbackFunction(String callbackType,
1082 String callbackFunction)
1084 System.err.println("Ignoring set-callback request to associate "
1085 + callbackType + " with function " + callbackFunction);
1089 public void showHelp()
1091 showUrl("http://jmol.sourceforge.net/docs/JmolUserGuide/", "jmolHelp");
1095 * open the URL somehow
1099 public abstract void showUrl(String url, String target);
1102 * called to show or hide the associated console window container.
1106 public abstract void showConsole(boolean show);
1109 * @param renderPanel
1111 * - when true will initialise jmol's file IO system (should be false
1112 * in applet context)
1114 * @param documentBase
1116 * @param commandOptions
1118 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1119 String htmlName, URL documentBase, URL codeBase,
1120 String commandOptions)
1122 allocateViewer(renderPanel, jmolfileio, htmlName, documentBase,
1123 codeBase, commandOptions, null, null);
1128 * @param renderPanel
1130 * - when true will initialise jmol's file IO system (should be false
1131 * in applet context)
1133 * @param documentBase
1135 * @param commandOptions
1136 * @param consolePanel
1137 * - panel to contain Jmol console
1138 * @param buttonsToShow
1139 * - buttons to show on the console, in ordr
1141 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1142 String htmlName, URL documentBase, URL codeBase,
1143 String commandOptions, final Container consolePanel,
1144 String buttonsToShow)
1146 if (commandOptions == null)
1148 commandOptions = "";
1150 jmolViewer = (Viewer) JmolViewer.allocateViewer(renderPanel,
1151 (jmolfileio ? new SmarterJmolAdapter() : null),
1152 htmlName + ((Object) this).toString(), documentBase, codeBase,
1153 commandOptions, this);
1155 jmolViewer.setJmolStatusListener(this); // extends JmolCallbackListener
1157 console = createJmolConsole(consolePanel, buttonsToShow);
1158 if (consolePanel != null)
1160 consolePanel.addComponentListener(this);
1166 protected abstract JmolAppConsoleInterface createJmolConsole(
1167 Container consolePanel, String buttonsToShow);
1169 protected org.jmol.api.JmolAppConsoleInterface console = null;
1172 public int[] resizeInnerPanel(String data)
1174 // Jalview doesn't honour resize panel requests
1181 protected void closeConsole()
1183 if (console != null)
1187 console.setVisible(false);
1190 } catch (Exception x)
1199 * ComponentListener method
1202 public void componentMoved(ComponentEvent e)
1207 * ComponentListener method
1210 public void componentResized(ComponentEvent e)
1215 * ComponentListener method
1218 public void componentShown(ComponentEvent e)
1224 * ComponentListener method
1227 public void componentHidden(ComponentEvent e)
1233 protected int getModelNoForFile(String pdbFile)
1235 if (modelFileNames == null)
1239 for (int i = 0; i < modelFileNames.length; i++)
1241 if (modelFileNames[i].equalsIgnoreCase(pdbFile))