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.FeatureColour;
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;
37 import javax.swing.BorderFactory;
38 import javax.swing.JCheckBox;
39 import javax.swing.JColorChooser;
40 import javax.swing.JComboBox;
41 import javax.swing.JLabel;
42 import javax.swing.JPanel;
43 import javax.swing.JSlider;
44 import javax.swing.JTextField;
45 import javax.swing.border.LineBorder;
46 import javax.swing.event.ChangeEvent;
47 import javax.swing.event.ChangeListener;
49 public class FeatureColourChooser extends JalviewDialog
51 // FeatureSettings fs;
54 private FeatureColourI cs;
56 private FeatureColourI oldcs;
60 * @return the last colour setting selected by user - either oldcs (which may
61 * be a java.awt.Color) or the new GraduatedColor
63 public FeatureColourI getLastColour()
74 boolean adjusting = false;
76 final private float min;
78 final private float max;
80 final private float scaleFactor;
84 public FeatureColourChooser(FeatureRenderer frender, String type)
86 this(frender, false, type);
89 public FeatureColourChooser(FeatureRenderer frender, boolean block,
95 String title = MessageManager.formatMessage(
96 "label.graduated_color_for_params", new String[] { type });
97 initDialogFrame(this, true, block, title, 480, 185);
98 // frame.setLayer(JLayeredPane.PALETTE_LAYER);
99 // Desktop.addInternalFrame(frame, "Graduated Feature Colour for "+type,
102 slider.addChangeListener(new ChangeListener()
105 public void stateChanged(ChangeEvent evt)
109 thresholdValue.setText((slider.getValue() / scaleFactor) + "");
114 slider.addMouseListener(new MouseAdapter()
117 public void mouseReleased(MouseEvent evt)
121 ap.paintAlignment(true);
127 float mm[] = fr.getMinMax().get(type)[0];
132 * ensure scale factor allows a scaled range with
133 * 10 integer divisions ('ticks'); if we have got here,
134 * we should expect that max != min
136 scaleFactor = (max == min) ? 1f : 100f / (max - min);
138 oldcs = fr.getFeatureColours().get(type);
139 if (!oldcs.isSimpleColour())
141 if (oldcs.isAutoScaled())
144 cs = new FeatureColour((FeatureColour) oldcs, min, max);
148 cs = new FeatureColour((FeatureColour) oldcs);
153 // promote original color to a graduated color
154 Color bl = oldcs.getColour();
159 // original colour becomes the maximum colour
160 cs = new FeatureColour(Color.white, bl, mm[0], mm[1]);
161 cs.setColourByLabel(false);
163 minColour.setBackground(oldminColour = cs.getMinColour());
164 maxColour.setBackground(oldmaxColour = cs.getMaxColour());
170 } catch (Exception ex)
173 // update the gui from threshold state
174 thresholdIsMin.setSelected(!cs.isAutoScaled());
175 colourByLabel.setSelected(cs.isColourByLabel());
176 if (cs.hasThreshold())
178 // initialise threshold slider and selector
179 threshold.setSelectedIndex(cs.isAboveThreshold() ? 1 : 2);
180 slider.setEnabled(true);
181 slider.setValue((int) (cs.getThreshold() * scaleFactor));
182 thresholdValue.setEnabled(true);
183 threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black);
184 threshline.value = cs.getThreshold();
193 private void jbInit() throws Exception
196 minColour.setFont(JvSwingUtils.getLabelFont());
197 minColour.setBorder(BorderFactory.createLineBorder(Color.black));
198 minColour.setPreferredSize(new Dimension(40, 20));
199 minColour.setToolTipText(MessageManager.getString("label.min_colour"));
200 minColour.addMouseListener(new MouseAdapter()
203 public void mousePressed(MouseEvent e)
205 if (minColour.isEnabled())
207 minColour_actionPerformed();
211 maxColour.setFont(JvSwingUtils.getLabelFont());
212 maxColour.setBorder(BorderFactory.createLineBorder(Color.black));
213 maxColour.setPreferredSize(new Dimension(40, 20));
214 maxColour.setToolTipText(MessageManager.getString("label.max_colour"));
215 maxColour.addMouseListener(new MouseAdapter()
218 public void mousePressed(MouseEvent e)
220 if (maxColour.isEnabled())
222 maxColour_actionPerformed();
226 maxColour.setBorder(new LineBorder(Color.black));
227 minText.setText(MessageManager.getString("label.min"));
228 minText.setFont(JvSwingUtils.getLabelFont());
229 maxText.setText(MessageManager.getString("label.max"));
230 maxText.setFont(JvSwingUtils.getLabelFont());
231 this.setLayout(borderLayout1);
232 jPanel2.setLayout(flowLayout1);
233 jPanel1.setBackground(Color.white);
234 jPanel2.setBackground(Color.white);
235 threshold.addActionListener(new ActionListener()
238 public void actionPerformed(ActionEvent e)
240 threshold_actionPerformed(e);
243 threshold.setToolTipText(MessageManager
244 .getString("label.threshold_feature_display_by_score"));
245 threshold.addItem(MessageManager
246 .getString("label.threshold_feature_no_threshold")); // index 0
247 threshold.addItem(MessageManager
248 .getString("label.threshold_feature_above_threshold")); // index 1
249 threshold.addItem(MessageManager
250 .getString("label.threshold_feature_below_threshold")); // index 2
251 jPanel3.setLayout(flowLayout2);
252 thresholdValue.addActionListener(new ActionListener()
255 public void actionPerformed(ActionEvent e)
257 thresholdValue_actionPerformed(e);
260 slider.setPaintLabels(false);
261 slider.setPaintTicks(true);
262 slider.setBackground(Color.white);
263 slider.setEnabled(false);
264 slider.setOpaque(false);
265 slider.setPreferredSize(new Dimension(100, 32));
266 slider.setToolTipText(MessageManager
267 .getString("label.adjust_threshold"));
268 thresholdValue.setEnabled(false);
269 thresholdValue.setColumns(7);
270 jPanel3.setBackground(Color.white);
271 thresholdIsMin.setBackground(Color.white);
272 thresholdIsMin.setText(MessageManager
273 .getString("label.threshold_minmax"));
274 thresholdIsMin.setToolTipText(MessageManager
275 .getString("label.toggle_absolute_relative_display_threshold"));
276 thresholdIsMin.addActionListener(new ActionListener()
279 public void actionPerformed(ActionEvent actionEvent)
281 thresholdIsMin_actionPerformed(actionEvent);
284 colourByLabel.setBackground(Color.white);
286 .setText(MessageManager.getString("label.colour_by_label"));
288 .setToolTipText(MessageManager
289 .getString("label.display_features_same_type_different_label_using_different_colour"));
290 colourByLabel.addActionListener(new ActionListener()
293 public void actionPerformed(ActionEvent actionEvent)
295 colourByLabel_actionPerformed(actionEvent);
298 colourPanel.setBackground(Color.white);
301 jPanel2.add(colourByLabel, java.awt.BorderLayout.WEST);
302 jPanel2.add(colourPanel, java.awt.BorderLayout.EAST);
303 colourPanel.add(minText);
304 colourPanel.add(minColour);
305 colourPanel.add(maxText);
306 colourPanel.add(maxColour);
307 this.add(jPanel3, java.awt.BorderLayout.CENTER);
308 jPanel3.add(threshold);
310 jPanel3.add(thresholdValue);
311 jPanel3.add(thresholdIsMin);
312 this.add(jPanel1, java.awt.BorderLayout.SOUTH);
313 this.add(jPanel2, java.awt.BorderLayout.NORTH);
316 JLabel minText = new JLabel();
318 JLabel maxText = new JLabel();
320 JPanel minColour = new JPanel();
322 JPanel maxColour = new JPanel();
324 JPanel colourPanel = new JPanel();
326 JPanel jPanel1 = new JPanel();
328 JPanel jPanel2 = new JPanel();
330 BorderLayout borderLayout1 = new BorderLayout();
332 JComboBox threshold = new JComboBox();
334 FlowLayout flowLayout1 = new FlowLayout();
336 JPanel jPanel3 = new JPanel();
338 FlowLayout flowLayout2 = new FlowLayout();
340 JSlider slider = new JSlider();
342 JTextField thresholdValue = new JTextField(20);
344 // TODO implement GUI for tolower flag
345 // JCheckBox toLower = new JCheckBox();
347 JCheckBox thresholdIsMin = new JCheckBox();
349 JCheckBox colourByLabel = new JCheckBox();
351 private GraphLine threshline;
353 private Color oldmaxColour;
355 private Color oldminColour;
357 public void minColour_actionPerformed()
359 Color col = JColorChooser.showDialog(this,
360 MessageManager.getString("label.select_colour_minimum_value"),
361 minColour.getBackground());
364 minColour.setBackground(col);
365 minColour.setForeground(col);
371 public void maxColour_actionPerformed()
373 Color col = JColorChooser.showDialog(this,
374 MessageManager.getString("label.select_colour_maximum_value"),
375 maxColour.getBackground());
378 maxColour.setBackground(col);
379 maxColour.setForeground(col);
387 // Check if combobox is still adjusting
393 boolean aboveThreshold = false;
394 boolean belowThreshold = false;
395 if (threshold.getSelectedIndex() == 1)
397 aboveThreshold = true;
399 else if (threshold.getSelectedIndex() == 2)
401 belowThreshold = true;
403 boolean hasThreshold = aboveThreshold || belowThreshold;
405 slider.setEnabled(true);
406 thresholdValue.setEnabled(true);
409 if (cs.isColourByLabel())
411 acg = new FeatureColour(oldminColour, oldmaxColour, min, max);
415 acg = new FeatureColour(oldminColour = minColour.getBackground(),
416 oldmaxColour = maxColour.getBackground(), min, max);
422 slider.setEnabled(false);
423 thresholdValue.setEnabled(false);
424 thresholdValue.setText("");
425 thresholdIsMin.setEnabled(false);
427 else if (threshline == null)
429 // todo visual indication of feature threshold
430 threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black);
436 acg.setThreshold(threshline.value);
438 float range = (max - min) * scaleFactor;
440 slider.setMinimum((int) (min * scaleFactor));
441 slider.setMaximum((int) (max * scaleFactor));
442 slider.setValue((int) (threshline.value * scaleFactor));
443 thresholdValue.setText(threshline.value + "");
444 slider.setMajorTickSpacing((int) (range / 10f));
445 slider.setEnabled(true);
446 thresholdValue.setEnabled(true);
447 thresholdIsMin.setEnabled(!colourByLabel.isSelected());
451 acg.setAboveThreshold(aboveThreshold);
452 acg.setBelowThreshold(belowThreshold);
453 if (thresholdIsMin.isSelected() && hasThreshold)
455 acg.setAutoScaled(false);
458 acg = new FeatureColour((FeatureColour) acg, threshline.value, max);
462 acg = new FeatureColour((FeatureColour) acg, min, threshline.value);
467 acg.setAutoScaled(true);
469 acg.setColourByLabel(colourByLabel.isSelected());
470 if (acg.isColourByLabel())
472 maxColour.setEnabled(false);
473 minColour.setEnabled(false);
474 maxColour.setBackground(this.getBackground());
475 maxColour.setForeground(this.getBackground());
476 minColour.setBackground(this.getBackground());
477 minColour.setForeground(this.getBackground());
482 maxColour.setEnabled(true);
483 minColour.setEnabled(true);
484 maxColour.setBackground(oldmaxColour);
485 minColour.setBackground(oldminColour);
486 maxColour.setForeground(oldmaxColour);
487 minColour.setForeground(oldminColour);
489 fr.setColour(type, acg);
491 ap.paintAlignment(false);
495 protected void raiseClosed()
497 if (this.colourEditor != null)
499 colourEditor.actionPerformed(new ActionEvent(this, 0, "CLOSED"));
504 public void okPressed()
510 public void cancelPressed()
517 fr.setColour(type, oldcs);
518 ap.paintAlignment(false);
522 public void thresholdCheck_actionPerformed(ActionEvent e)
527 public void annotations_actionPerformed(ActionEvent e)
532 public void threshold_actionPerformed(ActionEvent e)
537 public void thresholdValue_actionPerformed(ActionEvent e)
541 float f = Float.parseFloat(thresholdValue.getText());
542 slider.setValue((int) (f * scaleFactor));
543 threshline.value = f;
544 } catch (NumberFormatException ex)
549 public void valueChanged()
551 threshline.value = slider.getValue() / scaleFactor;
552 cs.setThreshold(threshline.value);
554 ap.paintAlignment(false);
557 public void thresholdIsMin_actionPerformed(ActionEvent actionEvent)
562 public void colourByLabel_actionPerformed(ActionEvent actionEvent)
567 ActionListener colourEditor = null;
569 public void addActionListener(ActionListener graduatedColorEditor)
571 if (colourEditor != null)
574 .println("IMPLEMENTATION ISSUE: overwriting action listener for FeatureColourChooser");
576 colourEditor = graduatedColorEditor;