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