caching of DnD files dropped
[jalview.git] / src / jalview / gui / AlignFrame.java
index 7dbed05..77b8552 100644 (file)
@@ -24,6 +24,7 @@ import jalview.analysis.AlignmentSorter;
 import jalview.analysis.AlignmentUtils;
 import jalview.analysis.CrossRef;
 import jalview.analysis.Dna;
+import jalview.analysis.GeneticCodeI;
 import jalview.analysis.ParseProperties;
 import jalview.analysis.SequenceIdMatcher;
 import jalview.api.AlignExportSettingsI;
@@ -64,6 +65,7 @@ import jalview.gui.ColourMenuHelper.ColourChangeListener;
 import jalview.gui.ViewSelectionMenu.ViewSetProvider;
 import jalview.io.AlignmentProperties;
 import jalview.io.AnnotationFile;
+import jalview.io.BackupFiles;
 import jalview.io.BioJsHTMLOutput;
 import jalview.io.DataSourceType;
 import jalview.io.FileFormat;
@@ -83,13 +85,14 @@ import jalview.io.ScoreMatrixFile;
 import jalview.io.TCoffeeScoreFile;
 import jalview.io.vcf.VCFLoader;
 import jalview.jbgui.GAlignFrame;
+import jalview.project.Jalview2XML;
 import jalview.schemes.ColourSchemeI;
 import jalview.schemes.ColourSchemes;
 import jalview.schemes.ResidueColourScheme;
 import jalview.schemes.TCoffeeColourScheme;
 import jalview.util.ImageMaker.TYPE;
 import jalview.util.MessageManager;
-import jalview.util.dialogrunner.RunResponse;
+import jalview.util.Platform;
 import jalview.viewmodel.AlignmentViewport;
 import jalview.viewmodel.ViewportRanges;
 import jalview.ws.DBRefFetcher;
@@ -137,6 +140,7 @@ import java.util.Hashtable;
 import java.util.List;
 import java.util.Vector;
 
+import javax.swing.ButtonGroup;
 import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JComponent;
 import javax.swing.JEditorPane;
@@ -149,12 +153,15 @@ import javax.swing.JPanel;
 import javax.swing.JScrollPane;
 import javax.swing.SwingUtilities;
 
+import ext.vamsas.ServiceHandle;
+
 /**
  * DOCUMENT ME!
  * 
  * @author $author$
  * @version $Revision$
  */
+@SuppressWarnings("serial")
 public class AlignFrame extends GAlignFrame implements DropTargetListener,
         IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener
 {
@@ -338,6 +345,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    */
   void init()
   {
+//       setBackground(Color.white); // BH 2019
+                 
     if (!Jalview.isHeadlessMode())
     {
       progressBar = new ProgressBar(this.statusPanel, this.statusBar);
@@ -386,12 +395,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     if (Desktop.desktop != null)
     {
       this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
-      /**
-       * BH 2018 ignore service listeners
-       * 
-       * @j2sNative
-       * 
-       */
+      if (!Platform.isJS())
       {
         addServiceListeners();
       }
@@ -622,7 +626,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         case KeyEvent.VK_BACK_SPACE:
           if (!viewport.cursorMode)
           {
-            cut_actionPerformed(null);
+            cut_actionPerformed();
           }
           else
           {
@@ -845,7 +849,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         Desktop.instance.removeJalviewPropertyChangeListener("services",
                 thisListener);
         closeMenuItem_actionPerformed(true);
-      };
+      }
     });
     // Finally, build the menu once to get current service state
     new Thread(new Runnable()
@@ -990,10 +994,15 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     return progressBar.operationInProgress();
   }
 
+  /**
+   * Sets the text of the status bar. Note that setting a null or empty value
+   * will cause the status bar to be hidden, with possibly undesirable flicker
+   * of the screen layout.
+   */
   @Override
   public void setStatus(String text)
   {
-    statusBar.setText(text);
+    statusBar.setText(text == null || text.isEmpty() ? " " : text);
   }
 
   /*
@@ -1223,7 +1232,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    */
   public void saveAlignment(String file, FileFormatI format)
   {
-    lastSaveSuccessful = false;
+    lastSaveSuccessful = true;
     lastFilenameSaved = file;
     lastFormatSaved = format;
 
@@ -1235,8 +1244,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         shortName = shortName.substring(
                 shortName.lastIndexOf(File.separatorChar) + 1);
       }
-      lastSaveSuccessful = new jalview.project.Jalview2XML().saveAlignment(this, file,
-              shortName);
+      lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file, shortName);
       
       statusBar.setText(MessageManager.formatMessage(
               "label.successfully_saved_to_file_in_format", new Object[]
@@ -1246,7 +1254,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     }
 
     AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
-    RunResponse cancelAction = new RunResponse(JvOptionPane.CANCEL_OPTION)
+    Runnable cancelAction = new Runnable()
     {
       @Override
       public void run()
@@ -1254,7 +1262,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         lastSaveSuccessful = false;
       }
     };
