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.analysis.AnnotationSorter;
24 import jalview.api.AlignViewportI;
25 import jalview.api.AlignmentViewPanel;
26 import jalview.bin.JalviewLite;
27 import jalview.datamodel.AlignmentI;
28 import jalview.datamodel.SearchResultsI;
29 import jalview.datamodel.SequenceI;
30 import jalview.structure.StructureSelectionManager;
31 import jalview.viewmodel.ViewportListenerI;
32 import jalview.viewmodel.ViewportRanges;
34 import java.awt.BorderLayout;
35 import java.awt.Color;
36 import java.awt.Dimension;
37 import java.awt.FontMetrics;
38 import java.awt.Frame;
39 import java.awt.Graphics;
40 import java.awt.Panel;
41 import java.awt.Scrollbar;
42 import java.awt.event.AdjustmentEvent;
43 import java.awt.event.AdjustmentListener;
44 import java.awt.event.ComponentAdapter;
45 import java.awt.event.ComponentEvent;
46 import java.beans.PropertyChangeEvent;
47 import java.util.List;
49 public class AlignmentPanel extends Panel
50 implements AdjustmentListener, AlignmentViewPanel, ViewportListenerI
53 public AlignViewport av;
55 OverviewPanel overviewPanel;
61 IdwidthAdjuster idwidthAdjuster;
63 public AlignFrame alignFrame;
65 ScalePanel scalePanel;
67 AnnotationPanel annotationPanel;
69 AnnotationLabels alabels;
71 ViewportRanges vpRanges;
73 // this value is set false when selection area being dragged
74 boolean fastPaint = true;
76 public AlignmentPanel(AlignFrame af, final AlignViewport av)
88 vpRanges = av.getRanges();
89 seqPanel = new SeqPanel(av, this);
90 idPanel = new IdPanel(av, this);
91 scalePanel = new ScalePanel(av, this);
92 idwidthAdjuster = new IdwidthAdjuster(this);
93 annotationPanel = new AnnotationPanel(this);
94 annotationPanelHolder.add(annotationPanel, BorderLayout.CENTER);
96 sequenceHolderPanel.add(annotationPanelHolder, BorderLayout.SOUTH);
97 alabels = new AnnotationLabels(this);
99 setAnnotationVisible(av.isShowAnnotation());
101 idPanelHolder.add(idPanel, BorderLayout.CENTER);
102 idSpaceFillerPanel1.add(idwidthAdjuster, BorderLayout.CENTER);
103 annotationSpaceFillerHolder.add(alabels, BorderLayout.CENTER);
104 scalePanelHolder.add(scalePanel, BorderLayout.CENTER);
105 seqPanelHolder.add(seqPanel, BorderLayout.CENTER);
108 setScrollValues(0, 0);
110 apvscroll.addAdjustmentListener(this);
111 hscroll.addAdjustmentListener(this);
112 vscroll.addAdjustmentListener(this);
114 addComponentListener(new ComponentAdapter()
117 public void componentResized(ComponentEvent evt)
119 // reset the viewport ranges when the alignment panel is resized
120 // in particular, this initialises the end residue value when Jalview
122 if (av.getWrapAlignment())
124 int widthInRes = seqPanel.seqCanvas
125 .getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());
126 vpRanges.setViewportWidth(widthInRes);
130 int widthInRes = seqPanel.seqCanvas.getWidth()
132 int heightInSeq = seqPanel.seqCanvas.getHeight()
133 / av.getCharHeight();
135 vpRanges.setViewportWidth(widthInRes);
136 vpRanges.setViewportHeight(heightInSeq);
138 // setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq());
139 if (getSize().height > 0
140 && annotationPanelHolder.getSize().height > 0)
142 validateAnnotationDimensions(false);
149 Dimension d = calculateIdWidth();
150 idPanel.idCanvas.setSize(d);
152 hscrollFillerPanel.setSize(d.width, annotationPanel.getSize().height);
154 idPanel.idCanvas.setSize(d.width, seqPanel.seqCanvas.getSize().height);
155 annotationSpaceFillerHolder.setSize(d.width,
156 annotationPanel.getSize().height);
157 alabels.setSize(d.width, annotationPanel.getSize().height);
158 final AlignmentPanel ap = this;
159 av.addPropertyChangeListener(new java.beans.PropertyChangeListener()
162 public void propertyChange(java.beans.PropertyChangeEvent evt)
164 if (evt.getPropertyName().equals("alignment"))
166 PaintRefresher.Refresh(ap, av.getSequenceSetId(), true, true);
171 av.getRanges().addPropertyChangeListener(this);
175 public AlignViewportI getAlignViewport()
180 public SequenceRenderer getSequenceRenderer()
182 return seqPanel.seqCanvas.sr;
186 public jalview.api.FeatureRenderer getFeatureRenderer()
188 return seqPanel.seqCanvas.fr;
192 public jalview.api.FeatureRenderer cloneFeatureRenderer()
194 FeatureRenderer nfr = new FeatureRenderer(av);
195 nfr.transferSettings(seqPanel.seqCanvas.fr);
199 public void alignmentChanged()
201 av.alignmentChanged(this);
203 if (overviewPanel != null)
205 overviewPanel.updateOverviewImage();
208 alignFrame.updateEditMenuBar();
213 public void fontChanged()
215 // set idCanvas bufferedImage to null
216 // to prevent drawing old image
217 idPanel.idCanvas.image = null;
218 FontMetrics fm = getFontMetrics(av.getFont());
221 new Dimension(10, av.getCharHeight() + fm.getDescent()));
222 idwidthAdjuster.setSize(
223 new Dimension(10, av.getCharHeight() + fm.getDescent()));
224 av.updateSequenceIdColours();
225 annotationPanel.image = null;
226 int ap = annotationPanel.adjustPanelHeight(false);
227 Dimension d = calculateIdWidth();
228 d.setSize(d.width + 4, seqPanel.seqCanvas.getSize().height);
229 alabels.setSize(d.width + 4, ap);
231 idPanel.idCanvas.setSize(d);
232 hscrollFillerPanel.setSize(d);
234 validateAnnotationDimensions(false);
235 annotationPanel.repaint();
240 public void setIdWidth(int w, int h)
242 idPanel.idCanvas.setSize(w, h);
243 idPanelHolder.setSize(w, idPanelHolder.getSize().height);
244 annotationSpaceFillerHolder.setSize(w,
245 annotationSpaceFillerHolder.getSize().height);
246 alabels.setSize(w, alabels.getSize().height);
250 Dimension calculateIdWidth()
252 if (av.nullFrame == null)
254 av.nullFrame = new Frame();
255 av.nullFrame.addNotify();
258 Graphics g = av.nullFrame.getGraphics();
260 FontMetrics fm = g.getFontMetrics(av.font);
261 AlignmentI al = av.getAlignment();
266 while (i < al.getHeight() && al.getSequenceAt(i) != null)
268 SequenceI s = al.getSequenceAt(i);
269 id = s.getDisplayId(av.getShowJVSuffix());
271 if (fm.stringWidth(id) > idWidth)
273 idWidth = fm.stringWidth(id);
278 // Also check annotation label widths
280 if (al.getAlignmentAnnotation() != null)
282 fm = g.getFontMetrics(av.nullFrame.getFont());
283 while (i < al.getAlignmentAnnotation().length)
285 String label = al.getAlignmentAnnotation()[i].label;
286 if (fm.stringWidth(label) > idWidth)
288 idWidth = fm.stringWidth(label);
294 return new Dimension(idWidth, idPanel.idCanvas.getSize().height);
298 * Highlight the given results on the alignment.
301 public void highlightSearchResults(SearchResultsI results)
303 scrollToPosition(results);
304 seqPanel.seqCanvas.highlightSearchResults(results);
308 * scroll the view to show the position of the highlighted region in results
309 * (if any) and redraw the overview
312 * @return false if results were not found
314 public boolean scrollToPosition(SearchResultsI results)
316 return scrollToPosition(results, true);
320 * scroll the view to show the position of the highlighted region in results
324 * @param redrawOverview
325 * - when set, the overview will be recalculated (takes longer)
326 * @return false if results were not found
328 public boolean scrollToPosition(SearchResultsI results,
329 boolean redrawOverview)
331 return scrollToPosition(results, 0, redrawOverview, false);
335 * scroll the view to show the position of the highlighted region in results
339 * @param redrawOverview
340 * - when set, the overview will be recalculated (takes longer)
341 * @return false if results were not found
343 public boolean scrollToPosition(SearchResultsI results,
344 int verticalOffset, boolean redrawOverview, boolean centre)
346 // do we need to scroll the panel?
347 if (results != null && results.getSize() > 0)
349 AlignmentI alignment = av.getAlignment();
350 int seqIndex = alignment.findIndex(results);
356 * allow for offset of target sequence (actually scroll to one above it)
359 SequenceI seq = alignment.getSequenceAt(seqIndex);
360 int[] r = results.getResults(seq, 0, alignment.getWidth());
363 if (JalviewLite.debug)
366 "DEBUG: scroll didn't happen - results not within alignment : "
367 + seq.getStart() + "," + seq.getEnd());
371 if (JalviewLite.debug)
375 * System.out.println("DEBUG: scroll: start=" + r[0] +
376 * " av.getStartRes()=" + av.getStartRes() + " end=" + r[1] +
377 * " seq.end=" + seq.getEnd() + " av.getEndRes()=" + av.getEndRes() +
378 * " hextent=" + hextent);
385 * To centre results, scroll to positions half the visible width
386 * left/right of the start/end positions
390 int offset = (vpRanges.getEndRes() - vpRanges.getStartRes() + 1) / 2
392 start = Math.max(start - offset, 0);
393 end = end + offset - 1;
394 // end = Math.min(end + offset, seq.getEnd() - 1);
401 if (end == seq.getEnd())
407 * allow for offset of target sequence (actually scroll to one above it)
409 seqIndex = Math.max(0, seqIndex - verticalOffset);
410 return scrollTo(start, end, seqIndex, false, redrawOverview);
415 public boolean scrollTo(int ostart, int end, int seqIndex,
416 boolean scrollToNearest, boolean redrawOverview)
418 int startv, endv, starts, ends, width;
421 if (av.hasHiddenColumns())
423 AlignmentI al = av.getAlignment();
424 start = al.getHiddenColumns().findColumnPosition(ostart);
425 end = al.getHiddenColumns().findColumnPosition(end);
428 if (!scrollToNearest && !al.getHiddenColumns().isVisible(ostart))
430 // don't scroll - position isn't visible
440 if (!av.getWrapAlignment())
443 * int spos=av.getStartRes(),sqpos=av.getStartSeq(); if ((startv =
444 * av.getStartRes()) >= start) { spos=start-1; // seqIn //
445 * setScrollValues(start - 1, seqIndex); } else if ((endv =
446 * av.getEndRes()) <= end) { // setScrollValues(spos=startv + 1 + end -
447 * endv, seqIndex); spos=startv + 1 + end - endv; } else if ((starts =
448 * av.getStartSeq()) > seqIndex) { setScrollValues(av.getStartRes(),
449 * seqIndex); } else if ((ends = av.getEndSeq()) <= seqIndex) {
450 * setScrollValues(av.getStartRes(), starts + seqIndex - ends + 1); }
453 // below is scrolling logic up to Jalview 2.8.2
454 // if ((av.getStartRes() > end)
455 // || (av.getEndRes() < start)
456 // || ((av.getStartSeq() > seqIndex) || (av.getEndSeq() < seqIndex)))
458 // if (start > av.getAlignment().getWidth() - hextent)
460 // start = av.getAlignment().getWidth() - hextent;
467 // if (seqIndex > av.getAlignment().getHeight() - vextent)
469 // seqIndex = av.getAlignment().getHeight() - vextent;
475 // setScrollValues(start, seqIndex);
477 // logic copied from jalview.gui.AlignmentPanel:
478 if ((startv = vpRanges.getStartRes()) >= start)
481 * Scroll left to make start of search results visible
483 setScrollValues(start - 1, seqIndex);
485 else if ((endv = vpRanges.getEndRes()) <= end)
488 * Scroll right to make end of search results visible
490 setScrollValues(startv + 1 + end - endv, seqIndex);
492 else if ((starts = vpRanges.getStartSeq()) > seqIndex)
495 * Scroll up to make start of search results visible
497 setScrollValues(vpRanges.getStartRes(), seqIndex);
499 else if ((ends = vpRanges.getEndSeq()) <= seqIndex)
502 * Scroll down to make end of search results visible
504 setScrollValues(vpRanges.getStartRes(),
505 starts + seqIndex - ends + 1);
508 * Else results are already visible - no need to scroll
513 vpRanges.scrollToWrappedVisible(start);
516 paintAlignment(redrawOverview);
520 public OverviewPanel getOverviewPanel()
522 return overviewPanel;
525 public void setOverviewPanel(OverviewPanel op)
530 public void setAnnotationVisible(boolean b)
532 if (!av.getWrapAlignment())
534 annotationSpaceFillerHolder.setVisible(b);
535 annotationPanelHolder.setVisible(b);
539 annotationSpaceFillerHolder.setVisible(false);
540 annotationPanelHolder.setVisible(false);
547 * automatically adjust annotation panel height for new annotation whilst
548 * ensuring the alignment is still visible.
551 public void adjustAnnotationHeight()
553 // TODO: display vertical annotation scrollbar if necessary
554 // this is called after loading new annotation onto alignment
555 if (alignFrame.getSize().height == 0)
558 "adjustAnnotationHeight frame size zero NEEDS FIXING");
561 validateAnnotationDimensions(true);
562 apvscroll.addNotify();
565 paintAlignment(true);
569 * Calculate the annotation dimensions and refresh slider values accordingly.
570 * Need to do repaints/notifys afterwards.
572 protected void validateAnnotationDimensions(boolean adjustPanelHeight)
574 int rowHeight = av.getCharHeight();
575 int alignmentHeight = rowHeight * av.getAlignment().getHeight();
576 int annotationHeight = av.calcPanelHeight();
578 int mheight = annotationHeight;
579 Dimension d = sequenceHolderPanel.getSize();
581 int availableHeight = d.height - scalePanelHolder.getHeight();
583 if (adjustPanelHeight)
586 * If not enough vertical space, maximize annotation height while keeping
587 * at least two rows of alignment visible
589 if (annotationHeight + alignmentHeight > availableHeight)
591 annotationHeight = Math.min(annotationHeight,
592 availableHeight - 2 * rowHeight);
597 // maintain same window layout whilst updating sliders
598 annotationHeight = annotationPanelHolder.getSize().height;
601 if (availableHeight - annotationHeight < 5)
603 annotationHeight = availableHeight;
606 annotationPanel.setSize(new Dimension(d.width, annotationHeight));
607 annotationPanelHolder.setSize(new Dimension(d.width, annotationHeight));
608 // seqPanelHolder.setSize(d.width, seqandannot - height);
609 seqPanel.seqCanvas.setSize(d.width,
610 seqPanel.seqCanvas.getSize().height);
612 Dimension e = idPanel.getSize();
613 alabels.setSize(new Dimension(e.width, annotationHeight));
614 annotationSpaceFillerHolder
615 .setSize(new Dimension(e.width, annotationHeight));
617 int s = apvscroll.getValue();
618 if (s > mheight - annotationHeight)
622 apvscroll.setValues(s, annotationHeight, 0, mheight);
623 annotationPanel.setScrollOffset(apvscroll.getValue(), false);
624 alabels.setScrollOffset(apvscroll.getValue(), false);
627 public void setWrapAlignment(boolean wrap)
629 vpRanges.setStartEndSeq(0, vpRanges.getVisibleAlignmentHeight());
630 vpRanges.setStartRes(0);
631 scalePanelHolder.setVisible(!wrap);
633 hscroll.setVisible(!wrap);
634 idwidthAdjuster.setVisible(!wrap);
638 annotationPanelHolder.setVisible(false);
639 annotationSpaceFillerHolder.setVisible(false);
641 else if (av.isShowAnnotation())
643 annotationPanelHolder.setVisible(true);
644 annotationSpaceFillerHolder.setVisible(true);
647 idSpaceFillerPanel1.setVisible(!wrap);
649 fontChanged(); // This is so that the scalePanel is resized correctly
652 sequenceHolderPanel.validate();
661 public void setScrollValues(int xpos, int ypos)
666 if (av.getWrapAlignment())
668 setScrollingForWrappedPanel(x);
672 int width = av.getAlignment().getWidth();
673 int height = av.getAlignment().getHeight();
675 if (av.hasHiddenColumns())
677 width = av.getAlignment().getHiddenColumns()
678 .findColumnPosition(width);
685 hextent = seqPanel.seqCanvas.getSize().width / av.getCharWidth();
686 vextent = seqPanel.seqCanvas.getSize().height / av.getCharHeight();
693 if (vextent > height)
698 if ((hextent + x) > width)
700 System.err.println("hextent was " + hextent + " and x was " + x);
705 if ((vextent + y) > height)
707 y = height - vextent;
717 System.err.println("x was " + x);
721 hscroll.setValues(x, hextent, 0, width);
722 vscroll.setValues(y, vextent, 0, height);
724 // AWT scrollbar does not fire adjustmentValueChanged for setValues
725 // so also call adjustment code!
734 * Respond to adjustment event when horizontal or vertical scrollbar is
738 * adjustment event encoding whether apvscroll, hscroll or vscroll
742 public void adjustmentValueChanged(AdjustmentEvent evt)
744 // Note that this event is NOT fired by the AWT scrollbar when setValues is
745 // called. Instead manually call adjustHorizontal and adjustVertical
747 if (evt == null || evt.getSource() == apvscroll)
749 annotationPanel.setScrollOffset(apvscroll.getValue(), false);
750 alabels.setScrollOffset(apvscroll.getValue(), false);
752 if (evt == null || evt.getSource() == hscroll)
754 int x = hscroll.getValue();
758 if (evt == null || evt.getSource() == vscroll)
760 int offy = vscroll.getValue();
761 adjustVertical(offy);
766 private void adjustHorizontal(int x)
768 int oldX = vpRanges.getStartRes();
769 int oldwidth = vpRanges.getViewportWidth();
770 int width = seqPanel.seqCanvas.getWidth() / av.getCharWidth();
772 // if we're scrolling to the position we're already at, stop
773 // this prevents infinite recursion of events when the scroll/viewport
774 // ranges values are the same
775 if ((x == oldX) && (width == oldwidth))
779 vpRanges.setViewportStartAndWidth(x, width);
781 if (av.getWrapAlignment() || !fastPaint)
788 private void adjustVertical(int newY)
790 if (av.getWrapAlignment())
793 * if we're scrolling to the position we're already at, stop
794 * this prevents infinite recursion of events when the scroll/viewport
795 * ranges values are the same
797 int oldX = vpRanges.getStartRes();
798 int oldY = vpRanges.getWrappedScrollPosition(oldX);
806 * limit page up/down to one width's worth of positions
808 int rowSize = vpRanges.getViewportWidth();
809 int newX = newY > oldY ? oldX + rowSize : oldX - rowSize;
810 vpRanges.setViewportStartAndWidth(Math.max(0, newX), rowSize);
815 int height = seqPanel.seqCanvas.getHeight() / av.getCharHeight();
816 int oldY = vpRanges.getStartSeq();
817 int oldheight = vpRanges.getViewportHeight();
819 // if we're scrolling to the position we're already at, stop
820 // this prevents infinite recursion of events when the scroll/viewport
821 // ranges values are the same
822 if ((newY == oldY) && (height == oldheight))
826 vpRanges.setViewportStartAndHeight(newY, height);
828 if (av.getWrapAlignment() || !fastPaint)
836 * A helper method to return the AlignmentPanel in the other (complementary)
837 * half of a SplitFrame view. Returns null if not in a SplitFrame.
841 private AlignmentPanel getComplementPanel()
843 AlignmentPanel ap = null;
844 if (alignFrame != null)
846 SplitFrame sf = alignFrame.getSplitFrame();
849 AlignFrame other = sf.getComplement(alignFrame);
852 ap = other.alignPanel;
860 * Follow a scrolling change in the (cDNA/Protein) complementary alignment.
861 * The aim is to keep the two alignments 'lined up' on their centre columns.
864 * holds mapped region(s) of this alignment that we are scrolling
865 * 'to'; may be modified for sequence offset by this method
867 * the number of visible sequences to show above the mapped region
869 protected void scrollToCentre(SearchResultsI sr, int seqOffset)
872 * To avoid jumpy vertical scrolling (if some sequences are gapped or not
873 * mapped), we can make the scroll-to location a sequence above the one
876 SequenceI mappedTo = sr.getResults().get(0).getSequence();
877 List<SequenceI> seqs = av.getAlignment().getSequences();
880 * This is like AlignmentI.findIndex(seq) but here we are matching the
881 * dataset sequence not the aligned sequence
883 boolean matched = false;
884 for (SequenceI seq : seqs)
886 if (mappedTo == seq.getDatasetSequence())
894 return; // failsafe, shouldn't happen
898 * Scroll to position but centring the target residue. Also set a state flag
899 * to prevent adjustmentValueChanged performing this recursively.
901 scrollToPosition(sr, seqOffset, true, true);
904 private void sendViewPosition()
906 StructureSelectionManager.getStructureSelectionManager(av.applet)
907 .sendViewPosition(this, vpRanges.getStartRes(),
908 vpRanges.getEndRes(), vpRanges.getStartSeq(),
909 vpRanges.getEndSeq());
913 * Repaint the alignment and annotations, and, optionally, any overview window
916 public void paintAlignment(boolean updateOverview)
918 final AnnotationSorter sorter = new AnnotationSorter(getAlignment(),
919 av.isShowAutocalculatedAbove());
920 sorter.sort(getAlignment().getAlignmentAnnotation(),
921 av.getSortAnnotationsBy());
926 // TODO: determine if this paintAlignment changed structure colours
927 jalview.structure.StructureSelectionManager
928 .getStructureSelectionManager(av.applet)
929 .sequenceColoursChanged(this);
931 if (overviewPanel != null)
933 overviewPanel.updateOverviewImage();
939 public void update(Graphics g)
945 public void paint(Graphics g)
948 Dimension d = idPanel.idCanvas.getSize();
949 final int canvasHeight = seqPanel.seqCanvas.getSize().height;
950 if (canvasHeight != d.height)
952 idPanel.idCanvas.setSize(d.width, canvasHeight);
955 setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq());
957 seqPanel.seqCanvas.repaint();
958 idPanel.idCanvas.repaint();
959 if (!av.getWrapAlignment())
961 if (av.isShowAnnotation())
964 annotationPanel.repaint();
966 scalePanel.repaint();
972 * Set vertical scroll bar parameters for wrapped panel
974 * @param topLeftColumn
975 * the column position at top left (0..)
977 private void setScrollingForWrappedPanel(int topLeftColumn)
979 int scrollPosition = vpRanges.getWrappedScrollPosition(topLeftColumn);
980 int maxScroll = vpRanges.getWrappedMaxScroll(topLeftColumn);
983 * a scrollbar's value can be set to at most (maximum-extent)
984 * so we add extent (1) to the maxScroll value
986 vscroll.setUnitIncrement(1);
987 vscroll.setValues(scrollPosition, 1, 0, maxScroll + 1);
990 protected Panel sequenceHolderPanel = new Panel();
992 protected Scrollbar vscroll = new Scrollbar();
994 protected Scrollbar hscroll = new Scrollbar();
996 protected Panel seqPanelHolder = new Panel();
998 protected Panel scalePanelHolder = new Panel();
1000 protected Panel idPanelHolder = new Panel();
1002 protected Panel idSpaceFillerPanel1 = new Panel();
1004 public Panel annotationSpaceFillerHolder = new Panel();
1006 protected Panel hscrollFillerPanel = new Panel();
1008 Panel annotationPanelHolder = new Panel();
1010 protected Scrollbar apvscroll = new Scrollbar();
1013 * Flag set while scrolling to follow complementary cDNA/protein scroll. When
1014 * false, suppresses invoking the same method recursively.
1016 private boolean scrollComplementaryPanel = true;
1018 private void jbInit() throws Exception
1020 // idPanelHolder.setPreferredSize(new Dimension(70, 10));
1021 this.setLayout(new BorderLayout());
1023 // sequenceHolderPanel.setPreferredSize(new Dimension(150, 150));
1024 sequenceHolderPanel.setLayout(new BorderLayout());
1025 seqPanelHolder.setLayout(new BorderLayout());
1026 scalePanelHolder.setBackground(Color.white);
1028 // scalePanelHolder.setPreferredSize(new Dimension(10, 30));
1029 scalePanelHolder.setLayout(new BorderLayout());
1030 idPanelHolder.setLayout(new BorderLayout());
1031 idSpaceFillerPanel1.setBackground(Color.white);
1033 // idSpaceFillerPanel1.setPreferredSize(new Dimension(10, 30));
1034 idSpaceFillerPanel1.setLayout(new BorderLayout());
1035 annotationSpaceFillerHolder.setBackground(Color.white);
1037 // annotationSpaceFillerHolder.setPreferredSize(new Dimension(10, 80));
1038 annotationSpaceFillerHolder.setLayout(new BorderLayout());
1039 hscroll.setOrientation(Scrollbar.HORIZONTAL);
1041 Panel hscrollHolder = new Panel();
1042 hscrollHolder.setLayout(new BorderLayout());
1043 hscrollFillerPanel.setBackground(Color.white);
1044 apvscroll.setOrientation(Scrollbar.VERTICAL);
1045 apvscroll.setVisible(true);
1046 apvscroll.addAdjustmentListener(this);
1048 annotationPanelHolder.setBackground(Color.white);
1049 annotationPanelHolder.setLayout(new BorderLayout());
1050 annotationPanelHolder.add(apvscroll, BorderLayout.EAST);
1051 // hscrollFillerPanel.setPreferredSize(new Dimension(70, 10));
1052 hscrollHolder.setBackground(Color.white);
1054 // annotationScroller.setPreferredSize(new Dimension(10, 80));
1055 // this.setPreferredSize(new Dimension(220, 166));
1056 seqPanelHolder.setBackground(Color.white);
1057 idPanelHolder.setBackground(Color.white);
1058 sequenceHolderPanel.add(scalePanelHolder, BorderLayout.NORTH);
1059 sequenceHolderPanel.add(seqPanelHolder, BorderLayout.CENTER);
1060 seqPanelHolder.add(vscroll, BorderLayout.EAST);
1062 // Panel3.add(secondaryPanelHolder, BorderLayout.SOUTH);
1063 this.add(idPanelHolder, BorderLayout.WEST);
1064 idPanelHolder.add(idSpaceFillerPanel1, BorderLayout.NORTH);
1065 idPanelHolder.add(annotationSpaceFillerHolder, BorderLayout.SOUTH);
1066 this.add(hscrollHolder, BorderLayout.SOUTH);
1067 hscrollHolder.add(hscroll, BorderLayout.CENTER);
1068 hscrollHolder.add(hscrollFillerPanel, BorderLayout.WEST);
1069 this.add(sequenceHolderPanel, BorderLayout.CENTER);
1073 * hides or shows dynamic annotation rows based on groups and av state flags
1075 public void updateAnnotation()
1077 updateAnnotation(false);
1080 public void updateAnnotation(boolean applyGlobalSettings)
1082 updateAnnotation(applyGlobalSettings, false);
1085 public void updateAnnotation(boolean applyGlobalSettings,
1086 boolean preserveNewGroupSettings)
1088 av.updateGroupAnnotationSettings(applyGlobalSettings,
1089 preserveNewGroupSettings);
1090 adjustAnnotationHeight();
1094 public AlignmentI getAlignment()
1096 return av.getAlignment();
1100 public String getViewName()
1106 public StructureSelectionManager getStructureSelectionManager()
1108 return StructureSelectionManager
1109 .getStructureSelectionManager(av.applet);
1113 public void raiseOOMWarning(String string, OutOfMemoryError error)
1116 System.err.println("Out of memory whilst '" + string + "'");
1117 error.printStackTrace();
1121 * Set a flag to say we are scrolling to follow a (cDNA/protein) complement.
1125 protected void setToScrollComplementPanel(boolean b)
1127 this.scrollComplementaryPanel = b;
1131 * Get whether to scroll complement panel
1133 * @return true if cDNA/protein complement panels should be scrolled
1135 protected boolean isSetToScrollComplementPanel()
1137 return this.scrollComplementaryPanel;
1142 * Property change event fired when a change is made to the viewport ranges
1143 * object associated with this alignment panel's viewport
1145 public void propertyChange(PropertyChangeEvent evt)
1147 // update this panel's scroll values based on the new viewport ranges values
1148 int x = vpRanges.getStartRes();
1149 int y = vpRanges.getStartSeq();
1150 setScrollValues(x, y);
1152 // now update any complementary alignment (its viewport ranges object
1153 // is different so does not get automatically updated)
1154 if (isSetToScrollComplementPanel())
1156 setToScrollComplementPanel(false);
1157 av.scrollComplementaryAlignment(getComplementPanel());
1158 setToScrollComplementPanel(true);