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