c466b8665a3c316faae19781e91037c3a5a3344b
[jalview.git] / src / jalview / appletgui / AlignmentPanel.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer (Version 2.6)
3  * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
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 of the License, or (at your option) any later version.
10  * 
11  * Jalview is distributed in the hope that it will be useful, but 
12  * WITHOUT ANY WARRANTY; without even the implied warranty 
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14  * PURPOSE.  See the GNU General Public License for more details.
15  * 
16  * You should have received a copy of the GNU General Public License along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 package jalview.appletgui;
19
20 import java.awt.*;
21 import java.awt.event.*;
22 import java.util.Hashtable;
23 import java.util.Vector;
24
25 import jalview.datamodel.*;
26
27 public class AlignmentPanel extends Panel implements AdjustmentListener
28 {
29
30   public AlignViewport av;
31
32   OverviewPanel overviewPanel;
33
34   SeqPanel seqPanel;
35
36   IdPanel idPanel;
37
38   IdwidthAdjuster idwidthAdjuster;
39
40   public AlignFrame alignFrame;
41
42   ScalePanel scalePanel;
43
44   AnnotationPanel annotationPanel;
45
46   AnnotationLabels alabels;
47
48   // this value is set false when selection area being dragged
49   boolean fastPaint = true;
50
51   public AlignmentPanel(AlignFrame af, final AlignViewport av)
52   {
53     try
54     {
55       jbInit();
56     } catch (Exception e)
57     {
58       e.printStackTrace();
59     }
60
61     alignFrame = af;
62     this.av = av;
63     seqPanel = new SeqPanel(av, this);
64     idPanel = new IdPanel(av, this);
65     scalePanel = new ScalePanel(av, this);
66     idwidthAdjuster = new IdwidthAdjuster(this);
67     annotationPanel = new AnnotationPanel(this);
68     annotationPanelHolder.add(annotationPanel, BorderLayout.CENTER);
69
70     sequenceHolderPanel.add(annotationPanelHolder, BorderLayout.SOUTH);
71
72     alabels = new AnnotationLabels(this);
73
74     setAnnotationVisible(av.showAnnotation);
75
76     idPanelHolder.add(idPanel, BorderLayout.CENTER);
77     idSpaceFillerPanel1.add(idwidthAdjuster, BorderLayout.CENTER);
78     annotationSpaceFillerHolder.add(alabels, BorderLayout.CENTER);
79     scalePanelHolder.add(scalePanel, BorderLayout.CENTER);
80     seqPanelHolder.add(seqPanel, BorderLayout.CENTER);
81
82     fontChanged();
83     setScrollValues(0, 0);
84
85     apvscroll.addAdjustmentListener(this);
86     hscroll.addAdjustmentListener(this);
87     vscroll.addAdjustmentListener(this);
88
89     addComponentListener(new ComponentAdapter()
90     {
91       public void componentResized(ComponentEvent evt)
92       {
93         setScrollValues(av.getStartRes(), av.getStartSeq());
94         repaint();
95       }
96     });
97
98     Dimension d = calculateIdWidth();
99     idPanel.idCanvas.setSize(d);
100
101     hscrollFillerPanel.setSize(d.width, annotationPanel.getSize().height);
102
103     idPanel.idCanvas.setSize(d.width, seqPanel.seqCanvas.getSize().height);
104     annotationSpaceFillerHolder.setSize(d.width,
105             annotationPanel.getSize().height);
106     alabels.setSize(d.width, annotationPanel.getSize().height);
107     final AlignmentPanel ap = this;
108     av.addPropertyChangeListener(new java.beans.PropertyChangeListener()
109     {
110       public void propertyChange(java.beans.PropertyChangeEvent evt)
111       {
112         if (evt.getPropertyName().equals("alignment"))
113         {
114           PaintRefresher.Refresh(ap, av.getSequenceSetId(), true, true);
115           alignmentChanged();
116         }
117       }
118     });
119
120   }
121
122   public SequenceRenderer getSequenceRenderer()
123   {
124     return seqPanel.seqCanvas.sr;
125   }
126
127   public FeatureRenderer getFeatureRenderer()
128   {
129     return seqPanel.seqCanvas.fr;
130   }
131
132   public void alignmentChanged()
133   {
134     av.alignmentChanged(this);
135
136     if (overviewPanel != null)
137     {
138       overviewPanel.updateOverviewImage();
139     }
140
141     alignFrame.updateEditMenuBar();
142
143     repaint();
144   }
145
146   public void fontChanged()
147   {
148     // set idCanvas bufferedImage to null
149     // to prevent drawing old image
150     idPanel.idCanvas.image = null;
151     FontMetrics fm = getFontMetrics(av.getFont());
152
153     scalePanel.setSize(new Dimension(10, av.charHeight + fm.getDescent()));
154     idwidthAdjuster.setSize(new Dimension(10, av.charHeight
155             + fm.getDescent()));
156     av.updateSequenceIdColours();
157     annotationPanel.image = null;
158     int ap = annotationPanel.adjustPanelHeight(false);
159     Dimension d = calculateIdWidth();
160     d.setSize(d.width + 4, seqPanel.seqCanvas.getSize().height);
161     alabels.setSize(d.width + 4, ap);
162     idPanel.idCanvas.setSize(d);
163     hscrollFillerPanel.setSize(d);
164     
165     validateAnnotationDimensions(false);
166     annotationPanel.repaint();
167     validate();
168     repaint();
169
170     if (overviewPanel != null)
171     {
172       overviewPanel.updateOverviewImage();
173     }
174   }
175
176   public void setIdWidth(int w, int h)
177   {
178     idPanel.idCanvas.setSize(w, h);
179     idPanelHolder.setSize(w, idPanelHolder.getSize().height);
180     annotationSpaceFillerHolder.setSize(w,annotationSpaceFillerHolder.getSize().height);
181     alabels.setSize(w, alabels.getSize().height);
182     validate();
183   }
184
185   Dimension calculateIdWidth()
186   {
187     if (av.nullFrame == null)
188     {
189       av.nullFrame = new Frame();
190       av.nullFrame.addNotify();
191     }
192
193     Graphics g = av.nullFrame.getGraphics();
194
195     FontMetrics fm = g.getFontMetrics(av.font);
196     AlignmentI al = av.getAlignment();
197
198     int i = 0;
199     int idWidth = 0;
200     String id;
201     while (i < al.getHeight() && al.getSequenceAt(i) != null)
202     {
203       SequenceI s = al.getSequenceAt(i);
204       id = s.getDisplayId(av.getShowJVSuffix());
205
206       if (fm.stringWidth(id) > idWidth)
207       {
208         idWidth = fm.stringWidth(id);
209       }
210       i++;
211     }
212
213     // Also check annotation label widths
214     i = 0;
215     if (al.getAlignmentAnnotation() != null)
216     {
217       fm = g.getFontMetrics(av.nullFrame.getFont());
218       while (i < al.getAlignmentAnnotation().length)
219       {
220         String label = al.getAlignmentAnnotation()[i].label;
221         if (fm.stringWidth(label) > idWidth)
222         {
223           idWidth = fm.stringWidth(label);
224         }
225         i++;
226       }
227     }
228
229     return new Dimension(idWidth, idPanel.idCanvas.getSize().height);
230   }
231
232   /**
233    * Highlight the given results on the alignment.
234    * 
235    */
236   public void highlightSearchResults(SearchResults results)
237   {
238     scrollToPosition(results);
239     seqPanel.seqCanvas.highlightSearchResults(results);
240   }
241
242   /**
243    * scroll the view to show the position of the highlighted region in results
244    * (if any) and redraw the overview
245    * 
246    * @param results
247    * @return false if results were not found
248    */
249   public boolean scrollToPosition(SearchResults results)
250   {
251     return scrollToPosition(results, true);
252   }
253
254   /**
255    * scroll the view to show the position of the highlighted region in results
256    * (if any)
257    * 
258    * @param results
259    * @param redrawOverview
260    *          - when set, the overview will be recalculated (takes longer)
261    * @return false if results were not found
262    */
263   public boolean scrollToPosition(SearchResults results,
264           boolean redrawOverview)
265   {
266     // do we need to scroll the panel?
267     if (results != null && results.getSize() > 0)
268     {
269       int seqIndex = av.alignment.findIndex(results);
270       if (seqIndex == -1)
271       {
272         return false;
273       }
274       SequenceI seq = av.alignment.getSequenceAt(seqIndex);
275       int[] r = results.getResults(seq, seq.getStart(), seq.getEnd());
276       if (r == null)
277       {
278         if (av.applet.debug) {// DEBUG
279           System.out.println("DEBUG: scroll didn't happen - results not within alignment : "+seq.getStart()+","+seq.getEnd());
280         }
281         return false;
282       }
283       if (av.applet.debug) {
284         // DEBUG
285         System.out.println("DEBUG: scroll didn't happen: start=" + r[0]
286                 + " av.getStartRes()=" + av.getStartRes() + " end=" + r[1]
287                 + " seq.end=" + seq.getEnd() + " av.getEndRes()="
288                 + av.getEndRes() + " hextent=" + hextent);
289       }
290       int start = r[0];
291       int end = r[1];
292       if (start < 0)
293       {
294         return false;
295       }
296       if (end == seq.getEnd())
297       {
298         return false;
299       }
300       if (av.hasHiddenColumns)
301       {
302         start = av.getColumnSelection().findColumnPosition(start);
303         end = av.getColumnSelection().findColumnPosition(end);
304         if (start == end)
305         {
306           if (!av.colSel.isVisible(r[0]))
307           {
308             // don't scroll - position isn't visible
309             return false;
310           }
311         }
312       }
313       if (!av.wrapAlignment)
314       {
315         if ((av.getStartRes() > end)
316                 || (av.getEndRes() < start)
317                 || ((av.getStartSeq() > seqIndex) || (av.getEndSeq() < seqIndex)))
318         {
319           if (start > av.alignment.getWidth() - hextent)
320           {
321             start = av.alignment.getWidth() - hextent;
322             if (start < 0)
323             {
324               start = 0;
325             }
326
327           }
328           if (seqIndex > av.alignment.getHeight() - vextent)
329           {
330             seqIndex = av.alignment.getHeight() - vextent;
331             if (seqIndex < 0)
332             {
333               seqIndex = 0;
334             }
335           }
336           setScrollValues(start, seqIndex);
337         }
338       }
339       else
340       {
341         scrollToWrappedVisible(start);
342       }
343     }
344     if (redrawOverview && overviewPanel != null)
345     {
346       overviewPanel.setBoxPosition();
347     }
348     paintAlignment(redrawOverview);
349     return true;
350   }
351
352   void scrollToWrappedVisible(int res)
353   {
354     int cwidth = seqPanel.seqCanvas
355             .getWrappedCanvasWidth(seqPanel.seqCanvas.getSize().width);
356     if (res <= av.getStartRes() || res >= (av.getStartRes() + cwidth))
357     {
358       vscroll.setValue(res / cwidth);
359       av.startRes = vscroll.getValue() * cwidth;
360     }
361   }
362
363   public OverviewPanel getOverviewPanel()
364   {
365     return overviewPanel;
366   }
367
368   public void setOverviewPanel(OverviewPanel op)
369   {
370     overviewPanel = op;
371   }
372
373   public void setAnnotationVisible(boolean b)
374   {
375     if (!av.wrapAlignment)
376     {
377       annotationSpaceFillerHolder.setVisible(b);
378       annotationPanelHolder.setVisible(b);
379     }
380     validate();
381     repaint();
382   }
383
384   public void setWrapAlignment(boolean wrap)
385   {
386     av.startSeq = 0;
387     av.startRes = 0;
388     scalePanelHolder.setVisible(!wrap);
389
390     hscroll.setVisible(!wrap);
391     idwidthAdjuster.setVisible(!wrap);
392
393     if (wrap)
394     {
395       annotationPanelHolder.setVisible(false);
396       annotationSpaceFillerHolder.setVisible(false);
397     }
398     else if (av.showAnnotation)
399     {
400       annotationPanelHolder.setVisible(true);
401       annotationSpaceFillerHolder.setVisible(true);
402     }
403
404     idSpaceFillerPanel1.setVisible(!wrap);
405
406     fontChanged(); // This is so that the scalePanel is resized correctly
407
408     validate();
409     repaint();
410
411   }
412
413   int hextent = 0;
414
415   int vextent = 0;
416
417   // return value is true if the scroll is valid
418   public boolean scrollUp(boolean up)
419   {
420     if (up)
421     {
422       if (vscroll.getValue() < 1)
423       {
424         return false;
425       }
426       setScrollValues(hscroll.getValue(), vscroll.getValue() - 1);
427     }
428     else
429     {
430       if (vextent + vscroll.getValue() >= av.getAlignment().getHeight())
431       {
432         return false;
433       }
434       setScrollValues(hscroll.getValue(), vscroll.getValue() + 1);
435     }
436
437     repaint();
438     return true;
439   }
440
441   public boolean scrollRight(boolean right)
442   {
443     if (!right)
444     {
445       if (hscroll.getValue() < 1)
446       {
447         return false;
448       }
449       setScrollValues(hscroll.getValue() - 1, vscroll.getValue());
450     }
451     else
452     {
453       if (hextent + hscroll.getValue() >= av.getAlignment().getWidth())
454       {
455         return false;
456       }
457       setScrollValues(hscroll.getValue() + 1, vscroll.getValue());
458     }
459
460     repaint();
461     return true;
462   }
463
464   public void setScrollValues(int x, int y)
465   {
466     int width = av.alignment.getWidth();
467     int height = av.alignment.getHeight();
468
469     if (av.hasHiddenColumns)
470     {
471       width = av.getColumnSelection().findColumnPosition(width);
472     }
473
474     av.setStartRes(x);
475     av.setEndRes((x + (seqPanel.seqCanvas.getSize().width / av.charWidth)) - 1);
476
477     hextent = seqPanel.seqCanvas.getSize().width / av.charWidth;
478     vextent = seqPanel.seqCanvas.getSize().height / av.charHeight;
479     
480     if (hextent > width)
481     {
482       hextent = width;
483     }
484
485     if (vextent > height)
486     {
487       vextent = height;
488     }
489
490     if ((hextent + x) > width)
491     {
492       x = width - hextent;
493     }
494
495     if ((vextent + y) > height)
496     {
497       y = height - vextent;
498     }
499
500     if (y < 0)
501     {
502       y = 0;
503     }
504
505     if (x < 0)
506     {
507       x = 0;
508     }
509
510     av.setStartSeq(y);
511
512     int endSeq = y + vextent;
513     if (endSeq > av.alignment.getHeight())
514     {
515       endSeq = av.alignment.getHeight();
516     }
517
518     av.setEndSeq(endSeq);
519     hscroll.setValues(x, hextent, 0, width);
520     vscroll.setValues(y, vextent, 0, height);
521
522     if (overviewPanel != null)
523     {
524       overviewPanel.setBoxPosition();
525     }
526
527   }
528
529   public void adjustmentValueChanged(AdjustmentEvent evt)
530   {
531     int oldX = av.getStartRes();
532     int oldY = av.getStartSeq();
533
534     if (evt == null || evt.getSource() == apvscroll)
535     {
536       annotationPanel.setScrollOffset(apvscroll.getValue());
537       alabels.setScrollOffset(apvscroll.getValue());
538       // annotationPanel.image=null;
539       // alabels.image=null;
540       // alabels.repaint();
541       // annotationPanel.repaint();
542     }
543     if (evt == null || evt.getSource() == hscroll)
544     {
545       int x = hscroll.getValue();
546       av.setStartRes(x);
547       av.setEndRes(x + seqPanel.seqCanvas.getSize().width
548               / av.getCharWidth() - 1);
549     }
550
551     if (evt == null || evt.getSource() == vscroll)
552     {
553       int offy = vscroll.getValue();
554       if (av.getWrapAlignment())
555       {
556         int rowSize = seqPanel.seqCanvas
557                 .getWrappedCanvasWidth(seqPanel.seqCanvas.getSize().width);
558         av.setStartRes(vscroll.getValue() * rowSize);
559         av.setEndRes((vscroll.getValue() + 1) * rowSize);
560       }
561       else
562       {
563         av.setStartSeq(offy);
564         av.setEndSeq(offy + seqPanel.seqCanvas.getSize().height
565                 / av.getCharHeight());
566       }
567     }
568
569     if (overviewPanel != null)
570     {
571       overviewPanel.setBoxPosition();
572     }
573
574     int scrollX = av.startRes - oldX;
575     int scrollY = av.startSeq - oldY;
576
577     if (av.getWrapAlignment() || !fastPaint || av.MAC)
578     {
579       repaint();
580     }
581     else
582     {
583       // Make sure we're not trying to draw a panel
584       // larger than the visible window
585       if (scrollX > av.endRes - av.startRes)
586       {
587         scrollX = av.endRes - av.startRes;
588       }
589       else if (scrollX < av.startRes - av.endRes)
590       {
591         scrollX = av.startRes - av.endRes;
592       }
593
594       idPanel.idCanvas.fastPaint(scrollY);
595       seqPanel.seqCanvas.fastPaint(scrollX, scrollY);
596
597       scalePanel.repaint();
598       if (av.getShowAnnotation())
599       {
600         annotationPanel.fastPaint(av.getStartRes() - oldX);
601       }
602     }
603
604   }
605
606   public void paintAlignment(boolean updateOverview)
607   {
608     repaint();
609
610     if (updateOverview)
611     {
612       jalview.structure.StructureSelectionManager
613               .getStructureSelectionManager().sequenceColoursChanged(this);
614
615       if (overviewPanel != null)
616       {
617         overviewPanel.updateOverviewImage();
618       }
619     }
620   }
621
622   public void update(Graphics g)
623   {
624     paint(g);
625   }
626
627   public void paint(Graphics g)
628   {
629     invalidate();
630     Dimension d = idPanel.idCanvas.getSize();
631     idPanel.idCanvas.setSize(d.width, seqPanel.seqCanvas.getSize().height);
632     
633     if (av.getWrapAlignment())
634     {
635       int maxwidth = av.alignment.getWidth();
636
637       if (av.hasHiddenColumns)
638       {
639         maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
640       }
641
642       int canvasWidth = seqPanel.seqCanvas
643               .getWrappedCanvasWidth(seqPanel.seqCanvas.getSize().width);
644
645       if (canvasWidth > 0)
646       {
647         int max = maxwidth / canvasWidth;
648         vscroll.setMaximum(1 + max);
649         vscroll.setUnitIncrement(1);
650         vscroll.setVisibleAmount(1);
651       }
652     }
653     else
654     {
655       setScrollValues(av.getStartRes(), av.getStartSeq());
656     }
657
658     alabels.repaint();
659
660     seqPanel.seqCanvas.repaint();
661     scalePanel.repaint();
662     annotationPanel.repaint();
663     idPanel.idCanvas.repaint();
664   }
665
666   protected Panel sequenceHolderPanel = new Panel();
667
668   protected Scrollbar vscroll = new Scrollbar();
669
670   protected Scrollbar hscroll = new Scrollbar();
671
672   protected Panel seqPanelHolder = new Panel();
673
674   BorderLayout borderLayout1 = new BorderLayout();
675
676   BorderLayout borderLayout3 = new BorderLayout();
677
678   protected Panel scalePanelHolder = new Panel();
679
680   protected Panel idPanelHolder = new Panel();
681
682   BorderLayout borderLayout5 = new BorderLayout();
683
684   protected Panel idSpaceFillerPanel1 = new Panel();
685
686   public Panel annotationSpaceFillerHolder = new Panel();
687
688   BorderLayout borderLayout6 = new BorderLayout();
689
690   BorderLayout borderLayout7 = new BorderLayout();
691
692   Panel hscrollHolder = new Panel();
693
694   BorderLayout borderLayout10 = new BorderLayout();
695
696   protected Panel hscrollFillerPanel = new Panel();
697
698   BorderLayout borderLayout11 = new BorderLayout();
699
700   BorderLayout borderLayout4 = new BorderLayout();
701
702   BorderLayout borderLayout2 = new BorderLayout();
703
704   Panel annotationPanelHolder = new Panel();
705
706   protected Scrollbar apvscroll = new Scrollbar();
707
708   BorderLayout borderLayout12 = new BorderLayout();
709
710   private void jbInit() throws Exception
711   {
712     // idPanelHolder.setPreferredSize(new Dimension(70, 10));
713     this.setLayout(borderLayout7);
714
715     //sequenceHolderPanel.setPreferredSize(new Dimension(150, 150));
716     sequenceHolderPanel.setLayout(borderLayout3);
717     seqPanelHolder.setLayout(borderLayout1);
718     scalePanelHolder.setBackground(Color.white);
719
720     // scalePanelHolder.setPreferredSize(new Dimension(10, 30));
721     scalePanelHolder.setLayout(borderLayout6);
722     idPanelHolder.setLayout(borderLayout5);
723     idSpaceFillerPanel1.setBackground(Color.white);
724
725     // idSpaceFillerPanel1.setPreferredSize(new Dimension(10, 30));
726     idSpaceFillerPanel1.setLayout(borderLayout11);
727     annotationSpaceFillerHolder.setBackground(Color.white);
728
729     // annotationSpaceFillerHolder.setPreferredSize(new Dimension(10, 80));
730     annotationSpaceFillerHolder.setLayout(borderLayout4);
731     hscroll.setOrientation(Scrollbar.HORIZONTAL);
732     hscrollHolder.setLayout(borderLayout10);
733     hscrollFillerPanel.setBackground(Color.white);
734     apvscroll.setOrientation(Scrollbar.VERTICAL);
735     apvscroll.setVisible(true);
736     apvscroll.addAdjustmentListener(this);
737
738     annotationPanelHolder.setBackground(Color.white);
739     annotationPanelHolder.setLayout(borderLayout12);
740     annotationPanelHolder.add(apvscroll, BorderLayout.EAST);
741     // hscrollFillerPanel.setPreferredSize(new Dimension(70, 10));
742     hscrollHolder.setBackground(Color.white);
743
744     // annotationScroller.setPreferredSize(new Dimension(10, 80));
745     // this.setPreferredSize(new Dimension(220, 166));
746     seqPanelHolder.setBackground(Color.white);
747     idPanelHolder.setBackground(Color.white);
748     sequenceHolderPanel.add(scalePanelHolder, BorderLayout.NORTH);
749     sequenceHolderPanel.add(seqPanelHolder, BorderLayout.CENTER);
750     seqPanelHolder.add(vscroll, BorderLayout.EAST);
751
752     // Panel3.add(secondaryPanelHolder, BorderLayout.SOUTH);
753     this.add(idPanelHolder, BorderLayout.WEST);
754     idPanelHolder.add(idSpaceFillerPanel1, BorderLayout.NORTH);
755     idPanelHolder.add(annotationSpaceFillerHolder, BorderLayout.SOUTH);
756     this.add(hscrollHolder, BorderLayout.SOUTH);
757     hscrollHolder.add(hscroll, BorderLayout.CENTER);
758     hscrollHolder.add(hscrollFillerPanel, BorderLayout.WEST);
759     this.add(sequenceHolderPanel, BorderLayout.CENTER);
760   }
761
762   /**
763    * hides or shows dynamic annotation rows based on groups and av state flags
764    */
765   public void updateAnnotation()
766   {
767     updateAnnotation(false);
768   }
769
770   public void updateAnnotation(boolean applyGlobalSettings)
771   {
772     // TODO: this should be merged with other annotation update stuff - that
773     // sits on AlignViewport
774     boolean updateCalcs = false;
775     boolean conv = av.isShowGroupConservation();
776     boolean cons = av.isShowGroupConsensus();
777     boolean showprf = av.isShowSequenceLogo();
778     boolean showConsHist = av.isShowConsensusHistogram();
779
780     boolean sortg = true;
781
782     // remove old automatic annotation
783     // add any new annotation
784
785     Vector gr = av.alignment.getGroups(); // OrderedBy(av.alignment.getSequencesArray());
786     // intersect alignment annotation with alignment groups
787
788     AlignmentAnnotation[] aan = av.alignment.getAlignmentAnnotation();
789     Hashtable oldrfs = new Hashtable();
790     if (aan != null)
791     {
792       for (int an = 0; an < aan.length; an++)
793       {
794         if (aan[an].autoCalculated && aan[an].groupRef != null)
795         {
796           oldrfs.put(aan[an].groupRef, aan[an].groupRef);
797           av.alignment.deleteAnnotation(aan[an]);
798           aan[an] = null;
799         }
800       }
801     }
802     SequenceGroup sg;
803     if (gr != null)
804     {
805       for (int g = 0; g < gr.size(); g++)
806       {
807         updateCalcs = false;
808         sg = (SequenceGroup) gr.elementAt(g);
809         if (applyGlobalSettings || !oldrfs.containsKey(sg))
810         {
811           // set defaults for this group's conservation/consensus
812           sg.setshowSequenceLogo(showprf);
813           sg.setShowConsensusHistogram(showConsHist);
814         }
815         if (conv)
816         {
817           updateCalcs = true;
818           av.alignment.addAnnotation(sg.getConservationRow(), 0);
819         }
820         if (cons)
821         {
822           updateCalcs = true;
823           av.alignment.addAnnotation(sg.getConsensus(), 0);
824         }
825         // refresh the annotation rows
826         if (updateCalcs)
827         {
828           sg.recalcConservation();
829         }
830       }
831     }
832     oldrfs.clear();
833     adjustAnnotationHeight();
834   }
835
836   /**
837    * automatically adjust annotation panel height for new annotation whilst
838    * ensuring the alignment is still visible.
839    */
840   public void adjustAnnotationHeight()
841   {
842     // TODO: display vertical annotation scrollbar if necessary
843     // this is called after loading new annotation onto alignment
844     if (alignFrame.getSize().height == 0)
845     {
846       System.out.println("NEEDS FIXING");
847     }
848     fontChanged();
849     validateAnnotationDimensions(true);
850     apvscroll.addNotify();
851     hscroll.addNotify();
852     validate();
853     addNotify();
854     repaint();
855   }
856   /**
857    * calculate the annotation dimensions and refresh slider values accordingly.
858    * need to do repaints/notifys afterwards. 
859    */
860   protected void validateAnnotationDimensions(boolean adjustPanelHeight) {
861     int height = annotationPanel.calcPanelHeight();
862     if (hscroll.isVisible())
863     {
864       height += hscroll.getPreferredSize().height;
865     }
866     int mheight = height;
867     // sets initial preferred height
868     if ((height+40) > getSize().height / 2)
869     {
870       height = getSize().height / 2;
871     }
872     if (!adjustPanelHeight)
873     {
874       // maintain same window layout whilst updating sliders
875       height=seqPanelHolder.getSize().height;
876     }
877     Dimension d=seqPanelHolder.getSize(),e=idPanel.getSize(); 
878     annotationPanel.setSize(new Dimension(d.width,height));
879     alabels.setSize(e.width,height);
880     annotationSpaceFillerHolder.setSize(new Dimension(e.width, height));
881     annotationPanelHolder.setSize(new Dimension(d.width, height));
882     seqPanelHolder.setSize(d.width,d.height-height);
883     int s=apvscroll.getValue();
884     if (s>mheight-height)
885     {
886       s = 0;
887     }
888     apvscroll.setValues(apvscroll.getValue(), height, 0, mheight);
889     annotationPanel.setScrollOffset(apvscroll.getValue());
890     alabels.setScrollOffset(apvscroll.getValue());
891   }
892
893 }