X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Fgui%2FAlignmentPanel.java;h=277e11dd84ab24874e80c089f9ef538233f41a07;hb=0751c58086542f9e0466201b624f84d1efd547bb;hp=2b6d5a02a501f2e83dbf8844c58f29d4a7dc1b0c;hpb=059d7006f69f0c1623627ee437f9479455260ee5;p=jalview.git
diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java
index 2b6d5a0..277e11d 100644
--- a/src/jalview/gui/AlignmentPanel.java
+++ b/src/jalview/gui/AlignmentPanel.java
@@ -20,29 +20,6 @@
*/
package jalview.gui;
-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.ViewportListenerI;
-import jalview.viewmodel.ViewportRanges;
-
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
@@ -67,6 +44,30 @@ 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!
*
@@ -122,7 +123,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
*/
public AlignmentPanel(AlignFrame af, final AlignViewport av)
{
-// setBackground(Color.white); // BH 2019
+ setName("AligmentPanel");
+ // setBackground(Color.white); // BH 2019
alignFrame = af;
this.av = av;
setSeqPanel(new SeqPanel(av, this));
@@ -173,6 +175,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
ranges.setViewportWidth(widthInRes);
ranges.setViewportHeight(heightInSeq);
}
+ repaint();
}
});
@@ -183,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;
}
}
};
@@ -259,32 +269,37 @@ public class AlignmentPanel extends GAlignmentPanel implements
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 idWidth = Math.min(afwidth - 200, 2 * afwidth / 3);
- int maxwidth = Math.max(IdwidthAdjuster.MIN_ID_WIDTH, idWidth);
- 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;
}
/*
* fudge: if desired width has changed, update layout
* (see also paintComponent - updates layout on a repaint)
*/
- if (r.width != oldWidth)
+ if (d.width != oldWidth)
{
- idPanelHolder.setPreferredSize(r);
+ idPanelHolder.setPreferredSize(d);
validate();
}
- return r;
+ 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);
}
/**
@@ -296,10 +311,9 @@ public class AlignmentPanel extends GAlignmentPanel implements
* @return Dimension giving the maximum width of the alignment label panel
* that should be used.
*/
- protected Dimension calculateIdWidth(int maxwidth)
+ 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()));
@@ -307,10 +321,12 @@ public class AlignmentPanel extends GAlignmentPanel implements
int i = 0;
int idWidth = 0;
+ boolean withSuffix = av.getShowJVSuffix();
+
while ((i < al.getHeight()) && (al.getSequenceAt(i) != null))
{
SequenceI s = al.getSequenceAt(i);
- String id = s.getDisplayId(av.getShowJVSuffix());
+ String id = s.getDisplayId(withSuffix);
int stringWidth = fm.stringWidth(id);
idWidth = Math.max(idWidth, stringWidth);
i++;
@@ -471,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
@@ -554,17 +569,24 @@ public class AlignmentPanel extends GAlignmentPanel implements
{
// 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. addNotify() is a very expensive operation,
+ // 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.
int annotationHeight = getAnnotationPanel().adjustPanelHeight();
annotationHeight = getAnnotationPanel()
.adjustForAlignFrame(adjustPanelHeight, annotationHeight);
+ // BH no!!
hscroll.addNotify();
annotationScroller.setPreferredSize(
new Dimension(annotationScroller.getWidth(), annotationHeight));
@@ -572,7 +594,6 @@ public class AlignmentPanel extends GAlignmentPanel implements
Dimension e = idPanel.getSize();
alabels.setSize(new Dimension(e.width, annotationHeight));
-
annotationSpaceFillerHolder.setPreferredSize(new Dimension(
annotationSpaceFillerHolder.getWidth(), annotationHeight));
annotationScroller.validate();
@@ -581,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);
@@ -605,9 +623,24 @@ public class AlignmentPanel extends GAlignmentPanel implements
{
annotationScroller.setVisible(true);
annotationSpaceFillerHolder.setVisible(true);
- validateAnnotationDimensions(false);
}
+ 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
@@ -628,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();
}
@@ -642,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)
{
@@ -660,46 +694,24 @@ public class AlignmentPanel extends GAlignmentPanel implements
{
int width = av.getAlignment().getVisibleWidth();
int height = av.getAlignment().getHeight();
-
- 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
@@ -716,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;
}
/**
@@ -829,7 +854,6 @@ public class AlignmentPanel extends GAlignmentPanel implements
av.isShowAutocalculatedAbove());
sorter.sort(getAlignment().getAlignmentAnnotation(),
av.getSortAnnotationsBy());
- repaint();
if (updateStructures)
{
@@ -837,17 +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();
}
}
@Override
public void paintComponent(Graphics g)
{
+ // BH OUCH!
invalidate(); // needed so that the id width adjuster works correctly
Dimension d = getIdPanel().getIdCanvas().getPreferredSize();
@@ -861,7 +889,7 @@ 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);
}
@@ -1020,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))
@@ -1065,11 +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(getWidth(),
- getHeight());
+ getSeqPanel().seqCanvas.calculateWrappedGeometry();
int annotationHeight = 0;
if (av.isShowAnnotation())
{
@@ -1118,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)
{
@@ -1284,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)
@@ -1307,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())
@@ -1702,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)
@@ -1717,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.
@@ -1856,19 +1888,29 @@ public class AlignmentPanel extends GAlignmentPanel implements
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;
}
- public void setHoldRepaint(boolean b)
+ /**
+ * Called by Jalview2xml while loading
+ *
+ * @param tf
+ */
+ public void setHoldRepaint(boolean tf)
{
- if (holdRepaint == b)
+ if (holdRepaint == tf)
{
return;
}
- holdRepaint = b;
- if (!b)
+ holdRepaint = tf;
+ if (!tf)
{
repaint();
}
@@ -1886,5 +1928,42 @@ public class AlignmentPanel extends GAlignmentPanel implements
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());
+ }
}