Clover icon

Coverage Report

  1. Project Clover database Thu Dec 4 2025 16:11:35 GMT
  2. Package jalview.gui

File AnnotationColourChooser.java

 

Coverage histogram

../../img/srcFileCovDistChart0.png
60% of files have more coverage

Code metrics

52
203
23
1
534
441
59
0.29
8.83
23
2.57

Classes

Class Line # Actions
AnnotationColourChooser 54 203 59
0.00%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3    * Copyright (C) $$Year-Rel$$ 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.gui;
22   
23    import java.awt.BorderLayout;
24    import java.awt.Color;
25    import java.awt.Dimension;
26    import java.awt.FlowLayout;
27    import java.awt.event.ActionEvent;
28    import java.awt.event.ActionListener;
29    import java.awt.event.MouseAdapter;
30    import java.awt.event.MouseEvent;
31    import java.util.Hashtable;
32    import java.util.Vector;
33   
34    import javax.swing.BorderFactory;
35    import javax.swing.JButton;
36    import javax.swing.JCheckBox;
37    import javax.swing.JComboBox;
38    import javax.swing.JInternalFrame;
39    import javax.swing.JLayeredPane;
40    import javax.swing.JPanel;
41   
42    import jalview.bin.Cache;
43    import jalview.datamodel.AlignmentAnnotation;
44    import jalview.datamodel.Annotation;
45    import jalview.datamodel.GraphLine;
46    import jalview.datamodel.SequenceGroup;
47    import jalview.gui.JalviewColourChooser.ColourChooserListener;
48    import jalview.schemes.AnnotationColourGradient;
49    import jalview.schemes.ColourSchemeI;
50    import jalview.util.MessageManager;
51    import net.miginfocom.swing.MigLayout;
52   
53    @SuppressWarnings("serial")
 
