Skip to content
Snippets Groups Projects
FeaturePopup.java 29.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • tjc's avatar
    tjc committed
    /* FeaturePopup.java
     *
     * created: Wed Oct 21 1998
     *
     * This file is part of Artemis
     *
     * Copyright(C) 1998,1999,2000,2001,2002  Genome Research Limited
     *
     * This program 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 2
     * of the License, or(at your option) any later version.
     *
     * This program 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 this program; if not, write to the Free Software
     * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
     *
    
    tjc's avatar
    tjc committed
     * $Header: //tmp/pathsoft/artemis/uk/ac/sanger/artemis/components/FeaturePopup.java,v 1.22 2008-01-17 09:57:06 tjc Exp $
    
    tjc's avatar
    tjc committed
     */
    
    package uk.ac.sanger.artemis.components;
    
    import uk.ac.sanger.artemis.*;
    
    tjc's avatar
    tjc committed
    import uk.ac.sanger.artemis.components.genebuilder.GeneUtils;
    
    import uk.ac.sanger.artemis.io.Key;
    
    tjc's avatar
    tjc committed
    import uk.ac.sanger.artemis.util.StringVector;
    
    import java.io.*;
    
    tjc's avatar
    tjc committed
    import java.awt.Component;
    
    tjc's avatar
    tjc committed
    import java.awt.BorderLayout;
    
    tjc's avatar
    tjc committed
    import java.awt.event.*;
    import javax.swing.*;
    
    /**
     *  FeaturePopup class
     *
     *  @author Kim Rutherford
    
    tjc's avatar
    tjc committed
     *  @version $Id: FeaturePopup.java,v 1.22 2008-01-17 09:57:06 tjc Exp $
    
    tjc's avatar
    tjc committed
     *
     **/
    
    public class FeaturePopup extends JPopupMenu 
    {
    
      /** */
      private static final long serialVersionUID = 1L;
    
    
    tjc's avatar
    tjc committed
      /**
       *  The reference of the EntryGroup object that was passed to the
       *  constructor.
       **/
      private EntryGroup entry_group;
    
      /**
       *  This is the Selection object that was passed to the constructor.
       **/
      final private Selection selection;
    
      /**
       *  This is a reference to the GotoEventSource object that was passed to the
       *  constructor.
       **/
      private GotoEventSource goto_event_source;
    
      /**
       *  The reference of the object that created this popup.
       **/
      private DisplayComponent owner;
    
      /**
       *  If the parent component of this popup is a FeatureDisplay then this will
       *  contain it's reference.
       **/
      private FeatureDisplay feature_display = null;
    
      /**
       *  If the parent component of this popup is a FeatureList then this will
       *  contain it's reference.
       **/
      private FeatureList feature_list = null;
    
      /**
       *  Set by the constructor to be the(possibly) empty vector of selected
       *  features.
       **/
      private FeatureVector selection_features;
    
      /**
       *  Set by the constructor to be the(possibly) empty vector of selected
       *  features.
       **/
      private FeatureSegmentVector selection_segments;
      private BasePlotGroup base_plot_group = null;
    
    tjc's avatar
    tjc committed
      private JMenuItem feature_display_menus[] = null;
    
    tjc's avatar
    tjc committed
      private int SCORE_MINIMUM = Integer.MAX_VALUE;
      private int SCORE_MAXIMUM = Integer.MIN_VALUE;
    
    tjc's avatar
    tjc committed
    
      /**
       *  Create a new FeaturePopup object.
       *  @param owner The component where this popup was popped up from.
       *  @param selection The selection to use for this popup.
       *  @param base_plot_group The BasePlotGroup associated with this JMenu -
       *    needed to call getCodonUsageAlgorithm()
       **/
      public FeaturePopup(final DisplayComponent owner,
                          final EntryGroup entry_group,
                          final Selection selection,
                          final GotoEventSource goto_event_source,
                          final BasePlotGroup base_plot_group) 
      {
        super(getMenuName(owner));
    
        this.owner = owner;
        this.entry_group = entry_group;
        this.selection = selection;
        this.goto_event_source = goto_event_source;
        this.base_plot_group = base_plot_group;
    
        selection_features = selection.getSelectedFeatures();
        selection_segments = selection.getSelectedSegments();
    
    
    tjc's avatar
    tjc committed
        final JMenuItem action_menus[] = makeSubMenus();
        JMenuItem feature_list_menus[] = null;
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
        if(owner instanceof FeatureDisplay)
        {
          feature_display = (FeatureDisplay)owner;
          feature_display_menus = addFeatureDisplayItems();
          for(int i = 0; i<feature_display_menus.length; i++)
            if(!(feature_display_menus[i] instanceof JCheckBoxMenuItem))
              maybeAdd(feature_display_menus[i]);
        }
        else // must be a FeatureList
        {
          feature_list = (FeatureList)owner;
          feature_list_menus = addFeatureListItems();
    
    tjc's avatar
    tjc committed
          for(int i=0; i<feature_list_menus.length; i++)
    
    tjc's avatar
    tjc committed
            if(!(feature_list_menus[i] instanceof JCheckBoxMenuItem))
              maybeAdd(feature_list_menus[i]);
        }
        addSeparator();
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
        for(int i = 0; i<action_menus.length; i++)
          maybeAdd(action_menus[i]);
    
        addSeparator();
    
    tjc's avatar
    tjc committed
        if(owner instanceof FeatureDisplay) 
        {
    
    tjc's avatar
    tjc committed
          for(int i = 0; i<feature_display_menus.length; i++)
            if((feature_display_menus[i] instanceof JCheckBoxMenuItem))
              maybeAdd(feature_display_menus[i]);
        }
    
    tjc's avatar
    tjc committed
        else 
        {
    
    tjc's avatar
    tjc committed
          for(int i=0; i<feature_list_menus.length; i++)
            if((feature_list_menus[i] instanceof JCheckBoxMenuItem))
              maybeAdd(feature_list_menus[i]);
    
    tjc's avatar
    tjc committed
        }
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
      }
    
      /**
       *  Rename the name String to use for this JMenu.
       **/
      private static String getMenuName(final DisplayComponent owner) 
      {
        if(owner instanceof FeatureDisplay) 
          return "Feature Viewer JMenu";
        else
          return "Feature List JMenu";
      }
    
      /**
       *  Add an item only if it isn't null.
       **/
      private void maybeAdd(JMenuItem item) 
      {
        if(item != null) 
          add(item);
      }
    
      /**
       *  Create the Edit, Add and View sub menus.
       **/
    
    tjc's avatar
    tjc committed
      private JMenuItem[] makeSubMenus()
    
    tjc's avatar
    tjc committed
      {
    
    tjc's avatar
    tjc committed
        final JMenuItem[] action_menus = new JMenuItem[8];
    
    
    tjc's avatar
    tjc committed
        final JFrame frame = owner.getParentFrame();
    
    tjc's avatar
    tjc committed
        action_menus[0] = new EntryGroupMenu(frame, getEntryGroup());
    
    tjc's avatar
    tjc committed
    
    
        AlignmentViewer alignQueryViewer   = null;
        AlignmentViewer alignSubjectViewer = null;
    
        if(frame instanceof MultiComparator)
        {
          MultiComparator mc = (MultiComparator)frame;
    
          // determine which FeatureDisplay
          int ifeature_display;
          for(ifeature_display = 0; ifeature_display < mc.getEntryGroupArray().length;
              ++ifeature_display)
          {
            final EntryGroup this_entry_group = mc.getEntryGroupArray()[ifeature_display];
            if(this_entry_group == getEntryGroup())
              break;
          }
    
          if(ifeature_display==0)
            alignQueryViewer = null;
          else
            alignQueryViewer = mc.getAlignmentViewerArray()[ifeature_display-1];
    
          if(ifeature_display == mc.getEntryGroupArray().length-1)
            alignSubjectViewer = null;
          else
            alignSubjectViewer = mc.getAlignmentViewerArray()[ifeature_display];
    
          action_menus[1] =
              new SelectMenu(frame, selection,
                             getGotoEventSource(),
                             getEntryGroup(),
                             base_plot_group,
                             alignQueryViewer, alignSubjectViewer,
                             "Select");
        }
        else
          action_menus[1] = new SelectMenu(frame, selection,
                                           getGotoEventSource(),
                                           getEntryGroup(),
                                           base_plot_group);
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
        action_menus[2] = new ViewMenu(frame, selection,
    
    tjc's avatar
    tjc committed
                                      getGotoEventSource(),
                                      getEntryGroup(),
                                      base_plot_group);
    
    
    tjc's avatar
    tjc committed
        action_menus[3] = new GotoMenu(frame, selection,
    
    tjc's avatar
    tjc committed
                                      getGotoEventSource(),
                                      getEntryGroup());
    
        if(Options.readWritePossible()) 
        {
    
    tjc's avatar
    tjc committed
          action_menus[4] = new EditMenu(frame, selection,
    
    tjc's avatar
    tjc committed
                                        getGotoEventSource(),
                                        getEntryGroup(),
    
    tjc's avatar
    tjc committed
                                        base_plot_group, owner);
    
    tjc's avatar
    tjc committed
          if(entry_group instanceof SimpleEntryGroup) 
    
          {
            if(frame instanceof MultiComparator)
              action_menus[5] = new AddMenu(frame, selection,
                                        getEntryGroup(),
                                        getGotoEventSource(),
                                        base_plot_group,
                                        alignQueryViewer, alignSubjectViewer,
                                        "Create");
            else
              action_menus[5] = new AddMenu(frame, selection,
    
    tjc's avatar
    tjc committed
                                        getEntryGroup(),
                                        getGotoEventSource(),
                                        base_plot_group);
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
          action_menus[6] = new WriteMenu(frame, selection,
    
    tjc's avatar
    tjc committed
                                          getEntryGroup());
          if(Options.isUnixHost()) 
    
    tjc's avatar
    tjc committed
            action_menus[7] = new RunMenu(frame, selection);
    
    tjc's avatar
    tjc committed
        }
    
    tjc's avatar
    tjc committed
        return action_menus;
    
    tjc's avatar
    tjc committed
      }
    
      /**
       *  Create those menu items that are relevant only to FeatureDisplay objects.
       **/
    
    tjc's avatar
    tjc committed
      private JMenuItem[] addFeatureDisplayItems() 
    
    tjc's avatar
    tjc committed
      {
    
    tjc's avatar
    tjc committed
        final JMenuItem[] feature_display_menus;
        
        final boolean isDatabaseGroup = GeneUtils.isDatabaseEntry( getEntryGroup() );
        if(isDatabaseGroup)
          feature_display_menus = new JMenuItem[21];
        else
          feature_display_menus = new JMenuItem[20];
        
    
    tjc's avatar
    tjc committed
        feature_display_menus[0] = new JCheckBoxMenuItem("Start Codons");
        ((JCheckBoxMenuItem)feature_display_menus[0]).setState(
                                   feature_display.getShowStartCodons());
        feature_display_menus[0].addItemListener(new ItemListener()
    
    tjc's avatar
    tjc committed
        {
          public void itemStateChanged(ItemEvent event) 
          {
    
    tjc's avatar
    tjc committed
            feature_display.setShowStartCodons(
                       ((JCheckBoxMenuItem)feature_display_menus[0]).getState());
    
    tjc's avatar
    tjc committed
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[1] = new JCheckBoxMenuItem("Stop Codons");
        ((JCheckBoxMenuItem)feature_display_menus[1]).setState(
                                   feature_display.getShowStopCodons());
        feature_display_menus[1].addItemListener(new ItemListener() 
    
    tjc's avatar
    tjc committed
        {
          public void itemStateChanged(ItemEvent event) 
          {
    
    tjc's avatar
    tjc committed
            feature_display.setShowStopCodons(
                      ((JCheckBoxMenuItem)feature_display_menus[1]).getState());
    
    tjc's avatar
    tjc committed
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[2] = new JCheckBoxMenuItem("Feature Arrows");
        ((JCheckBoxMenuItem)feature_display_menus[2]).setState(
                                   feature_display.getShowFeatureArrows());
        feature_display_menus[2].addItemListener(new ItemListener() 
    
    tjc's avatar
    tjc committed
        {
          public void itemStateChanged(ItemEvent event) 
          {
    
    tjc's avatar
    tjc committed
            feature_display.setShowFeatureArrows(
                      ((JCheckBoxMenuItem)feature_display_menus[2]).getState());
    
    tjc's avatar
    tjc committed
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[3] = new JCheckBoxMenuItem("Feature Borders");
        ((JCheckBoxMenuItem)feature_display_menus[3]).setState(
                                       feature_display.getShowFeatureBorders());
        feature_display_menus[3].addItemListener(new ItemListener() 
    
    tjc's avatar
    tjc committed
        {
          public void itemStateChanged(ItemEvent event) 
          {
    
    tjc's avatar
    tjc committed
            feature_display.setShowFeatureBorders(
                      ((JCheckBoxMenuItem)feature_display_menus[3]).getState());
    
    tjc's avatar
    tjc committed
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[4] = new JCheckBoxMenuItem("Feature Labels");
        ((JCheckBoxMenuItem)feature_display_menus[4]).setState(feature_display.getShowLabels());
        feature_display_menus[4].addItemListener(new ItemListener() 
    
    tjc's avatar
    tjc committed
        {
          public void itemStateChanged(ItemEvent e) 
          {
    
    tjc's avatar
    tjc committed
            feature_display.setShowLabels(
                      ((JCheckBoxMenuItem)feature_display_menus[4]).getState());
    
    tjc's avatar
    tjc committed
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[5] = new JCheckBoxMenuItem("One Line Per Entry");
        ((JCheckBoxMenuItem)feature_display_menus[5]).setState(
                                     feature_display.getOneLinePerEntryFlag());
        feature_display_menus[5].addItemListener(new ItemListener() 
    
    tjc's avatar
    tjc committed
        {
          public void itemStateChanged(ItemEvent e) 
          {
    
    tjc's avatar
    tjc committed
            final boolean new_state = 
                      ((JCheckBoxMenuItem)feature_display_menus[5]).getState();
    
    tjc's avatar
    tjc committed
            if(new_state && getEntryGroup().size() > 8) 
              feature_display.setShowLabels(false);
            feature_display.setOneLinePerEntry(new_state);
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[6] = new JCheckBoxMenuItem("Forward Frame Lines");
        ((JCheckBoxMenuItem)feature_display_menus[6]).setState(
                                    feature_display.getShowForwardFrameLines());
        feature_display_menus[6].addItemListener(new ItemListener() 
    
    tjc's avatar
    tjc committed
        {
          public void itemStateChanged(ItemEvent e) 
          {
    
    tjc's avatar
    tjc committed
            feature_display.setShowForwardFrameLines(
                      ((JCheckBoxMenuItem)feature_display_menus[6]).getState());
    
    tjc's avatar
    tjc committed
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[7] = new JCheckBoxMenuItem("Reverse Frame Lines");
        ((JCheckBoxMenuItem)feature_display_menus[7]).setState(
                                   feature_display.getShowReverseFrameLines());
        feature_display_menus[7].addItemListener(new ItemListener() 
    
    tjc's avatar
    tjc committed
        {
          public void itemStateChanged(ItemEvent e) 
          {
    
    tjc's avatar
    tjc committed
            feature_display.setShowReverseFrameLines(
                      ((JCheckBoxMenuItem)feature_display_menus[7]).getState());
    
    tjc's avatar
    tjc committed
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[8] = new JCheckBoxMenuItem("All Features On Frame Lines");
        ((JCheckBoxMenuItem)feature_display_menus[8]).setState(
                                                feature_display.getFrameFeaturesFlag());
        feature_display_menus[8].addItemListener(new ItemListener() 
    
    tjc's avatar
    tjc committed
        {
          public void itemStateChanged(ItemEvent e) 
          {
    
    tjc's avatar
    tjc committed
            feature_display.setFrameFeaturesFlag(
                      ((JCheckBoxMenuItem)feature_display_menus[8]).getState());
    
    tjc's avatar
    tjc committed
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[9] = new JCheckBoxMenuItem("Show Source Features");
        ((JCheckBoxMenuItem)feature_display_menus[9]).setState(
                                        feature_display.getShowSourceFeatures());
        feature_display_menus[9].addItemListener(new ItemListener() 
    
    tjc's avatar
    tjc committed
        {
          public void itemStateChanged(ItemEvent e) 
          {
    
    tjc's avatar
    tjc committed
            feature_display.setShowSourceFeatures(
                      ((JCheckBoxMenuItem)feature_display_menus[9]).getState());
    
    tjc's avatar
    tjc committed
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[10] = new JCheckBoxMenuItem("Flip Display");
        ((JCheckBoxMenuItem)feature_display_menus[10]).setState(
                                      feature_display.isRevCompDisplay());
        feature_display_menus[10].addItemListener(new ItemListener()
    
    tjc's avatar
    tjc committed
        {
          public void itemStateChanged(ItemEvent e) 
          {
    
    tjc's avatar
    tjc committed
            feature_display.setRevCompDisplay(
                      ((JCheckBoxMenuItem)feature_display_menus[10]).getState());
    
    tjc's avatar
    tjc committed
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[11] = new JCheckBoxMenuItem("Colourise Bases");
        ((JCheckBoxMenuItem)feature_display_menus[11]).setState(
                                       feature_display.getShowBaseColours());
        feature_display_menus[11].addItemListener(new ItemListener() 
    
    tjc's avatar
    tjc committed
        {
          public void itemStateChanged(ItemEvent e) 
          {
    
    tjc's avatar
    tjc committed
            feature_display.setShowBaseColours(
                      ((JCheckBoxMenuItem)feature_display_menus[11]).getState());
    
    tjc's avatar
    tjc committed
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[12] = new JMenuItem("Smallest Features In Front");
        feature_display_menus[12].addActionListener(new ActionListener() 
    
    tjc's avatar
    tjc committed
        {
          public void actionPerformed(ActionEvent e) 
          {
            // clear the selection because selected features will always be on
            // top - which is not usually what is wanted
            selection.clear();
            feature_display.smallestToFront();
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[13] = new JMenuItem("Set Score Cutoffs ...");
        feature_display_menus[13].addActionListener(new ActionListener() 
    
    tjc's avatar
    tjc committed
        {
          public void actionPerformed(ActionEvent e) 
          {
            final ScoreChangeListener minimum_listener =
              new ScoreChangeListener() 
              {
                public void scoreChanged(final ScoreChangeEvent event) 
                {
                  feature_display.setMinimumScore(event.getValue());
                }
              };
    
            final ScoreChangeListener maximum_listener =
              new ScoreChangeListener() 
              {
                public void scoreChanged(final ScoreChangeEvent event) 
                {
                  feature_display.setMaximumScore(event.getValue());
                }
              };
    
    
    tjc's avatar
    tjc committed
            FeatureVector features = getEntryGroup().getAllFeatures();
            int score;
            for(int i=0; i<features.size(); i++)
            {
              score = features.elementAt(i).getScore();
              if(score > -1)
              {
                if(score < SCORE_MINIMUM)
                  SCORE_MINIMUM = score;
                else if(score > SCORE_MAXIMUM)
                  SCORE_MAXIMUM = score;
              }
            }
            
            if(SCORE_MINIMUM == Integer.MAX_VALUE)
              SCORE_MINIMUM = 0;
            if(SCORE_MAXIMUM == Integer.MIN_VALUE)
              SCORE_MAXIMUM = 100;
            
    
    tjc's avatar
    tjc committed
            final ScoreChanger score_changer =
              new ScoreChanger("Score Cutoffs",
                                minimum_listener, maximum_listener,
    
    tjc's avatar
    tjc committed
                                SCORE_MINIMUM, SCORE_MAXIMUM);
    
    tjc's avatar
    tjc committed
    
            score_changer.setVisible(true);
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[14] = new JMenuItem("Raise Selected Features");
        feature_display_menus[14].addActionListener(new ActionListener() 
    
    tjc's avatar
    tjc committed
        {
    
    tjc's avatar
    tjc committed
          public void actionPerformed(ActionEvent event) 
    
    tjc's avatar
    tjc committed
          {
    
    tjc's avatar
    tjc committed
            raiseSelection();
          }
        });
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[15] = new JMenuItem("Lower Selected Features");
        feature_display_menus[15].addActionListener(new ActionListener() 
        {
          public void actionPerformed(ActionEvent event) 
    
    tjc's avatar
    tjc committed
          {
    
    tjc's avatar
    tjc committed
            lowerSelection();
          }
        });
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[16] = new JMenuItem("Zoom to Selection");
        feature_display_menus[16].addActionListener(new ActionListener() 
    
    tjc's avatar
    tjc committed
        {
    
    tjc's avatar
    tjc committed
          public void actionPerformed(ActionEvent event) 
    
    tjc's avatar
    tjc committed
          {
    
    tjc's avatar
    tjc committed
            zoomToSelection((FeatureDisplay) owner);
          }
        });
    
    tjc's avatar
    tjc committed
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[17] = new JMenuItem("Select Visible Range");
        feature_display_menus[17].addActionListener(new ActionListener() 
    
    tjc's avatar
    tjc committed
        {
          public void actionPerformed(ActionEvent e) 
          {
            selection.setMarkerRange(feature_display.getVisibleMarkerRange());
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_display_menus[18] = new JMenuItem("Select Visible Features");
        feature_display_menus[18].addActionListener(new ActionListener() 
        {
          public void actionPerformed(ActionEvent e) 
          {
    
    tjc's avatar
    tjc committed
            selection.set(feature_display.getCurrentVisibleFeatures());
          }
        });
    
    tjc's avatar
    tjc committed
    
    
        feature_display_menus[19] = new JMenuItem("Frame Line Features ...");
    
    tjc's avatar
    tjc committed
        feature_display_menus[19].addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
    
    tjc's avatar
    tjc committed
            final DefaultListModel listModel = new DefaultListModel();
            final Object protein_keys[] = ((FeatureDisplay)owner).getProteinKeys();
    
            for(int i=0; i<protein_keys.length; i++)
              listModel.addElement(protein_keys[i]);
    
    
    tjc's avatar
    tjc committed
            JPanel frame_keys = new JPanel(new BorderLayout());
    
            
            final JLabel label = new JLabel("Features Displayed on the Frame Lines:");
            final JList protein_list = new JList(listModel);
            final JScrollPane jsp    = new JScrollPane(protein_list);
    
            JButton remove_butt = new JButton("REMOVE");
            remove_butt.addActionListener(new ActionListener()
            {
              public void actionPerformed(ActionEvent e)
              {
                while(!protein_list.isSelectionEmpty())
                  listModel.remove(protein_list.getSelectedIndex());
              }
            });
    
            Box bdown = Box.createVerticalBox();
            bdown.add(label);
            bdown.add(jsp);
            bdown.add(remove_butt);
            frame_keys.add(bdown, BorderLayout.CENTER);
    
    
            final KeyChoice key_choice =
               new KeyChoice(entry_group.elementAt(0).getEntryInformation(),
                             new uk.ac.sanger.artemis.io.Key("CDS"));
    
            JButton add_butt = new JButton("ADD");
            add_butt.addActionListener(new ActionListener()
            {
              public void actionPerformed(ActionEvent e)
              {
                listModel.addElement(key_choice.getSelectedItem().toString());
              }
            });
    
            bdown = Box.createVerticalBox();
            bdown.add(Box.createVerticalGlue());
            bdown.add(key_choice);
            bdown.add(add_butt);
            frame_keys.add(bdown, BorderLayout.EAST);
    
    
    tjc's avatar
    tjc committed
            int select = JOptionPane.showConfirmDialog(null, frame_keys,
    
                                    "Frame Line Features ...",
    
    tjc's avatar
    tjc committed
                                     JOptionPane.OK_CANCEL_OPTION,
                                     JOptionPane.QUESTION_MESSAGE);
    
            if(select == JOptionPane.CANCEL_OPTION)
              return;
    
            
            ((FeatureDisplay)owner).setProteinKeys(listModel.toArray());
    
    tjc's avatar
    tjc committed
        
        if(isDatabaseGroup)
        {
    
    tjc's avatar
    tjc committed
          feature_display_menus[20] = new JMenuItem("Show/Hide Features ...");
    
    tjc's avatar
    tjc committed
          feature_display_menus[20].addActionListener(new ActionListener()
          {
            public void actionPerformed(ActionEvent e)
            {
              GeneUtils.defineShowHideGeneFeatures(feature_display.getEntryGroup()
                  .getAllFeatures());
            }
          });
        }
        
    
    tjc's avatar
    tjc committed
        return feature_display_menus;
    
    tjc's avatar
    tjc committed
      }
    
    
    tjc's avatar
    tjc committed
    
      /**
      *
      * Override show() 
      *
      */
      public void show(Component invoker, int x, int y)
      {
        if(owner instanceof FeatureDisplay)
        {
          if(selection_features.size() > 0 || selection_segments.size() > 0)
          {
            feature_display_menus[14].setEnabled(true);
            feature_display_menus[15].setEnabled(true);
    
    tjc's avatar
    tjc committed
    //      feature_display_menus[16].setEnabled(true);
    
    tjc's avatar
    tjc committed
          }
          else
          {
            feature_display_menus[14].setEnabled(false);
            feature_display_menus[15].setEnabled(false);
    
    tjc's avatar
    tjc committed
    //      feature_display_menus[16].setEnabled(false);
    
    tjc's avatar
    tjc committed
          }
        }
    
        super.show(invoker, x, y);
      }
    
    
    tjc's avatar
    tjc committed
      /**
       *  Create those menu items that are relevant only to FeatureList objects.
       **/
    
    tjc's avatar
    tjc committed
      private JMenuItem[] addFeatureListItems() 
    
    tjc's avatar
    tjc committed
      {
    
    tjc's avatar
    tjc committed
        final JMenuItem feature_list_menus[] = new JMenuItem[7];
    
    tjc's avatar
    tjc committed
        if(Options.getOptions().readWritePossible()) 
        {
    
    tjc's avatar
    tjc committed
          feature_list_menus[0] = new JMenuItem("Save List To File ...");
          feature_list_menus[0].addActionListener(new ActionListener() 
    
    tjc's avatar
    tjc committed
          {
            public void actionPerformed(ActionEvent e) 
            {
              saveFeatureList();
            }
          });
        }
    
    
    tjc's avatar
    tjc committed
        feature_list_menus[1] = new JCheckBoxMenuItem("Show Correlation Scores");
        ((JCheckBoxMenuItem)feature_list_menus[1]).setState(
                                            feature_list.getCorrelationScores());
        feature_list_menus[1].addItemListener(new ItemListener() 
    
    tjc's avatar
    tjc committed
        {
          public void itemStateChanged(ItemEvent e) 
          {
    
    tjc's avatar
    tjc committed
            feature_list.setCorrelationScores(
                          ((JCheckBoxMenuItem)feature_list_menus[1]).getState());
    
    tjc's avatar
    tjc committed
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_list_menus[2] = new JCheckBoxMenuItem("Show Gene Names");
        ((JCheckBoxMenuItem)feature_list_menus[2]).setState(feature_list.getShowGenes());
        feature_list_menus[2].addItemListener(new ItemListener() 
    
    tjc's avatar
    tjc committed
        {
          public void itemStateChanged(ItemEvent e) 
          {
    
    tjc's avatar
    tjc committed
            boolean show_sysid = ((JCheckBoxMenuItem)feature_list_menus[3]).getState();
            boolean show_genes = ((JCheckBoxMenuItem)feature_list_menus[2]).getState();
            if(show_sysid && show_genes)
    
    tjc's avatar
    tjc committed
              ((JCheckBoxMenuItem)feature_list_menus[3]).setState(false);
              feature_list.setShowSystematicID(false);
    
    tjc's avatar
    tjc committed
            feature_list.setShowGenes(show_genes);
    
    tjc's avatar
    tjc committed
          }
        });
    
    
    tjc's avatar
    tjc committed
        feature_list_menus[3] = new JCheckBoxMenuItem("Show Systematic ID");
        ((JCheckBoxMenuItem)feature_list_menus[3]).setState(feature_list.getShowSysID());
        feature_list_menus[3].addItemListener(new ItemListener()
    
        {
          public void itemStateChanged(ItemEvent e)
          {
    
    tjc's avatar
    tjc committed
            boolean show_sysid = ((JCheckBoxMenuItem)feature_list_menus[3]).getState();
            boolean show_genes = ((JCheckBoxMenuItem)feature_list_menus[2]).getState();
            if(show_genes && show_sysid)
    
    tjc's avatar
    tjc committed
              ((JCheckBoxMenuItem)feature_list_menus[2]).setState(false);
              feature_list.setShowGenes(false);
    
    tjc's avatar
    tjc committed
            feature_list.setShowSystematicID(show_sysid);
    
    tjc's avatar
    tjc committed
        feature_list_menus[4] = new JCheckBoxMenuItem("Show Products");
        ((JCheckBoxMenuItem)feature_list_menus[4]).setState(feature_list.getShowProducts());
        feature_list_menus[4].addItemListener(new ItemListener() 
    
    tjc's avatar
    tjc committed
        {
          public void itemStateChanged(ItemEvent e) 
          {
    
    tjc's avatar
    tjc committed
            boolean show_products = ((JCheckBoxMenuItem)feature_list_menus[4]).getState();
            if(show_products) 
    
    tjc's avatar
    tjc committed
            {
              ((JCheckBoxMenuItem)feature_list_menus[5]).setState(false);
    
    tjc's avatar
    tjc committed
              feature_list.setShowQualifiers(false);
    
    tjc's avatar
    tjc committed
            }
    
    tjc's avatar
    tjc committed
            feature_list.setShowProducts(show_products);
    
    tjc's avatar
    tjc committed
          }
        });
        
    
    tjc's avatar
    tjc committed
        feature_list_menus[5] = new JCheckBoxMenuItem("Show Qualifiers");
        ((JCheckBoxMenuItem)feature_list_menus[5]).setState(feature_list.getShowQualifiers());
        feature_list_menus[5].addItemListener(new ItemListener() 
    
    tjc's avatar
    tjc committed
        {
          public void itemStateChanged(ItemEvent e) 
          {
    
    tjc's avatar
    tjc committed
            boolean show_qualifiers = ((JCheckBoxMenuItem)feature_list_menus[5]).getState();
            feature_list.setShowQualifiers(show_qualifiers);
            if(show_qualifiers) 
    
    tjc's avatar
    tjc committed
            { 
              ((JCheckBoxMenuItem)feature_list_menus[4]).setState(false);
    
    tjc's avatar
    tjc committed
              feature_list.setShowProducts(false);
    
    tjc's avatar
    tjc committed
            }
    
    tjc's avatar
    tjc committed
          }
        });
    
    tjc's avatar
    tjc committed
        
    
    tjc's avatar
    tjc committed
        feature_list_menus[6] = new JMenuItem("Show Selected Qualifiers ...");
        feature_list_menus[6].addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent e)
          {
    
            final StringVector sv = feature_list.getShowUserDefinedQualifier();
            final Object display_names[];
            
            if(sv != null && sv.size() > 0)
              display_names = sv.toArray();
            else
            {
              display_names = new Object[1];
              display_names[0] = "note";
            }
            
    
            final String[] description = { 
            		"Qualifiers to display in feature list displays."};
    
            ListSelectionPanel displayListSelectionPanel =
    
              new ListSelectionPanel(entry_group, display_names,
    
            		  description, false, new Key("gene"), null);
    
            int select = JOptionPane.showConfirmDialog(null, 
                displayListSelectionPanel,
                "Select Qualifier to Display",
                 JOptionPane.OK_CANCEL_OPTION,
                 JOptionPane.QUESTION_MESSAGE);
            
    
    tjc's avatar
    tjc committed
            if(select == JOptionPane.CANCEL_OPTION)
              return;
    
    
            feature_list.setShowUserDefinedQualifier(
    
            		displayListSelectionPanel.getResultString());
    
    tjc's avatar
    tjc committed
        return feature_list_menus;
    
    tjc's avatar
    tjc committed
      }
    
      /**
       *  Save the text of the feature list to a file.
       **/
      private void saveFeatureList() 
      {
        final JFrame frame = owner.getParentFrame();
        final StickyFileChooser file_dialog = new StickyFileChooser();
    
        file_dialog.setDialogTitle("Choose save file ...");
        file_dialog.setDialogType(JFileChooser.SAVE_DIALOG);
    
    tjc's avatar
    tjc committed
        final int status = file_dialog.showSaveDialog(frame);
    
    tjc's avatar
    tjc committed
    
        if(status != JFileChooser.APPROVE_OPTION ||
           file_dialog.getSelectedFile() == null) 
          return;
    
        final File write_file =
          new File(file_dialog.getCurrentDirectory(),
                    file_dialog.getSelectedFile().getName());
        
        if(write_file.exists()) 
        {
          final YesNoDialog yes_no_dialog =
            new YesNoDialog(frame,
                             "this file exists: " + write_file +
                             " overwrite it?");
          if(yes_no_dialog.getResult()) 
          {
            // yes - continue
          }
          else 
            return;
        }
        
        try 
        {
          final PrintWriter writer =
            new PrintWriter(new FileWriter(write_file));
          
          final StringVector list_strings = feature_list.getListStrings();
          
          for(int i = 0 ; i < list_strings.size() ; ++i) 
            writer.println(list_strings.elementAt(i));
          
          writer.close();
        } 
        catch(IOException e) 
        {
          new MessageDialog(frame, "error while writing: " + e.getMessage());
        }
      }
    
      /**
       *  Raise the selected features. (FeatureDisplay only.)
       **/
      private void raiseSelection() 
      {
        final FeatureVector features_to_raise = selection.getAllFeatures();
    
        for(int i = 0 ; i < features_to_raise.size() ; ++i) 
        {
          final Feature selection_feature = features_to_raise.elementAt(i);
          feature_display.raiseFeature(selection_feature);
        }
      }
    
      /**
       *  Lower the selected features. (FeatureDisplay only.)
       **/
      private void lowerSelection() 
      {
        final FeatureVector features_to_lower = selection.getAllFeatures();
    
        for(int i = 0 ; i < features_to_lower.size() ; ++i) 
        {
          final Feature selection_feature = features_to_lower.elementAt(i);
          feature_display.lowerFeature(selection_feature);
        }
      }
    
      /**
       *  Zoom the FeatureDisplay to the selection.
       **/
      static void zoomToSelection(final FeatureDisplay feature_display) 
      {
        final Selection selection = feature_display.getSelection();
    
        if(selection.isEmpty()) 
          return;
    
        // why bother in this case?
        if(feature_display.getEntryGroup().getSequenceLength() < 1000) 
          return;
    
        int first_base;
        int last_base;
    
        final FeatureSegmentVector segments = selection.getSelectedSegments();
    
        if(segments.size() == 1) 
        {
          // special case - zoom to the feature instead
          first_base = segments.elementAt(0).getFeature().getRawFirstBase();
          last_base  = segments.elementAt(0).getFeature().getRawLastBase();
        }
        else
        {
          first_base = selection.getLowestBaseOfSelection().getRawPosition();
          last_base  = selection.getHighestBaseOfSelection().getRawPosition();
        }
    
        if(first_base < 250) 
          first_base = 250;
        else 
          first_base -= 250;
    
        last_base += 250;
    
        feature_display.setFirstAndLastBase(first_base, last_base);
      }
    
      /**
       *  Return the EntryGroup object that this FeatureDisplay is displaying.
       **/
      private EntryGroup getEntryGroup() 
      {
        return entry_group;
      }
    
      /**
       *  Return an object that implements the GotoEventSource interface and is
       *  for the sequence that this DisplayComponent is displaying.
       **/
      public GotoEventSource getGotoEventSource() 
      {
        return goto_event_source;
      }
    
    }