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 public FeatureColourChooser(FeatureRenderer frender, String type)
89 this(frender, false, type);
92 public FeatureColourChooser(FeatureRenderer frender, boolean block,
98 String title = MessageManager.formatMessage(
99 "label.graduated_color_for_params", new String[] { type });
100 initDialogFrame(this, true, block, title, 480, 185);
101 // frame.setLayer(JLayeredPane.PALETTE_LAYER);
102 // Desktop.addInternalFrame(frame, "Graduated Feature Colour for "+type,
105 slider.addChangeListener(new ChangeListener()
108 public void stateChanged(ChangeEvent evt)
112 thresholdValue.setText((slider.getValue() / scaleFactor) + "");
117 slider.addMouseListener(new MouseAdapter()
120 public void mouseReleased(MouseEvent evt)
124 ap.paintAlignment(true);
130 float mm[] = ((float[][]) fr.getMinMax().get(type))[0];
135 * ensure scale factor allows a scaled range with
136 * 10 integer divisions ('ticks'); if we have got here,
137 * we should expect that max != min
139 scaleFactor = (max == min) ? 1f : 100f / (max - min);
141 oldcs = fr.getFeatureColours().get(type);
142 if (oldcs instanceof GraduatedColor)
144 if (((GraduatedColor) oldcs).isAutoScale())
147 cs = new GraduatedColor((GraduatedColor) oldcs, min, max);
151 cs = new GraduatedColor((GraduatedColor) oldcs);
156 // promote original color to a graduated color
157 Color bl = Color.black;
158 if (oldcs instanceof Color)
162 // original colour becomes the maximum colour
163 cs = new GraduatedColor(Color.white, bl, mm[0], mm[1]);
164 cs.setColourByLabel(false);
166 minColour.setBackground(oldminColour = cs.getMinColor());
167 maxColour.setBackground(oldmaxColour = cs.getMaxColor());
173 } catch (Exception ex)
176 // update the gui from threshold state
177 thresholdIsMin.setSelected(!cs.isAutoScale());
178 colourByLabel.setSelected(cs.isColourByLabel());
179 if (cs.getThreshType() != AnnotationColourGradient.NO_THRESHOLD)
181 // initialise threshold slider and selector
183 .setSelectedIndex(cs.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD ? 1
185 slider.setEnabled(true);
186 thresholdValue.setEnabled(true);
187 threshline = new jalview.datamodel.GraphLine((max - min) / 2f,
188 "Threshold", Color.black);
198 private void jbInit() throws Exception
201 minColour.setFont(JvSwingUtils.getLabelFont());
202 minColour.setBorder(BorderFactory.createLineBorder(Color.black));
203 minColour.setPreferredSize(new Dimension(40, 20));
204 minColour.setToolTipText(MessageManager.getString("label.min_colour"));
205 minColour.addMouseListener(new MouseAdapter()
208 public void mousePressed(MouseEvent e)
210 if (minColour.isEnabled())
212 minColour_actionPerformed();
216 maxColour.setFont(JvSwingUtils.getLabelFont());
217 maxColour.setBorder(BorderFactory.createLineBorder(Color.black));
218 maxColour.setPreferredSize(new Dimension(40, 20));
219 maxColour.setToolTipText(MessageManager.getString("label.max_colour"));
220 maxColour.addMouseListener(new MouseAdapter()
223 public void mousePressed(MouseEvent e)
225 if (maxColour.isEnabled())
227 maxColour_actionPerformed();
231 maxColour.setBorder(new LineBorder(Color.black));
232 minText.setText(MessageManager.getString("label.min"));
233 minText.setFont(JvSwingUtils.getLabelFont());
234 maxText.setText(MessageManager.getString("label.max"));
235 maxText.setFont(JvSwingUtils.getLabelFont());
236 this.setLayout(borderLayout1);
237 jPanel2.setLayout(flowLayout1);
238 jPanel1.setBackground(Color.white);
239 jPanel2.setBackground(Color.white);
240 threshold.addActionListener(new ActionListener()
243 public void actionPerformed(ActionEvent e)
245 threshold_actionPerformed(e);
248 threshold.setToolTipText(MessageManager
249 .getString("label.threshold_feature_display_by_score"));
250 threshold.addItem(MessageManager
251 .getString("label.threshold_feature_no_thereshold")); // index 0
252 threshold.addItem(MessageManager
253 .getString("label.threshold_feature_above_thereshold")); // index 1
254 threshold.addItem(MessageManager
255 .getString("label.threshold_feature_below_thereshold")); // index 2
256 jPanel3.setLayout(flowLayout2);
257 thresholdValue.addActionListener(new ActionListener()
260 public void actionPerformed(ActionEvent e)
262 thresholdValue_actionPerformed(e);
265 slider.setPaintLabels(false);
266 slider.setPaintTicks(true);
267 slider.setBackground(Color.white);
268 slider.setEnabled(false);
269 slider.setOpaque(false);
270 slider.setPreferredSize(new Dimension(100, 32));
271 slider.setToolTipText(MessageManager
272 .getString("label.adjust_thereshold"));
273 thresholdValue.setEnabled(false);
274 thresholdValue.setColumns(7);
275 jPanel3.setBackground(Color.white);
276 thresholdIsMin.setBackground(Color.white);
277 thresholdIsMin.setText(MessageManager
278 .getString("label.threshold_minmax"));
279 thresholdIsMin.setToolTipText(MessageManager
280 .getString("label.toggle_absolute_relative_display_threshold"));
281 thresholdIsMin.addActionListener(new ActionListener()
284 public void actionPerformed(ActionEvent actionEvent)
286 thresholdIsMin_actionPerformed(actionEvent);
289 colourByLabel.setBackground(Color.white);
291 .setText(MessageManager.getString("label.colour_by_label"));
293 .setToolTipText(MessageManager
294 .getString("label.display_features_same_type_different_label_using_different_colour"));
295 colourByLabel.addActionListener(new ActionListener()
298 public void actionPerformed(ActionEvent actionEvent)
300 colourByLabel_actionPerformed(actionEvent);
303 colourPanel.setBackground(Color.white);
306 jPanel2.add(colourByLabel, java.awt.BorderLayout.WEST);
307 jPanel2.add(colourPanel, java.awt.BorderLayout.EAST);
308 colourPanel.add(minText);
309 colourPanel.add(minColour);
310 colourPanel.add(maxText);
311 colourPanel.add(maxColour);
312 this.add(jPanel3, java.awt.BorderLayout.CENTER);
313 jPanel3.add(threshold);
315 jPanel3.add(thresholdValue);
316 jPanel3.add(thresholdIsMin);
317 this.add(jPanel1, java.awt.BorderLayout.SOUTH);
318 this.add(jPanel2, java.awt.BorderLayout.NORTH);
321 JLabel minText = new JLabel();
323 JLabel maxText = new JLabel();
325 JPanel minColour = new JPanel();
327 JPanel maxColour = new JPanel();
329 JPanel colourPanel = new JPanel();
331 JPanel jPanel1 = new JPanel();
333 JPanel jPanel2 = new JPanel();
335 BorderLayout borderLayout1 = new BorderLayout();
337 JComboBox threshold = new JComboBox();
339 FlowLayout flowLayout1 = new FlowLayout();
341 JPanel jPanel3 = new JPanel();
343 FlowLayout flowLayout2 = new FlowLayout();
345 JSlider slider = new JSlider();
347 JTextField thresholdValue = new JTextField(20);
349 // TODO implement GUI for tolower flag
350 // JCheckBox toLower = new JCheckBox();
352 JCheckBox thresholdIsMin = new JCheckBox();
354 JCheckBox colourByLabel = new JCheckBox();
356 private GraphLine threshline;
358 private Color oldmaxColour;
360 private Color oldminColour;
362 public void minColour_actionPerformed()
364 Color col = JColorChooser.showDialog(this,
365 MessageManager.getString("label.select_colour_minimum_value"),
366 minColour.getBackground());
369 minColour.setBackground(col);
370 minColour.setForeground(col);
376 public void maxColour_actionPerformed()
378 Color col = JColorChooser.showDialog(this,
379 MessageManager.getString("label.select_colour_maximum_value"),
380 maxColour.getBackground());
383 maxColour.setBackground(col);
384 maxColour.setForeground(col);
392 // Check if combobox is still adjusting
398 int aboveThreshold = AnnotationColourGradient.NO_THRESHOLD;
399 if (threshold.getSelectedIndex() == 1)
401 aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;
403 else if (threshold.getSelectedIndex() == 2)
405 aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;
408 slider.setEnabled(true);
409 thresholdValue.setEnabled(true);
412 if (cs.isColourByLabel())
414 acg = new GraduatedColor(oldminColour, oldmaxColour, min, max);
418 acg = new GraduatedColor(oldminColour = minColour.getBackground(),
419 oldmaxColour = maxColour.getBackground(), min, max);
423 if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)
425 slider.setEnabled(false);
426 thresholdValue.setEnabled(false);
427 thresholdValue.setText("");
428 thresholdIsMin.setEnabled(false);
430 else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD
431 && threshline == null)
433 // todo visual indication of feature threshold
434 threshline = new jalview.datamodel.GraphLine((max - min) / 2f,
435 "Threshold", Color.black);
438 if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
441 acg.setThresh(threshline.value);
443 float range = (max - min) * scaleFactor;
445 slider.setMinimum((int) (min * scaleFactor));
446 slider.setMaximum((int) (max * scaleFactor));
447 slider.setValue((int) (threshline.value * scaleFactor));
448 thresholdValue.setText(threshline.value + "");
449 slider.setMajorTickSpacing((int) (range / 10f));
450 slider.setEnabled(true);
451 thresholdValue.setEnabled(true);
452 thresholdIsMin.setEnabled(!colourByLabel.isSelected());
456 acg.setThreshType(aboveThreshold);
457 if (thresholdIsMin.isSelected()
458 && aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
460 acg.setAutoScaled(false);
461 if (aboveThreshold == AnnotationColourGradient.ABOVE_THRESHOLD)
463 acg = new GraduatedColor(acg, threshline.value, max);
467 acg = new GraduatedColor(acg, min, threshline.value);
472 acg.setAutoScaled(true);
474 acg.setColourByLabel(colourByLabel.isSelected());
475 if (acg.isColourByLabel())
477 maxColour.setEnabled(false);
478 minColour.setEnabled(false);
479 maxColour.setBackground(this.getBackground());
480 maxColour.setForeground(this.getBackground());
481 minColour.setBackground(this.getBackground());
482 minColour.setForeground(this.getBackground());
487 maxColour.setEnabled(true);
488 minColour.setEnabled(true);
489 maxColour.setBackground(oldmaxColour);
490 minColour.setBackground(oldminColour);
491 maxColour.setForeground(oldmaxColour);
492 minColour.setForeground(oldminColour);
494 fr.setColour(type, acg);
496 ap.paintAlignment(false);
500 protected void raiseClosed()
502 if (this.colourEditor != null)
504 colourEditor.actionPerformed(new ActionEvent(this, 0, "CLOSED"));
509 public void okPressed()
515 public void cancelPressed()
522 fr.setColour(type, oldcs);
523 ap.paintAlignment(false);
527 public void thresholdCheck_actionPerformed(ActionEvent e)
532 public void annotations_actionPerformed(ActionEvent e)
537 public void threshold_actionPerformed(ActionEvent e)
542 public void thresholdValue_actionPerformed(ActionEvent e)
546 float f = Float.parseFloat(thresholdValue.getText());
547 slider.setValue((int) (f * scaleFactor));
548 threshline.value = f;
549 } catch (NumberFormatException ex)
554 public void valueChanged()
556 threshline.value = slider.getValue() / scaleFactor;
557 cs.setThresh(threshline.value);
559 ap.paintAlignment(false);
562 public void thresholdIsMin_actionPerformed(ActionEvent actionEvent)
567 public void colourByLabel_actionPerformed(ActionEvent actionEvent)
572 ActionListener colourEditor = null;
574 public void addActionListener(ActionListener graduatedColorEditor)
576 if (colourEditor != null)
579 .println("IMPLEMENTATION ISSUE: overwriting action listener for FeatureColourChooser");
581 colourEditor = graduatedColorEditor;