Merge branch 'develop' into trialMerge
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 19 Apr 2019 15:04:51 +0000 (16:04 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Fri, 19 Apr 2019 15:04:51 +0000 (16:04 +0100)
Conflicts:
resources/lang/Messages.properties
resources/lang/Messages_es.properties
src/jalview/gui/FeatureSettings.java
src/jalview/gui/FeatureTypeSettings.java

1  2 
resources/lang/Messages.properties
resources/lang/Messages_es.properties
src/jalview/bin/Jalview.java
src/jalview/controller/AlignViewController.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/FeatureSettings.java
src/jalview/gui/FeatureTypeSettings.java
src/jalview/gui/SequenceFetcher.java
test/jalview/controller/AlignViewControllerTest.java
test/jalview/gui/AlignFrameTest.java

@@@ -1364,7 -1336,60 +1337,64 @@@ label.most_bound_molecules = Most Boun
  label.most_polymer_residues = Most Polymer Residues
  label.cached_structures = Cached Structures
  label.free_text_search = Free Text Search
 +label.summary_view = Summary View
 +label.summary_view_tip = Show only top level ontology terms
 +label.apply_to_subtypes = Apply changes also to sub-types of ''{0}''
- label.apply_also_to = Apply also to:
++label.apply_also_to = Apply also to:
+ label.backupfiles_confirm_delete = Confirm delete
+ label.backupfiles_confirm_delete_old_files = Delete the following older backup files? (see the Backups tab in Preferences for more options)
+ label.backupfiles_confirm_save_file = Confirm save file
+ label.backupfiles_confirm_save_file_backupfiles_roll_wrong = Something possibly went wrong with the backups of this file.
+ label.backupfiles_confirm_save_new_saved_file_ok = The new saved file seems okay.
+ label.backupfiles_confirm_save_new_saved_file_not_ok = The new saved file might not be okay.
+ label.backups = Backups
+ label.backup = Backup
+ label.backup_files = Backup Files
+ label.enable_backupfiles = Enable backup files
+ label.backup_filename_strategy = Backup filename strategy
+ label.append_to_filename = Append to filename (%n is replaced by the backup number)
+ label.append_to_filename_tooltip = %n in the text will be replaced by the backup number. The text will appear after the filename. See the summary box above.
+ label.index_digits = Number of digits to use for the backup number (%n)
+ label.summary_of_backups_scheme = Summary of backup scheme
+ label.increment_index = Increase appended text numbers - newest file has largest number.
+ label.reverse_roll = "Roll" appended text numbers - newest backup file is always number 1.
+ label.keep_files = Deleting old backup files
+ label.keep_all_backup_files = Do not delete old backup files
+ label.keep_only_this_number_of_backup_files = Keep only this number of most recent backup files
+ label.autodelete_old_backup_files = Autodelete old backup files:
+ label.always_ask = Always ask
+ label.auto_delete = Automatically delete
+ label.filename = filename
+ label.braced_oldest = (oldest)
+ label.braced_newest = (most recent)
+ label.configuration = Configuration
+ label.configure_feature_tooltip = Click to configure variable colour or filters
+ label.schemes = Schemes
+ label.customise = Customise
+ label.default = Default
+ label.single_file = Single backup
+ label.keep_all_versions = Keep all versions
+ label.rolled_backups = Rolled backup files
+ label.previously_saved_scheme = Previously saved scheme
+ label.no_backup_files = NO BACKUP FILES
+ label.include_backup_files = Include backup files
+ label.cancel_changes = Cancel changes
+ label.warning_confirm_change_reverse = Warning!\nIf you change the increment/decrement of the backup filename number, without changing the suffix or number of digits,\nthis may cause loss of backup files created with the previous backup filename scheme.\nAre you sure you wish to do this?
+ label.change_increment_decrement = Change increment/decrement?
+ label.was_previous = was {0}
+ label.newerdelete_replacement_line = Backup file\n''{0}''\t(modified {2}, size {4})\nis to be deleted and replaced by apparently older file\n''{1}''\t(modified {3}, size {5}).
+ label.confirm_deletion_or_rename = Confirm deletion of ''{0}'' or rename to ''{1}''?
+ label.newerdelete_line = Backup file\n''{0}''\t(modified {2}, size {4})\nis to be deleted but is newer than the oldest remaining backup file\n''{1}''\t(modified {3}, size {5}).
+ label.confirm_deletion = Confirm deletion of ''{0}''?
+ label.delete = Delete
+ label.rename = Rename
+ label.keep = Keep
+ label.file_info = (modified {0}, size {1})
+ label.annotation_name = Annotation Name
+ label.annotation_description = Annotation Description 
+ label.edit_annotation_name_description = Edit Annotation Name/Description
+ label.alignment = alignment
+ label.pca = PCA
+ label.create_image_of = Create {0} image of {1}
+ label.click_to_edit = Click to edit, right-click for menu
+ label.by_annotation_tooltip = Annotation Colour is configured from the main Colour menu
@@@ -1365,7 -1337,60 +1338,64 @@@ label.most_bound_molecules = Más Molécu
  label.most_polymer_residues = Más Residuos de Polímeros
  label.cached_structures = Estructuras en Caché
  label.free_text_search = Búsqueda de texto libre
 +label.summary_view = Vista Resumida
 +label.summary_view_tip = Mostrar solo términos de ontología de nivel mayor
 +label.apply_to_subtypes = Aplicar cambios también a subtipos de ''{0}''
- label.apply_also_to = Aplicar también a:
++label.apply_also_to = Aplicar también a:
+ label.backupfiles_confirm_delete = Confirmar borrar
+ label.backupfiles_confirm_delete_old_files = ¿Borrar los siguientes archivos? (ver la pestaña 'Copias' de la ventana de Preferencias para más opciones)
+ label.backupfiles_confirm_save_file = Confirmar guardar archivo
+ label.backupfiles_confirm_save_file_backupfiles_roll_wrong = Posiblemente algo está mal con los archivos de respaldos.
+ label.backupfiles_confirm_save_new_saved_file_ok = El nuevo archivo guardado parece estar bien.
+ label.backupfiles_confirm_save_new_saved_file_not_ok = El nuevo archivo guardado podría no estar bien.
+ label.backups = Respaldos
+ label.backup = Respaldo
+ label.backup_files = Archivos de respaldos
+ label.enable_backupfiles = Habilitar archivos de respaldos
+ label.backup_filename_strategy = Estrategia de nombres de archivo de respaldos
+ label.append_to_filename = Adjuntar texto (%n es reemplazado por el número de respaldo)
+ label.append_to_filename_tooltip = %n en el texto será reemplazado por el número de respaldo. El texto será después del nombre del archivo. Vea el cuadro de resumen arriba.
+ label.index_digits = Número de dígitos a utilizar para el número de respaldo.
+ label.summary_of_backups_scheme = Resumen del esquema de copias de seguridad
+ label.increment_index = Aumente los números de texto adjuntos: el archivo más nuevo tiene el número más grande
+ label.reverse_roll = Ciclos de texto adjuntos: el respaldo más reciente es siempre el número 1
+ label.keep_files = Borrando los respaldos antiguos
+ label.keep_all_backup_files = No borrar respaldos antiguas
+ label.keep_only_this_number_of_backup_files = Mantenga solo este número de respaldos más recientes
+ label.autodelete_old_backup_files = Borrer automáticamente respaldos antiguos:
+ label.always_ask = Pregunta siempre
+ label.auto_delete = Borrer automáticamente
+ label.filename = nombre_de_archivo
+ label.braced_oldest = (mas antiguo)
+ label.braced_newest = (mas nuevo)
+ label.configuration = Configuración
+ label.configure_feature_tooltip = Haga clic para configurar el color o los filtros
+ label.schemes = Esquemas
+ label.customise = Personalizado
+ label.default = Defecto
+ label.single_file = Solo uno respaldo
+ label.keep_all_versions = Mantener todas las versiones
+ label.rolled_backups = Ciclos respaldos
+ label.previously_saved_scheme = Esquema previamente guardado
+ label.no_backup_files = NO ARCHIVOS DE RESPALDOS
+ label.include_backup_files = Incluir archivos de respaldos
+ label.cancel_changes = Cancelar cambios
+ label.warning_confirm_change_reverse = ¡Advertencia!\nSi cambia el incremento/decremento del número de archivos de respaldos, sin cambiar el sufijo o número de dígitos,\nesto puede causar la pérdida de los archivos de respaldos creados con el esquema anterior de nombre de archivo de respaldos.\n¿Está seguro de que desea hacer esto?
+ label.change_increment_decrement = ¿Cambiar de incremento/decremento?
+ label.was_previous = era {0}
+ label.newerdelete_replacement_line = El archivo de respaldo\n''{0}''\t(modificado {2}, tamaño {4})\nserá borrado y reemplazarse por un archivo aparentemente más antiguo\n''{1}''\t(modificado {3}, tamaño {5}).
+ label.confirm_deletion_or_rename = Confirmar borrar ''{0}'', o cambiar el nombre a ''{1}''?
+ label.newerdelete_line = El archivo de respaldo\n''{0}''\t(modificado {2}, tamaño {4})\nserá borrado pero es mas nuevo que el archivo de respaldo restante más antiguo\n''{1}''\t(modified {3}, size {5}).
+ label.confirm_deletion = Confirmar eliminar ''{0}''?
+ label.delete = Borrar
+ label.rename = Cambiar
+ label.keep = Mantener
+ label.file_info = (modificado {0}, tamaño {1})
+ label.annotation_name = Nombre de la anotación
+ label.annotation_description = Descripción de la anotación 
+ label.edit_annotation_name_description = Editar el nombre/descripción de la anotación
+ label.alignment = alineamiento
+ label.pca = ACP
+ label.create_image_of = Crear imagen {0} de {1}
+ label.click_to_edit = Haga clic para editar, clic en el botón derecho para ver el menú  
+ label.by_annotation_tooltip = El color de anotación se configura desde el menú principal de colores
Simple merge
Simple merge
@@@ -31,10 -31,6 +32,7 @@@ import jalview.datamodel.ontology.Ontol
  import jalview.gui.Help.HelpId;
  import jalview.io.JalviewFileChooser;
  import jalview.io.JalviewFileView;
 +import jalview.io.gff.SequenceOntologyFactory;
- import jalview.schemabinding.version2.Filter;
- import jalview.schemabinding.version2.JalviewUserColours;
- import jalview.schemabinding.version2.MatcherSet;
  import jalview.schemes.FeatureColour;
  import jalview.util.MessageManager;
  import jalview.util.Platform;
@@@ -94,8 -92,8 +95,9 @@@ import javax.swing.JScrollPane
  import javax.swing.JSlider;
  import javax.swing.JTable;
  import javax.swing.ListSelectionModel;
 +import javax.swing.RowFilter;
  import javax.swing.SwingConstants;
+ import javax.swing.border.Border;
  import javax.swing.event.ChangeEvent;
  import javax.swing.event.ChangeListener;
  import javax.swing.table.AbstractTableModel;
@@@ -102,7 -101,11 +105,12 @@@ import javax.swing.table.JTableHeader
  import javax.swing.table.TableCellEditor;
  import javax.swing.table.TableCellRenderer;
  import javax.swing.table.TableColumn;
 +import javax.swing.table.TableRowSorter;
+ import javax.xml.bind.JAXBContext;
+ import javax.xml.bind.JAXBElement;
+ import javax.xml.bind.Marshaller;
+ import javax.xml.stream.XMLInputFactory;
+ import javax.xml.stream.XMLStreamReader;
  
  public class FeatureSettings extends JPanel
          implements FeatureSettingsControllerI
        {
          String tip = null;
          int column = table.columnAtPoint(e.getPoint());
+         int row = table.rowAtPoint(e.getPoint());
          switch (column)
          {
          case TYPE_COLUMN:
 -          tip = JvSwingUtils.wrapTooltip(true, MessageManager
 +          /*
 +           * drag to reorder not enabled in Summary View
 +           */
 +          tip = summaryView.isSelected()
 +                  ? MessageManager.getString(
 +                          "label.feature_settings_select_columns")
 +                  : JvSwingUtils.wrapTooltip(true, MessageManager
                    .getString("label.feature_settings_click_drag"));
            break;
+         case COLOUR_COLUMN:
+           FeatureColourI colour = (FeatureColourI) table.getValueAt(row,
+                   column);
+           tip = getColorTooltip(colour, true);
+           break;
          case FILTER_COLUMN:
-           int row = table.rowAtPoint(e.getPoint());
            FeatureMatcherSet o = (FeatureMatcherSet) table.getValueAt(row,
                    column);
            tip = o.isEmpty()
          default:
            break;
          }
 -        
          return tip;
        }
+       /**
+        * Position the tooltip near the bottom edge of, and half way across, the
+        * current cell
+        */
+       @Override
+       public Point getToolTipLocation(MouseEvent e)
+       {
+         Point point = e.getPoint();
+         int column = table.columnAtPoint(point);
+         int row = table.rowAtPoint(point);
+         Rectangle r = getCellRect(row, column, false);
+         Point loc = new Point(r.x + r.width / 2, r.y + r.height - 3);
+         return loc;
+       }
      };
-     table.getTableHeader().setFont(VERDANA_12);
++
+     JTableHeader tableHeader = table.getTableHeader();
 -    tableHeader.setFont(new Font("Verdana", Font.PLAIN, 12));
++    tableHeader.setFont(VERDANA_12);
+     tableHeader.setReorderingAllowed(false);
 -    table.setFont(new Font("Verdana", Font.PLAIN, 12));
 +    table.setFont(VERDANA_12);
  
      table.setDefaultEditor(FeatureColour.class, new ColorEditor(this));
      table.setDefaultRenderer(FeatureColour.class, new ColorRenderer());
          String type = (String) table.getValueAt(selectedRow, TYPE_COLUMN);
          if (evt.isPopupTrigger())
          {
--          Object colour = table.getValueAt(selectedRow, COLOUR_COLUMN);
-           popupMenu(selectedRow, type, colour, evt.getX(), evt.getY());
 -          popupSort(selectedRow, type, colour, fr.getMinMax(), evt.getX(),
 -                  evt.getY());
++          popupMenu(selectedRow, type, evt.getX(), evt.getY());
          }
          else if (evt.getClickCount() == 2)
          {
          if (evt.isPopupTrigger())
          {
            String type = (String) table.getValueAt(selectedRow, TYPE_COLUMN);
--          Object colour = table.getValueAt(selectedRow, COLOUR_COLUMN);
-           popupMenu(selectedRow, type, colour, evt.getX(), evt.getY());
 -          popupSort(selectedRow, type, colour, fr.getMinMax(), evt.getX(),
 -                  evt.getY());
++          popupMenu(selectedRow, type, evt.getX(), evt.getY());
          }
        }
      });
        public void mouseDragged(MouseEvent evt)
        {
          int newRow = table.rowAtPoint(evt.getPoint());
 -        if (newRow != selectedRow && selectedRow != -1 && newRow != -1)
 -        {
 -          /*
 -           * reposition 'selectedRow' to 'newRow' (the dragged to location)
 -           * this could be more than one row away for a very fast drag action
 -           * so just swap it with adjacent rows until we get it there
 -           */
 -          Object[][] data = ((FeatureTableModel) table.getModel())
 -                  .getData();
 -          int direction = newRow < selectedRow ? -1 : 1;
 -          for (int i = selectedRow; i != newRow; i += direction)
 -          {
 -            Object[] temp = data[i];
 -            data[i] = data[i + direction];
 -            data[i + direction] = temp;
 -          }
 -          updateFeatureRenderer(data);
 -          table.repaint();
 -          selectedRow = newRow;
 -        }
 +        dragRow(newRow);
        }
      });
 -    // table.setToolTipText(JvSwingUtils.wrapTooltip(true,
 -    // MessageManager.getString("label.feature_settings_click_drag")));
 -    scrollPane.setViewportView(table);
 +  }
  
 -    if (af.getViewport().isShowSequenceFeatures() || !fr.hasRenderOrder())
 +  /**
 +   * Answers an array consisting of the given type, and also (if 'Summary View'
 +   * is selected), any child terms in the sequence ontology
 +   * 
 +   * @param type
 +   * @return
 +   */
 +  protected String[] getTermsInScope(String type)
 +  {
 +    if (!summaryView.isSelected())
      {
 -      fr.findAllFeatures(true); // display everything!
 +      return new String[] { type };
      }
  
 -    discoverAllFeatureData();
 -    final PropertyChangeListener change;
 -    final FeatureSettings fs = this;
 -    fr.addPropertyChangeListener(change = new PropertyChangeListener()
 -    {
 -      @Override
 -      public void propertyChange(PropertyChangeEvent evt)
 -      {
 -        if (!fs.resettingTable && !fs.handlingUpdate)
 -        {
 -          fs.handlingUpdate = true;
 -          fs.resetTable(null);
 -          // new groups may be added with new sequence feature types only
 -          fs.handlingUpdate = false;
 -        }
 -      }
 +    List<String> terms = new ArrayList<>();
 +    terms.add(type);
  
 -    });
 +    OntologyI so = SequenceOntologyFactory.getInstance();
  
 -    frame = new JInternalFrame();
 -    frame.setContentPane(this);
 -    if (Platform.isAMac())
 -    {
 -      Desktop.addInternalFrame(frame,
 -              MessageManager.getString("label.sequence_feature_settings"),
 -              600, 480);
 -    }
 -    else
 +    Object[][] data = ((FeatureTableModel) table.getModel()).getData();
 +    for (Object[] row : data)
      {
 -      Desktop.addInternalFrame(frame,
 -              MessageManager.getString("label.sequence_feature_settings"),
 -              600, 450);
 +      String type2 = (String) row[TYPE_COLUMN];
 +      if (!type2.equals(type) && so.isA(type2, type))
 +      {
 +        terms.add(type2);
 +      }
      }
 -    frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
 -
 -    frame.addInternalFrameListener(
 -            new javax.swing.event.InternalFrameAdapter()
 -            {
 -              @Override
 -              public void internalFrameClosed(
 -                      javax.swing.event.InternalFrameEvent evt)
 -              {
 -                fr.removePropertyChangeListener(change);
 -              };
 -            });
 -    frame.setLayer(JLayeredPane.PALETTE_LAYER);
 -    inConstruction = false;
 +    return terms.toArray(new String[terms.size()]);
    }
  
