Merge branch 'develop' into features/JAL-2068groovyAnnotationWorker features/JAL-2068groovyAnnotationWorker
authorJim Procter <jprocter@issues.jalview.org>
Mon, 20 Jun 2016 11:12:29 +0000 (12:12 +0100)
committerJim Procter <jprocter@issues.jalview.org>
Mon, 20 Jun 2016 11:12:29 +0000 (12:12 +0100)
fun fact: Jalview.getCurrentAlignFrame() should be used in place of Desktop.getCurrentAlignFrame() now

1  2 
src/jalview/appletgui/FeatureRenderer.java
src/jalview/gui/AnnotationLabels.java
src/jalview/renderer/seqfeatures/FeatureRenderer.java
src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java
src/jalview/workers/AlignmentAnnotationFactory.java

@@@ -61,10 -61,8 +61,8 @@@ public class FeatureRenderer extend
     */
    public FeatureRenderer(AlignmentViewport av)
    {
 -    super();
 -    this.av = av;
 +    super(av);
 +
-     setTransparencyAvailable(!System.getProperty("java.version")
-             .startsWith("1.1"));
    }
  
    static String lastFeatureAdded;
      start.setText(features[0].getBegin() + "");
      end.setText(features[0].getEnd() + "");
      description.setText(features[0].getDescription());
-     Color col = getColour(name.getText());
-     if (col == null)
-     {
-       col = new jalview.schemes.UserColourScheme()
-               .createColourFromName(name.getText());
-     }
      Object fcol = getFeatureStyle(name.getText());
      // simply display the feature color in a box
      colourPanel.updateColor(fcol);
@@@ -244,7 -244,6 +244,7 @@@ public class AnnotationLabels extends J
      else if (evt.getActionCommand().equals(DELETE))
      {
        ap.av.getAlignment().deleteAnnotation(aa[selectedRow]);
 +      ap.av.getCalcManager().removeWorkerForAnnotation(aa[selectedRow]);
      }
      else if (evt.getActionCommand().equals(SHOWALL))
      {
      return true;
    }
  
