Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
SliderPanel | 47 | 165 | 72 |
1 | /* | |
2 | * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$) | |
3 | * Copyright (C) $$Year-Rel$$ The Jalview Authors | |
4 | * | |
5 | * This file is part of Jalview. | |
6 | * | |
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. | |
11 | * | |
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. | |
16 | * | |
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. | |
20 | */ | |
21 | package jalview.gui; | |
22 | ||
23 | import java.awt.event.MouseAdapter; | |
24 | import java.awt.event.MouseEvent; | |
25 | import java.beans.PropertyVetoException; | |
26 | import java.util.List; | |
27 | ||
28 | import javax.swing.JInternalFrame; | |
29 | import javax.swing.JLayeredPane; | |
30 | import javax.swing.event.ChangeEvent; | |
31 | import javax.swing.event.ChangeListener; | |
32 | import javax.swing.event.InternalFrameAdapter; | |
33 | import javax.swing.event.InternalFrameEvent; | |
34 | ||
35 | import jalview.analysis.Conservation; | |
36 | import jalview.datamodel.SequenceGroup; | |
37 | import jalview.jbgui.GSliderPanel; | |
38 | import jalview.renderer.ResidueShaderI; | |
39 | import jalview.util.MessageManager; | |
40 | ||
41 | /** | |
42 | * DOCUMENT ME! | |
43 | * | |
44 | * @author $author$ | |
45 | * @version $Revision$ | |
46 | */ | |
47 | public class SliderPanel extends GSliderPanel | |
48 | { | |
49 | private static final String BACKGROUND = "Background"; | |
50 | ||
51 | static JInternalFrame conservationSlider; | |
52 | ||
53 | static JInternalFrame consensusSecondaryStructureSlider; | |
54 | ||
55 | static JInternalFrame PIDSlider; | |
56 | ||
57 | AlignmentPanel ap; | |
58 | ||
59 | boolean forConservation = true; | |
60 | ||
61 | boolean forConsensusSecondaryStructure = false; | |
62 | ||
63 | ResidueShaderI cs; | |
64 | ||
65 | /** | |
66 | * Returns the currently displayed slider panel (or null if none). | |
67 | * | |
68 | * @return | |
69 | */ | |
70 | 19 | public static SliderPanel getSliderPanel() |
71 | { | |
72 | 19 | if (conservationSlider != null && conservationSlider.isVisible()) |
73 | { | |
74 | 10 | return (SliderPanel) conservationSlider.getContentPane(); |
75 | } | |
76 | 9 | if (PIDSlider != null && PIDSlider.isVisible()) |
77 | { | |
78 | 9 | return (SliderPanel) PIDSlider.getContentPane(); |
79 | } | |
80 | 0 | if (consensusSecondaryStructureSlider != null |
81 | && consensusSecondaryStructureSlider.isVisible()) | |
82 | { | |
83 | 0 | return (SliderPanel) consensusSecondaryStructureSlider |
84 | .getContentPane(); | |
85 | } | |
86 | 0 | return null; |
87 | } | |
88 | ||
89 | /** | |
90 | * Creates a new SliderPanel object. | |
91 | * | |
92 | * @param ap | |
93 | * DOCUMENT ME! | |
94 | * @param value | |
95 | * DOCUMENT ME! | |
96 | * @param forConserve | |
97 | * DOCUMENT ME! | |
98 | * @param scheme | |
99 | * DOCUMENT ME! | |
100 | */ | |
101 | 17 | public SliderPanel(final AlignmentPanel ap, int value, |
102 | boolean forConserve, boolean forConsensusSS, | |
103 | ResidueShaderI scheme) | |
104 | { | |
105 | 17 | this.ap = ap; |
106 | 17 | this.cs = scheme; |
107 | 17 | forConservation = forConserve; |
108 | 17 | forConsensusSecondaryStructure = forConsensusSS; |
109 | ||
110 | 17 | undoButton.setVisible(false); |
111 | 17 | applyButton.setVisible(false); |
112 | ||
113 | 17 | if (forConservation) |
114 | { | |
115 | 7 | label.setText(MessageManager.getString( |
116 | "label.enter_value_increase_conservation_visibility")); | |
117 | 7 | slider.setMinimum(0); |
118 | 7 | slider.setMaximum(100); |
119 | } | |
120 | 17 | if (forConsensusSS) |
121 | { | |
122 | 0 | label.setText(MessageManager.getString( |
123 | "label.enter_value_increase_conservation_visibility")); | |
124 | 0 | slider.setMinimum(0); |
125 | 0 | slider.setMaximum(100); |
126 | } | |
127 | else | |
128 | { | |
129 | 17 | label.setText(MessageManager.getString( |
130 | "label.enter_percentage_identity_above_which_colour_residues")); | |
131 | 17 | slider.setMinimum(0); |
132 | 17 | slider.setMaximum(100); |
133 | } | |
134 | ||
135 | 17 | slider.addChangeListener(new ChangeListener() |
136 | { | |
137 | 17 | @Override |
138 | public void stateChanged(ChangeEvent evt) | |
139 | { | |
140 | 17 | valueField.setText(String.valueOf(slider.getValue())); |
141 | 17 | valueChanged(slider.getValue()); |
142 | } | |
143 | }); | |
144 | ||
145 | 17 | slider.addMouseListener(new MouseAdapter() |
146 | { | |
147 | 0 | @Override |
148 | public void mouseReleased(MouseEvent evt) | |
149 | { | |
150 | 0 | ap.paintAlignment(true, true); |
151 | } | |
152 | }); | |
153 | ||
154 | 17 | slider.setValue(value); |
155 | 17 | valueField.setText(String.valueOf(value)); |
156 | } | |
157 | ||
158 | /** | |
159 | * Method to 'set focus' of the Conservation slider panel | |
160 | * | |
161 | * @param ap | |
162 | * the panel to repaint on change of slider | |
163 | * @param rs | |
164 | * the colour scheme to update on change of slider | |
165 | * @param source | |
166 | * a text description for the panel's title | |
167 | * | |
168 | * @return | |
169 | */ | |
170 | 11 | public static int setConservationSlider(AlignmentPanel ap, |
171 | ResidueShaderI rs, String source) | |
172 | { | |
173 | 11 | SliderPanel sliderPanel = null; |
174 | ||
175 | 11 | if (conservationSlider == null) |
176 | { | |
177 | 7 | sliderPanel = new SliderPanel(ap, rs.getConservationInc(), true, |
178 | false, rs); | |
179 | 7 | conservationSlider = new JInternalFrame(); |
180 | 7 | conservationSlider.setFrameIcon(null); |
181 | 7 | conservationSlider.setContentPane(sliderPanel); |
182 | 7 | conservationSlider.setLayer(JLayeredPane.PALETTE_LAYER); |
183 | } | |
184 | else | |
185 | { | |
186 | 4 | sliderPanel = (SliderPanel) conservationSlider.getContentPane(); |
187 | 4 | sliderPanel.valueField |
188 | .setText(String.valueOf(rs.getConservationInc())); | |
189 | 4 | sliderPanel.cs = rs; |
190 | 4 | sliderPanel.ap = ap; |
191 | 4 | sliderPanel.slider.setValue(rs.getConservationInc()); |
192 | } | |
193 | ||
194 | 11 | conservationSlider.setTitle(MessageManager.formatMessage( |
195 | "label.conservation_colour_increment", new String[] | |
196 | 11 | { source == null ? BACKGROUND : source })); |
197 | ||
198 | 11 | List<SequenceGroup> groups = ap.av.getAlignment().getGroups(); |
199 | 11 | if (groups != null && !groups.isEmpty()) |
200 | { | |
201 | 6 | sliderPanel.setAllGroupsCheckEnabled(true); |
202 | 6 | sliderPanel.allGroupsCheck |
203 | .setSelected(ap.av.getColourAppliesToAllGroups()); | |
204 | } | |
205 | else | |
206 | { | |
207 | 5 | sliderPanel.setAllGroupsCheckEnabled(false); |
208 | } | |
209 | ||
210 | 11 | return sliderPanel.getValue(); |
211 | } | |
212 | ||
213 | /** | |
214 | * Hides the PID slider panel if it is shown | |
215 | */ | |
216 | 170 | public static void hidePIDSlider() |
217 | { | |
218 | 170 | if (PIDSlider != null) |
219 | { | |
220 | 8 | try |
221 | { | |
222 | 8 | PIDSlider.setClosed(true); |
223 | 8 | PIDSlider = null; |
224 | } catch (PropertyVetoException ex) | |
225 | { | |
226 | } | |
227 | } | |
228 | } | |
229 | ||
230 | /** | |
231 | * Hides the conservation slider panel if it is shown | |
232 | */ | |
233 | 169 | public static void hideConservationSlider() |
234 | { | |
235 | 169 | if (conservationSlider != null) |
236 | { | |
237 | 6 | try |
238 | { | |
239 | 6 | conservationSlider.setClosed(true); |
240 | 6 | conservationSlider = null; |
241 | } catch (PropertyVetoException ex) | |
242 | { | |
243 | } | |
244 | } | |
245 | } | |
246 | ||
247 | /** | |
248 | * DOCUMENT ME! | |
249 | */ | |
250 | 9 | public static void showConservationSlider() |
251 | { | |
252 | 9 | hidePIDSlider(); |
253 | ||
254 | 9 | if (!conservationSlider.isVisible()) |
255 | { | |
256 | 7 | Desktop.addInternalFrame(conservationSlider, |
257 | conservationSlider.getTitle(), true, FRAME_WIDTH, | |
258 | FRAME_HEIGHT, false, true); | |
259 | 7 | conservationSlider.addInternalFrameListener(new InternalFrameAdapter() |
260 | { | |
261 | 7 | @Override |
262 | public void internalFrameClosed(InternalFrameEvent e) | |
263 | { | |
264 | 7 | conservationSlider = null; |
265 | } | |
266 | }); | |
267 | 7 | conservationSlider.setLayer(JLayeredPane.PALETTE_LAYER); |
268 | } | |
269 | } | |
270 | ||
271 | 0 | public static int setConsensusSecondaryStructureSlider(AlignmentPanel ap, |
272 | ResidueShaderI rs, String source) | |
273 | { | |
274 | 0 | SliderPanel sliderPanel = null; |
275 | ||
276 | 0 | if (consensusSecondaryStructureSlider == null) |
277 | { | |
278 | 0 | sliderPanel = new SliderPanel(ap, |
279 | rs.getConsensusSecondaryStructureThreshold(), false, true, | |
280 | rs); | |
281 | 0 | consensusSecondaryStructureSlider = new JInternalFrame(); |
282 | 0 | consensusSecondaryStructureSlider.setFrameIcon(null); |
283 | 0 | consensusSecondaryStructureSlider.setContentPane(sliderPanel); |
284 | 0 | consensusSecondaryStructureSlider |
285 | .setLayer(JLayeredPane.PALETTE_LAYER); | |
286 | } | |
287 | else | |
288 | { | |
289 | 0 | sliderPanel = (SliderPanel) consensusSecondaryStructureSlider |
290 | .getContentPane(); | |
291 | 0 | sliderPanel.valueField.setText( |
292 | String.valueOf(rs.getConsensusSecondaryStructureThreshold())); | |
293 | 0 | sliderPanel.cs = rs; |
294 | 0 | sliderPanel.ap = ap; |
295 | 0 | sliderPanel.slider |
296 | .setValue(rs.getConsensusSecondaryStructureThreshold()); | |
297 | } | |
298 | ||
299 | 0 | consensusSecondaryStructureSlider.setTitle(MessageManager.formatMessage( |
300 | "label.secondary_structure_conservation_threshold", new String[] | |
301 | 0 | { source == null ? BACKGROUND : source })); |
302 | ||
303 | 0 | List<SequenceGroup> groups = ap.av.getAlignment().getGroups(); |
304 | 0 | if (groups != null && !groups.isEmpty()) |
305 | { | |
306 | 0 | sliderPanel.setAllGroupsCheckEnabled(true); |
307 | 0 | sliderPanel.allGroupsCheck |
308 | .setSelected(ap.av.getColourAppliesToAllGroups()); | |
309 | } | |
310 | else | |
311 | { | |
312 | 0 | sliderPanel.setAllGroupsCheckEnabled(false); |
313 | } | |
314 | ||
315 | 0 | return sliderPanel.getValue(); |
316 | } | |
317 | ||
318 | 160 | public static void hideConsensusSecondaryStructureSlider() |
319 | { | |
320 | 160 | if (consensusSecondaryStructureSlider != null) |
321 | { | |
322 | 0 | try |
323 | { | |
324 | 0 | consensusSecondaryStructureSlider.setClosed(true); |
325 | 0 | consensusSecondaryStructureSlider = null; |
326 | } catch (PropertyVetoException ex) | |
327 | { | |
328 | } | |
329 | } | |
330 | } | |
331 | ||
332 | 0 | public static void showConsensusSecondaryStructureSlider() |
333 | { | |
334 | 0 | hidePIDSlider(); |
335 | 0 | hideConservationSlider(); |
336 | ||
337 | 0 | if (!consensusSecondaryStructureSlider.isVisible()) |
338 | { | |
339 | 0 | Desktop.addInternalFrame(consensusSecondaryStructureSlider, |
340 | consensusSecondaryStructureSlider.getTitle(), true, | |
341 | FRAME_WIDTH, FRAME_HEIGHT, false, true); | |
342 | 0 | consensusSecondaryStructureSlider |
343 | .addInternalFrameListener(new InternalFrameAdapter() | |
344 | { | |
345 | 0 | @Override |
346 | public void internalFrameClosed(InternalFrameEvent e) | |
347 | { | |
348 | 0 | consensusSecondaryStructureSlider = null; |
349 | } | |
350 | }); | |
351 | 0 | consensusSecondaryStructureSlider |
352 | .setLayer(JLayeredPane.PALETTE_LAYER); | |
353 | } | |
354 | } | |
355 | ||
356 | /** | |
357 | * Method to 'set focus' of the PID slider panel | |
358 | * | |
359 | * @param ap | |
360 | * the panel to repaint on change of slider | |
361 | * @param rs | |
362 | * the colour scheme to update on change of slider | |
363 | * @param source | |
364 | * a text description for the panel's title | |
365 | * | |
366 | * @return | |
367 | */ | |
368 | 11 | public static int setPIDSliderSource(AlignmentPanel ap, ResidueShaderI rs, |
369 | String source) | |
370 | { | |
371 | 11 | int threshold = rs.getThreshold(); |
372 | ||
373 | 11 | SliderPanel sliderPanel = null; |
374 | ||
375 | 11 | if (PIDSlider == null) |
376 | { | |
377 | 10 | sliderPanel = new SliderPanel(ap, threshold, false, false, rs); |
378 | 10 | PIDSlider = new JInternalFrame(); |
379 | 10 | PIDSlider.setFrameIcon(null); |
380 | 10 | PIDSlider.setContentPane(sliderPanel); |
381 | 10 | PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER); |
382 | } | |
383 | else | |
384 | { | |
385 | 1 | sliderPanel = (SliderPanel) PIDSlider.getContentPane(); |
386 | 1 | sliderPanel.cs = rs; |
387 | 1 | sliderPanel.ap = ap; |
388 | 1 | sliderPanel.valueField.setText(String.valueOf(rs.getThreshold())); |
389 | 1 | sliderPanel.slider.setValue(rs.getThreshold()); |
390 | } | |
391 | ||
392 | 11 | PIDSlider.setTitle(MessageManager.formatMessage( |
393 | "label.percentage_identity_threshold", new String[] | |
394 | 11 | { source == null ? BACKGROUND : source })); |
395 | ||
396 | 11 | if (ap.av.getAlignment().getGroups() != null) |
397 | { | |
398 | 11 | sliderPanel.setAllGroupsCheckEnabled(true); |
399 | } | |
400 | else | |
401 | { | |
402 | 0 | sliderPanel.setAllGroupsCheckEnabled(false); |
403 | } | |
404 | ||
405 | 11 | return sliderPanel.getValue(); |
406 | } | |
407 | ||
408 | /** | |
409 | * DOCUMENT ME! | |
410 | * | |
411 | * @return | |
412 | */ | |
413 | 9 | public static JInternalFrame showPIDSlider() |
414 | { | |
415 | 9 | hideConservationSlider(); |
416 | ||
417 | 9 | if (!PIDSlider.isVisible()) |
418 | { | |
419 | 9 | Desktop.addInternalFrame(PIDSlider, PIDSlider.getTitle(), true, |
420 | FRAME_WIDTH, FRAME_HEIGHT, false, true); | |
421 | 9 | PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER); |
422 | 9 | PIDSlider.addInternalFrameListener(new InternalFrameAdapter() |
423 | { | |
424 | 9 | @Override |
425 | public void internalFrameClosed(InternalFrameEvent e) | |
426 | { | |
427 | 9 | PIDSlider = null; |
428 | } | |
429 | }); | |
430 | 9 | PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER); |
431 | } | |
432 | 9 | return PIDSlider; |
433 | } | |
434 | ||
435 | /** | |
436 | * Updates the colour scheme with the current (identity threshold or | |
437 | * conservation) percentage value. Also updates all groups if 'apply to all | |
438 | * groups' is selected. | |
439 | * | |
440 | * @param percent | |
441 | */ | |
442 | 37 | public void valueChanged(int percent) |
443 | { | |
444 | 37 | if (!forConservation && !forConsensusSecondaryStructure) |
445 | { | |
446 | 21 | ap.av.setThreshold(percent); |
447 | } | |
448 | 37 | updateColourScheme(percent, cs, null); |
449 | ||
450 | 37 | if (allGroupsCheck.isSelected()) |
451 | { | |
452 | 2 | List<SequenceGroup> groups = ap.av.getAlignment().getGroups(); |
453 | 2 | for (SequenceGroup sg : groups) |
454 | { | |
455 | 2 | updateColourScheme(percent, sg.getGroupColourScheme(), sg); |
456 | } | |
457 | } | |
458 | ||
459 | 37 | ap.getSeqPanel().seqCanvas.repaint(); |
460 | } | |
461 | ||
462 | /** | |
463 | * Updates the colour scheme (if not null) with the current (identity | |
464 | * threshold or conservation) percentage value | |
465 | * | |
466 | * @param percent | |
467 | * @param scheme | |
468 | * @param sg | |
469 | */ | |
470 | 39 | protected void updateColourScheme(int percent, ResidueShaderI scheme, |
471 | SequenceGroup sg) | |
472 | { | |
473 | 39 | if (scheme == null) |
474 | { | |
475 | 0 | return; |
476 | } | |
477 | 39 | if (forConservation) |
478 | { | |
479 | 18 | if (!scheme.conservationApplied() && sg != null) |
480 | { | |
481 | /* | |
482 | * first time the colour scheme has had Conservation shading applied | |
483 | * - compute conservation | |
484 | */ | |
485 | 0 | Conservation c = new Conservation("Group", sg.getSequences(null), |
486 | sg.getStartRes(), sg.getEndRes()); | |
487 | 0 | c.calculate(); |
488 | 0 | c.verdict(false, ap.av.getConsPercGaps()); |
489 | 0 | sg.cs.setConservation(c); |
490 | ||
491 | } | |
492 | 18 | scheme.setConservationApplied(true); |
493 | 18 | scheme.setConservationInc(percent); |
494 | } | |
495 | 21 | else if(forConsensusSecondaryStructure) |
496 | { | |
497 | 0 | scheme.setConsensusSecondaryStructureColouring(true); |
498 | 0 | scheme.setConsensusSecondaryStructureThreshold(percent); |
499 | } | |
500 | else | |
501 | { | |
502 | 21 | scheme.setThreshold(percent, ap.av.isIgnoreGapsConsensus()); |
503 | ||
504 | } | |
505 | } | |
506 | ||
507 | /** | |
508 | * DOCUMENT ME! | |
509 | * | |
510 | * @param b | |
511 | * DOCUMENT ME! | |
512 | */ | |
513 | 22 | public void setAllGroupsCheckEnabled(boolean b) |
514 | { | |
515 | 22 | allGroupsCheck.setEnabled(b); |
516 | } | |
517 | ||
518 | /** | |
519 | * DOCUMENT ME! | |
520 | * | |
521 | * @param e | |
522 | * DOCUMENT ME! | |
523 | */ | |
524 | 0 | @Override |
525 | public void valueField_actionPerformed() | |
526 | { | |
527 | 0 | try |
528 | { | |
529 | 0 | int i = Integer.parseInt(valueField.getText()); |
530 | 0 | slider.setValue(i); |
531 | } catch (NumberFormatException ex) | |
532 | { | |
533 | 0 | valueField.setText(slider.getValue() + ""); |
534 | } | |
535 | } | |
536 | ||
537 | /** | |
538 | * DOCUMENT ME! | |
539 | * | |
540 | * @param value | |
541 | * DOCUMENT ME! | |
542 | */ | |
543 | 0 | public void setValue(int value) |
544 | { | |
545 | 0 | slider.setValue(value); |
546 | } | |
547 | ||
548 | /** | |
549 | * DOCUMENT ME! | |
550 | * | |
551 | * @return DOCUMENT ME! | |
552 | */ | |
553 | 24 | public int getValue() |
554 | { | |
555 | 24 | return Integer.parseInt(valueField.getText()); |
556 | } | |
557 | ||
558 | 0 | @Override |
559 | public void slider_mouseReleased(MouseEvent e) | |
560 | { | |
561 | 0 | if (ap.overviewPanel != null) |
562 | { | |
563 | 0 | ap.overviewPanel.updateOverviewImage(); |
564 | } | |
565 | } | |
566 | ||
567 | 0 | public static int getConservationValue() |
568 | { | |
569 | 0 | return getValue(conservationSlider); |
570 | } | |
571 | ||
572 | 0 | static int getValue(JInternalFrame slider) |
573 | { | |
574 | 0 | return slider == null ? 0 |
575 | : ((SliderPanel) slider.getContentPane()).getValue(); | |
576 | } | |
577 | ||
578 | 0 | public static int getPIDValue() |
579 | { | |
580 | 0 | return getValue(PIDSlider); |
581 | } | |
582 | ||
583 | 0 | public static int getConsensusSecondaryStructureSliderValue() |
584 | { | |
585 | 0 | return getValue(consensusSecondaryStructureSlider); |
586 | } | |
587 | ||
588 | /** | |
589 | * Answers true if the SliderPanel is for Conservation, false if it is for PID | |
590 | * threshold | |
591 | * | |
592 | * @return | |
593 | */ | |
594 | 24 | public boolean isForConservation() |
595 | { | |
596 | 24 | return forConservation; |
597 | } | |
598 | ||
599 | /** | |
600 | * Answers the title for the slider panel; this may include 'Background' if | |
601 | * for the alignment, or the group id if for a group | |
602 | * | |
603 | * @return | |
604 | */ | |
605 | 6 | public String getTitle() |
606 | { | |
607 | 6 | String title = null; |
608 | 6 | if (isForConservation()) |
609 | { | |
610 | 4 | if (conservationSlider != null) |
611 | { | |
612 | 4 | title = conservationSlider.getTitle(); |
613 | } | |
614 | } | |
615 | 2 | else if (PIDSlider != null) |
616 | { | |
617 | 2 | title = PIDSlider.getTitle(); |
618 | } | |
619 | 0 | else if (consensusSecondaryStructureSlider != null) |
620 | { | |
621 | 0 | title = consensusSecondaryStructureSlider.getTitle(); |
622 | } | |
623 | 6 | return title; |
624 | } | |
625 | } |