X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FAlignmentPanel.java;h=277e11dd84ab24874e80c089f9ef538233f41a07;hb=0751c58086542f9e0466201b624f84d1efd547bb;hp=9cf01fae08b442ae602f6066bf624de4a258a6b7;hpb=6a18ba9e7e4bd4deee0337dfd072b959596ca4b5;p=jalview.git
diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java
index 9cf01fa..277e11d 100644
--- a/src/jalview/gui/AlignmentPanel.java
+++ b/src/jalview/gui/AlignmentPanel.java
@@ -20,27 +20,6 @@
*/
package jalview.gui;
-import jalview.analysis.AnnotationSorter;
-import jalview.api.AlignViewportI;
-import jalview.api.AlignmentViewPanel;
-import jalview.bin.Cache;
-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.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.MessageManager;
-import jalview.util.Platform;
-import jalview.viewmodel.ViewportListenerI;
-import jalview.viewmodel.ViewportRanges;
-
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
@@ -65,15 +44,45 @@ import java.util.List;
import javax.swing.SwingUtilities;
+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.viewmodel.AlignmentViewport;
+import jalview.viewmodel.ViewportListenerI;
+import jalview.viewmodel.ViewportRanges;
+
/**
* DOCUMENT ME!
*
* @author $author$
* @version $Revision: 1.161 $
*/
+@SuppressWarnings("serial")
public class AlignmentPanel extends GAlignmentPanel implements
AdjustmentListener, Printable, AlignmentViewPanel, ViewportListenerI
{
+ /*
+ * spare space in pixels between sequence id and alignment panel
+ */
+ private static final int ID_WIDTH_PADDING = 4;
+
public AlignViewport av;
OverviewPanel overviewPanel;
@@ -82,11 +91,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
private IdPanel idPanel;
- private boolean headless;
-
IdwidthAdjuster idwidthAdjuster;
- /** DOCUMENT ME!! */
public AlignFrame alignFrame;
private ScalePanel scalePanel;
@@ -117,6 +123,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
*/
public AlignmentPanel(AlignFrame af, final AlignViewport av)
{
+ setName("AligmentPanel");
+ // setBackground(Color.white); // BH 2019
alignFrame = af;
this.av = av;
setSeqPanel(new SeqPanel(av, this));
@@ -167,6 +175,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
ranges.setViewportWidth(widthInRes);
ranges.setViewportHeight(heightInSeq);
}
+ repaint();
}
});
@@ -177,10 +186,17 @@ public class AlignmentPanel extends GAlignmentPanel implements
@Override
public void propertyChange(PropertyChangeEvent evt)
{
- if (evt.getPropertyName().equals("alignment"))
- {
+ switch (evt.getPropertyName()) {
+ case AlignmentViewport.PROPERTY_SEQUENCE:
+ updateScrollBarsFromRanges();
+ if (annotationPanel != null)
+ annotationPanel.paintImmediately(0, 0, getWidth(), getHeight());
+ break;
+ case AlignmentViewport.PROPERTY_ALIGNMENT:
+ updateScrollBarsFromRanges();
PaintRefresher.Refresh(ap, av.getSequenceSetId(), true, true);
alignmentChanged();
+ break;
}
}
};
@@ -229,13 +245,11 @@ 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();
Dimension d = calculateIdWidth();
-
- d.setSize(d.width + 4, d.height);
getIdPanel().getIdCanvas().setPreferredSize(d);
hscrollFillerPanel.setPreferredSize(d);
@@ -243,30 +257,49 @@ public class AlignmentPanel extends GAlignmentPanel implements
}
/**
- * Calculate the width of the alignment labels based on the displayed names
- * and any bounds on label width set in preferences.
+ * 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.
*
* @return Dimension giving the maximum width of the alignment label panel
* that should be used.
*/
public Dimension calculateIdWidth()
{
+ int oldWidth = av.getIdWidth();
+
// calculate sensible default width when no preference is available
- Dimension r = null;
+ Dimension d = null;
if (av.getIdWidth() < 0)
{
- int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300);
- int maxwidth = Math.max(20, Math.min(afwidth - 200, 2 * afwidth / 3));
- r = calculateIdWidth(maxwidth);
- av.setIdWidth(r.width);
+ int maxWidth = getMaxWidth();
+ d = calculateIdWidth(maxWidth);
+ av.setIdWidth(d.width);
}
else
{
- r = new Dimension();
- r.width = av.getIdWidth();
- r.height = 0;
+ d = new Dimension();
+ d.width = av.getIdWidth();
+ d.height = 0;
}
- return r;
+
+ /*
+ * fudge: if desired width has changed, update layout
+ * (see also paintComponent - updates layout on a repaint)
+ */
+ if (d.width != oldWidth)
+ {
+ idPanelHolder.setPreferredSize(d);
+ validate();
+ }
+ return d;
+ }
+
+ public int getMaxWidth()
+ {
+ int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300);
+ int idWidth = Math.min(afwidth - 200, 2 * afwidth / 3);
+ return Math.max(IdwidthAdjuster.MIN_ID_WIDTH, idWidth);
}
/**
@@ -280,27 +313,22 @@ public class AlignmentPanel extends GAlignmentPanel implements
*/
public Dimension calculateIdWidth(int maxwidth)
{
- Container c = new Container();
-
+ Container c = this;// new Container();
FontMetrics fm = c.getFontMetrics(
new Font(av.font.getName(), Font.ITALIC, av.font.getSize()));
AlignmentI al = av.getAlignment();
int i = 0;
int idWidth = 0;
- String id;
+
+ boolean withSuffix = av.getShowJVSuffix();
while ((i < al.getHeight()) && (al.getSequenceAt(i) != null))
{
SequenceI s = al.getSequenceAt(i);
-
- id = s.getDisplayId(av.getShowJVSuffix());
-
- if (fm.stringWidth(id) > idWidth)
- {
- idWidth = fm.stringWidth(id);
- }
-
+ String id = s.getDisplayId(withSuffix);
+ int stringWidth = fm.stringWidth(id);
+ idWidth = Math.max(idWidth, stringWidth);
i++;
}
@@ -314,31 +342,29 @@ public class AlignmentPanel extends GAlignmentPanel implements
while (i < al.getAlignmentAnnotation().length)
{
String label = al.getAlignmentAnnotation()[i].label;
-
- if (fm.stringWidth(label) > idWidth)
- {
- idWidth = fm.stringWidth(label);
- }
-
+ int stringWidth = fm.stringWidth(label);
+ idWidth = Math.max(idWidth, stringWidth);
i++;
}
}
- return new Dimension(
- maxwidth < 0 ? idWidth : Math.min(maxwidth, idWidth), 12);
+ int w = maxwidth < 0 ? idWidth : Math.min(maxwidth, idWidth);
+ w += ID_WIDTH_PADDING;
+
+ return new Dimension(w, 12);
}
/**
- * Highlight the given results on the alignment.
+ * Highlight the given results on the alignment
*
*/
public void highlightSearchResults(SearchResultsI results)
{
- boolean scrolled = scrollToPosition(results, 0, true, false);
+ boolean scrolled = scrollToPosition(results, 0, false);
- boolean noFastPaint = scrolled && av.getWrapAlignment();
+ boolean fastPaint = !(scrolled && av.getWrapAlignment());
- getSeqPanel().seqCanvas.highlightSearchResults(results, noFastPaint);
+ getSeqPanel().seqCanvas.highlightSearchResults(results, fastPaint);
}
/**
@@ -346,13 +372,11 @@ public class AlignmentPanel extends GAlignmentPanel implements
* (if any)
*
* @param searchResults
- * @param redrawOverview
* @return
*/
- public boolean scrollToPosition(SearchResultsI searchResults,
- boolean redrawOverview)
+ public boolean scrollToPosition(SearchResultsI searchResults)
{
- return scrollToPosition(searchResults, 0, redrawOverview, false);
+ return scrollToPosition(searchResults, 0, false);
}
/**
@@ -365,14 +389,12 @@ public class AlignmentPanel extends GAlignmentPanel implements
* @param verticalOffset
* if greater than zero, allows scrolling to a position below the
* first displayed sequence
- * @param redrawOverview
- * - when set, the overview will be recalculated (takes longer)
* @param centre
* if true, try to centre the search results horizontally in the view
* @return
*/
protected boolean scrollToPosition(SearchResultsI results,
- int verticalOffset, boolean redrawOverview, boolean centre)
+ int verticalOffset, boolean centre)
{
int startv, endv, starts, ends;
ViewportRanges ranges = av.getRanges();
@@ -465,8 +487,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
/*
* Scroll down to make end of search results visible
*/
- setScrollValues(ranges.getStartRes(), starts + seqIndex - ends
- + 1);
+ setScrollValues(ranges.getStartRes(), starts + seqIndex - ends + 1);
}
/*
* Else results are already visible - no need to scroll
@@ -478,7 +499,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
scrollNeeded = ranges.scrollToWrappedVisible(start);
}
- paintAlignment(redrawOverview, false);
+ paintAlignment(false, false);
return scrollNeeded;
}
@@ -537,7 +558,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
addNotify();
// TODO: many places call this method and also paintAlignment with various
// different settings. this means multiple redraws are triggered...
- paintAlignment(true, false);
+ paintAlignment(true, av.needToUpdateStructureViews());
}
/**
@@ -546,38 +567,27 @@ public class AlignmentPanel extends GAlignmentPanel implements
*/
protected void validateAnnotationDimensions(boolean adjustPanelHeight)
{
- int annotationHeight = getAnnotationPanel().adjustPanelHeight();
+ // BH 2018.04.18 comment: addNotify() is not appropriate here. We
+ // are not changing ancestors, and keyboard action listeners do
+ // not need to be reset, and most importantly, we can't be sure we are actually
+ // connected to resources.
+
+ // addNotify() is a very expensive operation,
+ // requiring a full re-layout of all parents and children.
+
+ // Note in JComponent:
+
+ // This method is called by the toolkit internally and should
+ // not be called directly by programs.
+
+ // I note that addNotify() is called in several areas of Jalview.
- 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;
+ int annotationHeight = getAnnotationPanel().adjustPanelHeight();
+ annotationHeight = getAnnotationPanel()
+ .adjustForAlignFrame(adjustPanelHeight, annotationHeight);
- /*
- * 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;
- }
+ // BH no!!
hscroll.addNotify();
-
annotationScroller.setPreferredSize(
new Dimension(annotationScroller.getWidth(), annotationHeight));
@@ -592,16 +602,13 @@ public class AlignmentPanel extends GAlignmentPanel implements
/**
* update alignment layout for viewport settings
- *
- * @param wrap
- * DOCUMENT ME!
*/
public void updateLayout()
{
+ ViewportRanges ranges = av.getRanges();
fontChanged();
setAnnotationVisible(av.isShowAnnotation());
boolean wrap = av.getWrapAlignment();
- ViewportRanges ranges = av.getRanges();
ranges.setStartSeq(0);
scalePanelHolder.setVisible(!wrap);
hscroll.setVisible(!wrap);
@@ -618,6 +625,22 @@ public class AlignmentPanel extends GAlignmentPanel implements
annotationSpaceFillerHolder.setVisible(true);
}
+ idSpaceFillerPanel1.setVisible(!wrap);
+
+ /*
+ * defer dimension calculations if panel not yet added to a Window
+ * BH 2020.06.09
+ */
+ if (getTopLevelAncestor() == null)
+ {
+ repaint();
+ return;
+ }
+
+ if (!wrap && av.isShowAnnotation())
+ {
+ validateAnnotationDimensions(false);
+ }
int canvasWidth = getSeqPanel().seqCanvas.getWidth();
if (canvasWidth > 0)
{ // may not yet be laid out
@@ -638,7 +661,10 @@ public class AlignmentPanel extends GAlignmentPanel implements
}
}
- idSpaceFillerPanel1.setVisible(!wrap);
+ // System.out.println("ap dim = " + getSize());
+ // these values will go negative if getSize() returns (0,0):
+ // System.out.println("seqpan dim = " + getSeqPanel().getSize());
+ // System.out.println("seqcan dim = " + getSeqPanel().seqCanvas.getSize());
repaint();
}
@@ -652,10 +678,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
* visible row to scroll to
*
*/
- public void setScrollValues(int xpos, int ypos)
+ public void setScrollValues(int x, int y)
{
- int x = xpos;
- int y = ypos;
if (av == null || av.getAlignment() == null)
{
@@ -668,55 +692,26 @@ public class AlignmentPanel extends GAlignmentPanel implements
}
else
{
- int width = av.getAlignment().getWidth();
+ int width = av.getAlignment().getVisibleWidth();
int height = av.getAlignment().getHeight();
-
- if (av.hasHiddenColumns())
- {
- // reset the width to exclude hidden columns
- width = av.getAlignment().getHiddenColumns()
- .absoluteToVisibleColumn(width);
- }
-
- hextent = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
- vextent = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight();
-
- if (hextent > width)
- {
- hextent = width;
- }
-
- if (vextent > height)
- {
- vextent = height;
- }
-
- if ((hextent + x) > width)
- {
- x = width - hextent;
- }
-
- if ((vextent + y) > height)
- {
- y = height - vextent;
- }
-
- if (y < 0)
- {
- y = 0;
- }
-
- if (x < 0)
- {
- x = 0;
- }
-
- // update the scroll values
- hscroll.setValues(x, hextent, 0, width);
- vscroll.setValues(y, vextent, 0, height);
+
+ hextent = Math.min(getSeqPanel().seqCanvas.getWidth() / av.getCharWidth(), width);
+ vextent = Math.min(getSeqPanel().seqCanvas.getHeight() / av.getCharHeight(), height);
+
+ x = Math.max(0, Math.min(x, width - hextent));
+ y = Math.max(0, Math.min(y, height - vextent));
+
+ updateRanges(x, y);
+ updateScrollBars(x, y, width, height);
}
}
+ private void updateScrollBars(int x, int y, int width, int height)
+ {
+ hscroll.setValues(x, hextent, 0, width);
+ vscroll.setValues(y, vextent, 0, height);
+ }
+
/**
* Respond to adjustment event when horizontal or vertical scrollbar is
* changed
@@ -733,41 +728,54 @@ public class AlignmentPanel extends GAlignmentPanel implements
return;
}
- ViewportRanges ranges = av.getRanges();
-
if (evt.getSource() == hscroll)
{
+ if (!updateRanges(hscroll.getValue(), Integer.MIN_VALUE))
+ return;
+ }
+ else if (evt.getSource() == vscroll)
+ {
+ if (!updateRanges(Integer.MIN_VALUE, vscroll.getValue()))
+ return;
+ }
+ repaint();
+ }
+
+ private boolean updateRanges(int x, int y)
+ {
+ ViewportRanges ranges = av.getRanges();
+ boolean isChanged = false;
+ if (x != Integer.MIN_VALUE)
+ {
int oldX = ranges.getStartRes();
int oldwidth = ranges.getViewportWidth();
- int x = hscroll.getValue();
int width = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
// if we're scrolling to the position we're already at, stop
// this prevents infinite recursion of events when the scroll/viewport
// ranges values are the same
- if ((x == oldX) && (width == oldwidth))
+ if (width > 0 && (x != oldX || width != oldwidth))
{
- return;
+ ranges.setViewportStartAndWidth(x, width);
+ isChanged = true;
}
- ranges.setViewportStartAndWidth(x, width);
}
- else if (evt.getSource() == vscroll)
+ if (y != Integer.MIN_VALUE)
{
int oldY = ranges.getStartSeq();
int oldheight = ranges.getViewportHeight();
- int y = vscroll.getValue();
int height = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight();
// if we're scrolling to the position we're already at, stop
// this prevents infinite recursion of events when the scroll/viewport
// ranges values are the same
- if ((y == oldY) && (height == oldheight))
+ if (height > 0 && (y != oldY || height != oldheight))
{
- return;
+ ranges.setViewportStartAndHeight(y, height);
+ isChanged = true;
}
- ranges.setViewportStartAndHeight(y, height);
}
- repaint();
+ return isChanged;
}
/**
@@ -846,7 +854,6 @@ public class AlignmentPanel extends GAlignmentPanel implements
av.isShowAutocalculatedAbove());
sorter.sort(getAlignment().getAlignmentAnnotation(),
av.getSortAnnotationsBy());
- repaint();
if (updateStructures)
{
@@ -854,23 +861,21 @@ public class AlignmentPanel extends GAlignmentPanel implements
}
if (updateOverview)
{
-
+ alignFrame.repaint();
if (overviewPanel != null)
{
overviewPanel.updateOverviewImage();
}
+ } else {
+ invalidate(); // needed so that the id width adjuster works correctly
+ repaint();
}
}
- /**
- * DOCUMENT ME!
- *
- * @param g
- * DOCUMENT ME!
- */
@Override
public void paintComponent(Graphics g)
{
+ // BH OUCH!
invalidate(); // needed so that the id width adjuster works correctly
Dimension d = getIdPanel().getIdCanvas().getPreferredSize();
@@ -884,7 +889,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
* though I still think this call should be elsewhere.
*/
ViewportRanges ranges = av.getRanges();
- setScrollValues(ranges.getStartRes(), ranges.getStartSeq());
+ // setScrollValues(ranges.getStartRes(), ranges.getStartSeq());
+ super.paintComponent(g);
}
/**
@@ -989,8 +995,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
final int totalSeq = (pageHeight - scaleHeight) / charHeight - 1;
- final int alignmentWidth = av.getAlignment().getWidth();
- final int pagesWide = (alignmentWidth / totalRes) + 1;
+ final int alignmentWidth = av.getAlignment().getVisibleWidth();
+ int pagesWide = (alignmentWidth / totalRes) + 1;
final int startRes = (pageIndex % pagesWide) * totalRes;
final int endRes = Math.min(startRes + totalRes - 1,
@@ -1042,8 +1048,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
* single graphics context), then reset to (0, scale height)
*/
alignmentGraphics.translate(alignmentGraphicsOffset, scaleHeight);
- getSeqPanel().seqCanvas.drawPanelForPrinting(alignmentGraphics, startRes,
- endRes, startSeq, endSeq - 1);
+ getSeqPanel().seqCanvas.drawPanelForPrinting(alignmentGraphics,
+ startRes, endRes, startSeq, endSeq - 1);
alignmentGraphics.translate(-alignmentGraphicsOffset, 0);
if (av.isShowAnnotation() && (endSeq == alignmentHeight))
@@ -1087,9 +1093,10 @@ public class AlignmentPanel extends GAlignmentPanel implements
*
* @throws PrinterException
*/
- public int printWrappedAlignment(int pageWidth, int pageHeight, int pageNumber,
- Graphics g) throws PrinterException
+ public int printWrappedAlignment(int pageWidth, int pageHeight,
+ int pageNumber, Graphics g) throws PrinterException
{
+ getSeqPanel().seqCanvas.calculateWrappedGeometry();
int annotationHeight = 0;
if (av.isShowAnnotation())
{
@@ -1107,15 +1114,11 @@ public class AlignmentPanel extends GAlignmentPanel implements
int idWidth = getVisibleIdWidth(false);
- int maxwidth = av.getAlignment().getWidth();
- if (av.hasHiddenColumns())
- {
- maxwidth = av.getAlignment().getHiddenColumns()
- .absoluteToVisibleColumn(maxwidth) - 1;
- }
+ int maxwidth = av.getAlignment().getVisibleWidth();
int resWidth = getSeqPanel().seqCanvas
.getWrappedCanvasWidth(pageWidth - idWidth);
+ av.getRanges().setViewportStartAndWidth(0, resWidth);
int totalHeight = cHeight * (maxwidth / resWidth + 1);
@@ -1124,6 +1127,12 @@ public class AlignmentPanel extends GAlignmentPanel implements
g.setFont(av.getFont());
g.setColor(Color.black);
+ /*
+ * 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 repeated processing in the
+ * 'normal' case, when all pages are printed)
+ */
g.translate(0, -pageNumber * pageHeight);
g.setClip(0, pageNumber * pageHeight, pageWidth, pageHeight);
@@ -1136,8 +1145,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
g.translate(idWidth, 0);
- getSeqPanel().seqCanvas.drawWrappedPanelForPrinting(g, pageWidth - idWidth,
- totalHeight, 0);
+ getSeqPanel().seqCanvas.drawWrappedPanelForPrinting(g,
+ pageWidth - idWidth, totalHeight, 0);
if ((pageNumber * pageHeight) < totalHeight)
{
@@ -1169,111 +1178,73 @@ public class AlignmentPanel extends GAlignmentPanel implements
* be returned
* @return
*/
- public int getVisibleIdWidth(boolean onscreen)
+ protected int getVisibleIdWidth(boolean onscreen)
{
// see if rendering offscreen - check preferences and calc width accordingly
if (!onscreen && Cache.getDefault("FIGURE_AUTOIDWIDTH", false))
{
- return calculateIdWidth(-1).width + 4;
+ return calculateIdWidth(-1).width;
}
- Integer idwidth = null;
- if (onscreen || (idwidth = Cache
- .getIntegerProperty("FIGURE_FIXEDIDWIDTH")) == null)
+ Integer idwidth = onscreen ? null
+ : Cache.getIntegerProperty("FIGURE_FIXEDIDWIDTH");
+ if (idwidth != null)
{
- int w = getIdPanel().getWidth();
- return (w > 0 ? w : calculateIdWidth().width + 4);
+ return idwidth.intValue() + ID_WIDTH_PADDING;
}
- return idwidth.intValue() + 4;
+
+ int w = getIdPanel().getWidth();
+ return (w > 0 ? w : calculateIdWidth().width);
}
- 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();
- if (av.hasHiddenColumns())
- {
- maxwidth = av.getAlignment().getHiddenColumns()
- .absoluteToVisibleColumn(maxwidth);
- }
+ int maxwidth = av.getAlignment().getVisibleWidth();
int height = ((av.getAlignment().getHeight() + 1) * av.getCharHeight())
+ getScalePanel().getHeight();
@@ -1282,7 +1253,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
@@ -1306,27 +1277,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
@@ -1361,13 +1311,13 @@ public class AlignmentPanel extends GAlignmentPanel implements
String triplet = null;
if (av.getAlignment().isNucleotide())
{
- triplet = ResidueProperties.nucleotideName.get(seq
- .getCharAt(column) + "");
+ triplet = ResidueProperties.nucleotideName
+ .get(seq.getCharAt(column) + "");
}
else
{
- triplet = ResidueProperties.aa2Triplet.get(seq.getCharAt(column)
- + "");
+ triplet = ResidueProperties.aa2Triplet
+ .get(seq.getCharAt(column) + "");
}
if (triplet == null)
@@ -1384,7 +1334,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
text.append(" features = seq.findFeatures(column, column);
+ List features = seq.findFeatures(column,
+ column);
for (SequenceFeature sf : features)
{
if (sf.isContactFeature())
@@ -1456,6 +1408,12 @@ public class AlignmentPanel extends GAlignmentPanel implements
}
+ /**
+ * Answers the height of the entire alignment in pixels, assuming it is in
+ * wrapped mode
+ *
+ * @return
+ */
int getWrappedHeight()
{
int seqPanelWidth = getSeqPanel().seqCanvas.getWidth();
@@ -1480,6 +1438,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
int annotationHeight = 0;
if (av.isShowAnnotation())
{
+ hgap += SeqCanvas.SEQS_ANNOTATION_GAP;
annotationHeight = getAnnotationPanel().adjustPanelHeight();
}
@@ -1588,7 +1547,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
@Override
public String getViewName()
{
- return av.viewName;
+ return av.getViewName();
}
/**
@@ -1719,7 +1678,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
*/
protected void scrollToCentre(SearchResultsI sr, int verticalOffset)
{
- scrollToPosition(sr, verticalOffset, true, true);
+ scrollToPosition(sr, verticalOffset, true);
}
/**
@@ -1772,10 +1731,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
public void propertyChange(PropertyChangeEvent evt)
{
// update this panel's scroll values based on the new viewport ranges values
- ViewportRanges ranges = av.getRanges();
- int x = ranges.getStartRes();
- int y = ranges.getStartSeq();
- setScrollValues(x, y);
+ updateScrollBarsFromRanges();
// now update any complementary alignment (its viewport ranges object
// is different so does not get automatically updated)
@@ -1787,6 +1743,12 @@ public class AlignmentPanel extends GAlignmentPanel implements
}
}
+ void updateScrollBarsFromRanges()
+ {
+ ViewportRanges ranges = av.getRanges();
+ setScrollValues(ranges.getStartRes(), ranges.getStartSeq());
+ }
+
/**
* Set the reference to the PCA/Tree chooser dialog for this panel. This
* reference should be nulled when the dialog is closed.
@@ -1806,4 +1768,202 @@ public class AlignmentPanel extends GAlignmentPanel implements
{
return calculationDialog;
}
+
+ /**
+ * From appletgui, for JalviewJS JavaScript interface
+ *
+ * preliminary - untested
+ *
+ * @param ostart
+ * @param end
+ * @param seqIndex
+ * @param scrollToNearest
+ * @param redrawOverview
+ * @return
+ */
+ public boolean scrollTo(int ostart, int end, int seqIndex,
+ boolean scrollToNearest, boolean redrawOverview)
+ {
+ int startv, endv, starts, ends;// , width;
+
+ int start = -1;
+ if (av.hasHiddenColumns())
+ {
+ AlignmentI al = av.getAlignment();
+ start = al.getHiddenColumns().absoluteToVisibleColumn(ostart);
+ end = al.getHiddenColumns().absoluteToVisibleColumn(end);
+ if (start == end)
+ {
+ if (!scrollToNearest && !al.getHiddenColumns().isVisible(ostart))
+ {
+ // don't scroll - position isn't visible
+ return false;
+ }
+ }
+ }
+ else
+ {
+ start = ostart;
+ }
+
+ ViewportRanges ranges = av.getRanges();
+ if (!av.getWrapAlignment())
+ {
+ /*
+ * int spos=av.getStartRes(),sqpos=av.getStartSeq(); if ((startv =
+ * av.getStartRes()) >= start) { spos=start-1; // seqIn //
+ * setScrollValues(start - 1, seqIndex); } else if ((endv =
+ * av.getEndRes()) <= end) { // setScrollValues(spos=startv + 1 + end -
+ * endv, seqIndex); spos=startv + 1 + end - endv; } else if ((starts =
+ * av.getStartSeq()) > seqIndex) { setScrollValues(av.getStartRes(),
+ * seqIndex); } else if ((ends = av.getEndSeq()) <= seqIndex) {
+ * setScrollValues(av.getStartRes(), starts + seqIndex - ends + 1); }
+ */
+
+ // below is scrolling logic up to Jalview 2.8.2
+ // if ((av.getStartRes() > end)
+ // || (av.getEndRes() < start)
+ // || ((av.getStartSeq() > seqIndex) || (av.getEndSeq() < seqIndex)))
+ // {
+ // if (start > av.getAlignment().getWidth() - hextent)
+ // {
+ // start = av.getAlignment().getWidth() - hextent;
+ // if (start < 0)
+ // {
+ // start = 0;
+ // }
+ //
+ // }
+ // if (seqIndex > av.getAlignment().getHeight() - vextent)
+ // {
+ // seqIndex = av.getAlignment().getHeight() - vextent;
+ // if (seqIndex < 0)
+ // {
+ // seqIndex = 0;
+ // }
+ // }
+ // setScrollValues(start, seqIndex);
+ // }
+ // logic copied from jalview.gui.AlignmentPanel:
+ if ((startv = ranges.getStartRes()) >= start)
+ {
+ /*
+ * Scroll left to make start of search results visible
+ */
+ setScrollValues(start - 1, seqIndex);
+ }
+ else if ((endv = ranges.getEndRes()) <= end)
+ {
+ /*
+ * Scroll right to make end of search results visible
+ */
+ setScrollValues(startv + 1 + end - endv, seqIndex);
+ }
+ else if ((starts = ranges.getStartSeq()) > seqIndex)
+ {
+ /*
+ * Scroll up to make start of search results visible
+ */
+ setScrollValues(ranges.getStartRes(), seqIndex);
+ }
+ else if ((ends = ranges.getEndSeq()) <= seqIndex)
+ {
+ /*
+ * Scroll down to make end of search results visible
+ */
+ setScrollValues(ranges.getStartRes(), starts + seqIndex - ends + 1);
+ }
+ /*
+ * Else results are already visible - no need to scroll
+ */
+ }
+ else
+ {
+ ranges.scrollToWrappedVisible(start);
+ }
+
+ paintAlignment(redrawOverview, false);
+ return true;
+ }
+
+ private boolean holdRepaint = false;
+
+ /**
+ * Called by IdCanvas and SeqPanel to defer painting until after JVP loading.
+ *
+ * @return true if holding
+ */
+ public boolean getHoldRepaint()
+ {
+ return holdRepaint;
+ }
+
+ /**
+ * Called by Jalview2xml while loading
+ *
+ * @param tf
+ */
+ public void setHoldRepaint(boolean tf)
+ {
+ if (holdRepaint == tf)
+ {
+ return;
+ }
+ holdRepaint = tf;
+ if (!tf)
+ {
+ repaint();
+ }
+ }
+
+ @Override
+ public void repaint()
+ {
+ if (holdRepaint)
+ {
+ // System.out.println("AP repaint holding");
+ // Platform.stackTrace();
+ return;
+ }
+ super.repaint();
+ }
+
+ public void selectAllSequences()
+ {
+ selectSequences(av.getAlignment().getSequences());
+ }
+
+ public void deselectAllSequences()
+ {
+ if (av.cursorMode)
+ {
+ getSeqPanel().keyboardNo1 = null;
+ getSeqPanel().keyboardNo2 = null;
+ }
+ av.setSelectionGroup(null);
+ av.getColumnSelection().clear();
+ av.setSearchResults(null);
+ getIdPanel().getIdCanvas().searchResults = null;
+ av.sendSelection();
+ // JAL-2034 - should delegate to
+ // alignPanel to decide if overview needs
+ // updating.
+ paintAlignment(false, false);
+ PaintRefresher.Refresh(this, av.getSequenceSetId());
+ }
+
+ public void selectSequences(List seqs)
+ {
+ SequenceGroup sg = new SequenceGroup(seqs);
+ sg.setEndRes(av.getAlignment().getWidth() - 1);
+ av.setSelectionGroup(sg);
+ av.isSelectionGroupChanged(true);
+ av.sendSelection();
+ // JAL-2034 - should delegate to
+ // alignPanel to decide if overview needs
+ // updating.
+ paintAlignment(false, false);
+ PaintRefresher.Refresh(this, av.getSequenceSetId());
+ }
+
}