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