Formatting
[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, 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 \r
85     if (av.alignment.getAlignmentAnnotation() == null)\r
86     {\r
87       return;\r
88     }\r
89 \r
90     if (oldcs instanceof AnnotationColourGradient)\r
91     {\r
92       AnnotationColourGradient acg = (AnnotationColourGradient) oldcs;\r
93       minColour.setBackground(acg.getMinColour());\r
94       maxColour.setBackground(acg.getMaxColour());\r
95     }\r
96     else\r
97     {\r
98       minColour.setBackground(Color.orange);\r
99       maxColour.setBackground(Color.red);\r
100     }\r
101 \r
102     adjusting = true;\r
103     for (int i = 0; i < av.alignment.getAlignmentAnnotation().length; i++)\r
104     {\r
105       if (av.alignment.getAlignmentAnnotation()[i].graph > 0)\r
106       {\r
107         annotations.addItem(av.alignment.getAlignmentAnnotation()[i].label);\r
108       }\r
109     }\r
110 \r
111     threshold.addItem("No Threshold");\r
112     threshold.addItem("Above Threshold");\r
113     threshold.addItem("Below Threshold");\r
114 \r
115     adjusting = false;\r
116 \r
117     changeColour();\r
118 \r
119   }\r
120 \r
121   public AnnotationColourChooser()\r
122   {\r
123     try\r
124     {\r
125       jbInit();\r
126     }\r
127     catch (Exception ex)\r
128     {\r
129       ex.printStackTrace();\r
130     }\r
131   }\r
132 \r
133   private void jbInit()\r
134       throws Exception\r
135   {\r
136     minColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
137     minColour.setBorder(BorderFactory.createEtchedBorder());\r
138     minColour.setPreferredSize(new Dimension(40, 20));\r
139     minColour.setToolTipText("Minimum Colour");\r
140     minColour.addMouseListener(new MouseAdapter()\r
141     {\r
142       public void mousePressed(MouseEvent e)\r
143       {\r
144         if (minColour.isEnabled())\r
145         {\r
146           minColour_actionPerformed();\r
147         }\r
148       }\r
149     });\r
150     maxColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
151     maxColour.setBorder(BorderFactory.createEtchedBorder());\r
152     maxColour.setPreferredSize(new Dimension(40, 20));\r
153     maxColour.setToolTipText("Maximum Colour");\r
154     maxColour.addMouseListener(new MouseAdapter()\r
155     {\r
156       public void mousePressed(MouseEvent e)\r
157       {\r
158         if (maxColour.isEnabled())\r
159         {\r
160           maxColour_actionPerformed();\r
161         }\r
162       }\r
163     });\r
164     ok.setOpaque(false);\r
165     ok.setText("OK");\r
166     ok.addActionListener(new ActionListener()\r
167     {\r
168       public void actionPerformed(ActionEvent e)\r
169       {\r
170         ok_actionPerformed(e);\r
171       }\r
172     });\r
173     cancel.setOpaque(false);\r
174     cancel.setText("Cancel");\r
175     cancel.addActionListener(new ActionListener()\r
176     {\r
177       public void actionPerformed(ActionEvent e)\r
178       {\r
179         cancel_actionPerformed(e);\r
180       }\r
181     });\r
182     this.setLayout(borderLayout1);\r
183     jPanel2.setLayout(flowLayout1);\r
184     annotations.addActionListener(new ActionListener()\r
185     {\r
186       public void actionPerformed(ActionEvent e)\r
187       {\r
188         annotations_actionPerformed(e);\r
189       }\r
190     });\r
191     jPanel1.setBackground(Color.white);\r
192     jPanel2.setBackground(Color.white);\r
193     threshold.addActionListener(new ActionListener()\r
194     {\r
195       public void actionPerformed(ActionEvent e)\r
196       {\r
197         threshold_actionPerformed(e);\r
198       }\r
199     });\r
200     jPanel3.setLayout(flowLayout2);\r
201     thresholdValue.addActionListener(new ActionListener()\r
202     {\r
203       public void actionPerformed(ActionEvent e)\r
204       {\r
205         thresholdValue_actionPerformed(e);\r
206       }\r
207     });\r
208     slider.setPaintLabels(false);\r
209     slider.setPaintTicks(true);\r
210     slider.setBackground(Color.white);\r
211     slider.setEnabled(false);\r
212     slider.setOpaque(false);\r
213     slider.setPreferredSize(new Dimension(150, 32));\r
214     thresholdValue.setEnabled(false);\r
215     thresholdValue.setColumns(10);\r
216     jPanel3.setBackground(Color.white);\r
217     currentColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
218     currentColours.setOpaque(false);\r
219     currentColours.setText("Use Original Colours");\r
220     currentColours.addActionListener(new ActionListener()\r
221     {\r
222       public void actionPerformed(ActionEvent e)\r
223       {\r
224         currentColours_actionPerformed(e);\r
225       }\r
226     });\r
227     jPanel1.add(ok);\r
228     jPanel1.add(cancel);\r
229     jPanel2.add(annotations);\r
230     jPanel2.add(currentColours);\r
231     jPanel2.add(minColour);\r
232     jPanel2.add(maxColour);\r
233     this.add(jPanel3, java.awt.BorderLayout.CENTER);\r
234     jPanel3.add(threshold);\r
235     jPanel3.add(slider);\r
236     jPanel3.add(thresholdValue);\r
237     this.add(jPanel1, java.awt.BorderLayout.SOUTH);\r
238     this.add(jPanel2, java.awt.BorderLayout.NORTH);\r
239   }\r
240 \r
241   JComboBox annotations = new JComboBox();\r
242   JPanel minColour = new JPanel();\r
243   JPanel maxColour = new JPanel();\r
244   JButton ok = new JButton();\r
245   JButton cancel = new JButton();\r
246   JPanel jPanel1 = new JPanel();\r
247   JPanel jPanel2 = new JPanel();\r
248   BorderLayout borderLayout1 = new BorderLayout();\r
249   JComboBox threshold = new JComboBox();\r
250   FlowLayout flowLayout1 = new FlowLayout();\r
251   JPanel jPanel3 = new JPanel();\r
252   FlowLayout flowLayout2 = new FlowLayout();\r
253   JSlider slider = new JSlider();\r
254   JTextField thresholdValue = new JTextField(20);\r
255   JCheckBox currentColours = new JCheckBox();\r
256 \r
257   public void minColour_actionPerformed()\r
258   {\r
259     Color col = JColorChooser.showDialog(this,\r
260                                          "Select Colour for Minimum Value",\r
261                                          minColour.getBackground());\r
262     if (col != null)\r
263     {\r
264       minColour.setBackground(col);\r
265     }\r
266     minColour.repaint();\r
267     changeColour();\r
268   }\r
269 \r
270   public void maxColour_actionPerformed()\r
271   {\r
272     Color col = JColorChooser.showDialog(this,\r
273                                          "Select Colour for Maximum Value",\r
274                                          maxColour.getBackground());\r
275     if (col != null)\r
276     {\r
277       maxColour.setBackground(col);\r
278     }\r
279     maxColour.repaint();\r
280     changeColour();\r
281   }\r
282 \r
283   void changeColour()\r
284   {\r
285     // Check if combobox is still adjusting\r
286     if (adjusting)\r
287     {\r
288       return;\r
289     }\r
290 \r
291     // We removed the non-graph annotations when filling the combobox\r
292     // so allow for them again here\r
293     int nograph = 0, graph = -1;\r
294     for (int i = 0; i < av.alignment.getAlignmentAnnotation().length; i++)\r
295     {\r
296       if (av.alignment.getAlignmentAnnotation()[i].graph == 0)\r
297       {\r
298         nograph++;\r
299       }\r
300       else\r
301       {\r
302         graph++;\r
303       }\r
304 \r
305       if (graph == annotations.getSelectedIndex())\r
306       {\r
307         break;\r
308       }\r
309     }\r
310 \r
311     currentAnnotation = av.alignment.getAlignmentAnnotation()[graph + nograph];\r
312 \r
313     int aboveThreshold = -1;\r
314     if (threshold.getSelectedItem().equals("Above Threshold"))\r
315     {\r
316       aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;\r
317     }\r
318     else if (threshold.getSelectedItem().equals("Below Threshold"))\r
319     {\r
320       aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;\r
321     }\r
322 \r
323     slider.setEnabled(true);\r
324     thresholdValue.setEnabled(true);\r
325 \r
326     if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)\r
327     {\r
328       slider.setEnabled(false);\r
329       thresholdValue.setEnabled(false);\r
330       thresholdValue.setText("");\r
331     }\r
332     else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD &&\r
333              currentAnnotation.threshold == null)\r
334     {\r
335       currentAnnotation.setThreshold(new jalview.datamodel.GraphLine\r
336                                      ( (currentAnnotation.graphMax -\r
337                                         currentAnnotation.graphMin) / 2f,\r
338                                       "Threshold",\r
339                                       Color.black));\r
340     }\r
341 \r
342     if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)\r
343     {\r
344       adjusting = true;\r
345       float range = currentAnnotation.graphMax * 1000 -\r
346           currentAnnotation.graphMin * 1000;\r
347 \r
348       slider.setMinimum( (int) (currentAnnotation.graphMin * 1000));\r
349       slider.setMaximum( (int) (currentAnnotation.graphMax * 1000));\r
350       slider.setValue( (int) (currentAnnotation.threshold.value * 1000));\r
351       thresholdValue.setText(currentAnnotation.threshold.value + "");\r
352       slider.setMajorTickSpacing( (int) (range / 10f));\r
353       slider.setEnabled(true);\r
354       thresholdValue.setEnabled(true);\r
355       adjusting = false;\r
356     }\r
357 \r
358     AnnotationColourGradient acg = null;\r
359     if (currentColours.isSelected())\r
360     {\r
361       acg = new AnnotationColourGradient(\r
362           currentAnnotation,\r
363           av.getGlobalColourScheme(), aboveThreshold);\r
364     }\r
365     else\r
366     {\r
367       acg =\r
368           new AnnotationColourGradient(\r
369               currentAnnotation,\r
370               minColour.getBackground(),\r
371               maxColour.getBackground(),\r
372               aboveThreshold);\r
373     }\r
374 \r
375     av.setGlobalColourScheme(acg);\r
376 \r
377     if (av.alignment.getGroups() != null)\r
378     {\r
379       Vector allGroups = ap.av.alignment.getGroups();\r
380       SequenceGroup sg;\r
381       for (int g = 0; g < allGroups.size(); g++)\r
382       {\r
383         sg = (SequenceGroup) allGroups.get(g);\r
384 \r
385         if (sg.cs == null)\r
386         {\r
387           continue;\r
388         }\r
389 \r
390         if (currentColours.isSelected())\r
391         {\r
392           sg.cs = new AnnotationColourGradient(\r
393               currentAnnotation,\r
394               sg.cs, aboveThreshold);\r
395         }\r
396         else\r
397         {\r
398           sg.cs = new AnnotationColourGradient(\r
399               currentAnnotation,\r
400               minColour.getBackground(),\r
401               maxColour.getBackground(),\r
402               aboveThreshold);\r
403         }\r
404 \r
405       }\r
406     }\r
407 \r
408     ap.repaint();\r
409   }\r
410 \r
411   public void ok_actionPerformed(ActionEvent e)\r
412   {\r
413     changeColour();\r
414     try\r
415     {\r
416       frame.setClosed(true);\r
417     }\r
418     catch (Exception ex)\r
419     {}\r
420   }\r
421 \r
422   public void cancel_actionPerformed(ActionEvent e)\r
423   {\r
424     reset();\r
425     try\r
426     {\r
427       frame.setClosed(true);\r
428     }\r
429     catch (Exception ex)\r
430     {}\r
431   }\r
432 \r
433   void reset()\r
434   {\r
435     av.setGlobalColourScheme(oldcs);\r
436     if (av.alignment.getGroups() != null)\r
437     {\r
438       Vector allGroups = ap.av.alignment.getGroups();\r
439       SequenceGroup sg;\r
440       for (int g = 0; g < allGroups.size(); g++)\r
441       {\r
442         sg = (SequenceGroup) allGroups.get(g);\r
443         sg.cs = (ColourSchemeI) oldgroupColours.get(sg);\r
444       }\r
445     }\r
446   }\r
447 \r
448   public void thresholdCheck_actionPerformed(ActionEvent e)\r
449   {\r
450     changeColour();\r
451   }\r
452 \r
453   public void annotations_actionPerformed(ActionEvent e)\r
454   {\r
455     changeColour();\r
456   }\r
457 \r
458   public void threshold_actionPerformed(ActionEvent e)\r
459   {\r
460     changeColour();\r
461   }\r
462 \r
463   public void thresholdValue_actionPerformed(ActionEvent e)\r
464   {\r
465     try\r
466     {\r
467       float f = Float.parseFloat(thresholdValue.getText());\r
468       slider.setValue( (int) (f * 1000));\r
469     }\r
470     catch (NumberFormatException ex)\r
471     {}\r
472   }\r
473 \r
474   public void valueChanged()\r
475   {\r
476     if (currentColours.isSelected()\r
477         && ! (av.getGlobalColourScheme() instanceof AnnotationColourGradient))\r
478     {\r
479       changeColour();\r
480     }\r
481 \r
482     currentAnnotation.threshold.value = (float) slider.getValue() / 1000f;\r
483     ap.repaint();\r
484   }\r
485 \r
486   public void currentColours_actionPerformed(ActionEvent e)\r
487   {\r
488     if (currentColours.isSelected())\r
489     {\r
490       reset();\r
491     }\r
492 \r
493     maxColour.setEnabled(!currentColours.isSelected());\r
494     minColour.setEnabled(!currentColours.isSelected());\r
495 \r
496     changeColour();\r
497   }\r
498 \r
499 }\r