Merge branch 'releases/Release_2_10_0_Branch'
[jalview.git] / src / jalview / appletgui / AppletJmol.java
index 9ff3078..c9ff821 100644 (file)
-/*\r
- * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA\r
- */\r
-\r
-package jalview.appletgui;\r
-\r
-import java.util.*;\r
-import java.awt.*;\r
-import java.awt.event.*;\r
-\r
-import jalview.datamodel.*;\r
-import jalview.structure.*;\r
-import jalview.io.*;\r
-\r
-import org.jmol.api.*;\r
-import org.jmol.adapter.smarter.SmarterJmolAdapter;\r
-import org.jmol.popup.*;\r
-\r
-\r
-public class AppletJmol extends Frame\r
-    implements  StructureListener, JmolStatusListener,\r
-    KeyListener, ActionListener, ItemListener\r
-\r
-{\r
-  Menu fileMenu = new Menu("File");\r
-  Menu viewMenu = new Menu("View");\r
-  Menu chainMenu = new Menu("Show Chain");\r
-  MenuItem mappingMenuItem = new MenuItem("View Mapping");\r
-\r
-  JmolViewer viewer;\r
-  JmolPopup jmolpopup;\r
-\r
-  Panel scriptWindow;\r
-  TextField inputLine;\r
-  TextArea history;\r
-  SequenceI[] sequence;\r
-  StructureSelectionManager ssm;\r
-  RenderPanel renderPanel;\r
-  AlignmentPanel ap;\r
-  String fileLoadingError;\r
-  boolean loadedInline;\r
-  PDBEntry pdbentry;\r
-  boolean colourBySequence = true;\r
-\r
-  public AppletJmol(PDBEntry pdbentry,\r
-                    SequenceI[] seq,\r
-                    AlignmentPanel ap,\r
-                    String protocol)\r
-  {\r
-    this.ap = ap;\r
-    this.sequence = seq;\r
-    this.pdbentry = pdbentry;\r
-\r
-   String alreadyMapped = StructureSelectionManager\r
-        .getStructureSelectionManager()\r
-        .alreadyMappedToFile(pdbentry.getId());\r
-\r
-    if (alreadyMapped != null)\r
-    {\r
-       StructureSelectionManager.getStructureSelectionManager()\r
-            .setMapping(seq, pdbentry.getFile(), protocol);\r
-        return;\r
-    }\r
-\r
-    renderPanel = new RenderPanel();\r
-\r
-    this.add(renderPanel, BorderLayout.CENTER);\r
-\r
-    viewer = JmolViewer.allocateViewer(renderPanel, new SmarterJmolAdapter());\r
-\r
-    viewer.setAppletContext("jalview",\r
-                       ap.av.applet.getDocumentBase(),\r
-                            ap.av.applet.getCodeBase(),\r
-                            null);\r
-\r
-    viewer.setJmolStatusListener(this);\r
-\r
-    jmolpopup = JmolPopup.newJmolPopup(viewer);\r
-\r
-    this.addWindowListener(new WindowAdapter()\r
-        {\r
-          public void windowClosing(WindowEvent evt)\r
-          {\r
-            closeViewer();\r
-          }\r
-        });\r
-\r
-    MenuBar menuBar = new MenuBar();\r
-    menuBar.add(fileMenu);\r
-    fileMenu.add(mappingMenuItem);\r
-    menuBar.add(viewMenu);\r
-    mappingMenuItem.addActionListener(this);\r
-    viewMenu.add(chainMenu);\r
-    this.setMenuBar(menuBar);\r
-\r
-    if(pdbentry.getFile()!=null)\r
-    {\r
-      if (protocol.equals(AppletFormatAdapter.PASTE))\r
-        loadInline(pdbentry.getFile());\r
-      else\r
-          viewer.openFile(pdbentry.getFile());\r
-    }\r
-\r
-    this.setBounds(400, 400, 400, 400);\r
-\r
-    this.setVisible(true);\r
-  }\r
-\r
-  public void loadInline(String string)\r
-  {\r
-    loadedInline = true;\r
-    viewer.openStringInline(string);\r
-  }\r
-\r
-\r
-  void setChainMenuItems(Vector chains)\r
-  {\r
-    chainMenu.removeAll();\r
-\r
-    MenuItem menuItem = new MenuItem("All");\r
-    menuItem.addActionListener(this);\r
-\r
-    chainMenu.add(menuItem);\r
-\r
-    CheckboxMenuItem menuItemCB;\r
-    for (int c = 0; c < chains.size(); c++)\r
-    {\r
-      menuItemCB = new CheckboxMenuItem(chains.elementAt(c).toString(), true);\r
-      menuItemCB.addItemListener(this);\r
-      chainMenu.add(menuItemCB);\r
-    }\r
-  }\r
-\r
-  boolean allChainsSelected = false;\r
-  void centerViewer()\r
-  {\r
-    StringBuffer cmd = new StringBuffer();\r
-    for (int i = 0; i < chainMenu.getItemCount(); i++)\r
-    {\r
-      if (chainMenu.getItem(i) instanceof CheckboxMenuItem)\r
-      {\r
-        CheckboxMenuItem item = (CheckboxMenuItem) chainMenu.getItem(i);\r
-        if (item.getState())\r
-          cmd.append(":" + item.getLabel() + " or ");\r
-      }\r
-    }\r
-\r
-    if (cmd.length() > 0)\r
-      cmd.setLength(cmd.length() - 4);\r
-\r
-    viewer.evalString("select *;restrict "\r
-                      + cmd + ";cartoon;center " + cmd);\r
-  }\r
-\r
-\r
-  void closeViewer()\r
-  {\r
-    viewer.setModeMouse(org.jmol.viewer.JmolConstants.MOUSE_NONE);\r
-    viewer.evalStringQuiet("zap");\r
-    viewer.setJmolStatusListener(null);\r
-    viewer = null;\r
-\r
-    //We'll need to find out what other\r
-    // listeners need to be shut down in Jmol\r
-    StructureSelectionManager\r
-        .getStructureSelectionManager()\r
-        .removeStructureViewerListener(this, pdbentry.getId());\r
-\r
-    this.setVisible(false);\r
-  }\r
-\r
-  public void actionPerformed(ActionEvent evt)\r
-  {\r
-    if(evt.getSource()==mappingMenuItem)\r
-    {\r
-      jalview.appletgui.CutAndPasteTransfer cap\r
-          = new jalview.appletgui.CutAndPasteTransfer(false, null);\r
-      Frame frame = new Frame();\r
-      frame.add(cap);\r
-\r
-      jalview.bin.JalviewLite.addFrame(frame, "PDB - Sequence Mapping", 550,\r
-                                       600);\r
-      cap.setText(\r
-          StructureSelectionManager.getStructureSelectionManager().printMapping(\r
-              pdbentry.getFile())\r
-          );\r
-    }\r
-    else\r
-    {\r
-      allChainsSelected = true;\r
-      for (int i = 0; i < chainMenu.getItemCount(); i++)\r
-      {\r
-        if (chainMenu.getItem(i) instanceof CheckboxMenuItem)\r
-          ( (CheckboxMenuItem) chainMenu.getItem(i)).setState(true);\r
-      }\r
-      centerViewer();\r
-      allChainsSelected = false;\r
-    }\r
-  }\r
-\r
-  public void itemStateChanged(ItemEvent evt)\r
-  {\r
-    if (!allChainsSelected)\r
-      centerViewer();\r
-  }\r
-\r
-  public void keyPressed(KeyEvent evt)\r
-  {\r
-    if (evt.getKeyCode() == KeyEvent.VK_ENTER\r
-        && scriptWindow.isVisible())\r
-    {\r
-      viewer.evalString(inputLine.getText());\r
-      history.append("\n$ "+inputLine.getText());\r
-      inputLine.setText("");\r
-    }\r
-\r
-  }\r
-\r
-  public void keyTyped(KeyEvent evt)\r
-  {  }\r
-\r
-  public void keyReleased(KeyEvent evt){}\r
-\r
-  //////////////////////////////////\r
-  ///StructureListener\r
-  public String getPdbFile()\r
-  {\r
-    return "???";\r
-  }\r
-\r
-\r
-\r
-  String lastMessage;\r
-  public void mouseOverStructure(int atomIndex, String strInfo)\r
-  {\r
-      int pdbResNum = Integer.parseInt(\r
-          strInfo.substring(strInfo.indexOf("]")+ 1, strInfo.indexOf(":")));\r
-\r
-      String chainId = strInfo.substring\r
-          (strInfo.indexOf(":"), strInfo.indexOf("."));\r
-\r
-      if (chainId != null)\r
-        chainId = chainId.substring(1, chainId.length());\r
-      else\r
-      {\r
-        chainId = " ";\r
-      }\r
-\r
-      if (lastMessage == null || !lastMessage.equals(strInfo))\r
-        ssm.mouseOverStructure(pdbResNum, chainId, pdbentry.getFile());\r
-\r
-      lastMessage = strInfo;\r
-  }\r
-\r
-  StringBuffer resetLastRes = new StringBuffer();\r
-  StringBuffer eval = new StringBuffer();\r
-\r
-  public void highlightAtom(int atomIndex, int pdbResNum, String chain, String pdbfile)\r
-  {\r
-    if (!pdbfile.equals(pdbentry.getFile()))\r
-      return;\r
-\r
-    if (resetLastRes.length() > 0)\r
-    {\r
-      viewer.evalStringQuiet(resetLastRes.toString());\r
-    }\r
-\r
-    eval.setLength(0);\r
-    eval.append("select " + pdbResNum);\r
-\r
-    resetLastRes.setLength(0);\r
-    resetLastRes.append("select " + pdbResNum);\r
-\r
-    if (!chain.equals(" "))\r
-    {\r
-      eval.append(":" + chain);\r
-      resetLastRes.append(":" + chain);\r
-    }\r
-\r
-    eval.append(";color gold;wireframe 100");\r
-\r
-    Color col = new Color(viewer.getAtomArgb(atomIndex));\r
-\r
-    resetLastRes.append(";color["\r
-                        + col.getRed() + ","\r
-                        + col.getGreen() + ","\r
-                        + col.getBlue() + "];wireframe 0");\r
-\r
-    viewer.evalStringQuiet(eval.toString());\r
-\r
-  }\r
-\r
-  public void updateColours(Object source)\r
-  {\r
-    colourBySequence( (AlignmentPanel) source);\r
-  }\r
-\r
-//End StructureListener\r
-////////////////////////////\r
-\r
-  FeatureRenderer fr;\r
-  public void colourBySequence(AlignmentPanel ap)\r
-  {\r
-    if(!colourBySequence)\r
-      return;\r
-\r
-\r
-    StructureMapping[] mapping = ssm.getMapping(pdbentry.getFile());\r
-\r
-    if (mapping.length < 1)\r
-      return;\r
-\r
-    SequenceRenderer sr = ap.seqPanel.seqCanvas.getSequenceRenderer();\r
-\r
-    boolean showFeatures = false;\r
-    if (ap.av.showSequenceFeatures)\r
-    {\r
-      showFeatures = true;\r
-      if (fr == null)\r
-      {\r
-        fr = new jalview.appletgui.FeatureRenderer(ap.av);\r
-      }\r
-\r
-      fr.transferSettings(ap.seqPanel.seqCanvas.getFeatureRenderer());\r
-    }\r
-\r
-    StringBuffer command = new StringBuffer();\r
-\r
-    int lastPos = -1;\r
-    for (int s = 0; s < sequence.length; s++)\r
-    {\r
-      for (int m = 0; m < mapping.length; m++)\r
-      {\r
-        if (mapping[m].getSequence() == sequence[s])\r
-        {\r
-          for (int r = 0; r < sequence[s].getLength(); r++)\r
-          {\r
-            int pos = mapping[m].getPDBResNum(\r
-                sequence[s].findPosition(r));\r
-\r
-            if (pos < 1 || pos==lastPos)\r
-              continue;\r
-\r
-            lastPos = pos;\r
-\r
-            Color col = sr.getResidueBoxColour(sequence[s], r);\r
-\r
-            if (showFeatures)\r
-              col = fr.findFeatureColour(col, sequence[s], r);\r
-\r
-            if (command.toString().endsWith(":" + mapping[m].getChain()+\r
-                                            ";color["\r
-                                            + col.getRed() + ","\r
-                                            + col.getGreen() + ","\r
-                                            + col.getBlue() + "]"))\r
-            {\r
-              command = condenseCommand(command.toString(), pos);\r
-              continue;\r
-            }\r
-\r
-            command.append(";select " + pos);\r
-\r
-            if (!mapping[m].getChain().equals(" "))\r
-            {\r
-              command.append(":" + mapping[m].getChain());\r
-            }\r
-\r
-            command.append(";color["\r
-                             + col.getRed() + ","\r
-                             + col.getGreen() + ","\r
-                             + col.getBlue() + "]");\r
-\r
-          }\r
-          break;\r
-        }\r
-      }\r
-    }\r
-\r
-    viewer.evalStringQuiet(command.toString());\r
-  }\r
-\r
-  StringBuffer condenseCommand(String command, int pos)\r
-  {\r
-\r
-    StringBuffer sb = new StringBuffer(command.substring(0, command.lastIndexOf("select")+7));\r
-\r
-    command = command.substring(sb.length());\r
-\r
-    String start;\r
-\r
-    if (command.indexOf("-") > -1)\r
-    {\r
-      start = command.substring(0,command.indexOf("-"));\r
-    }\r
-    else\r
-    {\r
-      start = command.substring(0, command.indexOf(":"));\r
-    }\r
-\r
-    sb.append(start+"-"+pos+command.substring(command.indexOf(":")));\r
-\r
-    return sb;\r
-  }\r
-\r
-  /////////////////////////////////\r
-  //JmolStatusListener\r
-\r
-  public String eval(String strEval)\r
-  {\r
-   // System.out.println(strEval);\r
-   //"# 'eval' is implemented only for the applet.";\r
-    return null;\r
-  }\r
-\r
-  public void createImage(String file, String type, int quality)\r
-  {}\r
-\r
-  public void setCallbackFunction(String callbackType,\r
-                                  String callbackFunction)\r
-  {}\r
-\r
-  public void notifyFileLoaded(String fullPathName, String fileName,\r
-                               String modelName, Object clientFile,\r
-                               String errorMsg)\r
-  {\r
-    if(errorMsg!=null)\r
-    {\r
-      fileLoadingError = errorMsg;\r
-      repaint();\r
-      return;\r
-    }\r
-\r
-    fileLoadingError = null;\r
-\r
-    if (fileName != null)\r
-    {\r
-      //FILE LOADED OK\r
-      jmolpopup.updateComputedMenus();\r
-            viewer.evalStringQuiet(\r
-          "select backbone;restrict;cartoon;wireframe off;spacefill off");\r
-\r
-      ssm = StructureSelectionManager.getStructureSelectionManager();\r
-\r
-      MCview.PDBfile pdb;\r
-      if (loadedInline)\r
-      {\r
-        pdb = ssm.setMapping(sequence,\r
-                                pdbentry.getFile(),\r
-                                AppletFormatAdapter.PASTE);\r
-        pdbentry.setFile("INLINE"+pdb.id);\r
-      }\r
-      else\r
-      {\r
-         pdb = ssm.setMapping(sequence,\r
-                              pdbentry.getFile(),\r
-                              AppletFormatAdapter.URL);\r
-      }\r
-\r
-      pdbentry.setId(pdb.id);\r
-\r
-      ssm.addStructureViewerListener(this);\r
-\r
-      Vector chains = new Vector();\r
-      for (int i = 0; i < pdb.chains.size(); i++)\r
-      {\r
-        chains.addElement( ( (MCview.PDBChain) pdb.chains.elementAt(i)).id);\r
-      }\r
-      setChainMenuItems(chains);\r
-\r
-      colourBySequence(ap);\r
-\r
-      StringBuffer title = new StringBuffer(sequence[0].getName() + ":" +\r
-                                            pdbentry.getId());\r
-\r
-      if (pdbentry.getProperty() != null)\r
-      {\r
-        if (pdbentry.getProperty().get("method") != null)\r
-        {\r
-          title.append(" Method: ");\r
-          title.append(pdbentry.getProperty().get("method"));\r
-        }\r
-        if (pdbentry.getProperty().get("chains") != null)\r
-        {\r
-          title.append(" Chain:");\r
-          title.append(pdbentry.getProperty().get("chains"));\r
-        }\r
-      }\r
-\r
-      this.setTitle(title.toString());\r
-\r
-    }\r
-    else\r
-      return;\r
-  }\r
-\r
-  public void notifyFrameChanged(int frameNo)\r
-  {\r
-    boolean isAnimationRunning = (frameNo <= -2);\r
-  }\r
-\r
-  public void notifyScriptStart(String statusMessage, String additionalInfo)\r
-  {}\r
-\r
-  public void sendConsoleEcho(String strEcho)\r
-  {\r
-  //  if (scriptWindow != null)\r
-   //   scriptWindow.sendConsoleEcho(strEcho);\r
-  }\r
-\r
-  public void sendConsoleMessage(String strStatus)\r
-  {\r
-    if(history!=null && strStatus!=null\r
-       && !strStatus.equals("Script completed"))\r
-    {\r
-      history.append("\n"+strStatus);\r
-    }\r
-  }\r
-\r
-  public void notifyScriptTermination(String strStatus, int msWalltime)\r
-  {\r
-   // if (scriptWindow != null)\r
-   //   scriptWindow.notifyScriptTermination(strStatus, msWalltime);\r
-  }\r
-\r
-  public void handlePopupMenu(int x, int y)\r
-  {\r
-    jmolpopup.show(x, y);\r
-  }\r
-\r
-  public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)\r
-  {\r
-    notifyAtomPicked(iatom, strMeasure);\r
-  }\r
-\r
-  public void notifyNewDefaultModeMeasurement(int count, String strInfo)\r
-  {}\r
-\r
-  public void notifyAtomPicked(int atomIndex, String strInfo)\r
-  {\r
-   // if (scriptWindow != null)\r
-    {\r
-   //   scriptWindow.sendConsoleMessage(strInfo);\r
-   //   scriptWindow.sendConsoleMessage("\n");\r
-    }\r
-  }\r
-\r
-  public void notifyAtomHovered(int atomIndex, String strInfo)\r
-  {\r
-    mouseOverStructure(atomIndex, strInfo);\r
-  }\r
-\r
-  public void sendSyncScript(String script, String appletName)\r
-  {}\r
-\r
-  public void showUrl(String url)\r
-  {}\r
-\r
-  public void showConsole(boolean showConsole)\r
-  {\r
-    if (scriptWindow == null)\r
-    {\r
-      scriptWindow = new Panel(new BorderLayout());\r
-      inputLine = new TextField();\r
-      history = new TextArea(5, 40);\r
-      scriptWindow.add(history, BorderLayout.CENTER);\r
-      scriptWindow.add(inputLine, BorderLayout.SOUTH);\r
-      add(scriptWindow, BorderLayout.SOUTH);\r
-      scriptWindow.setVisible(false);\r
-      history.setEditable(false);\r
-      inputLine.addKeyListener(this);\r
-    }\r
-\r
-    scriptWindow.setVisible(!scriptWindow.isVisible());\r
-    validate();\r
-  }\r
-\r
-  public float functionXY(String functionName, int x, int y)\r
-  {\r
-    return 0;\r
-  }\r
-\r
-  ///End JmolStatusListener\r
-  ///////////////////////////////\r
-\r
-\r
-  class RenderPanel\r
-      extends Panel\r
-  {\r
-    Dimension currentSize = new Dimension();\r
-    Rectangle rectClip = new Rectangle();\r
-\r
-    public void update(Graphics g) {\r
-      paint(g);\r
-    }\r
-    public void paint(Graphics g)\r
-    {\r
-      currentSize = this.getSize();\r
-      rectClip = g.getClipBounds();\r
-\r
-      if (viewer == null)\r
-      {\r
-        g.setColor(Color.black);\r
-        g.fillRect(0, 0, currentSize.width, currentSize.height);\r
-        g.setColor(Color.white);\r
-        g.setFont(new Font("Verdana", Font.BOLD, 14));\r
-        g.drawString("Retrieving PDB data....", 20, currentSize.height / 2);\r
-      }\r
-      else\r
-      {\r
-        viewer.renderScreenImage(g, currentSize, rectClip);\r
-      }\r
-    }\r
-  }\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.9.0b2)
+ * Copyright (C) 2015 The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview is distributed in the hope that it will be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty 
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+ * PURPOSE.  See the GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.appletgui;
+
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.SequenceI;
+import jalview.io.AppletFormatAdapter;
+import jalview.io.FileParse;
+import jalview.io.StructureFile;
+import jalview.schemes.BuriedColourScheme;
+import jalview.schemes.HelixColourScheme;
+import jalview.schemes.HydrophobicColourScheme;
+import jalview.schemes.PurinePyrimidineColourScheme;
+import jalview.schemes.StrandColourScheme;
+import jalview.schemes.TaylorColourScheme;
+import jalview.schemes.TurnColourScheme;
+import jalview.schemes.UserColourScheme;
+import jalview.schemes.ZappoColourScheme;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.MessageManager;
+
+import java.awt.BorderLayout;
+import java.awt.CheckboxMenuItem;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuItem;
+import java.awt.Panel;
+import java.awt.TextArea;
+import java.awt.TextField;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.KeyListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+public class AppletJmol extends EmbmenuFrame implements
+// StructureListener,
+        KeyListener, ActionListener, ItemListener
+
+{
+  Menu fileMenu = new Menu(MessageManager.getString("action.file"));
+
+  Menu viewMenu = new Menu(MessageManager.getString("action.view"));
+
+  Menu coloursMenu = new Menu(MessageManager.getString("action.colour"));
+
+  Menu chainMenu = new Menu(MessageManager.getString("action.show_chain"));
+
+  Menu helpMenu = new Menu(MessageManager.getString("action.help"));
+
+  MenuItem mappingMenuItem = new MenuItem(
+          MessageManager.getString("label.view_mapping"));
+
+  CheckboxMenuItem seqColour = new CheckboxMenuItem(
+          MessageManager.getString("action.by_sequence"), true);
+
+  CheckboxMenuItem jmolColour = new CheckboxMenuItem(
+          MessageManager.getString("action.using_jmol"), false);
+
+  MenuItem chain = new MenuItem(MessageManager.getString("action.by_chain"));
+
+  MenuItem charge = new MenuItem(
+          MessageManager.getString("label.charge_cysteine"));
+
+  MenuItem zappo = new MenuItem(MessageManager.getString("label.zappo"));
+
+  MenuItem taylor = new MenuItem(MessageManager.getString("label.taylor"));
+
+  MenuItem hydro = new MenuItem(
+          MessageManager.getString("label.hydrophobicity"));
+
+  MenuItem helix = new MenuItem(
+          MessageManager.getString("label.helix_propensity"));
+
+  MenuItem strand = new MenuItem(
+          MessageManager.getString("label.strand_propensity"));
+
+  MenuItem turn = new MenuItem(
+          MessageManager.getString("label.turn_propensity"));
+
+  MenuItem buried = new MenuItem(
+          MessageManager.getString("label.buried_index"));
+
+  MenuItem purinepyrimidine = new MenuItem(
+          MessageManager.getString("label.purine_pyrimidine"));
+
+  MenuItem user = new MenuItem(
+          MessageManager.getString("label.user_defined_colours"));
+
+  MenuItem jmolHelp = new MenuItem(
+          MessageManager.getString("label.jmol_help"));
+
+  Panel scriptWindow;
+
+  TextField inputLine;
+
+  TextArea history;
+
+  RenderPanel renderPanel;
+
+  AlignmentPanel ap;
+
+  List<AlignmentPanel> _aps = new ArrayList<AlignmentPanel>(); // remove? never
+                                                               // added to
+
+  String fileLoadingError;
+
+  boolean loadedInline;
+
+  // boolean colourBySequence = true;
+
+  FeatureRenderer fr = null;
+
+  AppletJmolBinding jmb;
+
+  /**
+   * datasource protocol for access to PDBEntry
+   */
+  String protocol = null;
+
+  /**
+   * Load a bunch of pdb entries associated with sequences in the alignment and
+   * display them - aligning them if necessary.
+   * 
+   * @param pdbentries
+   *          each pdb file (at least one needed)
+   * @param boundseqs
+   *          each set of sequences for each pdb file (must match number of pdb
+   *          files)
+   * @param boundchains
+   *          the target pdb chain corresponding with each sequence associated
+   *          with each pdb file (may be null at any level)
+   * @param align
+   *          true/false
+   * @param ap
+   *          associated alignment
+   * @param protocol
+   *          how to get pdb data
+   */
+  public AppletJmol(PDBEntry[] pdbentries, SequenceI[][] boundseqs,
+          String[][] boundchains, boolean align, AlignmentPanel ap,
+          String protocol)
+  {
+    throw new Error(MessageManager.getString("error.not_yet_implemented"));
+  }
+
+  public AppletJmol(PDBEntry pdbentry, SequenceI[] seq, String[] chains,
+          AlignmentPanel ap, String protocol)
+  {
+    this.ap = ap;
+    jmb = new AppletJmolBinding(this, ap.getStructureSelectionManager(),
+            new PDBEntry[] { pdbentry }, new SequenceI[][] { seq },
+            new String[][] { chains }, protocol);
+    jmb.setColourBySequence(true);
+    if (pdbentry.getId() == null || pdbentry.getId().length() < 1)
+    {
+      if (protocol.equals(AppletFormatAdapter.PASTE))
+      {
+        pdbentry.setId("PASTED PDB"
+                + (chains == null ? "_" : chains.toString()));
+      }
+      else
+      {
+        pdbentry.setId(pdbentry.getFile());
+      }
+    }
+
+    if (jalview.bin.JalviewLite.debug)
+    {
+      System.err
+              .println("AppletJmol: PDB ID is '" + pdbentry.getId() + "'");
+    }
+
+    String alreadyMapped = StructureSelectionManager
+            .getStructureSelectionManager(ap.av.applet)
+            .alreadyMappedToFile(pdbentry.getId());
+    StructureFile reader = null;
+    if (alreadyMapped != null)
+    {
+      reader = StructureSelectionManager.getStructureSelectionManager(
+              ap.av.applet).setMapping(seq, chains, pdbentry.getFile(),
+              protocol);
+      // PROMPT USER HERE TO ADD TO NEW OR EXISTING VIEW?
+      // FOR NOW, LETS JUST OPEN A NEW WINDOW
+    }
+    MenuBar menuBar = new MenuBar();
+    menuBar.add(fileMenu);
+    fileMenu.add(mappingMenuItem);
+    menuBar.add(viewMenu);
+    mappingMenuItem.addActionListener(this);
+    viewMenu.add(chainMenu);
+    menuBar.add(coloursMenu);
+    menuBar.add(helpMenu);
+
+    charge.addActionListener(this);
+    hydro.addActionListener(this);
+    chain.addActionListener(this);
+    seqColour.addItemListener(this);
+    jmolColour.addItemListener(this);
+    zappo.addActionListener(this);
+    taylor.addActionListener(this);
+    helix.addActionListener(this);
+    strand.addActionListener(this);
+    turn.addActionListener(this);
+    buried.addActionListener(this);
+    purinepyrimidine.addActionListener(this);
+    user.addActionListener(this);
+
+    jmolHelp.addActionListener(this);
+
+    coloursMenu.add(seqColour);
+    coloursMenu.add(chain);
+    coloursMenu.add(charge);
+    coloursMenu.add(zappo);
+    coloursMenu.add(taylor);
+    coloursMenu.add(hydro);
+    coloursMenu.add(helix);
+    coloursMenu.add(strand);
+    coloursMenu.add(turn);
+    coloursMenu.add(buried);
+    coloursMenu.add(purinepyrimidine);
+    coloursMenu.add(user);
+    coloursMenu.add(jmolColour);
+    helpMenu.add(jmolHelp);
+    this.setLayout(new BorderLayout());
+
+    setMenuBar(menuBar);
+
+    renderPanel = new RenderPanel();
+    embedMenuIfNeeded(renderPanel);
+    this.add(renderPanel, BorderLayout.CENTER);
+    scriptWindow = new Panel();
+    scriptWindow.setVisible(false);
+    // this.add(scriptWindow, BorderLayout.SOUTH);
+
+    try
+    {
+      jmb.allocateViewer(renderPanel, true, ap.av.applet.getName()
+              + "_jmol_", ap.av.applet.getDocumentBase(),
+              ap.av.applet.getCodeBase(), "-applet", scriptWindow, null);
+    } catch (Exception e)
+    {
+      System.err
+              .println("Couldn't create a jmol viewer. Args to allocate viewer were:\nDocumentBase="
+                      + ap.av.applet.getDocumentBase()
+                      + "\nCodebase="
+                      + ap.av.applet.getCodeBase());
+      e.printStackTrace();
+      dispose();
+      return;
+    }
+    // jmb.newJmolPopup(true, "Jmol", true);
+
+    this.addWindowListener(new WindowAdapter()
+    {
+      @Override
+      public void windowClosing(WindowEvent evt)
+      {
+        closeViewer();
+      }
+    });
+    pdbentry.setProperty("protocol", protocol);
+
+    if (pdbentry.getFile() != null)
+    {
+      // import structure data from pdbentry.getFile based on given protocol
+      if (protocol.equals(AppletFormatAdapter.PASTE))
+      {
+        // TODO: JAL-623 : correctly record file contents for matching up later
+        // pdbentry.getProperty().put("pdbfilehash",""+pdbentry.getFile().hashCode());
+        loadInline(pdbentry.getFile());
+      }
+      else if (protocol.equals(AppletFormatAdapter.FILE)
+              || protocol.equals(AppletFormatAdapter.URL))
+      {
+        jmb.viewer.openFile(pdbentry.getFile());
+      }
+      else
+      {
+        // probably CLASSLOADER based datasource..
+        // Try and get a reader on the datasource, and pass that to Jmol
+        try
+        {
+          java.io.Reader freader = null;
+          if (reader != null)
+          {
+            if (jalview.bin.JalviewLite.debug)
+            {
+              System.err
+                      .println("AppletJmol:Trying to reuse existing PDBfile IO parser.");
+            }
+            // re-use the one we opened earlier
+            freader = reader.getReader();
+          }
+          if (freader == null)
+          {
+            if (jalview.bin.JalviewLite.debug)
+            {
+              System.err
+                      .println("AppletJmol:Creating new PDBfile IO parser.");
+            }
+            FileParse fp = new FileParse(pdbentry.getFile(), protocol);
+            fp.mark();
+            // reader = new MCview.PDBfile(fp);
+            // could set ID, etc.
+            // if (!reader.isValid())
+            // {
+            // throw new Exception("Invalid datasource.
+            // "+reader.getWarningMessage());
+            // }
+            // fp.reset();
+            freader = fp.getReader();
+          }
+          if (freader == null)
+          {
+            throw new Exception(
+                    MessageManager
+                            .getString("exception.invalid_datasource_couldnt_obtain_reader"));
+          }
+          jmb.viewer.openReader(pdbentry.getFile(), pdbentry.getId(),
+                  freader);
+        } catch (Exception e)
+        {
+          // give up!
+          System.err.println("Couldn't access pdbentry id="
+                  + pdbentry.getId() + " and file=" + pdbentry.getFile()
+                  + " using protocol=" + protocol);
+          e.printStackTrace();
+        }
+      }
+    }
+
+    jalview.bin.JalviewLite.addFrame(this, jmb.getViewerTitle(), 400, 400);
+  }
+
+  public void loadInline(String string)
+  {
+    loadedInline = true;
+    jmb.loadInline(string);
+  }
+
+  void setChainMenuItems(Vector<String> chains)
+  {
+    chainMenu.removeAll();
+
+    MenuItem menuItem = new MenuItem(MessageManager.getString("label.all"));
+    menuItem.addActionListener(this);
+
+    chainMenu.add(menuItem);
+
+    CheckboxMenuItem menuItemCB;
+    for (String ch : chains)
+    {
+      menuItemCB = new CheckboxMenuItem(ch, true);
+      menuItemCB.addItemListener(this);
+      chainMenu.add(menuItemCB);
+    }
+  }
+
+  boolean allChainsSelected = false;
+
+  void centerViewer()
+  {
+    Vector<String> toshow = new Vector<String>();
+    for (int i = 0; i < chainMenu.getItemCount(); i++)
+    {
+      if (chainMenu.getItem(i) instanceof CheckboxMenuItem)
+      {
+        CheckboxMenuItem item = (CheckboxMenuItem) chainMenu.getItem(i);
+        if (item.getState())
+        {
+          toshow.addElement(item.getLabel());
+        }
+      }
+    }
+    jmb.centerViewer(toshow);
+  }
+
+  void closeViewer()
+  {
+    jmb.closeViewer();
+    jmb = null;
+    this.setVisible(false);
+  }
+
+  @Override
+  public void actionPerformed(ActionEvent evt)
+  {
+    if (evt.getSource() == mappingMenuItem)
+    {
+      jalview.appletgui.CutAndPasteTransfer cap = new jalview.appletgui.CutAndPasteTransfer(
+              false, null);
+      Frame frame = new Frame();
+      frame.add(cap);
+
+      StringBuffer sb = new StringBuffer();
+      try
+      {
+        cap.setText(jmb.printMappings());
+      } catch (OutOfMemoryError ex)
+      {
+        frame.dispose();
+        System.err
+                .println("Out of memory when trying to create dialog box with sequence-structure mapping.");
+        return;
+      }
+      jalview.bin.JalviewLite.addFrame(frame,
+              MessageManager.getString("label.pdb_sequence_mapping"), 550,
+              600);
+    }
+    else if (evt.getSource() == charge)
+    {
+      setEnabled(charge);
+      jmb.colourByCharge();
+    }
+
+    else if (evt.getSource() == chain)
+    {
+      setEnabled(chain);
+      jmb.colourByChain();
+    }
+    else if (evt.getSource() == zappo)
+    {
+      setEnabled(zappo);
+      jmb.setJalviewColourScheme(new ZappoColourScheme());
+    }
+    else if (evt.getSource() == taylor)
+    {
+      setEnabled(taylor);
+      jmb.setJalviewColourScheme(new TaylorColourScheme());
+    }
+    else if (evt.getSource() == hydro)
+    {
+      setEnabled(hydro);
+      jmb.setJalviewColourScheme(new HydrophobicColourScheme());
+    }
+    else if (evt.getSource() == helix)
+    {
+      setEnabled(helix);
+      jmb.setJalviewColourScheme(new HelixColourScheme());
+    }
+    else if (evt.getSource() == strand)
+    {
+      setEnabled(strand);
+      jmb.setJalviewColourScheme(new StrandColourScheme());
+    }
+    else if (evt.getSource() == turn)
+    {
+      setEnabled(turn);
+      jmb.setJalviewColourScheme(new TurnColourScheme());
+    }
+    else if (evt.getSource() == buried)
+    {
+      setEnabled(buried);
+      jmb.setJalviewColourScheme(new BuriedColourScheme());
+    }
+    else if (evt.getSource() == purinepyrimidine)
+    {
+      jmb.setJalviewColourScheme(new PurinePyrimidineColourScheme());
+    }
+    else if (evt.getSource() == user)
+    {
+      setEnabled(user);
+      new UserDefinedColours(this);
+    }
+    else if (evt.getSource() == jmolHelp)
+    {
+      try
+      {
+        ap.av.applet.getAppletContext().showDocument(
+                new java.net.URL(
+                        "http://jmol.sourceforge.net/docs/JmolUserGuide/"),
+                "jmolHelp");
+      } catch (java.net.MalformedURLException ex)
+      {
+      }
+    }
+    else
+    {
+      allChainsSelected = true;
+      for (int i = 0; i < chainMenu.getItemCount(); i++)
+      {
+        if (chainMenu.getItem(i) instanceof CheckboxMenuItem)
+        {
+          ((CheckboxMenuItem) chainMenu.getItem(i)).setState(true);
+        }
+      }
+
+      centerViewer();
+      allChainsSelected = false;
+    }
+  }
+
+  /**
+   * tick or untick the seqColour menu entry or jmoColour entry depending upon
+   * if it was selected or not.
+   * 
+   * @param itm
+   */
+  private void setEnabled(MenuItem itm)
+  {
+    jmolColour.setState(itm == jmolColour);
+    seqColour.setState(itm == seqColour);
+    jmb.setColourBySequence(itm == seqColour);
+  }
+
+  @Override
+  public void itemStateChanged(ItemEvent evt)
+  {
+    if (evt.getSource() == jmolColour)
+    {
+      setEnabled(jmolColour);
+      jmb.setColourBySequence(false);
+    }
+    else if (evt.getSource() == seqColour)
+    {
+      setEnabled(seqColour);
+      jmb.colourBySequence(ap);
+    }
+    else if (!allChainsSelected)
+    {
+      centerViewer();
+    }
+  }
+
+  @Override
+  public void keyPressed(KeyEvent evt)
+  {
+    if (evt.getKeyCode() == KeyEvent.VK_ENTER && scriptWindow.isVisible())
+    {
+      jmb.eval(inputLine.getText());
+      addToHistory("$ " + inputLine.getText());
+      inputLine.setText("");
+    }
+
+  }
+
+  @Override
+  public void keyTyped(KeyEvent evt)
+  {
+  }
+
+  @Override
+  public void keyReleased(KeyEvent evt)
+  {
+  }
+
+  public void updateColours(Object source)
+  {
+    AlignmentPanel panel = (AlignmentPanel) source;
+    jmb.colourBySequence(panel);
+  }
+
+  public void updateTitleAndMenus()
+  {
+    if (jmb.fileLoadingError != null && jmb.fileLoadingError.length() > 0)
+    {
+      repaint();
+      return;
+    }
+    setChainMenuItems(jmb.chainNames);
+    jmb.colourBySequence(ap);
+
+    setTitle(jmb.getViewerTitle());
+  }
+
+  public void showUrl(String url)
+  {
+    try
+    {
+      ap.av.applet.getAppletContext().showDocument(new java.net.URL(url),
+              "jmolOutput");
+    } catch (java.net.MalformedURLException ex)
+    {
+    }
+  }
+
+  Panel splitPane = null;
+
+  public void showConsole(boolean showConsole)
+  {
+    if (showConsole)
+    {
+      remove(renderPanel);
+      splitPane = new Panel();
+
+      splitPane.setLayout(new java.awt.GridLayout(2, 1));
+      splitPane.add(renderPanel);
+      splitPane.add(scriptWindow);
+      scriptWindow.setVisible(true);
+      this.add(splitPane, BorderLayout.CENTER);
+      splitPane.setVisible(true);
+      splitPane.validate();
+    }
+    else
+    {
+      scriptWindow.setVisible(false);
+      remove(splitPane);
+      add(renderPanel, BorderLayout.CENTER);
+      splitPane = null;
+    }
+    validate();
+  }
+
+  public float[][] functionXY(String functionName, int x, int y)
+  {
+    return null;
+  }
+
+  // /End JmolStatusListener
+  // /////////////////////////////
+
+  class RenderPanel extends Panel
+  {
+    Dimension currentSize = new Dimension();
+
+    @Override
+    public void update(Graphics g)
+    {
+      paint(g);
+    }
+
+    @Override
+    public void paint(Graphics g)
+    {
+      currentSize = this.getSize();
+
+      if (jmb.viewer == null)
+      {
+        g.setColor(Color.black);
+        g.fillRect(0, 0, currentSize.width, currentSize.height);
+        g.setColor(Color.white);
+        g.setFont(new Font("Verdana", Font.BOLD, 14));
+        g.drawString(MessageManager.getString("label.retrieving_pdb_data"),
+                20, currentSize.height / 2);
+      }
+      else
+      {
+        jmb.viewer.renderScreenImage(g, currentSize.width,
+                currentSize.height);
+      }
+    }
+  }
+
+  /*
+   * @Override public Color getColour(int atomIndex, int pdbResNum, String
+   * chain, String pdbId) { return jmb.getColour(atomIndex, pdbResNum, chain,
+   * pdbId); }
+   * 
+   * @Override public String[] getPdbFile() { return jmb.getPdbFile(); }
+   * 
+   * @Override public void highlightAtom(int atomIndex, int pdbResNum, String
+   * chain, String pdbId) { jmb.highlightAtom(atomIndex, pdbResNum, chain,
+   * pdbId);
+   * 
+   * }
+   * 
+   * @Override public void mouseOverStructure(int atomIndex, String strInfo) {
+   * jmb.mouseOverStructure(atomIndex, strInfo);
+   * 
+   * }
+   */
+  public void setJalviewColourScheme(UserColourScheme ucs)
+  {
+    jmb.setJalviewColourScheme(ucs);
+  }
+
+  public AlignmentPanel getAlignmentPanelFor(AlignmentI alignment)
+  {
+    for (int i = 0; i < _aps.size(); i++)
+    {
+      if (_aps.get(i).av.getAlignment() == alignment)
+      {
+        return (_aps.get(i));
+      }
+    }
+    return ap;
+  }
+
+  /**
+   * Append the given text to the history object
+   * 
+   * @param text
+   */
+  public void addToHistory(String text)
+  {
+    // actually currently never initialised
+    if (history != null)
+    {
+      history.append("\n" + text);
+    }
+  }
+}