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().getWidth();
673 int height = av.getAlignment().getHeight();
675 if (av.hasHiddenColumns())
677 width = av.getAlignment().getHiddenColumns()
678 .absoluteToVisibleColumn(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,
917 boolean updateStructures)
919 final AnnotationSorter sorter = new AnnotationSorter(getAlignment(),
920 av.isShowAutocalculatedAbove());
921 sorter.sort(getAlignment().getAlignmentAnnotation(),
922 av.getSortAnnotationsBy());
925 if (updateStructures)
927 jalview.structure.StructureSelectionManager
928 .getStructureSelectionManager(av.applet)
929 .sequenceColoursChanged(this);
933 if (overviewPanel != null)
935 overviewPanel.updateOverviewImage();
941 public void update(Graphics g)
947 public void paint(Graphics g)
950 Dimension d = idPanel.idCanvas.getSize();
951 final int canvasHeight = seqPanel.seqCanvas.getSize().height;
952 if (canvasHeight != d.height)
954 idPanel.idCanvas.setSize(d.width, canvasHeight);
957 setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq());
959 seqPanel.seqCanvas.repaint();
960 idPanel.idCanvas.repaint();
961 if (!av.getWrapAlignment())
963 if (av.isShowAnnotation())
966 annotationPanel.repaint();
968 scalePanel.repaint();
974 * Set vertical scroll bar parameters for wrapped panel
976 * @param topLeftColumn
977 * the column position at top left (0..)
979 private void setScrollingForWrappedPanel(int topLeftColumn)
981 int scrollPosition = vpRanges.getWrappedScrollPosition(topLeftColumn);
982 int maxScroll = vpRanges.getWrappedMaxScroll(topLeftColumn);
985 * a scrollbar's value can be set to at most (maximum-extent)
986 * so we add extent (1) to the maxScroll value
988 vscroll.setUnitIncrement(1);
989 vscroll.setValues(scrollPosition, 1, 0, maxScroll + 1);
992 protected Panel sequenceHolderPanel = new Panel();
994 protected Scrollbar vscroll = new Scrollbar();
996 protected Scrollbar hscroll = new Scrollbar();
998 protected Panel seqPanelHolder = new Panel();
1000 protected Panel scalePanelHolder = new Panel();
1002 protected Panel idPanelHolder = new Panel();
1004 protected Panel idSpaceFillerPanel1 = new Panel();
1006 public Panel annotationSpaceFillerHolder = new Panel();
1008 protected Panel hscrollFillerPanel = new Panel();
1010 Panel annotationPanelHolder = new Panel();
1012 protected Scrollbar apvscroll = new Scrollbar();
1015 * Flag set while scrolling to follow complementary cDNA/protein scroll. When
1016 * false, suppresses invoking the same method recursively.
1018 private boolean scrollComplementaryPanel = true;
1020 private void jbInit() throws Exception
1022 // idPanelHolder.setPreferredSize(new Dimension(70, 10));
1023 this.setLayout(new BorderLayout());
1025 // sequenceHolderPanel.setPreferredSize(new Dimension(150, 150));
1026 sequenceHolderPanel.setLayout(new BorderLayout());
1027 seqPanelHolder.setLayout(new BorderLayout());
1028 scalePanelHolder.setBackground(Color.white);
1030 // scalePanelHolder.setPreferredSize(new Dimension(10, 30));
1031 scalePanelHolder.setLayout(new BorderLayout());
1032 idPanelHolder.setLayout(new BorderLayout());
1033 idSpaceFillerPanel1.setBackground(Color.white);
1035 // idSpaceFillerPanel1.setPreferredSize(new Dimension(10, 30));
1036 idSpaceFillerPanel1.setLayout(new BorderLayout());
1037 annotationSpaceFillerHolder.setBackground(Color.white);
1039 // annotationSpaceFillerHolder.setPreferredSize(new Dimension(10, 80));
1040 annotationSpaceFillerHolder.setLayout(new BorderLayout());
1041 hscroll.setOrientation(Scrollbar.HORIZONTAL);
1043 Panel hscrollHolder = new Panel();
1044 hscrollHolder.setLayout(new BorderLayout());
1045 hscrollFillerPanel.setBackground(Color.white);
1046 apvscroll.setOrientation(Scrollbar.VERTICAL);
1047 apvscroll.setVisible(true);
1048 apvscroll.addAdjustmentListener(this);
1050 annotationPanelHolder.setBackground(Color.white);
1051 annotationPanelHolder.setLayout(new BorderLayout());
1052 annotationPanelHolder.add(apvscroll, BorderLayout.EAST);
1053 // hscrollFillerPanel.setPreferredSize(new Dimension(70, 10));
1054 hscrollHolder.setBackground(Color.white);
1056 // annotationScroller.setPreferredSize(new Dimension(10, 80));
1057 // this.setPreferredSize(new Dimension(220, 166));
1058 seqPanelHolder.setBackground(Color.white);
1059 idPanelHolder.setBackground(Color.white);
1060 sequenceHolderPanel.add(scalePanelHolder, BorderLayout.NORTH);
1061 sequenceHolderPanel.add(seqPanelHolder, BorderLayout.CENTER);
1062 seqPanelHolder.add(vscroll, BorderLayout.EAST);
1064 // Panel3.add(secondaryPanelHolder, BorderLayout.SOUTH);
1065 this.add(idPanelHolder, BorderLayout.WEST);
1066 idPanelHolder.add(idSpaceFillerPanel1, BorderLayout.NORTH);
1067 idPanelHolder.add(annotationSpaceFillerHolder, BorderLayout.SOUTH);
1068 this.add(hscrollHolder, BorderLayout.SOUTH);
1069 hscrollHolder.add(hscroll, BorderLayout.CENTER);
1070 hscrollHolder.add(hscrollFillerPanel, BorderLayout.WEST);
1071 this.add(sequenceHolderPanel, BorderLayout.CENTER);
1075 * hides or shows dynamic annotation rows based on groups and av state flags
1077 public void updateAnnotation()
1079 updateAnnotation(false);
1082 public void updateAnnotation(boolean applyGlobalSettings)
1084 updateAnnotation(applyGlobalSettings, false);
1087 public void updateAnnotation(boolean applyGlobalSettings,
1088 boolean preserveNewGroupSettings)
1090 av.updateGroupAnnotationSettings(applyGlobalSettings,
1091 preserveNewGroupSettings);
1092 adjustAnnotationHeight();
1096 public AlignmentI getAlignment()
1098 return av.getAlignment();
1102 public String getViewName()
1108 public StructureSelectionManager getStructureSelectionManager()
1110 return StructureSelectionManager
1111 .getStructureSelectionManager(av.applet);
1115 public void raiseOOMWarning(String string, OutOfMemoryError error)
1118 System.err.println("Out of memory whilst '" + string + "'");
1119 error.printStackTrace();
1123 * Set a flag to say we are scrolling to follow a (cDNA/protein) complement.
1127 protected void setToScrollComplementPanel(boolean b)
1129 this.scrollComplementaryPanel = b;
1133 * Get whether to scroll complement panel
1135 * @return true if cDNA/protein complement panels should be scrolled
1137 protected boolean isSetToScrollComplementPanel()
1139 return this.scrollComplementaryPanel;
1144 * Property change event fired when a change is made to the viewport ranges
1145 * object associated with this alignment panel's viewport
1147 public void propertyChange(PropertyChangeEvent evt)
1149 // update this panel's scroll values based on the new viewport ranges values
1150 int x = vpRanges.getStartRes();
1151 int y = vpRanges.getStartSeq();
1152 setScrollValues(x, y);
1154 // now update any complementary alignment (its viewport ranges object
1155 // is different so does not get automatically updated)
1156 if (isSetToScrollComplementPanel())
1158 setToScrollComplementPanel(false);
1159 av.scrollComplementaryAlignment(getComplementPanel());
1160 setToScrollComplementPanel(true);