--- /dev/null
+package jalview.gui;
+
+import jalview.bin.Cache;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.GraphLine;
+import jalview.schemes.AnnotationColourGradient;
+import jalview.schemes.ColourSchemeI;
+import jalview.util.MessageManager;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JInternalFrame;
+import javax.swing.JLayeredPane;
+import javax.swing.JPanel;
+import javax.swing.JSlider;
+import javax.swing.JTextField;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+import net.miginfocom.swing.MigLayout;
+
+public class AnnotationColumnSelection extends JPanel
+{
+ JInternalFrame frame;
+
+ AlignViewport av;
+
+ AlignmentPanel ap;
+
+ ColourSchemeI oldcs;
+
+ Hashtable oldgroupColours;
+
+ private JComboBox annotations;
+
+ int[] annmap;
+
+ JPanel minColour = new JPanel();
+
+ JPanel maxColour = new JPanel();
+
+ JButton defColours = new JButton();
+
+ JButton ok = new JButton();
+
+ JButton cancel = new JButton();
+
+ JPanel jPanel1 = new JPanel();
+
+ JPanel jPanel2 = new JPanel();
+
+ BorderLayout borderLayout1 = new BorderLayout();
+
+ private JComboBox threshold = new JComboBox();
+
+ JSlider slider = new JSlider();
+
+ JTextField thresholdValue = new JTextField(20);
+
+ JCheckBox currentColours = new JCheckBox();
+
+ JCheckBox thresholdIsMin = new JCheckBox();
+
+ JCheckBox seqAssociated = new JCheckBox();
+
+ private jalview.datamodel.AlignmentAnnotation currentAnnotation;
+
+ boolean adjusting = false;
+
+ /**
+ * enabled if the user is dragging the slider - try to keep updates to a
+ * minimun
+ */
+ boolean sliderDragging = false;
+
+ public AnnotationColumnSelection(AlignViewport av, final AlignmentPanel ap)
+ {
+
+ this.av = av;
+ this.ap = ap;
+ frame = new JInternalFrame();
+ frame.setContentPane(this);
+ frame.setLayer(JLayeredPane.PALETTE_LAYER);
+ Desktop.addInternalFrame(frame, "Select By Annotation", 520, 215);
+
+ slider.addChangeListener(new ChangeListener()
+ {
+ @Override
+ public void stateChanged(ChangeEvent evt)
+ {
+ if (!adjusting)
+ {
+ thresholdValue.setText((slider.getValue() / 1000f) + "");
+ valueChanged(!sliderDragging);
+ }
+ }
+ });
+ slider.addMouseListener(new MouseAdapter()
+ {
+ @Override
+ public void mousePressed(MouseEvent e)
+ {
+ sliderDragging = true;
+ super.mousePressed(e);
+ }
+
+ @Override
+ public void mouseDragged(MouseEvent e)
+ {
+ sliderDragging = true;
+ super.mouseDragged(e);
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent evt)
+ {
+ if (sliderDragging)
+ {
+ sliderDragging = false;
+ valueChanged(true);
+ }
+ ap.paintAlignment(true);
+ }
+ });
+
+ if (av.getAlignment().getAlignmentAnnotation() == null)
+ {
+ return;
+ }
+
+ // Always get default shading from preferences.
+ setDefaultMinMax();
+
+ adjusting = true;
+
+ setAnnotations(new JComboBox(
+ getAnnotationItems(seqAssociated.isSelected())));
+
+ threshold.addItem(MessageManager
+ .getString("label.threshold_feature_no_thereshold"));
+ threshold.addItem(MessageManager
+ .getString("label.threshold_feature_above_thereshold"));
+ threshold.addItem(MessageManager
+ .getString("label.threshold_feature_below_thereshold"));
+
+ if (av.getCurrentAnnotationColumnSelectionState() != null)
+ {
+ annotations.setSelectedIndex(av
+ .getCurrentAnnotationColumnSelectionState().getAnnotations()
+ .getSelectedIndex());
+ threshold.setSelectedIndex(av
+ .getCurrentAnnotationColumnSelectionState().getThreshold()
+ .getSelectedIndex());
+ System.out.println("selected annotation : "
+ + av.getCurrentAnnotationColumnSelectionState()
+ .getAnnotations().getSelectedIndex());
+ System.out.println("selected threshold : "
+ + av.getCurrentAnnotationColumnSelectionState()
+ .getThreshold().getSelectedIndex());
+ }
+
+ try
+ {
+ jbInit();
+ } catch (Exception ex)
+ {
+ }
+
+ adjusting = false;
+
+ changeColumnSelection();
+ frame.invalidate();
+ frame.pack();
+
+ }
+
+ private Vector<String> getAnnotationItems(boolean isSeqAssociated)
+ {
+ Vector<String> list = new Vector<String>();
+ int index = 1;
+ int[] anmap = new int[av.getAlignment().getAlignmentAnnotation().length];
+ boolean enableSeqAss = false;
+ for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
+ {
+ if (av.getAlignment().getAlignmentAnnotation()[i].sequenceRef == null)
+ {
+ if (isSeqAssociated)
+ {
+ continue;
+ }
+ }
+ else
+ {
+ enableSeqAss = true;
+ }
+ String label = av.getAlignment().getAlignmentAnnotation()[i].label;
+ if (!list.contains(label))
+ {
+ anmap[list.size()] = i;
+ list.add(label);
+
+ }
+ else
+ {
+ if (!isSeqAssociated)
+ {
+ anmap[list.size()] = i;
+ list.add(label + "_" + (index++));
+ }
+ }
+ }
+ seqAssociated.setEnabled(enableSeqAss);
+ this.annmap = new int[list.size()];
+ System.arraycopy(anmap, 0, this.annmap, 0, this.annmap.length);
+ return list;
+ }
+
+ private void setDefaultMinMax()
+ {
+ minColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN",
+ Color.orange));
+ maxColour.setBackground(Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX",
+ Color.red));
+ }
+
+ public AnnotationColumnSelection()
+ {
+ try
+ {
+ jbInit();
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ private void jbInit() throws Exception
+ {
+ ok.setOpaque(false);
+ ok.setText(MessageManager.getString("action.ok"));
+ ok.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ ok_actionPerformed(e);
+ }
+ });
+ cancel.setOpaque(false);
+ cancel.setText(MessageManager.getString("action.cancel"));
+ cancel.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ cancel_actionPerformed(e);
+ }
+ });
+
+ getAnnotations().addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ annotations_actionPerformed(e);
+ }
+ });
+ getThreshold().addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ threshold_actionPerformed(e);
+ }
+ });
+ thresholdValue.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ thresholdValue_actionPerformed(e);
+ }
+ });
+ slider.setPaintLabels(false);
+ slider.setPaintTicks(true);
+ slider.setBackground(Color.white);
+ slider.setEnabled(false);
+ slider.setOpaque(false);
+ slider.setPreferredSize(new Dimension(100, 32));
+ thresholdValue.setEnabled(false);
+ thresholdValue.setColumns(7);
+ thresholdIsMin.setBackground(Color.white);
+ thresholdIsMin.setFont(JvSwingUtils.getLabelFont());
+ thresholdIsMin.setText(MessageManager
+ .getString("label.threshold_minmax"));
+ thresholdIsMin.addActionListener(new ActionListener()
+ {
+ @Override
+ public void actionPerformed(ActionEvent actionEvent)
+ {
+ thresholdIsMin_actionPerformed(actionEvent);
+ }
+ });
+ seqAssociated.setBackground(Color.white);
+ seqAssociated.setFont(JvSwingUtils.getLabelFont());
+ seqAssociated.setText(MessageManager
+ .getString("label.per_sequence_only"));
+ seqAssociated.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent arg0)
+ {
+ seqAssociated_actionPerformed(arg0);
+ }
+ });
+
+ this.setLayout(borderLayout1);
+ jPanel2.setLayout(new MigLayout("", "[left][center][right]", "[][][]"));
+ jPanel1.setBackground(Color.white);
+ jPanel2.setBackground(Color.white);
+
+ jPanel1.add(ok);
+ jPanel1.add(cancel);
+ jPanel2.add(getAnnotations(), "grow, wrap");
+ jPanel2.add(seqAssociated, "wrap");
+ jPanel2.add(getThreshold(), "grow, wrap");
+ jPanel2.add(thresholdIsMin, "wrap");
+ jPanel2.add(slider, "grow");
+ jPanel2.add(thresholdValue, "grow");
+ this.add(jPanel1, java.awt.BorderLayout.SOUTH);
+ this.add(jPanel2, java.awt.BorderLayout.CENTER);
+ this.validate();
+ }
+
+ protected void seqAssociated_actionPerformed(ActionEvent arg0)
+ {
+ adjusting = true;
+ String cursel = (String) getAnnotations().getSelectedItem();
+ boolean isvalid = false, isseqs = seqAssociated.isSelected();
+ this.getAnnotations().removeAllItems();
+ for (String anitem : getAnnotationItems(seqAssociated.isSelected()))
+ {
+ if (anitem.equals(cursel) || (isseqs && cursel.startsWith(anitem)))
+ {
+ isvalid = true;
+ cursel = anitem;
+ }
+ this.getAnnotations().addItem(anitem);
+ }
+ adjusting = false;
+ if (isvalid)
+ {
+ this.getAnnotations().setSelectedItem(cursel);
+ }
+ else
+ {
+ if (getAnnotations().getItemCount() > 0)
+ {
+ getAnnotations().setSelectedIndex(0);
+ }
+ }
+ }
+
+
+ void changeColumnSelection()
+ {
+ // Check if combobox is still adjusting
+ if (adjusting)
+ {
+ return;
+ }
+
+ setCurrentAnnotation(av.getAlignment().getAlignmentAnnotation()[annmap[getAnnotations()
+ .getSelectedIndex()]]);
+
+ int aboveThreshold = -1;
+ if (getThreshold().getSelectedIndex() == 1)
+ {
+ aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;
+ }
+ else if (getThreshold().getSelectedIndex() == 2)
+ {
+ aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;
+ }
+
+ slider.setEnabled(true);
+ thresholdValue.setEnabled(true);
+ thresholdIsMin.setEnabled(true);
+
+ if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)
+ {
+ slider.setEnabled(false);
+ thresholdValue.setEnabled(false);
+ thresholdValue.setText("");
+ thresholdIsMin.setEnabled(false);
+ }
+ else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD
+ && getCurrentAnnotation().threshold == null)
+ {
+ getCurrentAnnotation()
+ .setThreshold(new jalview.datamodel.GraphLine(
+ (getCurrentAnnotation().graphMax - getCurrentAnnotation().graphMin) / 2f,
+ "Threshold", Color.black));
+ }
+
+ if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
+ {
+ adjusting = true;
+ float range = getCurrentAnnotation().graphMax * 1000
+ - getCurrentAnnotation().graphMin * 1000;
+
+ slider.setMinimum((int) (getCurrentAnnotation().graphMin * 1000));
+ slider.setMaximum((int) (getCurrentAnnotation().graphMax * 1000));
+ slider.setValue((int) (getCurrentAnnotation().threshold.value * 1000));
+ thresholdValue.setText(getCurrentAnnotation().threshold.value + "");
+ slider.setMajorTickSpacing((int) (range / 10f));
+ slider.setEnabled(true);
+ thresholdValue.setEnabled(true);
+ adjusting = false;
+ }
+
+ markColumnsContaining(getCurrentAnnotation(), aboveThreshold);
+ av.setCurrentAnnotationColumnSelectionState(this);
+ ap.alignmentChanged();
+ // ensure all associated views (overviews, structures, etc) are notified of
+ // updated colours.
+ ap.paintAlignment(true);
+ }
+
+ public boolean markColumnsContaining(
+ AlignmentAnnotation currentAnnotation, int thresholdComparisonType)
+ {
+ try
+ {
+ if (currentAnnotation != null)
+ {
+ Annotation[] annotations = currentAnnotation.annotations;
+ ColumnSelection cs = av.getColumnSelection();
+ cs.clear();
+ if (thresholdComparisonType == AnnotationColourGradient.NO_THRESHOLD)
+ {
+ int count = 0;
+ do
+ {
+ if (annotations[count] != null)
+ {
+ if (currentAnnotation.label.equals("Secondary Structure")
+ && annotations[count].secondaryStructure != ' ')
+ {
+ cs.addElement(count);
+ }
+ else if (currentAnnotation.label
+ .equals("Iron Sulphur Contacts"))
+ {
+ cs.addElement(count);
+ }
+ else if (annotations[count].value != 0.0)
+ {
+ cs.addElement(count);
+ }
+
+ }
+ count++;
+ } while (count < annotations.length);
+ }
+ else
+ {
+ int count = 0;
+ do
+ {
+ if (annotations[count] != null)
+ {
+ if (thresholdComparisonType == AnnotationColourGradient.ABOVE_THRESHOLD)
+ {
+ if (annotations[count].value > currentAnnotation.threshold.value)
+ {
+ cs.addElement(count);
+ }
+ }
+ else if (thresholdComparisonType == AnnotationColourGradient.BELOW_THRESHOLD)
+ {
+ if (annotations[count].value < currentAnnotation.threshold.value)
+ {
+ cs.addElement(count);
+ }
+ }
+
+ }
+ count++;
+ } while (count < annotations.length);
+ }
+ }
+
+ return true;
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ return false;
+ }
+ }
+
+ public void ok_actionPerformed(ActionEvent e)
+ {
+ changeColumnSelection();
+ try
+ {
+ frame.setClosed(true);
+ } catch (Exception ex)
+ {
+ }
+ }
+
+ public void cancel_actionPerformed(ActionEvent e)
+ {
+ reset();
+ // ensure all original colouring is propagated to listeners.
+ ap.paintAlignment(true);
+ try
+ {
+ frame.setClosed(true);
+ } catch (Exception ex)
+ {
+ }
+ }
+
+ void reset()
+ {
+ av.getColumnSelection().clear();
+ }
+
+ public void thresholdCheck_actionPerformed(ActionEvent e)
+ {
+ changeColumnSelection();
+ }
+
+ public void annotations_actionPerformed(ActionEvent e)
+ {
+ changeColumnSelection();
+ }
+
+ public void threshold_actionPerformed(ActionEvent e)
+ {
+ changeColumnSelection();
+ }
+
+ public void thresholdValue_actionPerformed(ActionEvent e)
+ {
+ try
+ {
+ float f = Float.parseFloat(thresholdValue.getText());
+ slider.setValue((int) (f * 1000));
+ changeColumnSelection();
+ } catch (NumberFormatException ex)
+ {
+ }
+ }
+
+ public void valueChanged(boolean updateAllAnnotation)
+ {
+ getCurrentAnnotation().threshold.value = slider.getValue() / 1000f;
+ changeColumnSelection();
+ // propagateSeqAssociatedThreshold(updateAllAnnotation);
+ ap.paintAlignment(false);
+ }
+
+ private void propagateSeqAssociatedThreshold(boolean allAnnotation)
+ {
+ if (getCurrentAnnotation().sequenceRef == null
+ || getCurrentAnnotation().threshold == null)
+ {
+ return;
+ }
+
+
+ float thr = getCurrentAnnotation().threshold.value;
+ for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
+ {
+ AlignmentAnnotation aa = av.getAlignment().getAlignmentAnnotation()[i];
+ if (aa.label.equals(getCurrentAnnotation().label)
+ && (getCurrentAnnotation().getCalcId() == null ? aa
+ .getCalcId() == null : getCurrentAnnotation()
+ .getCalcId()
+ .equals(aa.getCalcId())))
+ {
+ if (aa.threshold == null)
+ {
+ aa.threshold = new GraphLine(getCurrentAnnotation().threshold);
+ }
+ else
+ {
+ aa.threshold.value = thr;
+ }
+ }
+ }
+ }
+
+ public void currentColours_actionPerformed(ActionEvent e)
+ {
+ if (currentColours.isSelected())
+ {
+ reset();
+ }
+
+ maxColour.setEnabled(!currentColours.isSelected());
+ minColour.setEnabled(!currentColours.isSelected());
+
+ changeColumnSelection();
+ }
+
+ public void thresholdIsMin_actionPerformed(ActionEvent actionEvent)
+ {
+ changeColumnSelection();
+ }
+
+ public jalview.datamodel.AlignmentAnnotation getCurrentAnnotation()
+ {
+ return currentAnnotation;
+ }
+
+ public void setCurrentAnnotation(
+ jalview.datamodel.AlignmentAnnotation currentAnnotation)
+ {
+ this.currentAnnotation = currentAnnotation;
+ }
+
+ public JComboBox getThreshold()
+ {
+ return threshold;
+ }
+
+ public void setThreshold(JComboBox threshold)
+ {
+ this.threshold = threshold;
+ }
+
+ public JComboBox getAnnotations()
+ {
+ return annotations;
+ }
+
+ public void setAnnotations(JComboBox annotations)
+ {
+ this.annotations = annotations;
+ }
+
+}