-   /**
-    * DOCUMENT ME!
-    * 
-    * @param evt
-    *          DOCUMENT ME!
-    */
    @Override
    public void mousePressed(MouseEvent evt)
    {
      getSelectedRow(evt.getY() - getScrollOffset());
      oldY = evt.getY();
+     if (!evt.isPopupTrigger())
+     {
+       return;
+     }
+     evt.consume();
+     // handle popup menu event
+     final AlignmentAnnotation[] aa = ap.av.getAlignment()
+             .getAlignmentAnnotation();
+     JPopupMenu pop = new JPopupMenu(
+             MessageManager.getString("label.annotations"));
+     JMenuItem item = new JMenuItem(ADDNEW);
+     item.addActionListener(this);
+     pop.add(item);
+     if (selectedRow < 0)
+     {
+       if (hasHiddenRows)
+       { // let the user make everything visible again
+         item = new JMenuItem(SHOWALL);
+         item.addActionListener(this);
+         pop.add(item);
+       }
+       pop.show(this, evt.getX(), evt.getY());
+       return;
+     }
+     item = new JMenuItem(EDITNAME);
+     item.addActionListener(this);
+     pop.add(item);
+     item = new JMenuItem(HIDE);
+     item.addActionListener(this);
+     pop.add(item);
+     // JAL-1264 hide all sequence-specific annotations of this type
+     if (selectedRow < aa.length)
+     {
+       if (aa[selectedRow].sequenceRef != null)
+       {
+         final String label = aa[selectedRow].label;
+         JMenuItem hideType = new JMenuItem();
+         String text = MessageManager.getString("label.hide_all") + " "
+                 + label;
+         hideType.setText(text);
+         hideType.addActionListener(new ActionListener()
+         {
+           @Override
+           public void actionPerformed(ActionEvent e)
+           {
+             AlignmentUtils.showOrHideSequenceAnnotations(
+                     ap.av.getAlignment(), Collections.singleton(label),
+                     null, false, false);
+             // for (AlignmentAnnotation ann : ap.av.getAlignment()
+             // .getAlignmentAnnotation())
+             // {
+             // if (ann.sequenceRef != null && ann.label != null
+             // && ann.label.equals(label))
+             // {
+             // ann.visible = false;
+             // }
+             // }
+             refresh();
+           }
+         });
+         pop.add(hideType);
+       }
+     }
+     item = new JMenuItem(DELETE);
+     item.addActionListener(this);
+     pop.add(item);
+     if (hasHiddenRows)
+     {
+       item = new JMenuItem(SHOWALL);
+       item.addActionListener(this);
+       pop.add(item);
+     }
+     item = new JMenuItem(OUTPUT_TEXT);
+     item.addActionListener(this);
+     pop.add(item);
+     // TODO: annotation object should be typed for autocalculated/derived
+     // property methods
+     if (selectedRow < aa.length)
+     {
+       final String label = aa[selectedRow].label;
+       if (!aa[selectedRow].autoCalculated)
+       {
+         if (aa[selectedRow].graph == AlignmentAnnotation.NO_GRAPH)
+         {
+           // display formatting settings for this row.
+           pop.addSeparator();
+           // av and sequencegroup need to implement same interface for
+           item = new JCheckBoxMenuItem(TOGGLE_LABELSCALE,
+                   aa[selectedRow].scaleColLabel);
+           item.addActionListener(this);
+           pop.add(item);
+         }
+       }
+       else if (label.indexOf("Consensus") > -1)
+       {
+         pop.addSeparator();
+         // av and sequencegroup need to implement same interface for
+         final JCheckBoxMenuItem cbmi = new JCheckBoxMenuItem(
+                 MessageManager.getString("label.ignore_gaps_consensus"),
+                 (aa[selectedRow].groupRef != null) ? aa[selectedRow].groupRef
+                         .getIgnoreGapsConsensus() : ap.av
+                         .isIgnoreGapsConsensus());
+         final AlignmentAnnotation aaa = aa[selectedRow];
+         cbmi.addActionListener(new ActionListener()
+         {
+           @Override
+           public void actionPerformed(ActionEvent e)
+           {
+             if (aaa.groupRef != null)
+             {
+               // TODO: pass on reference to ap so the view can be updated.
+               aaa.groupRef.setIgnoreGapsConsensus(cbmi.getState());
+               ap.getAnnotationPanel().paint(
+                       ap.getAnnotationPanel().getGraphics());
+             }
+             else
+             {
+               ap.av.setIgnoreGapsConsensus(cbmi.getState(), ap);
+             }
+           }
+         });
+         pop.add(cbmi);
+         // av and sequencegroup need to implement same interface for
+         if (aaa.groupRef != null)
+         {
+           final JCheckBoxMenuItem chist = new JCheckBoxMenuItem(
+                   MessageManager.getString("label.show_group_histogram"),
+                   aa[selectedRow].groupRef.isShowConsensusHistogram());
+           chist.addActionListener(new ActionListener()
+           {
+             @Override
+             public void actionPerformed(ActionEvent e)
+             {
+               // TODO: pass on reference
+               // to ap
+               // so the
+               // view
+               // can be
+               // updated.
+               aaa.groupRef.setShowConsensusHistogram(chist.getState());
+               ap.repaint();
+               // ap.annotationPanel.paint(ap.annotationPanel.getGraphics());
+             }
+           });
+           pop.add(chist);
+           final JCheckBoxMenuItem cprofl = new JCheckBoxMenuItem(
+                   MessageManager.getString("label.show_group_logo"),
+                   aa[selectedRow].groupRef.isShowSequenceLogo());
+           cprofl.addActionListener(new ActionListener()
+           {
+             @Override
+             public void actionPerformed(ActionEvent e)
+             {
+               // TODO: pass on reference
+               // to ap
+               // so the
+               // view
+               // can be
+               // updated.
+               aaa.groupRef.setshowSequenceLogo(cprofl.getState());
+               ap.repaint();
+               // ap.annotationPanel.paint(ap.annotationPanel.getGraphics());
+             }
+           });
+           pop.add(cprofl);
+           final JCheckBoxMenuItem cproflnorm = new JCheckBoxMenuItem(
+                   MessageManager.getString("label.normalise_group_logo"),
+                   aa[selectedRow].groupRef.isNormaliseSequenceLogo());
+           cproflnorm.addActionListener(new ActionListener()
+           {
+             @Override
+             public void actionPerformed(ActionEvent e)
+             {
+               // TODO: pass on reference
+               // to ap
+               // so the
+               // view
+               // can be
+               // updated.
+               aaa.groupRef.setNormaliseSequenceLogo(cproflnorm.getState());
+               // automatically enable logo display if we're clicked
+               aaa.groupRef.setshowSequenceLogo(true);
+               ap.repaint();
+               // ap.annotationPanel.paint(ap.annotationPanel.getGraphics());
+             }
+           });
+           pop.add(cproflnorm);
+         }
+         else
+         {
+           final JCheckBoxMenuItem chist = new JCheckBoxMenuItem(
+                   MessageManager.getString("label.show_histogram"),
+                   av.isShowConsensusHistogram());
+           chist.addActionListener(new ActionListener()
+           {
+             @Override
+             public void actionPerformed(ActionEvent e)
+             {
+               // TODO: pass on reference
+               // to ap
+               // so the
+               // view
+               // can be
+               // updated.
+               av.setShowConsensusHistogram(chist.getState());
+               ap.alignFrame.setMenusForViewport();
+               ap.repaint();
+               // ap.annotationPanel.paint(ap.annotationPanel.getGraphics());
+             }
+           });
+           pop.add(chist);
+           final JCheckBoxMenuItem cprof = new JCheckBoxMenuItem(
+                   MessageManager.getString("label.show_logo"),
+                   av.isShowSequenceLogo());
+           cprof.addActionListener(new ActionListener()
+           {
+             @Override
+             public void actionPerformed(ActionEvent e)
+             {
+               // TODO: pass on reference
+               // to ap
+               // so the
+               // view
+               // can be
+               // updated.
+               av.setShowSequenceLogo(cprof.getState());
+               ap.alignFrame.setMenusForViewport();
+               ap.repaint();
+               // ap.annotationPanel.paint(ap.annotationPanel.getGraphics());
+             }
+           });
+           pop.add(cprof);
+           final JCheckBoxMenuItem cprofnorm = new JCheckBoxMenuItem(
+                   MessageManager.getString("label.normalise_logo"),
+                   av.isNormaliseSequenceLogo());
+           cprofnorm.addActionListener(new ActionListener()
+           {
+             @Override
+             public void actionPerformed(ActionEvent e)
+             {
+               // TODO: pass on reference
+               // to ap
+               // so the
+               // view
+               // can be
+               // updated.
+               av.setShowSequenceLogo(true);
+               av.setNormaliseSequenceLogo(cprofnorm.getState());
+               ap.alignFrame.setMenusForViewport();
+               ap.repaint();
+               // ap.annotationPanel.paint(ap.annotationPanel.getGraphics());
+             }
+           });
+           pop.add(cprofnorm);
+         }
+         final JMenuItem consclipbrd = new JMenuItem(COPYCONS_SEQ);
+         consclipbrd.addActionListener(this);
+         pop.add(consclipbrd);
+       }
+     }
+     pop.show(this, evt.getX(), evt.getY());
    }
  
    /**
      }
    }
  
-   /**
-    * DOCUMENT ME!
-    * 
-    * @param evt
-    *          DOCUMENT ME!
-    */
    @Override
    public void mouseClicked(MouseEvent evt)
    {
      final AlignmentAnnotation[] aa = ap.av.getAlignment()
              .getAlignmentAnnotation();
-     if (SwingUtilities.isLeftMouseButton(evt))
+     if (!evt.isPopupTrigger() && SwingUtilities.isLeftMouseButton(evt))
      {
        if (selectedRow > -1 && selectedRow < aa.length)
        {
              // todo: make the ap scroll to the selection - not necessary, first
              // click highlights/scrolls, second selects
              ap.getSeqPanel().ap.getIdPanel().highlightSearchResults(null);
-             ap.av.setSelectionGroup(// new SequenceGroup(
-             aa[selectedRow].groupRef); // );
+             // process modifiers
+             SequenceGroup sg = ap.av.getSelectionGroup();
+             if (sg == null
+                     || sg == aa[selectedRow].groupRef
+                     || !(jalview.util.Platform.isControlDown(evt) || evt
+                             .isShiftDown()))
+             {
+               if (jalview.util.Platform.isControlDown(evt)
+                       || evt.isShiftDown())
+               {
+                 // clone a new selection group from the associated group
+                 ap.av.setSelectionGroup(new SequenceGroup(
+                         aa[selectedRow].groupRef));
+               }
+               else
+               {
+                 // set selection to the associated group so it can be edited
+                 ap.av.setSelectionGroup(aa[selectedRow].groupRef);
+               }
+             }
+             else
+             {
+               // modify current selection with associated group
+               int remainToAdd = aa[selectedRow].groupRef.getSize();
+               for (SequenceI sgs : aa[selectedRow].groupRef.getSequences())
+               {
+                 if (jalview.util.Platform.isControlDown(evt))
+                 {
+                   sg.addOrRemove(sgs, --remainToAdd == 0);
+                 }
+                 else
+                 {
+                   // notionally, we should also add intermediate sequences from
+                   // last added sequence ?
+                   sg.addSequence(sgs, --remainToAdd == 0);
+                 }
+               }
+             }
              ap.paintAlignment(false);
              PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
              ap.av.sendSelection();
                // we make a copy rather than edit the current selection if no
                // modifiers pressed
                // see Enhancement JAL-1557
-               if (!(evt.isControlDown() || evt.isShiftDown()))
+               if (!(jalview.util.Platform.isControlDown(evt) || evt
+                       .isShiftDown()))
                {
                  sg = new SequenceGroup(sg);
                  sg.clear();
                }
                else
                {
-                 if (evt.isControlDown())
+                 if (jalview.util.Platform.isControlDown(evt))
                  {
                    sg.addOrRemove(aa[selectedRow].sequenceRef, true);
                  }
                sg.addSequence(aa[selectedRow].sequenceRef, false);
              }
              ap.av.setSelectionGroup(sg);
-             ap.av.sendSelection();
              ap.paintAlignment(false);
              PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
+             ap.av.sendSelection();
            }
  
          }
        }
