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.
21 package jalview.appletgui;
23 import jalview.api.FeatureColourI;
24 import jalview.datamodel.GraphLine;
25 import jalview.schemes.AnnotationColourGradient;
26 import jalview.schemes.FeatureColour;
27 import jalview.util.MessageManager;
29 import java.awt.Checkbox;
30 import java.awt.Choice;
31 import java.awt.Color;
32 import java.awt.Dimension;
33 import java.awt.FlowLayout;
35 import java.awt.Frame;
36 import java.awt.GridLayout;
37 import java.awt.Label;
38 import java.awt.Panel;
39 import java.awt.Scrollbar;
40 import java.awt.TextField;
41 import java.awt.event.ActionEvent;
42 import java.awt.event.ActionListener;
43 import java.awt.event.AdjustmentEvent;
44 import java.awt.event.AdjustmentListener;
45 import java.awt.event.FocusAdapter;
46 import java.awt.event.FocusEvent;
47 import java.awt.event.ItemEvent;
48 import java.awt.event.ItemListener;
49 import java.awt.event.MouseEvent;
50 import java.awt.event.MouseListener;
52 public class FeatureColourChooser extends Panel implements ActionListener,
53 AdjustmentListener, ItemListener, MouseListener
56 * the absolute min-max range of a feature score is scaled to
57 * 1000 positions on the colour threshold slider
59 private static final int SCALE_FACTOR_1K = 1000;
61 private static final String COLON = ":";
63 private JVDialog frame;
67 private FeatureRenderer fr;
69 private FeatureSettings fs = null;
71 private FeatureColourI cs;
73 private FeatureColourI oldcs;
75 private boolean adjusting = false;
77 private float min, max;
79 private String type = null;
81 private AlignFrame af = null;
83 private Panel minColour = new Panel();
85 private Panel maxColour = new Panel();
87 private Choice threshold = new Choice();
89 private Scrollbar slider = new Scrollbar(Scrollbar.HORIZONTAL);
91 private TextField thresholdValue = new TextField(20);
93 private Checkbox thresholdIsMin = new Checkbox();
95 private Checkbox colourFromLabel = new Checkbox();
97 private GraphLine threshline;
100 * Constructor given a context AlignFrame and a feature type. This is used
101 * when opening the graduated colour dialog from the Amend Feature dialog.
106 public FeatureColourChooser(AlignFrame alignFrame, String featureType)
108 this.af = alignFrame;
109 init(alignFrame.getSeqcanvas().getFeatureRenderer(), featureType);
113 * Constructor given a context FeatureSettings and a feature type. This is
114 * used when opening the graduated colour dialog from Feature Settings.
119 public FeatureColourChooser(FeatureSettings fsettings, String featureType)
122 init(fsettings.fr, featureType);
125 private void init(FeatureRenderer frenderer, String featureType)
127 this.type = featureType;
129 float mm[] = fr.getMinMax().get(type)[0];
132 threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black);
133 oldcs = fr.getFeatureColours().get(type);
134 if (oldcs.isGraduatedColour())
136 threshline.value = oldcs.getThreshold();
137 cs = new FeatureColour(oldcs.getColour(), oldcs.getMinColour(),
138 oldcs.getMaxColour(), oldcs.getNoColour(), min, max);
142 // promote original color to a graduated color
143 Color bl = Color.black;
144 if (oldcs.isSimpleColour())
146 bl = oldcs.getColour();
148 // original colour becomes the maximum colour
149 cs = new FeatureColour(bl, Color.white, bl, Color.white, mm[0],
152 minColour.setBackground(cs.getMinColour());
153 maxColour.setBackground(cs.getMaxColour());
154 minColour.setForeground(cs.getMinColour());
155 maxColour.setForeground(cs.getMaxColour());
156 colourFromLabel.setState(cs.isColourByLabel());
162 } catch (Exception ex)
166 cs.isAboveThreshold() ? 1 : (cs.isBelowThreshold() ? 2 : 0));
170 colourFromLabel.addItemListener(this);
171 slider.addAdjustmentListener(this);
172 slider.addMouseListener(this);
173 owner = (af != null) ? af : fs.frame;
174 frame = new JVDialog(owner, MessageManager
175 .formatMessage("label.variable_color_for", new String[]
176 { type }), true, 480, 248);
177 frame.setMainPanel(this);
179 frame.setVisible(true);
188 frame.setVisible(false);
192 public FeatureColourChooser()
197 } catch (Exception ex)
199 ex.printStackTrace();
203 private void jbInit() throws Exception
205 Label minLabel = new Label(
206 MessageManager.getString("label.min_value") + COLON);
207 Label maxLabel = new Label(
208 MessageManager.getString("label.max_value") + COLON);
209 minLabel.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
210 maxLabel.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
211 // minColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
212 // minColour.setLabel("Min Colour");
214 minColour.setBounds(0, 0, 40, 27);
215 maxColour.setBounds(0, 0, 40, 27);
216 minColour.addMouseListener(this);
218 maxColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
219 maxColour.addMouseListener(this);
221 thresholdIsMin.addItemListener(this);
223 this.setLayout(new GridLayout(4, 1));
224 Panel jPanel1 = new Panel();
225 jPanel1.setLayout(new FlowLayout());
226 Panel jPanel2 = new Panel();
227 jPanel2.setLayout(new FlowLayout());
228 Panel jPanel3 = new Panel();
229 jPanel3.setLayout(new GridLayout(1, 1));
230 Panel jPanel4 = new Panel();
231 jPanel4.setLayout(new FlowLayout());
232 jPanel1.setBackground(Color.white);
233 jPanel2.setBackground(Color.white);
234 jPanel4.setBackground(Color.white);
235 threshold.addItemListener(this);
236 threshold.addItem(MessageManager
237 .getString("label.threshold_feature_no_threshold"));
238 threshold.addItem(MessageManager
239 .getString("label.threshold_feature_above_threshold"));
240 threshold.addItem(MessageManager
241 .getString("label.threshold_feature_below_threshold"));
242 thresholdValue.addActionListener(this);
243 thresholdValue.addFocusListener(new FocusAdapter()
246 public void focusLost(FocusEvent e)
248 thresholdValue_actionPerformed();
251 slider.setBackground(Color.white);
252 slider.setEnabled(false);
253 slider.setSize(new Dimension(93, 21));
254 thresholdValue.setEnabled(false);
255 thresholdValue.setSize(new Dimension(79, 22)); // setBounds(new
256 // Rectangle(248, 2, 79,
258 thresholdValue.setColumns(5);
259 jPanel3.setBackground(Color.white);
261 colourFromLabel.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
263 .setLabel(MessageManager.getString("label.colour_by_label"));
264 colourFromLabel.setSize(new Dimension(139, 22));
265 // threshold.setBounds(new Rectangle(11, 3, 139, 22));
266 thresholdIsMin.setBackground(Color.white);
268 .setLabel(MessageManager.getString("label.threshold_minmax"));
269 thresholdIsMin.setSize(new Dimension(135, 23));
270 // thresholdIsMin.setBounds(new Rectangle(328, 3, 135, 23));
271 jPanel1.add(minLabel);
272 jPanel1.add(minColour);
273 jPanel1.add(maxLabel);
274 jPanel1.add(maxColour);
275 jPanel1.add(colourFromLabel);
276 jPanel2.add(threshold);
278 jPanel4.add(thresholdValue);
279 jPanel4.add(thresholdIsMin);
280 this.add(jPanel1);// , java.awt.BorderLayout.NORTH);
281 this.add(jPanel2);// , java.awt.BorderLayout.NORTH);
282 this.add(jPanel3);// , java.awt.BorderLayout.CENTER);
283 this.add(jPanel4);// , java.awt.BorderLayout.CENTER);
287 public void actionPerformed(ActionEvent evt)
289 if (evt.getSource() == thresholdValue)
291 thresholdValue_actionPerformed();
293 else if (evt.getSource() == minColour)
295 minColour_actionPerformed(null);
297 else if (evt.getSource() == maxColour)
299 maxColour_actionPerformed(null);
308 * Action on input of a value for colour score threshold
310 protected void thresholdValue_actionPerformed()
314 float f = Float.valueOf(thresholdValue.getText()).floatValue();
315 slider.setValue((int) (f * SCALE_FACTOR_1K));
316 adjustmentValueChanged(null);
319 * force repaint of any Overview window or structure
322 } catch (NumberFormatException ex)
328 public void itemStateChanged(ItemEvent evt)
330 maxColour.setEnabled(!colourFromLabel.getState());
331 minColour.setEnabled(!colourFromLabel.getState());
336 * Handler called when the value of the threshold slider changes, either by
337 * user action or programmatically
340 public void adjustmentValueChanged(AdjustmentEvent evt)
344 thresholdValue.setText((slider.getValue() / 1000f) + "");
350 * Responds to a change of colour threshold by computing the absolute value
351 * and refreshing the alignment.
353 protected void valueChanged()
355 threshline.value = slider.getValue() / 1000f;
356 cs.setThreshold(threshline.value);
358 PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
361 public void minColour_actionPerformed(Color newCol)
365 new UserDefinedColours(this, minColour.getBackground(), owner,
367 .getString("label.select_colour_minimum_value"));
371 minColour.setBackground(newCol);
372 minColour.setForeground(newCol);
379 public void maxColour_actionPerformed(Color newCol)
383 new UserDefinedColours(this, maxColour.getBackground(), owner,
385 .getString("label.select_colour_maximum_value"));
389 maxColour.setBackground(newCol);
390 maxColour.setForeground(newCol);
396 void changeColour(boolean updateOverview)
398 // Check if combobox is still adjusting
404 int thresholdOption = AnnotationColourGradient.NO_THRESHOLD;
405 if (threshold.getSelectedIndex() == 1)
407 thresholdOption = AnnotationColourGradient.ABOVE_THRESHOLD;
409 else if (threshold.getSelectedIndex() == 2)
411 thresholdOption = AnnotationColourGradient.BELOW_THRESHOLD;
414 slider.setEnabled(true);
415 thresholdValue.setEnabled(true);
416 Color minc = minColour.getBackground();
417 Color maxc = maxColour.getBackground();
418 FeatureColour acg = new FeatureColour(maxc, minc, maxc, minc, min, max);
420 acg.setColourByLabel(colourFromLabel.getState());
421 maxColour.setEnabled(!colourFromLabel.getState());
422 minColour.setEnabled(!colourFromLabel.getState());
423 if (thresholdOption == AnnotationColourGradient.NO_THRESHOLD)
425 slider.setEnabled(false);
426 thresholdValue.setEnabled(false);
427 thresholdValue.setText("");
430 if (thresholdOption != AnnotationColourGradient.NO_THRESHOLD)
433 acg.setThreshold(threshline.value);
435 slider.setMinimum((int) (min * SCALE_FACTOR_1K));
436 slider.setMaximum((int) (max * SCALE_FACTOR_1K));
437 slider.setValue((int) (threshline.value * SCALE_FACTOR_1K));
438 thresholdValue.setText(threshline.value + "");
439 slider.setEnabled(true);
440 thresholdValue.setEnabled(true);
444 acg.setAboveThreshold(
445 thresholdOption == AnnotationColourGradient.ABOVE_THRESHOLD);
446 acg.setBelowThreshold(
447 thresholdOption == AnnotationColourGradient.BELOW_THRESHOLD);
449 if (thresholdIsMin.getState()
450 && thresholdOption != AnnotationColourGradient.NO_THRESHOLD)
452 if (thresholdOption == AnnotationColourGradient.ABOVE_THRESHOLD)
454 acg = new FeatureColour(acg.getColour(), acg.getMinColour(),
455 acg.getMaxColour(), acg.getNoColour(), threshline.value,
460 acg = new FeatureColour(acg.getColour(), acg.getMinColour(),
461 acg.getMaxColour(), acg.getNoColour(), min,
466 fr.setColour(type, acg);
468 fs.selectionChanged(updateOverview);
473 fr.setColour(type, oldcs);
474 fs.selectionChanged(true);
478 public void mouseClicked(MouseEvent evt)
483 public void mousePressed(MouseEvent evt)
488 public void mouseReleased(MouseEvent evt)
490 if (evt.getSource() == minColour)
492 minColour_actionPerformed(null);
494 else if (evt.getSource() == maxColour)
496 maxColour_actionPerformed(null);
501 // PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
506 public void mouseEntered(MouseEvent evt)
511 public void mouseExited(MouseEvent evt)