2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
3 * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
11 * Jalview is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 * PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with Jalview. If not, see <http://www.gnu.org/licenses/>.
18 package jalview.ext.jmol;
24 import java.awt.event.*;
26 import jalview.api.FeatureRenderer;
27 import jalview.api.SequenceRenderer;
28 import jalview.api.SequenceStructureBinding;
29 import jalview.datamodel.*;
30 import jalview.structure.*;
33 import org.jmol.api.*;
34 import org.jmol.adapter.smarter.SmarterJmolAdapter;
36 import org.jmol.popup.*;
37 import org.jmol.viewer.JmolConstants;
39 import jalview.schemes.*;
41 public abstract class JalviewJmolBinding implements StructureListener,
42 JmolStatusListener, SequenceStructureBinding, JmolSelectionListener
46 * set if Jmol state is being restored from some source - instructs binding
47 * not to apply default display style when structure set is updated for first
50 private boolean loadingFromArchive = false;
53 * state flag used to check if the Jmol viewer's paint method can be called
55 private boolean finishedInit = false;
57 public boolean isFinishedInit()
62 public void setFinishedInit(boolean finishedInit)
64 this.finishedInit = finishedInit;
67 boolean allChainsSelected = false;
70 * when true, try to search the associated datamodel for sequences that are
71 * associated with any unknown structures in the Jmol view.
73 private boolean associateNewStructs = false;
75 Vector atomsPicked = new Vector();
77 public Vector chainNames;
81 boolean colourBySequence = true;
83 StringBuffer eval = new StringBuffer();
85 public String fileLoadingError;
88 * the default or current model displayed if the model cannot be identified
89 * from the selection message
93 protected JmolPopup jmolpopup;
102 * current set of model filenames loaded in the Jmol instance
104 String[] modelFileNames = null;
106 public PDBEntry[] pdbentry;
109 * datasource protocol for access to PDBEntry
111 String protocol = null;
113 StringBuffer resetLastRes = new StringBuffer();
115 public SequenceI[] sequence;
117 StructureSelectionManager ssm;
119 public JmolViewer viewer;
121 public JalviewJmolBinding(PDBEntry[] pdbentry, SequenceI[] seq,
122 String[] chains, String protocol)
125 this.chains = chains;
126 this.pdbentry = pdbentry;
127 this.protocol = protocol;
130 * viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter(),
131 * "jalviewJmol", ap.av.applet .getDocumentBase(),
132 * ap.av.applet.getCodeBase(), "", this);
134 * jmolpopup = JmolPopup.newJmolPopup(viewer, true, "Jmol", true);
138 public JalviewJmolBinding(JmolViewer viewer2)
141 viewer.setJmolStatusListener(this);
142 viewer.addSelectionListener(this);
146 * construct a title string for the viewer window based on the data jalview
151 public String getViewerTitle()
153 if (sequence == null || pdbentry == null || sequence.length < 1
154 || pdbentry.length < 1)
156 return ("Jalview Jmol Window");
158 StringBuffer title = new StringBuffer(sequence[0].getName() + ":"
159 + pdbentry[0].getId());
161 if (pdbentry[0].getProperty() != null)
163 if (pdbentry[0].getProperty().get("method") != null)
165 title.append(" Method: ");
166 title.append(pdbentry[0].getProperty().get("method"));
168 if (pdbentry[0].getProperty().get("chains") != null)
170 title.append(" Chain:");
171 title.append(pdbentry[0].getProperty().get("chains"));
174 return title.toString();
178 * prepare the view for a given set of models/chains. chainList contains
179 * strings of the form 'pdbfilename:Chaincode'
182 * list of chains to make visible
184 public void centerViewer(Vector chainList)
186 StringBuffer cmd = new StringBuffer();
189 for (int i = 0, iSize = chainList.size(); i < iSize; i++)
192 lbl = (String) chainList.elementAt(i);
196 mlength = lbl.indexOf(":", p);
197 } while (p < mlength && mlength < (lbl.length() - 2));
198 cmd.append(":" + lbl.substring(mlength + 1) + " /"
199 + getModelNum(lbl.substring(0, mlength)) + " or ");
201 if (cmd.length() > 0)
202 cmd.setLength(cmd.length() - 4);
203 evalStateCommand("select *;restrict " + cmd + ";cartoon;center " + cmd);
206 public void closeViewer()
208 viewer.setModeMouse(org.jmol.viewer.JmolConstants.MOUSE_NONE);
209 // remove listeners for all structures in viewer
210 StructureSelectionManager.getStructureSelectionManager()
211 .removeStructureViewerListener(this, this.getPdbFile());
212 // and shut down jmol
213 viewer.evalStringQuiet("zap");
214 viewer.setJmolStatusListener(null);
219 public void colourByChain()
221 colourBySequence = false;
222 evalStateCommand("select *;color chain");
225 public void colourByCharge()
227 colourBySequence = false;
228 evalStateCommand("select *;color white;select ASP,GLU;color red;"
229 + "select LYS,ARG;color blue;select CYS;color yellow");
233 * superpose the structures associated with sequences in the alignment
234 * according to their corresponding positions.
236 public void superposeStructures(AlignmentI alignment)
238 String[] files = getPdbFile();
240 StringBuffer command = new StringBuffer();
241 boolean matched[] = new boolean[alignment.getWidth()];
242 String commonpositions[][] = new String[files.length][alignment
244 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
246 StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
248 if (mapping == null || mapping.length < 1)
252 for (int s = 0; s < sequence.length; s++)
254 for (int sp, m = 0; m < mapping.length; m++)
256 if (mapping[m].getSequence() == sequence[s]
257 && (sp = alignment.findIndex(sequence[s])) > -1)
259 SequenceI asp = alignment.getSequenceAt(sp);
260 for (int r = 0; r < asp.getLength(); r++)
262 // no mapping to gaps in sequence
263 if (jalview.util.Comparison.isGap(asp.getCharAt(r)))
265 matched[r] = false; // exclude from common set
268 int pos = mapping[m].getPDBResNum(asp.findPosition(r));
270 if (pos < 1 || pos == lastPos)
275 commonpositions[m][r] = (mapping[m].getChain() != " " ? ":"
276 + mapping[m].getChain() : "")
277 + "/" + (pdbfnum + 1) + ".1";
284 command.append("select ");
285 // form the matched pair selection strings
287 for (int r = 0; r < matched.length; r++)
293 for (int s = 0; s < commonpositions.length; s++)
297 command.append(" | ");
299 command.append(commonpositions[s][r]);
305 evalStateCommand(command.toString());
308 public void evalStateCommand(String command)
311 if (lastCommand == null || !lastCommand.equals(command))
313 viewer.evalStringQuiet(command + "\n");
316 lastCommand = command;
320 * colour any structures associated with sequences in the given alignment
321 * using the getFeatureRenderer() and getSequenceRenderer() renderers but only
322 * if colourBySequence is enabled.
324 public void colourBySequence(boolean showFeatures, AlignmentI alignment)
326 if (!colourBySequence)
332 String[] files = getPdbFile();
333 SequenceRenderer sr = getSequenceRenderer();
335 FeatureRenderer fr = null;
338 fr = getFeatureRenderer();
341 StringBuffer command = new StringBuffer();
343 for (int pdbfnum = 0; pdbfnum < files.length; pdbfnum++)
345 StructureMapping[] mapping = ssm.getMapping(files[pdbfnum]);
347 if (mapping == null || mapping.length < 1)
351 for (int s = 0; s < sequence.length; s++)
353 for (int sp, m = 0; m < mapping.length; m++)
355 if (mapping[m].getSequence() == sequence[s]
356 && (sp = alignment.findIndex(sequence[s])) > -1)
358 SequenceI asp = alignment.getSequenceAt(sp);
359 for (int r = 0; r < asp.getLength(); r++)
361 // no mapping to gaps in sequence
362 if (jalview.util.Comparison.isGap(asp.getCharAt(r)))
366 int pos = mapping[m].getPDBResNum(asp.findPosition(r));
368 if (pos < 1 || pos == lastPos)
373 Color col = sr.getResidueBoxColour(sequence[s], r);
376 col = fr.findFeatureColour(col, sequence[s], r);
377 String newSelcom = (mapping[m].getChain() != " " ? ":"
378 + mapping[m].getChain() : "")
387 + col.getBlue() + "]";
388 if (command.toString().endsWith(newSelcom))
390 command = condenseCommand(command.toString(), pos);
393 // TODO: deal with case when buffer is too large for Jmol to parse
394 // - execute command and flush
396 command.append(";select " + pos);
397 command.append(newSelcom);
404 evalStateCommand(command.toString());
407 public boolean isColourBySequence()
409 return colourBySequence;
412 public void setColourBySequence(boolean colourBySequence)
414 this.colourBySequence = colourBySequence;
417 StringBuffer condenseCommand(String command, int pos)
420 StringBuffer sb = new StringBuffer(command.substring(0,
421 command.lastIndexOf("select") + 7));
423 command = command.substring(sb.length());
427 if (command.indexOf("-") > -1)
429 start = command.substring(0, command.indexOf("-"));
433 start = command.substring(0, command.indexOf(":"));
436 sb.append(start + "-" + pos + command.substring(command.indexOf(":")));
441 public void createImage(String file, String type, int quality)
443 System.out.println("JMOL CREATE IMAGE");
446 public String createImage(String fileName, String type,
447 Object textOrBytes, int quality)
449 System.out.println("JMOL CREATE IMAGE");
453 public String eval(String strEval)
455 // System.out.println(strEval);
456 // "# 'eval' is implemented only for the applet.";
460 // End StructureListener
461 // //////////////////////////
463 public float[][] functionXY(String functionName, int x, int y)
468 public float[][][] functionXYZ(String functionName, int nx, int ny, int nz)
470 // TODO Auto-generated method stub
474 public Color getColour(int atomIndex, int pdbResNum, String chain,
477 if (getModelNum(pdbfile) < 0)
479 // TODO: verify atomIndex is selecting correct model.
480 return new Color(viewer.getAtomArgb(atomIndex));
484 * returns the current featureRenderer that should be used to colour the
489 public abstract FeatureRenderer getFeatureRenderer();
492 * instruct the Jalview binding to update the pdbentries vector if necessary
493 * prior to matching the jmol view's contents to the list of structure files
494 * Jalview knows about.
496 public abstract void refreshPdbEntries();
498 private int getModelNum(String modelFileName)
500 String[] mfn = getPdbFile();
505 for (int i = 0; i < mfn.length; i++)
507 if (mfn[i].equalsIgnoreCase(modelFileName))
513 // ////////////////////////////////
514 // /StructureListener
515 public String[] getPdbFile()
517 if (modelFileNames == null)
519 String mset[] = new String[viewer.getModelCount()];
520 for (int i = 0; i < mset.length; i++)
522 mset[i] = viewer.getModelFileName(i);
524 modelFileNames = mset;
526 return modelFileNames;
529 public Hashtable getRegistryInfo()
531 // TODO Auto-generated method stub
536 * returns the current sequenceRenderer that should be used to colour the
541 public abstract SequenceRenderer getSequenceRenderer();
543 // ///////////////////////////////
544 // JmolStatusListener
546 public void handlePopupMenu(int x, int y)
548 jmolpopup.show(x, y);
552 public void highlightAtom(int atomIndex, int pdbResNum, String chain,
555 if (modelFileNames == null)
560 // look up file model number for this pdbfile
563 // may need to adjust for URLencoding here - we don't worry about that yet.
564 while (mdlNum < modelFileNames.length
565 && !pdbfile.equals(modelFileNames[mdlNum]))
567 // System.out.println("nomatch:"+pdbfile+"\nmodelfn:"+fn);
570 if (mdlNum == modelFileNames.length)
576 // if (!pdbfile.equals(pdbentry.getFile()))
578 if (resetLastRes.length() > 0)
580 viewer.evalStringQuiet(resetLastRes.toString());
584 eval.append("select " + pdbResNum); // +modelNum
586 resetLastRes.setLength(0);
587 resetLastRes.append("select " + pdbResNum); // +modelNum
590 resetLastRes.append(":");
591 if (!chain.equals(" "))
594 resetLastRes.append(chain);
597 eval.append(" /" + (mdlNum + 1));
598 resetLastRes.append("/" + (mdlNum + 1));
600 eval.append(";wireframe 100;" + eval.toString() + " and not hetero;");
602 resetLastRes.append(";wireframe 0;" + resetLastRes.toString()
603 + " and not hetero; spacefill 0;");
605 eval.append("spacefill 200;select none");
607 viewer.evalStringQuiet(eval.toString());
612 boolean debug = true;
614 private void jmolHistory(boolean enable)
616 viewer.evalStringQuiet("History " + ((debug || enable) ? "on" : "off"));
619 public void loadInline(String string)
622 viewer.openStringInline(string);
625 public void mouseOverStructure(int atomIndex, String strInfo)
628 int mdlSep = strInfo.indexOf("/");
629 int chainSeparator = strInfo.indexOf(":"), chainSeparator1 = -1;
631 if (chainSeparator == -1)
633 chainSeparator = strInfo.indexOf(".");
634 if (mdlSep > -1 && mdlSep < chainSeparator)
636 chainSeparator1 = chainSeparator;
637 chainSeparator = mdlSep;
640 pdbResNum = Integer.parseInt(strInfo.substring(
641 strInfo.indexOf("]") + 1, chainSeparator));
645 if (strInfo.indexOf(":") > -1)
646 chainId = strInfo.substring(strInfo.indexOf(":") + 1,
647 strInfo.indexOf("."));
653 String pdbfilename = modelFileNames[frameNo]; // default is first or current
657 if (chainSeparator1 == -1)
659 chainSeparator1 = strInfo.indexOf(".", mdlSep);
661 String mdlId = (chainSeparator1 > -1) ? strInfo.substring(mdlSep + 1,
662 chainSeparator1) : strInfo.substring(mdlSep + 1);
665 // recover PDB filename for the model hovered over.
667 .getModelFileName(new Integer(mdlId).intValue() - 1);
668 } catch (Exception e)
673 if (lastMessage == null || !lastMessage.equals(strInfo))
674 ssm.mouseOverStructure(pdbResNum, chainId, pdbfilename);
676 lastMessage = strInfo;
679 public void notifyAtomHovered(int atomIndex, String strInfo, String data)
683 System.err.println("Ignoring additional hover info: " + data
684 + " (other info: '" + strInfo + "' pos " + atomIndex + ")");
686 mouseOverStructure(atomIndex, strInfo);
690 * { if (history != null && strStatus != null &&
691 * !strStatus.equals("Script completed")) { history.append("\n" + strStatus);
695 public void notifyAtomPicked(int atomIndex, String strInfo, String strData)
698 * this implements the toggle label behaviour copied from the original
699 * structure viewer, MCView
703 System.err.println("Ignoring additional pick data string " + strData);
705 int chainSeparator = strInfo.indexOf(":");
707 if (chainSeparator == -1)
708 chainSeparator = strInfo.indexOf(".");
710 String picked = strInfo.substring(strInfo.indexOf("]") + 1,
712 String mdlString = "";
713 if ((p = strInfo.indexOf(":")) > -1)
714 picked += strInfo.substring(p + 1, strInfo.indexOf("."));
716 if ((p = strInfo.indexOf("/")) > -1)
718 mdlString += strInfo.substring(p, strInfo.indexOf(" #"));
720 picked = "((" + picked + ".CA" + mdlString + ")|(" + picked + ".P"
724 if (!atomsPicked.contains(picked))
726 viewer.evalStringQuiet("select " + picked + ";label %n %r:%c");
727 atomsPicked.addElement(picked);
731 viewer.evalString("select " + picked + ";label off");
732 atomsPicked.removeElement(picked);
735 // TODO: in application this happens
737 // if (scriptWindow != null)
739 // scriptWindow.sendConsoleMessage(strInfo);
740 // scriptWindow.sendConsoleMessage("\n");
745 public void notifyCallback(int type, Object[] data)
751 case JmolConstants.CALLBACK_LOADSTRUCT:
752 notifyFileLoaded((String) data[1], (String) data[2],
753 (String) data[3], (String) data[4],
754 ((Integer) data[5]).intValue());
757 case JmolConstants.CALLBACK_PICK:
758 notifyAtomPicked(((Integer) data[2]).intValue(), (String) data[1],
760 // also highlight in alignment
761 case JmolConstants.CALLBACK_HOVER:
762 notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1],
765 case JmolConstants.CALLBACK_SCRIPT:
766 notifyScriptTermination((String) data[2],
767 ((Integer) data[3]).intValue());
769 case JmolConstants.CALLBACK_ECHO:
770 sendConsoleEcho((String) data[1]);
772 case JmolConstants.CALLBACK_MESSAGE:
773 sendConsoleMessage((data == null) ? ((String) null)
776 case JmolConstants.CALLBACK_ERROR:
777 // System.err.println("Ignoring error callback.");
779 case JmolConstants.CALLBACK_SYNC:
780 case JmolConstants.CALLBACK_RESIZE:
783 case JmolConstants.CALLBACK_MEASURE:
785 case JmolConstants.CALLBACK_CLICK:
788 System.err.println("Unhandled callback " + type + " "
789 + data[1].toString());
792 } catch (Exception e)
794 System.err.println("Squashed Jmol callback handler error:");
799 public boolean notifyEnabled(int callbackPick)
801 switch (callbackPick)
803 case JmolConstants.CALLBACK_ECHO:
804 case JmolConstants.CALLBACK_LOADSTRUCT:
805 case JmolConstants.CALLBACK_MEASURE:
806 case JmolConstants.CALLBACK_MESSAGE:
807 case JmolConstants.CALLBACK_PICK:
808 case JmolConstants.CALLBACK_SCRIPT:
809 case JmolConstants.CALLBACK_HOVER:
810 case JmolConstants.CALLBACK_ERROR:
812 case JmolConstants.CALLBACK_RESIZE:
813 case JmolConstants.CALLBACK_SYNC:
814 case JmolConstants.CALLBACK_CLICK:
815 case JmolConstants.CALLBACK_ANIMFRAME:
816 case JmolConstants.CALLBACK_MINIMIZATION:
821 public void notifyFileLoaded(String fullPathName, String fileName2,
822 String modelName, String errorMsg, int modelParts)
824 if (errorMsg != null)
826 fileLoadingError = errorMsg;
830 // the rest of this routine ignores the arguments, and simply interrogates
831 // the Jmol view to find out what structures it contains, and adds them to
832 // the structure selection manager.
833 fileLoadingError = null;
834 String[] oldmodels = modelFileNames;
835 modelFileNames = null;
836 chainNames = new Vector();
837 boolean notifyLoaded = false;
838 String[] modelfilenames = getPdbFile();
839 ssm = StructureSelectionManager.getStructureSelectionManager();
840 // first check if we've lost any structures
841 if (oldmodels != null && oldmodels.length > 0)
844 for (int i = 0; i < oldmodels.length; i++)
846 for (int n = 0; n < modelfilenames.length; n++)
848 if (modelfilenames[n] == oldmodels[i])
854 if (oldmodels[i] != null)
861 String[] oldmfn = new String[oldm];
863 for (int i = 0; i < oldmodels.length; i++)
865 if (oldmodels[i] != null)
867 oldmfn[oldm++] = oldmodels[i];
870 // deregister the Jmol instance for these structures - we'll add
871 // ourselves again at the end for the current structure set.
872 ssm.removeStructureViewerListener(this, oldmfn);
876 for (int modelnum = 0; modelnum < modelfilenames.length; modelnum++)
878 String fileName = modelfilenames[modelnum];
879 if (fileName != null)
881 boolean foundEntry = false;
882 // search pdbentries and sequences to find correct pdbentry and
883 // sequence[] pair for this filename
884 if (pdbentry != null)
886 for (int pe = 0; pe < pdbentry.length; pe++)
888 if (pdbentry[pe].getFile().equals(fileName))
894 // TODO: replace with getData ?
895 pdb = ssm.setMapping(sequence, chains,
896 pdbentry[pe].getFile(), AppletFormatAdapter.PASTE);
897 pdbentry[pe].setFile("INLINE" + pdb.id);
901 // TODO: Jmol can in principle retrieve from CLASSLOADER but
904 // to be tested. See mantis bug
905 // https://mantis.lifesci.dundee.ac.uk/view.php?id=36605
906 String protocol = AppletFormatAdapter.URL;
909 File fl = new java.io.File(pdbentry[pe].getFile());
912 protocol = AppletFormatAdapter.FILE;
914 } catch (Exception e)
920 pdb = ssm.setMapping(sequence, chains,
921 pdbentry[pe].getFile(), protocol);
925 pdbentry[pe].setId(pdb.id);
927 for (int i = 0; i < pdb.chains.size(); i++)
929 chainNames.addElement(new String(pdb.id + ":"
930 + ((MCview.PDBChain) pdb.chains.elementAt(i)).id));
936 if (!foundEntry && associateNewStructs)
938 // this is a foreign pdb file that jalview doesn't know about - add
939 // it to the dataset and try to find a home - either on a matching
940 // sequence or as a new sequence.
941 String pdbcontent = viewer.getData("/" + (modelnum + 1) + ".1",
943 // parse pdb file into a chain, etc.
944 // locate best match for pdb in associated views and add mapping to
946 // if properly registered then
953 // so finally, update the jmol bits and pieces
954 if (jmolpopup != null)
956 jmolpopup.updateComputedMenus();
958 if (!isLoadingFromArchive())
960 viewer.evalStringQuiet("model 0; select backbone;restrict;cartoon;wireframe off;spacefill off");
962 setLoadingFromArchive(false);
963 // register ourselves as a listener and notify the gui that it needs to
965 ssm.addStructureViewerListener(this);
968 FeatureRenderer fr = getFeatureRenderer();
977 public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
979 notifyAtomPicked(iatom, strMeasure, null);
982 public abstract void notifyScriptTermination(String strStatus,
986 * display a message echoed from the jmol viewer
990 public abstract void sendConsoleEcho(String strEcho); /*
991 * { showConsole(true);
993 * history.append("\n" +
997 // /End JmolStatusListener
998 // /////////////////////////////
1002 * status message - usually the response received after a script
1005 public abstract void sendConsoleMessage(String strStatus);
1007 public void setCallbackFunction(String callbackType,
1008 String callbackFunction)
1010 System.err.println("Ignoring set-callback request to associate "
1011 + callbackType + " with function " + callbackFunction);
1015 public void setJalviewColourScheme(ColourSchemeI cs)
1017 colourBySequence = false;
1026 // TODO: Switch between nucleotide or aa selection expressions
1027 Enumeration en = ResidueProperties.aa3Hash.keys();
1028 StringBuffer command = new StringBuffer("select *;color white;");
1029 while (en.hasMoreElements())
1031 res = en.nextElement().toString();
1032 index = ((Integer) ResidueProperties.aa3Hash.get(res)).intValue();
1036 col = cs.findColour(ResidueProperties.aa[index].charAt(0));
1038 command.append("select " + res + ";color[" + col.getRed() + ","
1039 + col.getGreen() + "," + col.getBlue() + "];");
1042 evalStateCommand(command.toString());
1046 public void showHelp()
1048 showUrl("http://jmol.sourceforge.net/docs/JmolUserGuide/", "jmolHelp");
1052 * open the URL somehow
1056 public abstract void showUrl(String url, String target);
1059 * called when the binding thinks the UI needs to be refreshed after a Jmol
1060 * state change. this could be because structures were loaded, or because an
1061 * error has occured.
1063 public abstract void updateUI();
1065 public void allocateViewer(Component renderPanel, String htmlName,
1066 URL documentBase, URL codeBase, String commandOptions)
1068 viewer = JmolViewer.allocateViewer(renderPanel,
1069 new SmarterJmolAdapter(),
1070 htmlName + ((Object) this).toString(), documentBase, codeBase,
1071 commandOptions, this);
1074 public void setLoadingFromArchive(boolean loadingFromArchive)
1076 this.loadingFromArchive = loadingFromArchive;
1079 public boolean isLoadingFromArchive()
1081 return loadingFromArchive;
1084 public void setBackgroundColour(java.awt.Color col)
1087 viewer.evalStringQuiet("background [" + col.getRed() + ","
1088 + col.getGreen() + "," + col.getBlue() + "];");