-    RunResponse outputAction = new RunResponse(JvOptionPane.OK_OPTION)
+    Runnable outputAction = new Runnable()
     {
       @Override
       public void run()
@@ -1273,21 +1281,34 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         }
         else
         {
+          // create backupfiles object and get new temp filename destination
+          boolean doBackup = BackupFiles.getEnabled();
+          BackupFiles backupfiles = doBackup ? new BackupFiles(file) : null;
           try
           {
-            PrintWriter out = new PrintWriter(new FileWriter(file));
+            String tempFilePath = doBackup ? backupfiles.getTempFilePath() : file;
+                       PrintWriter out = new PrintWriter(
+                    new FileWriter(tempFilePath));
+
             out.print(output);
             out.close();
             AlignFrame.this.setTitle(file);
-            setStatus(MessageManager.formatMessage(
-                    "label.successfully_saved_to_file_in_format",
-                    new Object[]
-                    { fileName, format.getName() }));
+            statusBar.setText(MessageManager.formatMessage(
+                  "label.successfully_saved_to_file_in_format", new Object[]
+                  { fileName, format.getName() }));
+            lastSaveSuccessful = true;
           } catch (Exception ex)
           {
             lastSaveSuccessful = false;
             ex.printStackTrace();
           }
+
+          if (doBackup)
+          {
+            backupfiles.setWriteSuccess(lastSaveSuccessful);
+            // do the backup file roll and rename the temp file to actual file
+            lastSaveSuccessful = backupfiles.rollBackupsAndRenameTempFile();
+          }
         }
       }
     };
@@ -1299,8 +1320,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     {
       AlignExportOptions choices = new AlignExportOptions(
               alignPanel.getAlignViewport(), format, options);
-      choices.setResponseAction(outputAction);
-      choices.setResponseAction(cancelAction);
+      choices.setResponseAction(0, outputAction);
+      choices.setResponseAction(1, cancelAction);
       choices.showDialog();
     }
     else
@@ -1322,7 +1343,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     FileFormatI fileFormat = FileFormats.getInstance()
             .forName(fileFormatName);
     AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
-    RunResponse outputAction = new RunResponse(JvOptionPane.OK_OPTION)
+    Runnable outputAction = new Runnable()
     {
       @Override
       public void run()
@@ -1359,7 +1380,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     {
       AlignExportOptions choices = new AlignExportOptions(
               alignPanel.getAlignViewport(), fileFormat, options);
-      choices.setResponseAction(outputAction);
+      choices.setResponseAction(0, outputAction);
       choices.showDialog();
     }
     else
@@ -1472,9 +1493,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             MessageManager.getString("label.load_jalview_annotations"));
     chooser.setToolTipText(
             MessageManager.getString("label.load_jalview_annotations"));
