2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
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.
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.
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.
23 import jalview.datamodel.GraphLine;
24 import jalview.schemes.AnnotationColourGradient;
25 import jalview.schemes.GraduatedColor;
26 import jalview.util.MessageManager;
28 import java.awt.BorderLayout;
29 import java.awt.Color;
30 import java.awt.Dimension;
31 import java.awt.FlowLayout;
32 import java.awt.event.ActionEvent;
33 import java.awt.event.ActionListener;
34 import java.awt.event.MouseAdapter;
35 import java.awt.event.MouseEvent;
36 import java.util.Hashtable;
38 import javax.swing.BorderFactory;
39 import javax.swing.JCheckBox;
40 import javax.swing.JColorChooser;
41 import javax.swing.JComboBox;
42 import javax.swing.JLabel;
43 import javax.swing.JPanel;
44 import javax.swing.JSlider;
45 import javax.swing.JTextField;
46 import javax.swing.border.LineBorder;
47 import javax.swing.event.ChangeEvent;
48 import javax.swing.event.ChangeListener;
50 public class FeatureColourChooser extends JalviewDialog
52 // FeatureSettings fs;
55 private GraduatedColor cs;
61 * @return the last colour setting selected by user - either oldcs (which may
62 * be a java.awt.Color) or the new GraduatedColor
64 public Object getLastColour()
73 Hashtable oldgroupColours;
77 boolean adjusting = false;
79 final private float min;
81 final private float max;
83 final private float scaleFactor;
87 JPanel minColour = new JPanel();
89 JPanel maxColour = new JPanel();
91 JComboBox threshold = new JComboBox();
93 JSlider slider = new JSlider();
95 JTextField thresholdValue = new JTextField(20);
97 // TODO implement GUI for tolower flag
98 // JCheckBox toLower = new JCheckBox();
100 JCheckBox thresholdIsMin = new JCheckBox();
102 JCheckBox colourAlternately = new JCheckBox();
104 JCheckBox colourByLabel = new JCheckBox();
106 private GraphLine threshline;
108 private Color oldmaxColour;
110 private Color oldminColour;
112 public FeatureColourChooser(FeatureRenderer frender, String type)
114 this(frender, false, type);
117 public FeatureColourChooser(FeatureRenderer frender, boolean block,
123 String title = MessageManager.formatMessage(
124 "label.graduated_color_for_params", new String[] { type });
125 initDialogFrame(this, true, block, title, 480, 185);
126 // frame.setLayer(JLayeredPane.PALETTE_LAYER);
127 // Desktop.addInternalFrame(frame, "Graduated Feature Colour for "+type,
130 slider.addChangeListener(new ChangeListener()
133 public void stateChanged(ChangeEvent evt)
137 thresholdValue.setText((slider.getValue() / scaleFactor) + "");
142 slider.addMouseListener(new MouseAdapter()
145 public void mouseReleased(MouseEvent evt)
149 ap.paintAlignment(true);
155 float mm[] = fr.getMinMax().get(type)[0];
160 * ensure scale factor allows a scaled range with
161 * 10 integer divisions ('ticks'); if we have got here,
162 * we should expect that max != min
164 scaleFactor = (max == min) ? 1f : 100f / (max - min);
166 oldcs = fr.getFeatureColours().get(type);
167 if (oldcs instanceof GraduatedColor)
169 if (((GraduatedColor) oldcs).isAutoScale())
172 cs = new GraduatedColor((GraduatedColor) oldcs, min, max);
176 cs = new GraduatedColor((GraduatedColor) oldcs);
181 // promote original color to a graduated color
182 Color bl = Color.black;
183 if (oldcs instanceof Color)
187 // original colour becomes the maximum colour
188 cs = new GraduatedColor(Color.white, bl, mm[0], mm[1]);
189 cs.setColourByLabel(false);
191 minColour.setBackground(oldminColour = cs.getMinColor());
192 maxColour.setBackground(oldmaxColour = cs.getMaxColor());
198 } catch (Exception ex)
201 // update the gui from threshold state
202 thresholdIsMin.setSelected(!cs.isAutoScale());
203 colourByLabel.setSelected(cs.isColourByLabel());
204 colourAlternately.setSelected(cs.isColourAlternately());
205 if (cs.getThreshType() != AnnotationColourGradient.NO_THRESHOLD)
207 // initialise threshold slider and selector
209 .setSelectedIndex(cs.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD ? 1
211 slider.setEnabled(true);
212 thresholdValue.setEnabled(true);
213 threshline = new jalview.datamodel.GraphLine((max - min) / 2f,
214 "Threshold", Color.black);
224 private void jbInit() throws Exception
227 minColour.setFont(JvSwingUtils.getLabelFont());
228 minColour.setBorder(BorderFactory.createLineBorder(Color.black));
229 minColour.setPreferredSize(new Dimension(40, 20));
230 minColour.setToolTipText(MessageManager.getString("label.min_colour"));
231 minColour.addMouseListener(new MouseAdapter()
234 public void mousePressed(MouseEvent e)
236 if (minColour.isEnabled())
238 minColour_actionPerformed();
242 maxColour.setFont(JvSwingUtils.getLabelFont());
243 maxColour.setBorder(BorderFactory.createLineBorder(Color.black));
244 maxColour.setPreferredSize(new Dimension(40, 20));
245 maxColour.setToolTipText(MessageManager.getString("label.max_colour"));
246 maxColour.addMouseListener(new MouseAdapter()
249 public void mousePressed(MouseEvent e)
251 if (maxColour.isEnabled())
253 maxColour_actionPerformed();
257 maxColour.setBorder(new LineBorder(Color.black));
258 JLabel minText = new JLabel();
259 minText.setText(MessageManager.getString("label.min"));
260 minText.setFont(JvSwingUtils.getLabelFont());
261 JLabel maxText = new JLabel();
262 maxText.setText(MessageManager.getString("label.max"));
263 maxText.setFont(JvSwingUtils.getLabelFont());
264 this.setLayout(new BorderLayout());
265 JPanel jPanel1 = new JPanel();
266 JPanel jPanel2 = new JPanel();
267 jPanel2.setLayout(new FlowLayout());
268 jPanel1.setBackground(Color.white);
269 jPanel2.setBackground(Color.white);
270 threshold.addActionListener(new ActionListener()
273 public void actionPerformed(ActionEvent e)
275 threshold_actionPerformed(e);
278 threshold.setToolTipText(MessageManager
279 .getString("label.threshold_feature_display_by_score"));
280 threshold.addItem(MessageManager
281 .getString("label.threshold_feature_no_thereshold")); // index 0
282 threshold.addItem(MessageManager
283 .getString("label.threshold_feature_above_thereshold")); // index 1
284 threshold.addItem(MessageManager
285 .getString("label.threshold_feature_below_thereshold")); // index 2
286 JPanel jPanel3 = new JPanel();
287 jPanel3.setLayout(new FlowLayout());
288 thresholdValue.addActionListener(new ActionListener()
291 public void actionPerformed(ActionEvent e)
293 thresholdValue_actionPerformed(e);
296 slider.setPaintLabels(false);
297 slider.setPaintTicks(true);
298 slider.setBackground(Color.white);
299 slider.setEnabled(false);
300 slider.setOpaque(false);
301 slider.setPreferredSize(new Dimension(100, 32));
302 slider.setToolTipText(MessageManager
303 .getString("label.adjust_thereshold"));
304 thresholdValue.setEnabled(false);
305 thresholdValue.setColumns(7);
306 jPanel3.setBackground(Color.white);
307 thresholdIsMin.setBackground(Color.white);
308 thresholdIsMin.setText(MessageManager
309 .getString("label.threshold_minmax"));
310 thresholdIsMin.setToolTipText(MessageManager
311 .getString("label.toggle_absolute_relative_display_threshold"));
312 thresholdIsMin.addActionListener(new ActionListener()
315 public void actionPerformed(ActionEvent actionEvent)
317 thresholdIsMin_actionPerformed(actionEvent);
320 colourAlternately.setBackground(Color.white);
321 colourAlternately.setText(MessageManager
322 .getString("label.colour_alternately"));
323 colourAlternately.setToolTipText(MessageManager
324 .getString("label.colour_alternately_tip"));
325 colourAlternately.addActionListener(new ActionListener()
328 public void actionPerformed(ActionEvent actionEvent)
330 colourAlternately_actionPerformed(actionEvent);
333 colourByLabel.setBackground(Color.white);
335 .setText(MessageManager.getString("label.colour_by_label"));
337 .setToolTipText(MessageManager
338 .getString("label.display_features_same_type_different_label_using_different_colour"));
339 colourByLabel.addActionListener(new ActionListener()
342 public void actionPerformed(ActionEvent actionEvent)
344 colourByLabel_actionPerformed(actionEvent);
348 JPanel colourPanel = new JPanel();
349 colourPanel.setBackground(Color.white);
352 jPanel2.add(colourAlternately, java.awt.BorderLayout.WEST);
353 jPanel2.add(colourByLabel, java.awt.BorderLayout.CENTER);
354 jPanel2.add(colourPanel, java.awt.BorderLayout.EAST);
355 colourPanel.add(minText);
356 colourPanel.add(minColour);
357 colourPanel.add(maxText);
358 colourPanel.add(maxColour);
359 this.add(jPanel3, java.awt.BorderLayout.CENTER);
360 jPanel3.add(threshold);
362 jPanel3.add(thresholdValue);
363 jPanel3.add(thresholdIsMin);
364 this.add(jPanel1, java.awt.BorderLayout.SOUTH);
365 this.add(jPanel2, java.awt.BorderLayout.NORTH);
368 protected void colourAlternately_actionPerformed(ActionEvent actionEvent)
373 public void minColour_actionPerformed()
375 Color col = JColorChooser.showDialog(this,
376 MessageManager.getString("label.select_colour_minimum_value"),
377 minColour.getBackground());
380 minColour.setBackground(col);
381 minColour.setForeground(col);
387 public void maxColour_actionPerformed()
389 Color col = JColorChooser.showDialog(this,
390 MessageManager.getString("label.select_colour_maximum_value"),
391 maxColour.getBackground());
394 maxColour.setBackground(col);
395 maxColour.setForeground(col);
403 // Check if combobox is still adjusting
409 int aboveThreshold = AnnotationColourGradient.NO_THRESHOLD;
410 if (threshold.getSelectedIndex() == 1)
412 aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;
414 else if (threshold.getSelectedIndex() == 2)
416 aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;
419 slider.setEnabled(true);
420 thresholdValue.setEnabled(true);
423 if (cs.isColourByLabel())
425 acg = new GraduatedColor(oldminColour, oldmaxColour, min, max);
429 acg = new GraduatedColor(oldminColour = minColour.getBackground(),
430 oldmaxColour = maxColour.getBackground(), min, max);
434 if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)
436 slider.setEnabled(false);
437 thresholdValue.setEnabled(false);
438 thresholdValue.setText("");
439 thresholdIsMin.setEnabled(false);
441 else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD
442 && threshline == null)
444 // todo visual indication of feature threshold
445 threshline = new jalview.datamodel.GraphLine((max - min) / 2f,
446 "Threshold", Color.black);
449 if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
452 acg.setThresh(threshline.value);
454 float range = (max - min) * scaleFactor;
456 slider.setMinimum((int) (min * scaleFactor));
457 slider.setMaximum((int) (max * scaleFactor));
458 slider.setValue((int) (threshline.value * scaleFactor));
459 thresholdValue.setText(threshline.value + "");
460 slider.setMajorTickSpacing((int) (range / 10f));
461 slider.setEnabled(true);
462 thresholdValue.setEnabled(true);
463 thresholdIsMin.setEnabled(!colourByLabel.isSelected());
467 acg.setThreshType(aboveThreshold);
468 if (thresholdIsMin.isSelected()
469 && aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
471 acg.setAutoScaled(false);
472 if (aboveThreshold == AnnotationColourGradient.ABOVE_THRESHOLD)
474 acg = new GraduatedColor(acg, threshline.value, max);
478 acg = new GraduatedColor(acg, min, threshline.value);
483 acg.setAutoScaled(true);
485 acg.setColourByLabel(colourByLabel.isSelected());
486 acg.setColourAlternately(colourAlternately.isSelected());
487 colourByLabel.setEnabled(!colourAlternately.isSelected());
488 colourAlternately.setEnabled(!colourByLabel.isSelected());
489 if (!fr.isOrdinal(type))
491 // don't allow colour alternately if no feature numbering on features
492 colourAlternately.setEnabled(false);
494 if (acg.isColourByLabel())
496 maxColour.setEnabled(false);
497 minColour.setEnabled(false);
498 maxColour.setBackground(this.getBackground());
499 maxColour.setForeground(this.getBackground());
500 minColour.setBackground(this.getBackground());
501 minColour.setForeground(this.getBackground());
506 maxColour.setEnabled(true);
507 minColour.setEnabled(true);
508 maxColour.setBackground(oldmaxColour);
509 minColour.setBackground(oldminColour);
510 maxColour.setForeground(oldmaxColour);
511 minColour.setForeground(oldminColour);
513 fr.setColour(type, acg);
515 ap.paintAlignment(false);
519 protected void raiseClosed()
521 if (this.colourEditor != null)
523 colourEditor.actionPerformed(new ActionEvent(this, 0, "CLOSED"));
528 public void okPressed()
534 public void cancelPressed()
541 fr.setColour(type, oldcs);
542 ap.paintAlignment(false);
546 public void thresholdCheck_actionPerformed(ActionEvent e)
551 public void annotations_actionPerformed(ActionEvent e)
556 public void threshold_actionPerformed(ActionEvent e)
561 public void thresholdValue_actionPerformed(ActionEvent e)
565 float f = Float.parseFloat(thresholdValue.getText());
566 slider.setValue((int) (f * scaleFactor));
567 threshline.value = f;
568 } catch (NumberFormatException ex)
573 public void valueChanged()
575 threshline.value = slider.getValue() / scaleFactor;
576 cs.setThresh(threshline.value);
578 ap.paintAlignment(false);
581 public void thresholdIsMin_actionPerformed(ActionEvent actionEvent)
586 public void colourByLabel_actionPerformed(ActionEvent actionEvent)
591 ActionListener colourEditor = null;
593 public void addActionListener(ActionListener graduatedColorEditor)
595 if (colourEditor != null)
598 .println("IMPLEMENTATION ISSUE: overwriting action listener for FeatureColourChooser");
600 colourEditor = graduatedColorEditor;