JAL-1871 JAL-1553 don’t modify selection/view colour scheme again after OK is pressed.
[jalview.git] / src / jalview / gui / AnnotationRowFilter.java
1 package jalview.gui;
2
3 import jalview.datamodel.AlignmentAnnotation;
4 import jalview.datamodel.GraphLine;
5 import jalview.datamodel.SequenceGroup;
6 import jalview.schemes.AnnotationColourGradient;
7 import jalview.util.MessageManager;
8
9 import java.awt.event.ActionEvent;
10 import java.awt.event.MouseAdapter;
11 import java.awt.event.MouseEvent;
12 import java.util.Vector;
13
14 import javax.swing.JButton;
15 import javax.swing.JCheckBox;
16 import javax.swing.JComboBox;
17 import javax.swing.JInternalFrame;
18 import javax.swing.JPanel;
19 import javax.swing.JSlider;
20 import javax.swing.JTextField;
21 import javax.swing.event.ChangeEvent;
22 import javax.swing.event.ChangeListener;
23
24 @SuppressWarnings("serial")
25 public abstract class AnnotationRowFilter extends JPanel
26 {
27   protected AlignViewport av;
28
29   protected AlignmentPanel ap;
30
31   protected int[] annmap;
32
33   protected boolean enableSeqAss = false;
34
35   private jalview.datamodel.AlignmentAnnotation currentAnnotation;
36
37   protected boolean adjusting = false;
38
39   protected JCheckBox currentColours = new JCheckBox();
40
41   protected JPanel minColour = new JPanel();
42
43   protected JPanel maxColour = new JPanel();
44
45   protected JCheckBox seqAssociated = new JCheckBox();
46
47   protected JCheckBox thresholdIsMin = new JCheckBox();
48
49   protected JSlider slider = new JSlider();
50
51   protected JTextField thresholdValue = new JTextField(20);
52
53   protected JInternalFrame frame;
54
55   protected JButton ok = new JButton();
56
57   protected JButton cancel = new JButton();
58
59   /**
60    * enabled if the user is dragging the slider - try to keep updates to a
61    * minimun
62    */
63   protected boolean sliderDragging = false;
64
65   protected void addSliderChangeListener()
66   {
67
68     slider.addChangeListener(new ChangeListener()
69     {
70       @Override
71       public void stateChanged(ChangeEvent evt)
72       {
73         if (!adjusting)
74         {
75           thresholdValue.setText((slider.getValue() / 1000f) + "");
76           valueChanged(!sliderDragging);
77         }
78       }
79     });
80   }
81
82   protected void addSliderMouseListeners()
83   {
84
85     slider.addMouseListener(new MouseAdapter()
86     {
87       @Override
88       public void mousePressed(MouseEvent e)
89       {
90         sliderDragging = true;
91         super.mousePressed(e);
92       }
93
94       @Override
95       public void mouseDragged(MouseEvent e)
96       {
97         sliderDragging = true;
98         super.mouseDragged(e);
99       }
100
101       @Override
102       public void mouseReleased(MouseEvent evt)
103       {
104         if (sliderDragging)
105         {
106           sliderDragging = false;
107           valueChanged(true);
108         }
109         ap.paintAlignment(true);
110       }
111     });
112   }
113
114
115   public AnnotationRowFilter(AlignViewport av, final AlignmentPanel ap)
116   {
117     this.av = av;
118     this.ap = ap;
119   }
120
121   public AnnotationRowFilter()
122   {
123
124   }
125
126   public Vector<String> getAnnotationItems(boolean isSeqAssociated)
127   {
128     Vector<String> list = new Vector<String>();
129     int index = 1;
130     int[] anmap = new int[av.getAlignment().getAlignmentAnnotation().length];
131     for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
132     {
133       if (av.getAlignment().getAlignmentAnnotation()[i].sequenceRef == null)
134       {
135         if (isSeqAssociated)
136         {
137           continue;
138         }
139       }
140       else
141       {
142         enableSeqAss = true;
143       }
144       String label = av.getAlignment().getAlignmentAnnotation()[i].label;
145       if (!list.contains(label))
146       {
147         anmap[list.size()] = i;
148         list.add(label);
149
150       }
151       else
152       {
153         if (!isSeqAssociated)
154         {
155           anmap[list.size()] = i;
156           list.add(label + "_" + (index++));
157         }
158       }
159     }
160     this.annmap = new int[list.size()];
161     System.arraycopy(anmap, 0, this.annmap, 0, this.annmap.length);
162     return list;
163   }
164
165   protected int getSelectedThresholdItem(int indexValue)
166   {
167     int selectedThresholdItem = -1;
168     if (indexValue == 1)
169     {
170       selectedThresholdItem = AnnotationColourGradient.ABOVE_THRESHOLD;
171     }
172     else if (indexValue == 2)
173     {
174       selectedThresholdItem = AnnotationColourGradient.BELOW_THRESHOLD;
175     }
176     return selectedThresholdItem;
177   }
178
179   public void modelChanged()
180   {
181     seqAssociated.setEnabled(enableSeqAss);
182   }
183
184   public void ok_actionPerformed(ActionEvent e)
185   {
186     try
187     {
188       frame.setClosed(true);
189     } catch (Exception ex)
190     {
191     }
192   }
193
194   public void cancel_actionPerformed(ActionEvent e)
195   {
196     reset();
197     ap.paintAlignment(true);
198     try
199     {
200       frame.setClosed(true);
201     } catch (Exception ex)
202     {
203     }
204   }
205
206   public void thresholdCheck_actionPerformed(ActionEvent e)
207   {
208     updateView();
209   }
210
211   public void annotations_actionPerformed(ActionEvent e)
212   {
213     updateView();
214   }
215
216   public void threshold_actionPerformed(ActionEvent e)
217   {
218     updateView();
219   }
220
221   public void thresholdValue_actionPerformed(ActionEvent e)
222   {
223     try
224     {
225       float f = Float.parseFloat(thresholdValue.getText());
226       slider.setValue((int) (f * 1000));
227       updateView();
228     } catch (NumberFormatException ex)
229     {
230     }
231   }
232
233   public void thresholdIsMin_actionPerformed(ActionEvent actionEvent)
234   {
235     updateView();
236   }
237
238   protected void populateThresholdComboBox(JComboBox<String> threshold)
239   {
240     threshold.addItem(MessageManager
241             .getString("label.threshold_feature_no_thereshold"));
242     threshold.addItem(MessageManager
243             .getString("label.threshold_feature_above_thereshold"));
244     threshold.addItem(MessageManager
245             .getString("label.threshold_feature_below_thereshold"));
246   }
247
248   protected void seqAssociated_actionPerformed(ActionEvent arg0,
249           JComboBox<String> annotations, JCheckBox seqAssociated)
250   {
251     adjusting = true;
252     String cursel = (String) annotations.getSelectedItem();
253     boolean isvalid = false, isseqs = seqAssociated.isSelected();
254     annotations.removeAllItems();
255     for (String anitem : getAnnotationItems(seqAssociated.isSelected()))
256     {
257       if (anitem.equals(cursel) || (isseqs && cursel.startsWith(anitem)))
258       {
259         isvalid = true;
260         cursel = anitem;
261       }
262       annotations.addItem(anitem);
263     }
264     adjusting = false;
265     if (isvalid)
266     {
267       annotations.setSelectedItem(cursel);
268     }
269     else
270     {
271       if (annotations.getItemCount() > 0)
272       {
273         annotations.setSelectedIndex(0);
274       }
275     }
276   }
277
278   protected void propagateSeqAssociatedThreshold(boolean allAnnotation,
279           AlignmentAnnotation annotation)
280   {
281     if (annotation.sequenceRef == null || annotation.threshold == null)
282     {
283       return;
284     }
285
286     float thr = annotation.threshold.value;
287     for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
288     {
289       AlignmentAnnotation aa = av.getAlignment().getAlignmentAnnotation()[i];
290       if (aa.label.equals(annotation.label)
291               && (annotation.getCalcId() == null ? aa.getCalcId() == null
292                       : annotation.getCalcId().equals(aa.getCalcId())))
293       {
294         if (aa.threshold == null)
295         {
296           aa.threshold = new GraphLine(annotation.threshold);
297         }
298         else
299         {
300           aa.threshold.value = thr;
301         }
302       }
303     }
304   }
305
306   protected boolean colorAlignmContaining(
307           AlignmentAnnotation currentAnnotation, int selectedThresholdItem)
308   {
309
310     AnnotationColourGradient acg = null;
311     if (currentColours.isSelected())
312     {
313       acg = new AnnotationColourGradient(currentAnnotation,
314               av.getGlobalColourScheme(), selectedThresholdItem);
315     }
316     else
317     {
318       acg = new AnnotationColourGradient(currentAnnotation,
319               minColour.getBackground(), maxColour.getBackground(),
320               selectedThresholdItem);
321     }
322     acg.setSeqAssociated(seqAssociated.isSelected());
323
324     if (currentAnnotation.graphMin == 0f
325             && currentAnnotation.graphMax == 0f)
326     {
327       acg.setPredefinedColours(true);
328     }
329
330     acg.thresholdIsMinMax = thresholdIsMin.isSelected();
331
332     av.setGlobalColourScheme(acg);
333
334     if (av.getAlignment().getGroups() != null)
335     {
336
337       for (SequenceGroup sg : ap.av.getAlignment().getGroups())
338       {
339         if (sg.cs == null)
340         {
341           continue;
342         }
343
344         if (currentColours.isSelected())
345         {
346           sg.cs = new AnnotationColourGradient(currentAnnotation, sg.cs,
347                   selectedThresholdItem);
348           ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
349                   .isSelected());
350
351         }
352         else
353         {
354           sg.cs = new AnnotationColourGradient(currentAnnotation,
355                   minColour.getBackground(), maxColour.getBackground(),
356                   selectedThresholdItem);
357           ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
358                   .isSelected());
359         }
360
361       }
362     }
363     return false;
364   }
365
366
367   public jalview.datamodel.AlignmentAnnotation getCurrentAnnotation()
368   {
369     return currentAnnotation;
370   }
371
372   public void setCurrentAnnotation(
373           jalview.datamodel.AlignmentAnnotation currentAnnotation)
374   {
375     this.currentAnnotation = currentAnnotation;
376   }
377
378   public abstract void valueChanged(boolean updateAllAnnotation);
379
380   public abstract void updateView();
381
382   public abstract void reset();
383 }