X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FAlignmentPanel.java;h=0ea2b8a8f9f1420764dedc1f01655197dbc734aa;hb=31b84e9690b026255a488724ef7b847da94e48af;hp=065d0c319f706161a51b31f069cca39ca5ac5b0f;hpb=6f0b432ac19ed1d0d5e01a834586dc81b8a6a72d;p=jalview.git diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java index 065d0c3..0ea2b8a 100644 --- a/src/jalview/gui/AlignmentPanel.java +++ b/src/jalview/gui/AlignmentPanel.java @@ -24,20 +24,22 @@ import jalview.analysis.AnnotationSorter; import jalview.api.AlignViewportI; import jalview.api.AlignmentViewPanel; import jalview.bin.Cache; +import jalview.bin.Jalview; import jalview.datamodel.AlignmentI; import jalview.datamodel.HiddenColumns; import jalview.datamodel.SearchResultsI; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; +import jalview.gui.ImageExporter.ImageWriterI; import jalview.io.HTMLOutput; import jalview.jbgui.GAlignmentPanel; import jalview.math.AlignmentDimension; import jalview.schemes.ResidueProperties; import jalview.structure.StructureSelectionManager; import jalview.util.Comparison; +import jalview.util.ImageMaker; import jalview.util.MessageManager; -import jalview.util.Platform; import jalview.viewmodel.ViewportListenerI; import jalview.viewmodel.ViewportRanges; @@ -48,6 +50,7 @@ import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; import java.awt.event.ComponentAdapter; @@ -81,11 +84,8 @@ public class AlignmentPanel extends GAlignmentPanel implements private IdPanel idPanel; - private boolean headless; - IdwidthAdjuster idwidthAdjuster; - /** DOCUMENT ME!! */ public AlignFrame alignFrame; private ScalePanel scalePanel; @@ -116,6 +116,7 @@ public class AlignmentPanel extends GAlignmentPanel implements */ public AlignmentPanel(AlignFrame af, final AlignViewport av) { +// setBackground(Color.white); // BH 2019 alignFrame = af; this.av = av; setSeqPanel(new SeqPanel(av, this)); @@ -228,7 +229,7 @@ public class AlignmentPanel extends GAlignmentPanel implements new Dimension(10, av.getCharHeight() + fm.getDescent())); idwidthAdjuster.invalidate(); scalePanelHolder.invalidate(); - getIdPanel().getIdCanvas().gg = null; + // BH 2018 getIdPanel().getIdCanvas().gg = null; getSeqPanel().seqCanvas.img = null; getAnnotationPanel().adjustPanelHeight(); @@ -546,37 +547,10 @@ public class AlignmentPanel extends GAlignmentPanel implements protected void validateAnnotationDimensions(boolean adjustPanelHeight) { int annotationHeight = getAnnotationPanel().adjustPanelHeight(); + annotationHeight = getAnnotationPanel() + .adjustForAlignFrame(adjustPanelHeight, annotationHeight); - if (adjustPanelHeight) - { - int rowHeight = av.getCharHeight(); - int alignmentHeight = rowHeight * av.getAlignment().getHeight(); - - /* - * Estimate available height in the AlignFrame for alignment + - * annotations. Deduct an estimate for title bar, menu bar, scale panel, - * hscroll, status bar, insets. - */ - int stuff = Platform.isAMac() ? 120 : 140; - int availableHeight = alignFrame.getHeight() - stuff; - - /* - * If not enough vertical space, maximize annotation height while keeping - * at least two rows of alignment visible - */ - if (annotationHeight + alignmentHeight > availableHeight) - { - annotationHeight = Math.min(annotationHeight, - availableHeight - 2 * rowHeight); - } - } - else - { - // maintain same window layout whilst updating sliders - annotationHeight = annotationScroller.getSize().height; - } hscroll.addNotify(); - annotationScroller.setPreferredSize( new Dimension(annotationScroller.getWidth(), annotationHeight)); @@ -615,6 +589,7 @@ public class AlignmentPanel extends GAlignmentPanel implements { annotationScroller.setVisible(true); annotationSpaceFillerHolder.setVisible(true); + validateAnnotationDimensions(false); } int canvasWidth = getSeqPanel().seqCanvas.getWidth(); @@ -884,6 +859,7 @@ public class AlignmentPanel extends GAlignmentPanel implements */ ViewportRanges ranges = av.getRanges(); setScrollValues(ranges.getStartRes(), ranges.getStartSeq()); + super.paintComponent(g); } /** @@ -942,30 +918,16 @@ public class AlignmentPanel extends GAlignmentPanel implements } /** - * DOCUMENT ME! - * - * @param pg - * DOCUMENT ME! - * @param pwidth - * DOCUMENT ME! - * @param pheight - * DOCUMENT ME! - * @param pi - * DOCUMENT ME! - * - * @return DOCUMENT ME! - * - * @throws PrinterException - * DOCUMENT ME! - */ - /** * Draws the alignment image, including sequence ids, sequences, and * annotation labels and annotations if shown, on either one or two Graphics - * context. + * contexts. * * @param pageWidth + * in pixels * @param pageHeight - * @param pi + * in pixels + * @param pageIndex + * (0, 1, ...) * @param idGraphics * the graphics context for sequence ids and annotation labels * @param alignmentGraphics @@ -974,7 +936,7 @@ public class AlignmentPanel extends GAlignmentPanel implements * @return * @throws PrinterException */ - public int printUnwrapped(int pageWidth, int pageHeight, int pi, + public int printUnwrapped(int pageWidth, int pageHeight, int pageIndex, Graphics idGraphics, Graphics alignmentGraphics) throws PrinterException { @@ -988,8 +950,8 @@ public class AlignmentPanel extends GAlignmentPanel implements : idWidth; FontMetrics fm = getFontMetrics(av.getFont()); - int charHeight = av.getCharHeight(); - int scaleHeight = charHeight + fm.getDescent(); + final int charHeight = av.getCharHeight(); + final int scaleHeight = charHeight + fm.getDescent(); idGraphics.setColor(Color.white); idGraphics.fillRect(0, 0, pageWidth, pageHeight); @@ -998,29 +960,20 @@ public class AlignmentPanel extends GAlignmentPanel implements /* * How many sequences and residues can we fit on a printable page? */ - int totalRes = (pageWidth - idWidth) / av.getCharWidth(); - - int totalSeq = (pageHeight - scaleHeight) / charHeight - 1; - - int alignmentWidth = av.getAlignment().getWidth(); - int pagesWide = (alignmentWidth / totalRes) + 1; + final int totalRes = (pageWidth - idWidth) / av.getCharWidth(); - final int startRes = (pi % pagesWide) * totalRes; - int endRes = (startRes + totalRes) - 1; + final int totalSeq = (pageHeight - scaleHeight) / charHeight - 1; - if (endRes > (alignmentWidth - 1)) - { - endRes = alignmentWidth - 1; - } + final int alignmentWidth = av.getAlignment().getWidth(); + final int pagesWide = (alignmentWidth / totalRes) + 1; - final int startSeq = (pi / pagesWide) * totalSeq; - int endSeq = startSeq + totalSeq; + final int startRes = (pageIndex % pagesWide) * totalRes; + final int endRes = Math.min(startRes + totalRes - 1, + alignmentWidth - 1); - int alignmentHeight = av.getAlignment().getHeight(); - if (endSeq > alignmentHeight) - { - endSeq = alignmentHeight; - } + final int startSeq = (pageIndex / pagesWide) * totalSeq; + final int alignmentHeight = av.getAlignment().getHeight(); + final int endSeq = Math.min(startSeq + totalSeq, alignmentHeight); int pagesHigh = ((alignmentHeight / totalSeq) + 1) * pageHeight; @@ -1031,7 +984,7 @@ public class AlignmentPanel extends GAlignmentPanel implements pagesHigh /= pageHeight; - if (pi >= (pagesWide * pagesHigh)) + if (pageIndex >= (pagesWide * pagesHigh)) { return Printable.NO_SUCH_PAGE; } @@ -1050,47 +1003,12 @@ public class AlignmentPanel extends GAlignmentPanel implements * then reset to top left (0, 0) */ idGraphics.translate(0, scaleHeight); - idGraphics.setFont(getIdPanel().getIdCanvas().getIdfont()); - Color currentColor = null; - Color currentTextColor = null; + IdCanvas idCanvas = getIdPanel().getIdCanvas(); + List selection = av.getSelectionGroup() == null ? null + : av.getSelectionGroup().getSequences(null); + idCanvas.drawIds((Graphics2D) idGraphics, av, startSeq, endSeq - 1, + selection); - SequenceI seq; - for (int i = startSeq; i < endSeq; i++) - { - seq = av.getAlignment().getSequenceAt(i); - if ((av.getSelectionGroup() != null) - && av.getSelectionGroup().getSequences(null).contains(seq)) - { - /* - * gray out ids of sequences in selection group (if any) - */ - currentColor = Color.gray; - currentTextColor = Color.black; - } - else - { - currentColor = av.getSequenceColour(seq); - currentTextColor = Color.black; - } - - idGraphics.setColor(currentColor); - idGraphics.fillRect(0, (i - startSeq) * charHeight, idWidth, - charHeight); - - idGraphics.setColor(currentTextColor); - - int xPos = 0; - String displayId = seq.getDisplayId(av.getShowJVSuffix()); - if (av.isRightAlignIds()) - { - fm = idGraphics.getFontMetrics(); - xPos = idWidth - fm.stringWidth(displayId) - 4; - } - - idGraphics.drawString(displayId, xPos, - (((i - startSeq) * charHeight) + charHeight) - - (charHeight / 5)); - } idGraphics.setFont(av.getFont()); idGraphics.translate(0, -scaleHeight); @@ -1100,7 +1018,7 @@ public class AlignmentPanel extends GAlignmentPanel implements */ alignmentGraphics.translate(alignmentGraphicsOffset, scaleHeight); getSeqPanel().seqCanvas.drawPanelForPrinting(alignmentGraphics, startRes, - endRes, startSeq, endSeq); + endRes, startSeq, endSeq - 1); alignmentGraphics.translate(-alignmentGraphicsOffset, 0); if (av.isShowAnnotation() && (endSeq == alignmentHeight)) @@ -1130,31 +1048,27 @@ public class AlignmentPanel extends GAlignmentPanel implements } /** - * DOCUMENT ME! + * Prints one page of an alignment in wrapped mode. Returns + * Printable.PAGE_EXISTS (0) if a page was drawn, or Printable.NO_SUCH_PAGE if + * no page could be drawn (page number out of range). * - * @param pg - * DOCUMENT ME! - * @param pwidth - * DOCUMENT ME! - * @param pheight - * DOCUMENT ME! - * @param pi - * DOCUMENT ME! + * @param pageWidth + * @param pageHeight + * @param pageNumber + * (0, 1, ...) + * @param g * - * @return DOCUMENT ME! + * @return * * @throws PrinterException - * DOCUMENT ME! */ - public int printWrappedAlignment(int pwidth, int pheight, int pi, - Graphics pg) throws PrinterException + public int printWrappedAlignment(int pageWidth, int pageHeight, int pageNumber, + Graphics g) throws PrinterException { int annotationHeight = 0; - AnnotationLabels labels = null; if (av.isShowAnnotation()) { annotationHeight = getAnnotationPanel().adjustPanelHeight(); - labels = new AnnotationLabels(av); } int hgap = av.getCharHeight(); @@ -1176,64 +1090,39 @@ public class AlignmentPanel extends GAlignmentPanel implements } int resWidth = getSeqPanel().seqCanvas - .getWrappedCanvasWidth(pwidth - idWidth); + .getWrappedCanvasWidth(pageWidth - idWidth); int totalHeight = cHeight * (maxwidth / resWidth + 1); - pg.setColor(Color.white); - pg.fillRect(0, 0, pwidth, pheight); - pg.setFont(av.getFont()); - - // ////////////// - // Draw the ids - pg.setColor(Color.black); + g.setColor(Color.white); + g.fillRect(0, 0, pageWidth, pageHeight); + g.setFont(av.getFont()); + g.setColor(Color.black); - pg.translate(0, -pi * pheight); - - pg.setClip(0, pi * pheight, pwidth, pheight); - - int ypos = hgap; - - do - { - for (int i = 0; i < av.getAlignment().getHeight(); i++) - { - pg.setFont(getIdPanel().getIdCanvas().getIdfont()); - SequenceI s = av.getAlignment().getSequenceAt(i); - String string = s.getDisplayId(av.getShowJVSuffix()); - int xPos = 0; - if (av.isRightAlignIds()) - { - FontMetrics fm = pg.getFontMetrics(); - xPos = idWidth - fm.stringWidth(string) - 4; - } - pg.drawString(string, xPos, - ((i * av.getCharHeight()) + ypos + av.getCharHeight()) - - (av.getCharHeight() / 5)); - } - if (labels != null) - { - pg.translate(-3, ypos - + (av.getAlignment().getHeight() * av.getCharHeight())); + /* + * method: print the whole wrapped alignment, but with a clip region that + * is restricted to the requested page; this supports selective print of + * single pages or ranges, (at the cost of some repeated processing in + * the 'normal' case, when all pages are printed) + */ + g.translate(0, -pageNumber * pageHeight); - pg.setFont(av.getFont()); - labels.drawComponent(pg, idWidth); - pg.translate(+3, -ypos - - (av.getAlignment().getHeight() * av.getCharHeight())); - } + g.setClip(0, pageNumber * pageHeight, pageWidth, pageHeight); - ypos += cHeight; - } while (ypos < totalHeight); + /* + * draw sequence ids and annotation labels (if shown) + */ + IdCanvas idCanvas = getIdPanel().getIdCanvas(); + idCanvas.drawIdsWrapped((Graphics2D) g, av, 0, totalHeight); - pg.translate(idWidth, 0); + g.translate(idWidth, 0); - getSeqPanel().seqCanvas.drawWrappedPanelForPrinting(pg, pwidth - idWidth, + getSeqPanel().seqCanvas.drawWrappedPanelForPrinting(g, pageWidth - idWidth, totalHeight, 0); - if ((pi * pheight) < totalHeight) + if ((pageNumber * pageHeight) < totalHeight) { return Printable.PAGE_EXISTS; - } else { @@ -1278,86 +1167,52 @@ public class AlignmentPanel extends GAlignmentPanel implements return idwidth.intValue() + 4; } - void makeAlignmentImage(jalview.util.ImageMaker.TYPE type, File file) + /** + * Builds an image of the alignment of the specified type (EPS/PNG/SVG) and + * writes it to the specified file + * + * @param type + * @param file + */ + void makeAlignmentImage(ImageMaker.TYPE type, File file) { - int boarderBottomOffset = 5; - long pSessionId = System.currentTimeMillis(); - headless = (System.getProperty("java.awt.headless") != null - && System.getProperty("java.awt.headless").equals("true")); - if (alignFrame != null && !headless) - { - if (file != null) - { - alignFrame.setProgressBar(MessageManager - .formatMessage("status.saving_file", new Object[] - { type.getLabel() }), pSessionId); - } - } - try + final int borderBottomOffset = 5; + + AlignmentDimension aDimension = getAlignmentDimension(); + // todo use a lambda function in place of callback here? + ImageWriterI writer = new ImageWriterI() { - AlignmentDimension aDimension = getAlignmentDimension(); - try + @Override + public void exportImage(Graphics graphics) throws Exception { - jalview.util.ImageMaker im; - final String imageAction, imageTitle; - if (type == jalview.util.ImageMaker.TYPE.PNG) - { - imageAction = "Create PNG image from alignment"; - imageTitle = null; - } - else if (type == jalview.util.ImageMaker.TYPE.EPS) - { - imageAction = "Create EPS file from alignment"; - imageTitle = alignFrame.getTitle(); - } - else - { - imageAction = "Create SVG file from alignment"; - imageTitle = alignFrame.getTitle(); - } - - im = new jalview.util.ImageMaker(this, type, imageAction, - aDimension.getWidth(), - aDimension.getHeight() + boarderBottomOffset, file, - imageTitle, alignFrame, pSessionId, headless); - Graphics graphics = im.getGraphics(); if (av.getWrapAlignment()) { - if (graphics != null) - { - printWrappedAlignment(aDimension.getWidth(), - aDimension.getHeight() + boarderBottomOffset, 0, - graphics); - im.writeImage(); - } + printWrappedAlignment(aDimension.getWidth(), + aDimension.getHeight() + borderBottomOffset, 0, graphics); } else { - if (graphics != null) - { - printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0, - graphics, graphics); - im.writeImage(); - } + printUnwrapped(aDimension.getWidth(), aDimension.getHeight(), 0, + graphics, graphics); } - - } catch (OutOfMemoryError err) - { - // Be noisy here. - System.out.println("########################\n" + "OUT OF MEMORY " - + file + "\n" + "########################"); - new OOMWarning("Creating Image for " + file, err); - // System.out.println("Create IMAGE: " + err); - } catch (Exception ex) - { - ex.printStackTrace(); } - } finally - { + }; - } + String fileTitle = alignFrame.getTitle(); + ImageExporter exporter = new ImageExporter(writer, alignFrame, type, + fileTitle); + int imageWidth = aDimension.getWidth(); + int imageHeight = aDimension.getHeight() + borderBottomOffset; + String of = MessageManager.getString("label.alignment"); + exporter.doExport(file, this, imageWidth, imageHeight, of); } + /** + * Calculates and returns a suitable width and height (in pixels) for an + * exported image + * + * @return + */ public AlignmentDimension getAlignmentDimension() { int maxwidth = av.getAlignment().getWidth(); @@ -1374,7 +1229,7 @@ public class AlignmentPanel extends GAlignmentPanel implements if (av.getWrapAlignment()) { height = getWrappedHeight(); - if (headless) + if (Jalview.isHeadlessMode()) { // need to obtain default alignment width and then add in any // additional allowance for id margin @@ -1398,27 +1253,6 @@ public class AlignmentPanel extends GAlignmentPanel implements } - /** - * DOCUMENT ME! - */ - public void makeEPS(File epsFile) - { - makeAlignmentImage(jalview.util.ImageMaker.TYPE.EPS, epsFile); - } - - /** - * DOCUMENT ME! - */ - public void makePNG(File pngFile) - { - makeAlignmentImage(jalview.util.ImageMaker.TYPE.PNG, pngFile); - } - - public void makeSVG(File svgFile) - { - makeAlignmentImage(jalview.util.ImageMaker.TYPE.SVG, svgFile); - } - public void makePNGImageMap(File imgMapFile, String imageName) { // /////ONLY WORKS WITH NON WRAPPED ALIGNMENTS @@ -1680,7 +1514,7 @@ public class AlignmentPanel extends GAlignmentPanel implements @Override public String getViewName() { - return av.viewName; + return av.getViewName(); } /**