X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FAlignmentPanel.java;h=fe6477e9b5bff1b8c348a03ba342027aaf9db6a4;hb=1140532d01b32b648e7e5b17ea717ae790625f8f;hp=a5a1affd009da3ff94e4fcf5da380d886c1dc444;hpb=ec24991b1786e17158a43f713c8ae9c4f8647393;p=jalview.git diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java index a5a1aff..fe6477e 100644 --- a/src/jalview/gui/AlignmentPanel.java +++ b/src/jalview/gui/AlignmentPanel.java @@ -50,6 +50,7 @@ import jalview.api.AlignmentViewPanel; import jalview.bin.Cache; import jalview.bin.Console; import jalview.bin.Jalview; +import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.HiddenColumns; import jalview.datamodel.SearchResultsI; @@ -58,6 +59,7 @@ import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.gui.ImageExporter.ImageWriterI; import jalview.io.HTMLOutput; +import jalview.io.exceptions.ImageOutputException; import jalview.jbgui.GAlignmentPanel; import jalview.math.AlignmentDimension; import jalview.schemes.ResidueProperties; @@ -65,6 +67,7 @@ import jalview.structure.StructureSelectionManager; import jalview.util.Comparison; import jalview.util.ImageMaker; import jalview.util.MessageManager; +import jalview.util.imagemaker.BitmapImageSizing; import jalview.viewmodel.ViewportListenerI; import jalview.viewmodel.ViewportRanges; @@ -253,8 +256,10 @@ public class AlignmentPanel extends GAlignmentPanel implements /** * Calculates the width of the alignment labels based on the displayed names - * and any bounds on label width set in preferences. The calculated width is - * also set as a property of the viewport. + * and any bounds on label width set in preferences. + * + * The calculated width is set as a property of the viewport and the layout is + * updated. * * @return Dimension giving the maximum width of the alignment label panel * that should be used. @@ -267,10 +272,7 @@ public class AlignmentPanel extends GAlignmentPanel implements Dimension r = null; if (av.getIdWidth() < 0) { - int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300); - int idWidth = Math.min(afwidth - 200, 2 * afwidth / 3); - int maxwidth = Math.max(IdwidthAdjuster.MIN_ID_WIDTH, idWidth); - r = calculateIdWidth(maxwidth); + r = calculateDefaultAlignmentIdWidth(); av.setIdWidth(r.width); } else @@ -292,9 +294,30 @@ public class AlignmentPanel extends GAlignmentPanel implements return r; } + public Dimension calculateDefaultAlignmentIdWidth() + { + return calculateIdWidth(-1, false, false); + } + /** + * pre 2.11.3 Id width calculation - used when importing old projects only + * @return + */ + public int getLegacyIdWidth() + { + int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300); + int idWidth = Math.min(afwidth - 200, 2 * afwidth / 3); + int maxwidth = Math.max(IdwidthAdjuster.MIN_ID_WIDTH, idWidth); + Dimension w = calculateIdWidthOrLegacy(true, maxwidth, false, false); + return w.width; + } + /** * Calculate the width of the alignment labels based on the displayed names - * and any bounds on label width set in preferences. + * and any bounds on label width set in preferences. Also includes annotations + * not actually visible. + * + * FIXME JAL-244 JAL-4091 - doesn't include sequence associated annotation + * label decorators and only called during tests * * @param maxwidth * -1 or maximum width allowed for IdWidth @@ -303,6 +326,36 @@ public class AlignmentPanel extends GAlignmentPanel implements */ protected Dimension calculateIdWidth(int maxwidth) { + return calculateIdWidth(maxwidth, true, false); + } + /** + * Calculate the width of the alignment labels based on the displayed names + * and any bounds on label width set in preferences. + * + * @param maxwidth + * -1 or maximum width allowed for IdWidth + * @param includeAnnotations - when true includes width of any additional marks in annotation id panel + * @param visibleOnly - when true, ignore label widths for hidden annotation rows + * @return Dimension giving the maximum width of the alignment label panel + * that should be used. + */ + public Dimension calculateIdWidth(int maxwidth, + boolean includeAnnotations, boolean visibleOnly) + { + return calculateIdWidthOrLegacy(false, maxwidth, includeAnnotations, visibleOnly); + } + + /** + * legacy mode or post 2.11.3 ID width calculation + * @param legacy - uses annotation labels, not rendered label width (excludes additional decorators) + * @param maxwidth + * @param includeAnnotations + * @param visibleOnly + * @return + */ + private Dimension calculateIdWidthOrLegacy(boolean legacy, int maxwidth, + boolean includeAnnotations, boolean visibleOnly) + { Container c = new Container(); FontMetrics fm = c.getFontMetrics( @@ -322,18 +375,30 @@ public class AlignmentPanel extends GAlignmentPanel implements } // Also check annotation label widths - i = 0; - - if (al.getAlignmentAnnotation() != null) + if (includeAnnotations && al.getAlignmentAnnotation() != null) { fm = c.getFontMetrics(getAlabels().getFont()); - while (i < al.getAlignmentAnnotation().length) + if (!legacy || Jalview.isHeadlessMode()) { - String label = al.getAlignmentAnnotation()[i].label; - int stringWidth = fm.stringWidth(label); + AnnotationLabels aal = getAlabels(); + int stringWidth = aal.drawLabels(null, false, idWidth, false, false, + fm, !visibleOnly); idWidth = Math.max(idWidth, stringWidth); - i++; + } + else + { + for (i = 0; i < al.getAlignmentAnnotation().length; i++) + { + AlignmentAnnotation aa = al.getAlignmentAnnotation()[i]; + if (visibleOnly && !aa.visible) + { + continue; + } + String label = aa.label; + int stringWidth = fm.stringWidth(label); + idWidth = Math.max(idWidth, stringWidth); + } } } @@ -541,7 +606,7 @@ public class AlignmentPanel extends GAlignmentPanel implements // this is called after loading new annotation onto alignment if (alignFrame.getHeight() == 0) { - System.out.println("NEEDS FIXING"); + jalview.bin.Console.error("adjustAnnotationHeight called with zero height alignment window"); } validateAnnotationDimensions(true); addNotify(); @@ -565,21 +630,29 @@ public class AlignmentPanel extends GAlignmentPanel implements // not be called directly by programs. // I note that addNotify() is called in several areas of Jalview. - int annotationHeight = getAnnotationPanel().adjustPanelHeight(); - annotationHeight = getAnnotationPanel() - .adjustForAlignFrame(adjustPanelHeight, annotationHeight); + AnnotationPanel ap = getAnnotationPanel(); + int annotationHeight = ap.adjustPanelHeight(); + annotationHeight = ap.adjustForAlignFrame(adjustPanelHeight, + annotationHeight); hscroll.addNotify(); - annotationScroller.setPreferredSize( - new Dimension(annotationScroller.getWidth(), annotationHeight)); - Dimension e = idPanel.getSize(); - alabels.setSize(new Dimension(e.width, annotationHeight)); + int idWidth = e.width; + boolean manuallyAdjusted = this.getIdPanel().getIdCanvas() + .isManuallyAdjusted(); + annotationScroller.setPreferredSize(new Dimension( + manuallyAdjusted ? idWidth : annotationScroller.getWidth(), + annotationHeight)); + + alabels.setPreferredSize(new Dimension(idWidth, annotationHeight)); annotationSpaceFillerHolder.setPreferredSize(new Dimension( - annotationSpaceFillerHolder.getWidth(), annotationHeight)); + manuallyAdjusted ? idWidth + : annotationSpaceFillerHolder.getWidth(), + annotationHeight)); annotationScroller.validate(); annotationScroller.addNotify(); + ap.validate(); } /** @@ -595,9 +668,10 @@ public class AlignmentPanel extends GAlignmentPanel implements boolean wrap = av.getWrapAlignment(); ViewportRanges ranges = av.getRanges(); ranges.setStartSeq(0); - scalePanelHolder.setVisible(!wrap); + // scalePanelHolder.setVisible(!wrap); hscroll.setVisible(!wrap); - idwidthAdjuster.setVisible(!wrap); + // Allow idPanel width adjustment in wrap mode + idwidthAdjuster.setVisible(true); if (wrap) { @@ -631,7 +705,7 @@ public class AlignmentPanel extends GAlignmentPanel implements } } - idSpaceFillerPanel1.setVisible(!wrap); + // idSpaceFillerPanel1.setVisible(!wrap); repaint(); } @@ -852,10 +926,27 @@ public class AlignmentPanel extends GAlignmentPanel implements public void paintComponent(Graphics g) { invalidate(); // needed so that the id width adjuster works correctly - Dimension d = getIdPanel().getIdCanvas().getPreferredSize(); - idPanelHolder.setPreferredSize(d); - hscrollFillerPanel.setPreferredSize(new Dimension(d.width, 12)); + int idWidth = d.width; + + // check wrapped alignment as at least 1 residue width + if (av.getWrapAlignment()) + { + SeqCanvas sc = this.getSeqPanel().seqCanvas; + if (sc != null && sc.getWidth() < sc.getMinimumWrappedCanvasWidth()) + { + // need to make some adjustments + idWidth -= (sc.getMinimumWrappedCanvasWidth() - sc.getWidth()); + av.setIdWidth(idWidth); + av.getAlignPanel().getIdPanel().getIdCanvas() + .setManuallyAdjusted(true); + + validateAnnotationDimensions(false); + } + } + + idPanelHolder.setPreferredSize(new Dimension(idWidth, d.height)); + hscrollFillerPanel.setPreferredSize(new Dimension(idWidth, 12)); validate(); // needed so that the id width adjuster works correctly @@ -946,8 +1037,16 @@ public class AlignmentPanel extends GAlignmentPanel implements Graphics idGraphics, Graphics alignmentGraphics) throws PrinterException { - final int idWidth = getVisibleIdWidth(false); - + final int idWidth, idWidthForGui; + // otherwise calculate it + idWidth = getVisibleIdWidth(false); +// if (getIdPanel()!=null && getIdPanel().getWidth()>0) +// { +// // use the current IdPanel's width, if its set and non-zero +// idWidthForGui = getIdPanel().getWidth(); +// } else { +// idWidthForGui=0; +// } /* * Get the horizontal offset to where we draw the sequences. * This is idWidth if using a single Graphics context, else zero. @@ -996,6 +1095,9 @@ public class AlignmentPanel extends GAlignmentPanel implements } final int alignmentDrawnHeight = (endSeq - startSeq) * charHeight + 3; + alignmentGraphics.setColor(Color.white); + alignmentGraphics.fillRect(0, 0, pageWidth, pageHeight+scaleHeight); + /* * draw the Scale at horizontal offset, then reset to top left (0, 0) */ @@ -1012,8 +1114,9 @@ public class AlignmentPanel extends GAlignmentPanel implements IdCanvas idCanvas = getIdPanel().getIdCanvas(); List selection = av.getSelectionGroup() == null ? null : av.getSelectionGroup().getSequences(null); + idCanvas.drawIds((Graphics2D) idGraphics, av, startSeq, endSeq - 1, - selection); + selection, false,idWidth); idGraphics.setFont(av.getFont()); idGraphics.translate(0, -scaleHeight); @@ -1037,7 +1140,7 @@ public class AlignmentPanel extends GAlignmentPanel implements int offset = getAlabels().getScrollOffset(); idGraphics.translate(0, -offset); idGraphics.translate(0, alignmentDrawnHeight); - getAlabels().drawComponent(idGraphics, idWidth); + getAlabels().drawComponentNotGUI(idGraphics, idWidth); idGraphics.translate(0, -alignmentDrawnHeight); /* @@ -1118,7 +1221,7 @@ public class AlignmentPanel extends GAlignmentPanel implements * draw sequence ids and annotation labels (if shown) */ IdCanvas idCanvas = getIdPanel().getIdCanvas(); - idCanvas.drawIdsWrapped((Graphics2D) g, av, 0, totalHeight); + idCanvas.drawIdsWrappedNoGUI((Graphics2D) g, av, 0, totalHeight); g.translate(idWidth, 0); @@ -1160,7 +1263,7 @@ public class AlignmentPanel extends GAlignmentPanel implements // see if rendering offscreen - check preferences and calc width accordingly if (!onscreen && Cache.getDefault("FIGURE_AUTOIDWIDTH", false)) { - return calculateIdWidth(-1).width; + return calculateIdWidth(-1,true,true).width; } Integer idwidth = onscreen ? null : Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH"); @@ -1170,12 +1273,15 @@ public class AlignmentPanel extends GAlignmentPanel implements } int w = getIdPanel().getWidth(); + w = calculateIdWidth(-1, true, true).width; return (w > 0 ? w : calculateIdWidth().width); } void makeAlignmentImage(ImageMaker.TYPE type, File file, String renderer) + throws ImageOutputException { - makeAlignmentImage(type, file, renderer, 0.0f, 0, 0); + makeAlignmentImage(type, file, renderer, + BitmapImageSizing.defaultBitmapImageSizing()); } /** @@ -1188,11 +1294,12 @@ public class AlignmentPanel extends GAlignmentPanel implements * @param bitmapscale */ void makeAlignmentImage(ImageMaker.TYPE type, File file, String renderer, - float bitmapscale, int bitmapwidth, int bitmapheight) + BitmapImageSizing userBis) throws ImageOutputException { final int borderBottomOffset = 5; AlignmentDimension aDimension = getAlignmentDimension(); + // todo use a lambda function in place of callback here? ImageWriterI writer = new ImageWriterI() { @@ -1219,7 +1326,7 @@ public class AlignmentPanel extends GAlignmentPanel implements int imageHeight = aDimension.getHeight() + borderBottomOffset; String of = MessageManager.getString("label.alignment"); exporter.doExport(file, this, imageWidth, imageHeight, of, renderer, - bitmapscale, bitmapwidth, bitmapheight); + userBis); } /** @@ -1264,6 +1371,7 @@ public class AlignmentPanel extends GAlignmentPanel implements } public void makePNGImageMap(File imgMapFile, String imageName) + throws ImageOutputException { // /////ONLY WORKS WITH NON WRAPPED ALIGNMENTS // //////////////////////////////////////////// @@ -1388,7 +1496,8 @@ public class AlignmentPanel extends GAlignmentPanel implements } catch (Exception ex) { - ex.printStackTrace(); + throw new ImageOutputException( + "couldn't write ImageMap due to unexpected error", ex); } } // /////////END OF IMAGE MAP @@ -1404,8 +1513,7 @@ public class AlignmentPanel extends GAlignmentPanel implements { int seqPanelWidth = getSeqPanel().seqCanvas.getWidth(); - if (System.getProperty("java.awt.headless") != null - && System.getProperty("java.awt.headless").equals("true")) + if (Jalview.isHeadlessMode()) { seqPanelWidth = alignFrame.getWidth() - getVisibleIdWidth() - vscroll.getPreferredSize().width @@ -1793,5 +1901,4 @@ public class AlignmentPanel extends GAlignmentPanel implements overviewPanel = null; } } - }