Skip to content
Snippets Groups Projects
FeaturePlotGroup.java 9.53 KiB
Newer Older
  • Learn to ignore specific revisions
  • tjc's avatar
    tjc committed
    /* FeaturePlotGroup.java
     *
     * created: Wed Dec 16 1998
     *
     * This file is part of Artemis
     *
     * Copyright (C) 1998,1999,2000  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.
     *
     * $Header: //tmp/pathsoft/artemis/uk/ac/sanger/artemis/components/FeaturePlotGroup.java,v 1.1 2004-06-09 09:46:43 tjc Exp $
     */
    
    package uk.ac.sanger.artemis.components;
    
    import uk.ac.sanger.artemis.*;
    import uk.ac.sanger.artemis.sequence.*;
    import uk.ac.sanger.artemis.plot.*;
    
    import java.awt.*;
    import java.awt.event.*;
    import java.util.Vector;
    
    import javax.swing.*;
    
    /**
     *  This is a super-component containing several FeaturePlot components, each
     *  of which can toggled off and on.  The component contains a row of toggle
     *  buttons and then the FeaturePlot components below.
     *
     *  @author Kim Rutherford
     *  @version $Id: FeaturePlotGroup.java,v 1.1 2004-06-09 09:46:43 tjc Exp $
     **/
    
    public class FeaturePlotGroup extends JFrame
        implements EntryChangeListener, FeatureChangeListener {
      /**
       *  Create a new FeaturePlotGroup component for the given feature.
       **/
      public FeaturePlotGroup (Feature feature) {
        super ("Graphs for: " + feature.getIDString ());
        this.feature = feature;
        this.entry = feature.getEntry ();
    
        // don't repeat an algorithm in this array.
        final FeatureAlgorithm [] plot_value_producers = {
          new HydrophobicityAlgorithm (getFeature ()),
          new HydrophilicityAlgorithm (getFeature ()),
          new CoilFeatureAlgorithm (getFeature ())
        };
    
        final Font font = Options.getOptions ().getFont ();
    
        setFont (font);
    
        GridBagLayout gridbag = new GridBagLayout();
        getContentPane ().setLayout (gridbag);
    
        GridBagConstraints c = new GridBagConstraints();
    
        c.anchor = GridBagConstraints.NORTH;
        c.gridwidth = GridBagConstraints.REMAINDER;
        c.gridheight = 1;
        c.weightx = 1;
        c.fill = GridBagConstraints.BOTH;
        c.weighty = 1;
    //    c.insets = new Insets (0,0,5,0);
    
        for (int i = 0 ; i < plot_value_producers.length ; ++i) {
          final FeatureAlgorithm this_algorithm = plot_value_producers[i];
    
          final FeaturePlot new_feature_plot = new FeaturePlot (this_algorithm);
    
          gridbag.setConstraints (new_feature_plot, c);
          getContentPane ().add (new_feature_plot);
          new_feature_plot.setVisible (true);
        }
    
        getFeature ().getEntry ().addEntryChangeListener (this);
        getFeature ().addFeatureChangeListener (this);
    
        addWindowListener (new WindowAdapter () {
          public void windowClosing (WindowEvent event) {
            stopListening ();
            FeaturePlotGroup.this.dispose ();
          }
        });
    
        addComponentListener (new ComponentAdapter () {
          public void componentResized (ComponentEvent event) {
            fixScrollbar ();
            fireAdjustmentEvent (scrollbar.getValue ());
          }
        });
    
        int new_x_size = feature.getTranslation ().length () + SCROLL_BAR_SIZE;
    
        if (new_x_size > 1000) {
          new_x_size = 1000;
        }
    
        if (new_x_size < 300) {
          new_x_size = 300;
        }
    
        scrollbar = new JScrollBar (Scrollbar.HORIZONTAL);
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weighty = 0;
        gridbag.setConstraints (scrollbar, c);
        scrollbar.addAdjustmentListener (new AdjustmentListener () {
          public void adjustmentValueChanged(AdjustmentEvent e) {
            fireAdjustmentEvent (e.getValue ());
          }
        });
        getContentPane ().add (scrollbar);
    
        final Component [] children = getContentPane ().getComponents ();
    
        for (int i = 0 ; i < children.length ; ++i) {
          if (children[i] instanceof FeaturePlot) {
            addDisplayAdjustmentListener ((FeaturePlot)children[i]);
          }
        }
    
    
        bottom_button_panel = new JPanel ();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.weighty = 0;
        gridbag.setConstraints (bottom_button_panel, c);
        getContentPane ().add (bottom_button_panel);
    
        close_button = new JButton ("Close");
        close_button.addActionListener (new ActionListener () {
          public void actionPerformed (ActionEvent e) {
            stopListening ();
            FeaturePlotGroup.this.dispose ();
          }
        });
    
        bottom_button_panel.add (close_button);
    
        pack ();
    
        // give each FeaturePlot component a height of 200
        setSize (new_x_size, getSize ().height);
    
        final Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
        setLocation (new Point ((screen.width - getSize ().width) / 2,
                                (screen.height - getSize ().height) / 2));
    
        show ();
    
        fixScrollbar ();
    
        fireAdjustmentEvent (1);
      }
    
      /**
       *  Fudge factor to take the scroll bar width into account when creating
       *  windows and scrollbars.
       **/
      private final int SCROLL_BAR_SIZE = 100;
    
      /**
       *  Remove this object as a entry change listener and then call
       *  stopListening () on each FeaturePlot component.
       **/
      private void stopListening () {
        getEntry ().removeEntryChangeListener (this);
    
        final Component [] children = getComponents ();
    
        for (int i = 0 ; i < children.length ; ++i) {
          if (children[i] instanceof FeaturePlot) {
            ((FeaturePlot)children[i]).stopListening ();
          }
        }
    
        getFeature ().getEntry ().removeEntryChangeListener (this);
        getFeature ().removeFeatureChangeListener (this);
      }
    
      /**
       *  Set the scrollbar maximum, minimum and value.
       **/
      private void fixScrollbar () {
        final int feature_length = getFeature ().getTranslation ().length ();
    
        int scroll_max = feature_length;
    
        if (scroll_max < 1) {
          scroll_max = 1;
        }
    
        scrollbar.setValues (1, getSize ().width,
                             1, scroll_max + SCROLL_BAR_SIZE);
    
        scrollbar.setBlockIncrement (getSize ().width);
      }
    
      /**
       *  Adds the specified event adjustemnt listener to receive adjustment
       *  change events from this object.
       *  @param l the event change listener.
       **/
      private  void addDisplayAdjustmentListener (DisplayAdjustmentListener l) {
        adjustment_listener_list.addElement (l);
      }
    
      /**
       *  Removes the specified event listener so that it no longer receives
       *  adjustment change events from this object.
       *  @param l the event change listener.
       **/
      private  void removeDisplayAdjustmentListener (DisplayAdjustmentListener l) {
        adjustment_listener_list.removeElement (l);
      }
    
      /**
       *  Implementation of the FeatureChangeListener interface.
       *  @param event The change event.
       **/
      public void featureChanged (FeatureChangeEvent event) {
        fixScrollbar ();
        fireAdjustmentEvent (scrollbar.getValue ());
      }
    
      /**
       *  Implementation of the EntryChangeListener interface.  We listen to
       *  EntryChange events so we can delete this component if the feature gets
       *  deleted.
       **/
      public void entryChanged (EntryChangeEvent event) {
        switch (event.getType ()) {
        case EntryChangeEvent.FEATURE_DELETED:
          if (event.getFeature () == getFeature ()) {
            stopListening ();
            dispose ();
          }
          break;
        default:
          // do nothing;
          break;
        }
      }
    
      /**
       *  Send a DisplayAdjustmentEvent to the objects that are listening for it.
       **/
      private void fireAdjustmentEvent (final int scroll_value) {
        final int feature_length = getFeature ().getTranslation ().length ();
    
        int end_value = scroll_value + getSize ().width;
    
        if (end_value > feature_length) {
          end_value = feature_length;
        }
    
        final DisplayAdjustmentEvent event =
          new DisplayAdjustmentEvent (this,
                                      scroll_value,
                                      end_value,
                                      getSize ().width,
                                      1,
                                      0,// this arg will be ignored
                                      false,
                                      DisplayAdjustmentEvent.SCALE_ADJUST_EVENT);
    
        final Vector targets;
    
        // copied from a book - synchronising the whole method might cause a
        // deadlock
        synchronized (this) {
          targets = (Vector) adjustment_listener_list.clone ();
        }
    
        for ( int i = 0 ; i < targets.size () ; ++i ) {
          DisplayAdjustmentListener target =
            (DisplayAdjustmentListener) targets.elementAt (i);
    
          target.displayAdjustmentValueChanged (event);
        }
      }
    
      /**
       *  Return the feature that this component is plotting.
       **/
      private Feature getFeature () {
        return feature;
      }
    
      /**
       *  Return the Entry that contains the Feature this object is displaying.
       **/
      private Entry getEntry () {
        return entry;
      }
    
      /**
       *  The feature we are plotting.
       **/
      private Feature feature;
    
      /**
       *  The Entry that contains the Feature this object is displaying.
       **/
      private Entry entry;
    
      /**
       *  Pressing this button will distroy the JFrame.
       **/
      private JButton close_button;
    
      /**
       *  A JPanel to hold the buttons.
       **/
      private JPanel bottom_button_panel;
    
      private JScrollBar scrollbar;
    
      /**
       *  A vector of those objects listening for adjustment events.
       **/
      final private Vector adjustment_listener_list = new Vector ();
    }