-    chooser.addResponse(new RunResponse(JalviewFileChooser.APPROVE_OPTION)
+    chooser.setResponseHandler(0, new Runnable()
     {
-
       @Override
       public void run()
       {
@@ -1482,7 +1502,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         jalview.bin.Cache.setProperty("LAST_DIRECTORY", choice);
         loadJalviewDataFile(chooser.getSelectedFile(), null, null, null);
       }
-
     });
 
     chooser.showOpenDialog(this);
@@ -1890,7 +1909,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    *          DOCUMENT ME!
    */
   @Override
-  protected void copy_actionPerformed(ActionEvent e)
+  protected void copy_actionPerformed()
   {
     if (viewport.getSelectionGroup() == null)
     {
@@ -2065,7 +2084,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                 && Desktop.jalviewClipboard[1] != alignment.getDataset();
         // importDs==true instructs us to copy over new dataset sequences from
         // an existing alignment
-        Vector newDs = (importDs) ? new Vector() : null; // used to create
+        Vector<SequenceI> newDs = (importDs) ? new Vector<>() : null; // used to
+                                                                      // create
         // minimum dataset set
 
         for (int i = 0; i < sequences.length; i++)
@@ -2359,26 +2379,20 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   }
 
   /**
-   * DOCUMENT ME!
-   * 
-   * @param e
-   *          DOCUMENT ME!
+   * Action Cut (delete and copy) the selected region
    */
   @Override
-  protected void cut_actionPerformed(ActionEvent e)
+  protected void cut_actionPerformed()
   {
-    copy_actionPerformed(null);
-    delete_actionPerformed(null);
+    copy_actionPerformed();
+    delete_actionPerformed();
   }
 
   /**
-   * DOCUMENT ME!
-   * 
-   * @param e
-   *          DOCUMENT ME!
+   * Performs menu option to Delete the currently selected region
    */
   @Override
-  protected void delete_actionPerformed(ActionEvent evt)
+  protected void delete_actionPerformed()
   {
 
     SequenceGroup sg = viewport.getSelectionGroup();
@@ -2387,52 +2401,56 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       return;
     }
 
+    Runnable okAction = new Runnable() 
+    {
+               @Override
+               public void run() 
+               {
+                   SequenceI[] cut = sg.getSequences()
+                           .toArray(new SequenceI[sg.getSize()]);
+
+                   addHistoryItem(new EditCommand(
+                           MessageManager.getString("label.cut_sequences"), Action.CUT,
+                           cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
+                           viewport.getAlignment()));
+
+                   viewport.setSelectionGroup(null);
+                   viewport.sendSelection();
+                   viewport.getAlignment().deleteGroup(sg);
+
+                   viewport.firePropertyChange("alignment", null,
+                           viewport.getAlignment().getSequences());
+                   if (viewport.getAlignment().getHeight() < 1)
+                   {
+                     try
+                     {
+                       AlignFrame.this.setClosed(true);
+                     } catch (Exception ex)
+                     {
+                     }
+                   }
+               }};
+
     /*
-     * If the cut affects all sequences, warn, remove highlighted columns
+     * If the cut affects all sequences, prompt for confirmation
      */
-    if (sg.getSize() == viewport.getAlignment().getHeight())
-    {
-      boolean isEntireAlignWidth = (((sg.getEndRes() - sg.getStartRes())
-              + 1) == viewport.getAlignment().getWidth()) ? true : false;
-      if (isEntireAlignWidth)
-      {
-        int confirm = JvOptionPane.showConfirmDialog(this,
-                MessageManager.getString("warn.delete_all"), // $NON-NLS-1$
-                MessageManager.getString("label.delete_all"), // $NON-NLS-1$
-                JvOptionPane.OK_CANCEL_OPTION);
-
-        if (confirm == JvOptionPane.CANCEL_OPTION
-                || confirm == JvOptionPane.CLOSED_OPTION)
-        {
-          return;
-        }
-      }
-      viewport.getColumnSelection().removeElements(sg.getStartRes(),
-              sg.getEndRes() + 1);
-    }
-    SequenceI[] cut = sg.getSequences()
-            .toArray(new SequenceI[sg.getSize()]);
-
-    addHistoryItem(new EditCommand(
-            MessageManager.getString("label.cut_sequences"), Action.CUT,
-            cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
-            viewport.getAlignment()));
-
-    viewport.setSelectionGroup(null);
-    viewport.sendSelection();
-    viewport.getAlignment().deleteGroup(sg);
-
-    viewport.firePropertyChange("alignment", null,
-            viewport.getAlignment().getSequences());
-    if (viewport.getAlignment().getHeight() < 1)
-    {
-      try
-      {
-        this.setClosed(true);
-      } catch (Exception ex)
-      {
-      }
-    }
+    boolean wholeHeight = sg.getSize() == viewport.getAlignment().getHeight();
+    boolean wholeWidth = (((sg.getEndRes() - sg.getStartRes())
+            + 1) == viewport.getAlignment().getWidth()) ? true : false;
+       if (wholeHeight && wholeWidth)
+       {
+           JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
+               dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
+           Object[] options = new Object[] { MessageManager.getString("action.ok"),
+                   MessageManager.getString("action.cancel") };
+               dialog.showDialog(MessageManager.getString("warn.delete_all"),
+                   MessageManager.getString("label.delete_all"),
+                   JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
+                   options, options[0]);
+       } else 
+       {
+               okAction.run();
+       }
   }
 
   /**
@@ -2461,15 +2479,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   @Override
   public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
   {
-    SequenceGroup sg = new SequenceGroup();
-
-    for (int i = 0; i < viewport.getAlignment().getSequences().size(); i++)
-    {
-      sg.addSequence(viewport.getAlignment().getSequenceAt(i), false);
-    }
+    SequenceGroup sg = new SequenceGroup(
+            viewport.getAlignment().getSequences());
 
     sg.setEndRes(viewport.getAlignment().getWidth() - 1);
     viewport.setSelectionGroup(sg);
+    viewport.isSelectionGroupChanged(true);
     viewport.sendSelection();
     // JAL-2034 - should delegate to
     // alignPanel to decide if overview needs
@@ -2791,6 +2806,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     newap.av.setRedoList(viewport.getRedoList());
 
     /*
+     * copy any visualisation settings that are not saved in the project
+     */
+    newap.av.setColourAppliesToAllGroups(
+            viewport.getColourAppliesToAllGroups());
+
+    /*
      * Views share the same mappings; need to deregister any new mappings
      * created by copyAlignPanel, and register the new reference to the shared
      * mappings
@@ -2953,7 +2974,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     viewport.setFollowHighlight(state);
     if (state)
     {
-      alignPanel.scrollToPosition(viewport.getSearchResults(), false);
+      alignPanel.scrollToPosition(viewport.getSearchResults());
     }
   }
 
@@ -3012,7 +3033,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * @param toggleSeqs
    * @param toggleCols
    */
-  private void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
+  protected void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
   {
 
     boolean hide = false;
@@ -3100,6 +3121,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     viewport.expandColSelection(sg, false);
     viewport.hideAllSelectedSeqs();
     viewport.hideSelectedColumns();
+    alignPanel.updateLayout();
     alignPanel.paintAlignment(true, true);
     viewport.sendSelection();
   }
@@ -3124,6 +3146,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   public void hideSelColumns_actionPerformed(ActionEvent e)
   {
     viewport.hideSelectedColumns();
+    alignPanel.updateLayout();
     alignPanel.paintAlignment(true, true);
     viewport.sendSelection();
   }
@@ -3145,7 +3168,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void scaleAbove_actionPerformed(ActionEvent e)
   {
     viewport.setScaleAboveWrapped(scaleAbove.isSelected());
-    // TODO: do we actually need to update overview for scale above change ?
+    alignPanel.updateLayout();
     alignPanel.paintAlignment(true, false);
   }
 
@@ -3159,6 +3182,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void scaleLeft_actionPerformed(ActionEvent e)
   {
     viewport.setScaleLeftWrapped(scaleLeft.isSelected());
+    alignPanel.updateLayout();
     alignPanel.paintAlignment(true, false);
   }
 
@@ -3172,6 +3196,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
   protected void scaleRight_actionPerformed(ActionEvent e)
   {
     viewport.setScaleRightWrapped(scaleRight.isSelected());
+    alignPanel.updateLayout();
     alignPanel.paintAlignment(true, false);
   }
 
@@ -3285,7 +3310,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             { contents.toString() });
     contents = null;
 
