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().absoluteToVisibleColumn(ostart);
425 end = al.getHiddenColumns().absoluteToVisibleColumn(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, false);
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, false);
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().getVisibleWidth();
673 int height = av.getAlignment().getHeight();
680 hextent = seqPanel.seqCanvas.getSize().width / av.getCharWidth();
681 vextent = seqPanel.seqCanvas.getSize().height / av.getCharHeight();
688 if (vextent > height)
693 if ((hextent + x) > width)
695 System.err.println("hextent was " + hextent + " and x was " + x);
700 if ((vextent + y) > height)
702 y = height - vextent;
712 System.err.println("x was " + x);
716 hscroll.setValues(x, hextent, 0, width);
717 vscroll.setValues(y, vextent, 0, height);
719 // AWT scrollbar does not fire adjustmentValueChanged for setValues
720 // so also call adjustment code!
729 * Respond to adjustment event when horizontal or vertical scrollbar is
733 * adjustment event encoding whether apvscroll, hscroll or vscroll
737 public void adjustmentValueChanged(AdjustmentEvent evt)
739 // Note that this event is NOT fired by the AWT scrollbar when setValues is
740 // called. Instead manually call adjustHorizontal and adjustVertical
742 if (evt == null || evt.getSource() == apvscroll)
744 annotationPanel.setScrollOffset(apvscroll.getValue(), false);
745 alabels.setScrollOffset(apvscroll.getValue(), false);
747 if (evt == null || evt.getSource() == hscroll)
749 int x = hscroll.getValue();
753 if (evt == null || evt.getSource() == vscroll)
755 int offy = vscroll.getValue();
756 adjustVertical(offy);
761 private void adjustHorizontal(int x)
763 int oldX = vpRanges.getStartRes();
764 int oldwidth = vpRanges.getViewportWidth();
765 int width = seqPanel.seqCanvas.getWidth() / av.getCharWidth();
767 // if we're scrolling to the position we're already at, stop
768 // this prevents infinite recursion of events when the scroll/viewport
769 // ranges values are the same
770 if ((x == oldX) && (width == oldwidth))
774 vpRanges.setViewportStartAndWidth(x, width);
776 if (av.getWrapAlignment() || !fastPaint)
783 private void adjustVertical(int newY)
785 if (av.getWrapAlignment())
788 * if we're scrolling to the position we're already at, stop
789 * this prevents infinite recursion of events when the scroll/viewport
790 * ranges values are the same
792 int oldX = vpRanges.getStartRes();
793 int oldY = vpRanges.getWrappedScrollPosition(oldX);
801 * limit page up/down to one width's worth of positions
803 int rowSize = vpRanges.getViewportWidth();
804 int newX = newY > oldY ? oldX + rowSize : oldX - rowSize;
805 vpRanges.setViewportStartAndWidth(Math.max(0, newX), rowSize);
810 int height = seqPanel.seqCanvas.getHeight() / av.getCharHeight();
811 int oldY = vpRanges.getStartSeq();
812 int oldheight = vpRanges.getViewportHeight();
814 // if we're scrolling to the position we're already at, stop
815 // this prevents infinite recursion of events when the scroll/viewport
816 // ranges values are the same
817 if ((newY == oldY) && (height == oldheight))
821 vpRanges.setViewportStartAndHeight(newY, height);
823 if (av.getWrapAlignment() || !fastPaint)
831 * A helper method to return the AlignmentPanel in the other (complementary)
832 * half of a SplitFrame view. Returns null if not in a SplitFrame.
836 private AlignmentPanel getComplementPanel()
838 AlignmentPanel ap = null;
839 if (alignFrame != null)
841 SplitFrame sf = alignFrame.getSplitFrame();
844 AlignFrame other = sf.getComplement(alignFrame);
847 ap = other.alignPanel;
855 * Follow a scrolling change in the (cDNA/Protein) complementary alignment.
856 * The aim is to keep the two alignments 'lined up' on their centre columns.
859 * holds mapped region(s) of this alignment that we are scrolling
860 * 'to'; may be modified for sequence offset by this method
862 * the number of visible sequences to show above the mapped region
864 protected void scrollToCentre(SearchResultsI sr, int seqOffset)
867 * To avoid jumpy vertical scrolling (if some sequences are gapped or not
868 * mapped), we can make the scroll-to location a sequence above the one
871 SequenceI mappedTo = sr.getResults().get(0).getSequence();
872 List<SequenceI> seqs = av.getAlignment().getSequences();
875 * This is like AlignmentI.findIndex(seq) but here we are matching the
876 * dataset sequence not the aligned sequence
878 boolean matched = false;
879 for (SequenceI seq : seqs)
881 if (mappedTo == seq.getDatasetSequence())
889 return; // failsafe, shouldn't happen
893 * Scroll to position but centring the target residue. Also set a state flag
894 * to prevent adjustmentValueChanged performing this recursively.
896 scrollToPosition(sr, seqOffset, true, true);
899 private void sendViewPosition()
901 StructureSelectionManager.getStructureSelectionManager(av.applet)
902 .sendViewPosition(this, vpRanges.getStartRes(),
903 vpRanges.getEndRes(), vpRanges.getStartSeq(),
904 vpRanges.getEndSeq());
908 * Repaint the alignment and annotations, and, optionally, any overview window
911 public void paintAlignment(boolean updateOverview,
912 boolean updateStructures)
914 final AnnotationSorter sorter = new AnnotationSorter(getAlignment(),
915 av.isShowAutocalculatedAbove());
916 sorter.sort(getAlignment().getAlignmentAnnotation(),
917 av.getSortAnnotationsBy());
920 if (updateStructures)
922 jalview.structure.StructureSelectionManager
923 .getStructureSelectionManager(av.applet)
924 .sequenceColoursChanged(this);
928 if (overviewPanel != null)
930 overviewPanel.updateOverviewImage();
936 public void update(Graphics g)
942 public void paint(Graphics g)
945 Dimension d = idPanel.idCanvas.getSize();
946 final int canvasHeight = seqPanel.seqCanvas.getSize().height;
947 if (canvasHeight != d.height)
949 idPanel.idCanvas.setSize(d.width, canvasHeight);
952 setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq());
954 seqPanel.seqCanvas.repaint();
955 idPanel.idCanvas.repaint();
956 if (!av.getWrapAlignment())
958 if (av.isShowAnnotation())
961 annotationPanel.repaint();
963 scalePanel.repaint();
969 * Set vertical scroll bar parameters for wrapped panel
971 * @param topLeftColumn
972 * the column position at top left (0..)
974 private void setScrollingForWrappedPanel(int topLeftColumn)
976 int scrollPosition = vpRanges.getWrappedScrollPosition(topLeftColumn);
977 int maxScroll = vpRanges.getWrappedMaxScroll(topLeftColumn);
980 * a scrollbar's value can be set to at most (maximum-extent)
981 * so we add extent (1) to the maxScroll value
983 vscroll.setUnitIncrement(1);
984 vscroll.setValues(scrollPosition, 1, 0, maxScroll + 1);
987 protected Panel sequenceHolderPanel = new Panel();
989 protected Scrollbar vscroll = new Scrollbar();
991 protected Scrollbar hscroll = new Scrollbar();
993 protected Panel seqPanelHolder = new Panel();
995 protected Panel scalePanelHolder = new Panel();
997 protected Panel idPanelHolder = new Panel();
999 protected Panel idSpaceFillerPanel1 = new Panel();
1001 public Panel annotationSpaceFillerHolder = new Panel();
1003 protected Panel hscrollFillerPanel = new Panel();
1005 Panel annotationPanelHolder = new Panel();
1007 protected Scrollbar apvscroll = new Scrollbar();
1010 * Flag set while scrolling to follow complementary cDNA/protein scroll. When
1011 * false, suppresses invoking the same method recursively.
1013 private boolean scrollComplementaryPanel = true;
1015 private void jbInit() throws Exception
1017 // idPanelHolder.setPreferredSize(new Dimension(70, 10));
1018 this.setLayout(new BorderLayout());
1020 // sequenceHolderPanel.setPreferredSize(new Dimension(150, 150));
1021 sequenceHolderPanel.setLayout(new BorderLayout());
1022 seqPanelHolder.setLayout(new BorderLayout());
1023 scalePanelHolder.setBackground(Color.white);
1025 // scalePanelHolder.setPreferredSize(new Dimension(10, 30));
1026 scalePanelHolder.setLayout(new BorderLayout());
1027 idPanelHolder.setLayout(new BorderLayout());
1028 idSpaceFillerPanel1.setBackground(Color.white);
1030 // idSpaceFillerPanel1.setPreferredSize(new Dimension(10, 30));
1031 idSpaceFillerPanel1.setLayout(new BorderLayout());
1032 annotationSpaceFillerHolder.setBackground(Color.white);
1034 // annotationSpaceFillerHolder.setPreferredSize(new Dimension(10, 80));
1035 annotationSpaceFillerHolder.setLayout(new BorderLayout());
1036 hscroll.setOrientation(Scrollbar.HORIZONTAL);
1038 Panel hscrollHolder = new Panel();
1039 hscrollHolder.setLayout(new BorderLayout());
1040 hscrollFillerPanel.setBackground(Color.white);
1041 apvscroll.setOrientation(Scrollbar.VERTICAL);
1042 apvscroll.setVisible(true);
1043 apvscroll.addAdjustmentListener(this);
1045 annotationPanelHolder.setBackground(Color.white);
1046 annotationPanelHolder.setLayout(new BorderLayout());
1047 annotationPanelHolder.add(apvscroll, BorderLayout.EAST);
1048 // hscrollFillerPanel.setPreferredSize(new Dimension(70, 10));
1049 hscrollHolder.setBackground(Color.white);
1051 // annotationScroller.setPreferredSize(new Dimension(10, 80));
1052 // this.setPreferredSize(new Dimension(220, 166));
1053 seqPanelHolder.setBackground(Color.white);
1054 idPanelHolder.setBackground(Color.white);
1055 sequenceHolderPanel.add(scalePanelHolder, BorderLayout.NORTH);
1056 sequenceHolderPanel.add(seqPanelHolder, BorderLayout.CENTER);
1057 seqPanelHolder.add(vscroll, BorderLayout.EAST);
1059 // Panel3.add(secondaryPanelHolder, BorderLayout.SOUTH);
1060 this.add(idPanelHolder, BorderLayout.WEST);
1061 idPanelHolder.add(idSpaceFillerPanel1, BorderLayout.NORTH);
1062 idPanelHolder.add(annotationSpaceFillerHolder, BorderLayout.SOUTH);
1063 this.add(hscrollHolder, BorderLayout.SOUTH);
1064 hscrollHolder.add(hscroll, BorderLayout.CENTER);
1065 hscrollHolder.add(hscrollFillerPanel, BorderLayout.WEST);
1066 this.add(sequenceHolderPanel, BorderLayout.CENTER);
1070 * hides or shows dynamic annotation rows based on groups and av state flags
1072 public void updateAnnotation()
1074 updateAnnotation(false);
1077 public void updateAnnotation(boolean applyGlobalSettings)
1079 updateAnnotation(applyGlobalSettings, false);
1082 public void updateAnnotation(boolean applyGlobalSettings,
1083 boolean preserveNewGroupSettings)
1085 av.updateGroupAnnotationSettings(applyGlobalSettings,
1086 preserveNewGroupSettings);
1087 adjustAnnotationHeight();
1091 public AlignmentI getAlignment()
1093 return av.getAlignment();
1097 public String getViewName()
1103 public StructureSelectionManager getStructureSelectionManager()
1105 return StructureSelectionManager
1106 .getStructureSelectionManager(av.applet);
1110 public void raiseOOMWarning(String string, OutOfMemoryError error)
1113 System.err.println("Out of memory whilst '" + string + "'");
1114 error.printStackTrace();
1118 * Set a flag to say we are scrolling to follow a (cDNA/protein) complement.
1122 protected void setToScrollComplementPanel(boolean b)
1124 this.scrollComplementaryPanel = b;
1128 * Get whether to scroll complement panel
1130 * @return true if cDNA/protein complement panels should be scrolled
1132 protected boolean isSetToScrollComplementPanel()
1134 return this.scrollComplementaryPanel;
1139 * Property change event fired when a change is made to the viewport ranges
1140 * object associated with this alignment panel's viewport
1142 public void propertyChange(PropertyChangeEvent evt)
1144 // update this panel's scroll values based on the new viewport ranges values
1145 int x = vpRanges.getStartRes();
1146 int y = vpRanges.getStartSeq();
1147 setScrollValues(x, y);
1149 // now update any complementary alignment (its viewport ranges object
1150 // is different so does not get automatically updated)
1151 if (isSetToScrollComplementPanel())
1153 setToScrollComplementPanel(false);
1154 av.scrollComplementaryAlignment(getComplementPanel());
1155 setToScrollComplementPanel(true);