54    public class AnnotationColourChooser extends AnnotationRowFilter
55    {
56    private ColourSchemeI oldcs;
57   
58    private JButton defColours;
59   
60    private Hashtable<SequenceGroup, ColourSchemeI> oldgroupColours;
61   
62    private JCheckBox useOriginalColours = new JCheckBox();
63   
64    JPanel minColour = new JPanel();
65   
66    JPanel maxColour = new JPanel();
67   
68    private JCheckBox thresholdIsMin = new JCheckBox();
69    private JCheckBox transparency = new JCheckBox();
70   
71    protected static final int MIN_WIDTH = 500;
72   
73    protected static final int MIN_HEIGHT = 240;
74   
 
75  0 toggle public AnnotationColourChooser(AlignViewport av, final AlignmentPanel ap)
76    {
77  0 this(av, ap, null);
78    }
79   
 
80  0 toggle public AnnotationColourChooser(AlignViewport av, final AlignmentPanel ap,
81    AnnotationColourGradient initSettings)
82    {
83  0 super(av, ap);
84  0 oldcs = av.getGlobalColourScheme();
85  0 if (av.getAlignment().getGroups() != null)
86    {
87  0 oldgroupColours = new Hashtable<>();
88  0 for (SequenceGroup sg : ap.av.getAlignment().getGroups())
89    {
90  0 if (sg.getColourScheme() != null)
91    {
92  0 oldgroupColours.put(sg, sg.getColourScheme());
93    }
94    }
95    }
96  0 frame = new JInternalFrame();
97  0 frame.setFrameIcon(null);
98  0 frame.setContentPane(this);
99  0 frame.setLayer(JLayeredPane.PALETTE_LAYER);
100  0 Desktop.addInternalFrame(frame,
101    MessageManager.getString("label.colour_by_annotation"), 520,
102    215);
103  0 frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
104  0 addSliderChangeListener();
105  0 addSliderMouseListeners();
106   
107  0 if (av.getAlignment().getAlignmentAnnotation() == null)
108    {
109  0 return;
110    }
111   
112    // Always get default shading from preferences.
113  0 setDefaultMinMax();
114   
115  0 adjusting = true;
116  0 if (oldcs instanceof AnnotationColourGradient && initSettings == null)
117    {
118    // init from oldcs
119  0 initialiseFrom((AnnotationColourGradient) oldcs);
120    }
121    else
122    {
123    // use initial colour gradient - if any..
124  0 initialiseFrom(initSettings);
125    }
126   
127  0 jbInit();
128  0 adjusting = false;
129   
130  0 updateView();
131  0 frame.invalidate();
132  0 frame.pack();
133    }
134   
 
135  0 toggle private void initialiseFrom(AnnotationColourGradient acg)
136    {
137  0 if (acg != null)
138    {
139  0 useOriginalColours.setSelected(
140    acg.isPredefinedColours() || acg.getBaseColour() != null);
141  0 if (!acg.isPredefinedColours() && acg.getBaseColour() == null)
142    {
143  0 minColour.setBackground(acg.getMinColour());
144  0 maxColour.setBackground(acg.getMaxColour());
145    }
146  0 seqAssociated.setSelected(acg.isSeqAssociated());
147   
148    }
149  0 Vector<String> annotItems = getAnnotationItems(
150    seqAssociated.isSelected());
151  0 annotations = new JComboBox<>(annotItems);
152   
153  0 populateThresholdComboBox(threshold);
154   
155  0 if (acg != null)
156    {
157  0 String label = getAnnotationMenuLabel(acg.getAnnotation());
158    // TODO: workaround below shouldn't be necessary - there's a bug in
159    // getAnnotationMenuLabel!
160  0 if (acg.isSeqAssociated())
161    {
162  0 label = acg.getAnnotation().label;
163    }
164  0 annotations.setSelectedItem(label);
165  0 switch (acg.getAboveThreshold())
166    {
167  0 case AnnotationColourGradient.NO_THRESHOLD:
168  0 getThreshold().setSelectedIndex(0);
169  0 break;
170  0 case AnnotationColourGradient.ABOVE_THRESHOLD:
171  0 getThreshold().setSelectedIndex(1);
172  0 break;
173  0 case AnnotationColourGradient.BELOW_THRESHOLD:
174  0 getThreshold().setSelectedIndex(2);
175  0 break;
176  0 default:
177  0 throw new Error(MessageManager.getString(
178    "error.implementation_error_dont_know_about_threshold_setting"));
179    }
180  0 thresholdIsMin.setSelected(acg.isThresholdIsMinMax());
181  0 thresholdValue.setText(String.valueOf(acg.getAnnotationThreshold()));
182    }
183    }
184   
 
185  0 toggle @Override
186    protected void jbInit()
187    {
188  0 super.jbInit();
189   
190  0 minColour.setFont(JvSwingUtils.getLabelFont());
191  0 minColour.setBorder(BorderFactory.createEtchedBorder());
192  0 minColour.setPreferredSize(new Dimension(40, 20));
193  0 minColour.setToolTipText(MessageManager.getString("label.min_colour"));
194  0 minColour.addMouseListener(new MouseAdapter()
195    {
 
196  0 toggle @Override
197    public void mousePressed(MouseEvent e)
198    {
199  0 if (minColour.isEnabled())
200    {
201  0 showColourChooser(minColour, "label.select_colour_minimum_value");
202    }
203    }
204    });
205  0 maxColour.setFont(JvSwingUtils.getLabelFont());
206  0 maxColour.setBorder(BorderFactory.createEtchedBorder());
207  0 maxColour.setPreferredSize(new Dimension(40, 20));
208  0 maxColour.setToolTipText(MessageManager.getString("label.max_colour"));
209  0 maxColour.addMouseListener(new MouseAdapter()
210    {
 
211  0 toggle @Override
212    public void mousePressed(MouseEvent e)
213    {
214  0 if (maxColour.isEnabled())
215    {
216  0 showColourChooser(maxColour, "label.select_colour_maximum_value");
217    }
218    }
219    });
220   
221  0 defColours = new JButton();
222  0 defColours.setOpaque(false);
223  0 defColours.setText(MessageManager.getString("action.set_defaults"));
224  0 defColours.setToolTipText(MessageManager
225    .getString("label.reset_min_max_colours_to_defaults"));
226  0 defColours.addActionListener(new ActionListener()
227    {
228   
 
229  0 toggle @Override
230    public void actionPerformed(ActionEvent arg0)
231    {
232  0 resetColours_actionPerformed();
233    }
234    });
235   
236  0 useOriginalColours.setFont(JvSwingUtils.getLabelFont());
237  0 useOriginalColours.setOpaque(false);
238  0 useOriginalColours.setText(
239    MessageManager.getString("label.use_original_colours"));
240  0 useOriginalColours.addActionListener(new ActionListener()
241    {
 
242  0 toggle @Override
243    public void actionPerformed(ActionEvent e)
244    {
245  0 originalColours_actionPerformed();
246    }
247    });
248  0 thresholdIsMin.setBackground(Color.white);
249  0 thresholdIsMin.setFont(JvSwingUtils.getLabelFont());
250  0 thresholdIsMin
251    .setText(MessageManager.getString("label.threshold_minmax"));
252  0 thresholdIsMin.addActionListener(new ActionListener()
253    {
 
254  0 toggle @Override
255    public void actionPerformed(ActionEvent actionEvent)
256    {
257  0 thresholdIsMin_actionPerformed();
258    }
259    });
260  0 seqAssociated.setBackground(Color.white);
261  0 seqAssociated.setFont(JvSwingUtils.getLabelFont());
262  0 seqAssociated
263    .setText(MessageManager.getString("label.per_sequence_only"));
264  0 seqAssociated.addActionListener(new ActionListener()
265    {
266   
 
267  0 toggle @Override
268    public void actionPerformed(ActionEvent arg0)
269    {
270  0 seqAssociated_actionPerformed(annotations);
271    }
272    });
273   
274  0 transparency.setBackground(Color.white);
275  0 transparency.setFont(JvSwingUtils.getLabelFont());
276  0 transparency
277    .setText(MessageManager.getString("Use Transparency"));
278  0 transparency.addActionListener(new ActionListener()
279    {
280   
 
281  0 toggle @Override
282    public void actionPerformed(ActionEvent arg0)
283    {
284  0 transparency_actionPerformed();
285    }
286    });
287  0 this.setLayout(new BorderLayout());
288  0 JPanel jPanel1 = new JPanel();
289  0 JPanel jPanel2 = new JPanel();
290  0 jPanel2.setLayout(new MigLayout("", "[left][center][right]", "[][][]"));
291  0 jPanel1.setBackground(Color.white);
292  0 jPanel2.setBackground(Color.white);
293   
294  0 jPanel1.add(ok);
295  0 jPanel1.add(cancel);
296  0 jPanel2.add(annotations, "grow, wrap");
297  0 jPanel2.add(seqAssociated);
298  0 jPanel2.add(useOriginalColours);
299  0 jPanel2.add(transparency);
300  0 JPanel colpanel = new JPanel(new FlowLayout());
301  0 colpanel.setBackground(Color.white);
302  0 colpanel.add(minColour);
303  0 colpanel.add(maxColour);
304  0 jPanel2.add(colpanel, "wrap");
305  0 jPanel2.add(getThreshold());
306  0 jPanel2.add(defColours, "skip 1, wrap");
307  0 jPanel2.add(thresholdIsMin);
308  0 jPanel2.add(slider, "grow");
309  0 jPanel2.add(thresholdValue, "grow");
310  0 this.add(jPanel1, java.awt.BorderLayout.SOUTH);
311  0 this.add(jPanel2, java.awt.BorderLayout.CENTER);
312  0 this.validate();
313    }
314   
 
315  0 toggle protected void transparency_actionPerformed()
316    {
317  0 updateView();
318    }
 
319  0 toggle protected void resetColours_actionPerformed()
320    {
321  0 setDefaultMinMax();
322  0 updateView();
323    }
324   
 
325  0 toggle private void setDefaultMinMax()
326    {
327  0 minColour.setBackground(
328    Cache.getDefaultColour("ANNOTATIONCOLOUR_MIN", Color.orange));
329  0 maxColour.setBackground(
330    Cache.getDefaultColour("ANNOTATIONCOLOUR_MAX", Color.red));
331    }
332   
 
333  0 toggle protected void showColourChooser(JPanel colourPanel, String titleKey)
334    {
335  0 String ttl = MessageManager.getString(titleKey);
336  0 ColourChooserListener listener = new ColourChooserListener()
337    {
 
338  0 toggle @Override
339    public void colourSelected(Color c)
340    {
341  0 colourPanel.setBackground(c);
342  0 colourPanel.repaint();
343  0 updateView();
344    }
345    };
346  0 JalviewColourChooser.showColourChooser(Desktop.getDesktopPane(), ttl,
347    colourPanel.getBackground(), listener);
348    }
349   
 
350  0 toggle @Override
351    public void reset()
352    {
353  0 this.ap.alignFrame.changeColour(oldcs);
354  0 if (av.getAlignment().getGroups() != null)
355    {
356   
357  0 for (SequenceGroup sg : ap.av.getAlignment().getGroups())
358    {
359  0 sg.setColourScheme(oldgroupColours.get(sg));
360    }
361    }
362    }
363   
 
364  0 toggle @Override
365    public void valueChanged(boolean updateAllAnnotation)
366    {
367  0 if (slider.isEnabled())
368    {
369  0 if (useOriginalColours.isSelected() && !(av
370    .getGlobalColourScheme() instanceof AnnotationColourGradient))
371    {
372  0 updateView();
373    }
374  0 getCurrentAnnotation().threshold.value = getSliderValue();
375  0 propagateSeqAssociatedThreshold(updateAllAnnotation,
376    getCurrentAnnotation());
377  0 ap.paintAlignment(false, false);
378    }
379    }
380   
 
381  0 toggle public void originalColours_actionPerformed()
382    {
383  0 boolean selected = useOriginalColours.isSelected();
384  0 if (selected)
385    {
386  0 reset();
387    }
388  0 maxColour.setEnabled(!selected);
389  0 minColour.setEnabled(!selected);
390  0 thresholdIsMin.setEnabled(!selected);
391  0 updateView();
392    }
393   
 
394  0 toggle @Override
395    public void updateView()
396    {
397    // Check if combobox is still adjusting
398  0 if (adjusting)
399    {
400  0 return;
401    }
402   
403  0 int selIndex = annotations.getSelectedIndex();
404  0 int annIndex = annmap[selIndex];
405  0 setCurrentAnnotation(
406    av.getAlignment().getAlignmentAnnotation()[annIndex]);
407   
408  0 int selectedThresholdItem = getSelectedThresholdItem(
409    getThreshold().getSelectedIndex());
410   
411  0 slider.setEnabled(true);
412  0 thresholdValue.setEnabled(true);
413  0 thresholdIsMin.setEnabled(!useOriginalColours.isSelected());
414   
415  0 final AlignmentAnnotation currentAnnotation = getCurrentAnnotation();
416  0 if (selectedThresholdItem == AnnotationColourGradient.NO_THRESHOLD)
417    {
418  0 slider.setEnabled(false);
419  0 thresholdValue.setEnabled(false);
420  0 thresholdValue.setText("");
421  0 thresholdIsMin.setEnabled(false);
422    }
423  0 else if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD
424    && currentAnnotation.threshold == null)
425    {
426  0 currentAnnotation.setThreshold(new GraphLine(
427    (currentAnnotation.graphMax - currentAnnotation.graphMin)
428    / 2f,
429    "Threshold", Color.black));
430    }
431   
432  0 if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD)
433    {
434  0 adjusting = true;
435  0 setSliderModel(currentAnnotation.graphMin, currentAnnotation.graphMax,
436    currentAnnotation.threshold.value);
437  0 slider.setEnabled(true);
438   
439  0 setThresholdValueText();
440  0 thresholdValue.setEnabled(true);
441  0 adjusting = false;
442    }
443  0 colorAlignmentContaining(currentAnnotation, selectedThresholdItem);
444   
445  0 ap.alignmentChanged();
446    }
447   
 
