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