-   protected void popupMenu(final int rowSelected, final String type,
-           final Object typeCol, int x, int y)
 -  protected void popupSort(final int rowSelected, final String type,
 -          final Object typeCol, final Map<String, float[][]> minmax, int x,
++  protected void popupMenu(final int rowSelected, final String type, int x,
+           int y)
    {
--    final FeatureColourI featureColour = (FeatureColourI) typeCol;
--
      JPopupMenu men = new JPopupMenu(MessageManager
              .formatMessage("label.settings_for_param", new String[]
              { type }));
    }
  
    /**
 +   * Reorders features by 'dragging' selectedRow to 'newRow'
 +   * 
 +   * @param newRow
 +   */
 +  protected void dragRow(int newRow)
 +  {
 +    if (summaryView.isSelected())
 +    {
 +      // no drag while in summary view
 +      return;
 +    }
 +
 +    if (newRow != selectedRow && selectedRow != -1 && newRow != -1)
 +    {
 +      /*
 +       * reposition 'selectedRow' to 'newRow' (the dragged to location)
 +       * this could be more than one row away for a very fast drag action
 +       * so just swap it with adjacent rows until we get it there
 +       */
 +      Object[][] data = ((FeatureTableModel) table.getModel())
 +              .getData();
 +      int direction = newRow < selectedRow ? -1 : 1;
 +      for (int i = selectedRow; i != newRow; i += direction)
 +      {
 +        Object[] temp = data[i];
 +        data[i] = data[i + direction];
 +        data[i + direction] = temp;
 +      }
 +      updateFeatureRenderer(data);
 +      table.repaint();
 +      selectedRow = newRow;
 +    }
 +  }
 +
 +  protected void refreshTable()
 +  {
 +    Object[][] data = ((FeatureTableModel) table.getModel()).getData();
 +    for (Object[] row : data)
 +    {
 +      String type = (String) row[TYPE_COLUMN];
 +      FeatureColourI colour = fr.getFeatureColours().get(type);
 +      FeatureMatcherSetI filter = fr.getFeatureFilter(type);
 +      if (filter == null)
 +      {
 +        filter = new FeatureMatcherSet();
 +      }
 +      row[COLOUR_COLUMN] = colour;
 +      row[FILTER_COLUMN] = filter;
 +    }
 +    repaint();
 +  }
 +
++  /*
+    * Answers a suitable tooltip to show on the colour cell of the table
+    * 
+    * @param fcol
+    * @param withHint
+    *          if true include 'click to edit' and similar text
+    * @return
+    */
+   public static String getColorTooltip(FeatureColourI fcol,
+           boolean withHint)
+   {
+     if (fcol == null)
+     {
+       return null;
+     }
+     if (fcol.isSimpleColour())
+     {
+       return withHint ? BASE_TOOLTIP : null;
+     }
+     String description = fcol.getDescription();
+     description = description.replaceAll("<", "&lt;");
+     description = description.replaceAll(">", "&gt;");
+     StringBuilder tt = new StringBuilder(description);
+     if (withHint)
+     {
+       tt.append("<br>").append(BASE_TOOLTIP).append("</br>");
+     }
+     return JvSwingUtils.wrapTooltip(true, tt.toString());
+   }
+   public static void renderGraduatedColor(JLabel comp, FeatureColourI gcol,
+           int w, int h)
+   {
+     boolean thr = false;
+     StringBuilder tx = new StringBuilder();
+   
+     if (gcol.isColourByAttribute())
+     {
+       tx.append(FeatureMatcher
+               .toAttributeDisplayName(gcol.getAttributeName()));
+     }
+     else if (!gcol.isColourByLabel())
+     {
+       tx.append(MessageManager.getString("label.score"));
+     }
+     tx.append(" ");
+     if (gcol.isAboveThreshold())
+     {
+       thr = true;
+       tx.append(">");
+     }
+     if (gcol.isBelowThreshold())
+     {
+       thr = true;
+       tx.append("<");
+     }
+     if (gcol.isColourByLabel())
+     {
+       if (thr)
+       {
+         tx.append(" ");
+       }
+       if (!gcol.isColourByAttribute())
+       {
+         tx.append("Label");
+       }
+       comp.setIcon(null);
+     }
+     else
+     {
+       Color newColor = gcol.getMaxColour();
+       comp.setBackground(newColor);
+       // System.err.println("Width is " + w / 2);
+       Icon ficon = new FeatureIcon(gcol, comp.getBackground(), w, h, thr);
+       comp.setIcon(ficon);
+       // tt+="RGB value: Max (" + newColor.getRed() + ", "
+       // + newColor.getGreen() + ", " + newColor.getBlue()
+       // + ")\nMin (" + minCol.getRed() + ", " + minCol.getGreen()
+       // + ", " + minCol.getBlue() + ")");
+     }
+     comp.setHorizontalAlignment(SwingConstants.CENTER);
+     comp.setText(tx.toString());
+   }
    // ///////////////////////////////////////////////////////////////////////
    // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html
    // ///////////////////////////////////////////////////////////////////////
@@@ -603,13 -562,20 +602,21 @@@ public class FeatureTypeSettings extend
      maxColour.setBorder(new LineBorder(Color.black));
  
      /*
-      * default max colour to last plain colour;
-      * make min colour a pale version of max colour
+      * if not set, default max colour to last plain colour,
+      * and make min colour a pale version of max colour
       */
-     FeatureColourI fc = fr.getFeatureColours().get(featureType);
-     Color bg = fc.getColour() == null ? Color.BLACK : fc.getColour();
-     maxColour.setBackground(bg);
-     minColour.setBackground(ColorUtils.bleachColour(bg, 0.9f));
++    FeatureColourI originalColour = originalColours.get(featureType);
+     Color max = originalColour.getMaxColour();
+     if (max == null)
+     {
+       max = originalColour.getColour();
+       minColour.setBackground(ColorUtils.bleachColour(max, 0.9f));
+     }
+     else
+     {
+       maxColour.setBackground(max);
+       minColour.setBackground(originalColour.getMinColour());
+     }
  
      noValueCombo = new JComboBox<>();
      noValueCombo.addItem(MessageManager.getString("label.no_colour"));
      singleColour.setFont(JvSwingUtils.getLabelFont());
      singleColour.setBorder(BorderFactory.createLineBorder(Color.black));
      singleColour.setPreferredSize(new Dimension(40, 20));
 -    // if (originalColour.isGraduatedColour())
 -    // {
 -    // singleColour.setBackground(originalColour.getMaxColour());
 -    // singleColour.setForeground(originalColour.getMaxColour());
 -    // }
 -    // else
 -    // {
 -      singleColour.setBackground(originalColour.getColour());
 -      singleColour.setForeground(originalColour.getColour());
 -    // }
++    FeatureColourI originalColour = originalColours.get(featureType);
++    singleColour.setBackground(originalColour.getColour());
++    singleColour.setForeground(originalColour.getColour());
++
      singleColour.addMouseListener(new MouseAdapter()
      {
        @Override
Simple merge
@@@ -115,16 -116,15 +116,17 @@@ public class AlignFrameTes
  
      /*
       * threshold Metal to hide features where score < 5
 -     * seq1 feature in columns 1-5 is hidden
 -     * seq2 feature in columns 6-10 is shown
 +     * seq1 feature in columns 1-8 is hidden
 +     * seq2 feature in columns 8-14 is shown
 +     * result: columns 8-14 are hidden
 +     * note this includes gapped columns spanned by the feature
       */
-     FeatureColourI fc = new FeatureColour(Color.red, Color.blue, 0f, 10f);
+     FeatureColourI fc = new FeatureColour(null, Color.red, Color.blue, null,
+             0f, 10f);
      fc.setAboveThreshold(true);
      fc.setThreshold(5f);
 -    alignFrame.getFeatureRenderer().setColour("Metal", fc);
 -    assertTrue(alignFrame.hideFeatureColumns("Metal", true));
 +    alignFrame.getFeatureRenderer().setColour(METAL, fc);
 +    assertTrue(alignFrame.hideFeatureColumns(true, METAL));
      HiddenColumns hidden = alignFrame.getViewport().getAlignment().getHiddenColumns();
      assertEquals(hidden.getNumberOfRegions(), 1);
      Iterator<int[]> regions = hidden.iterator();