-    if (Jalview.isJS())
+    if (Platform.isJS())
     {
       JLabel textLabel = new JLabel();
       textLabel.setText(content);
@@ -3297,6 +3322,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       ((JPanel) pane).add(textLabel, BorderLayout.NORTH);
     }
     else
+    /**
+     * Java only
+     * 
+     * @j2sIgnore
+     */
     {
       JEditorPane editPane = new JEditorPane("text/html", "");
       editPane.setEditable(false);
@@ -3345,7 +3375,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
               {
                 overview.dispose();
                 alignPanel.setOverviewPanel(null);
-              };
+              }
             });
     if (getKeyListeners().length > 0)
     {
@@ -3415,6 +3445,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
      * otherwise set the chosen colour scheme (or null for 'None')
      */
     ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
+            viewport,
             viewport.getAlignment(), viewport.getHiddenRepSequences());
     changeColour(cs);
   }
@@ -3782,7 +3813,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     {
       sortByAnnotScore.removeAll();
       // almost certainly a quicker way to do this - but we keep it simple
-      Hashtable scoreSorts = new Hashtable();
+      Hashtable<String, String> scoreSorts = new Hashtable<>();
       AlignmentAnnotation aann[];
       for (SequenceI sqa : viewport.getAlignment().getSequences())
       {
@@ -3795,11 +3826,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           }
         }
       }
