JAL-4046 JAL-3993 patch for 2.11.2.4 release
[jalview.git] / src / jalview / gui / SliderPanel.java
index 5a87102..37ab219 100755 (executable)
-package jalview.gui;\r
-\r
-import jalview.jbgui.*;\r
-import jalview.schemes.*;\r
-import jalview.datamodel.*;\r
-import java.awt.event.*;\r
-import javax.swing.event.*;\r
-import javax.swing.*;\r
-import java.util.*;\r
-\r
-public class SliderPanel extends GSliderPanel\r
-{\r
-  AlignmentPanel ap;\r
-  boolean forConservation = true;\r
-  ColourSchemeI cs;\r
-\r
-  static JInternalFrame conservationSlider;\r
-  static JInternalFrame PIDSlider;\r
-\r
-  public static int setConservationSlider(AlignmentPanel ap, ColourSchemeI cs, String source)\r
-  {\r
-    SliderPanel sp = null;\r
-    ConservationColourScheme ccs = (ConservationColourScheme)cs;\r
-\r
-    if(conservationSlider == null)\r
-    {\r
-      sp = new SliderPanel(ap, ccs.inc, true, cs);\r
-      conservationSlider = new JInternalFrame();\r
-      conservationSlider.setContentPane(sp);\r
-      conservationSlider.setLayer(JLayeredPane.PALETTE_LAYER);\r
-    }\r
-    else\r
-    {\r
-        sp = (SliderPanel)conservationSlider.getContentPane();\r
-        sp.cs = cs;\r
-    }\r
-\r
-    conservationSlider.setTitle("Conservation Colour Increment  ("+source+")");\r
-    if(ap.av.alignment.getGroups()!=null)\r
-      sp.setAllGroupsCheckEnabled( true );\r
-    else\r
-      sp.setAllGroupsCheckEnabled( false);\r
-\r
-    return sp.getValue();\r
-  }\r
-\r
-  public static void showConservationSlider()\r
-  {\r
-    try{\r
-      PIDSlider.setClosed(true);\r
-      PIDSlider = null;\r
-    }catch(Exception ex){}\r
-\r
-\r
-    if(!conservationSlider.isVisible())\r
-    {\r
-      Desktop.addInternalFrame(conservationSlider, conservationSlider.getTitle(), 420, 90, false);\r
-      conservationSlider.addInternalFrameListener(new javax.swing.event.\r
-                                                  InternalFrameAdapter()\r
-      {\r
-        public void internalFrameClosed(javax.swing.event.InternalFrameEvent e)\r
-        {\r
-          conservationSlider = null;\r
-        }\r
-      });\r
-      conservationSlider.setLayer(JLayeredPane.PALETTE_LAYER);\r
-    }\r
-\r
-  }\r
-\r
-  public static int setPIDSliderSource(AlignmentPanel ap, ColourSchemeI cs, String source)\r
-   {\r
-     SliderPanel pid = null;\r
-\r
-     int threshold = 50;\r
-     if (cs instanceof ResidueColourScheme)\r
-       threshold = ( ( (ResidueColourScheme) cs).getThreshold());\r
-     else if (cs instanceof ScoreColourScheme)\r
-       threshold = ( ( (ScoreColourScheme) cs).getThreshold());\r
-\r
-\r
-     if(PIDSlider == null)\r
-     {\r
-       pid = new SliderPanel(ap, threshold, false, cs);\r
-       PIDSlider = new JInternalFrame();\r
-       PIDSlider.setContentPane(pid);\r
-       PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);\r
-     }\r
-     else\r
-     {\r
-         pid = (SliderPanel)PIDSlider.getContentPane();\r
-         pid.cs = cs;\r
-     }\r
-     PIDSlider.setTitle("Percentage Identity Threshold ("+source+")");\r
-\r
-     if (ap.av.alignment.getGroups() != null)\r
-       pid.setAllGroupsCheckEnabled(true);\r
-     else\r
-       pid.setAllGroupsCheckEnabled(false);\r
-\r
-     return pid.getValue();\r
-\r
-   }\r
-\r
-   public static void showPIDSlider()\r
-   {\r
-     try{\r
-       conservationSlider.setClosed(true);\r
-       conservationSlider = null;\r
-     }catch(Exception ex){}\r
-\r
-     if(!PIDSlider.isVisible())\r
-    {\r
-      Desktop.addInternalFrame(PIDSlider, PIDSlider.getTitle(), 420, 90, false);\r
-      PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);\r
-      PIDSlider.addInternalFrameListener(new javax.swing.event.\r
-                                                  InternalFrameAdapter()\r
-      {\r
-        public void internalFrameClosed(javax.swing.event.InternalFrameEvent e)\r
-        {\r
-          PIDSlider = null;\r
-        }\r
-      });\r
-      PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);\r
-    }\r
-\r
-   }\r
-\r
-\r
-  public SliderPanel(AlignmentPanel ap, int value, boolean forConserve, ColourSchemeI cs)\r
-  {\r
-    this.ap = ap;\r
-    this.cs = cs;\r
-    forConservation = forConserve;\r
-    undoButton.setVisible(false);\r
-    applyButton.setVisible(false);\r
-    if(forConservation)\r
-    {\r
-      label.setText("Enter value to increase conservation visibility");\r
-      slider.setMinimum(0);\r
-      slider.setMaximum(50);\r
-    }\r
-    else\r
-    {\r
-      label.setText("Enter % identity above which to colour residues");\r
-      slider.setMinimum(0);\r
-      slider.setMaximum(100);\r
-    }\r
-\r
-\r
-\r
-    slider.addChangeListener( new ChangeListener()\r
-    {\r
-      public void stateChanged(ChangeEvent evt)\r
-      {\r
-        valueField.setText( slider.getValue()+"" );\r
-        valueChanged( slider.getValue() );\r
-      }\r
-    });\r
-\r
-    slider.setValue(value);\r
-    valueField.setText(value+"");\r
-  }\r
-\r
-  public void valueChanged(int i)\r
-  {\r
-    if(cs == null)\r
-      return;\r
-\r
-    ColourSchemeI toChange = null;\r
-    Vector allGroups = null;\r
-    int groupIndex = 0;\r
-\r
-    if(allGroupsCheck.isSelected())\r
-    {\r
-      allGroups = ap.av.alignment.getGroups();\r
-      groupIndex = allGroups.size()-1;\r
-    }\r
-    else\r
-      toChange = cs;\r
-\r
-\r
-    while( groupIndex > -1 )\r
-    {\r
-      if(allGroups!=null)\r
-        toChange = ((SequenceGroup)allGroups.get(groupIndex)).cs;\r
-\r
-      if (forConservation)\r
-      {\r
-        if (toChange instanceof ConservationColourScheme)\r
-          ( (ConservationColourScheme) toChange).inc = i;\r
-      }\r
-      else\r
-      {\r
-          ( (ResidueColourScheme) toChange).setThreshold(i);\r
-      }\r
-\r
-      groupIndex--;\r
-    }\r
-\r
-    ap.seqPanel.seqCanvas.repaint();\r
-\r
-  }\r
-\r
-  public void setAllGroupsCheckEnabled(boolean b)\r
-  {\r
-    allGroupsCheck.setEnabled(b);\r
-  }\r
-\r
-\r
-  public void valueField_actionPerformed(ActionEvent e)\r
-  {\r
-    try{\r
-      int i = Integer.parseInt(valueField.getText());\r
-      slider.setValue(i);\r
-    }\r
-    catch(Exception ex)\r
-    {\r
-      valueField.setText( slider.getValue()+"" );\r
-    }\r
-  }\r
-\r
-  public void setValue(int value)\r
-  {\r
-    slider.setValue(value);\r
-  }\r
-  public int getValue()\r
-  {\r
-    return Integer.parseInt(valueField.getText());\r
-  }\r
-\r
-\r
-}\r
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ * 
+ * This file is part of Jalview.
+ * 
+ * Jalview 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 3
+ * of the License, or (at your option) any later version.
+ *  
+ * Jalview 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 Jalview.  If not, see <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.gui;
+
+import jalview.analysis.Conservation;
+import jalview.datamodel.SequenceGroup;
+import jalview.jbgui.GSliderPanel;
+import jalview.renderer.ResidueShaderI;
+import jalview.util.MessageManager;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyVetoException;
+import java.util.List;
+
+import javax.swing.JInternalFrame;
+import javax.swing.JLayeredPane;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
+
+/**
+ * DOCUMENT ME!
+ * 
+ * @author $author$
+ * @version $Revision$
+ */
+public class SliderPanel extends GSliderPanel
+{
+  private static final String BACKGROUND = "Background";
+
+  static JInternalFrame conservationSlider;
+
+  static JInternalFrame PIDSlider;
+
+  AlignmentPanel ap;
+
+  boolean forConservation = true;
+
+  ResidueShaderI cs;
+
+  /**
+   * Returns the currently displayed slider panel (or null if none).
+   * 
+   * @return
+   */
+  public static SliderPanel getSliderPanel()
+  {
+    if (conservationSlider != null && conservationSlider.isVisible())
+    {
+      return (SliderPanel) conservationSlider.getContentPane();
+    }
+    if (PIDSlider != null && PIDSlider.isVisible())
+    {
+      return (SliderPanel) PIDSlider.getContentPane();
+    }
+    return null;
+  }
+
+  /**
+   * Creates a new SliderPanel object.
+   * 
+   * @param ap
+   *          DOCUMENT ME!
+   * @param value
+   *          DOCUMENT ME!
+   * @param forConserve
+   *          DOCUMENT ME!
+   * @param scheme
+   *          DOCUMENT ME!
+   */
+  public SliderPanel(final AlignmentPanel ap, int value,
+          boolean forConserve, ResidueShaderI scheme)
+  {
+    this.ap = ap;
+    this.cs = scheme;
+    forConservation = forConserve;
+    undoButton.setVisible(false);
+    applyButton.setVisible(false);
+
+    if (forConservation)
+    {
+      label.setText(MessageManager.getString(
+              "label.enter_value_increase_conservation_visibility"));
+      slider.setMinimum(0);
+      slider.setMaximum(100);
+    }
+    else
+    {
+      label.setText(MessageManager.getString(
+              "label.enter_percentage_identity_above_which_colour_residues"));
+      slider.setMinimum(0);
+      slider.setMaximum(100);
+    }
+
+    slider.addChangeListener(new ChangeListener()
+    {
+      @Override
+      public void stateChanged(ChangeEvent evt)
+      {
+        valueField.setText(String.valueOf(slider.getValue()));
+        valueChanged(slider.getValue());
+      }
+    });
+
+    slider.addMouseListener(new MouseAdapter()
+    {
+      @Override
+      public void mouseReleased(MouseEvent evt)
+      {
+        ap.paintAlignment(true, true);
+      }
+    });
+
+    slider.setValue(value);
+    valueField.setText(String.valueOf(value));
+  }
+
+  /**
+   * Method to 'set focus' of the Conservation slider panel
+   * 
+   * @param ap
+   *          the panel to repaint on change of slider
+   * @param rs
+   *          the colour scheme to update on change of slider
+   * @param source
+   *          a text description for the panel's title
+   * 
+   * @return
+   */
+  public static int setConservationSlider(AlignmentPanel ap,
+          ResidueShaderI rs, String source)
+  {
+    SliderPanel sliderPanel = null;
+
+    if (conservationSlider == null)
+    {
+      sliderPanel = new SliderPanel(ap, rs.getConservationInc(), true, rs);
+      conservationSlider = new JInternalFrame();
+      conservationSlider.setContentPane(sliderPanel);
+      conservationSlider.setLayer(JLayeredPane.PALETTE_LAYER);
+    }
+    else
+    {
+      sliderPanel = (SliderPanel) conservationSlider.getContentPane();
+      sliderPanel.valueField
+              .setText(String.valueOf(rs.getConservationInc()));
+      sliderPanel.cs = rs;
+      sliderPanel.ap = ap;
+      sliderPanel.slider.setValue(rs.getConservationInc());
+    }
+
+    conservationSlider.setTitle(MessageManager.formatMessage(
+            "label.conservation_colour_increment", new String[]
+            { source == null ? BACKGROUND : source }));
+
+    List<SequenceGroup> groups = ap.av.getAlignment().getGroups();
+    if (groups != null && !groups.isEmpty())
+    {
+      sliderPanel.setAllGroupsCheckEnabled(true);
+      sliderPanel.allGroupsCheck
+              .setSelected(ap.av.getColourAppliesToAllGroups());
+    }
+    else
+    {
+      sliderPanel.setAllGroupsCheckEnabled(false);
+    }
+
+    return sliderPanel.getValue();
+  }
+
+  /**
+   * Hides the PID slider panel if it is shown
+   */
+  public static void hidePIDSlider()
+  {
+    if (PIDSlider != null)
+    {
+      try
+      {
+        PIDSlider.setClosed(true);
+        PIDSlider = null;
+      } catch (PropertyVetoException ex)
+      {
+      }
+    }
+  }
+
+  /**
+   * Hides the conservation slider panel if it is shown
+   */
+  public static void hideConservationSlider()
+  {
+    if (conservationSlider != null)
+    {
+      try
+      {
+        conservationSlider.setClosed(true);
+        conservationSlider = null;
+      } catch (PropertyVetoException ex)
+      {
+      }
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   */
+  public static void showConservationSlider()
+  {
+    hidePIDSlider();
+
+    if (!conservationSlider.isVisible())
+    {
+      Desktop.addInternalFrame(conservationSlider,
+              conservationSlider.getTitle(), true, FRAME_WIDTH,
+              FRAME_HEIGHT, false, true);
+      conservationSlider.addInternalFrameListener(new InternalFrameAdapter()
+      {
+        @Override
+        public void internalFrameClosed(InternalFrameEvent e)
+        {
+          conservationSlider = null;
+        }
+      });
+      conservationSlider.setLayer(JLayeredPane.PALETTE_LAYER);
+    }
+  }
+
+  /**
+   * Method to 'set focus' of the PID slider panel
+   * 
+   * @param ap
+   *          the panel to repaint on change of slider
+   * @param rs
+   *          the colour scheme to update on change of slider
+   * @param source
+   *          a text description for the panel's title
+   * 
+   * @return
+   */
+  public static int setPIDSliderSource(AlignmentPanel ap, ResidueShaderI rs,
+          String source)
+  {
+    int threshold = rs.getThreshold();
+
+    SliderPanel sliderPanel = null;
+
+    if (PIDSlider == null)
+    {
+      sliderPanel = new SliderPanel(ap, threshold, false, rs);
+      PIDSlider = new JInternalFrame();
+      PIDSlider.setContentPane(sliderPanel);
+      PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);
+    }
+    else
+    {
+      sliderPanel = (SliderPanel) PIDSlider.getContentPane();
+      sliderPanel.cs = rs;
+      sliderPanel.ap = ap;
+      sliderPanel.valueField.setText(String.valueOf(rs.getThreshold()));
+      sliderPanel.slider.setValue(rs.getThreshold());
+    }
+
+    PIDSlider.setTitle(MessageManager.formatMessage(
+            "label.percentage_identity_threshold", new String[]
+            { source == null ? BACKGROUND : source }));
+
+    if (ap.av.getAlignment().getGroups() != null)
+    {
+      sliderPanel.setAllGroupsCheckEnabled(true);
+    }
+    else
+    {
+      sliderPanel.setAllGroupsCheckEnabled(false);
+    }
+
+    return sliderPanel.getValue();
+  }
+
+  /**
+   * DOCUMENT ME!
+   * 
+   * @return
+   */
+  public static JInternalFrame showPIDSlider()
+  {
+    hideConservationSlider();
+
+    if (!PIDSlider.isVisible())
+    {
+      Desktop.addInternalFrame(PIDSlider, PIDSlider.getTitle(), true,
+              FRAME_WIDTH, FRAME_HEIGHT, false, true);
+      PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);
+      PIDSlider.addInternalFrameListener(new InternalFrameAdapter()
+      {
+        @Override
+        public void internalFrameClosed(InternalFrameEvent e)
+        {
+          PIDSlider = null;
+        }
+      });
+      PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);
+    }
+    return PIDSlider;
+  }
+
+  /**
+   * Updates the colour scheme with the current (identity threshold or
+   * conservation) percentage value. Also updates all groups if 'apply to all
+   * groups' is selected.
+   * 
+   * @param percent
+   */
+  public void valueChanged(int percent)
+  {
+    if (!forConservation)
+    {
+      ap.av.setThreshold(percent);
+    }
+    updateColourScheme(percent, cs, null);
+
+    if (allGroupsCheck.isSelected())
+    {
+      List<SequenceGroup> groups = ap.av.getAlignment().getGroups();
+      for (SequenceGroup sg : groups)
+      {
+        updateColourScheme(percent, sg.getGroupColourScheme(), sg);
+      }
+    }
+
+    ap.getSeqPanel().seqCanvas.repaint();
+  }
+
+  /**
+   * Updates the colour scheme (if not null) with the current (identity
+   * threshold or conservation) percentage value
+   * 
+   * @param percent
+   * @param scheme
+   * @param sg
+   */
+  protected void updateColourScheme(int percent, ResidueShaderI scheme,
+          SequenceGroup sg)
+  {
+    if (scheme == null)
+    {
+      return;
+    }
+    if (forConservation)
+    {
+      if (!scheme.conservationApplied() && sg != null)
+      {
+        /*
+         * first time the colour scheme has had Conservation shading applied
+         * - compute conservation
+         */
+        Conservation c = new Conservation("Group", sg.getSequences(null),
+                sg.getStartRes(), sg.getEndRes());
+        c.calculate();
+        c.verdict(false, ap.av.getConsPercGaps());
+        sg.cs.setConservation(c);
+
+      }
+      scheme.setConservationApplied(true);
+      scheme.setConservationInc(percent);
+    }
+    else
+    {
+      scheme.setThreshold(percent, ap.av.isIgnoreGapsConsensus());
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   * 
+   * @param b
+   *          DOCUMENT ME!
+   */
+  public void setAllGroupsCheckEnabled(boolean b)
+  {
+    allGroupsCheck.setEnabled(b);
+  }
+
+  /**
+   * DOCUMENT ME!
+   * 
+   * @param e
+   *          DOCUMENT ME!
+   */
+  @Override
+  public void valueField_actionPerformed()
+  {
+    try
+    {
+      int i = Integer.parseInt(valueField.getText());
+      slider.setValue(i);
+    } catch (NumberFormatException ex)
+    {
+      valueField.setText(slider.getValue() + "");
+    }
+  }
+
+  /**
+   * DOCUMENT ME!
+   * 
+   * @param value
+   *          DOCUMENT ME!
+   */
+  public void setValue(int value)
+  {
+    slider.setValue(value);
+  }
+
+  /**
+   * DOCUMENT ME!
+   * 
+   * @return DOCUMENT ME!
+   */
+  public int getValue()
+  {
+    return Integer.parseInt(valueField.getText());
+  }
+
+  @Override
+  public void slider_mouseReleased(MouseEvent e)
+  {
+    if (ap.overviewPanel != null)
+    {
+      ap.overviewPanel.updateOverviewImage();
+    }
+  }
+
+  public static int getConservationValue()
+  {
+    return getValue(conservationSlider);
+  }
+
+  static int getValue(JInternalFrame slider)
+  {
+    return slider == null ? 0
+            : ((SliderPanel) slider.getContentPane()).getValue();
+  }
+
+  public static int getPIDValue()
+  {
+    return getValue(PIDSlider);
+  }
+
+  /**
+   * Answers true if the SliderPanel is for Conservation, false if it is for PID
+   * threshold
+   * 
+   * @return
+   */
+  public boolean isForConservation()
+  {
+    return forConservation;
+  }
+
+  /**
+   * Answers the title for the slider panel; this may include 'Background' if
+   * for the alignment, or the group id if for a group
+   * 
+   * @return
+   */
+  public String getTitle()
+  {
+    String title = null;
+    if (isForConservation())
+    {
+      if (conservationSlider != null)
+      {
+        title = conservationSlider.getTitle();
+      }
+    }
+    else if (PIDSlider != null)
+    {
+      title = PIDSlider.getTitle();
+    }
+    return title;
+  }
+}