JAL-2416 tooltip with descriptions for score models drop-down list
authorgmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 27 Mar 2017 11:40:35 +0000 (12:40 +0100)
committergmungoc <g.m.carstairs@dundee.ac.uk>
Mon, 27 Mar 2017 11:40:35 +0000 (12:40 +0100)
src/jalview/gui/CalculationChooser.java
src/jalview/gui/ComboBoxTooltipRenderer.java [new file with mode: 0644]

index faaf86b..d3b7cfc 100644 (file)
@@ -28,13 +28,18 @@ import jalview.api.analysis.SimilarityParamsI;
 import jalview.util.MessageManager;
 
 import java.awt.Color;
+import java.awt.Component;
 import java.awt.FlowLayout;
 import java.awt.Font;
 import java.awt.GridLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
 import java.beans.PropertyVetoException;
+import java.util.ArrayList;
+import java.util.List;
 
 import javax.swing.ButtonGroup;
 import javax.swing.JButton;
@@ -153,18 +158,9 @@ public class CalculationChooser extends JPanel
     treeChoicePanel.add(averageDistance);
 
     /*
-     * score model drop-down
+     * score models drop-down - with added tooltips!
      */
-    modelNames = new JComboBox<String>();
-    ScoreModels scoreModels = ScoreModels.getInstance();
-    for (ScoreModelI sm : scoreModels.getModels())
-    {
-      boolean nucleotide = af.getViewport().getAlignment().isNucleotide();
-      if (sm.isDNA() && nucleotide || sm.isProtein() && !nucleotide)
-      {
-        modelNames.addItem(sm.getName());
-      }
-    }
+    modelNames = buildModelOptionsList();
 
     JPanel scoreModelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
     scoreModelPanel.setOpaque(false);
@@ -233,6 +229,77 @@ public class CalculationChooser extends JPanel
   }
 
   /**
+   * A rather elaborate helper method (blame Swing, not me) that builds a
+   * drop-down list of score models (by name) with descriptions as tooltips.
+   * There is also a tooltip shown for the currently selected item when hovering
+   * over it (without opening the list).
+   */
+  protected JComboBox<String> buildModelOptionsList()
+  {
+    final JComboBox<String> comboBox = new JComboBox<String>();
+    ComboBoxTooltipRenderer renderer = new ComboBoxTooltipRenderer();
+    comboBox.setRenderer(renderer);
+    final List<String> tips = new ArrayList<String>();
+
+    /*
+     * show tooltip on mouse over the combobox
+     * note the listener has to be on the components that make up
+     * the combobox, doesn't work if just on the combobox
+     */
+    MouseAdapter mouseListener = new MouseAdapter()
+    {
+      @Override
+      public void mouseEntered(MouseEvent e)
+      {
+        comboBox.setToolTipText(tips.get(comboBox.getSelectedIndex()));
+      }
+
+      @Override
+      public void mouseExited(MouseEvent e)
+      {
+        comboBox.setToolTipText(null);
+      }
+    };
+    for (Component c : comboBox.getComponents())
+    {
+      c.addMouseListener(mouseListener);
+    }
+
+    /*
+     * now we can actually add entries to the combobox,
+     * remembering their descriptions for tooltips
+     */
+    ScoreModels scoreModels = ScoreModels.getInstance();
+    for (ScoreModelI sm : scoreModels.getModels())
+    {
+      boolean nucleotide = af.getViewport().getAlignment().isNucleotide();
+      if (sm.isDNA() && nucleotide || sm.isProtein() && !nucleotide)
+      {
+        comboBox.addItem(sm.getName());
+
+        /*
+         * tooltip is description if provided, else text lookup with
+         * fallback on the model name
+         */
+        String tooltip = sm.getDescription();
+        if (tooltip == null)
+        {
+          tooltip = MessageManager.getStringOrReturn("label.score_model_",
+                  sm.getName());
+        }
+        tips.add(tooltip);
+      }
+
+      /*
+       * set the list of tooltips on the combobox's renderer
+       */
+      renderer.setTooltips(tips);
+    }
+
+    return comboBox;
+  }
+
+  /**
    * Open and calculate the selected tree on 'OK'
    */
   protected void ok_actionPerformed()
diff --git a/src/jalview/gui/ComboBoxTooltipRenderer.java b/src/jalview/gui/ComboBoxTooltipRenderer.java
new file mode 100644 (file)
index 0000000..b776757
--- /dev/null
@@ -0,0 +1,42 @@
+package jalview.gui;
+
+import java.awt.Component;
+import java.util.List;
+
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.JComponent;
+import javax.swing.JList;
+
+/**
+ * A helper class to render a combobox with tooltips
+ * 
+ * @see http
+ *      ://stackoverflow.com/questions/480261/java-swing-mouseover-text-on-jcombobox
+ *      -items
+ */
+public class ComboBoxTooltipRenderer extends DefaultListCellRenderer
+{
+  private static final long serialVersionUID = 1L;
+
+  List<String> tooltips;
+
+  @Override
+  public Component getListCellRendererComponent(JList list, Object value,
+          int index, boolean isSelected, boolean cellHasFocus)
+  {
+
+    JComponent comp = (JComponent) super.getListCellRendererComponent(list,
+            value, index, isSelected, cellHasFocus);
+
+    if (-1 < index && null != value && null != tooltips)
+    {
+      list.setToolTipText(tooltips.get(index));
+    }
+    return comp;
+  }
+
+  public void setTooltips(List<String> tips)
+  {
+    this.tooltips = tips;
+  }
+}