-     }
-     // if (!evt.isPopupTrigger())
-     // {
-     // return;
-     // }
-     JPopupMenu pop = new JPopupMenu(
-             MessageManager.getString("label.annotations"));
-     JMenuItem item = new JMenuItem(ADDNEW);
-     item.addActionListener(this);
-     pop.add(item);
-     if (selectedRow < 0)
-     {
-       if (hasHiddenRows)
-       { // let the user make everything visible again
-         item = new JMenuItem(SHOWALL);
-         item.addActionListener(this);
-         pop.add(item);
-       }
-       pop.show(this, evt.getX(), evt.getY());
        return;
      }
-     item = new JMenuItem(EDITNAME);
-     item.addActionListener(this);
-     pop.add(item);
-     item = new JMenuItem(HIDE);
-     item.addActionListener(this);
-     pop.add(item);
-     // JAL-1264 hide all sequence-specific annotations of this type
-     if (selectedRow < aa.length)
-     {
-       if (aa[selectedRow].sequenceRef != null)
-       {
-         final String label = aa[selectedRow].label;
-         JMenuItem hideType = new JMenuItem();
-         String text = MessageManager.getString("label.hide_all") + " "
-                 + label;
-         hideType.setText(text);
-         hideType.addActionListener(new ActionListener()
-         {
-           @Override
-           public void actionPerformed(ActionEvent e)
-           {
-             AlignmentUtils.showOrHideSequenceAnnotations(
-                     ap.av.getAlignment(), Collections.singleton(label),
-                     null, false, false);
-             // for (AlignmentAnnotation ann : ap.av.getAlignment()
-             // .getAlignmentAnnotation())
-             // {
-             // if (ann.sequenceRef != null && ann.label != null
-             // && ann.label.equals(label))
-             // {
-             // ann.visible = false;
-             // }
-             // }
-             refresh();
-           }
-         });
-         pop.add(hideType);
-       }
-     }
-     item = new JMenuItem(DELETE);
-     item.addActionListener(this);
-     pop.add(item);
-     if (hasHiddenRows)
-     {
-       item = new JMenuItem(SHOWALL);
-       item.addActionListener(this);
-       pop.add(item);
-     }
-     item = new JMenuItem(OUTPUT_TEXT);
-     item.addActionListener(this);
-     pop.add(item);
-     // TODO: annotation object should be typed for autocalculated/derived
-     // property methods
-     if (selectedRow < aa.length)
-     {
-       final String label = aa[selectedRow].label;
-       if (!aa[selectedRow].autoCalculated)
-       {
-         if (aa[selectedRow].graph == AlignmentAnnotation.NO_GRAPH)
-         {
-           // display formatting settings for this row.
-           pop.addSeparator();
-           // av and sequencegroup need to implement same interface for
-           item = new JCheckBoxMenuItem(TOGGLE_LABELSCALE,
-                   aa[selectedRow].scaleColLabel);
-           item.addActionListener(this);
-           pop.add(item);
-         }
-       }
-       else if (label.indexOf("Consensus") > -1)
-       {
-         pop.addSeparator();
-         // av and sequencegroup need to implement same interface for
-         final JCheckBoxMenuItem cbmi = new JCheckBoxMenuItem(
-                 MessageManager.getString("label.ignore_gaps_consensus"),
-                 (aa[selectedRow].groupRef != null) ? aa[selectedRow].groupRef
-                         .getIgnoreGapsConsensus() : ap.av
-                         .isIgnoreGapsConsensus());
-         final AlignmentAnnotation aaa = aa[selectedRow];
-         cbmi.addActionListener(new ActionListener()
-         {
-           @Override
-           public void actionPerformed(ActionEvent e)
-           {
-             if (aaa.groupRef != null)
-             {
-               // TODO: pass on reference to ap so the view can be updated.
-               aaa.groupRef.setIgnoreGapsConsensus(cbmi.getState());
-               ap.getAnnotationPanel().paint(
-                       ap.getAnnotationPanel().getGraphics());
-             }
-             else
-             {
-               ap.av.setIgnoreGapsConsensus(cbmi.getState(), ap);
-             }
-           }
-         });
-         pop.add(cbmi);
-         // av and sequencegroup need to implement same interface for
-         if (aaa.groupRef != null)
-         {
-           final JCheckBoxMenuItem chist = new JCheckBoxMenuItem(
-                   MessageManager.getString("label.show_group_histogram"),
-                   aa[selectedRow].groupRef.isShowConsensusHistogram());
-           chist.addActionListener(new ActionListener()
-           {
-             @Override
-             public void actionPerformed(ActionEvent e)
-             {
-               // TODO: pass on reference
-               // to ap
-               // so the
-               // view
-               // can be
-               // updated.
-               aaa.groupRef.setShowConsensusHistogram(chist.getState());
-               ap.repaint();
-               // ap.annotationPanel.paint(ap.annotationPanel.getGraphics());
-             }
-           });
-           pop.add(chist);
-           final JCheckBoxMenuItem cprofl = new JCheckBoxMenuItem(
-                   MessageManager.getString("label.show_group_logo"),
-                   aa[selectedRow].groupRef.isShowSequenceLogo());
-           cprofl.addActionListener(new ActionListener()
-           {
-             @Override
-             public void actionPerformed(ActionEvent e)
-             {
-               // TODO: pass on reference
-               // to ap
-               // so the
-               // view
-               // can be
-               // updated.
-               aaa.groupRef.setshowSequenceLogo(cprofl.getState());
-               ap.repaint();
-               // ap.annotationPanel.paint(ap.annotationPanel.getGraphics());
-             }
-           });
-           pop.add(cprofl);
-           final JCheckBoxMenuItem cproflnorm = new JCheckBoxMenuItem(
-                   MessageManager.getString("label.normalise_group_logo"),
-                   aa[selectedRow].groupRef.isNormaliseSequenceLogo());
-           cproflnorm.addActionListener(new ActionListener()
-           {
-             @Override
-             public void actionPerformed(ActionEvent e)
-             {
-               // TODO: pass on reference
-               // to ap
-               // so the
-               // view
-               // can be
-               // updated.
-               aaa.groupRef.setNormaliseSequenceLogo(cproflnorm.getState());
-               // automatically enable logo display if we're clicked
-               aaa.groupRef.setshowSequenceLogo(true);
-               ap.repaint();
-               // ap.annotationPanel.paint(ap.annotationPanel.getGraphics());
-             }
-           });
-           pop.add(cproflnorm);
-         }
-         else
-         {
-           final JCheckBoxMenuItem chist = new JCheckBoxMenuItem(
-                   MessageManager.getString("label.show_histogram"),
-                   av.isShowConsensusHistogram());
-           chist.addActionListener(new ActionListener()
-           {
-             @Override
-             public void actionPerformed(ActionEvent e)
-             {
-               // TODO: pass on reference
-               // to ap
-               // so the
-               // view
-               // can be
-               // updated.
-               av.setShowConsensusHistogram(chist.getState());
-               ap.alignFrame.setMenusForViewport();
-               ap.repaint();
-               // ap.annotationPanel.paint(ap.annotationPanel.getGraphics());
-             }
-           });
-           pop.add(chist);
-           final JCheckBoxMenuItem cprof = new JCheckBoxMenuItem(
-                   MessageManager.getString("label.show_logo"),
-                   av.isShowSequenceLogo());
-           cprof.addActionListener(new ActionListener()
-           {
-             @Override
-             public void actionPerformed(ActionEvent e)
-             {
-               // TODO: pass on reference
-               // to ap
-               // so the
-               // view
-               // can be
-               // updated.
-               av.setShowSequenceLogo(cprof.getState());
-               ap.alignFrame.setMenusForViewport();
-               ap.repaint();
-               // ap.annotationPanel.paint(ap.annotationPanel.getGraphics());
-             }
-           });
-           pop.add(cprof);
-           final JCheckBoxMenuItem cprofnorm = new JCheckBoxMenuItem(
-                   MessageManager.getString("label.normalise_logo"),
-                   av.isNormaliseSequenceLogo());
-           cprofnorm.addActionListener(new ActionListener()
-           {
-             @Override
-             public void actionPerformed(ActionEvent e)
-             {
-               // TODO: pass on reference
-               // to ap
-               // so the
-               // view
-               // can be
-               // updated.
-               av.setShowSequenceLogo(true);
-               av.setNormaliseSequenceLogo(cprofnorm.getState());
-               ap.alignFrame.setMenusForViewport();
-               ap.repaint();
-               // ap.annotationPanel.paint(ap.annotationPanel.getGraphics());
-             }
-           });
-           pop.add(cprofnorm);
-         }
-         final JMenuItem consclipbrd = new JMenuItem(COPYCONS_SEQ);
-         consclipbrd.addActionListener(this);
-         pop.add(consclipbrd);
-       }
-     }
-     pop.show(this, evt.getX(), evt.getY());
    }
  
    /**
@@@ -20,7 -20,6 +20,7 @@@
   */
  package jalview.renderer.seqfeatures;
  
 +import jalview.api.AlignViewportI;
  import jalview.datamodel.SequenceFeature;
  import jalview.datamodel.SequenceI;
  import jalview.viewmodel.seqfeatures.FeatureRendererModel;
