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 getAnnotationItems(boolean isSeqAssociated) { Vector list = new Vector(); 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; } }