-      Enumeration labels = scoreSorts.keys();
+      Enumeration<String> labels = scoreSorts.keys();
       while (labels.hasMoreElements())
       {
         addSortByAnnotScoreMenuItem(sortByAnnotScore,
-                (String) labels.nextElement());
+                labels.nextElement());
       }
       sortByAnnotScore.setVisible(scoreSorts.size() > 0);
       scoreSorts.clear();
@@ -3966,8 +3997,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     chooser.setToolTipText(
             MessageManager.getString("label.load_tree_file"));
 
-    chooser.addResponse(new jalview.util.dialogrunner.RunResponse(
-            JalviewFileChooser.APPROVE_OPTION)
+    chooser.setResponseHandler(0,new Runnable()
     {
       @Override
       public void run()
@@ -4128,14 +4158,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
             // No MSAWS used any more:
             // Vector msaws = null; // (Vector)
             // Discoverer.services.get("MsaWS");
-            Vector secstrpr = (Vector) Discoverer.services
+            Vector<ServiceHandle> secstrpr = Discoverer.services
                     .get("SecStrPred");
             if (secstrpr != null)
             {
               // Add any secondary structure prediction services
               for (int i = 0, j = secstrpr.size(); i < j; i++)
               {
-                final ext.vamsas.ServiceHandle sh = (ext.vamsas.ServiceHandle) secstrpr
+                final ext.vamsas.ServiceHandle sh = secstrpr
                         .get(i);
                 jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
                         .getServiceClient(sh);
@@ -4245,7 +4275,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * 
    * @param webService
    */
-  private void build_urlServiceMenu(JMenu webService)
+  protected void build_urlServiceMenu(JMenu webService)
   {
     // TODO: remove this code when 2.7 is released
     // DEBUG - alignmentView
@@ -4353,14 +4383,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
    * frame's DNA sequences to their aligned protein (amino acid) equivalents.
    */
   @Override
-  public void showTranslation_actionPerformed(ActionEvent e)
+  public void showTranslation_actionPerformed(GeneticCodeI codeTable)
   {
     AlignmentI al = null;
     try
     {
       Dna dna = new Dna(viewport, viewport.getViewAsVisibleContigs(true));
 
-      al = dna.translateCdna();
+      al = dna.translateCdna(codeTable);
     } catch (Exception ex)
     {
       jalview.bin.Cache.log.error(
@@ -4389,7 +4419,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
       af.setFileFormat(this.currentFileFormat);
       final String newTitle = MessageManager
               .formatMessage("label.translation_of_params", new Object[]
-              { this.getTitle() });
+              { this.getTitle(), codeTable.getId() });
       af.setTitle(newTitle);
       if (Cache.getDefault(Preferences.ENABLE_SPLIT_FRAME, true))
       {
@@ -4514,8 +4544,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
                       : FormatAdapter.checkProtocol(fileName));
               if (protocol == DataSourceType.FILE)
               {
-                File fl = (file instanceof File ? (File) file
-                        : new File(fileName));
+                File fl;
+                if (file instanceof File) {
+                  fl = (File) file;
+                  Platform.cacheFileData(fl);
+                } else {
+                  fl = new File(fileName);
+                }
                 pdbfn = fl.getName();
               }
               else if (protocol == DataSourceType.URL)
@@ -4980,7 +5015,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
         trimrs.setSelected(trimrs.isSelected());
         Cache.setProperty(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES,
                 Boolean.valueOf(trimrs.isSelected()).toString());
-      };
+      }
     });
     rfetch.add(trimrs);
     JMenuItem fetchr = new JMenuItem(
@@ -5377,7 +5412,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     {
       PaintRefresher.Refresh(this, viewport.getSequenceSetId());
       alignPanel.updateAnnotation();
-      alignPanel.paintAlignment(true, true);
+      alignPanel.paintAlignment(true,
+              viewport.needToUpdateStructureViews());
     }
   }
 
@@ -5663,15 +5699,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     colourMenu.add(textColour);
     colourMenu.addSeparator();
 
-    ColourMenuHelper.addMenuItems(colourMenu, this, viewport.getAlignment(),
-            false);
+    ButtonGroup bg = ColourMenuHelper.addMenuItems(colourMenu, this,
+            viewport.getAlignment(), false);
 
+    colourMenu.add(annotationColour);
+    bg.add(annotationColour);
     colourMenu.addSeparator();
     colourMenu.add(conservationMenuItem);
     colourMenu.add(modifyConservation);
     colourMenu.add(abovePIDThreshold);
     colourMenu.add(modifyPID);
-    colourMenu.add(annotationColour);
 
     ColourSchemeI colourScheme = viewport.getGlobalColourScheme();
     ColourMenuHelper.setColourSelected(colourMenu, colourScheme);
@@ -5698,20 +5735,16 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
     chooser.setDialogTitle(MessageManager.getString("label.load_vcf_file"));
     chooser.setToolTipText(MessageManager.getString("label.load_vcf_file"));
     final AlignFrame us = this;
-    chooser.addResponse(new RunResponse(JalviewFileChooser.APPROVE_OPTION)
+    chooser.setResponseHandler(0, new Runnable()
     {
       @Override
       public void run()
       {
-
-        {
-          String choice = chooser.getSelectedFile().getPath();
-          Cache.setProperty("LAST_DIRECTORY", choice);
-          SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
-          new VCFLoader(choice).loadVCF(seqs, us);
-        }
-
-      };
+        String choice = chooser.getSelectedFile().getPath();
+        Cache.setProperty("LAST_DIRECTORY", choice);
+        SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
+        new VCFLoader(choice).loadVCF(seqs, us);
+      }
     });
     chooser.showOpenDialog(null);