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;
62 boolean allChainsSelected = false;
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 Vector<String> atomsPicked = new Vector<>();
73 * the default or current model displayed if the model cannot be identified
74 * from the selection message
78 // protected JmolGenericPopup jmolpopup; // not used - remove?
84 StringBuffer resetLastRes = new StringBuffer();
86 public Viewer jmolViewer;
88 public JalviewJmolBinding(StructureSelectionManager ssm,
89 PDBEntry[] pdbentry, SequenceI[][] sequenceIs,
90 DataSourceType protocol)
92 super(ssm, pdbentry, sequenceIs, protocol);
93 setStructureCommands(new JmolCommands());
95 * viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter(),
96 * "jalviewJmol", ap.av.applet .getDocumentBase(),
97 * ap.av.applet.getCodeBase(), "", this);
99 * jmolpopup = JmolPopup.newJmolPopup(viewer, true, "Jmol", true);
103 public JalviewJmolBinding(StructureSelectionManager ssm,
104 SequenceI[][] seqs, Viewer theViewer)
108 jmolViewer = theViewer;
109 jmolViewer.setJmolStatusListener(this);
110 jmolViewer.addSelectionListener(this);
111 setStructureCommands(new JmolCommands());
115 * construct a title string for the viewer window based on the data jalview
120 public String getViewerTitle()
122 return getViewerTitle("Jmol", true);
125 public void closeViewer()
127 // remove listeners for all structures in viewer
128 getSsm().removeStructureViewerListener(this, this.getStructureFiles());
129 jmolViewer.dispose();
132 releaseUIResources();
136 * superpose the structures associated with sequences in the alignment
137 * according to their corresponding positions.
139 public void superposeStructures(AlignmentI alignment)
141 superposeStructures(alignment, -1, null);
145 * superpose the structures associated with sequences in the alignment
146 * according to their corresponding positions. ded)
148 * @param refStructure
149 * - select which pdb file to use as reference (default is -1 - the
150 * first structure in the alignment)
152 public void superposeStructures(AlignmentI alignment, int refStructure)
154 superposeStructures(alignment, refStructure, null);
158 * superpose the structures associated with sequences in the alignment
159 * according to their corresponding positions. ded)
161 * @param refStructure
162 * - select which pdb file to use as reference (default is -1 - the
163 * first structure in the alignment)
167 public void superposeStructures(AlignmentI alignment, int refStructure,
168 HiddenColumns hiddenCols)
170 superposeStructures(new AlignmentI[] { alignment },
172 { refStructure }, new HiddenColumns[] { hiddenCols });
179 public String superposeStructures(AlignmentI[] _alignment,
180 int[] _refStructure, HiddenColumns[] _hiddenCols)
182 while (jmolViewer.isScriptExecuting())
187 } catch (InterruptedException i)
193 * get the distinct structure files modelled
194 * (a file with multiple chains may map to multiple sequences)
196 String[] files = getStructureFiles();
197 if (!waitForFileLoad(files))
202 StringBuilder selectioncom = new StringBuilder(256);
203 // In principle - nSeconds specifies the speed of animation for each
204 // superposition - but is seems to behave weirdly, so we don't specify it.
205 String nSeconds = " ";
206 if (files.length > 10)
208 nSeconds = " 0.005 ";
212 nSeconds = " " + (2.0 / files.length) + " ";
213 // if (nSeconds).substring(0,5)+" ";
216 // see JAL-1345 - should really automatically turn off the animation for
217 // large numbers of structures, but Jmol doesn't seem to allow that.
219 // union of all aligned positions are collected together.
220 for (int a = 0; a < _alignment.length; a++)
222 int refStructure = _refStructure[a];
223 AlignmentI alignment = _alignment[a];
224 HiddenColumns hiddenCols = _hiddenCols[a];
225 if (a > 0 && selectioncom.length() > 0 && !selectioncom
226 .substring(selectioncom.length() - 1).equals("|"))
228 selectioncom.append("|");
230 // process this alignment
231 if (refStructure >= files.length)
234 "Invalid reference structure value " + refStructure);
239 * 'matched' bit j will be set for visible alignment columns j where
240 * all sequences have a residue with a mapping to the PDB structure
242 BitSet matched = new BitSet();
243 for (int m = 0; m < alignment.getWidth(); m++)
245 if (hiddenCols == null || hiddenCols.isVisible(m))
251 SuperposeData[] structures = new SuperposeData[files.length];
252 for (int f = 0; f < files.length; f++)
254 structures[f] = new SuperposeData(alignment.getWidth());
258 * Calculate the superposable alignment columns ('matched'), and the
259 * corresponding structure residue positions (structures.pdbResNo)
261 int candidateRefStructure = findSuperposableResidues(alignment,
262 matched, structures);
263 if (refStructure < 0)
266 * If no reference structure was specified, pick the first one that has
267 * a mapping in the alignment
269 refStructure = candidateRefStructure;
272 String[] selcom = new String[files.length];
273 int nmatched = matched.cardinality();
276 return (MessageManager.formatMessage("label.insufficient_residues",
281 * generate select statements to select regions to superimpose structures
284 // TODO extract method to construct selection statements
285 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
287 String chainCd = ":" + structures[pdbfnum].chain;
290 StringBuilder molsel = new StringBuilder();
293 int nextColumnMatch = matched.nextSetBit(0);
294 while (nextColumnMatch != -1)
296 int pdbResNo = structures[pdbfnum].pdbResNo[nextColumnMatch];
297 if (lpos != pdbResNo - 1)
303 molsel.append(chainCd);
310 // continuous run - and lpos >-1
313 // at the beginning, so add dash
320 nextColumnMatch = matched.nextSetBit(nextColumnMatch + 1);
323 * add final selection phrase
328 molsel.append(chainCd);
331 if (molsel.length() > 1)
333 selcom[pdbfnum] = molsel.toString();
334 selectioncom.append("((");
335 selectioncom.append(selcom[pdbfnum].substring(1,
336 selcom[pdbfnum].length() - 1));
337 selectioncom.append(" )& ");
338 selectioncom.append(pdbfnum + 1);
339 selectioncom.append(".1)");
340 if (pdbfnum < files.length - 1)
342 selectioncom.append("|");
347 selcom[pdbfnum] = null;
351 StringBuilder command = new StringBuilder(256);
352 // command.append("set spinFps 10;\n");
354 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
356 if (pdbfnum == refStructure || selcom[pdbfnum] == null
357 || selcom[refStructure] == null)
361 command.append("echo ");
362 command.append("\"Superposing (");
363 command.append(structures[pdbfnum].pdbId);
364 command.append(") against reference (");
365 command.append(structures[refStructure].pdbId);
366 command.append(")\";\ncompare " + nSeconds);
368 command.append(Integer.toString(1 + pdbfnum));
369 command.append(".1} {");
370 command.append(Integer.toString(1 + refStructure));
371 // conformation=1 excludes alternate locations for CA (JAL-1757)
373 ".1} SUBSET {(*.CA | *.P) and conformation=1} ATOMS ");
375 // for (int s = 0; s < 2; s++)
377 // command.append(selcom[(s == 0 ? pdbfnum : refStructure)]);
379 command.append(selcom[pdbfnum]);
380 command.append(selcom[refStructure]);
381 command.append(" ROTATE TRANSLATE;\n");
383 if (selectioncom.length() > 0)
385 // TODO is performing selectioncom redundant here? is done later on
386 // System.out.println("Select regions:\n" + selectioncom.toString());
387 executeCommand("select *; cartoons off; backbone; select ("
388 + selectioncom.toString() + "); cartoons; ", false);
389 // selcom.append("; ribbons; ");
390 String cmdString = command.toString();
391 // System.out.println("Superimpose command(s):\n" + cmdString);
393 executeCommand(cmdString, false);
396 if (selectioncom.length() > 0)
397 {// finally, mark all regions that were superposed.
398 if (selectioncom.substring(selectioncom.length() - 1).equals("|"))
400 selectioncom.setLength(selectioncom.length() - 1);
402 // System.out.println("Select regions:\n" + selectioncom.toString());
403 executeCommand("select *; cartoons off; backbone; select ("
404 + selectioncom.toString() + "); cartoons; ", false);
405 // evalStateCommand("select *; backbone; select "+selcom.toString()+";
406 // cartoons; center "+selcom.toString());
413 public List<String> executeCommand(String command, boolean getReply)
420 if (lastCommand == null || !lastCommand.equals(command))
422 jmolViewer.evalStringQuiet(command + "\n");
425 lastCommand = command;
429 public void createImage(String file, String type, int quality)
431 System.out.println("JMOL CREATE IMAGE");
435 public String createImage(String fileName, String type,
436 Object textOrBytes, int quality)
438 System.out.println("JMOL CREATE IMAGE");
443 public String eval(String strEval)
445 // System.out.println(strEval);
446 // "# 'eval' is implemented only for the applet.";
450 // End StructureListener
451 // //////////////////////////
454 public float[][] functionXY(String functionName, int x, int y)
460 public float[][][] functionXYZ(String functionName, int nx, int ny,
463 // TODO Auto-generated method stub
468 * instruct the Jalview binding to update the pdbentries vector if necessary
469 * prior to matching the jmol view's contents to the list of structure files
470 * Jalview knows about.
472 public abstract void refreshPdbEntries();
475 * map between index of model filename returned from getPdbFile and the first
476 * index of models from this file in the viewer. Note - this is not trimmed -
477 * use getPdbFile to get number of unique models.
479 private int _modelFileNameMap[];
482 public synchronized String[] getStructureFiles()
484 List<String> mset = new ArrayList<>();
485 if (jmolViewer == null)
487 return new String[0];
490 if (modelFileNames == null)
492 int modelCount = jmolViewer.ms.mc;
493 String filePath = null;
494 for (int i = 0; i < modelCount; ++i)
496 filePath = jmolViewer.ms.getModelFileName(i);
497 if (!mset.contains(filePath))
502 modelFileNames = mset.toArray(new String[mset.size()]);
505 return modelFileNames;
509 * map from string to applet
512 public Map<String, Object> getRegistryInfo()
514 // TODO Auto-generated method stub
518 // ///////////////////////////////
519 // JmolStatusListener
521 public void handlePopupMenu(int x, int y)
523 // jmolpopup.show(x, y);
524 // jmolpopup.jpiShow(x, y);
528 * Highlight zero, one or more atoms on the structure
531 public void highlightAtoms(List<AtomSpec> atoms)
535 if (resetLastRes.length() > 0)
537 jmolViewer.evalStringQuiet(resetLastRes.toString());
538 resetLastRes.setLength(0);
540 for (AtomSpec atom : atoms)
542 highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(),
543 atom.getChain(), atom.getPdbFile());
549 public void highlightAtom(int atomIndex, int pdbResNum, String chain,
552 if (modelFileNames == null)
557 // look up file model number for this pdbfile
559 // may need to adjust for URLencoding here - we don't worry about that yet.
560 while (mdlNum < modelFileNames.length
561 && !pdbfile.equals(modelFileNames[mdlNum]))
565 if (mdlNum == modelFileNames.length)
572 StringBuilder cmd = new StringBuilder(64);
573 cmd.append("select " + pdbResNum); // +modelNum
575 resetLastRes.append("select " + pdbResNum); // +modelNum
578 resetLastRes.append(":");
579 if (!chain.equals(" "))
582 resetLastRes.append(chain);
585 cmd.append(" /" + (mdlNum + 1));
586 resetLastRes.append("/" + (mdlNum + 1));
588 cmd.append(";wireframe 100;" + cmd.toString() + " and not hetero;");
590 resetLastRes.append(";wireframe 0;" + resetLastRes.toString()
591 + " and not hetero; spacefill 0;");
593 cmd.append("spacefill 200;select none");
595 jmolViewer.evalStringQuiet(cmd.toString());
600 boolean debug = true;
602 private void jmolHistory(boolean enable)
604 jmolViewer.evalStringQuiet("History " + ((debug || enable) ? "on" : "off"));
607 public void loadInline(String string)
611 // viewer.loadInline(strModel, isAppend);
613 // construct fake fullPathName and fileName so we can identify the file
615 // Then, construct pass a reader for the string to Jmol.
616 // ((org.jmol.Viewer.Viewer) viewer).loadModelFromFile(fullPathName,
617 // fileName, null, reader, false, null, null, 0);
618 jmolViewer.openStringInline(string);
621 protected void mouseOverStructure(int atomIndex, final String strInfo)
624 int alocsep = strInfo.indexOf("^");
625 int mdlSep = strInfo.indexOf("/");
626 int chainSeparator = strInfo.indexOf(":"), chainSeparator1 = -1;
628 if (chainSeparator == -1)
630 chainSeparator = strInfo.indexOf(".");
631 if (mdlSep > -1 && mdlSep < chainSeparator)
633 chainSeparator1 = chainSeparator;
634 chainSeparator = mdlSep;
637 // handle insertion codes
640 pdbResNum = Integer.parseInt(
641 strInfo.substring(strInfo.indexOf("]") + 1, alocsep));
646 pdbResNum = Integer.parseInt(
647 strInfo.substring(strInfo.indexOf("]") + 1, chainSeparator));
651 if (strInfo.indexOf(":") > -1)
653 chainId = strInfo.substring(strInfo.indexOf(":") + 1,
654 strInfo.indexOf("."));
661 String pdbfilename = modelFileNames[frameNo]; // default is first or current
665 if (chainSeparator1 == -1)
667 chainSeparator1 = strInfo.indexOf(".", mdlSep);
669 String mdlId = (chainSeparator1 > -1)
670 ? strInfo.substring(mdlSep + 1, chainSeparator1)
671 : strInfo.substring(mdlSep + 1);
674 // recover PDB filename for the model hovered over.
675 int mnumber = Integer.valueOf(mdlId).intValue() - 1;
676 if (_modelFileNameMap != null)
678 int _mp = _modelFileNameMap.length - 1;
680 while (mnumber < _modelFileNameMap[_mp])
684 pdbfilename = modelFileNames[_mp];
688 if (mnumber >= 0 && mnumber < modelFileNames.length)
690 pdbfilename = modelFileNames[mnumber];
693 if (pdbfilename == null)
695 pdbfilename = new File(jmolViewer.ms.getModelFileName(mnumber))
699 } catch (Exception e)
705 * highlight position on alignment(s); if some text is returned,
706 * show this as a second line on the structure hover tooltip
708 String label = getSsm().mouseOverStructure(pdbResNum, chainId,
712 // change comma to pipe separator (newline token for Jmol)
713 label = label.replace(',', '|');
714 StringTokenizer toks = new StringTokenizer(strInfo, " ");
715 StringBuilder sb = new StringBuilder();
716 sb.append("select ").append(String.valueOf(pdbResNum)).append(":")
717 .append(chainId).append("/1");
718 sb.append(";set hoverLabel \"").append(toks.nextToken()).append(" ")
719 .append(toks.nextToken());
720 sb.append("|").append(label).append("\"");
721 executeCommand(sb.toString(), false);
725 public void notifyAtomHovered(int atomIndex, String strInfo, String data)
727 if (strInfo.equals(lastMessage))
731 lastMessage = strInfo;
734 System.err.println("Ignoring additional hover info: " + data
735 + " (other info: '" + strInfo + "' pos " + atomIndex + ")");
737 mouseOverStructure(atomIndex, strInfo);
741 * { if (history != null && strStatus != null &&
742 * !strStatus.equals("Script completed")) { history.append("\n" + strStatus);
746 public void notifyAtomPicked(int atomIndex, String strInfo,
750 * this implements the toggle label behaviour copied from the original
751 * structure viewer, MCView
755 System.err.println("Ignoring additional pick data string " + strData);
757 int chainSeparator = strInfo.indexOf(":");
759 if (chainSeparator == -1)
761 chainSeparator = strInfo.indexOf(".");
764 String picked = strInfo.substring(strInfo.indexOf("]") + 1,
766 String mdlString = "";
767 if ((p = strInfo.indexOf(":")) > -1)
769 picked += strInfo.substring(p, strInfo.indexOf("."));
772 if ((p = strInfo.indexOf("/")) > -1)
774 mdlString += strInfo.substring(p, strInfo.indexOf(" #"));
776 picked = "((" + picked + ".CA" + mdlString + ")|(" + picked + ".P"
780 if (!atomsPicked.contains(picked))
782 jmolViewer.evalStringQuiet("select " + picked + ";label %n %r:%c");
783 atomsPicked.addElement(picked);
787 jmolViewer.evalString("select " + picked + ";label off");
788 atomsPicked.removeElement(picked);
791 // TODO: in application this happens
793 // if (scriptWindow != null)
795 // scriptWindow.sendConsoleMessage(strInfo);
796 // scriptWindow.sendConsoleMessage("\n");
802 public void notifyCallback(CBK type, Object[] data)
809 notifyFileLoaded((String) data[1], (String) data[2],
810 (String) data[3], (String) data[4],
811 ((Integer) data[5]).intValue());
815 notifyAtomPicked(((Integer) data[2]).intValue(), (String) data[1],
817 // also highlight in alignment
818 // deliberate fall through
820 notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1],
824 notifyScriptTermination((String) data[2],
825 ((Integer) data[3]).intValue());
828 sendConsoleEcho((String) data[1]);
832 (data == null) ? ((String) null) : (String) data[1]);
835 // System.err.println("Ignoring error callback.");
846 "Unhandled callback " + type + " " + data[1].toString());
849 } catch (Exception e)
851 System.err.println("Squashed Jmol callback handler error:");
857 public boolean notifyEnabled(CBK callbackPick)
859 switch (callbackPick)
875 // incremented every time a load notification is successfully handled -
876 // lightweight mechanism for other threads to detect when they can start
877 // referrring to new structures.
878 private long loadNotifiesHandled = 0;
880 public long getLoadNotifiesHandled()
882 return loadNotifiesHandled;
885 public void notifyFileLoaded(String fullPathName, String fileName2,
886 String modelName, String errorMsg, int modelParts)
888 if (errorMsg != null)
890 fileLoadingError = errorMsg;
894 // TODO: deal sensibly with models loaded inLine:
895 // modelName will be null, as will fullPathName.
897 // the rest of this routine ignores the arguments, and simply interrogates
898 // the Jmol view to find out what structures it contains, and adds them to
899 // the structure selection manager.
900 fileLoadingError = null;
901 String[] oldmodels = modelFileNames;
902 modelFileNames = null;
903 boolean notifyLoaded = false;
904 String[] modelfilenames = getStructureFiles();
905 // first check if we've lost any structures
906 if (oldmodels != null && oldmodels.length > 0)
909 for (int i = 0; i < oldmodels.length; i++)
911 for (int n = 0; n < modelfilenames.length; n++)
913 if (modelfilenames[n] == oldmodels[i])
919 if (oldmodels[i] != null)
926 String[] oldmfn = new String[oldm];
928 for (int i = 0; i < oldmodels.length; i++)
930 if (oldmodels[i] != null)
932 oldmfn[oldm++] = oldmodels[i];
935 // deregister the Jmol instance for these structures - we'll add
936 // ourselves again at the end for the current structure set.
937 getSsm().removeStructureViewerListener(this, oldmfn);
941 for (int modelnum = 0; modelnum < modelfilenames.length; modelnum++)
943 String fileName = modelfilenames[modelnum];
944 boolean foundEntry = false;
945 StructureFile pdb = null;
946 String pdbfile = null;
947 // model was probably loaded inline - so check the pdb file hashcode
950 // calculate essential attributes for the pdb data imported inline.
951 // prolly need to resolve modelnumber properly - for now just use our
953 pdbfile = jmolViewer.getData(
954 "" + (1 + _modelFileNameMap[modelnum]) + ".0", "PDB");
956 // search pdbentries and sequences to find correct pdbentry for this
958 for (int pe = 0; pe < getPdbCount(); pe++)
960 boolean matches = false;
961 addSequence(pe, getSequence()[pe]);
962 if (fileName == null)
965 // see JAL-623 - need method of matching pasted data up
967 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
968 pdbfile, DataSourceType.PASTE,
969 getIProgressIndicator());
970 getPdbEntry(modelnum).setFile("INLINE" + pdb.getId());
977 File fl = new File(getPdbEntry(pe).getFile());
978 matches = fl.equals(new File(fileName));
982 // TODO: Jmol can in principle retrieve from CLASSLOADER but
985 // to be tested. See mantis bug
986 // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605
987 DataSourceType protocol = DataSourceType.URL;
992 protocol = DataSourceType.FILE;
994 } catch (Exception e)
999 // Explicitly map to the filename used by Jmol ;
1000 pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
1001 fileName, protocol, getIProgressIndicator());
1002 // pdbentry[pe].getFile(), protocol);
1008 // add an entry for every chain in the model
1009 for (int i = 0; i < pdb.getChains().size(); i++)
1011 String chid = pdb.getId() + ":"
1012 + pdb.getChains().elementAt(i).id;
1013 addChainFile(chid, fileName);
1014 getChainNames().add(chid);
1016 notifyLoaded = true;
1020 if (!foundEntry && associateNewStructs)
1022 // this is a foreign pdb file that jalview doesn't know about - add
1023 // it to the dataset and try to find a home - either on a matching
1024 // sequence or as a new sequence.
1025 String pdbcontent = jmolViewer.getData("/" + (modelnum + 1) + ".1",
1027 // parse pdb file into a chain, etc.
1028 // locate best match for pdb in associated views and add mapping to
1030 // if properly registered then
1031 notifyLoaded = true;
1036 // so finally, update the jmol bits and pieces
1037 // if (jmolpopup != null)
1039 // // potential for deadlock here:
1040 // // jmolpopup.updateComputedMenus();
1042 if (!isLoadingFromArchive())
1044 jmolViewer.evalStringQuiet(
1045 "model *; select backbone;restrict;cartoon;wireframe off;spacefill off");
1047 // register ourselves as a listener and notify the gui that it needs to
1049 getSsm().addStructureViewerListener(this);
1052 FeatureRenderer fr = getFeatureRenderer(null);
1058 loadNotifiesHandled++;
1060 setLoadingFromArchive(false);
1063 protected IProgressIndicator getIProgressIndicator()
1068 public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
1070 notifyAtomPicked(iatom, strMeasure, null);
1073 public abstract void notifyScriptTermination(String strStatus,
1077 * display a message echoed from the jmol viewer
1081 public abstract void sendConsoleEcho(String strEcho); /*
1082 * { showConsole(true);
1084 * history.append("\n" +
1088 // /End JmolStatusListener
1089 // /////////////////////////////
1093 * status message - usually the response received after a script
1096 public abstract void sendConsoleMessage(String strStatus);
1099 public void setCallbackFunction(String callbackType,
1100 String callbackFunction)
1102 System.err.println("Ignoring set-callback request to associate "
1103 + callbackType + " with function " + callbackFunction);
1107 public void showHelp()
1109 showUrl("http://jmol.sourceforge.net/docs/JmolUserGuide/", "jmolHelp");
1113 * open the URL somehow
1117 public abstract void showUrl(String url, String target);
1120 * called when the binding thinks the UI needs to be refreshed after a Jmol
1121 * state change. this could be because structures were loaded, or because an
1122 * error has occured.
1124 public abstract void refreshGUI();
1127 * called to show or hide the associated console window container.
1131 public abstract void showConsole(boolean show);
1134 * @param renderPanel
1136 * - when true will initialise jmol's file IO system (should be false
1137 * in applet context)
1139 * @param documentBase
1141 * @param commandOptions
1143 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1144 String htmlName, URL documentBase, URL codeBase,
1145 String commandOptions)
1147 allocateViewer(renderPanel, jmolfileio, htmlName, documentBase,
1148 codeBase, commandOptions, null, null);
1153 * @param renderPanel
1155 * - when true will initialise jmol's file IO system (should be false
1156 * in applet context)
1158 * @param documentBase
1160 * @param commandOptions
1161 * @param consolePanel
1162 * - panel to contain Jmol console
1163 * @param buttonsToShow
1164 * - buttons to show on the console, in ordr
1166 public void allocateViewer(Container renderPanel, boolean jmolfileio,
1167 String htmlName, URL documentBase, URL codeBase,
1168 String commandOptions, final Container consolePanel,
1169 String buttonsToShow)
1171 if (commandOptions == null)
1173 commandOptions = "";
1175 jmolViewer = (Viewer) JmolViewer.allocateViewer(renderPanel,
1176 (jmolfileio ? new SmarterJmolAdapter() : null),
1177 htmlName + ((Object) this).toString(), documentBase, codeBase,
1178 commandOptions, this);
1180 jmolViewer.setJmolStatusListener(this); // extends JmolCallbackListener
1182 console = createJmolConsole(consolePanel, buttonsToShow);
1183 if (consolePanel != null)
1185 consolePanel.addComponentListener(this);
1191 protected abstract JmolAppConsoleInterface createJmolConsole(
1192 Container consolePanel, String buttonsToShow);
1194 protected org.jmol.api.JmolAppConsoleInterface console = null;
1197 public int[] resizeInnerPanel(String data)
1199 // Jalview doesn't honour resize panel requests
1206 protected void closeConsole()
1208 if (console != null)
1212 console.setVisible(false);
1215 } catch (Exception x)
1224 * ComponentListener method
1227 public void componentMoved(ComponentEvent e)
1232 * ComponentListener method
1235 public void componentResized(ComponentEvent e)
1240 * ComponentListener method
1243 public void componentShown(ComponentEvent e)
1249 * ComponentListener method
1252 public void componentHidden(ComponentEvent e)
1258 protected int getModelNoForFile(String pdbFile)
1260 if (modelFileNames == null)
1264 for (int i = 0; i < modelFileNames.length; i++)
1266 if (modelFileNames[i].equalsIgnoreCase(pdbFile))