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.api.FeatureColourI;
24 import jalview.datamodel.GraphLine;
25 import jalview.schemes.Colour;
26 import jalview.schemes.FeatureColour;
27 import jalview.util.ColorUtils;
28 import jalview.util.MessageManager;
30 import java.awt.BorderLayout;
31 import java.awt.Color;
32 import java.awt.Dimension;
33 import java.awt.FlowLayout;
34 import java.awt.event.ActionEvent;
35 import java.awt.event.ActionListener;
36 import java.awt.event.MouseAdapter;
37 import java.awt.event.MouseEvent;
39 import javax.swing.BorderFactory;
40 import javax.swing.JCheckBox;
41 import javax.swing.JColorChooser;
42 import javax.swing.JComboBox;
43 import javax.swing.JLabel;
44 import javax.swing.JPanel;
45 import javax.swing.JSlider;
46 import javax.swing.JTextField;
47 import javax.swing.border.LineBorder;
48 import javax.swing.event.ChangeEvent;
49 import javax.swing.event.ChangeListener;
51 public class FeatureColourChooser extends JalviewDialog
53 // FeatureSettings fs;
56 private FeatureColourI cs;
58 private FeatureColourI oldcs;
62 * @return the last colour setting selected by user - either oldcs (which may
63 * be a java.awt.Color) or the new GraduatedColor
65 public FeatureColourI getLastColour()
76 boolean adjusting = false;
78 final private float min;
80 final private float max;
82 final private float scaleFactor;
86 public FeatureColourChooser(FeatureRenderer frender, String type)
88 this(frender, false, type);
91 public FeatureColourChooser(FeatureRenderer frender, boolean block,
97 String title = MessageManager.formatMessage(
98 "label.graduated_color_for_params", new String[] { type });
99 initDialogFrame(this, true, block, title, 480, 185);
100 // frame.setLayer(JLayeredPane.PALETTE_LAYER);
101 // Desktop.addInternalFrame(frame, "Graduated Feature Colour for "+type,
104 slider.addChangeListener(new ChangeListener()
107 public void stateChanged(ChangeEvent evt)
111 thresholdValue.setText((slider.getValue() / scaleFactor) + "");
116 slider.addMouseListener(new MouseAdapter()
119 public void mouseReleased(MouseEvent evt)
123 ap.paintAlignment(true);
129 float mm[] = fr.getMinMax().get(type)[0];
134 * ensure scale factor allows a scaled range with
135 * 10 integer divisions ('ticks'); if we have got here,
136 * we should expect that max != min
138 scaleFactor = (max == min) ? 1f : 100f / (max - min);
140 oldcs = fr.getFeatureColours().get(type);
141 if (!oldcs.isSimpleColour())
143 if (oldcs.isAutoScaled())
146 cs = new FeatureColour((FeatureColour) oldcs, min, max);
150 cs = new FeatureColour((FeatureColour) oldcs);
155 // promote original color to a graduated color
156 Color bl = ColorUtils.getColor(oldcs.getColour());
161 // original colour becomes the maximum colour
162 cs = new FeatureColour(new Colour(Color.white), new Colour(bl),
164 cs.setColourByLabel(false);
166 minColour.setBackground(oldminColour = ColorUtils.getColor(cs
168 maxColour.setBackground(oldmaxColour = ColorUtils.getColor(cs
175 } catch (Exception ex)
178 // update the gui from threshold state
179 thresholdIsMin.setSelected(!cs.isAutoScaled());
180 colourByLabel.setSelected(cs.isColourByLabel());
181 if (cs.hasThreshold())
183 // initialise threshold slider and selector
184 threshold.setSelectedIndex(cs.isAboveThreshold() ? 1 : 2);
185 slider.setEnabled(true);
186 thresholdValue.setEnabled(true);
187 threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black);
197 private void jbInit() throws Exception
200 minColour.setFont(JvSwingUtils.getLabelFont());
201 minColour.setBorder(BorderFactory.createLineBorder(Color.black));
202 minColour.setPreferredSize(new Dimension(40, 20));
203 minColour.setToolTipText(MessageManager.getString("label.min_colour"));
204 minColour.addMouseListener(new MouseAdapter()
207 public void mousePressed(MouseEvent e)
209 if (minColour.isEnabled())
211 minColour_actionPerformed();
215 maxColour.setFont(JvSwingUtils.getLabelFont());
216 maxColour.setBorder(BorderFactory.createLineBorder(Color.black));
217 maxColour.setPreferredSize(new Dimension(40, 20));
218 maxColour.setToolTipText(MessageManager.getString("label.max_colour"));
219 maxColour.addMouseListener(new MouseAdapter()
222 public void mousePressed(MouseEvent e)
224 if (maxColour.isEnabled())
226 maxColour_actionPerformed();
230 maxColour.setBorder(new LineBorder(Color.black));
231 minText.setText(MessageManager.getString("label.min"));
232 minText.setFont(JvSwingUtils.getLabelFont());
233 maxText.setText(MessageManager.getString("label.max"));
234 maxText.setFont(JvSwingUtils.getLabelFont());
235 this.setLayout(borderLayout1);
236 jPanel2.setLayout(flowLayout1);
237 jPanel1.setBackground(Color.white);
238 jPanel2.setBackground(Color.white);
239 threshold.addActionListener(new ActionListener()
242 public void actionPerformed(ActionEvent e)
244 threshold_actionPerformed(e);
247 threshold.setToolTipText(MessageManager
248 .getString("label.threshold_feature_display_by_score"));
249 threshold.addItem(MessageManager
250 .getString("label.threshold_feature_no_thereshold")); // index 0
251 threshold.addItem(MessageManager
252 .getString("label.threshold_feature_above_thereshold")); // index 1
253 threshold.addItem(MessageManager
254 .getString("label.threshold_feature_below_thereshold")); // index 2
255 jPanel3.setLayout(flowLayout2);
256 thresholdValue.addActionListener(new ActionListener()
259 public void actionPerformed(ActionEvent e)
261 thresholdValue_actionPerformed(e);
264 slider.setPaintLabels(false);
265 slider.setPaintTicks(true);
266 slider.setBackground(Color.white);
267 slider.setEnabled(false);
268 slider.setOpaque(false);
269 slider.setPreferredSize(new Dimension(100, 32));
270 slider.setToolTipText(MessageManager
271 .getString("label.adjust_thereshold"));
272 thresholdValue.setEnabled(false);
273 thresholdValue.setColumns(7);
274 jPanel3.setBackground(Color.white);
275 thresholdIsMin.setBackground(Color.white);
276 thresholdIsMin.setText(MessageManager
277 .getString("label.threshold_minmax"));
278 thresholdIsMin.setToolTipText(MessageManager
279 .getString("label.toggle_absolute_relative_display_threshold"));
280 thresholdIsMin.addActionListener(new ActionListener()
283 public void actionPerformed(ActionEvent actionEvent)
285 thresholdIsMin_actionPerformed(actionEvent);
288 colourByLabel.setBackground(Color.white);
290 .setText(MessageManager.getString("label.colour_by_label"));
292 .setToolTipText(MessageManager
293 .getString("label.display_features_same_type_different_label_using_different_colour"));
294 colourByLabel.addActionListener(new ActionListener()
297 public void actionPerformed(ActionEvent actionEvent)
299 colourByLabel_actionPerformed(actionEvent);
302 colourPanel.setBackground(Color.white);
305 jPanel2.add(colourByLabel, java.awt.BorderLayout.WEST);
306 jPanel2.add(colourPanel, java.awt.BorderLayout.EAST);
307 colourPanel.add(minText);
308 colourPanel.add(minColour);
309 colourPanel.add(maxText);
310 colourPanel.add(maxColour);
311 this.add(jPanel3, java.awt.BorderLayout.CENTER);
312 jPanel3.add(threshold);
314 jPanel3.add(thresholdValue);
315 jPanel3.add(thresholdIsMin);
316 this.add(jPanel1, java.awt.BorderLayout.SOUTH);
317 this.add(jPanel2, java.awt.BorderLayout.NORTH);
320 JLabel minText = new JLabel();
322 JLabel maxText = new JLabel();
324 JPanel minColour = new JPanel();
326 JPanel maxColour = new JPanel();
328 JPanel colourPanel = new JPanel();
330 JPanel jPanel1 = new JPanel();
332 JPanel jPanel2 = new JPanel();
334 BorderLayout borderLayout1 = new BorderLayout();
336 JComboBox threshold = new JComboBox();
338 FlowLayout flowLayout1 = new FlowLayout();
340 JPanel jPanel3 = new JPanel();
342 FlowLayout flowLayout2 = new FlowLayout();
344 JSlider slider = new JSlider();
346 JTextField thresholdValue = new JTextField(20);
348 // TODO implement GUI for tolower flag
349 // JCheckBox toLower = new JCheckBox();
351 JCheckBox thresholdIsMin = new JCheckBox();
353 JCheckBox colourByLabel = new JCheckBox();
355 private GraphLine threshline;
357 private Color oldmaxColour;
359 private Color oldminColour;
361 public void minColour_actionPerformed()
363 Color col = JColorChooser.showDialog(this,
364 MessageManager.getString("label.select_colour_minimum_value"),
365 minColour.getBackground());
368 minColour.setBackground(col);
369 minColour.setForeground(col);
375 public void maxColour_actionPerformed()
377 Color col = JColorChooser.showDialog(this,
378 MessageManager.getString("label.select_colour_maximum_value"),
379 maxColour.getBackground());
382 maxColour.setBackground(col);
383 maxColour.setForeground(col);
391 // Check if combobox is still adjusting
397 boolean aboveThreshold = false;
398 boolean belowThreshold = false;
399 if (threshold.getSelectedIndex() == 1)
401 aboveThreshold = true;
403 else if (threshold.getSelectedIndex() == 2)
405 belowThreshold = true;
407 boolean hasThreshold = aboveThreshold || belowThreshold;
409 slider.setEnabled(true);
410 thresholdValue.setEnabled(true);
413 if (cs.isColourByLabel())
415 acg = new FeatureColour(new Colour(oldminColour), new Colour(
416 oldmaxColour), min, max);
420 acg = new FeatureColour(new Colour(
421 oldminColour = minColour.getBackground()), new Colour(
422 oldmaxColour = maxColour.getBackground()), min, max);
428 slider.setEnabled(false);
429 thresholdValue.setEnabled(false);
430 thresholdValue.setText("");
431 thresholdIsMin.setEnabled(false);
433 else if (threshline == null)
435 // todo visual indication of feature threshold
436 threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black);
442 acg.setThreshold(threshline.value);
444 float range = (max - min) * scaleFactor;
446 slider.setMinimum((int) (min * scaleFactor));
447 slider.setMaximum((int) (max * scaleFactor));
448 slider.setValue((int) (threshline.value * scaleFactor));
449 thresholdValue.setText(threshline.value + "");
450 slider.setMajorTickSpacing((int) (range / 10f));
451 slider.setEnabled(true);
452 thresholdValue.setEnabled(true);
453 thresholdIsMin.setEnabled(!colourByLabel.isSelected());
457 acg.setAboveThreshold(aboveThreshold);
458 acg.setBelowThreshold(belowThreshold);
459 if (thresholdIsMin.isSelected() && hasThreshold)
461 acg.setAutoScaled(false);
464 acg = new FeatureColour((FeatureColour) acg, threshline.value, max);
468 acg = new FeatureColour((FeatureColour) acg, min, threshline.value);
473 acg.setAutoScaled(true);
475 acg.setColourByLabel(colourByLabel.isSelected());
476 if (acg.isColourByLabel())
478 maxColour.setEnabled(false);
479 minColour.setEnabled(false);
480 maxColour.setBackground(this.getBackground());
481 maxColour.setForeground(this.getBackground());
482 minColour.setBackground(this.getBackground());
483 minColour.setForeground(this.getBackground());
488 maxColour.setEnabled(true);
489 minColour.setEnabled(true);
490 maxColour.setBackground(oldmaxColour);
491 minColour.setBackground(oldminColour);
492 maxColour.setForeground(oldmaxColour);
493 minColour.setForeground(oldminColour);
495 fr.setColour(type, acg);
497 ap.paintAlignment(false);
501 protected void raiseClosed()
503 if (this.colourEditor != null)
505 colourEditor.actionPerformed(new ActionEvent(this, 0, "CLOSED"));
510 public void okPressed()
516 public void cancelPressed()
523 fr.setColour(type, oldcs);
524 ap.paintAlignment(false);
528 public void thresholdCheck_actionPerformed(ActionEvent e)
533 public void annotations_actionPerformed(ActionEvent e)
538 public void threshold_actionPerformed(ActionEvent e)
543 public void thresholdValue_actionPerformed(ActionEvent e)
547 float f = Float.parseFloat(thresholdValue.getText());
548 slider.setValue((int) (f * scaleFactor));
549 threshline.value = f;
550 } catch (NumberFormatException ex)
555 public void valueChanged()
557 threshline.value = slider.getValue() / scaleFactor;
558 cs.setThreshold(threshline.value);
560 ap.paintAlignment(false);
563 public void thresholdIsMin_actionPerformed(ActionEvent actionEvent)
568 public void colourByLabel_actionPerformed(ActionEvent actionEvent)
573 ActionListener colourEditor = null;
575 public void addActionListener(ActionListener graduatedColorEditor)
577 if (colourEditor != null)
580 .println("IMPLEMENTATION ISSUE: overwriting action listener for FeatureColourChooser");
582 colourEditor = graduatedColorEditor;