merge
[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     updateView();
187     try
188     {
189       frame.setClosed(true);
190     } catch (Exception ex)
191     {
192     }
193   }
194
195   public void cancel_actionPerformed(ActionEvent e)
196   {
197     reset();
198     ap.paintAlignment(true);
199     try
200     {
201       frame.setClosed(true);
202     } catch (Exception ex)
203     {
204     }
205   }
206
207   public void thresholdCheck_actionPerformed(ActionEvent e)
208   {
209     updateView();
210   }
211
212   public void annotations_actionPerformed(ActionEvent e)
213   {
214     updateView();
215   }
216
217   public void threshold_actionPerformed(ActionEvent e)
218   {
219     updateView();
220   }
221
222   public void thresholdValue_actionPerformed(ActionEvent e)
223   {
224     try
225     {
226       float f = Float.parseFloat(thresholdValue.getText());
227       slider.setValue((int) (f * 1000));
228       updateView();
229     } catch (NumberFormatException ex)
230     {
231     }
232   }
233
234   public void thresholdIsMin_actionPerformed(ActionEvent actionEvent)
235   {
236     updateView();
237   }
238
239   protected void populateThresholdComboBox(JComboBox<String> threshold)
240   {
241     threshold.addItem(MessageManager
242             .getString("label.threshold_feature_no_thereshold"));
243     threshold.addItem(MessageManager
244             .getString("label.threshold_feature_above_thereshold"));
245     threshold.addItem(MessageManager
246             .getString("label.threshold_feature_below_thereshold"));
247   }
248
249   protected void seqAssociated_actionPerformed(ActionEvent arg0,
250           JComboBox<String> annotations, JCheckBox seqAssociated)
251   {
252     adjusting = true;
253     String cursel = (String) annotations.getSelectedItem();
254     boolean isvalid = false, isseqs = seqAssociated.isSelected();
255     annotations.removeAllItems();
256     for (String anitem : getAnnotationItems(seqAssociated.isSelected()))
257     {
258       if (anitem.equals(cursel) || (isseqs && cursel.startsWith(anitem)))
259       {
260         isvalid = true;
261         cursel = anitem;
262       }
263       annotations.addItem(anitem);
264     }
265     adjusting = false;
266     if (isvalid)
267     {
268       annotations.setSelectedItem(cursel);
269     }
270     else
271     {
272       if (annotations.getItemCount() > 0)
273       {
274         annotations.setSelectedIndex(0);
275       }
276     }
277   }
278
279   protected void propagateSeqAssociatedThreshold(boolean allAnnotation,
280           AlignmentAnnotation annotation)
281   {
282     if (annotation.sequenceRef == null || annotation.threshold == null)
283     {
284       return;
285     }
286
287     float thr = annotation.threshold.value;
288     for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
289     {
290       AlignmentAnnotation aa = av.getAlignment().getAlignmentAnnotation()[i];
291       if (aa.label.equals(annotation.label)
292               && (annotation.getCalcId() == null ? aa.getCalcId() == null
293                       : annotation.getCalcId().equals(aa.getCalcId())))
294       {
295         if (aa.threshold == null)
296         {
297           aa.threshold = new GraphLine(annotation.threshold);
298         }
299         else
300         {
301           aa.threshold.value = thr;
302         }
303       }
304     }
305   }
306
307   protected boolean colorAlignmContaining(
308           AlignmentAnnotation currentAnnotation, int selectedThresholdItem)
309   {
310
311     AnnotationColourGradient acg = null;
312     if (currentColours.isSelected())
313     {
314       acg = new AnnotationColourGradient(currentAnnotation,
315               av.getGlobalColourScheme(), selectedThresholdItem);
316     }
317     else
318     {
319       acg = new AnnotationColourGradient(currentAnnotation,
320               minColour.getBackground(), maxColour.getBackground(),
321               selectedThresholdItem);
322     }
323     acg.setSeqAssociated(seqAssociated.isSelected());
324
325     if (currentAnnotation.graphMin == 0f
326             && currentAnnotation.graphMax == 0f)
327     {
328       acg.setPredefinedColours(true);
329     }
330
331     acg.thresholdIsMinMax = thresholdIsMin.isSelected();
332
333     av.setGlobalColourScheme(acg);
334
335     if (av.getAlignment().getGroups() != null)
336     {
337
338       for (SequenceGroup sg : ap.av.getAlignment().getGroups())
339       {
340         if (sg.cs == null)
341         {
342           continue;
343         }
344
345         if (currentColours.isSelected())
346         {
347           sg.cs = new AnnotationColourGradient(currentAnnotation, sg.cs,
348                   selectedThresholdItem);
349           ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
350                   .isSelected());
351
352         }
353         else
354         {
355           sg.cs = new AnnotationColourGradient(currentAnnotation,
356                   minColour.getBackground(), maxColour.getBackground(),
357                   selectedThresholdItem);
358           ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
359                   .isSelected());
360         }
361
362       }
363     }
364     return false;
365   }
366
367
368   public jalview.datamodel.AlignmentAnnotation getCurrentAnnotation()
369   {
370     return currentAnnotation;
371   }
372
373   public void setCurrentAnnotation(
374           jalview.datamodel.AlignmentAnnotation currentAnnotation)
375   {
376     this.currentAnnotation = currentAnnotation;
377   }
378
379   public abstract void valueChanged(boolean updateAllAnnotation);
380
381   public abstract void updateView();
382
383   public abstract void reset();
384 }