2 * Jalview - A Sequence Alignment Editor and Viewer (Version 2.8.2)
3 * Copyright (C) 2014 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.
27 import java.awt.event.*;
28 import java.awt.print.*;
31 import jalview.api.AlignmentViewPanel;
32 import jalview.bin.Cache;
33 import jalview.datamodel.*;
34 import jalview.jbgui.*;
35 import jalview.schemes.*;
36 import jalview.structure.StructureSelectionManager;
42 * @version $Revision: 1.161 $
44 public class AlignmentPanel extends GAlignmentPanel implements
45 AdjustmentListener, Printable, AlignmentViewPanel
47 public AlignViewport av;
49 OverviewPanel overviewPanel;
55 IdwidthAdjuster idwidthAdjuster;
58 public AlignFrame alignFrame;
60 ScalePanel scalePanel;
62 AnnotationPanel annotationPanel;
64 AnnotationLabels alabels;
66 // this value is set false when selection area being dragged
67 boolean fastPaint = true;
74 * Creates a new AlignmentPanel object.
81 public AlignmentPanel(AlignFrame af, final AlignViewport av)
85 seqPanel = new SeqPanel(av, this);
86 idPanel = new IdPanel(av, this);
88 scalePanel = new ScalePanel(av, this);
90 idPanelHolder.add(idPanel, BorderLayout.CENTER);
91 idwidthAdjuster = new IdwidthAdjuster(this);
92 idSpaceFillerPanel1.add(idwidthAdjuster, BorderLayout.CENTER);
94 annotationPanel = new AnnotationPanel(this);
95 alabels = new AnnotationLabels(this);
97 annotationScroller.setViewportView(annotationPanel);
98 annotationSpaceFillerHolder.add(alabels, BorderLayout.CENTER);
100 scalePanelHolder.add(scalePanel, BorderLayout.CENTER);
101 seqPanelHolder.add(seqPanel, BorderLayout.CENTER);
103 setScrollValues(0, 0);
105 setAnnotationVisible(av.getShowAnnotation());
107 hscroll.addAdjustmentListener(this);
108 vscroll.addAdjustmentListener(this);
110 final AlignmentPanel ap = this;
111 av.addPropertyChangeListener(new PropertyChangeListener()
113 public void propertyChange(PropertyChangeEvent evt)
115 if (evt.getPropertyName().equals("alignment"))
117 PaintRefresher.Refresh(ap, av.getSequenceSetId(), true, true);
123 adjustAnnotationHeight();
127 public void alignmentChanged()
129 av.alignmentChanged(this);
131 alignFrame.updateEditMenuBar();
133 paintAlignment(true);
140 public void fontChanged()
142 // set idCanvas bufferedImage to null
143 // to prevent drawing old image
144 FontMetrics fm = getFontMetrics(av.getFont());
146 scalePanelHolder.setPreferredSize(new Dimension(10, av.charHeight
148 idSpaceFillerPanel1.setPreferredSize(new Dimension(10, av.charHeight
151 idPanel.idCanvas.gg = null;
152 seqPanel.seqCanvas.img = null;
153 annotationPanel.adjustPanelHeight();
155 Dimension d = calculateIdWidth();
156 d.setSize(d.width + 4, d.height);
157 idPanel.idCanvas.setPreferredSize(d);
158 hscrollFillerPanel.setPreferredSize(d);
160 if (overviewPanel != null)
162 overviewPanel.setBoxPosition();
169 * Calculate the width of the alignment labels based on the displayed names
170 * and any bounds on label width set in preferences.
172 * @return Dimension giving the maximum width of the alignment label panel
173 * that should be used.
175 public Dimension calculateIdWidth()
177 // calculate sensible default width when no preference is available
179 int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300);
180 int maxwidth = Math.max(20,
181 Math.min(afwidth - 200, (int) 2 * afwidth / 3));
182 return calculateIdWidth(maxwidth);
186 * Calculate the width of the alignment labels based on the displayed names
187 * and any bounds on label width set in preferences.
190 * -1 or maximum width allowed for IdWidth
191 * @return Dimension giving the maximum width of the alignment label panel
192 * that should be used.
194 public Dimension calculateIdWidth(int maxwidth)
196 Container c = new Container();
198 FontMetrics fm = c.getFontMetrics(new Font(av.font.getName(),
199 Font.ITALIC, av.font.getSize()));
201 AlignmentI al = av.getAlignment();
206 while ((i < al.getHeight()) && (al.getSequenceAt(i) != null))
208 SequenceI s = al.getSequenceAt(i);
210 id = s.getDisplayId(av.getShowJVSuffix());
212 if (fm.stringWidth(id) > idWidth)
214 idWidth = fm.stringWidth(id);
220 // Also check annotation label widths
223 if (al.getAlignmentAnnotation() != null)
225 fm = c.getFontMetrics(alabels.getFont());
227 while (i < al.getAlignmentAnnotation().length)
229 String label = al.getAlignmentAnnotation()[i].label;
231 if (fm.stringWidth(label) > idWidth)
233 idWidth = fm.stringWidth(label);
240 return new Dimension(maxwidth < 0 ? idWidth : Math.min(maxwidth,
245 * Highlight the given results on the alignment.
248 public void highlightSearchResults(SearchResults results)
250 scrollToPosition(results);
251 seqPanel.seqCanvas.highlightSearchResults(results);
255 * scroll the view to show the position of the highlighted region in results
256 * (if any) and redraw the overview
260 public boolean scrollToPosition(SearchResults results)
262 return scrollToPosition(results, true);
266 * scroll the view to show the position of the highlighted region in results
270 * @param redrawOverview
271 * - when set, the overview will be recalculated (takes longer)
272 * @return false if results were not found
274 public boolean scrollToPosition(SearchResults results,
275 boolean redrawOverview)
277 int startv, endv, starts, ends, width;
278 // TODO: properly locate search results in view when large numbers of hidden
279 // columns exist before highlighted region
280 // do we need to scroll the panel?
281 // TODO: tons of nullpointereexceptions raised here.
282 if (results != null && results.getSize() > 0 && av != null
283 && av.getAlignment() != null)
285 int seqIndex = av.getAlignment().findIndex(results);
290 SequenceI seq = av.getAlignment().getSequenceAt(seqIndex);
292 int[] r = results.getResults(seq, 0, av.getAlignment().getWidth());
299 // System.err.println("Seq : "+seqIndex+" Scroll to "+start+","+end); //
305 if (end == seq.getEnd())
309 if (av.hasHiddenColumns())
311 start = av.getColumnSelection().findColumnPosition(start);
312 end = av.getColumnSelection().findColumnPosition(end);
315 if (!av.getColumnSelection().isVisible(r[0]))
317 // don't scroll - position isn't visible
322 if (!av.wrapAlignment)
324 if ((startv = av.getStartRes()) >= start)
326 setScrollValues(start - 1, seqIndex);
328 else if ((endv = av.getEndRes()) <= end)
330 setScrollValues(startv + 1 + end - endv, seqIndex);
332 else if ((starts = av.getStartSeq()) > seqIndex)
334 setScrollValues(av.getStartRes(), seqIndex);
336 else if ((ends = av.getEndSeq()) <= seqIndex)
338 setScrollValues(av.getStartRes(), starts + seqIndex - ends + 1);
343 scrollToWrappedVisible(start);
346 if (redrawOverview && overviewPanel != null)
348 overviewPanel.setBoxPosition();
350 paintAlignment(redrawOverview);
354 void scrollToWrappedVisible(int res)
356 int cwidth = seqPanel.seqCanvas
357 .getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());
358 if (res < av.getStartRes() || res >= (av.getStartRes() + cwidth))
360 vscroll.setValue((res / cwidth));
361 av.startRes = vscroll.getValue() * cwidth;
369 * @return DOCUMENT ME!
371 public OverviewPanel getOverviewPanel()
373 return overviewPanel;
382 public void setOverviewPanel(OverviewPanel op)
390 * Hide or show annotation panel
393 public void setAnnotationVisible(boolean b)
395 if (!av.wrapAlignment)
397 annotationSpaceFillerHolder.setVisible(b);
398 annotationScroller.setVisible(b);
404 * automatically adjust annotation panel height for new annotation whilst
405 * ensuring the alignment is still visible.
407 public void adjustAnnotationHeight()
409 // TODO: display vertical annotation scrollbar if necessary
410 // this is called after loading new annotation onto alignment
411 if (alignFrame.getHeight() == 0)
413 System.out.println("NEEDS FIXING");
415 validateAnnotationDimensions(true);
417 paintAlignment(true);
421 * calculate the annotation dimensions and refresh slider values accordingly.
422 * need to do repaints/notifys afterwards.
424 protected void validateAnnotationDimensions(boolean adjustPanelHeight)
426 int height = annotationPanel.adjustPanelHeight();
428 int theight = av.getCharHeight()
429 * (av.getAlignment().getHeight() + (!av.hasHiddenRows() ? 0
430 : av.getAlignment().getHiddenSequences().getSize()));
431 float sscaling = (float) (theight / (1.0 * theight + height));
432 float ascaling = (float) (height * 1.0 / alignFrame.getHeight());
433 int rheight = alignFrame.getHeight() - height - av.getCharHeight();
434 if (adjustPanelHeight)
436 // NOTE: this logic is different in the applet. Need a better algorithm to
438 // try and set height according to alignment
439 if (ascaling > 0 && sscaling < 0.5)
441 // if the alignment is too big then
442 // default is 0.5 split
443 height = alignFrame.getHeight() / 2;
447 // if space for more than one sequence row left when annotation is fully
448 // displayed then set height to annotation height
449 // otherwise, leave at least two lines of sequence shown.
450 height = (rheight > av.getCharHeight()) ? height
451 : (-av.getCharHeight() * 3 + (int) (alignFrame.getHeight() * (1 - sscaling)));
456 // maintain same window layout whilst updating sliders
457 height = annotationScroller.getSize().height;
461 annotationScroller.setPreferredSize(new Dimension(annotationScroller
462 .getWidth(), height));
464 annotationSpaceFillerHolder.setPreferredSize(new Dimension(
465 annotationSpaceFillerHolder.getWidth(), height));
466 annotationScroller.validate();// repaint();
467 annotationScroller.addNotify();
476 public void setWrapAlignment(boolean wrap)
479 scalePanelHolder.setVisible(!wrap);
480 hscroll.setVisible(!wrap);
481 idwidthAdjuster.setVisible(!wrap);
485 annotationScroller.setVisible(false);
486 annotationSpaceFillerHolder.setVisible(false);
488 else if (av.showAnnotation)
490 annotationScroller.setVisible(true);
491 annotationSpaceFillerHolder.setVisible(true);
494 idSpaceFillerPanel1.setVisible(!wrap);
499 // return value is true if the scroll is valid
500 public boolean scrollUp(boolean up)
504 if (vscroll.getValue() < 1)
510 vscroll.setValue(vscroll.getValue() - 1);
514 if ((vextent + vscroll.getValue()) >= av.getAlignment().getHeight())
520 vscroll.setValue(vscroll.getValue() + 1);
534 * @return DOCUMENT ME!
536 public boolean scrollRight(boolean right)
540 if (hscroll.getValue() < 1)
546 hscroll.setValue(hscroll.getValue() - 1);
550 if ((hextent + hscroll.getValue()) >= av.getAlignment().getWidth())
556 hscroll.setValue(hscroll.getValue() + 1);
565 * Adjust row/column scrollers to show a visible position in the alignment.
568 * visible column to scroll to DOCUMENT ME!
570 * visible row to scroll to
573 public void setScrollValues(int x, int y)
575 // System.err.println("Scroll to "+x+","+y);
576 if (av == null || av.getAlignment() == null)
580 int width = av.getAlignment().getWidth();
581 int height = av.getAlignment().getHeight();
583 if (av.hasHiddenColumns())
585 width = av.getColumnSelection().findColumnPosition(width);
588 av.setEndRes((x + (seqPanel.seqCanvas.getWidth() / av.charWidth)) - 1);
590 hextent = seqPanel.seqCanvas.getWidth() / av.charWidth;
591 vextent = seqPanel.seqCanvas.getHeight() / av.charHeight;
598 if (vextent > height)
603 if ((hextent + x) > width)
608 if ((vextent + y) > height)
610 y = height - vextent;
623 hscroll.setValues(x, hextent, 0, width);
624 vscroll.setValues(y, vextent, 0, height);
633 public void adjustmentValueChanged(AdjustmentEvent evt)
636 int oldX = av.getStartRes();
637 int oldY = av.getStartSeq();
639 if (evt.getSource() == hscroll)
641 int x = hscroll.getValue();
643 av.setEndRes((x + (seqPanel.seqCanvas.getWidth() / av.getCharWidth())) - 1);
646 if (evt.getSource() == vscroll)
648 int offy = vscroll.getValue();
650 if (av.getWrapAlignment())
654 int rowSize = seqPanel.seqCanvas
655 .getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());
656 av.setStartRes(offy * rowSize);
657 av.setEndRes((offy + 1) * rowSize);
661 // This is only called if file loaded is a jar file that
662 // was wrapped when saved and user has wrap alignment true
663 // as preference setting
664 SwingUtilities.invokeLater(new Runnable()
668 setScrollValues(av.getStartRes(), av.getStartSeq());
675 av.setStartSeq(offy);
677 + (seqPanel.seqCanvas.getHeight() / av.getCharHeight()));
681 if (overviewPanel != null)
683 overviewPanel.setBoxPosition();
686 int scrollX = av.startRes - oldX;
687 int scrollY = av.startSeq - oldY;
689 if (av.getWrapAlignment() || !fastPaint)
695 // Make sure we're not trying to draw a panel
696 // larger than the visible window
697 if (scrollX > av.endRes - av.startRes)
699 scrollX = av.endRes - av.startRes;
701 else if (scrollX < av.startRes - av.endRes)
703 scrollX = av.startRes - av.endRes;
706 if (scrollX != 0 || scrollY != 0)
708 idPanel.idCanvas.fastPaint(scrollY);
709 seqPanel.seqCanvas.fastPaint(scrollX, scrollY);
710 scalePanel.repaint();
712 if (av.getShowAnnotation() && scrollX != 0)
714 annotationPanel.fastPaint(scrollX);
720 public void paintAlignment(boolean updateOverview)
726 av.getStructureSelectionManager().sequenceColoursChanged(this);
728 if (overviewPanel != null)
730 overviewPanel.updateOverviewImage();
741 public void paintComponent(Graphics g)
745 Dimension d = idPanel.idCanvas.getPreferredSize();
746 idPanelHolder.setPreferredSize(d);
747 hscrollFillerPanel.setPreferredSize(new Dimension(d.width, 12));
750 if (av.getWrapAlignment())
752 int maxwidth = av.getAlignment().getWidth();
754 if (av.hasHiddenColumns())
756 maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
759 int canvasWidth = seqPanel.seqCanvas
760 .getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());
765 .getWrappedCanvasWidth(seqPanel.seqCanvas
767 vscroll.setMaximum(max);
768 vscroll.setUnitIncrement(1);
769 vscroll.setVisibleAmount(1);
774 setScrollValues(av.getStartRes(), av.getStartSeq());
788 * @return DOCUMENT ME!
790 * @throws PrinterException
793 public int print(Graphics pg, PageFormat pf, int pi)
794 throws PrinterException
796 pg.translate((int) pf.getImageableX(), (int) pf.getImageableY());
798 int pwidth = (int) pf.getImageableWidth();
799 int pheight = (int) pf.getImageableHeight();
801 if (av.getWrapAlignment())
803 return printWrappedAlignment(pg, pwidth, pheight, pi);
807 return printUnwrapped(pg, pwidth, pheight, pi);
823 * @return DOCUMENT ME!
825 * @throws PrinterException
828 public int printUnwrapped(Graphics pg, int pwidth, int pheight, int pi)
829 throws PrinterException
831 int idWidth = getVisibleIdWidth(false);
832 FontMetrics fm = getFontMetrics(av.getFont());
833 int scaleHeight = av.charHeight + fm.getDescent();
835 pg.setColor(Color.white);
836 pg.fillRect(0, 0, pwidth, pheight);
837 pg.setFont(av.getFont());
839 // //////////////////////////////////
840 // / How many sequences and residues can we fit on a printable page?
841 int totalRes = (pwidth - idWidth) / av.getCharWidth();
843 int totalSeq = (int) ((pheight - scaleHeight) / av.getCharHeight()) - 1;
845 int pagesWide = (av.getAlignment().getWidth() / totalRes) + 1;
847 // ///////////////////////////
848 // / Only print these sequences and residues on this page
851 // ///////////////////////////
852 // / Only print these sequences and residues on this page
855 // ///////////////////////////
856 // / Only print these sequences and residues on this page
859 // ///////////////////////////
860 // / Only print these sequences and residues on this page
862 startRes = (pi % pagesWide) * totalRes;
863 endRes = (startRes + totalRes) - 1;
865 if (endRes > (av.getAlignment().getWidth() - 1))
867 endRes = av.getAlignment().getWidth() - 1;
870 startSeq = (pi / pagesWide) * totalSeq;
871 endSeq = startSeq + totalSeq;
873 if (endSeq > av.getAlignment().getHeight())
875 endSeq = av.getAlignment().getHeight();
878 int pagesHigh = ((av.getAlignment().getHeight() / totalSeq) + 1)
881 if (av.showAnnotation)
883 pagesHigh += annotationPanel.adjustPanelHeight() + 3;
886 pagesHigh /= pheight;
888 if (pi >= (pagesWide * pagesHigh))
890 return Printable.NO_SUCH_PAGE;
894 pg.translate(idWidth, 0);
895 scalePanel.drawScale(pg, startRes, endRes, pwidth - idWidth,
897 pg.translate(-idWidth, scaleHeight);
901 Color currentColor = null;
902 Color currentTextColor = null;
904 pg.setFont(idPanel.idCanvas.idfont);
907 for (int i = startSeq; i < endSeq; i++)
909 seq = av.getAlignment().getSequenceAt(i);
910 if ((av.getSelectionGroup() != null)
911 && av.getSelectionGroup().getSequences(null).contains(seq))
913 currentColor = Color.gray;
914 currentTextColor = Color.black;
918 currentColor = av.getSequenceColour(seq);
919 currentTextColor = Color.black;
922 pg.setColor(currentColor);
923 pg.fillRect(0, (i - startSeq) * av.charHeight, idWidth,
926 pg.setColor(currentTextColor);
929 if (av.rightAlignIds)
931 fm = pg.getFontMetrics();
933 - fm.stringWidth(seq.getDisplayId(av.getShowJVSuffix()))
938 seq.getDisplayId(av.getShowJVSuffix()),
940 (((i - startSeq) * av.charHeight) + av.getCharHeight())
941 - (av.getCharHeight() / 5));
944 pg.setFont(av.getFont());
946 // draw main sequence panel
947 pg.translate(idWidth, 0);
948 seqPanel.seqCanvas.drawPanel(pg, startRes, endRes, startSeq, endSeq, 0);
950 if (av.showAnnotation && (endSeq == av.getAlignment().getHeight()))
952 // draw annotation - need to offset for current scroll position
953 int offset = -alabels.scrollOffset;
954 pg.translate(0, offset);
955 pg.translate(-idWidth - 3, (endSeq - startSeq) * av.charHeight + 3);
956 alabels.drawComponent((Graphics2D) pg, idWidth);
957 pg.translate(idWidth + 3, 0);
958 annotationPanel.renderer.drawComponent(annotationPanel, av,
959 (Graphics2D) pg, -1, startRes, endRes + 1);
960 pg.translate(0, -offset);
963 return Printable.PAGE_EXISTS;
978 * @return DOCUMENT ME!
980 * @throws PrinterException
983 public int printWrappedAlignment(Graphics pg, int pwidth, int pheight,
984 int pi) throws PrinterException
987 int annotationHeight = 0;
988 AnnotationLabels labels = null;
989 if (av.showAnnotation)
991 annotationHeight = annotationPanel.adjustPanelHeight();
992 labels = new AnnotationLabels(av);
995 int hgap = av.charHeight;
996 if (av.scaleAboveWrapped)
998 hgap += av.charHeight;
1001 int cHeight = av.getAlignment().getHeight() * av.charHeight + hgap
1004 int idWidth = getVisibleIdWidth(false);
1006 int maxwidth = av.getAlignment().getWidth();
1007 if (av.hasHiddenColumns())
1009 maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
1012 int resWidth = seqPanel.seqCanvas.getWrappedCanvasWidth(pwidth
1015 int totalHeight = cHeight * (maxwidth / resWidth + 1);
1017 pg.setColor(Color.white);
1018 pg.fillRect(0, 0, pwidth, pheight);
1019 pg.setFont(av.getFont());
1023 pg.setColor(Color.black);
1025 pg.translate(0, -pi * pheight);
1027 pg.setClip(0, pi * pheight, pwidth, pheight);
1033 for (int i = 0; i < av.getAlignment().getHeight(); i++)
1035 pg.setFont(idPanel.idCanvas.idfont);
1036 SequenceI s = av.getAlignment().getSequenceAt(i);
1037 String string = s.getDisplayId(av.getShowJVSuffix());
1039 if (av.rightAlignIds)
1041 FontMetrics fm = pg.getFontMetrics();
1042 xPos = idWidth - fm.stringWidth(string) - 4;
1044 pg.drawString(string, xPos,
1045 ((i * av.charHeight) + ypos + av.charHeight)
1046 - (av.charHeight / 5));
1050 pg.translate(-3, ypos
1051 + (av.getAlignment().getHeight() * av.charHeight));
1053 pg.setFont(av.getFont());
1054 labels.drawComponent(pg, idWidth);
1055 pg.translate(+3, -ypos
1056 - (av.getAlignment().getHeight() * av.charHeight));
1060 } while (ypos < totalHeight);
1062 pg.translate(idWidth, 0);
1064 seqPanel.seqCanvas.drawWrappedPanel(pg, pwidth - idWidth, totalHeight,
1067 if ((pi * pheight) < totalHeight)
1069 return Printable.PAGE_EXISTS;
1074 return Printable.NO_SUCH_PAGE;
1079 * get current sequence ID panel width, or nominal value if panel were to be
1080 * displayed using default settings
1084 int getVisibleIdWidth()
1086 return getVisibleIdWidth(true);
1090 * get current sequence ID panel width, or nominal value if panel were to be
1091 * displayed using default settings
1094 * indicate if the Id width for onscreen or offscreen display should
1098 int getVisibleIdWidth(boolean onscreen)
1100 // see if rendering offscreen - check preferences and calc width accordingly
1101 if (!onscreen && Cache.getDefault("FIGURE_AUTOIDWIDTH", false))
1103 return calculateIdWidth(-1).width + 4;
1105 Integer idwidth = null;
1107 || (idwidth = Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH")) == null)
1109 return (idPanel.getWidth() > 0 ? idPanel.getWidth()
1110 : calculateIdWidth().width + 4);
1112 return idwidth.intValue() + 4;
1115 void makeAlignmentImage(int type, File file)
1117 long progress = System.currentTimeMillis();
1118 boolean headless = (System.getProperty("java.awt.headless") != null && System
1119 .getProperty("java.awt.headless").equals("true"));
1120 if (alignFrame != null && !headless)
1122 alignFrame.setProgressBar("Saving "
1123 + (type == jalview.util.ImageMaker.PNG ? "PNG image"
1124 : "EPS file"), progress);
1128 int maxwidth = av.getAlignment().getWidth();
1129 if (av.hasHiddenColumns())
1131 maxwidth = av.getColumnSelection().findColumnPosition(maxwidth);
1134 int height = ((av.getAlignment().getHeight() + 1) * av.charHeight)
1135 + scalePanel.getHeight();
1136 int width = getVisibleIdWidth(false) + (maxwidth * av.charWidth);
1138 if (av.getWrapAlignment())
1140 height = getWrappedHeight();
1143 // need to obtain default alignment width and then add in any
1144 // additional allowance for id margin
1145 // this duplicates the calculation in getWrappedHeight but adjusts for
1147 width = alignFrame.getWidth() - vscroll.getPreferredSize().width
1148 - alignFrame.getInsets().left
1149 - alignFrame.getInsets().right - getVisibleIdWidth()
1150 + getVisibleIdWidth(false);
1154 width = seqPanel.getWidth() + getVisibleIdWidth(false);
1158 else if (av.getShowAnnotation())
1160 height += annotationPanel.adjustPanelHeight() + 3;
1166 jalview.util.ImageMaker im;
1167 final String imageAction, imageTitle;
1168 if (type == jalview.util.ImageMaker.PNG)
1170 imageAction = "Create PNG image from alignment";
1175 imageAction = "Create EPS file from alignment";
1176 imageTitle = alignFrame.getTitle();
1178 im = new jalview.util.ImageMaker(this, type, imageAction, width,
1179 height, file, imageTitle);
1180 if (av.getWrapAlignment())
1182 if (im.getGraphics() != null)
1184 printWrappedAlignment(im.getGraphics(), width, height, 0);
1190 if (im.getGraphics() != null)
1192 printUnwrapped(im.getGraphics(), width, height, 0);
1196 } catch (OutOfMemoryError err)
1199 System.out.println("########################\n" + "OUT OF MEMORY "
1200 + file + "\n" + "########################");
1201 new OOMWarning("Creating Image for " + file, err);
1202 // System.out.println("Create IMAGE: " + err);
1203 } catch (Exception ex)
1205 ex.printStackTrace();
1209 if (alignFrame != null && !headless)
1211 alignFrame.setProgressBar("Export complete.", progress);
1219 public void makeEPS(File epsFile)
1221 makeAlignmentImage(jalview.util.ImageMaker.EPS, epsFile);
1227 public void makePNG(File pngFile)
1229 makeAlignmentImage(jalview.util.ImageMaker.PNG, pngFile);
1232 public void makePNGImageMap(File imgMapFile, String imageName)
1234 // /////ONLY WORKS WITH NONE WRAPPED ALIGNMENTS
1235 // ////////////////////////////////////////////
1236 int idWidth = getVisibleIdWidth(false);
1237 FontMetrics fm = getFontMetrics(av.getFont());
1238 int scaleHeight = av.charHeight + fm.getDescent();
1241 // ////////////////////////////////
1242 if (imgMapFile != null)
1246 int s, sSize = av.getAlignment().getHeight(), res, alwidth = av
1247 .getAlignment().getWidth(), g, gSize, f, fSize, sy;
1248 StringBuffer text = new StringBuffer();
1249 PrintWriter out = new PrintWriter(new FileWriter(imgMapFile));
1250 out.println(jalview.io.HTMLOutput.getImageMapHTML());
1251 out.println("<img src=\"" + imageName
1252 + "\" border=\"0\" usemap=\"#Map\" >"
1253 + "<map name=\"Map\">");
1255 for (s = 0; s < sSize; s++)
1257 sy = s * av.charHeight + scaleHeight;
1259 SequenceI seq = av.getAlignment().getSequenceAt(s);
1260 SequenceFeature[] features = seq.getDatasetSequence()
1261 .getSequenceFeatures();
1262 SequenceGroup[] groups = av.getAlignment().findAllGroups(seq);
1263 for (res = 0; res < alwidth; res++)
1265 text = new StringBuffer();
1267 if (av.getAlignment().isNucleotide())
1269 obj = ResidueProperties.nucleotideName.get(seq.getCharAt(res)
1274 obj = ResidueProperties.aa2Triplet.get(seq.getCharAt(res)
1283 String triplet = obj.toString();
1284 int alIndex = seq.findPosition(res);
1285 gSize = groups.length;
1286 for (g = 0; g < gSize; g++)
1288 if (text.length() < 1)
1290 text.append("<area shape=\"rect\" coords=\""
1291 + (idWidth + res * av.charWidth) + "," + sy + ","
1292 + (idWidth + (res + 1) * av.charWidth) + ","
1293 + (av.charHeight + sy) + "\""
1294 + " onMouseOver=\"toolTip('" + alIndex + " "
1298 if (groups[g].getStartRes() < res
1299 && groups[g].getEndRes() > res)
1301 text.append("<br><em>" + groups[g].getName() + "</em>");
1305 if (features != null)
1307 if (text.length() < 1)
1309 text.append("<area shape=\"rect\" coords=\""
1310 + (idWidth + res * av.charWidth) + "," + sy + ","
1311 + (idWidth + (res + 1) * av.charWidth) + ","
1312 + (av.charHeight + sy) + "\""
1313 + " onMouseOver=\"toolTip('" + alIndex + " "
1316 fSize = features.length;
1317 for (f = 0; f < fSize; f++)
1320 if ((features[f].getBegin() <= seq.findPosition(res))
1321 && (features[f].getEnd() >= seq.findPosition(res)))
1323 if (features[f].getType().equals("disulfide bond"))
1325 if (features[f].getBegin() == seq.findPosition(res)
1326 || features[f].getEnd() == seq
1329 text.append("<br>disulfide bond "
1330 + features[f].getBegin() + ":"
1331 + features[f].getEnd());
1336 text.append("<br>");
1337 text.append(features[f].getType());
1338 if (features[f].getDescription() != null
1339 && !features[f].getType().equals(
1340 features[f].getDescription()))
1342 text.append(" " + features[f].getDescription());
1345 if (features[f].getValue("status") != null)
1347 text.append(" (" + features[f].getValue("status")
1355 if (text.length() > 1)
1357 text.append("')\"; onMouseOut=\"toolTip()\"; href=\"#\">");
1358 out.println(text.toString());
1362 out.println("</map></body></html>");
1365 } catch (Exception ex)
1367 ex.printStackTrace();
1369 } // /////////END OF IMAGE MAP
1373 int getWrappedHeight()
1375 int seqPanelWidth = seqPanel.seqCanvas.getWidth();
1377 if (System.getProperty("java.awt.headless") != null
1378 && System.getProperty("java.awt.headless").equals("true"))
1380 seqPanelWidth = alignFrame.getWidth() - getVisibleIdWidth()
1381 - vscroll.getPreferredSize().width
1382 - alignFrame.getInsets().left - alignFrame.getInsets().right;
1385 int chunkWidth = seqPanel.seqCanvas
1386 .getWrappedCanvasWidth(seqPanelWidth);
1388 int hgap = av.charHeight;
1389 if (av.scaleAboveWrapped)
1391 hgap += av.charHeight;
1394 int annotationHeight = 0;
1395 if (av.showAnnotation)
1397 annotationHeight = annotationPanel.adjustPanelHeight();
1400 int cHeight = av.getAlignment().getHeight() * av.charHeight + hgap
1403 int maxwidth = av.getAlignment().getWidth();
1404 if (av.hasHiddenColumns())
1406 maxwidth = av.getColumnSelection().findColumnPosition(maxwidth) - 1;
1409 int height = ((maxwidth / chunkWidth) + 1) * cHeight;
1415 * close the panel - deregisters all listeners and nulls any references to
1418 public void closePanel()
1420 PaintRefresher.RemoveComponent(seqPanel.seqCanvas);
1421 PaintRefresher.RemoveComponent(idPanel.idCanvas);
1422 PaintRefresher.RemoveComponent(this);
1425 jalview.structure.StructureSelectionManager ssm = av
1426 .getStructureSelectionManager();
1427 ssm.removeStructureViewerListener(seqPanel, null);
1428 ssm.removeSelectionListener(seqPanel);
1429 av.setAlignment(null);
1434 if (Cache.log.isDebugEnabled())
1436 Cache.log.warn("Closing alignment panel which is already closed.");
1442 * hides or shows dynamic annotation rows based on groups and av state flags
1444 public void updateAnnotation()
1446 updateAnnotation(false, false);
1449 public void updateAnnotation(boolean applyGlobalSettings)
1451 updateAnnotation(applyGlobalSettings, false);
1454 public void updateAnnotation(boolean applyGlobalSettings,
1455 boolean preserveNewGroupSettings)
1457 av.updateGroupAnnotationSettings(applyGlobalSettings,
1458 preserveNewGroupSettings);
1459 adjustAnnotationHeight();
1463 public AlignmentI getAlignment()
1465 return av.getAlignment();
1469 * get the name for this view
1473 public String getViewName()
1479 * Make/Unmake this alignment panel the current input focus
1483 public void setSelected(boolean b)
1487 alignFrame.setSelected(b);
1488 } catch (Exception ex)
1495 alignFrame.setDisplayedView(this);
1500 public StructureSelectionManager getStructureSelectionManager()
1502 return av.getStructureSelectionManager();
1506 public void raiseOOMWarning(String string, OutOfMemoryError error)
1508 new OOMWarning(string, error, this);
1512 public jalview.api.FeatureRenderer cloneFeatureRenderer()
1515 return new FeatureRenderer(this);
1518 public jalview.api.FeatureRenderer getFeatureRenderer()
1520 return seqPanel.seqCanvas.getFeatureRenderer();
1522 public void updateFeatureRenderer(FeatureRenderer fr)
1524 fr.transferSettings(seqPanel.seqCanvas.getFeatureRenderer());
1527 public void updateFeatureRendererFrom(jalview.api.FeatureRenderer fr)
1529 if (seqPanel.seqCanvas.getFeatureRenderer() != null)
1531 seqPanel.seqCanvas.getFeatureRenderer().transferSettings(fr);