@@@ -51,16 -50,6 +51,16 @@@ public class FeatureRenderer extends Fe
  
    boolean av_validCharWidth, av_isShowSeqFeatureHeight;
  
 +  /**
 +   * Constructor given a viewport
 +   * 
 +   * @param viewport
 +   */
 +  public FeatureRenderer(AlignViewportI viewport)
 +  {
 +    this.av = viewport;
 +  }
 +
    protected void updateAvConfig()
    {
      av_charHeight = av.getCharHeight();
  
      }
  
-     if (transparency != 1.0f && g != null && transparencyAvailable)
+     if (transparency != 1.0f && g != null)
      {
        Graphics2D g2 = (Graphics2D) g;
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
      }
    }
  
-   boolean transparencyAvailable = true;
-   protected void setTransparencyAvailable(boolean isTransparencyAvailable)
-   {
-     transparencyAvailable = isTransparencyAvailable;
-   }
-   @Override
-   public boolean isTransparencyAvailable()
-   {
-     return transparencyAvailable;
-   }
    /**
     * Called when alignment in associated view has new/modified features to
     * discover and display.
@@@ -28,6 -28,7 +28,6 @@@ import jalview.datamodel.SequenceFeatur
  import jalview.datamodel.SequenceI;
  import jalview.renderer.seqfeatures.FeatureRenderer;
  import jalview.schemes.GraduatedColor;
 -import jalview.viewmodel.AlignmentViewport;
  
  import java.awt.Color;
  import java.beans.PropertyChangeListener;
@@@ -65,7 -66,7 +65,7 @@@ public abstract class FeatureRendererMo
    protected PropertyChangeSupport changeSupport = new PropertyChangeSupport(
            this);
  
 -  protected AlignmentViewport av;
 +  protected AlignViewportI av;
  
    /*
     * map holds per feature type, {{min, max}, {min, max}} feature score
    }
  
    /**
-    * return a nominal colour for this feature
-    * 
-    * @param featureType
-    * @return standard color, or maximum colour for graduated colourscheme
-    */
-   public Color getColour(String featureType)
-   {
-     Object fc = getFeatureStyle(featureType);
-     if (fc instanceof Color)
-     {
-       return (Color) fc;
-     }
-     else
-     {
-       if (fc instanceof GraduatedColor)
-       {
-         return ((GraduatedColor) fc).getMaxColor();
-       }
-     }
-     throw new Error("Implementation Error: Unrecognised render object "
-             + fc.getClass() + " for features of type " + featureType);
-   }
-   /**
     * calculate the render colour for a specific feature using current feature
     * settings.
     * 
      return renderOrder != null;
    }
  
+   /**
+    * Returns feature types in ordering of rendering, where last means on top
+    */
    public List<String> getRenderOrder()
    {
      if (renderOrder == null)
      while (en.hasNext())
      {
        String col = en.next();
-       fcols.put(col, getColour(col));
+       fcols.put(col, featureColours.get(col));
      }
      return fcols;
    }