448  0 toggle protected void colorAlignmentContaining(AlignmentAnnotation currentAnn,
449    int selectedThresholdOption)
450    {
451   
452  0 AnnotationColourGradient acg = null;
453  0 if (useOriginalColours.isSelected())
454    {
455  0 acg = new AnnotationColourGradient(currentAnn,
456    av.getGlobalColourScheme(), selectedThresholdOption);
457    }
458    else
459    {
460  0 acg = new AnnotationColourGradient(currentAnn,
461    minColour.getBackground(), maxColour.getBackground(),
462    selectedThresholdOption);
463    }
464  0 acg.setSeqAssociated(seqAssociated.isSelected());
465   
466  0 if (currentAnn.graphMin == 0f && currentAnn.graphMax == 0f)
467    {
468  0 acg.setPredefinedColours(true);
469    }
470   
471  0 acg.setThresholdIsMinMax(thresholdIsMin.isSelected());
472   
473  0 acg.setPositionToTransparency(transparency.isSelected());
474   
475  0 this.ap.alignFrame.changeColour(acg);
476   
477  0 if (av.getAlignment().getGroups() != null)
478    {
479   
480  0 for (SequenceGroup sg : ap.av.getAlignment().getGroups())
481    {
482  0 if (sg.cs == null)
483    {
484  0 continue;
485    }
486  0 sg.setColourScheme(acg.getInstance(av, sg));
487    }
488    }
489    }
490   
 
