spike branch updated from latest features/JAL-2446
[jalview.git] / src / jalview / appletgui / SliderPanel.java
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.appletgui;
22
23 import jalview.analysis.Conservation;
24 import jalview.datamodel.SequenceGroup;
25 import jalview.renderer.ResidueShaderI;
26 import jalview.util.MessageManager;
27
28 import java.awt.BorderLayout;
29 import java.awt.Button;
30 import java.awt.Checkbox;
31 import java.awt.Color;
32 import java.awt.FlowLayout;
33 import java.awt.Frame;
34 import java.awt.Label;
35 import java.awt.Panel;
36 import java.awt.Scrollbar;
37 import java.awt.TextField;
38 import java.awt.event.ActionEvent;
39 import java.awt.event.ActionListener;
40 import java.awt.event.AdjustmentEvent;
41 import java.awt.event.AdjustmentListener;
42 import java.awt.event.FocusAdapter;
43 import java.awt.event.FocusEvent;
44 import java.awt.event.MouseEvent;
45 import java.awt.event.MouseListener;
46 import java.awt.event.WindowAdapter;
47 import java.awt.event.WindowEvent;
48 import java.util.List;
49
50 public class SliderPanel extends Panel implements ActionListener,
51         AdjustmentListener, MouseListener
52 {
53   private static final String BACKGROUND = "Background";
54
55   AlignmentPanel ap;
56
57   boolean forConservation = true;
58
59   ResidueShaderI cs;
60
61   static Frame conservationSlider;
62
63   static Frame PIDSlider;
64
65   public static int setConservationSlider(AlignmentPanel ap,
66           ResidueShaderI ccs, String source)
67   {
68     SliderPanel sp = null;
69
70     if (conservationSlider == null)
71     {
72       sp = new SliderPanel(ap, ccs.getConservationInc(), true, ccs);
73       conservationSlider = new Frame();
74       conservationSlider.add(sp);
75     }
76     else
77     {
78       sp = (SliderPanel) conservationSlider.getComponent(0);
79       sp.cs = ccs;
80       sp.valueField.setText(String.valueOf(ccs.getConservationInc()));
81     }
82
83     conservationSlider.setTitle(MessageManager.formatMessage(
84             "label.conservation_colour_increment",
85             new String[] { source == null ? BACKGROUND : source }));
86     List<SequenceGroup> groups = ap.av.getAlignment().getGroups();
87     if (groups != null && !groups.isEmpty())
88     {
89       sp.setAllGroupsCheckEnabled(true);
90     }
91     else
92     {
93       sp.setAllGroupsCheckEnabled(false);
94     }
95
96     return sp.getValue();
97   }
98
99   public static void showConservationSlider()
100   {
101     try
102     {
103       PIDSlider.setVisible(false);
104       PIDSlider = null;
105     } catch (Exception ex)
106     {
107     }
108
109     if (!conservationSlider.isVisible())
110     {
111       jalview.bin.JalviewLite.addFrame(conservationSlider,
112               conservationSlider.getTitle(), 420, 100);
113       conservationSlider.addWindowListener(new WindowAdapter()
114       {
115         @Override
116         public void windowClosing(WindowEvent e)
117         {
118           conservationSlider = null;
119         }
120       });
121
122     }
123
124   }
125
126   public static int setPIDSliderSource(AlignmentPanel ap,
127           ResidueShaderI ccs, String source)
128   {
129     SliderPanel pid = null;
130     if (PIDSlider == null)
131     {
132       pid = new SliderPanel(ap, ccs.getThreshold(), false, ccs);
133       PIDSlider = new Frame();
134       PIDSlider.add(pid);
135     }
136     else
137     {
138       pid = (SliderPanel) PIDSlider.getComponent(0);
139       pid.cs = ccs;
140       pid.valueField.setText(String.valueOf(ccs.getThreshold()));
141     }
142     PIDSlider.setTitle(MessageManager.formatMessage(
143             "label.percentage_identity_threshold",
144             new String[] { source == null ? BACKGROUND : source }));
145
146     if (ap.av.getAlignment().getGroups() != null)
147     {
148       pid.setAllGroupsCheckEnabled(true);
149     }
150     else
151     {
152       pid.setAllGroupsCheckEnabled(false);
153     }
154
155     return pid.getValue();
156
157   }
158
159   public static void showPIDSlider()
160   {
161     try
162     {
163       conservationSlider.setVisible(false);
164       conservationSlider = null;
165     } catch (Exception ex)
166     {
167     }
168
169     if (!PIDSlider.isVisible())
170     {
171       jalview.bin.JalviewLite.addFrame(PIDSlider, PIDSlider.getTitle(),
172               420, 100);
173       PIDSlider.addWindowListener(new WindowAdapter()
174       {
175         @Override
176         public void windowClosing(WindowEvent e)
177         {
178           PIDSlider = null;
179         }
180       });
181     }
182
183   }
184
185   /**
186    * Hides the PID slider panel if it is shown
187    */
188   public static void hidePIDSlider()
189   {
190     if (PIDSlider != null)
191     {
192       PIDSlider.setVisible(false);
193       PIDSlider = null;
194     }
195   }
196
197   /**
198    * Hides the Conservation slider panel if it is shown
199    */
200   public static void hideConservationSlider()
201   {
202     if (conservationSlider != null)
203     {
204       conservationSlider.setVisible(false);
205       conservationSlider = null;
206     }
207   }
208   public SliderPanel(AlignmentPanel ap, int value, boolean forConserve,
209           ResidueShaderI shader)
210   {
211     try
212     {
213       jbInit();
214     } catch (Exception e)
215     {
216       e.printStackTrace();
217     }
218     this.ap = ap;
219     this.cs = shader;
220     forConservation = forConserve;
221     undoButton.setVisible(false);
222     applyButton.setVisible(false);
223     if (forConservation)
224     {
225       label.setText(MessageManager
226               .getString("label.modify_conservation_visibility"));
227       slider.setMinimum(0);
228       slider.setMaximum(50 + slider.getVisibleAmount());
229       slider.setUnitIncrement(1);
230     }
231     else
232     {
233       label.setText(MessageManager
234               .getString("label.colour_residues_above_occurrence"));
235       slider.setMinimum(0);
236       slider.setMaximum(100 + slider.getVisibleAmount());
237       slider.setBlockIncrement(1);
238     }
239
240     slider.addAdjustmentListener(this);
241     slider.addMouseListener(this);
242
243     slider.setValue(value);
244     valueField.setText(value + "");
245   }
246
247   public void valueChanged(int i)
248   {
249     if (cs == null)
250     {
251       return;
252     }
253     if (forConservation)
254     {
255       cs.setConservationApplied(true);
256       cs.setConservationInc(i);
257     }
258     else
259     {
260       cs.setThreshold(i, ap.av.isIgnoreGapsConsensus());
261     }
262
263     if (allGroupsCheck.getState())
264     {
265       for (SequenceGroup group : ap.av.getAlignment().getGroups())
266       {
267         ResidueShaderI groupColourScheme = group.getGroupColourScheme();
268         if (forConservation)
269         {
270           if (!groupColourScheme.conservationApplied())
271           {
272             /*
273              * first time the colour scheme has had Conservation shading applied
274              * - compute conservation
275              */
276             Conservation c = new Conservation("Group",
277                     group.getSequences(null), group.getStartRes(),
278                     group.getEndRes());
279             c.calculate();
280             c.verdict(false, ap.av.getConsPercGaps());
281             group.cs.setConservation(c);
282
283           }
284           groupColourScheme.setConservationApplied(true);
285           groupColourScheme.setConservationInc(i);
286         }
287         else
288         {
289           groupColourScheme.setThreshold(i, ap.av.isIgnoreGapsConsensus());
290         }
291       }
292     }
293
294     ap.seqPanel.seqCanvas.repaint();
295   }
296
297   public void setAllGroupsCheckEnabled(boolean b)
298   {
299     allGroupsCheck.setState(ap.av.getColourAppliesToAllGroups());
300     allGroupsCheck.setEnabled(b);
301   }
302
303   @Override
304   public void actionPerformed(ActionEvent evt)
305   {
306     if (evt.getSource() == applyButton)
307     {
308       applyButton_actionPerformed();
309     }
310     else if (evt.getSource() == undoButton)
311     {
312       undoButton_actionPerformed();
313     }
314     else if (evt.getSource() == valueField)
315     {
316       valueField_actionPerformed();
317     }
318   }
319
320   @Override
321   public void adjustmentValueChanged(AdjustmentEvent evt)
322   {
323     valueField.setText(slider.getValue() + "");
324     valueChanged(slider.getValue());
325   }
326
327   public void valueField_actionPerformed()
328   {
329     try
330     {
331       int i = Integer.valueOf(valueField.getText());
332       slider.setValue(i);
333     } catch (NumberFormatException ex)
334     {
335       valueField.setText(String.valueOf(slider.getValue()));
336     }
337   }
338
339   public void setValue(int value)
340   {
341     slider.setValue(value);
342   }
343
344   public int getValue()
345   {
346     return Integer.parseInt(valueField.getText());
347   }
348
349   // this is used for conservation colours, PID colours and redundancy threshold
350   protected Scrollbar slider = new Scrollbar();
351
352   protected TextField valueField = new TextField();
353
354   protected Label label = new Label();
355
356   Panel jPanel1 = new Panel();
357
358   Panel jPanel2 = new Panel();
359
360   protected Button applyButton = new Button();
361
362   protected Button undoButton = new Button();
363
364   FlowLayout flowLayout1 = new FlowLayout();
365
366   protected Checkbox allGroupsCheck = new Checkbox();
367
368   BorderLayout borderLayout1 = new BorderLayout();
369
370   BorderLayout borderLayout2 = new BorderLayout();
371
372   FlowLayout flowLayout2 = new FlowLayout();
373
374   private void jbInit() throws Exception
375   {
376     this.setLayout(borderLayout2);
377
378     // slider.setMajorTickSpacing(10);
379     // slider.setMinorTickSpacing(1);
380     // slider.setPaintTicks(true);
381     slider.setBackground(Color.white);
382     slider.setFont(new java.awt.Font("Verdana", 0, 11));
383     slider.setOrientation(0);
384     valueField.setFont(new java.awt.Font("Verdana", 0, 11));
385     valueField.setText("   ");
386     valueField.addActionListener(this);
387     valueField.setColumns(3);
388     valueField.addFocusListener(new FocusAdapter()
389     {
390       @Override
391       public void focusLost(FocusEvent e)
392       {
393         valueField_actionPerformed();
394         valueChanged(slider.getValue());
395       }
396     });
397     
398     label.setFont(new java.awt.Font("Verdana", 0, 11));
399     label.setText(MessageManager.getString("label.set_this_label_text"));
400     jPanel1.setLayout(borderLayout1);
401     jPanel2.setLayout(flowLayout1);
402     applyButton.setFont(new java.awt.Font("Verdana", 0, 11));
403     applyButton.setLabel(MessageManager.getString("action.apply"));
404     applyButton.addActionListener(this);
405     undoButton.setEnabled(false);
406     undoButton.setFont(new java.awt.Font("Verdana", 0, 11));
407     undoButton.setLabel(MessageManager.getString("action.undo"));
408     undoButton.addActionListener(this);
409     allGroupsCheck.setEnabled(false);
410     allGroupsCheck.setFont(new java.awt.Font("Verdana", 0, 11));
411     allGroupsCheck.setLabel(MessageManager
412             .getString("action.apply_threshold_all_groups"));
413     allGroupsCheck.setName(MessageManager
414             .getString("action.apply_all_groups"));
415     this.setBackground(Color.white);
416     this.setForeground(Color.black);
417     jPanel2.add(label, null);
418     jPanel2.add(applyButton, null);
419     jPanel2.add(undoButton, null);
420     jPanel2.add(allGroupsCheck);
421     jPanel1.add(valueField, java.awt.BorderLayout.EAST);
422     jPanel1.add(slider, java.awt.BorderLayout.CENTER);
423     this.add(jPanel1, java.awt.BorderLayout.SOUTH);
424     this.add(jPanel2, java.awt.BorderLayout.CENTER);
425   }
426
427   protected void applyButton_actionPerformed()
428   {
429   }
430
431   protected void undoButton_actionPerformed()
432   {
433   }
434
435   @Override
436   public void mousePressed(MouseEvent evt)
437   {
438   }
439
440   @Override
441   public void mouseReleased(MouseEvent evt)
442   {
443     ap.paintAlignment(true);
444   }
445
446   @Override
447   public void mouseClicked(MouseEvent evt)
448   {
449   }
450
451   @Override
452   public void mouseEntered(MouseEvent evt)
453   {
454   }
455
456   @Override
457   public void mouseExited(MouseEvent evt)
458   {
459   }
460 }