7b2fb36a2d00fc5ad065760ec4de54940c23b82d
[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   public AnnotationRowFilter(AlignViewport av, final AlignmentPanel ap)
115   {
116     this.av = av;
117     this.ap = ap;
118   }
119
120   public AnnotationRowFilter()
121   {
122
123   }
124
125   public Vector<String> getAnnotationItems(boolean isSeqAssociated)
126   {
127     Vector<String> list = new Vector<String>();
128     int index = 1;
129     int[] anmap = new int[av.getAlignment().getAlignmentAnnotation().length];
130     for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
131     {
132       if (av.getAlignment().getAlignmentAnnotation()[i].sequenceRef == null)
133       {
134         if (isSeqAssociated)
135         {
136           continue;
137         }
138       }
139       else
140       {
141         enableSeqAss = true;
142       }
143       String label = av.getAlignment().getAlignmentAnnotation()[i].label;
144       if (!list.contains(label))
145       {
146         anmap[list.size()] = i;
147         list.add(label);
148
149       }
150       else
151       {
152         if (!isSeqAssociated)
153         {
154           anmap[list.size()] = i;
155           list.add(label + "_" + (index++));
156         }
157       }
158     }
159     this.annmap = new int[list.size()];
160     System.arraycopy(anmap, 0, this.annmap, 0, this.annmap.length);
161     return list;
162   }
163
164   protected int getSelectedThresholdItem(int indexValue)
165   {
166     int selectedThresholdItem = -1;
167     if (indexValue == 1)
168     {
169       selectedThresholdItem = AnnotationColourGradient.ABOVE_THRESHOLD;
170     }
171     else if (indexValue == 2)
172     {
173       selectedThresholdItem = AnnotationColourGradient.BELOW_THRESHOLD;
174     }
175     return selectedThresholdItem;
176   }
177
178   public void modelChanged()
179   {
180     seqAssociated.setEnabled(enableSeqAss);
181   }
182
183   public void ok_actionPerformed(ActionEvent e)
184   {
185     try
186     {
187       frame.setClosed(true);
188     } catch (Exception ex)
189     {
190     }
191   }
192
193   public void cancel_actionPerformed(ActionEvent e)
194   {
195     reset();
196     ap.paintAlignment(true);
197     try
198     {
199       frame.setClosed(true);
200     } catch (Exception ex)
201     {
202     }
203   }
204
205   public void thresholdCheck_actionPerformed(ActionEvent e)
206   {
207     updateView();
208   }
209
210   public void annotations_actionPerformed(ActionEvent e)
211   {
212     updateView();
213   }
214
215   public void threshold_actionPerformed(ActionEvent e)
216   {
217     updateView();
218   }
219
220   public void thresholdValue_actionPerformed(ActionEvent e)
221   {
222     try
223     {
224       float f = Float.parseFloat(thresholdValue.getText());
225       slider.setValue((int) (f * 1000));
226       updateView();
227     } catch (NumberFormatException ex)
228     {
229     }
230   }
231
232   public void thresholdIsMin_actionPerformed(ActionEvent actionEvent)
233   {
234     updateView();
235   }
236
237   protected void populateThresholdComboBox(JComboBox<String> threshold)
238   {
239     threshold.addItem(MessageManager
240             .getString("label.threshold_feature_no_thereshold"));
241     threshold.addItem(MessageManager
242             .getString("label.threshold_feature_above_thereshold"));
243     threshold.addItem(MessageManager
244             .getString("label.threshold_feature_below_thereshold"));
245   }
246
247   protected void seqAssociated_actionPerformed(ActionEvent arg0,
248           JComboBox<String> annotations, JCheckBox seqAssociated)
249   {
250     adjusting = true;
251     String cursel = (String) annotations.getSelectedItem();
252     boolean isvalid = false, isseqs = seqAssociated.isSelected();
253     annotations.removeAllItems();
254     for (String anitem : getAnnotationItems(seqAssociated.isSelected()))
255     {
256       if (anitem.equals(cursel) || (isseqs && cursel.startsWith(anitem)))
257       {
258         isvalid = true;
259         cursel = anitem;
260       }
261       annotations.addItem(anitem);
262     }
263     adjusting = false;
264     if (isvalid)
265     {
266       annotations.setSelectedItem(cursel);
267     }
268     else
269     {
270       if (annotations.getItemCount() > 0)
271       {
272         annotations.setSelectedIndex(0);
273       }
274     }
275   }
276
277   protected void propagateSeqAssociatedThreshold(boolean allAnnotation,
278           AlignmentAnnotation annotation)
279   {
280     if (annotation.sequenceRef == null || annotation.threshold == null)
281     {
282       return;
283     }
284
285     float thr = annotation.threshold.value;
286     for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
287     {
288       AlignmentAnnotation aa = av.getAlignment().getAlignmentAnnotation()[i];
289       if (aa.label.equals(annotation.label)
290               && (annotation.getCalcId() == null ? aa.getCalcId() == null
291                       : annotation.getCalcId().equals(aa.getCalcId())))
292       {
293         if (aa.threshold == null)
294         {
295           aa.threshold = new GraphLine(annotation.threshold);
296         }
297         else
298         {
299           aa.threshold.value = thr;
300         }
301       }
302     }
303   }
304
305   protected boolean colorAlignmContaining(
306           AlignmentAnnotation currentAnnotation, int selectedThresholdItem)
307   {
308
309     AnnotationColourGradient acg = null;
310     if (currentColours.isSelected())
311     {
312       acg = new AnnotationColourGradient(currentAnnotation,
313               av.getGlobalColourScheme(), selectedThresholdItem);
314     }
315     else
316     {
317       acg = new AnnotationColourGradient(currentAnnotation,
318               minColour.getBackground(), maxColour.getBackground(),
319               selectedThresholdItem);
320     }
321     acg.setSeqAssociated(seqAssociated.isSelected());
322
323     if (currentAnnotation.graphMin == 0f
324             && currentAnnotation.graphMax == 0f)
325     {
326       acg.setPredefinedColours(true);
327     }
328
329     acg.thresholdIsMinMax = thresholdIsMin.isSelected();
330
331     av.setGlobalColourScheme(acg);
332
333     if (av.getAlignment().getGroups() != null)
334     {
335
336       for (SequenceGroup sg : ap.av.getAlignment().getGroups())
337       {
338         if (sg.cs == null)
339         {
340           continue;
341         }
342
343         if (currentColours.isSelected())
344         {
345           sg.cs = new AnnotationColourGradient(currentAnnotation, sg.cs,
346                   selectedThresholdItem);
347           ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
348                   .isSelected());
349
350         }
351         else
352         {
353           sg.cs = new AnnotationColourGradient(currentAnnotation,
354                   minColour.getBackground(), maxColour.getBackground(),
355                   selectedThresholdItem);
356           ((AnnotationColourGradient) sg.cs).setSeqAssociated(seqAssociated
357                   .isSelected());
358         }
359
360       }
361     }
362     return false;
363   }
364
365   public jalview.datamodel.AlignmentAnnotation getCurrentAnnotation()
366   {
367     return currentAnnotation;
368   }
369
370   public void setCurrentAnnotation(
371           jalview.datamodel.AlignmentAnnotation currentAnnotation)
372   {
373     this.currentAnnotation = currentAnnotation;
374   }
375
376   public abstract void valueChanged(boolean updateAllAnnotation);
377
378   public abstract void updateView();
379
380   public abstract void reset();
381 }