491  0 toggle @Override
492    protected void sliderDragReleased()
493    {
494  0 super.sliderDragReleased();
495  0 ap.paintAlignment(true, true);
496    }
497   
498    /**
499    * construct and display a colourchooser for a given annotation row
500    *
501    * @param av
502    * @param ap
503    * @param alignmentAnnotation
504    * @param perseq
505    * - when true, enable per-sequence if alignment annotation is per
506    * sequence
507    */
 
508  0 toggle public static void displayFor(AlignViewport av, AlignmentPanel ap,
509    AlignmentAnnotation alignmentAnnotation, boolean perSeq)
510    {
511  0 ColourSchemeI global = av.getGlobalColourScheme();
512  0 AnnotationColourGradient newCS = new AnnotationColourGradient(
513    alignmentAnnotation, global,
514  0 alignmentAnnotation.threshold != null
515    ? AnnotationColourGradient.ABOVE_THRESHOLD
516    : AnnotationColourGradient.NO_THRESHOLD);
517  0 if (alignmentAnnotation.sequenceRef != null)
518    {
519  0 newCS.setSeqAssociated(perSeq);
520    }
521  0 for (int i = 0; i < alignmentAnnotation.annotations.length; i++)
522    {
523  0 Annotation ann = alignmentAnnotation.annotations[i];
524  0 if (ann != null && ann.colour != null
525    && !ann.colour.equals(Color.white))
526    {
527  0 newCS.setPredefinedColours(true);
528  0 break;
529    }
530    }
531  0 AnnotationColourChooser achooser = new AnnotationColourChooser(av, ap,
532    newCS);
533    }
534    }