JAL-1517 source formatting
[jalview.git] / src / jalview / appletgui / AnnotationColourChooser.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3  * Copyright (C) 2014 The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.appletgui;
22
23 import java.util.*;
24
25 import java.awt.*;
26 import java.awt.event.*;
27
28 import jalview.datamodel.*;
29 import jalview.schemes.*;
30 import jalview.util.MessageManager;
31
32 public class AnnotationColourChooser extends Panel implements
33         ActionListener, AdjustmentListener, ItemListener, MouseListener
34 {
35   Frame frame;
36
37   AlignViewport av;
38
39   AlignmentPanel ap;
40
41   ColourSchemeI oldcs;
42
43   Hashtable oldgroupColours;
44
45   jalview.datamodel.AlignmentAnnotation currentAnnotation;
46
47   boolean adjusting = false;
48
49   public AnnotationColourChooser(AlignViewport av, AlignmentPanel ap)
50   {
51     try
52     {
53       jbInit();
54     } catch (Exception ex)
55     {
56     }
57
58     oldcs = av.getGlobalColourScheme();
59     if (av.getAlignment().getGroups() != null)
60     {
61       oldgroupColours = new Hashtable();
62       for (SequenceGroup sg : ap.av.getAlignment().getGroups())
63       {
64         if (sg.cs != null)
65         {
66           oldgroupColours.put(sg, sg.cs);
67         }
68         else
69         {
70           oldgroupColours.put(sg, "null");
71         }
72       }
73     }
74     this.av = av;
75     this.ap = ap;
76
77     slider.addAdjustmentListener(this);
78     slider.addMouseListener(this);
79
80     if (av.getAlignment().getAlignmentAnnotation() == null)
81     {
82       return;
83     }
84
85     setDefaultMinMax();
86
87     adjusting = true;
88     if (oldcs instanceof AnnotationColourGradient)
89     {
90       AnnotationColourGradient acg = (AnnotationColourGradient) oldcs;
91       currentColours.setState(acg.isPredefinedColours()
92               || acg.getBaseColour() != null);
93       if (!acg.isPredefinedColours() && acg.getBaseColour() == null)
94       {
95         minColour.setBackground(acg.getMinColour());
96         maxColour.setBackground(acg.getMaxColour());
97       }
98       // seqAssociated.setState(acg.isSeqAssociated());
99     }
100
101     Vector list = new Vector();
102     int index = 1;
103     for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++)
104     {
105       String label = av.getAlignment().getAlignmentAnnotation()[i].label;
106       if (!list.contains(label))
107         list.addElement(label);
108       else
109         list.addElement(label + "_" + (index++));
110     }
111
112     for (int i = 0; i < list.size(); i++)
113     {
114       annotations.addItem(list.elementAt(i).toString());
115     }
116
117     threshold.addItem(MessageManager
118             .getString("label.threshold_feature_no_thereshold"));
119     threshold.addItem(MessageManager
120             .getString("label.threshold_feature_above_thereshold"));
121     threshold.addItem(MessageManager
122             .getString("label.threshold_feature_below_thereshold"));
123
124     if (oldcs instanceof AnnotationColourGradient)
125     {
126       AnnotationColourGradient acg = (AnnotationColourGradient) oldcs;
127       annotations.select(acg.getAnnotation());
128       switch (acg.getAboveThreshold())
129       {
130       case AnnotationColourGradient.NO_THRESHOLD:
131         threshold.select(0);
132         break;
133       case AnnotationColourGradient.ABOVE_THRESHOLD:
134         threshold.select(1);
135         break;
136       case AnnotationColourGradient.BELOW_THRESHOLD:
137         threshold.select(1);
138         break;
139       default:
140         throw new Error(
141                 "Implementation error: don't know about threshold setting for current AnnotationColourGradient.");
142       }
143       thresholdIsMin.setState(acg.thresholdIsMinMax);
144       thresholdValue.setText("" + acg.getAnnotationThreshold());
145     }
146
147     adjusting = false;
148
149     changeColour();
150
151     frame = new Frame();
152     frame.add(this);
153     jalview.bin.JalviewLite.addFrame(frame,
154             MessageManager.getString("label.colour_by_annotation"), 560,
155             175);
156     validate();
157   }
158
159   private void setDefaultMinMax()
160   {
161     minColour.setBackground(av.applet.getDefaultColourParameter(
162             "ANNOTATIONCOLOUR_MIN", Color.orange));
163     maxColour.setBackground(av.applet.getDefaultColourParameter(
164             "ANNOTATIONCOLOUR_MAX", Color.red));
165
166   }
167
168   public AnnotationColourChooser()
169   {
170     try
171     {
172       jbInit();
173     } catch (Exception ex)
174     {
175       ex.printStackTrace();
176     }
177   }
178
179   private void jbInit() throws Exception
180   {
181     minColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
182     minColour.setLabel(MessageManager.getString("label.min_colour"));
183     minColour.addActionListener(this);
184
185     maxColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
186     maxColour.setLabel(MessageManager.getString("label.max_colour"));
187     maxColour.addActionListener(this);
188
189     thresholdIsMin.addItemListener(this);
190     ok.setLabel(MessageManager.getString("action.ok"));
191     ok.addActionListener(this);
192
193     cancel.setLabel(MessageManager.getString("action.cancel"));
194     cancel.addActionListener(this);
195
196     defColours.setLabel(MessageManager.getString("action.set_defaults"));
197     defColours.addActionListener(this);
198
199     annotations.addItemListener(this);
200
201     thresholdValue.addActionListener(this);
202     slider.setBackground(Color.white);
203     slider.setPreferredSize(new Dimension(193, 21));
204     slider.setEnabled(false);
205     thresholdValue.setPreferredSize(new Dimension(79, 22));
206     thresholdValue.setEnabled(false);
207     thresholdValue.setColumns(5);
208     currentColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
209     currentColours.setLabel(MessageManager
210             .getString("label.use_original_colours"));
211     currentColours.addItemListener(this);
212
213     thresholdIsMin.setBackground(Color.white);
214     thresholdIsMin.setLabel(MessageManager
215             .getString("label.threshold_minmax"));
216
217     this.setLayout(borderLayout1);
218
219     jPanel1.setBackground(Color.white);
220
221     jPanel2.setLayout(new FlowLayout());
222     jPanel2.setBackground(Color.white);
223     threshold.addItemListener(this);
224     jPanel3.setLayout(new FlowLayout());
225     jPanel3.setBackground(Color.white);
226     Panel jPanel4 = new Panel();
227     jPanel4.setLayout(new BorderLayout());
228     jPanel4.setBackground(Color.white);
229
230     jPanel1.add(ok);
231     jPanel1.add(cancel);
232
233     jPanel2.add(annotations);
234     jPanel2.add(currentColours);
235     jPanel2.add(minColour);
236     jPanel2.add(maxColour);
237
238     jPanel4.add(thresholdIsMin, BorderLayout.WEST);
239     jPanel4.add(slider, BorderLayout.CENTER);
240     jPanel4.add(thresholdValue, BorderLayout.EAST);
241
242     Panel jPanel34 = new Panel();
243     jPanel34.setLayout(new BorderLayout());
244     jPanel34.setBackground(Color.white);
245     jPanel34.add(jPanel2, BorderLayout.NORTH);
246     jPanel34.add(threshold, BorderLayout.WEST);
247     jPanel3.add(defColours);
248     jPanel34.add(jPanel3, BorderLayout.EAST);
249     jPanel34.add(jPanel4, BorderLayout.SOUTH);
250
251     this.add(jPanel34, java.awt.BorderLayout.CENTER);
252     this.add(jPanel1, java.awt.BorderLayout.SOUTH);
253
254   }
255
256   Choice annotations = new Choice();
257
258   Button minColour = new Button();
259
260   Button maxColour = new Button();
261
262   Button ok = new Button();
263
264   Button cancel = new Button();
265
266   Button defColours = new Button();
267
268   Panel jPanel1 = new Panel();
269
270   Panel jPanel2 = new Panel();
271
272   Choice threshold = new Choice();
273
274   FlowLayout flowLayout1 = new FlowLayout();
275
276   Panel jPanel3 = new Panel();
277
278   Scrollbar slider = new Scrollbar(Scrollbar.HORIZONTAL);
279
280   TextField thresholdValue = new TextField(20);
281
282   Checkbox currentColours = new Checkbox();
283
284   BorderLayout borderLayout1 = new BorderLayout();
285
286   Checkbox thresholdIsMin = new Checkbox();
287
288   public void actionPerformed(ActionEvent evt)
289   {
290     if (evt.getSource() == thresholdValue)
291     {
292       try
293       {
294         float f = new Float(thresholdValue.getText()).floatValue();
295         slider.setValue((int) (f * 1000));
296         adjustmentValueChanged(null);
297       } catch (NumberFormatException ex)
298       {
299       }
300     }
301     else if (evt.getSource() == minColour)
302     {
303       minColour_actionPerformed(null);
304     }
305     else if (evt.getSource() == maxColour)
306     {
307       maxColour_actionPerformed(null);
308     }
309     else if (evt.getSource() == defColours)
310     {
311       defColour_actionPerformed();
312     }
313     else if (evt.getSource() == ok)
314     {
315       changeColour();
316       frame.setVisible(false);
317     }
318     else if (evt.getSource() == cancel)
319     {
320       reset();
321       ap.paintAlignment(true);
322       frame.setVisible(false);
323     }
324
325     else
326     {
327       changeColour();
328     }
329   }
330
331   public void itemStateChanged(ItemEvent evt)
332   {
333     if (evt.getSource() == currentColours)
334     {
335       if (currentColours.getState())
336       {
337         reset();
338       }
339
340       maxColour.setEnabled(!currentColours.getState());
341       minColour.setEnabled(!currentColours.getState());
342
343     }
344
345     changeColour();
346   }
347
348   public void adjustmentValueChanged(AdjustmentEvent evt)
349   {
350     if (!adjusting)
351     {
352       thresholdValue.setText(((float) slider.getValue() / 1000f) + "");
353       if (currentColours.getState()
354               && !(av.getGlobalColourScheme() instanceof AnnotationColourGradient))
355       {
356         changeColour();
357       }
358
359       currentAnnotation.threshold.value = (float) slider.getValue() / 1000f;
360       ap.paintAlignment(false);
361     }
362   }
363
364   public void minColour_actionPerformed(Color newCol)
365   {
366     if (newCol != null)
367     {
368       minColour.setBackground(newCol);
369       minColour.repaint();
370       changeColour();
371     }
372     else
373     {
374       new UserDefinedColours(this, "Min Colour", minColour.getBackground());
375     }
376
377   }
378
379   public void maxColour_actionPerformed(Color newCol)
380   {
381     if (newCol != null)
382     {
383       maxColour.setBackground(newCol);
384       maxColour.repaint();
385       changeColour();
386     }
387     else
388     {
389       new UserDefinedColours(this, "Max Colour", maxColour.getBackground());
390     }
391   }
392
393   public void defColour_actionPerformed()
394   {
395     setDefaultMinMax();
396     minColour.repaint();
397     maxColour.repaint();
398     changeColour();
399   }
400
401   void changeColour()
402   {
403     // Check if combobox is still adjusting
404     if (adjusting)
405     {
406       return;
407     }
408
409     currentAnnotation = av.getAlignment().getAlignmentAnnotation()[annotations
410             .getSelectedIndex()];
411
412     int aboveThreshold = -1;
413     if (threshold.getSelectedIndex() == 1)
414     {
415       aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;
416     }
417     else if (threshold.getSelectedIndex() == 2)
418     {
419       aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;
420     }
421
422     slider.setEnabled(true);
423     thresholdValue.setEnabled(true);
424     thresholdIsMin.setEnabled(true);
425
426     if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)
427     {
428       slider.setEnabled(false);
429       thresholdValue.setEnabled(false);
430       thresholdIsMin.setEnabled(false);
431       thresholdValue.setText("");
432     }
433     else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD
434             && currentAnnotation.threshold == null)
435     {
436       currentAnnotation
437               .setThreshold(new jalview.datamodel.GraphLine(
438                       (currentAnnotation.graphMax - currentAnnotation.graphMin) / 2f,
439                       "Threshold", Color.black));
440     }
441
442     if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
443     {
444       adjusting = true;
445
446       slider.setMinimum((int) (currentAnnotation.graphMin * 1000));
447       slider.setMaximum((int) (currentAnnotation.graphMax * 1000));
448       slider.setValue((int) (currentAnnotation.threshold.value * 1000));
449       thresholdValue.setText(currentAnnotation.threshold.value + "");
450       slider.setEnabled(true);
451       thresholdValue.setEnabled(true);
452       adjusting = false;
453     }
454
455     AnnotationColourGradient acg = null;
456     if (currentColours.getState())
457     {
458       acg = new AnnotationColourGradient(currentAnnotation,
459               av.getGlobalColourScheme(), aboveThreshold);
460     }
461     else
462     {
463       acg = new AnnotationColourGradient(currentAnnotation,
464               minColour.getBackground(), maxColour.getBackground(),
465               aboveThreshold);
466     }
467
468     if (currentAnnotation.graphMin == 0f
469             && currentAnnotation.graphMax == 0f)
470     {
471       acg.setPredefinedColours(true);
472     }
473
474     acg.thresholdIsMinMax = thresholdIsMin.getState();
475
476     av.setGlobalColourScheme(acg);
477
478     // TODO: per group colour propagation not always desired
479     if (av.getAlignment().getGroups() != null)
480     {
481       for (SequenceGroup sg : ap.av.getAlignment().getGroups())
482       {
483
484         if (sg.cs == null)
485         {
486           continue;
487         }
488
489         if (currentColours.getState())
490         {
491           sg.cs = new AnnotationColourGradient(currentAnnotation, sg.cs,
492                   aboveThreshold);
493         }
494         else
495         {
496           sg.cs = new AnnotationColourGradient(currentAnnotation,
497                   minColour.getBackground(), maxColour.getBackground(),
498                   aboveThreshold);
499         }
500
501       }
502     }
503
504     // update colours in linked windows
505     ap.alignmentChanged();
506     ap.paintAlignment(true);
507   }
508
509   void reset()
510   {
511     av.setGlobalColourScheme(oldcs);
512     if (av.getAlignment().getGroups() != null)
513     {
514       for (SequenceGroup sg : ap.av.getAlignment().getGroups())
515       {
516         Object cs = oldgroupColours.get(sg);
517         if (cs instanceof ColourSchemeI)
518         {
519           sg.cs = (ColourSchemeI) cs;
520         }
521         else
522         {
523           // probably the "null" string we set it to if it was null originally.
524           sg.cs = null;
525         }
526       }
527     }
528     ap.paintAlignment(true);
529
530   }
531
532   public void mouseClicked(MouseEvent evt)
533   {
534   }
535
536   public void mousePressed(MouseEvent evt)
537   {
538   }
539
540   public void mouseReleased(MouseEvent evt)
541   {
542     ap.paintAlignment(true);
543   }
544
545   public void mouseEntered(MouseEvent evt)
546   {
547   }
548
549   public void mouseExited(MouseEvent evt)
550   {
551   }
552
553 }