@@@ -1,11 -1,9 +1,11 @@@
  package jalview.workers;
  
 +import jalview.api.AlignViewportI;
 +import jalview.api.AlignmentViewPanel;
+ import jalview.bin.Jalview;
  import jalview.datamodel.AlignmentAnnotation;
  import jalview.datamodel.Annotation;
  import jalview.gui.AlignFrame;
- import jalview.gui.Desktop;
  
  import java.awt.Color;
  
@@@ -14,9 -12,9 +14,9 @@@
   * such as Groovy) to 'register and forget' an alignment annotation calculator. <br>
   * Currently supports two flavours of calculator:
   * <ul>
 - * <li>a 'feature counter' which can count any desired property derivable from
 + * <li>a simple 'feature counter' which counts any desired score derivable from
   * residue value and any sequence features at each position of the alignment</li>
 - * <li>a 'general purpose' calculator which computes one more complete
 + * <li>a 'general purpose' calculator which computes one or more complete
   * AlignmentAnnotation objects</li>
   * </ul>
   */
@@@ -30,13 -28,9 +30,13 @@@ public class AlignmentAnnotationFactor
     */
    public static void newCalculator(FeatureCounterI counter)
    {
 -    if (Jalview.getCurrentAlignFrame() != null)
 +    // TODO need an interface for AlignFrame by which to access
 +    // its AlignViewportI and AlignmentViewPanel
-     AlignFrame currentAlignFrame = Desktop.getCurrentAlignFrame();
++    AlignFrame currentAlignFrame = Jalview.getCurrentAlignFrame() ;
 +    if (currentAlignFrame != null)
      {
 -      newCalculator(Jalview.getCurrentAlignFrame(), counter);
 +      newCalculator(currentAlignFrame.getViewport(), currentAlignFrame
 +              .getAlignPanels().get(0), counter);
      }
      else
      {
    /**
     * Constructs and registers a new alignment annotation worker
     * 
 -   * @param af
 -   *          the AlignFrame for which the annotation is to be calculated
 +   * @param viewport
 +   * @param panel
     * @param counter
     *          provider of feature counts per alignment position
     */
 -  public static void newCalculator(AlignFrame af, FeatureCounterI counter)
 +  public static void newCalculator(AlignViewportI viewport,
 +          AlignmentViewPanel panel, FeatureCounterI counter)
    {
 -    new ColumnCounterWorker(af, counter);
 +    new ColumnCounterWorker(viewport, panel, counter);
    }
  
    /**
     */
    public static void newCalculator(AnnotationProviderI calculator)
    {
 -    if (Jalview.getCurrentAlignFrame() != null)
 +    // TODO need an interface for AlignFrame by which to access
 +    // its AlignViewportI and AlignmentViewPanel
-     AlignFrame currentAlignFrame = Desktop.getCurrentAlignFrame();
++    AlignFrame currentAlignFrame = Jalview.getCurrentAlignFrame() ;
 +    if (currentAlignFrame != null)
      {
 -      newCalculator(Jalview.getCurrentAlignFrame(), calculator);
 +      newCalculator(currentAlignFrame.getViewport(), currentAlignFrame
 +              .getAlignPanels().get(0), calculator);
      }
      else
      {
    /**
     * Constructs and registers a new alignment annotation worker
     * 
 -   * @param af
 -   *          the AlignFrame for which the annotation is to be calculated
 +   * @param viewport
 +   * @param panel
     * @param calculator
     *          provider of AlignmentAnnotation for the alignment
     */
 -  public static void newCalculator(AlignFrame af,
 +  public static void newCalculator(AlignViewportI viewport,
 +          AlignmentViewPanel panel,
            AnnotationProviderI calculator)
    {
 -    new AnnotationWorker(af, calculator);
 +    new AnnotationWorker(viewport, panel, calculator);
    }
  
    /**