Fixed incorrect value in BLOSUM 62 score
- matrix - C->R should be '3' Old matrix restored with
+ matrix - C->R should be '-3' Old matrix restored with
this one-line groovy script: jalview.analysis.scoremodels.ScoreModels.instance.BLOSUM62.@matrix[4][1]=3
@@ -136,7 +136,7 @@ li:before {
earlier versions of Jalview, gaps matching gaps were
penalised, and gaps matching non-gaps penalised even more.
In the PCA calculation, gaps were actually treated as
- non-gaps - so different costs were applied, which mean't
+ non-gaps - so different costs were applied, which meant
Jalview's PCAs were different to those produced by
SeqSpace. Jalview now treats gaps in the same way as
SeqSpace (ie it scores them as 0). To restore pre-2.10.2
diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties
index f1ac099..c9d2e63 100644
--- a/resources/lang/Messages.properties
+++ b/resources/lang/Messages.properties
@@ -745,7 +745,6 @@ label.delete_sbrs_definition = Delete SBRS Definition
label.your_sequences_have_been_verified = Your sequences have been verified against known sequence databases.\n(Use Calculate | Show flanking regions to show enclosing sequence.)\nTo preserve data changes, save your alignment.\n\n
label.sequences_updated = Sequences updated
label.dbref_search_completed = DBRef search completed
-label.show_all_chains = Show all chains
label.fetch_all_param = Fetch all {0}
label.paste_new_window = Paste To New Window
label.settings_for_param = Settings for {0}
@@ -1282,7 +1281,6 @@ label.SEQUENCE_ID_no_longer_used = $SEQUENCE_ID$ is no longer used for DB access
label.SEQUENCE_ID_for_DB_ACCESSION1 = Please review your URL links in the 'Connections' tab of the Preferences window:
label.SEQUENCE_ID_for_DB_ACCESSION2 = URL links using '$SEQUENCE_ID$' for DB accessions now use '$DB_ACCESSION$'.
label.do_not_display_again = Do not display this message again
-exception.url_cannot_have_miriam_id = {0} is a MIRIAM id and cannot be used as a custom url name
exception.url_cannot_have_duplicate_id = {0} cannot be used as a label for more than one line
label.filter = Filter text:
action.customfilter = Custom only
diff --git a/resources/lang/Messages_es.properties b/resources/lang/Messages_es.properties
index 7808480..64f06c8 100644
--- a/resources/lang/Messages_es.properties
+++ b/resources/lang/Messages_es.properties
@@ -682,7 +682,6 @@ label.delete_sbrs_definition = Borrar una definici
label.your_sequences_have_been_verified = Sus secuencias has sido verificadas en una base de datos de secuencias conocidas.\n(Usar Calcular | Mostrar flancos para ver ampliación.)\nPara mantener los datos actualizados, guarde su alineamiento.\n\n
label.sequences_updated = Secuencias actualizadas
label.dbref_search_completed = Búsqueda de DBRef terminada
-label.show_all_chains = Mostrar todas las cadenas
label.fetch_all_param = Recuperar todas {0}
label.paste_new_window = Pegar en una nueva ventana
label.settings_for_param = Configuración para {0}
@@ -1282,7 +1281,6 @@ label.SEQUENCE_ID_no_longer_used = $SEQUENCE_ID$ no se utiliza m
label.SEQUENCE_ID_for_DB_ACCESSION1 = Por favor, revise sus URLs en la pestaña 'Conexiones' de la ventana de Preferencias:
label.SEQUENCE_ID_for_DB_ACCESSION2 = URL enlaza usando '$SEQUENCE_ID$' para accesiones DB ahora usar '$DB_ACCESSION$'.
label.do_not_display_again = No mostrar este mensaje de nuevo
-exception.url_cannot_have_miriam_id = {0} es una id MIRIAM y no puede ser usada como nombre url personalizado
exception.url_cannot_have_duplicate_id = {0} no puede ser usada como etiqueta en más de un enlace
label.filter = Filtrar texto:
action.customfilter = Sólo personalizado
@@ -1300,11 +1298,15 @@ warn.name_cannot_be_duplicate = Los nombres URL definidos por el usuario deben s
label.invalid_name = Nombre inválido !
label.output_seq_details = Seleccionar Detalles de la secuencia para ver todas
label.urllinks = Enlaces
+label.default_cache_size = Tamaño del caché por defecto
+action.clear_cached_items = Borrar elementos en caché
label.quality_descr = Calidad de alineamiento basándose en puntuación Blosum62
label.conservation_descr = Conservación del alineamiento total menos de {0}% huecos
label.consensus_descr = % Identidad
label.complement_consensus_descr = % Identidad para cDNA
label.strucconsensus_descr = % Identidad para pares de bases
label.occupancy_descr = Número de posiciones alineadas
-label.togglehidden = Show hidden regions
+label.togglehidden = Mostrar regiones ocultas
+label.show_experimental = Habilitar funciones experimentales
+label.show_experimental_tip = Habilitar funciones nuevas y experimentales (ver Latest Release Notes para más detalles)
label.warning_hidden = Advertencia: {0} {1} está actualmente oculto
diff --git a/src/jalview/api/FeatureColourI.java b/src/jalview/api/FeatureColourI.java
index 01eb7fa..0ded079 100644
--- a/src/jalview/api/FeatureColourI.java
+++ b/src/jalview/api/FeatureColourI.java
@@ -146,7 +146,9 @@ public interface FeatureColourI
boolean hasThreshold();
/**
- * Returns the computed colour for the given sequence feature
+ * Returns the computed colour for the given sequence feature. Answers null if
+ * the score of this feature instance is outside the range to render (if any),
+ * i.e. lies below or above a configured threshold.
*
* @param feature
* @return
@@ -154,17 +156,6 @@ public interface FeatureColourI
Color getColor(SequenceFeature feature);
/**
- * Answers true if the feature has a simple colour, or is coloured by label,
- * or has a graduated colour and the score of this feature instance is within
- * the range to render (if any), i.e. does not lie below or above any
- * threshold set.
- *
- * @param feature
- * @return
- */
- boolean isColored(SequenceFeature feature);
-
- /**
* Update the min-max range for a graduated colour scheme
*
* @param min
diff --git a/src/jalview/appletgui/APopupMenu.java b/src/jalview/appletgui/APopupMenu.java
index d5b7132..80b2d73 100644
--- a/src/jalview/appletgui/APopupMenu.java
+++ b/src/jalview/appletgui/APopupMenu.java
@@ -836,12 +836,16 @@ public class APopupMenu extends java.awt.PopupMenu implements
}
}
- if (ap.seqPanel.seqCanvas.getFeatureRenderer().amendFeatures(seqs,
- features, true, ap))
+ if (!seqs.isEmpty())
{
- ap.alignFrame.sequenceFeatures.setState(true);
- ap.av.setShowSequenceFeatures(true);
- ap.highlightSearchResults(null);
+ if (ap.seqPanel.seqCanvas.getFeatureRenderer().amendFeatures(seqs,
+ features, true, ap))
+ {
+ ap.alignFrame.sequenceFeatures.setState(true);
+ ap.av.setShowSequenceFeatures(true);
+ ap.av.setSearchResults(null); // clear highlighting
+ ap.repaint(); // draw new/amended features
+ }
}
}
else
diff --git a/src/jalview/appletgui/AlignFrame.java b/src/jalview/appletgui/AlignFrame.java
index 24f882e..b30c5ae 100644
--- a/src/jalview/appletgui/AlignFrame.java
+++ b/src/jalview/appletgui/AlignFrame.java
@@ -599,25 +599,11 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
}
case KeyEvent.VK_PAGE_UP:
- if (viewport.getWrapAlignment())
- {
- ranges.scrollUp(true);
- }
- else
- {
- ranges.pageUp();
- }
+ ranges.pageUp();
break;
case KeyEvent.VK_PAGE_DOWN:
- if (viewport.getWrapAlignment())
- {
- ranges.scrollUp(false);
- }
- else
- {
- ranges.pageDown();
- }
+ ranges.pageDown();
break;
case KeyEvent.VK_Z:
@@ -1811,7 +1797,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
synchronized void slideSequences(boolean right, int size)
{
- List sg = new Vector();
+ List sg = new Vector<>();
if (viewport.cursorMode)
{
sg.add(viewport.getAlignment().getSequenceAt(
@@ -1913,7 +1899,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
static StringBuffer copiedSequences;
- static Vector copiedHiddenColumns;
+ static Vector copiedHiddenColumns;
protected void copy_actionPerformed()
{
@@ -1924,7 +1910,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
SequenceGroup sg = viewport.getSelectionGroup();
copiedSequences = new StringBuffer();
- Map orderedSeqs = new HashMap();
+ Map orderedSeqs = new HashMap<>();
for (int i = 0; i < sg.getSize(); i++)
{
SequenceI seq = sg.getSequenceAt(i);
@@ -1937,13 +1923,13 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
if (viewport.hasHiddenColumns() && viewport.getSelectionGroup() != null)
{
- copiedHiddenColumns = new Vector();
+ copiedHiddenColumns = new Vector<>(viewport.getAlignment()
+ .getHiddenColumns().getHiddenColumnsCopy());
int hiddenOffset = viewport.getSelectionGroup().getStartRes();
- for (int[] region : viewport.getAlignment().getHiddenColumns()
- .getHiddenRegions())
+ for (int[] region : copiedHiddenColumns)
{
- copiedHiddenColumns.addElement(new int[] {
- region[0] - hiddenOffset, region[1] - hiddenOffset });
+ region[0] = region[0] - hiddenOffset;
+ region[1] = region[1] - hiddenOffset;
}
}
else
@@ -2058,7 +2044,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
{
for (int i = 0; i < copiedHiddenColumns.size(); i++)
{
- int[] region = (int[]) copiedHiddenColumns.elementAt(i);
+ int[] region = copiedHiddenColumns.elementAt(i);
af.viewport.hideColumns(region[0], region[1]);
}
}
@@ -2644,7 +2630,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
}
Frame frame = new Frame();
- OverviewPanel overview = new OverviewPanel(alignPanel);
+ final OverviewPanel overview = new OverviewPanel(alignPanel);
frame.add(overview);
// +50 must allow for applet frame window
jalview.bin.JalviewLite.addFrame(frame, MessageManager.formatMessage(
@@ -2659,6 +2645,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
@Override
public void windowClosing(WindowEvent e)
{
+ overview.dispose();
if (ap != null)
{
ap.setOverviewPanel(null);
diff --git a/src/jalview/appletgui/AlignViewport.java b/src/jalview/appletgui/AlignViewport.java
index 73cd9e9..1d2c4bc 100644
--- a/src/jalview/appletgui/AlignViewport.java
+++ b/src/jalview/appletgui/AlignViewport.java
@@ -26,6 +26,7 @@ import jalview.api.FeatureSettingsModelI;
import jalview.bin.JalviewLite;
import jalview.commands.CommandI;
import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.HiddenColumns;
import jalview.datamodel.SearchResults;
@@ -229,43 +230,6 @@ public class AlignViewport extends AlignmentViewport implements
}
- /**
- * get the consensus sequence as displayed under the PID consensus annotation
- * row.
- *
- * @return consensus sequence as a new sequence object
- */
- public SequenceI getConsensusSeq()
- {
- if (consensus == null)
- {
- updateConsensus(null);
- }
- if (consensus == null)
- {
- return null;
- }
- StringBuilder seqs = new StringBuilder(consensus.annotations.length);
- for (int i = 0; i < consensus.annotations.length; i++)
- {
- if (consensus.annotations[i] != null)
- {
- if (consensus.annotations[i].description.charAt(0) == '[')
- {
- seqs.append(consensus.annotations[i].description.charAt(1));
- }
- else
- {
- seqs.append(consensus.annotations[i].displayCharacter);
- }
- }
- }
- SequenceI sq = new Sequence("Consensus", seqs.toString());
- sq.setDescription("Percentage Identity Consensus "
- + ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
- return sq;
- }
-
java.awt.Frame nullFrame;
protected FeatureSettings featureSettings = null;
diff --git a/src/jalview/appletgui/AlignmentPanel.java b/src/jalview/appletgui/AlignmentPanel.java
index e402b9b..4147177 100644
--- a/src/jalview/appletgui/AlignmentPanel.java
+++ b/src/jalview/appletgui/AlignmentPanel.java
@@ -802,42 +802,45 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
sendViewPosition();
}
- private void adjustVertical(int offy)
+ private void adjustVertical(int newY)
{
- int oldX = vpRanges.getStartRes();
- int oldwidth = vpRanges.getViewportWidth();
- int oldY = vpRanges.getStartSeq();
- int oldheight = vpRanges.getViewportHeight();
-
if (av.getWrapAlignment())
{
- int rowSize = seqPanel.seqCanvas
- .getWrappedCanvasWidth(seqPanel.seqCanvas.getWidth());
-
- // 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 ((offy * rowSize == oldX) && (oldwidth == rowSize))
+ /*
+ * 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
+ */
+ int oldX = vpRanges.getStartRes();
+ int oldY = vpRanges.getWrappedScrollPosition(oldX);
+ if (oldY == newY)
{
return;
}
- else if (offy > -1)
+ if (newY > -1)
{
- vpRanges.setViewportStartAndWidth(offy * rowSize, rowSize);
+ /*
+ * limit page up/down to one width's worth of positions
+ */
+ int rowSize = vpRanges.getViewportWidth();
+ int newX = newY > oldY ? oldX + rowSize : oldX - rowSize;
+ vpRanges.setViewportStartAndWidth(Math.max(0, newX), rowSize);
}
}
else
{
int height = seqPanel.seqCanvas.getHeight() / av.getCharHeight();
+ int oldY = vpRanges.getStartSeq();
+ int oldheight = vpRanges.getViewportHeight();
// 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 ((offy == oldY) && (height == oldheight))
+ if ((newY == oldY) && (height == oldheight))
{
return;
}
- vpRanges.setViewportStartAndHeight(offy, height);
+ vpRanges.setViewportStartAndHeight(newY, height);
}
if (av.getWrapAlignment() || !fastPaint)
{
@@ -982,35 +985,23 @@ public class AlignmentPanel extends Panel implements AdjustmentListener,
}
- /*
+ /**
* Set vertical scroll bar parameters for wrapped panel
- * @param res
- * the residue to scroll to
+ *
+ * @param topLeftColumn
+ * the column position at top left (0..)
*/
- private void setScrollingForWrappedPanel(int res)
+ private void setScrollingForWrappedPanel(int topLeftColumn)
{
- // get the width of the alignment in residues
- int maxwidth = av.getAlignment().getWidth();
- if (av.hasHiddenColumns())
- {
- maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
- }
+ int scrollPosition = vpRanges.getWrappedScrollPosition(topLeftColumn);
+ int maxScroll = vpRanges.getWrappedMaxScroll(topLeftColumn);
- // get the width of the canvas in residues
- int canvasWidth = seqPanel.seqCanvas
- .getWrappedCanvasWidth(seqPanel.seqCanvas.getSize().width);
- if (canvasWidth > 0)
- {
- // position we want to scroll to is number of canvasWidth's to get there
- int current = res / canvasWidth;
-
- // max scroll position: add one because extent is 1 and scrollbar value
- // can only be set to at most max - extent
- int max = maxwidth / canvasWidth + 1;
- vscroll.setUnitIncrement(1);
- vscroll.setValues(current, 1, 0, max);
- }
+ /*
+ * a scrollbar's value can be set to at most (maximum-extent)
+ * so we add extent (1) to the maxScroll value
+ */
+ vscroll.setUnitIncrement(1);
+ vscroll.setValues(scrollPosition, 1, 0, maxScroll + 1);
}
protected Panel sequenceHolderPanel = new Panel();
diff --git a/src/jalview/appletgui/AnnotationColumnChooser.java b/src/jalview/appletgui/AnnotationColumnChooser.java
index 22978c3..3a7188e 100644
--- a/src/jalview/appletgui/AnnotationColumnChooser.java
+++ b/src/jalview/appletgui/AnnotationColumnChooser.java
@@ -46,7 +46,7 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.TextEvent;
import java.awt.event.TextListener;
-import java.util.Iterator;
+import java.util.ArrayList;
import java.util.Vector;
//import javax.swing.JPanel;
@@ -142,7 +142,7 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
}
setOldHiddenColumns(av.getAlignment().getHiddenColumns());
adjusting = true;
- Vector list = new Vector();
+ Vector list = new Vector<>();
int index = 1;
for (int i = 0; i < anns.length; i++)
{
@@ -298,16 +298,16 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements
HiddenColumns oldHidden = av
.getAnnotationColumnSelectionState()
.getOldHiddenColumns();
- if (oldHidden != null && oldHidden.getHiddenRegions() != null
- && !oldHidden.getHiddenRegions().isEmpty())
+ if (oldHidden != null)
{
- for (Iterator itr = oldHidden.getHiddenRegions()
- .iterator(); itr.hasNext();)
+ ArrayList regions = oldHidden.getHiddenColumnsCopy();
+ for (int[] positions : regions)
{
- int positions[] = itr.next();
av.hideColumns(positions[0], positions[1]);
}
}
+ // TODO not clear why we need to hide all the columns (above) if we are
+ // going to copy the hidden columns over wholesale anyway
av.getAlignment().setHiddenColumns(oldHidden);
}
av.sendSelection();
diff --git a/src/jalview/appletgui/AnnotationLabels.java b/src/jalview/appletgui/AnnotationLabels.java
index 307301d..3f7e523 100755
--- a/src/jalview/appletgui/AnnotationLabels.java
+++ b/src/jalview/appletgui/AnnotationLabels.java
@@ -838,13 +838,9 @@ public class AnnotationLabels extends Panel implements ActionListener,
+ sq.getSequenceAsString() + "\n");
if (av.hasHiddenColumns())
{
- jalview.appletgui.AlignFrame.copiedHiddenColumns = new Vector();
- for (int[] region : av.getAlignment().getHiddenColumns()
- .getHiddenRegions())
- {
- jalview.appletgui.AlignFrame.copiedHiddenColumns
- .addElement(new int[] { region[0], region[1] });
- }
+ jalview.appletgui.AlignFrame.copiedHiddenColumns = new Vector<>(
+ av.getAlignment().getHiddenColumns()
+ .getHiddenColumnsCopy());
}
}
diff --git a/src/jalview/appletgui/AnnotationPanel.java b/src/jalview/appletgui/AnnotationPanel.java
index c658811..39b718d 100755
--- a/src/jalview/appletgui/AnnotationPanel.java
+++ b/src/jalview/appletgui/AnnotationPanel.java
@@ -30,6 +30,7 @@ import jalview.util.Comparison;
import jalview.util.MessageManager;
import jalview.util.Platform;
import jalview.viewmodel.ViewportListenerI;
+import jalview.viewmodel.ViewportRanges;
import java.awt.Color;
import java.awt.Dimension;
@@ -118,13 +119,15 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
// ap.annotationScroller.getVAdjustable().addAdjustmentListener( this );
renderer = new AnnotationRenderer();
+
+ av.getRanges().addPropertyChangeListener(this);
}
public AnnotationPanel(AlignViewport av)
{
this.av = av;
renderer = new AnnotationRenderer();
- av.getRanges().addPropertyChangeListener(this);
+
}
@Override
@@ -758,8 +761,12 @@ public class AnnotationPanel extends Panel implements AwtRenderPanelI,
public void propertyChange(PropertyChangeEvent evt)
{
// Respond to viewport range changes (e.g. alignment panel was scrolled)
- if (evt.getPropertyName().equals("startres")
- || evt.getPropertyName().equals("endres"))
+ // Both scrolling and resizing change viewport ranges: scrolling changes
+ // both start and end points, but resize only changes end values.
+ // Here we only want to fastpaint on a scroll, with resize using a normal
+ // paint, so scroll events are identified as changes to the horizontal or
+ // vertical start value.
+ if (evt.getPropertyName().equals(ViewportRanges.STARTRES))
{
fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
}
diff --git a/src/jalview/appletgui/FeatureColourChooser.java b/src/jalview/appletgui/FeatureColourChooser.java
index 0e85017..4075e8b 100644
--- a/src/jalview/appletgui/FeatureColourChooser.java
+++ b/src/jalview/appletgui/FeatureColourChooser.java
@@ -95,9 +95,11 @@ public class FeatureColourChooser extends Panel implements ActionListener,
float mm[] = fr.getMinMax().get(type)[0];
min = mm[0];
max = mm[1];
+ threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black);
oldcs = fr.getFeatureColours().get(type);
if (oldcs.isGraduatedColour())
{
+ threshline.value = oldcs.getThreshold();
cs = new FeatureColour((FeatureColour) oldcs, min, max);
}
else
@@ -384,14 +386,6 @@ public class FeatureColourChooser extends Panel implements ActionListener,
thresholdValue.setText("");
}
- else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD
- && threshline == null)
- {
- // todo visual indication of feature threshold
- threshline = new jalview.datamodel.GraphLine((max - min) / 2f,
- "Threshold", Color.black);
- }
-
if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
{
adjusting = true;
diff --git a/src/jalview/appletgui/FeatureRenderer.java b/src/jalview/appletgui/FeatureRenderer.java
index 435e78d..8721ff4 100644
--- a/src/jalview/appletgui/FeatureRenderer.java
+++ b/src/jalview/appletgui/FeatureRenderer.java
@@ -413,7 +413,8 @@ public class FeatureRenderer extends
if (!colourPanel.isGcol)
{
// update colour - otherwise its already done.
- setColour(sf.type, new FeatureColour(colourPanel.getBackground()));
+ setColour(enteredType,
+ new FeatureColour(colourPanel.getBackground()));
}
int newBegin = sf.begin;
int newEnd = sf.end;
@@ -431,14 +432,14 @@ public class FeatureRenderer extends
* (to ensure integrity of SequenceFeatures data store)
*/
sequences.get(0).deleteFeature(sf);
- SequenceFeature newSf = new SequenceFeature(sf, newBegin, newEnd,
- enteredGroup, sf.getScore());
+ SequenceFeature newSf = new SequenceFeature(sf, enteredType,
+ newBegin, newEnd, enteredGroup, sf.getScore());
newSf.setDescription(enteredDesc);
ffile.parseDescriptionHTML(newSf, false);
// amend features dialog only updates one sequence at a time
sequences.get(0).addSequenceFeature(newSf);
- boolean typeOrGroupChanged = (!featureType.equals(sf.type) || !featureGroup
- .equals(sf.featureGroup));
+ boolean typeOrGroupChanged = (!featureType.equals(newSf.getType()) || !featureGroup
+ .equals(newSf.getFeatureGroup()));
ffile.parseDescriptionHTML(sf, false);
if (typeOrGroupChanged)
diff --git a/src/jalview/appletgui/FeatureSettings.java b/src/jalview/appletgui/FeatureSettings.java
index b0bb372..46498ad 100755
--- a/src/jalview/appletgui/FeatureSettings.java
+++ b/src/jalview/appletgui/FeatureSettings.java
@@ -386,11 +386,13 @@ public class FeatureSettings extends Panel implements ItemListener,
Set visibleGroups = new HashSet();
for (String group : groups)
{
- if (group == null || fr.checkGroupVisibility(group, true))
+ // if (group == null || fr.checkGroupVisibility(group, true))
+ if (group == null || checkGroupState(group))
{
visibleGroups.add(group);
}
}
+ foundGroups.addAll(groups);
/*
* get distinct feature types for visible groups
diff --git a/src/jalview/appletgui/IdCanvas.java b/src/jalview/appletgui/IdCanvas.java
index 74bbcf5..48c0c40 100755
--- a/src/jalview/appletgui/IdCanvas.java
+++ b/src/jalview/appletgui/IdCanvas.java
@@ -101,7 +101,7 @@ public class IdCanvas extends Panel implements ViewportListenerI
public void fastPaint(int vertical)
{
- if (gg == null)
+ if (gg == null || av.getWrapAlignment())
{
repaint();
return;
@@ -199,130 +199,148 @@ public class IdCanvas extends Panel implements ViewportListenerI
void drawIds(int starty, int endy)
{
- // hardwired italic IDs in applet currently
- Font italic = new Font(av.getFont().getName(), Font.ITALIC, av
- .getFont().getSize());
- // temp variable for speed
avcharHeight = av.getCharHeight();
- gg.setFont(italic);
-
Color currentColor = Color.white;
Color currentTextColor = Color.black;
final boolean doHiddenCheck = av.isDisplayReferenceSeq()
- || av.hasHiddenRows(), hiddenRows = av.hasHiddenRows()
- && av.getShowHiddenMarkers();
+ || av.hasHiddenRows();
+ boolean hiddenRows = av.hasHiddenRows() && av.getShowHiddenMarkers();
if (av.getWrapAlignment())
{
- int maxwidth = av.getAlignment().getWidth();
- int alheight = av.getAlignment().getHeight();
+ drawIdsWrapped(starty, doHiddenCheck, hiddenRows);
+ return;
+ }
- if (av.hasHiddenColumns())
+ // Now draw the id strings
+ SequenceI seq;
+ for (int i = starty; i <= endy; i++)
+ {
+ seq = av.getAlignment().getSequenceAt(i);
+ if (seq == null)
{
- maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
+ continue;
+ }
+ // hardwired italic IDs in applet currently
+ Font italic = new Font(av.getFont().getName(), Font.ITALIC, av
+ .getFont().getSize());
+ gg.setFont(italic);
+ // boolean isrep=false;
+ if (doHiddenCheck)
+ {
+ // isrep =
+ setHiddenFont(seq);
}
- int annotationHeight = 0;
- AnnotationLabels labels = null;
-
- if (av.isShowAnnotation())
+ // Selected sequence colours
+ if ((searchResults != null) && searchResults.contains(seq))
{
- AnnotationPanel ap = new AnnotationPanel(av);
- annotationHeight = ap.adjustPanelHeight();
- labels = new AnnotationLabels(av);
+ currentColor = Color.black;
+ currentTextColor = Color.white;
}
- int hgap = avcharHeight;
- if (av.getScaleAboveWrapped())
+ else if ((av.getSelectionGroup() != null)
+ && av.getSelectionGroup().getSequences(null).contains(seq))
+ {
+ currentColor = Color.lightGray;
+ currentTextColor = Color.black;
+ }
+ else
{
- hgap += avcharHeight;
+ currentColor = av.getSequenceColour(seq);
+ currentTextColor = Color.black;
}
- int cHeight = alheight * avcharHeight + hgap + annotationHeight;
+ gg.setColor(currentColor);
+ // TODO: isrep could be used to highlight the representative in a
+ // different way
+ gg.fillRect(0, (i - starty) * avcharHeight, getSize().width,
+ avcharHeight);
+ gg.setColor(currentTextColor);
- int rowSize = av.getRanges().getEndRes()
- - av.getRanges().getStartRes();
- // Draw the rest of the panels
- for (int ypos = hgap, row = av.getRanges().getStartRes(); (ypos <= getSize().height)
- && (row < maxwidth); ypos += cHeight, row += rowSize)
+ gg.drawString(seq.getDisplayId(av.getShowJVSuffix()), 0,
+ (((i - starty) * avcharHeight) + avcharHeight)
+ - (avcharHeight / 5));
+
+ if (hiddenRows)
{
- for (int i = starty; i < alheight; i++)
- {
+ drawMarker(i, starty, 0);
+ }
+ }
+ }
- SequenceI s = av.getAlignment().getSequenceAt(i);
- gg.setFont(italic);
- if (doHiddenCheck)
- {
- setHiddenFont(s);
- }
- drawIdString(gg, hiddenRows, s, i, 0, ypos);
- }
+ /**
+ * Draws sequence ids in wrapped mode
+ *
+ * @param starty
+ * @param doHiddenCheck
+ * @param hiddenRows
+ */
+ protected void drawIdsWrapped(int starty, final boolean doHiddenCheck,
+ boolean hiddenRows)
+ {
+ int maxwidth = av.getAlignment().getWidth();
+ int alheight = av.getAlignment().getHeight();
- if (labels != null)
- {
- gg.translate(0, ypos + (alheight * avcharHeight));
- labels.drawComponent(gg, getSize().width);
- gg.translate(0, -ypos - (alheight * avcharHeight));
- }
+ if (av.hasHiddenColumns())
+ {
+ maxwidth = av.getAlignment().getHiddenColumns()
+ .findColumnPosition(maxwidth) - 1;
+ }
- }
+ int annotationHeight = 0;
+ AnnotationLabels labels = null;
+
+ if (av.isShowAnnotation())
+ {
+ AnnotationPanel ap = new AnnotationPanel(av);
+ annotationHeight = ap.adjustPanelHeight();
+ labels = new AnnotationLabels(av);
}
- else
+ int hgap = avcharHeight;
+ if (av.getScaleAboveWrapped())
{
- // Now draw the id strings
- SequenceI seq;
- for (int i = starty; i <= endy; i++)
- {
+ hgap += avcharHeight;
+ }
- seq = av.getAlignment().getSequenceAt(i);
- if (seq == null)
- {
- continue;
- }
- gg.setFont(italic);
- // boolean isrep=false;
- if (doHiddenCheck)
- {
- // isrep =
- setHiddenFont(seq);
- }
+ int cHeight = alheight * avcharHeight + hgap + annotationHeight;
- // Selected sequence colours
- if ((searchResults != null) && searchResults.contains(seq))
- {
- currentColor = Color.black;
- currentTextColor = Color.white;
- }
- else if ((av.getSelectionGroup() != null)
- && av.getSelectionGroup().getSequences(null).contains(seq))
- {
- currentColor = Color.lightGray;
- currentTextColor = Color.black;
- }
- else
- {
- currentColor = av.getSequenceColour(seq);
- currentTextColor = Color.black;
- }
+ int rowSize = av.getRanges().getViewportWidth();
- gg.setColor(currentColor);
- // TODO: isrep could be used to highlight the representative in a
- // different way
- gg.fillRect(0, (i - starty) * avcharHeight, getSize().width,
- avcharHeight);
- gg.setColor(currentTextColor);
+ // hardwired italic IDs in applet currently
+ Font italic = new Font(av.getFont().getName(), Font.ITALIC, av
+ .getFont().getSize());
+ gg.setFont(italic);
- gg.drawString(seq.getDisplayId(av.getShowJVSuffix()), 0,
- (((i - starty) * avcharHeight) + avcharHeight)
- - (avcharHeight / 5));
+ /*
+ * draw repeating sequence ids until out of sequence data or
+ * out of visible space, whichever comes first
+ */
+ int ypos = hgap;
+ int row = av.getRanges().getStartRes();
+ while ((ypos <= getHeight()) && (row < maxwidth))
+ {
+ for (int i = starty; i < alheight; i++)
+ {
- if (hiddenRows)
+ SequenceI s = av.getAlignment().getSequenceAt(i);
+ // gg.setFont(italic);
+ if (doHiddenCheck)
{
- drawMarker(i, starty, 0);
+ setHiddenFont(s);
}
+ drawIdString(gg, hiddenRows, s, i, 0, ypos);
}
+
+ if (labels != null)
+ {
+ gg.translate(0, ypos + (alheight * avcharHeight));
+ labels.drawComponent(gg, getSize().width);
+ gg.translate(0, -ypos - (alheight * avcharHeight));
+ }
+ ypos += cHeight;
+ row += rowSize;
}
}
@@ -398,12 +416,25 @@ public class IdCanvas extends Panel implements ViewportListenerI
return false;
}
+ /**
+ * Respond to viewport range changes (e.g. alignment panel was scrolled). Both
+ * scrolling and resizing change viewport ranges. Scrolling changes both start
+ * and end points, but resize only changes end values. Here we only want to
+ * fastpaint on a scroll, with resize using a normal paint, so scroll events
+ * are identified as changes to the horizontal or vertical start value.
+ *
+ * In unwrapped mode, only responds to a vertical scroll, as horizontal scroll
+ * leaves sequence ids unchanged. In wrapped mode, only vertical scroll is
+ * provided, but it generates a change of "startres" which does require an
+ * update here.
+ */
@Override
public void propertyChange(PropertyChangeEvent evt)
{
- // Respond to viewport range changes (e.g. alignment panel was scrolled)
- if (evt.getPropertyName().equals("startseq")
- || evt.getPropertyName().equals("endseq"))
+ String propertyName = evt.getPropertyName();
+ if (propertyName.equals(ViewportRanges.STARTSEQ)
+ || (av.getWrapAlignment() && propertyName
+ .equals(ViewportRanges.STARTRES)))
{
fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
}
diff --git a/src/jalview/appletgui/OverviewCanvas.java b/src/jalview/appletgui/OverviewCanvas.java
index 23e82df..a0466d3 100644
--- a/src/jalview/appletgui/OverviewCanvas.java
+++ b/src/jalview/appletgui/OverviewCanvas.java
@@ -40,6 +40,8 @@ public class OverviewCanvas extends Component
private OverviewDimensions od;
+ private OverviewRenderer or = null;
+
private Image miniMe;
private Image offscreen;
@@ -92,6 +94,10 @@ public class OverviewCanvas extends Component
if (updaterunning)
{
restart = true;
+ if (or != null)
+ {
+ or.setRedraw(true);
+ }
}
else
{
@@ -113,7 +119,7 @@ public class OverviewCanvas extends Component
setPreferredSize(new Dimension(od.getWidth(), od.getHeight()));
- OverviewRenderer or = new OverviewRenderer(sr, fr, od);
+ or = new OverviewRenderer(sr, fr, od);
miniMe = nullFrame.createImage(od.getWidth(), od.getHeight());
offscreen = nullFrame.createImage(od.getWidth(), od.getHeight());
diff --git a/src/jalview/appletgui/OverviewPanel.java b/src/jalview/appletgui/OverviewPanel.java
index b3c4a37..ccdfee1 100755
--- a/src/jalview/appletgui/OverviewPanel.java
+++ b/src/jalview/appletgui/OverviewPanel.java
@@ -160,6 +160,14 @@ public class OverviewPanel extends Panel implements Runnable,
*/
public void updateOverviewImage()
{
+ if (oviewCanvas == null)
+ {
+ /*
+ * panel has been disposed
+ */
+ return;
+ }
+
if ((getSize().width > 0) && (getSize().height > 0))
{
od.setWidth(getSize().width);
@@ -257,4 +265,21 @@ public class OverviewPanel extends Panel implements Runnable,
oviewCanvas.resetOviewDims(od);
updateOverviewImage();
}
+
+ /**
+ * Removes this object as a property change listener, and nulls references
+ */
+ protected void dispose()
+ {
+ try
+ {
+ av.getRanges().removePropertyChangeListener(this);
+ } finally
+ {
+ av = null;
+ oviewCanvas = null;
+ ap = null;
+ od = null;
+ }
+ }
}
diff --git a/src/jalview/appletgui/ScalePanel.java b/src/jalview/appletgui/ScalePanel.java
index ec3e246..5e0a2fd 100755
--- a/src/jalview/appletgui/ScalePanel.java
+++ b/src/jalview/appletgui/ScalePanel.java
@@ -27,6 +27,7 @@ import jalview.renderer.ScaleRenderer;
import jalview.renderer.ScaleRenderer.ScaleMark;
import jalview.util.MessageManager;
import jalview.viewmodel.ViewportListenerI;
+import jalview.viewmodel.ViewportRanges;
import java.awt.Color;
import java.awt.FontMetrics;
@@ -139,7 +140,7 @@ public class ScalePanel extends Panel implements MouseMotionListener,
sg.setStartRes(min);
sg.setEndRes(max);
}
- ap.paintAlignment(true);
+ ap.paintAlignment(false);
av.sendSelection();
}
@@ -165,10 +166,6 @@ public class ScalePanel extends Panel implements MouseMotionListener,
av.showColumn(reveal[0]);
reveal = null;
ap.paintAlignment(true);
- if (ap.overviewPanel != null)
- {
- ap.overviewPanel.updateOverviewImage();
- }
av.sendSelection();
}
});
@@ -185,10 +182,6 @@ public class ScalePanel extends Panel implements MouseMotionListener,
av.showAllHiddenColumns();
reveal = null;
ap.paintAlignment(true);
- if (ap.overviewPanel != null)
- {
- ap.overviewPanel.updateOverviewImage();
- }
av.sendSelection();
}
});
@@ -215,10 +208,6 @@ public class ScalePanel extends Panel implements MouseMotionListener,
}
ap.paintAlignment(true);
- if (ap.overviewPanel != null)
- {
- ap.overviewPanel.updateOverviewImage();
- }
av.sendSelection();
}
});
@@ -334,18 +323,8 @@ public class ScalePanel extends Panel implements MouseMotionListener,
int res = (evt.getX() / av.getCharWidth())
+ av.getRanges().getStartRes();
- res = av.getAlignment().getHiddenColumns().adjustForHiddenColumns(res);
-
- reveal = null;
- for (int[] region : av.getAlignment().getHiddenColumns()
- .getHiddenRegions())
- {
- if (res + 1 == region[0] || res - 1 == region[1])
- {
- reveal = region;
- break;
- }
- }
+ reveal = av.getAlignment().getHiddenColumns()
+ .getRegionWithEdgeAtRes(res);
repaint();
}
@@ -359,9 +338,15 @@ public class ScalePanel extends Panel implements MouseMotionListener,
@Override
public void paint(Graphics g)
{
- drawScale(g, av.getRanges().getStartRes(), av.getRanges().getEndRes(),
- getSize().width,
- getSize().height);
+ /*
+ * shouldn't get called in wrapped mode as the scale above is
+ * drawn instead by SeqCanvas.drawNorthScale
+ */
+ if (!av.getWrapAlignment())
+ {
+ drawScale(g, av.getRanges().getStartRes(),
+ av.getRanges().getEndRes(), getSize().width, getSize().height);
+ }
}
// scalewidth will normally be screenwidth,
@@ -450,10 +435,11 @@ public class ScalePanel extends Panel implements MouseMotionListener,
if (av.getShowHiddenMarkers())
{
int widthx = 1 + endx - startx;
- for (int i = 0; i < hidden.getHiddenRegions().size(); i++)
+ List positions = hidden.findHiddenRegionPositions();
+ for (int pos : positions)
{
- res = hidden.findHiddenRegionPosition(i) - startx;
+ res = pos - startx;
if (res < 0 || res > widthx)
{
@@ -473,7 +459,16 @@ public class ScalePanel extends Panel implements MouseMotionListener,
public void propertyChange(PropertyChangeEvent evt)
{
// Respond to viewport change events (e.g. alignment panel was scrolled)
- repaint();
+ // Both scrolling and resizing change viewport ranges: scrolling changes
+ // both start and end points, but resize only changes end values.
+ // Here we only want to fastpaint on a scroll, with resize using a normal
+ // paint, so scroll events are identified as changes to the horizontal or
+ // vertical start value.
+ if (evt.getPropertyName().equals(ViewportRanges.STARTRES))
+ {
+ // scroll event, repaint panel
+ repaint();
+ }
}
}
diff --git a/src/jalview/appletgui/SeqCanvas.java b/src/jalview/appletgui/SeqCanvas.java
index 538f1d2..fe7abbb 100755
--- a/src/jalview/appletgui/SeqCanvas.java
+++ b/src/jalview/appletgui/SeqCanvas.java
@@ -37,6 +37,7 @@ import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
import java.beans.PropertyChangeEvent;
+import java.util.List;
public class SeqCanvas extends Panel implements ViewportListenerI
{
@@ -419,6 +420,9 @@ public class SeqCanvas extends Panel implements ViewportListenerI
FontMetrics fm = getFontMetrics(av.getFont());
+ LABEL_EAST = 0;
+ LABEL_WEST = 0;
+
if (av.getScaleRightWrapped())
{
LABEL_EAST = fm.stringWidth(getMask());
@@ -440,17 +444,17 @@ public class SeqCanvas extends Panel implements ViewportListenerI
av.setWrappedWidth(cWidth);
- av.getRanges().setEndRes(av.getRanges().getStartRes() + cWidth - 1);
+ av.getRanges().setViewportStartAndWidth(startRes, cWidth);
int endx;
int ypos = hgap;
- int maxwidth = av.getAlignment().getWidth() - 1;
+ int maxwidth = av.getAlignment().getWidth();
if (av.hasHiddenColumns())
{
maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
+ .findColumnPosition(maxwidth);
}
while ((ypos <= canvasHeight) && (startRes < maxwidth))
@@ -487,11 +491,10 @@ public class SeqCanvas extends Panel implements ViewportListenerI
HiddenColumns hidden = av.getAlignment().getHiddenColumns();
g.setColor(Color.blue);
int res;
- for (int i = 0; i < hidden.getHiddenRegions()
- .size(); i++)
+ List positions = hidden.findHiddenRegionPositions();
+ for (int pos : positions)
{
- res = hidden.findHiddenRegionPosition(i)
- - startRes;
+ res = pos - startRes;
if (res < 0 || res > endx - startRes)
{
@@ -570,7 +573,7 @@ public class SeqCanvas extends Panel implements ViewportListenerI
if (av.hasHiddenColumns())
{
HiddenColumns hidden = av.getAlignment().getHiddenColumns();
- for (int[] region : hidden.getHiddenRegions())
+ for (int[] region : hidden.getHiddenColumnsCopy())
{
int hideStart = region[0];
int hideEnd = region[1];
@@ -882,32 +885,44 @@ public class SeqCanvas extends Panel implements ViewportListenerI
@Override
public void propertyChange(PropertyChangeEvent evt)
{
+ String eventName = evt.getPropertyName();
+
if (!av.getWrapAlignment())
{
- if (evt.getPropertyName().equals("startres")
- || evt.getPropertyName().equals("endres"))
+ int scrollX = 0;
+ if (eventName.equals(ViewportRanges.STARTRES))
{
// Make sure we're not trying to draw a panel
// larger than the visible window
ViewportRanges vpRanges = av.getRanges();
- int scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
- if (scrollX > vpRanges.getEndRes() - vpRanges.getStartRes())
+ scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+ int range = vpRanges.getEndRes() - vpRanges.getStartRes();
+ if (scrollX > range)
{
- scrollX = vpRanges.getEndRes() - vpRanges.getStartRes();
+ scrollX = range;
}
- else if (scrollX < vpRanges.getStartRes() - vpRanges.getEndRes())
+ else if (scrollX < -range)
{
- scrollX = vpRanges.getStartRes() - vpRanges.getEndRes();
+ scrollX = -range;
}
+ }
+
+ // Both scrolling and resizing change viewport ranges: scrolling changes
+ // both start and end points, but resize only changes end values.
+ // Here we only want to fastpaint on a scroll, with resize using a normal
+ // paint, so scroll events are identified as changes to the horizontal or
+ // vertical start value.
+ if (eventName.equals(ViewportRanges.STARTRES))
+ {
+ // scroll - startres and endres both change
fastPaint(scrollX, 0);
}
- else if (evt.getPropertyName().equals("startseq")
- || evt.getPropertyName().equals("endseq"))
+ else if (eventName.equals(ViewportRanges.STARTSEQ))
{
+ // scroll
fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
}
}
-
}
}
diff --git a/src/jalview/appletgui/SeqPanel.java b/src/jalview/appletgui/SeqPanel.java
index 9e31efe..42e4d8e 100644
--- a/src/jalview/appletgui/SeqPanel.java
+++ b/src/jalview/appletgui/SeqPanel.java
@@ -577,7 +577,8 @@ public class SeqPanel extends Panel implements MouseMotionListener,
seqCanvas.highlightSearchResults(highlight);
seqCanvas.getFeatureRenderer().amendFeatures(
Collections.singletonList(sequence), features, false, ap);
- seqCanvas.highlightSearchResults(null);
+ av.setSearchResults(null); // clear highlighting
+ seqCanvas.repaint(); // draw new/amended features
}
}
}
@@ -615,6 +616,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
int res = 0;
int x = evt.getX();
+ int startRes = av.getRanges().getStartRes();
if (av.getWrapAlignment())
{
@@ -629,7 +631,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
int y = evt.getY();
y -= hgap;
- x -= seqCanvas.LABEL_WEST;
+ x = Math.max(0, x - seqCanvas.LABEL_WEST);
int cwidth = seqCanvas.getWrappedCanvasWidth(getSize().width);
if (cwidth < 1)
@@ -638,14 +640,15 @@ public class SeqPanel extends Panel implements MouseMotionListener,
}
wrappedBlock = y / cHeight;
- wrappedBlock += av.getRanges().getStartRes() / cwidth;
-
- res = wrappedBlock * cwidth + x / av.getCharWidth();
-
+ wrappedBlock += startRes / cwidth;
+ int startOffset = startRes % cwidth; // in case start is scrolled right
+ // from 0
+ res = wrappedBlock * cwidth
+ + Math.min(cwidth - 1, startOffset + x / av.getCharWidth());
}
else
{
- res = (x / av.getCharWidth()) + av.getRanges().getStartRes();
+ res = (x / av.getCharWidth()) + startRes;
}
if (av.hasHiddenColumns())
@@ -1175,7 +1178,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
// Find the next gap before the end
// of the visible region boundary
boolean blank = false;
- for (fixedRight = fixedRight; fixedRight > lastres; fixedRight--)
+ for (; fixedRight > lastres; fixedRight--)
{
blank = true;
@@ -1871,8 +1874,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
}
if (copycolsel
&& av.hasHiddenColumns()
- && (av.getColumnSelection() == null || av.getAlignment()
- .getHiddenColumns().getHiddenRegions() == null))
+ && (av.getColumnSelection() == null))
{
System.err.println("Bad things");
}
diff --git a/src/jalview/appletgui/SliderPanel.java b/src/jalview/appletgui/SliderPanel.java
index 9154aa0..47a0669 100644
--- a/src/jalview/appletgui/SliderPanel.java
+++ b/src/jalview/appletgui/SliderPanel.java
@@ -20,6 +20,7 @@
*/
package jalview.appletgui;
+import jalview.analysis.Conservation;
import jalview.datamodel.SequenceGroup;
import jalview.renderer.ResidueShaderI;
import jalview.util.MessageManager;
@@ -44,7 +45,7 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
-import java.util.Iterator;
+import java.util.List;
public class SliderPanel extends Panel implements ActionListener,
AdjustmentListener, MouseListener
@@ -82,7 +83,8 @@ public class SliderPanel extends Panel implements ActionListener,
conservationSlider.setTitle(MessageManager.formatMessage(
"label.conservation_colour_increment",
new String[] { source == null ? BACKGROUND : source }));
- if (ap.av.getAlignment().getGroups() != null)
+ List groups = ap.av.getAlignment().getGroups();
+ if (groups != null && !groups.isEmpty())
{
sp.setAllGroupsCheckEnabled(true);
}
@@ -248,45 +250,53 @@ public class SliderPanel extends Panel implements ActionListener,
{
return;
}
-
- ResidueShaderI toChange = cs;
- Iterator allGroups = null;
-
- if (allGroupsCheck.getState())
+ if (forConservation)
{
- allGroups = ap.av.getAlignment().getGroups().listIterator();
+ cs.setConservationApplied(true);
+ cs.setConservationInc(i);
+ }
+ else
+ {
+ cs.setThreshold(i, ap.av.isIgnoreGapsConsensus());
}
- while (toChange != null)
+ if (allGroupsCheck.getState())
{
- if (forConservation)
+ for (SequenceGroup group : ap.av.getAlignment().getGroups())
{
- toChange.setConservationInc(i);
- }
- else
- {
- toChange.setThreshold(i, ap.av.isIgnoreGapsConsensus());
- }
- if (allGroups != null && allGroups.hasNext())
- {
- while ((toChange = allGroups.next().cs) == null
- && allGroups.hasNext())
+ ResidueShaderI groupColourScheme = group.getGroupColourScheme();
+ if (forConservation)
{
- ;
+ if (!groupColourScheme.conservationApplied())
+ {
+ /*
+ * first time the colour scheme has had Conservation shading applied
+ * - compute conservation
+ */
+ Conservation c = new Conservation("Group",
+ group.getSequences(null), group.getStartRes(),
+ group.getEndRes());
+ c.calculate();
+ c.verdict(false, ap.av.getConsPercGaps());
+ group.cs.setConservation(c);
+
+ }
+ groupColourScheme.setConservationApplied(true);
+ groupColourScheme.setConservationInc(i);
+ }
+ else
+ {
+ groupColourScheme.setThreshold(i, ap.av.isIgnoreGapsConsensus());
}
- }
- else
- {
- toChange = null;
}
}
ap.seqPanel.seqCanvas.repaint();
-
}
public void setAllGroupsCheckEnabled(boolean b)
{
+ allGroupsCheck.setState(ap.av.getColourAppliesToAllGroups());
allGroupsCheck.setEnabled(b);
}
diff --git a/src/jalview/datamodel/Alignment.java b/src/jalview/datamodel/Alignment.java
index 5553840..26e8db1 100755
--- a/src/jalview/datamodel/Alignment.java
+++ b/src/jalview/datamodel/Alignment.java
@@ -1909,42 +1909,6 @@ public class Alignment implements AlignmentI
}
@Override
- public int[] getVisibleStartAndEndIndex(List hiddenCols)
- {
- int[] alignmentStartEnd = new int[] { 0, getWidth() - 1 };
- int startPos = alignmentStartEnd[0];
- int endPos = alignmentStartEnd[1];
-
- int[] lowestRange = new int[] { -1, -1 };
- int[] higestRange = new int[] { -1, -1 };
-
- for (int[] hiddenCol : hiddenCols)
- {
- lowestRange = (hiddenCol[0] <= startPos) ? hiddenCol : lowestRange;
- higestRange = (hiddenCol[1] >= endPos) ? hiddenCol : higestRange;
- }
-
- if (lowestRange[0] == -1 && lowestRange[1] == -1)
- {
- startPos = alignmentStartEnd[0];
- }
- else
- {
- startPos = lowestRange[1] + 1;
- }
-
- if (higestRange[0] == -1 && higestRange[1] == -1)
- {
- endPos = alignmentStartEnd[1];
- }
- else
- {
- endPos = higestRange[0] - 1;
- }
- return new int[] { startPos, endPos };
- }
-
- @Override
public void setHiddenColumns(HiddenColumns cols)
{
hiddenCols = cols;
diff --git a/src/jalview/datamodel/AlignmentI.java b/src/jalview/datamodel/AlignmentI.java
index 2e61f9d..1b5207f 100755
--- a/src/jalview/datamodel/AlignmentI.java
+++ b/src/jalview/datamodel/AlignmentI.java
@@ -580,15 +580,6 @@ public interface AlignmentI extends AnnotatedCollectionI
*/
AlignedCodonFrame getMapping(SequenceI mapFrom, SequenceI mapTo);
- /**
- * Calculate the visible start and end index of an alignment. The result is
- * returned an int array where: int[0] = startIndex, and int[1] = endIndex.
- *
- * @param hiddenCols
- * @return
- */
- public int[] getVisibleStartAndEndIndex(List hiddenCols);
-
public void setHiddenColumns(HiddenColumns cols);
}
diff --git a/src/jalview/datamodel/BinarySequence.java b/src/jalview/datamodel/BinarySequence.java
index 5789b2b..477f4a7 100755
--- a/src/jalview/datamodel/BinarySequence.java
+++ b/src/jalview/datamodel/BinarySequence.java
@@ -69,6 +69,7 @@ public class BinarySequence extends Sequence
{
int nores = (isNa) ? ResidueProperties.maxNucleotideIndex
: ResidueProperties.maxProteinIndex;
+
dbinary = new double[getLength() * nores];
return nores;
@@ -131,7 +132,7 @@ public class BinarySequence extends Sequence
{
int nores = initMatrixGetNoRes();
- for (int i = 0, iSize = getSequence().length; i < iSize; i++)
+ for (int i = 0, iSize = getLength(); i < iSize; i++)
{
int aanum = nores - 1;
diff --git a/src/jalview/datamodel/CigarArray.java b/src/jalview/datamodel/CigarArray.java
index 837a10b..febf6b4 100644
--- a/src/jalview/datamodel/CigarArray.java
+++ b/src/jalview/datamodel/CigarArray.java
@@ -90,7 +90,7 @@ public class CigarArray extends CigarBase
{
this(constructSeqCigarArray(alignment, selectionGroup));
constructFromAlignment(alignment,
- hidden != null ? hidden.getHiddenRegions()
+ hidden != null ? hidden.getHiddenColumnsCopy()
: null, selectionGroup);
}
diff --git a/src/jalview/datamodel/ColumnSelection.java b/src/jalview/datamodel/ColumnSelection.java
index eb2d174..4cdd7af 100644
--- a/src/jalview/datamodel/ColumnSelection.java
+++ b/src/jalview/datamodel/ColumnSelection.java
@@ -482,7 +482,7 @@ public class ColumnSelection
*/
public void invertColumnSelection(int first, int width, AlignmentI al)
{
- boolean hasHidden = al.getHiddenColumns().hasHidden();
+ boolean hasHidden = al.getHiddenColumns().hasHiddenColumns();
for (int i = first; i < width; i++)
{
if (contains(i))
@@ -511,7 +511,7 @@ public class ColumnSelection
selection = new IntList();
if (colsel.selection != null && colsel.selection.size() > 0)
{
- if (hiddenColumns.hasHidden())
+ if (hiddenColumns.hasHiddenColumns())
{
// only select visible columns in this columns selection
for (Integer col : colsel.getSelected())
diff --git a/src/jalview/datamodel/HiddenColumns.java b/src/jalview/datamodel/HiddenColumns.java
index f0d99e5..169b0a4 100644
--- a/src/jalview/datamodel/HiddenColumns.java
+++ b/src/jalview/datamodel/HiddenColumns.java
@@ -1,3 +1,23 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see .
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
package jalview.datamodel;
import jalview.util.Comparison;
@@ -8,85 +28,159 @@ import java.util.BitSet;
import java.util.Collections;
import java.util.List;
import java.util.Vector;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
public class HiddenColumns
{
+ private static final ReentrantReadWriteLock LOCK = new ReentrantReadWriteLock();
+
/*
* list of hidden column [start, end] ranges; the list is maintained in
* ascending start column order
*/
- private Vector hiddenColumns;
+ private ArrayList hiddenColumns;
/**
- * This Method is used to return all the HiddenColumn regions
- *
- * @return empty list or List of hidden column intervals
+ * Constructor
*/
- public List getHiddenRegions()
+ public HiddenColumns()
{
- return hiddenColumns == null ? Collections. emptyList()
- : hiddenColumns;
}
/**
- * Find the number of hidden columns
+ * Copy constructor
*
- * @return number of hidden columns
+ * @param copy
*/
- public int getSize()
+ public HiddenColumns(HiddenColumns copy)
{
- int size = 0;
- if (hasHidden())
+ try
{
- for (int[] range : hiddenColumns)
+ LOCK.writeLock().lock();
+ if (copy != null)
{
- size += range[1] - range[0] + 1;
+ if (copy.hiddenColumns != null)
+ {
+ hiddenColumns = copy.copyHiddenRegionsToArrayList();
+ }
}
+ } finally
+ {
+ LOCK.writeLock().unlock();
}
- return size;
}
/**
- * Answers if there are any hidden columns
+ * This method is used to return all the HiddenColumn regions and is intended
+ * to remain private. External callers which need a copy of the regions can
+ * call getHiddenColumnsCopyAsList.
*
- * @return true if there are hidden columns
+ * @return empty list or List of hidden column intervals
*/
- public boolean hasHidden()
+ private List getHiddenRegions()
{
- return (hiddenColumns != null) && (!hiddenColumns.isEmpty());
+ return hiddenColumns == null ? Collections. emptyList()
+ : hiddenColumns;
}
- @Override
- public boolean equals(Object obj)
+ /**
+ * Output regions data as a string. String is in the format:
+ * reg0[0]reg0[1]reg1[0]reg1[1] ... regn[1]
+ *
+ * @param delimiter
+ * string to delimit regions
+ * @param betweenstring
+ * to put between start and end region values
+ * @return regions formatted according to delimiter and between strings
+ */
+ public String regionsToString(String delimiter, String between)
{
- if (!(obj instanceof HiddenColumns))
+ try
+ {
+ LOCK.readLock().lock();
+ StringBuilder regionBuilder = new StringBuilder();
+ if (hiddenColumns != null)
+ {
+ for (int[] range : hiddenColumns)
+ {
+ regionBuilder.append(delimiter).append(range[0]).append(between)
+ .append(range[1]);
+ }
+
+ regionBuilder.deleteCharAt(0);
+ }
+ return regionBuilder.toString();
+ } finally
{
- return false;
+ LOCK.readLock().unlock();
}
- HiddenColumns that = (HiddenColumns) obj;
+ }
- /*
- * check hidden columns are either both null, or match
- */
- if (this.hiddenColumns == null)
+ /**
+ * Find the number of hidden columns
+ *
+ * @return number of hidden columns
+ */
+ public int getSize()
+ {
+ try
{
- return (that.hiddenColumns == null);
+ LOCK.readLock().lock();
+ int size = 0;
+ if (hasHiddenColumns())
+ {
+ for (int[] range : hiddenColumns)
+ {
+ size += range[1] - range[0] + 1;
+ }
+ }
+ return size;
}
- if (that.hiddenColumns == null
- || that.hiddenColumns.size() != this.hiddenColumns.size())
+ finally
{
- return false;
+ LOCK.readLock().unlock();
}
- int i = 0;
- for (int[] thisRange : hiddenColumns)
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ try
{
- int[] thatRange = that.hiddenColumns.get(i++);
- if (thisRange[0] != thatRange[0] || thisRange[1] != thatRange[1])
+ LOCK.readLock().lock();
+
+ if (!(obj instanceof HiddenColumns))
+ {
+ return false;
+ }
+ HiddenColumns that = (HiddenColumns) obj;
+
+ /*
+ * check hidden columns are either both null, or match
+ */
+ if (this.hiddenColumns == null)
+ {
+ return (that.hiddenColumns == null);
+ }
+ if (that.hiddenColumns == null
+ || that.hiddenColumns.size() != this.hiddenColumns.size())
{
return false;
}
+ int i = 0;
+ for (int[] thisRange : hiddenColumns)
+ {
+ int[] thatRange = that.hiddenColumns.get(i++);
+ if (thisRange[0] != thatRange[0] || thisRange[1] != thatRange[1])
+ {
+ return false;
+ }
+ }
+ return true;
+ } finally
+ {
+ LOCK.readLock().unlock();
}
- return true;
}
/**
@@ -98,19 +192,26 @@ public class HiddenColumns
*/
public int adjustForHiddenColumns(int column)
{
- int result = column;
- if (hiddenColumns != null)
+ try
{
- for (int i = 0; i < hiddenColumns.size(); i++)
+ LOCK.readLock().lock();
+ int result = column;
+ if (hiddenColumns != null)
{
- int[] region = hiddenColumns.elementAt(i);
- if (result >= region[0])
+ for (int i = 0; i < hiddenColumns.size(); i++)
{
- result += region[1] - region[0] + 1;
+ int[] region = hiddenColumns.get(i);
+ if (result >= region[0])
+ {
+ result += region[1] - region[0] + 1;
+ }
}
}
+ return result;
+ } finally
+ {
+ LOCK.readLock().unlock();
}
- return result;
}
/**
@@ -124,42 +225,52 @@ public class HiddenColumns
*/
public int findColumnPosition(int hiddenColumn)
{
- int result = hiddenColumn;
- if (hiddenColumns != null)
+ try
{
- int index = 0;
- int[] region;
- do
+ LOCK.readLock().lock();
+ int result = hiddenColumn;
+ if (hiddenColumns != null)
{
- region = hiddenColumns.elementAt(index++);
- if (hiddenColumn > region[1])
+ int index = 0;
+ int[] region;
+ do
{
- result -= region[1] + 1 - region[0];
- }
- } while ((hiddenColumn > region[1]) && (index < hiddenColumns.size()));
+ region = hiddenColumns.get(index++);
+ if (hiddenColumn > region[1])
+ {
+ result -= region[1] + 1 - region[0];
+ }
+ } while ((hiddenColumn > region[1])
+ && (index < hiddenColumns.size()));
- if (hiddenColumn >= region[0] && hiddenColumn <= region[1])
- {
- // Here the hidden column is within a region, so
- // we want to return the position of region[0]-1, adjusted for any
- // earlier hidden columns.
- // Calculate the difference between the actual hidden col position
- // and region[0]-1, and then subtract from result to convert result from
- // the adjusted hiddenColumn value to the adjusted region[0]-1 value
-
- // However, if the region begins at 0 we cannot return region[0]-1
- // just return 0
- if (region[0] == 0)
- {
- return 0;
- }
- else
+ if (hiddenColumn >= region[0] && hiddenColumn <= region[1])
{
- return result - (hiddenColumn - region[0] + 1);
+ // Here the hidden column is within a region, so
+ // we want to return the position of region[0]-1, adjusted for any
+ // earlier hidden columns.
+ // Calculate the difference between the actual hidden col position
+ // and region[0]-1, and then subtract from result to convert result
+ // from
+ // the adjusted hiddenColumn value to the adjusted region[0]-1 value
+
+ // However, if the region begins at 0 we cannot return region[0]-1
+ // just return 0
+ if (region[0] == 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return result - (hiddenColumn - region[0] + 1);
+ }
}
}
+ return result; // return the shifted position after removing hidden
+ // columns.
+ } finally
+ {
+ LOCK.readLock().unlock();
}
- return result; // return the shifted position after removing hidden columns.
}
/**
@@ -175,6 +286,10 @@ public class HiddenColumns
*/
public int subtractVisibleColumns(int visibleDistance, int startColumn)
{
+ try
+ {
+
+ LOCK.readLock().lock();
int distance = visibleDistance;
// in case startColumn is in a hidden region, move it to the left
@@ -216,40 +331,62 @@ public class HiddenColumns
return nextstart - distance;
}
return start - distance;
+ } finally
+ {
+ LOCK.readLock().unlock();
+ }
}
/**
- * Use this method to determine where the next hiddenRegion starts
+ * Use this method to determine the set of hiddenRegion start positions
*
- * @param hiddenRegion
- * index of hidden region (counts from 0)
- * @return column number in visible view
+ * @return list of column number in visible view where hidden regions start
*/
- public int findHiddenRegionPosition(int hiddenRegion)
+ public List findHiddenRegionPositions()
{
- int result = 0;
- if (hiddenColumns != null)
+ try
{
- int index = 0;
- int gaps = 0;
- do
+ LOCK.readLock().lock();
+ List positions = null;
+
+ if (hiddenColumns != null)
{
- int[] region = hiddenColumns.elementAt(index);
- if (hiddenRegion == 0)
+ positions = new ArrayList<>(hiddenColumns.size());
+
+ positions.add(hiddenColumns.get(0)[0]);
+ for (int i = 1; i < hiddenColumns.size(); ++i)
{
- return region[0];
- }
- gaps += region[1] + 1 - region[0];
- result = region[1] + 1;
- index++;
- } while (index <= hiddenRegion);
+ int result = 0;
+ if (hiddenColumns != null)
+ {
+ int index = 0;
+ int gaps = 0;
+ do
+ {
+ int[] region = hiddenColumns.get(index);
+ gaps += region[1] + 1 - region[0];
+ result = region[1] + 1;
+ index++;
+ } while (index <= i);
- result -= gaps;
- }
+ result -= gaps;
+ }
+ positions.add(result);
+ }
+ }
+ else
+ {
+ positions = new ArrayList<>();
+ }
- return result;
+ return positions;
+ }
+ finally
+ {
+ LOCK.readLock().unlock();
+ }
}
/**
@@ -261,22 +398,29 @@ public class HiddenColumns
*/
public int getHiddenBoundaryRight(int alPos)
{
- if (hiddenColumns != null)
+ try
{
- int index = 0;
- do
+ LOCK.readLock().lock();
+ if (hiddenColumns != null)
{
- int[] region = hiddenColumns.elementAt(index);
- if (alPos < region[0])
+ int index = 0;
+ do
{
- return region[0];
- }
+ int[] region = hiddenColumns.get(index);
+ if (alPos < region[0])
+ {
+ return region[0];
+ }
- index++;
- } while (index < hiddenColumns.size());
- }
+ index++;
+ } while (index < hiddenColumns.size());
+ }
- return alPos;
+ return alPos;
+ } finally
+ {
+ LOCK.readLock().unlock();
+ }
}
@@ -289,12 +433,16 @@ public class HiddenColumns
*/
public int getHiddenBoundaryLeft(int alPos)
{
+ try
+ {
+ LOCK.readLock().lock();
+
if (hiddenColumns != null)
{
int index = hiddenColumns.size() - 1;
do
{
- int[] region = hiddenColumns.elementAt(index);
+ int[] region = hiddenColumns.get(index);
if (alPos > region[1])
{
return region[1];
@@ -305,7 +453,10 @@ public class HiddenColumns
}
return alPos;
-
+ } finally
+ {
+ LOCK.readLock().unlock();
+ }
}
/**
@@ -318,12 +469,16 @@ public class HiddenColumns
*/
private int getHiddenIndexLeft(int pos)
{
+ try
+ {
+
+ LOCK.readLock().lock();
if (hiddenColumns != null)
{
int index = hiddenColumns.size() - 1;
do
{
- int[] region = hiddenColumns.elementAt(index);
+ int[] region = hiddenColumns.get(index);
if (pos > region[1])
{
return index;
@@ -334,6 +489,10 @@ public class HiddenColumns
}
return -1;
+ } finally
+ {
+ LOCK.readLock().unlock();
+ }
}
@@ -345,76 +504,101 @@ public class HiddenColumns
*/
public void hideColumns(int start, int end)
{
- if (hiddenColumns == null)
- {
- hiddenColumns = new Vector();
- }
-
- /*
- * traverse existing hidden ranges and insert / amend / append as
- * appropriate
- */
- for (int i = 0; i < hiddenColumns.size(); i++)
+ boolean wasAlreadyLocked = false;
+ try
{
- int[] region = hiddenColumns.elementAt(i);
-
- if (end < region[0] - 1)
+ // check if the write lock was already locked by this thread,
+ // as this method can be called internally in loops within HiddenColumns
+ if (!LOCK.isWriteLockedByCurrentThread())
{
- /*
- * insert discontiguous preceding range
- */
- hiddenColumns.insertElementAt(new int[] { start, end }, i);
- return;
+ LOCK.writeLock().lock();
+ }
+ else
+ {
+ wasAlreadyLocked = true;
}
- if (end <= region[1])
+ if (hiddenColumns == null)
{
- /*
- * new range overlaps existing, or is contiguous preceding it - adjust
- * start column
- */
- region[0] = Math.min(region[0], start);
- return;
+ hiddenColumns = new ArrayList<>();
}
- if (start <= region[1] + 1)
+ /*
+ * traverse existing hidden ranges and insert / amend / append as
+ * appropriate
+ */
+ for (int i = 0; i < hiddenColumns.size(); i++)
{
- /*
- * new range overlaps existing, or is contiguous following it - adjust
- * start and end columns
- */
- region[0] = Math.min(region[0], start);
- region[1] = Math.max(region[1], end);
-
- /*
- * also update or remove any subsequent ranges
- * that are overlapped
- */
- while (i < hiddenColumns.size() - 1)
+ int[] region = hiddenColumns.get(i);
+
+ if (end < region[0] - 1)
+ {
+ /*
+ * insert discontiguous preceding range
+ */
+ hiddenColumns.add(i, new int[] { start, end });
+ return;
+ }
+
+ if (end <= region[1])
+ {
+ /*
+ * new range overlaps existing, or is contiguous preceding it - adjust
+ * start column
+ */
+ region[0] = Math.min(region[0], start);
+ return;
+ }
+
+ if (start <= region[1] + 1)
{
- int[] nextRegion = hiddenColumns.get(i + 1);
- if (nextRegion[0] > end + 1)
+ /*
+ * new range overlaps existing, or is contiguous following it - adjust
+ * start and end columns
+ */
+ region[0] = Math.min(region[0], start);
+ region[1] = Math.max(region[1], end);
+
+ /*
+ * also update or remove any subsequent ranges
+ * that are overlapped
+ */
+ while (i < hiddenColumns.size() - 1)
{
- /*
- * gap to next hidden range - no more to update
- */
- break;
+ int[] nextRegion = hiddenColumns.get(i + 1);
+ if (nextRegion[0] > end + 1)
+ {
+ /*
+ * gap to next hidden range - no more to update
+ */
+ break;
+ }
+ region[1] = Math.max(nextRegion[1], end);
+ hiddenColumns.remove(i + 1);
}
- region[1] = Math.max(nextRegion[1], end);
- hiddenColumns.remove(i + 1);
+ return;
}
- return;
- }
}
/*
* remaining case is that the new range follows everything else
*/
- hiddenColumns.addElement(new int[] { start, end });
+ hiddenColumns.add(new int[] { start, end });
+ } finally
+ {
+ if (!wasAlreadyLocked)
+ {
+ LOCK.writeLock().unlock();
+ }
+ }
}
public boolean isVisible(int column)
{
+ try
+ {
+ LOCK.readLock().lock();
+
if (hiddenColumns != null)
{
for (int[] region : hiddenColumns)
@@ -427,39 +611,54 @@ public class HiddenColumns
}
return true;
+ } finally
+ {
+ LOCK.readLock().unlock();
+ }
}
- /**
- * ColumnSelection
- */
- public HiddenColumns()
+ private ArrayList copyHiddenRegionsToArrayList()
{
- }
+ int size = 0;
+ if (hiddenColumns != null)
+ {
+ size = hiddenColumns.size();
+ }
+ ArrayList copy = new ArrayList<>(size);
+
+ for (int i = 0, j = size; i < j; i++)
+ {
+ int[] rh;
+ int[] cp;
+ rh = hiddenColumns.get(i);
+ if (rh != null)
+ {
+ cp = new int[rh.length];
+ System.arraycopy(rh, 0, cp, 0, rh.length);
+ copy.add(cp);
+ }
+ }
+ return copy;
+ }
+
/**
- * Copy constructor
+ * Returns a copy of the vector of hidden regions, as an ArrayList. Before
+ * using this method please consider if you really need access to the hidden
+ * regions - a new (or existing!) method on HiddenColumns might be more
+ * appropriate.
*
- * @param copy
+ * @return hidden regions as an ArrayList of [start,end] pairs
*/
- public HiddenColumns(HiddenColumns copy)
+ public ArrayList getHiddenColumnsCopy()
{
- if (copy != null)
+ try
{
- if (copy.hiddenColumns != null)
- {
- hiddenColumns = new Vector(copy.hiddenColumns.size());
- for (int i = 0, j = copy.hiddenColumns.size(); i < j; i++)
- {
- int[] rh, cp;
- rh = copy.hiddenColumns.elementAt(i);
- if (rh != null)
- {
- cp = new int[rh.length];
- System.arraycopy(rh, 0, cp, 0, rh.length);
- hiddenColumns.addElement(cp);
- }
- }
- }
+ LOCK.readLock().lock();
+ return copyHiddenRegionsToArrayList();
+ } finally
+ {
+ LOCK.readLock().unlock();
}
}
@@ -474,42 +673,49 @@ public class HiddenColumns
public List compensateForEdit(int start, int change,
ColumnSelection sel)
{
- List deletedHiddenColumns = null;
-
- if (hiddenColumns != null)
+ try
{
- deletedHiddenColumns = new ArrayList();
- int hSize = hiddenColumns.size();
- for (int i = 0; i < hSize; i++)
+ LOCK.writeLock().lock();
+ List deletedHiddenColumns = null;
+
+ if (hiddenColumns != null)
{
- int[] region = hiddenColumns.elementAt(i);
- if (region[0] > start && start + change > region[1])
+ deletedHiddenColumns = new ArrayList<>();
+ int hSize = hiddenColumns.size();
+ for (int i = 0; i < hSize; i++)
{
- deletedHiddenColumns.add(region);
+ int[] region = hiddenColumns.get(i);
+ if (region[0] > start && start + change > region[1])
+ {
+ deletedHiddenColumns.add(region);
- hiddenColumns.removeElementAt(i);
- i--;
- hSize--;
- continue;
- }
+ hiddenColumns.remove(i);
+ i--;
+ hSize--;
+ continue;
+ }
- if (region[0] > start)
- {
- region[0] -= change;
- region[1] -= change;
- }
+ if (region[0] > start)
+ {
+ region[0] -= change;
+ region[1] -= change;
+ }
+
+ if (region[0] < 0)
+ {
+ region[0] = 0;
+ }
- if (region[0] < 0)
- {
- region[0] = 0;
}
+ this.revealHiddenColumns(0, sel);
}
- this.revealHiddenColumns(0, sel);
+ return deletedHiddenColumns;
+ } finally
+ {
+ LOCK.writeLock().unlock();
}
-
- return deletedHiddenColumns;
}
/**
@@ -523,34 +729,42 @@ public class HiddenColumns
*/
public void compensateForDelEdits(int start, int change)
{
- if (hiddenColumns != null)
+ try
{
- for (int i = 0; i < hiddenColumns.size(); i++)
+ LOCK.writeLock().lock();
+ if (hiddenColumns != null)
{
- int[] region = hiddenColumns.elementAt(i);
- if (region[0] >= start)
- {
- region[0] -= change;
- }
- if (region[1] >= start)
- {
- region[1] -= change;
- }
- if (region[1] < region[0])
+ for (int i = 0; i < hiddenColumns.size(); i++)
{
- hiddenColumns.removeElementAt(i--);
- }
+ int[] region = hiddenColumns.get(i);
+ if (region[0] >= start)
+ {
+ region[0] -= change;
+ }
+ if (region[1] >= start)
+ {
+ region[1] -= change;
+ }
+ if (region[1] < region[0])
+ {
+ hiddenColumns.remove(i--);
+ }
- if (region[0] < 0)
- {
- region[0] = 0;
- }
- if (region[1] < 0)
- {
- region[1] = 0;
+ if (region[0] < 0)
+ {
+ region[0] = 0;
+ }
+ if (region[1] < 0)
+ {
+ region[1] = 0;
+ }
}
}
}
+ finally
+ {
+ LOCK.writeLock().unlock();
+ }
}
/**
@@ -565,111 +779,130 @@ public class HiddenColumns
*/
public int[] getVisibleContigs(int start, int end)
{
- if (hiddenColumns != null && hiddenColumns.size() > 0)
+ try
{
- List visiblecontigs = new ArrayList();
- List regions = getHiddenRegions();
+ LOCK.readLock().lock();
+ if (hiddenColumns != null && hiddenColumns.size() > 0)
+ {
+ List visiblecontigs = new ArrayList<>();
+ List regions = getHiddenRegions();
- int vstart = start;
- int[] region;
- int hideStart, hideEnd;
+ int vstart = start;
+ int[] region;
+ int hideStart;
+ int hideEnd;
- for (int j = 0; vstart < end && j < regions.size(); j++)
- {
- region = regions.get(j);
- hideStart = region[0];
- hideEnd = region[1];
+ for (int j = 0; vstart < end && j < regions.size(); j++)
+ {
+ region = regions.get(j);
+ hideStart = region[0];
+ hideEnd = region[1];
+
+ if (hideEnd < vstart)
+ {
+ continue;
+ }
+ if (hideStart > vstart)
+ {
+ visiblecontigs.add(new int[] { vstart, hideStart - 1 });
+ }
+ vstart = hideEnd + 1;
+ }
- if (hideEnd < vstart)
+ if (vstart < end)
{
- continue;
+ visiblecontigs.add(new int[] { vstart, end - 1 });
}
- if (hideStart > vstart)
+ int[] vcontigs = new int[visiblecontigs.size() * 2];
+ for (int i = 0, j = visiblecontigs.size(); i < j; i++)
{
- visiblecontigs.add(new int[] { vstart, hideStart - 1 });
+ int[] vc = visiblecontigs.get(i);
+ visiblecontigs.set(i, null);
+ vcontigs[i * 2] = vc[0];
+ vcontigs[i * 2 + 1] = vc[1];
}
- vstart = hideEnd + 1;
- }
-
- if (vstart < end)
- {
- visiblecontigs.add(new int[] { vstart, end - 1 });
+ visiblecontigs.clear();
+ return vcontigs;
}
- int[] vcontigs = new int[visiblecontigs.size() * 2];
- for (int i = 0, j = visiblecontigs.size(); i < j; i++)
+ else
{
- int[] vc = visiblecontigs.get(i);
- visiblecontigs.set(i, null);
- vcontigs[i * 2] = vc[0];
- vcontigs[i * 2 + 1] = vc[1];
+ return new int[] { start, end - 1 };
}
- visiblecontigs.clear();
- return vcontigs;
}
- else
+ finally
{
- return new int[] { start, end - 1 };
+ LOCK.readLock().unlock();
}
}
public String[] getVisibleSequenceStrings(int start, int end,
SequenceI[] seqs)
{
- int i, iSize = seqs.length;
- String selections[] = new String[iSize];
- if (hiddenColumns != null && hiddenColumns.size() > 0)
+ try
{
- for (i = 0; i < iSize; i++)
+ LOCK.readLock().lock();
+ int iSize = seqs.length;
+ String[] selections = new String[iSize];
+ if (hiddenColumns != null && hiddenColumns.size() > 0)
{
- StringBuffer visibleSeq = new StringBuffer();
- List regions = getHiddenRegions();
-
- int blockStart = start, blockEnd = end;
- int[] region;
- int hideStart, hideEnd;
-
- for (int j = 0; j < regions.size(); j++)
+ for (int i = 0; i < iSize; i++)
{
- region = regions.get(j);
- hideStart = region[0];
- hideEnd = region[1];
+ StringBuffer visibleSeq = new StringBuffer();
+ List regions = getHiddenRegions();
- if (hideStart < start)
+ int blockStart = start;
+ int blockEnd = end;
+ int[] region;
+ int hideStart;
+ int hideEnd;
+
+ for (int j = 0; j < regions.size(); j++)
{
- continue;
- }
+ region = regions.get(j);
+ hideStart = region[0];
+ hideEnd = region[1];
- blockStart = Math.min(blockStart, hideEnd + 1);
- blockEnd = Math.min(blockEnd, hideStart);
+ if (hideStart < start)
+ {
+ continue;
+ }
- if (blockStart > blockEnd)
- {
- break;
+ blockStart = Math.min(blockStart, hideEnd + 1);
+ blockEnd = Math.min(blockEnd, hideStart);
+
+ if (blockStart > blockEnd)
+ {
+ break;
+ }
+
+ visibleSeq.append(seqs[i].getSequence(blockStart, blockEnd));
+
+ blockStart = hideEnd + 1;
+ blockEnd = end;
}
- visibleSeq.append(seqs[i].getSequence(blockStart, blockEnd));
+ if (end > blockStart)
+ {
+ visibleSeq.append(seqs[i].getSequence(blockStart, end));
+ }
- blockStart = hideEnd + 1;
- blockEnd = end;
+ selections[i] = visibleSeq.toString();
}
-
- if (end > blockStart)
+ }
+ else
+ {
+ for (int i = 0; i < iSize; i++)
{
- visibleSeq.append(seqs[i].getSequence(blockStart, end));
+ selections[i] = seqs[i].getSequenceAsString(start, end);
}
-
- selections[i] = visibleSeq.toString();
}
+
+ return selections;
}
- else
+ finally
{
- for (i = 0; i < iSize; i++)
- {
- selections[i] = seqs[i].getSequenceAsString(start, end);
- }
+ LOCK.readLock().unlock();
}
-
- return selections;
}
/**
@@ -684,70 +917,86 @@ public class HiddenColumns
*/
public int[] locateVisibleBoundsOfSequence(SequenceI seq)
{
- int fpos = seq.getStart(), lpos = seq.getEnd();
- int start = 0;
-
- if (hiddenColumns == null || hiddenColumns.size() == 0)
+ try
{
- int ifpos = seq.findIndex(fpos) - 1, ilpos = seq.findIndex(lpos) - 1;
- return new int[] { ifpos, ilpos, fpos, lpos, ifpos, ilpos };
- }
+ LOCK.readLock().lock();
+ int fpos = seq.getStart();
+ int lpos = seq.getEnd();
+ int start = 0;
- // Simply walk along the sequence whilst watching for hidden column
- // boundaries
- List regions = getHiddenRegions();
- int spos = fpos, lastvispos = -1, rcount = 0, hideStart = seq
- .getLength(), hideEnd = -1;
- int visPrev = 0, visNext = 0, firstP = -1, lastP = -1;
- boolean foundStart = false;
- for (int p = 0, pLen = seq.getLength(); spos <= seq.getEnd()
- && p < pLen; p++)
- {
- if (!Comparison.isGap(seq.getCharAt(p)))
+ if (hiddenColumns == null || hiddenColumns.size() == 0)
{
- // keep track of first/last column
- // containing sequence data regardless of visibility
- if (firstP == -1)
- {
- firstP = p;
- }
- lastP = p;
- // update hidden region start/end
- while (hideEnd < p && rcount < regions.size())
- {
- int[] region = regions.get(rcount++);
- visPrev = visNext;
- visNext += region[0] - visPrev;
- hideStart = region[0];
- hideEnd = region[1];
- }
- if (hideEnd < p)
- {
- hideStart = seq.getLength();
- }
- // update visible boundary for sequence
- if (p < hideStart)
+ int ifpos = seq.findIndex(fpos) - 1;
+ int ilpos = seq.findIndex(lpos) - 1;
+ return new int[] { ifpos, ilpos, fpos, lpos, ifpos, ilpos };
+ }
+
+ // Simply walk along the sequence whilst watching for hidden column
+ // boundaries
+ List regions = getHiddenRegions();
+ int spos = fpos;
+ int lastvispos = -1;
+ int rcount = 0;
+ int hideStart = seq.getLength();
+ int hideEnd = -1;
+ int visPrev = 0;
+ int visNext = 0;
+ int firstP = -1;
+ int lastP = -1;
+ boolean foundStart = false;
+ for (int p = 0, pLen = seq.getLength(); spos <= seq.getEnd()
+ && p < pLen; p++)
+ {
+ if (!Comparison.isGap(seq.getCharAt(p)))
{
- if (!foundStart)
+ // keep track of first/last column
+ // containing sequence data regardless of visibility
+ if (firstP == -1)
+ {
+ firstP = p;
+ }
+ lastP = p;
+ // update hidden region start/end
+ while (hideEnd < p && rcount < regions.size())
+ {
+ int[] region = regions.get(rcount++);
+ visPrev = visNext;
+ visNext += region[0] - visPrev;
+ hideStart = region[0];
+ hideEnd = region[1];
+ }
+ if (hideEnd < p)
{
- fpos = spos;
- start = p;
- foundStart = true;
+ hideStart = seq.getLength();
}
- lastvispos = p;
- lpos = spos;
+ // update visible boundary for sequence
+ if (p < hideStart)
+ {
+ if (!foundStart)
+ {
+ fpos = spos;
+ start = p;
+ foundStart = true;
+ }
+ lastvispos = p;
+ lpos = spos;
+ }
+ // look for next sequence position
+ spos++;
}
- // look for next sequence position
- spos++;
}
+ if (foundStart)
+ {
+ return new int[] { findColumnPosition(start),
+ findColumnPosition(lastvispos), fpos, lpos, firstP, lastP };
+ }
+ // otherwise, sequence was completely hidden
+ return new int[] { visPrev, visNext, 0, 0, firstP, lastP };
}
- if (foundStart)
+ finally
{
- return new int[] { findColumnPosition(start),
- findColumnPosition(lastvispos), fpos, lpos, firstP, lastP };
+ LOCK.readLock().unlock();
}
- // otherwise, sequence was completely hidden
- return new int[] { visPrev, visNext, 0, 0, firstP, lastP };
}
/**
@@ -775,88 +1024,100 @@ public class HiddenColumns
public void makeVisibleAnnotation(int start, int end,
AlignmentAnnotation alignmentAnnotation)
{
- if (alignmentAnnotation.annotations == null)
+ try
{
- return;
- }
- if (start == end && end == -1)
- {
- start = 0;
- end = alignmentAnnotation.annotations.length;
- }
- if (hiddenColumns != null && hiddenColumns.size() > 0)
- {
- // then mangle the alignmentAnnotation annotation array
- Vector annels = new Vector();
- Annotation[] els = null;
- List regions = getHiddenRegions();
- int blockStart = start, blockEnd = end;
- int[] region;
- int hideStart, hideEnd, w = 0;
-
- for (int j = 0; j < regions.size(); j++)
+ LOCK.readLock().lock();
+ if (alignmentAnnotation.annotations == null)
{
- region = regions.get(j);
- hideStart = region[0];
- hideEnd = region[1];
+ return;
+ }
+ if (start == end && end == -1)
+ {
+ start = 0;
+ end = alignmentAnnotation.annotations.length;
+ }
+ if (hiddenColumns != null && hiddenColumns.size() > 0)
+ {
+ // then mangle the alignmentAnnotation annotation array
+ Vector annels = new Vector<>();
+ Annotation[] els = null;
+ List regions = getHiddenRegions();
+ int blockStart = start;
+ int blockEnd = end;
+ int[] region;
+ int hideStart;
+ int hideEnd;
+ int w = 0;
- if (hideStart < start)
+ for (int j = 0; j < regions.size(); j++)
{
- continue;
- }
+ region = regions.get(j);
+ hideStart = region[0];
+ hideEnd = region[1];
- blockStart = Math.min(blockStart, hideEnd + 1);
- blockEnd = Math.min(blockEnd, hideStart);
+ if (hideStart < start)
+ {
+ continue;
+ }
- if (blockStart > blockEnd)
- {
- break;
- }
+ blockStart = Math.min(blockStart, hideEnd + 1);
+ blockEnd = Math.min(blockEnd, hideStart);
- annels.addElement(els = new Annotation[blockEnd - blockStart]);
- System.arraycopy(alignmentAnnotation.annotations, blockStart, els,
- 0, els.length);
- w += els.length;
- blockStart = hideEnd + 1;
- blockEnd = end;
- }
+ if (blockStart > blockEnd)
+ {
+ break;
+ }
- if (end > blockStart)
- {
- annels.addElement(els = new Annotation[end - blockStart + 1]);
- if ((els.length + blockStart) <= alignmentAnnotation.annotations.length)
+ annels.addElement(els = new Annotation[blockEnd - blockStart]);
+ System.arraycopy(alignmentAnnotation.annotations, blockStart, els,
+ 0, els.length);
+ w += els.length;
+ blockStart = hideEnd + 1;
+ blockEnd = end;
+ }
+
+ if (end > blockStart)
{
- // copy just the visible segment of the annotation row
- System.arraycopy(alignmentAnnotation.annotations, blockStart,
- els, 0, els.length);
+ annels.addElement(els = new Annotation[end - blockStart + 1]);
+ if ((els.length
+ + blockStart) <= alignmentAnnotation.annotations.length)
+ {
+ // copy just the visible segment of the annotation row
+ System.arraycopy(alignmentAnnotation.annotations, blockStart,
+ els, 0, els.length);
+ }
+ else
+ {
+ // copy to the end of the annotation row
+ System.arraycopy(alignmentAnnotation.annotations, blockStart,
+ els, 0,
+ (alignmentAnnotation.annotations.length - blockStart));
+ }
+ w += els.length;
}
- else
+ if (w == 0)
{
- // copy to the end of the annotation row
- System.arraycopy(alignmentAnnotation.annotations, blockStart,
- els, 0,
- (alignmentAnnotation.annotations.length - blockStart));
+ return;
}
- w += els.length;
- }
- if (w == 0)
- {
- return;
- }
- alignmentAnnotation.annotations = new Annotation[w];
- w = 0;
+ alignmentAnnotation.annotations = new Annotation[w];
+ w = 0;
- for (Annotation[] chnk : annels)
+ for (Annotation[] chnk : annels)
+ {
+ System.arraycopy(chnk, 0, alignmentAnnotation.annotations, w,
+ chnk.length);
+ w += chnk.length;
+ }
+ }
+ else
{
- System.arraycopy(chnk, 0, alignmentAnnotation.annotations, w,
- chnk.length);
- w += chnk.length;
+ alignmentAnnotation.restrict(start, end);
}
}
- else
+ finally
{
- alignmentAnnotation.restrict(start, end);
+ LOCK.readLock().unlock();
}
}
@@ -866,7 +1127,14 @@ public class HiddenColumns
*/
public boolean hasHiddenColumns()
{
- return hiddenColumns != null && hiddenColumns.size() > 0;
+ try
+ {
+ LOCK.readLock().lock();
+ return hiddenColumns != null && hiddenColumns.size() > 0;
+ } finally
+ {
+ LOCK.readLock().unlock();
+ }
}
/**
@@ -875,7 +1143,14 @@ public class HiddenColumns
*/
public boolean hasManyHiddenColumns()
{
- return hiddenColumns != null && hiddenColumns.size() > 1;
+ try
+ {
+ LOCK.readLock().lock();
+ return hiddenColumns != null && hiddenColumns.size() > 1;
+ } finally
+ {
+ LOCK.readLock().unlock();
+ }
}
/**
@@ -886,10 +1161,17 @@ public class HiddenColumns
*/
public void hideInsertionsFor(SequenceI sr)
{
- List inserts = sr.getInsertions();
- for (int[] r : inserts)
+ try
{
- hideColumns(r[0], r[1]);
+ LOCK.writeLock().lock();
+ List inserts = sr.getInsertions();
+ for (int[] r : inserts)
+ {
+ hideColumns(r[0], r[1]);
+ }
+ } finally
+ {
+ LOCK.writeLock().unlock();
}
}
@@ -898,19 +1180,27 @@ public class HiddenColumns
*/
public void revealAllHiddenColumns(ColumnSelection sel)
{
- if (hiddenColumns != null)
+ try
{
- for (int i = 0; i < hiddenColumns.size(); i++)
+ LOCK.writeLock().lock();
+ if (hiddenColumns != null)
{
- int[] region = hiddenColumns.elementAt(i);
- for (int j = region[0]; j < region[1] + 1; j++)
+ for (int i = 0; i < hiddenColumns.size(); i++)
{
- sel.addElement(j);
+ int[] region = hiddenColumns.get(i);
+ for (int j = region[0]; j < region[1] + 1; j++)
+ {
+ sel.addElement(j);
+ }
}
}
- }
- hiddenColumns = null;
+ hiddenColumns = null;
+ }
+ finally
+ {
+ LOCK.writeLock().unlock();
+ }
}
/**
@@ -921,23 +1211,31 @@ public class HiddenColumns
*/
public void revealHiddenColumns(int start, ColumnSelection sel)
{
- for (int i = 0; i < hiddenColumns.size(); i++)
+ try
{
- int[] region = hiddenColumns.elementAt(i);
- if (start == region[0])
+ LOCK.writeLock().lock();
+ for (int i = 0; i < hiddenColumns.size(); i++)
{
- for (int j = region[0]; j < region[1] + 1; j++)
+ int[] region = hiddenColumns.get(i);
+ if (start == region[0])
{
- sel.addElement(j);
- }
+ for (int j = region[0]; j < region[1] + 1; j++)
+ {
+ sel.addElement(j);
+ }
- hiddenColumns.removeElement(region);
- break;
+ hiddenColumns.remove(region);
+ break;
+ }
+ }
+ if (hiddenColumns.size() == 0)
+ {
+ hiddenColumns = null;
}
}
- if (hiddenColumns.size() == 0)
+ finally
{
- hiddenColumns = null;
+ LOCK.writeLock().unlock();
}
}
@@ -949,13 +1247,16 @@ public class HiddenColumns
* @param intervals
* @return
*/
- private boolean pruneIntervalVector(final List shifts,
- Vector intervals)
+ private boolean pruneIntervalList(final List shifts,
+ ArrayList intervals)
{
boolean pruned = false;
- int i = 0, j = intervals.size() - 1, s = 0, t = shifts.size() - 1;
- int hr[] = intervals.elementAt(i);
- int sr[] = shifts.get(s);
+ int i = 0;
+ int j = intervals.size() - 1;
+ int s = 0;
+ int t = shifts.size() - 1;
+ int[] hr = intervals.get(i);
+ int[] sr = shifts.get(s);
while (i <= j && s <= t)
{
boolean trailinghn = hr[1] >= sr[0];
@@ -963,7 +1264,7 @@ public class HiddenColumns
{
if (i < j)
{
- hr = intervals.elementAt(++i);
+ hr = intervals.get(++i);
}
else
{
@@ -991,12 +1292,12 @@ public class HiddenColumns
{
if (trailinghc)
{ // deleted hidden region.
- intervals.removeElementAt(i);
+ intervals.remove(i);
pruned = true;
j--;
if (i <= j)
{
- hr = intervals.elementAt(i);
+ hr = intervals.get(i);
}
continue;
}
@@ -1044,15 +1345,23 @@ public class HiddenColumns
*/
public void pruneDeletions(List shifts)
{
- // delete any intervals intersecting.
- if (hiddenColumns != null)
+ try
{
- pruneIntervalVector(shifts, hiddenColumns);
- if (hiddenColumns != null && hiddenColumns.size() == 0)
+ LOCK.writeLock().lock();
+ // delete any intervals intersecting.
+ if (hiddenColumns != null)
{
- hiddenColumns = null;
+ pruneIntervalList(shifts, hiddenColumns);
+ if (hiddenColumns != null && hiddenColumns.size() == 0)
+ {
+ hiddenColumns = null;
+ }
}
}
+ finally
+ {
+ LOCK.writeLock().unlock();
+ }
}
/**
@@ -1098,8 +1407,7 @@ public class HiddenColumns
// recover mapping between sequence's non-gap positions and positions
// mapping to view.
pruneDeletions(ShiftList.parseMap(origseq.gapMap()));
- int[] viscontigs = al.getHiddenColumns().getVisibleContigs(0,
- profileseq.getLength());
+ int[] viscontigs = getVisibleContigs(0, profileseq.getLength());
int spos = 0;
int offset = 0;
@@ -1251,16 +1559,24 @@ public class HiddenColumns
@Override
public int hashCode()
{
- int hashCode = 1;
- if (hiddenColumns != null)
+ try
{
- for (int[] hidden : hiddenColumns)
+ LOCK.readLock().lock();
+ int hashCode = 1;
+ if (hiddenColumns != null)
{
- hashCode = 31 * hashCode + hidden[0];
- hashCode = 31 * hashCode + hidden[1];
+ for (int[] hidden : hiddenColumns)
+ {
+ hashCode = 31 * hashCode + hidden[0];
+ hashCode = 31 * hashCode + hidden[1];
+ }
}
+ return hashCode;
+ }
+ finally
+ {
+ LOCK.readLock().unlock();
}
- return hashCode;
}
/**
@@ -1271,11 +1587,19 @@ public class HiddenColumns
*/
public void hideMarkedBits(BitSet inserts)
{
- for (int firstSet = inserts.nextSetBit(0), lastSet = 0; firstSet >= 0; firstSet = inserts
- .nextSetBit(lastSet))
+ try
{
- lastSet = inserts.nextClearBit(firstSet);
- hideColumns(firstSet, lastSet - 1);
+ LOCK.writeLock().lock();
+ for (int firstSet = inserts
+ .nextSetBit(0), lastSet = 0; firstSet >= 0; firstSet = inserts
+ .nextSetBit(lastSet))
+ {
+ lastSet = inserts.nextClearBit(firstSet);
+ hideColumns(firstSet, lastSet - 1);
+ }
+ } finally
+ {
+ LOCK.writeLock().unlock();
}
}
@@ -1286,13 +1610,109 @@ public class HiddenColumns
*/
public void markHiddenRegions(BitSet inserts)
{
- if (hiddenColumns == null)
+ try
+ {
+ LOCK.readLock().lock();
+ if (hiddenColumns == null)
+ {
+ return;
+ }
+ for (int[] range : hiddenColumns)
+ {
+ inserts.set(range[0], range[1] + 1);
+ }
+ }
+ finally
{
- return;
+ LOCK.readLock().unlock();
}
- for (int[] range : hiddenColumns)
+ }
+
+ /**
+ * Calculate the visible start and end index of an alignment.
+ *
+ * @param width
+ * full alignment width
+ * @return integer array where: int[0] = startIndex, and int[1] = endIndex
+ */
+ public int[] getVisibleStartAndEndIndex(int width)
+ {
+ try
+ {
+ LOCK.readLock().lock();
+ int[] alignmentStartEnd = new int[] { 0, width - 1 };
+ int startPos = alignmentStartEnd[0];
+ int endPos = alignmentStartEnd[1];
+
+ int[] lowestRange = new int[] { -1, -1 };
+ int[] higestRange = new int[] { -1, -1 };
+
+ if (hiddenColumns == null)
+ {
+ return new int[] { startPos, endPos };
+ }
+
+ for (int[] hiddenCol : hiddenColumns)
+ {
+ lowestRange = (hiddenCol[0] <= startPos) ? hiddenCol : lowestRange;
+ higestRange = (hiddenCol[1] >= endPos) ? hiddenCol : higestRange;
+ }
+
+ if (lowestRange[0] == -1 && lowestRange[1] == -1)
+ {
+ startPos = alignmentStartEnd[0];
+ }
+ else
+ {
+ startPos = lowestRange[1] + 1;
+ }
+
+ if (higestRange[0] == -1 && higestRange[1] == -1)
+ {
+ endPos = alignmentStartEnd[1];
+ }
+ else
+ {
+ endPos = higestRange[0] - 1;
+ }
+ return new int[] { startPos, endPos };
+ } finally
+ {
+ LOCK.readLock().unlock();
+ }
+
+ }
+
+ /**
+ * Finds the hidden region (if any) which starts or ends at res
+ *
+ * @param res
+ * visible residue position, unadjusted for hidden columns
+ * @return region as [start,end] or null if no matching region is found
+ */
+ public int[] getRegionWithEdgeAtRes(int res)
+ {
+ try
+ {
+ LOCK.readLock().lock();
+ int adjres = adjustForHiddenColumns(res);
+
+ int[] reveal = null;
+ if (hiddenColumns != null)
+ {
+ for (int[] region : hiddenColumns)
+ {
+ if (adjres + 1 == region[0] || adjres - 1 == region[1])
+ {
+ reveal = region;
+ break;
+ }
+ }
+ }
+ return reveal;
+ } finally
{
- inserts.set(range[0], range[1] + 1);
+ LOCK.readLock().unlock();
}
}
diff --git a/src/jalview/datamodel/HiddenSequences.java b/src/jalview/datamodel/HiddenSequences.java
index a98b10e..98e9694 100755
--- a/src/jalview/datamodel/HiddenSequences.java
+++ b/src/jalview/datamodel/HiddenSequences.java
@@ -157,9 +157,10 @@ public class HiddenSequences
int absAlignmentIndex = alignment.findIndex(sequence);
int alignmentIndex = adjustForHiddenSeqs(absAlignmentIndex);
- if (hiddenSequences[alignmentIndex] != null)
+ if (alignmentIndex < 0 || hiddenSequences[alignmentIndex] != null)
{
System.out.println("ERROR!!!!!!!!!!!");
+ return;
}
hiddenSequences[alignmentIndex] = sequence;
@@ -253,7 +254,8 @@ public class HiddenSequences
}
/**
- * Convert absolute alignment index to visible alignment index
+ * Convert absolute alignment index to visible alignment index (or -1 if
+ * before the first visible sequence)
*
* @param alignmentIndex
* @return
diff --git a/src/jalview/datamodel/SequenceFeature.java b/src/jalview/datamodel/SequenceFeature.java
index 9a6cf2b..ba7412c 100755
--- a/src/jalview/datamodel/SequenceFeature.java
+++ b/src/jalview/datamodel/SequenceFeature.java
@@ -143,15 +143,16 @@ public class SequenceFeature implements FeatureLocationI
* A copy constructor that allows the value of final fields to be 'modified'
*
* @param sf
+ * @param newType
* @param newBegin
* @param newEnd
* @param newGroup
* @param newScore
*/
- public SequenceFeature(SequenceFeature sf, int newBegin, int newEnd,
- String newGroup, float newScore)
+ public SequenceFeature(SequenceFeature sf, String newType, int newBegin,
+ int newEnd, String newGroup, float newScore)
{
- this(sf.getType(), sf.getDescription(), newBegin, newEnd, newScore,
+ this(newType, sf.getDescription(), newBegin, newEnd, newScore,
newGroup);
if (sf.otherDetails != null)
@@ -173,6 +174,21 @@ public class SequenceFeature implements FeatureLocationI
}
/**
+ * A copy constructor that allows the value of final fields to be 'modified'
+ *
+ * @param sf
+ * @param newBegin
+ * @param newEnd
+ * @param newGroup
+ * @param newScore
+ */
+ public SequenceFeature(SequenceFeature sf, int newBegin, int newEnd,
+ String newGroup, float newScore)
+ {
+ this(sf, sf.getType(), newBegin, newEnd, newGroup, newScore);
+ }
+
+ /**
* Two features are considered equal if they have the same type, group,
* description, start, end, phase, strand, and (if present) 'Name', ID' and
* 'Parent' attributes.
diff --git a/src/jalview/datamodel/SequenceGroup.java b/src/jalview/datamodel/SequenceGroup.java
index 463b909..46c802f 100755
--- a/src/jalview/datamodel/SequenceGroup.java
+++ b/src/jalview/datamodel/SequenceGroup.java
@@ -188,7 +188,7 @@ public class SequenceGroup implements AnnotatedCollectionI
colourText = seqsel.colourText;
startRes = seqsel.startRes;
endRes = seqsel.endRes;
- cs = new ResidueShader(seqsel.getColourScheme());
+ cs = new ResidueShader((ResidueShader) seqsel.cs);
if (seqsel.description != null)
{
description = new String(seqsel.description);
diff --git a/src/jalview/datamodel/VisibleColsIterator.java b/src/jalview/datamodel/VisibleColsIterator.java
index 70de1e3..a82de93 100644
--- a/src/jalview/datamodel/VisibleColsIterator.java
+++ b/src/jalview/datamodel/VisibleColsIterator.java
@@ -48,7 +48,7 @@ public class VisibleColsIterator implements Iterator
last = lastcol;
current = firstcol;
next = firstcol;
- hidden = hiddenCols.getHiddenRegions();
+ hidden = hiddenCols.getHiddenColumnsCopy();
lasthiddenregion = -1;
if (hidden != null)
diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java
index a9a970f..e5d550f 100644
--- a/src/jalview/gui/AlignFrame.java
+++ b/src/jalview/gui/AlignFrame.java
@@ -167,7 +167,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
public AlignViewControllerI avc;
- List alignPanels = new ArrayList();
+ List alignPanels = new ArrayList<>();
/**
* Last format used to load or save alignments in this window
@@ -396,8 +396,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
addKeyListener();
- final List selviews = new ArrayList();
- final List origview = new ArrayList();
+ final List selviews = new ArrayList<>();
+ final List origview = new ArrayList<>();
final String menuLabel = MessageManager
.getString("label.copy_format_from");
ViewSelectionMenu vsel = new ViewSelectionMenu(menuLabel,
@@ -410,7 +410,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
origview.clear();
origview.add(alignPanel);
// make an array of all alignment panels except for this one
- List aps = new ArrayList(
+ List aps = new ArrayList<>(
Arrays.asList(Desktop.getAlignmentPanels(null)));
aps.remove(AlignFrame.this.alignPanel);
return aps.toArray(new AlignmentPanel[aps.size()]);
@@ -689,24 +689,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
break;
}
case KeyEvent.VK_PAGE_UP:
- if (viewport.getWrapAlignment())
- {
- vpRanges.scrollUp(true);
- }
- else
- {
- vpRanges.pageUp();
- }
+ vpRanges.pageUp();
break;
case KeyEvent.VK_PAGE_DOWN:
- if (viewport.getWrapAlignment())
- {
- vpRanges.scrollUp(false);
- }
- else
- {
- vpRanges.pageDown();
- }
+ vpRanges.pageDown();
break;
}
}
@@ -1320,10 +1306,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
{
alignmentToExport = viewport.getAlignment();
}
- alignmentStartEnd = alignmentToExport
- .getVisibleStartAndEndIndex(viewport.getAlignment()
- .getHiddenColumns()
- .getHiddenRegions());
+ alignmentStartEnd = viewport.getAlignment().getHiddenColumns()
+ .getVisibleStartAndEndIndex(alignmentToExport.getWidth());
AlignmentExportData ed = new AlignmentExportData(alignmentToExport,
omitHidden, alignmentStartEnd, settings);
return ed;
@@ -1732,7 +1716,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
synchronized void slideSequences(boolean right, int size)
{
- List sg = new ArrayList();
+ List sg = new ArrayList<>();
if (viewport.cursorMode)
{
sg.add(viewport.getAlignment().getSequenceAt(
@@ -1751,7 +1735,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
return;
}
- List invertGroup = new ArrayList();
+ List invertGroup = new ArrayList<>();
for (SequenceI seq : viewport.getAlignment().getSequences())
{
@@ -1884,11 +1868,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
ArrayList hiddenColumns = null;
if (viewport.hasHiddenColumns())
{
- hiddenColumns = new ArrayList();
- int hiddenOffset = viewport.getSelectionGroup().getStartRes(), hiddenCutoff = viewport
- .getSelectionGroup().getEndRes();
- for (int[] region : viewport.getAlignment().getHiddenColumns()
- .getHiddenRegions())
+ hiddenColumns = new ArrayList<>();
+ int hiddenOffset = viewport.getSelectionGroup().getStartRes();
+ int hiddenCutoff = viewport.getSelectionGroup().getEndRes();
+ ArrayList hiddenRegions = viewport.getAlignment()
+ .getHiddenColumns().getHiddenColumnsCopy();
+ for (int[] region : hiddenRegions)
{
if (region[0] >= hiddenOffset && region[1] <= hiddenCutoff)
{
@@ -1994,7 +1979,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
}
int alwidth = 0;
- ArrayList newGraphGroups = new ArrayList();
+ ArrayList newGraphGroups = new ArrayList<>();
int fgroup = -1;
if (newAlignment)
@@ -2457,7 +2442,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
viewport.setSelectionGroup(null);
viewport.getColumnSelection().clear();
viewport.setSelectionGroup(null);
- alignPanel.getSeqPanel().seqCanvas.highlightSearchResults(null);
alignPanel.getIdPanel().getIdCanvas().searchResults = null;
// JAL-2034 - should delegate to
// alignPanel to decide if overview needs
@@ -2826,7 +2810,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*/
protected List getExistingViewNames(List comps)
{
- List existingNames = new ArrayList();
+ List existingNames = new ArrayList<>();
for (Component comp : comps)
{
if (comp instanceof AlignmentPanel)
@@ -3215,10 +3199,6 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
{
viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
alignPanel.paintAlignment(true);
- if (alignPanel.getOverviewPanel() != null)
- {
- alignPanel.getOverviewPanel().updateOverviewImage();
- }
}
/**
@@ -3274,7 +3254,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
}
JInternalFrame frame = new JInternalFrame();
- OverviewPanel overview = new OverviewPanel(alignPanel);
+ final OverviewPanel overview = new OverviewPanel(alignPanel);
frame.setContentPane(overview);
Desktop.addInternalFrame(frame, MessageManager.formatMessage(
"label.overview_params", new Object[] { this.getTitle() }),
@@ -3287,6 +3267,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
public void internalFrameClosed(
javax.swing.event.InternalFrameEvent evt)
{
+ overview.dispose();
alignPanel.setOverviewPanel(null);
};
});
@@ -3760,7 +3741,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
List comps = PaintRefresher.components.get(viewport
.getSequenceSetId());
- List treePanels = new ArrayList();
+ List treePanels = new ArrayList<>();
for (Component comp : comps)
{
if (comp instanceof TreePanel)
@@ -4020,7 +4001,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
@Override
public void run()
{
- final List legacyItems = new ArrayList();
+ final List legacyItems = new ArrayList<>();
try
{
// System.err.println("Building ws menu again "
@@ -4035,7 +4016,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
// TODO: group services by location as well as function and/or
// introduce
// object broker mechanism.
- final Vector wsmenu = new Vector();
+ final Vector wsmenu = new Vector<>();
final IProgressIndicator af = me;
/*
@@ -4403,8 +4384,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
// Java's Transferable for native dnd
evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
Transferable t = evt.getTransferable();
- List files = new ArrayList();
- List protocols = new ArrayList();
+ List files = new ArrayList<>();
+ List protocols = new ArrayList<>();
try
{
@@ -4424,8 +4405,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
/**
* Object[] { String,SequenceI}
*/
- ArrayList