applied copyright 2008
[jalview.git] / src / jalview / gui / AnnotationColourChooser.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
3  * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
4  * 
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18  */
19 package jalview.gui;
20
21 import java.util.*;
22
23 import java.awt.*;
24 import java.awt.event.*;
25 import javax.swing.*;
26 import javax.swing.event.*;
27
28 import jalview.datamodel.*;
29 import jalview.schemes.*;
30 import java.awt.Dimension;
31
32 public class AnnotationColourChooser
33     extends JPanel
34 {
35   JInternalFrame frame;
36   AlignViewport av;
37   AlignmentPanel ap;
38   ColourSchemeI oldcs;
39   Hashtable oldgroupColours;
40   jalview.datamodel.AlignmentAnnotation currentAnnotation;
41   boolean adjusting = false;
42
43   public AnnotationColourChooser(AlignViewport av, final AlignmentPanel ap)
44   {
45     oldcs = av.getGlobalColourScheme();
46     if (av.alignment.getGroups() != null)
47     {
48       oldgroupColours = new Hashtable();
49       Vector allGroups = ap.av.alignment.getGroups();
50       SequenceGroup sg;
51       for (int g = 0; g < allGroups.size(); g++)
52       {
53         sg = (SequenceGroup) allGroups.get(g);
54         if (sg.cs != null)
55         {
56           oldgroupColours.put(sg, sg.cs);
57         }
58       }
59     }
60     this.av = av;
61     this.ap = ap;
62     frame = new JInternalFrame();
63     frame.setContentPane(this);
64     frame.setLayer(JLayeredPane.PALETTE_LAYER);
65     Desktop.addInternalFrame(frame, "Colour by Annotation", 480, 145);
66
67
68     slider.addChangeListener(new ChangeListener()
69     {
70       public void stateChanged(ChangeEvent evt)
71       {
72         if (!adjusting)
73         {
74           thresholdValue.setText( ( (float) slider.getValue() / 1000f) + "");
75           valueChanged();
76         }
77       }
78     });
79     slider.addMouseListener(new MouseAdapter()
80         {
81           public void mouseReleased(MouseEvent evt)
82           {
83             ap.paintAlignment(true);
84           }
85         });
86
87     if (av.alignment.getAlignmentAnnotation() == null)
88     {
89       return;
90     }
91
92     if (oldcs instanceof AnnotationColourGradient)
93     {
94       AnnotationColourGradient acg = (AnnotationColourGradient) oldcs;
95       minColour.setBackground(acg.getMinColour());
96       maxColour.setBackground(acg.getMaxColour());
97     }
98     else
99     {
100       minColour.setBackground(Color.orange);
101       maxColour.setBackground(Color.red);
102     }
103
104     adjusting = true;
105     Vector list = new Vector();
106     int index = 1;
107     for (int i = 0; i < av.alignment.getAlignmentAnnotation().length; i++)
108     {
109       String label = av.alignment.getAlignmentAnnotation()[i].label;
110       if (!list.contains(label))
111         list.addElement(label);
112       else
113         list.addElement(label+"_"+(index++));
114     }
115
116     annotations = new JComboBox(list);
117
118     threshold.addItem("No Threshold");
119     threshold.addItem("Above Threshold");
120     threshold.addItem("Below Threshold");
121
122     try
123     {
124       jbInit();
125     }
126     catch (Exception ex)
127     {}
128
129     adjusting = false;
130
131     changeColour();
132
133   }
134
135   public AnnotationColourChooser()
136   {
137     try
138     {
139       jbInit();
140     }
141     catch (Exception ex)
142     {
143       ex.printStackTrace();
144     }
145   }
146
147   private void jbInit()
148       throws Exception
149   {
150     minColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
151     minColour.setBorder(BorderFactory.createEtchedBorder());
152     minColour.setPreferredSize(new Dimension(40, 20));
153     minColour.setToolTipText("Minimum Colour");
154     minColour.addMouseListener(new MouseAdapter()
155     {
156       public void mousePressed(MouseEvent e)
157       {
158         if (minColour.isEnabled())
159         {
160           minColour_actionPerformed();
161         }
162       }
163     });
164     maxColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
165     maxColour.setBorder(BorderFactory.createEtchedBorder());
166     maxColour.setPreferredSize(new Dimension(40, 20));
167     maxColour.setToolTipText("Maximum Colour");
168     maxColour.addMouseListener(new MouseAdapter()
169     {
170       public void mousePressed(MouseEvent e)
171       {
172         if (maxColour.isEnabled())
173         {
174           maxColour_actionPerformed();
175         }
176       }
177     });
178     ok.setOpaque(false);
179     ok.setText("OK");
180     ok.addActionListener(new ActionListener()
181     {
182       public void actionPerformed(ActionEvent e)
183       {
184         ok_actionPerformed(e);
185       }
186     });
187     cancel.setOpaque(false);
188     cancel.setText("Cancel");
189     cancel.addActionListener(new ActionListener()
190     {
191       public void actionPerformed(ActionEvent e)
192       {
193         cancel_actionPerformed(e);
194       }
195     });
196     this.setLayout(borderLayout1);
197     jPanel2.setLayout(flowLayout1);
198     annotations.addActionListener(new ActionListener()
199     {
200       public void actionPerformed(ActionEvent e)
201       {
202         annotations_actionPerformed(e);
203       }
204     });
205     jPanel1.setBackground(Color.white);
206     jPanel2.setBackground(Color.white);
207     threshold.addActionListener(new ActionListener()
208     {
209       public void actionPerformed(ActionEvent e)
210       {
211         threshold_actionPerformed(e);
212       }
213     });
214     jPanel3.setLayout(flowLayout2);
215     thresholdValue.addActionListener(new ActionListener()
216     {
217       public void actionPerformed(ActionEvent e)
218       {
219         thresholdValue_actionPerformed(e);
220       }
221     });
222     slider.setPaintLabels(false);
223     slider.setPaintTicks(true);
224     slider.setBackground(Color.white);
225     slider.setEnabled(false);
226     slider.setOpaque(false);
227     slider.setPreferredSize(new Dimension(100, 32));
228     thresholdValue.setEnabled(false);
229     thresholdValue.setColumns(7);
230     jPanel3.setBackground(Color.white);
231     currentColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
232     currentColours.setOpaque(false);
233     currentColours.setText("Use Original Colours");
234     currentColours.addActionListener(new ActionListener()
235     {
236       public void actionPerformed(ActionEvent e)
237       {
238         currentColours_actionPerformed(e);
239       }
240     });
241     thresholdIsMin.setBackground(Color.white);
242     thresholdIsMin.setText("Threshold is Min/Max");
243     thresholdIsMin.addActionListener(new ActionListener()
244     {
245       public void actionPerformed(ActionEvent actionEvent)
246       {
247         thresholdIsMin_actionPerformed(actionEvent);
248       }
249     });
250     jPanel1.add(ok);
251     jPanel1.add(cancel);
252     jPanel2.add(annotations);
253     jPanel2.add(currentColours);
254     jPanel2.add(minColour);
255     jPanel2.add(maxColour);
256     this.add(jPanel3, java.awt.BorderLayout.CENTER);
257     jPanel3.add(threshold);
258     jPanel3.add(slider);
259     jPanel3.add(thresholdValue);
260     jPanel3.add(thresholdIsMin);
261     this.add(jPanel1, java.awt.BorderLayout.SOUTH);
262     this.add(jPanel2, java.awt.BorderLayout.NORTH);
263   }
264
265   JComboBox annotations;
266   JPanel minColour = new JPanel();
267   JPanel maxColour = new JPanel();
268   JButton ok = new JButton();
269   JButton cancel = new JButton();
270   JPanel jPanel1 = new JPanel();
271   JPanel jPanel2 = new JPanel();
272   BorderLayout borderLayout1 = new BorderLayout();
273   JComboBox threshold = new JComboBox();
274   FlowLayout flowLayout1 = new FlowLayout();
275   JPanel jPanel3 = new JPanel();
276   FlowLayout flowLayout2 = new FlowLayout();
277   JSlider slider = new JSlider();
278   JTextField thresholdValue = new JTextField(20);
279   JCheckBox currentColours = new JCheckBox();
280   JCheckBox thresholdIsMin = new JCheckBox();
281
282   public void minColour_actionPerformed()
283   {
284     Color col = JColorChooser.showDialog(this,
285                                          "Select Colour for Minimum Value",
286                                          minColour.getBackground());
287     if (col != null)
288     {
289       minColour.setBackground(col);
290     }
291     minColour.repaint();
292     changeColour();
293   }
294
295   public void maxColour_actionPerformed()
296   {
297     Color col = JColorChooser.showDialog(this,
298                                          "Select Colour for Maximum Value",
299                                          maxColour.getBackground());
300     if (col != null)
301     {
302       maxColour.setBackground(col);
303     }
304     maxColour.repaint();
305     changeColour();
306   }
307
308   void changeColour()
309   {
310     // Check if combobox is still adjusting
311     if (adjusting)
312     {
313       return;
314     }
315
316
317     currentAnnotation = av.alignment.getAlignmentAnnotation()[annotations.getSelectedIndex()];
318
319     int aboveThreshold = -1;
320     if (threshold.getSelectedItem().equals("Above Threshold"))
321     {
322       aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;
323     }
324     else if (threshold.getSelectedItem().equals("Below Threshold"))
325     {
326       aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;
327     }
328
329     slider.setEnabled(true);
330     thresholdValue.setEnabled(true);
331
332     if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)
333     {
334       slider.setEnabled(false);
335       thresholdValue.setEnabled(false);
336       thresholdValue.setText("");
337     }
338     else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD &&
339              currentAnnotation.threshold == null)
340     {
341       currentAnnotation.setThreshold(new jalview.datamodel.GraphLine
342                                      ( (currentAnnotation.graphMax -
343                                         currentAnnotation.graphMin) / 2f,
344                                       "Threshold",
345                                       Color.black));
346     }
347
348     if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
349     {
350       adjusting = true;
351       float range = currentAnnotation.graphMax * 1000 -
352           currentAnnotation.graphMin * 1000;
353
354       slider.setMinimum( (int) (currentAnnotation.graphMin * 1000));
355       slider.setMaximum( (int) (currentAnnotation.graphMax * 1000));
356       slider.setValue( (int) (currentAnnotation.threshold.value * 1000));
357       thresholdValue.setText(currentAnnotation.threshold.value + "");
358       slider.setMajorTickSpacing( (int) (range / 10f));
359       slider.setEnabled(true);
360       thresholdValue.setEnabled(true);
361       adjusting = false;
362     }
363
364     AnnotationColourGradient acg = null;
365     if (currentColours.isSelected())
366     {
367       acg = new AnnotationColourGradient(
368           currentAnnotation,
369           av.getGlobalColourScheme(), aboveThreshold);
370     }
371     else
372     {
373       acg =
374           new AnnotationColourGradient(
375               currentAnnotation,
376               minColour.getBackground(),
377               maxColour.getBackground(),
378               aboveThreshold);
379     }
380
381     if(currentAnnotation.graphMin==0f&& currentAnnotation.graphMax==0f)
382     {
383       acg.predefinedColours = true;
384     }
385
386     acg.thresholdIsMinMax = thresholdIsMin.isSelected();
387
388     av.setGlobalColourScheme(acg);
389
390     if (av.alignment.getGroups() != null)
391     {
392       Vector allGroups = ap.av.alignment.getGroups();
393       SequenceGroup sg;
394       for (int g = 0; g < allGroups.size(); g++)
395       {
396         sg = (SequenceGroup) allGroups.get(g);
397
398         if (sg.cs == null)
399         {
400           continue;
401         }
402
403         if (currentColours.isSelected())
404         {
405           sg.cs = new AnnotationColourGradient(
406               currentAnnotation,
407               sg.cs, aboveThreshold);
408         }
409         else
410         {
411           sg.cs = new AnnotationColourGradient(
412               currentAnnotation,
413               minColour.getBackground(),
414               maxColour.getBackground(),
415               aboveThreshold);
416         }
417
418       }
419     }
420
421     ap.paintAlignment(false);
422   }
423
424   public void ok_actionPerformed(ActionEvent e)
425   {
426     changeColour();
427     try
428     {
429       frame.setClosed(true);
430     }
431     catch (Exception ex)
432     {}
433   }
434
435   public void cancel_actionPerformed(ActionEvent e)
436   {
437     reset();
438     try
439     {
440       frame.setClosed(true);
441     }
442     catch (Exception ex)
443     {}
444   }
445
446   void reset()
447   {
448     av.setGlobalColourScheme(oldcs);
449     if (av.alignment.getGroups() != null)
450     {
451       Vector allGroups = ap.av.alignment.getGroups();
452       SequenceGroup sg;
453       for (int g = 0; g < allGroups.size(); g++)
454       {
455         sg = (SequenceGroup) allGroups.get(g);
456         sg.cs = (ColourSchemeI) oldgroupColours.get(sg);
457       }
458     }
459   }
460
461   public void thresholdCheck_actionPerformed(ActionEvent e)
462   {
463     changeColour();
464   }
465
466   public void annotations_actionPerformed(ActionEvent e)
467   {
468     changeColour();
469   }
470
471   public void threshold_actionPerformed(ActionEvent e)
472   {
473     changeColour();
474   }
475
476   public void thresholdValue_actionPerformed(ActionEvent e)
477   {
478     try
479     {
480       float f = Float.parseFloat(thresholdValue.getText());
481       slider.setValue( (int) (f * 1000));
482     }
483     catch (NumberFormatException ex)
484     {}
485   }
486
487   public void valueChanged()
488   {
489     if (currentColours.isSelected()
490         && ! (av.getGlobalColourScheme() instanceof AnnotationColourGradient))
491     {
492       changeColour();
493     }
494
495     currentAnnotation.threshold.value = (float) slider.getValue() / 1000f;
496     ap.paintAlignment(false);
497   }
498
499   public void currentColours_actionPerformed(ActionEvent e)
500   {
501     if (currentColours.isSelected())
502     {
503       reset();
504     }
505
506     maxColour.setEnabled(!currentColours.isSelected());
507     minColour.setEnabled(!currentColours.isSelected());
508
509     changeColour();
510   }
511
512   public void thresholdIsMin_actionPerformed(ActionEvent actionEvent)
513   {
514     changeColour();
515   }
516
517 }