<file-match-pattern match-pattern="src/.*.java" include-pattern="true"/>
<file-match-pattern match-pattern="resources/.*.properties" include-pattern="true"/>
</fileset>
- <filter name="NonSrcDirs" enabled="false"/>
</fileset-config>
java -Djava.ext.dirs=JALVIEW_HOME/lib -cp JALVIEW_HOME/jalview.jar jalview.bin.Jalview
-Replace JALVIEW_HOME with the full path to Jalview Installation Directory.
+Replace JALVIEW_HOME with the full path to Jalview Installation Directory. If building from source:
+
+java -Djava.ext.dirs=JALVIEW_BUILD/dist -cp JALVIEW_BUILD/dist/jalview.jar jalview.bin.Jalview
+
##################
-jalview.release=releases/Release_2_10_2b1_Branch
-jalview.version=2.10.2b1
+jalview.release=releases/Release_2_10_3_Branch
+jalview.version=2.10.3
<offline_allowed />
</information>
<resources>
- <j2se version="9+" />
+ <j2se version="1.7+" />
<jar main="true" href="jalview.jar"/>
<fileset dir="${packageDir}">
<exclude name="jalview.jar" />
</presetdef>
<jnlpf toFile="${jnlpFile}" />
- <!-- add a j2se entry for java 9 -->
+ <!-- add the add-modules j2se attribute for java 9 -->
<replace file="${jnlpFile}" value="j2se version="1.7+" initial-heap-size="${inih}" max-heap-size="${maxh}" java-vm-args="--add-modules=java.se.ee"">
- <replacetoken>j2se version="1.9+"</replacetoken>
+ <replacetoken>j2se version="1.7+"</replacetoken>
</replace>
</target>
--- /dev/null
+/*
+ * 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 <http://www.gnu.org/licenses/>.
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+
+import jalview.analysis.scoremodels.ScoreModels
+import jalview.analysis.scoremodels.SimilarityParams
+
+// generate matrix for current selection using standard Jalview PID
+
+printSimilarityMatrix(true,true,SimilarityParams.Jalview)
+
+/**
+ * this function prints a sequence similarity matrix in PHYLIP format.
+ * printSimilarityMatrix(selected-only, include-ids, pidMethod)
+ *
+ * Allowed values for pidMethod:
+ *
+ * Jalview's Comparison.PID method includes matching gaps
+ * and counts over the length of the shorter gapped sequence
+ * SimilarityParams.Jalview;
+ *
+ * 'SeqSpace' mode PCA calculation does not count matching
+ * gaps but uses longest gapped sequence length
+ * SimilarityParams.SeqSpace;
+ *
+ * PID calcs from the Raghava-Barton paper
+ * SimilarityParams.PID1: ignores gap-gap, does not score gap-residue,
+ * includes gap-residue in lengths, matches on longer of two sequences.
+ *
+ * SimilarityParams.PID2: ignores gap-gap,ignores gap-residue,
+ * matches on longer of two sequences
+ *
+ * SimilarityParams.PID3: ignores gap-gap,ignores gap-residue,
+ * matches on shorter of sequences only
+ *
+ * SimilarityParams.PID4: ignores gap-gap,does not score gap-residue,
+ * includes gap-residue in lengths,matches on shorter of sequences only.
+ */
+
+void printSimilarityMatrix(boolean selview=false, boolean includeids=true, SimilarityParams pidMethod) {
+
+ def currentAlignFrame = jalview.bin.Jalview.getCurrentAlignFrame()
+
+ jalview.gui.AlignViewport av = currentAlignFrame.getCurrentView()
+
+ jalview.datamodel.AlignmentView seqStrings = av.getAlignmentView(selview)
+
+ if (!selview || av.getSelectionGroup()==null) {
+ start = 0
+ end = av.getAlignment().getWidth()
+ seqs = av.getAlignment().getSequencesArray()
+ } else {
+ start = av.getSelectionGroup().getStartRes()
+ end = av.getSelectionGroup().getEndRes() + 1
+ seqs = av.getSelectionGroup().getSequencesInOrder(av.getAlignment())
+ }
+
+ distanceCalc = ScoreModels.getInstance().getScoreModel("PID",
+ (jalview.api.AlignmentViewPanel) currentAlignFrame.alignPanel)
+
+ def distance=distanceCalc.findSimilarities(
+ seqStrings.getSequenceStrings(jalview.util.Comparison.GAP_DASH),pidMethod)
+
+ // output the PHYLIP Matrix
+
+ print distance.width()+" "+distance.height()+"\n"
+
+ p = 0
+
+ for (v in 1..distance.height()) {
+
+ if (includeids) {
+ print seqs[p++].getDisplayId(false)+" "
+ }
+
+ for (r in 1..distance.width()) {
+ print distance.getValue(v-1,r-1)+" "
+ }
+
+ print "\n"
+ }
+}
\ No newline at end of file
<p>
Gap open : 12 <br> Gap extend : 2
</p>
- <p>When you select the pairwise alignment option a new window will
- come up which will display the alignments in a text format as they
- are calculated. Also displayed is information about the alignment
- such as alignment score, length and percentage identity between the
+ <p>When you select the pairwise alignment option, a new window
+ will come up which displays the alignments in a text format, for
+ example:</p>
+ <p>
+ <pre>
+ FER1_SPIOL/5-13 TTMMGMAT<br />
+ |. .. ||<br />
+ FER1_MESCR/5-15 TAALSGAT
+ </pre>
+ shows the aligned sequences, where '|' links identical residues, and
+ (for peptide) '.' links residues that have a positive PAM250 score.
+ <p>The window also shows information about the alignment such as
+ alignment score, length and percentage identity between the
sequences.</p>
- <p> </p>
+ <p>A button is also provided to allow you to view the sequences as
+ an alignment.</p>
</body>
</html>
<td width="60" nowrap>
<div align="center">
<strong><a name="Jalview.2.10.3">2.10.3</a><br />
- <em>10/10/2017</em></strong>
+ <em>14/11/2017</em></strong>
</div>
</td>
<td><div align="left">
<!-- JAL-2446 -->Faster and more efficient management and
rendering of sequence features
</li>
+ <li>
+ <!-- JAL 2523-->More reliable Ensembl fetching with HTTP
+ 429 rate limit request hander
+ </li>
+ <li>
+ <!-- JAL-2773 -->Structure views don't get updated unless
+ their colours have changed
+ </li>
+ <li><!-- JAL-2495 -->All linked sequences are highlighted for a structure mousover (Jmol) or selection (Chimera)</li>
+ <li><!-- JAL-2790 -->'Cancel' button in progress bar for JABAWS AACon, RNAAliFold and Disorder prediction jobs
+ </li>
+
+ <li><!-- JAL-2617 -->Stop codons are excluded in CDS/Protein view from Ensembl locus cross-references</li>
+ <li><!-- JAL-2685 -->Start/End limits are shown in Pairwise Alignment report</li>
</ul>
- </div></td>
+ <ul><li>Example groovy script for generating a matrix of percent identity scores for current alignment.</li></ul>
+ <em>Testing and Deployment</em>
+ <ul><li><!-- JAL-2727 -->Test to catch memory leaks in Jalview UI</li></ul>
+ </div>
+ </td>
<td><div align="left">
- <em></em>
+ <em>General</em>
+ <ul>
+ <li><!-- JAL-2643 -->Pressing tab after updating the colour threshold text field doesn't trigger an update to the alignment view</li>
+ <li><!-- JAL-2682 -->Race condition when parsing sequence ID strings in parallel</li>
+ <li><!-- JAL-2608 -->Overview windows are also closed when alignment window is closed</li>
+ <li><!-- JAL-2548 -->Export of features doesn't always respect group visibility</li>
+ </ul>
+ <em>Desktop</em>
<ul>
+ <li><!-- JAL-2777 -->Structures with whitespace chainCode cannot be viewed in Chimera</li>
<li><!-- JAL-2728 -->Protein annotation panel too high in CDS/Protein view
+ </li>
+ <li><!-- JAL-2757 -->Can't edit the query after the server error warning icon is shown in Uniprot and PDB Free Text Search Dialogs
+ </li>
+ <li><!-- JAL-2253 -->Slow EnsemblGenome ID lookup</li>
+ <li><!-- JAL-2529 -->Revised Ensembl REST API CDNA query</li>
+ <li><!-- JAL-2739 -->Hidden column marker in last column not rendered when switching back from Wrapped to normal view</li>
+ <li><!-- JAL-2768 -->Annotation display corrupted when scrolling right in unwapped alignment view</li>
+ <li><!-- JAL-2542 -->Existing features on subsequence incorrectly relocated when full sequence retrieved from database</li>
+ <li><!-- JAL-2733 -->Last reported memory still shown when Desktop->Show Memory is unticked (OSX only)</li>
+ <li><!-- JAL-2658 -->Amend Features dialog doesn't allow features of same type and group to be selected for amending</li>
+ <li><!-- JAL-2524 -->Jalview becomes sluggish in wide alignments when hidden columns are present</li>
+ <li><!-- JAL-2392 -->Jalview freezes when loading and displaying several structures</li>
+ <li><!-- JAL-2732 -->Black outlines left after resizing or moving a window</li>
+ <li><!-- JAL-1900,JAL-1625 -->Unable to minimise windows within the Jalview desktop on OSX</li>
+ <li><!-- JAL-2667 -->Mouse wheel doesn't scroll vertically when in wrapped alignment mode</li>
+ <li><!-- JAL-2636 -->Scale mark not shown when close to right hand end of alignment</li>
+ <li><!-- JAL-2684 -->Pairwise alignment only aligns selected regions of each selected sequence</li>
+ <li><!-- JAL-2973 -->Alignment ruler height set incorrectly after canceling the Alignment Window's Font dialog</li>
+ <li><!-- JAL-2036 -->Show cross-references not enabled after restoring project until a new view is created</li>
+ <li><!-- JAL-2756 -->Warning popup about use of SEQUENCE_ID in URL links appears when only default EMBL-EBI link is configured (since 2.10.2b2)</li>
+ <li><!-- JAL-2775 -->Overview redraws whole window when box position is adjusted</li>
+ </ul>
+ <strong><em>Applet</em></strong><br/>
+ <ul>
+ <li><!-- JAL-2687 -->Concurrent modification exception when closing alignment panel</li>
+ </ul>
+ <strong><em>BioJSON</em></strong><br/>
+ <ul>
+ <li>
+ <!-- JAL-2546 -->BioJSON export does not preserve non-positional features
+ </li>
+ </ul>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td width="60" nowrap>
+ <div align="center">
+ <strong><a name="Jalview.2.10.2b2">2.10.2b2</a><br />
+ <em>2/10/2017</em></strong>
+ </div>
+ </td>
+ <td><div align="left">
+ <em>New features in Jalview Desktop</em>
+ <ul>
+ <li>
+ <!-- JAL-2748 -->Uniprot Sequence Fetcher now uses web API at uniprot.org
+ </li>
+ <li> <!-- JAL-2745 -->HTTPS used for all connections to ebi.ac.uk
</li>
</ul>
</div></td>
+ <td><div align="left">
+ </div></td>
</tr>
<tr>
<td width="60" nowrap>
after clicking on it to create new annotation for a
column.
</li>
+ <li>
+ <!-- JAL-1980 -->Null Pointer Exception raised when
+ pressing Add on an orphaned cut'n'paste window.
+ </li>
<!-- may exclude, this is an external service stability issue JAL-1941
-- > RNA 3D structure not added via DSSR service</li> -->
</ul>
try
{
- pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol);
+ pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol, null);
if (protocol == DataSourceType.PASTE)
{
try
{
- pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol);
+ pdb = ssm.setMapping(seq, chains, pdbentry.getFile(), protocol,
+ ap.alignFrame);
if (protocol.equals(jalview.io.DataSourceType.PASTE))
{
public void splitInsertionCode(String residue)
{
// OK, split the index into number and insertion code
+ // JBPNote - m.matches() can be true even if there is no resnum - this can
+ // cause NumberFormatExceptions below
Pattern p = Pattern.compile("(\\d*)([A-Z]?)");
Matcher m = p.matcher(residue);
if (m.matches())
import java.awt.Color;
import java.awt.Graphics;
+import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
*/
public class AlignSeq
{
+ private static final int MAX_NAME_LENGTH = 30;
+
+ private static final int GAP_OPEN_COST = 120;
+
+ private static final int GAP_EXTEND_COST = 20;
+
+ private static final int GAP_INDEX = -1;
+
public static final String PEP = "pep";
public static final String DNA = "dna";
float[][] F;
- int[][] traceback;
+ int[][] traceback; // todo is this actually used?
int[] seq1;
/** DOCUMENT ME!! */
public int seq2start;
- /** DOCUMENT ME!! */
public int seq2end;
int count;
- /** DOCUMENT ME!! */
public float maxscore;
- float pid;
-
int prev = 0;
- int gapOpen = 120;
-
- int gapExtend = 20;
-
StringBuffer output = new StringBuffer();
String type; // AlignSeq.PEP or AlignSeq.DNA
private ScoreMatrix scoreMatrix;
- private static final int GAP_INDEX = -1;
-
/**
* Creates a new AlignSeq object.
*
}
}
- // System.out.println(maxi + " " + maxj + " " + score[maxi][maxj]);
int i = maxi;
int j = maxj;
int trace;
- maxscore = score[i][j] / 10;
+ maxscore = score[i][j] / 10f;
seq1end = maxi + 1;
seq2end = maxj + 1;
/**
* DOCUMENT ME!
*/
- public void printAlignment(java.io.PrintStream os)
+ public void printAlignment(PrintStream os)
{
// TODO: Use original sequence characters rather than re-translated
// characters in output
// Find the biggest id length for formatting purposes
- String s1id = s1.getName(), s2id = s2.getName();
- int maxid = s1.getName().length();
- if (s2.getName().length() > maxid)
- {
- maxid = s2.getName().length();
- }
- if (maxid > 30)
+ String s1id = getAlignedSeq1().getDisplayId(true);
+ String s2id = getAlignedSeq2().getDisplayId(true);
+ int nameLength = Math.max(s1id.length(), s2id.length());
+ if (nameLength > MAX_NAME_LENGTH)
{
- maxid = 30;
+ int truncateBy = nameLength - MAX_NAME_LENGTH;
+ nameLength = MAX_NAME_LENGTH;
// JAL-527 - truncate the sequence ids
- if (s1.getName().length() > maxid)
+ if (s1id.length() > nameLength)
{
- s1id = s1.getName().substring(0, 30);
+ int slashPos = s1id.lastIndexOf('/');
+ s1id = s1id.substring(0, slashPos - truncateBy)
+ + s1id.substring(slashPos);
}
- if (s2.getName().length() > maxid)
+ if (s2id.length() > nameLength)
{
- s2id = s2.getName().substring(0, 30);
+ int slashPos = s2id.lastIndexOf('/');
+ s2id = s2id.substring(0, slashPos - truncateBy)
+ + s2id.substring(slashPos);
}
}
- int len = 72 - maxid - 1;
+ int len = 72 - nameLength - 1;
int nochunks = ((aseq1.length - count) / len)
+ ((aseq1.length - count) % len > 0 ? 1 : 0);
- pid = 0;
+ float pid = 0f;
output.append("Score = ").append(score[maxi][maxj]).append(NEWLINE);
output.append("Length of alignment = ")
.append(String.valueOf(aseq1.length - count)).append(NEWLINE);
output.append("Sequence ");
- output.append(new Format("%" + maxid + "s").form(s1.getName()));
- output.append(" : ").append(String.valueOf(s1.getStart()))
- .append(" - ").append(String.valueOf(s1.getEnd()));
+ Format nameFormat = new Format("%" + nameLength + "s");
+ output.append(nameFormat.form(s1id));
output.append(" (Sequence length = ")
.append(String.valueOf(s1str.length())).append(")")
.append(NEWLINE);
output.append("Sequence ");
- output.append(new Format("%" + maxid + "s").form(s2.getName()));
- output.append(" : ").append(String.valueOf(s2.getStart()))
- .append(" - ").append(String.valueOf(s2.getEnd()));
+ output.append(nameFormat.form(s2id));
output.append(" (Sequence length = ")
.append(String.valueOf(s2str.length())).append(")")
.append(NEWLINE).append(NEWLINE);
for (int j = 0; j < nochunks; j++)
{
// Print the first aligned sequence
- output.append(new Format("%" + (maxid) + "s").form(s1id)).append(" ");
+ output.append(nameFormat.form(s1id)).append(" ");
for (int i = 0; i < len; i++)
{
}
output.append(NEWLINE);
- output.append(new Format("%" + (maxid) + "s").form(" ")).append(" ");
+ output.append(nameFormat.form(" ")).append(" ");
/*
* Print out the match symbols:
pid++;
output.append("|");
}
- else if (type.equals("pep"))
+ else if (PEP.equals(type))
{
if (pam250.getPairwiseScore(c1, c2) > 0)
{
// Now print the second aligned sequence
output = output.append(NEWLINE);
- output = output.append(new Format("%" + (maxid) + "s").form(s2id))
- .append(" ");
+ output = output.append(nameFormat.form(s2id)).append(" ");
for (int i = 0; i < len; i++)
{
}
pid = pid / (aseq1.length - count) * 100;
- output = output.append(new Format("Percentage ID = %2.2f\n").form(pid));
+ output.append(new Format("Percentage ID = %3.2f\n").form(pid));
+ output.append(NEWLINE);
try
{
os.print(output.toString());
public int findTrace(int i, int j)
{
int t = 0;
- // float pairwiseScore = lookup[seq1[i]][seq2[j]];
float pairwiseScore = scoreMatrix.getPairwiseScore(s1str.charAt(i),
s2str.charAt(j));
float max = score[i - 1][j - 1] + (pairwiseScore * 10);
// top left hand element
score[0][0] = scoreMatrix.getPairwiseScore(s1str.charAt(0),
s2str.charAt(0)) * 10;
- E[0][0] = -gapExtend;
+ E[0][0] = -GAP_EXTEND_COST;
F[0][0] = 0;
// Calculate the top row first
for (int j = 1; j < m; j++)
{
// What should these values be? 0 maybe
- E[0][j] = max(score[0][j - 1] - gapOpen, E[0][j - 1] - gapExtend);
- F[0][j] = -gapExtend;
+ E[0][j] = max(score[0][j - 1] - GAP_OPEN_COST, E[0][j - 1] - GAP_EXTEND_COST);
+ F[0][j] = -GAP_EXTEND_COST;
float pairwiseScore = scoreMatrix.getPairwiseScore(s1str.charAt(0),
s2str.charAt(j));
- score[0][j] = max(pairwiseScore * 10, -gapOpen, -gapExtend);
+ score[0][j] = max(pairwiseScore * 10, -GAP_OPEN_COST, -GAP_EXTEND_COST);
traceback[0][j] = 1;
}
// Now do the left hand column
for (int i = 1; i < n; i++)
{
- E[i][0] = -gapOpen;
- F[i][0] = max(score[i - 1][0] - gapOpen, F[i - 1][0] - gapExtend);
+ E[i][0] = -GAP_OPEN_COST;
+ F[i][0] = max(score[i - 1][0] - GAP_OPEN_COST, F[i - 1][0] - GAP_EXTEND_COST);
float pairwiseScore = scoreMatrix.getPairwiseScore(s1str.charAt(i),
s2str.charAt(0));
{
for (int j = 1; j < m; j++)
{
- E[i][j] = max(score[i][j - 1] - gapOpen, E[i][j - 1] - gapExtend);
- F[i][j] = max(score[i - 1][j] - gapOpen, F[i - 1][j] - gapExtend);
+ E[i][j] = max(score[i][j - 1] - GAP_OPEN_COST, E[i][j - 1] - GAP_EXTEND_COST);
+ F[i][j] = max(score[i - 1][j] - GAP_OPEN_COST, F[i - 1][j] - GAP_EXTEND_COST);
float pairwiseScore = scoreMatrix.getPairwiseScore(s1str.charAt(i),
s2str.charAt(j));
/**
* Returns a mapping from dna to protein by inspecting sequence features of
- * type "CDS" on the dna.
+ * type "CDS" on the dna. A mapping is constructed if the total CDS feature
+ * length is 3 times the peptide length (optionally after dropping a trailing
+ * stop codon). This method does not check whether the CDS nucleotide sequence
+ * translates to the peptide sequence.
*
* @param dnaSeq
* @param proteinSeq
List<int[]> ranges = findCdsPositions(dnaSeq);
int mappedDnaLength = MappingUtils.getLength(ranges);
+ /*
+ * if not a whole number of codons, something is wrong,
+ * abort mapping
+ */
+ if (mappedDnaLength % CODON_LENGTH > 0)
+ {
+ return null;
+ }
+
int proteinLength = proteinSeq.getLength();
int proteinStart = proteinSeq.getStart();
int proteinEnd = proteinSeq.getEnd();
if (codesForResidues == (proteinLength + 1))
{
// assuming extra codon is for STOP and not in peptide
+ // todo: check trailing codon is indeed a STOP codon
codesForResidues--;
+ mappedDnaLength -= CODON_LENGTH;
+ MappingUtils.removeEndPositions(CODON_LENGTH, ranges);
}
+
if (codesForResidues == proteinLength)
{
proteinRange.add(new int[] { proteinStart, proteinEnd });
/**
* Returns a list of CDS ranges found (as sequence positions base 1), i.e. of
- * start/end positions of sequence features of type "CDS" (or a sub-type of
+ * [start, end] positions of sequence features of type "CDS" (or a sub-type of
* CDS in the Sequence Ontology). The ranges are sorted into ascending start
* position order, so this method is only valid for linear CDS in the same
* sense as the protein product.
return result;
}
SequenceFeatures.sortFeatures(sfs, true);
- int startPhase = 0;
for (SequenceFeature sf : sfs)
{
*/
int begin = sf.getBegin();
int end = sf.getEnd();
- if (result.isEmpty())
+ if (result.isEmpty() && phase > 0)
{
begin += phase;
if (begin > end)
}
/*
- * remove 'startPhase' positions (usually 0) from the first range
- * so we begin at the start of a complete codon
- */
- if (!result.isEmpty())
- {
- // TODO JAL-2022 correctly model start phase > 0
- result.get(0)[0] += startPhase;
- }
-
- /*
* Finally sort ranges by start position. This avoids a dependency on
* keeping features in order on the sequence (if they are in order anyway,
* the sort will have almost no work to do). The implicit assumption is CDS
package jalview.api;
import jalview.analysis.Conservation;
+import jalview.analysis.TreeModel;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
-import jalview.datamodel.CigarArray;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.ProfilesI;
import jalview.datamodel.SearchResultsI;
void clearSequenceColours();
/**
- * This method returns the visible alignment as text, as seen on the GUI, ie
- * if columns are hidden they will not be returned in the result. Use this for
- * calculating trees, PCA, redundancy etc on views which contain hidden
- * columns.
- *
- * @return String[]
- */
- CigarArray getViewAsCigars(boolean selectedRegionOnly);
-
- /**
* return a compact representation of the current alignment selection to pass
* to an analysis function
*
*
* @return
*/
+ @Override
boolean isProteinFontAsCdna();
/**
*
* @return
*/
+ @Override
void setProteinFontAsCdna(boolean b);
+
+ public abstract TreeModel getCurrentTree();
+
+ public abstract void setCurrentTree(TreeModel tree);
}
*
* @param updateOverview
* - if true, the overview panel will also be updated and repainted
+ * @param updateStructures
+ * - if true then any linked structure views will also be updated
*/
-
- void paintAlignment(boolean updateOverview);
+ void paintAlignment(boolean updateOverview, boolean updateStructures);
/**
* automatically adjust annotation panel height for new annotation whilst
void addFeatureLinks(final SequenceI seq, List<String> links)
{
Menu linkMenu = new Menu(MessageManager.getString("action.link"));
- Map<String, List<String>> linkset = new LinkedHashMap<String, List<String>>();
+ Map<String, List<String>> linkset = new LinkedHashMap<>();
for (String link : links)
{
* Temporary store to hold distinct calcId / type pairs for the tooltip.
* Using TreeMap means calcIds are shown in alphabetical order.
*/
- SortedMap<String, String> tipEntries = new TreeMap<String, String>();
- final Map<SequenceI, List<AlignmentAnnotation>> candidates = new LinkedHashMap<SequenceI, List<AlignmentAnnotation>>();
+ SortedMap<String, String> tipEntries = new TreeMap<>();
+ final Map<SequenceI, List<AlignmentAnnotation>> candidates = new LinkedHashMap<>();
AlignmentI al = this.ap.av.getAlignment();
AlignmentUtils.findAddableReferenceAnnotations(forSequences, tipEntries,
candidates, al);
}
int gSize = sg.getSize();
- List<SequenceI> seqs = new ArrayList<SequenceI>();
- List<SequenceFeature> features = new ArrayList<SequenceFeature>();
+ List<SequenceI> seqs = new ArrayList<>();
+ List<SequenceFeature> features = new ArrayList<>();
for (int i = 0; i < gSize; i++)
{
{
seq.setName(dialog.getName());
seq.setDescription(dialog.getDescription());
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
}
void refresh()
{
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
protected void clustalColour_actionPerformed()
SequenceGroup sg = ap.av.getSelectionGroup();
ap.av.getAlignment().deleteGroup(sg);
ap.av.setSelectionGroup(null);
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
void createGroupMenuItem_actionPerformed()
* the insertion order, which is the order of the annotations on the
* alignment.
*/
- Map<String, List<List<String>>> shownTypes = new LinkedHashMap<String, List<List<String>>>();
- Map<String, List<List<String>>> hiddenTypes = new LinkedHashMap<String, List<List<String>>>();
+ Map<String, List<List<String>>> shownTypes = new LinkedHashMap<>();
+ Map<String, List<List<String>>> hiddenTypes = new LinkedHashMap<>();
AlignmentAnnotationUtils.getShownHiddenTypes(shownTypes, hiddenTypes,
AlignmentAnnotationUtils.asList(annotations), forSequences);
createAlignFrameWindow(embedded);
validate();
alignPanel.adjustAnnotationHeight();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
public AlignViewport getAlignViewport()
{
viewport.featureSettings.refreshTable();
}
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
statusBar.setText(MessageManager
.getString("label.successfully_added_features_alignment"));
}
break;
}
- alignPanel.paintAlignment(true);
+ // TODO: repaint flags set only if the keystroke warrants it
+ alignPanel.paintAlignment(true, true);
}
/**
{
applyAutoAnnotationSettings_actionPerformed();
}
- alignPanel.paintAlignment(true);
+ // TODO: repaint flags set only if warranted
+ alignPanel.paintAlignment(true, true);
}
/**
else if (source == invertColSel)
{
viewport.invertColumnSelection();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
viewport.sendSelection();
}
else if (source == remove2LeftMenuItem)
else if (source == showColumns)
{
viewport.showAllHiddenColumns();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
else if (source == showSeqs)
{
viewport.showAllHiddenSeqs();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
// uncomment if we want to slave sequence selections in split frame
// viewport.sendSelection();
}
else if (source == hideColumns)
{
viewport.hideSelectedColumns();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
else if (source == hideSequences
&& viewport.getSelectionGroup() != null)
{
viewport.hideAllSelectedSeqs();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
// uncomment if we want to slave sequence selections in split frame
// viewport.sendSelection();
}
else if (source == hideAllButSelection)
{
toggleHiddenRegions(false, false);
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
else if (source == hideAllSelection)
viewport.expandColSelection(sg, false);
viewport.hideAllSelectedSeqs();
viewport.hideSelectedColumns();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
else if (source == showAllHidden)
{
viewport.showAllHiddenColumns();
viewport.showAllHiddenSeqs();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
else if (source == showGroupConsensus)
{
System.exit(0);
}
- else
+
+ viewport = null;
+ if (alignPanel != null && alignPanel.overviewPanel != null)
{
+ alignPanel.overviewPanel.dispose();
}
- viewport = null;
alignPanel = null;
this.dispose();
}
}
viewport.getAlignment().moveSelectedSequencesByOne(sg,
up ? null : viewport.getHiddenRepSequences(), up);
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
/*
* Also move cDNA/protein complement sequences
viewport, complement);
complement.getAlignment().moveSelectedSequencesByOne(mappedSelection,
up ? null : complement.getHiddenRepSequences(), up);
- getSplitFrame().getComplement(this).alignPanel.paintAlignment(true);
+ getSplitFrame().getComplement(this).alignPanel.paintAlignment(true,
+ false);
}
}
{
PaintRefresher.Refresh(this, viewport.getSequenceSetId());
alignPanel.updateAnnotation();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
}
// JAL-2034 - should delegate to
// alignPanel to decide if overview needs
// updating.
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
viewport.sendSelection();
}
// JAL-2034 - should delegate to
// alignPanel to decide if overview needs
// updating.
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
viewport.sendSelection();
}
public void invertColSel_actionPerformed()
{
viewport.invertColumnSelection();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
viewport.sendSelection();
}
{
viewport.setShowJVSuffix(seqLimits.getState());
alignPanel.fontChanged();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
protected void colourTextMenuItem_actionPerformed()
{
viewport.setColourText(colourTextMenuItem.getState());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
protected void displayNonconservedMenuItem_actionPerformed()
{
viewport.setShowUnconserved(displayNonconservedMenuItem.getState());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
protected void wrapMenuItem_actionPerformed()
scaleAbove.setEnabled(wrapMenuItem.getState());
scaleLeft.setEnabled(wrapMenuItem.getState());
scaleRight.setEnabled(wrapMenuItem.getState());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
public void overviewMenuItem_actionPerformed()
{
viewport.setGlobalColourScheme(cs);
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
protected void modifyPID_actionPerformed()
addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
public void sortIDMenuItem_actionPerformed()
AlignmentSorter.sortByID(viewport.getAlignment());
addHistoryItem(
new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
public void sortLengthMenuItem_actionPerformed()
AlignmentSorter.sortByLength(viewport.getAlignment());
addHistoryItem(new OrderCommand("Length Sort", oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
public void sortGroupMenuItem_actionPerformed()
AlignmentSorter.sortByGroup(viewport.getAlignment());
addHistoryItem(new OrderCommand("Group Sort", oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
current.insertCharAt(Width - 1, viewport.getGapCharacter());
}
}
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
if ((viewport.getSelectionGroup() != null
current.insertCharAt(Width - 1, viewport.getGapCharacter());
}
}
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
addHistoryItem(new OrderCommand(MessageManager
.formatMessage("label.order_by_params", new String[]
{ title }), oldOrder, viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
/**
addHistoryItem(new OrderCommand(undoname, oldOrder,
viewport.getAlignment()));
}
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
return true;
}
{
// register the association(s) and quit, don't create any windows.
if (StructureSelectionManager.getStructureSelectionManager(applet)
- .setMapping(seqs, chains, pdb.getFile(), protocol) == null)
+ .setMapping(seqs, chains, pdb.getFile(), protocol, null) == null)
{
System.err.println("Failed to map " + pdb.getFile() + " ("
+ protocol + ") to any sequences");
*/
package jalview.appletgui;
-import jalview.analysis.TreeModel;
import jalview.api.AlignViewportI;
import jalview.api.FeatureSettingsModelI;
import jalview.bin.JalviewLite;
boolean validCharWidth = true;
- TreeModel currentTree = null;
-
public jalview.bin.JalviewLite applet;
boolean MAC = false;
private AnnotationColumnChooser annotationColumnSelectionState;
- @Override
- public void finalize()
- {
- applet = null;
- quality = null;
- alignment = null;
- colSel = null;
- }
-
public AlignViewport(AlignmentI al, JalviewLite applet)
{
super(al);
ranges.setEndSeq(height / getCharHeight());
}
- public void setCurrentTree(TreeModel tree)
- {
- currentTree = tree;
- }
-
- public TreeModel getCurrentTree()
- {
- return currentTree;
- }
-
boolean centreColumnLabels;
public boolean getCentreColumnLabels()
// this value is set false when selection area being dragged
boolean fastPaint = true;
- @Override
- public void finalize() throws Throwable
- {
- alignFrame = null;
- av = null;
- vpRanges = null;
- seqPanel = null;
- seqPanelHolder = null;
- sequenceHolderPanel = null;
- scalePanel = null;
- scalePanelHolder = null;
- annotationPanel = null;
- annotationPanelHolder = null;
- annotationSpaceFillerHolder = null;
- super.finalize();
- }
-
public AlignmentPanel(AlignFrame af, final AlignViewport av)
{
try
vpRanges.scrollToWrappedVisible(start);
}
- paintAlignment(redrawOverview);
+ paintAlignment(redrawOverview, false);
return true;
}
apvscroll.addNotify();
hscroll.addNotify();
validate();
- paintAlignment(true);
+ paintAlignment(true, false);
}
/**
* Repaint the alignment and annotations, and, optionally, any overview window
*/
@Override
- public void paintAlignment(boolean updateOverview)
+ public void paintAlignment(boolean updateOverview,
+ boolean updateStructures)
{
final AnnotationSorter sorter = new AnnotationSorter(getAlignment(),
av.isShowAutocalculatedAbove());
av.getSortAnnotationsBy());
repaint();
- if (updateOverview)
+ if (updateStructures)
{
- // TODO: determine if this paintAlignment changed structure colours
jalview.structure.StructureSelectionManager
.getStructureSelectionManager(av.applet)
.sequenceColoursChanged(this);
-
+ }
+ if (updateOverview)
+ {
if (overviewPanel != null)
{
overviewPanel.updateOverviewImage();
oldcs = av.getGlobalColourScheme();
if (av.getAlignment().getGroups() != null)
{
- oldgroupColours = new HashMap<SequenceGroup, ColourSchemeI>();
+ oldgroupColours = new HashMap<>();
for (SequenceGroup sg : ap.av.getAlignment().getGroups())
{
oldgroupColours.put(sg, sg.getColourScheme());
// TODO remove duplication with gui.AnnotationRowFilter
// TODO add 'per sequence only' option / parameter
- annotationLabels = new HashMap<AlignmentAnnotation, String>();
- Vector<String> list = new Vector<String>();
+ annotationLabels = new HashMap<>();
+ Vector<String> list = new Vector<>();
AlignmentAnnotation[] anns = av.getAlignment().getAlignmentAnnotation();
if (anns == null)
{
else if (evt.getSource() == cancel)
{
reset();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
frame.setVisible(false);
}
}
currentAnnotation.threshold.value = slider.getValue() / 1000f;
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
}
// update colours in linked windows
ap.alignmentChanged();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
void reset()
sg.setColourScheme(oldgroupColours.get(sg));
}
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
@Override
@Override
public void mouseReleased(MouseEvent evt)
{
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
@Override
av.getAlignment().setHiddenColumns(oldHidden);
}
av.sendSelection();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
}
sliderDragging = false;
valueChanged(true);
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
});
}
if (slider.isEnabled())
{
getCurrentAnnotation().threshold.value = slider.getValue() / 1000f;
- updateView();
- ap.paintAlignment(false);
+ updateView(); // this also calls paintAlignment(true,true)
}
}
filterParams = null;
av.setAnnotationColumnSelectionState(this);
av.sendSelection();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
public HiddenColumns getOldHiddenColumns()
ap.annotationPanel.adjustPanelHeight();
setSize(getSize().width, ap.annotationPanel.getSize().height);
ap.validate();
- ap.paintAlignment(true);
+ // TODO: only paint if we needed to
+ ap.paintAlignment(true, true);
}
boolean editLabelDescription(AlignmentAnnotation annotation)
{
ap.av.setIgnoreGapsConsensus(cbmi.getState(), ap);
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
});
popup.add(cbmi);
}
}
}
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
ap.av.sendSelection();
}
sg.addSequence(aa[selectedRow].sequenceRef, false);
}
ap.av.setSelectionGroup(sg);
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
ap.av.sendSelection();
}
graphStretchY = evt.getY();
av.calcPanelHeight();
needValidating = true;
- ap.paintAlignment(true);
+ // TODO: only update overview visible geometry
+ ap.paintAlignment(true, false);
}
else
{
public void cancel_actionPerformed(ActionEvent e)
{
reset();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
frame.setVisible(false);
}
AlignmentPanel ap;
- List<AlignmentPanel> _aps = new ArrayList<AlignmentPanel>(); // remove? never
+ List<AlignmentPanel> _aps = new ArrayList<>(); // remove? never
// added to
String fileLoadingError;
{
reader = StructureSelectionManager
.getStructureSelectionManager(ap.av.applet)
- .setMapping(seq, chains, pdbentry.getFile(), protocol);
+ .setMapping(seq, chains, pdbentry.getFile(), protocol, null);
// PROMPT USER HERE TO ADD TO NEW OR EXISTING VIEW?
// FOR NOW, LETS JUST OPEN A NEW WINDOW
}
void centerViewer()
{
- Vector<String> toshow = new Vector<String>();
+ Vector<String> toshow = new Vector<>();
for (int i = 0; i < chainMenu.getItemCount(); i++)
{
if (chainMenu.getItem(i) instanceof CheckboxMenuItem)
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
import jalview.ext.jmol.JalviewJmolBinding;
+import jalview.gui.IProgressIndicator;
import jalview.io.DataSourceType;
import jalview.structure.StructureSelectionManager;
// TODO Auto-generated method stub
return null;
}
+
+ @Override
+ protected IProgressIndicator getIProgressIndicator()
+ {
+ // no progress indicators on the applet
+ return null;
+ }
}
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
import jalview.ext.jmol.JalviewJmolBinding;
+import jalview.gui.IProgressIndicator;
import jalview.io.DataSourceType;
import java.awt.Container;
}
@Override
+ protected IProgressIndicator getIProgressIndicator()
+ {
+ // no progress indicators on applet (could access javascript for this)
+ return null;
+ }
+
+ @Override
public void updateColours(Object source)
{
}
}
+
@Override
public SequenceRenderer getSequenceRenderer(AlignmentViewPanel alignment)
{
@Override
public void refreshPdbEntries()
{
- List<PDBEntry> pdbe = new ArrayList<PDBEntry>();
- List<String> fileids = new ArrayList<String>();
+ List<PDBEntry> pdbe = new ArrayList<>();
+ List<String> fileids = new ArrayList<>();
SequenceI[] sq = ap.av.getAlignment().getSequencesArray();
for (int s = 0; s < sq.length; s++)
{
}
// findAllFeatures();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
return true;
}
// Group selection states
void resetTable(boolean groupsChanged)
{
- List<String> displayableTypes = new ArrayList<String>();
- Set<String> foundGroups = new HashSet<String>();
+ List<String> displayableTypes = new ArrayList<>();
+ Set<String> foundGroups = new HashSet<>();
AlignmentI alignment = av.getAlignment();
* and keep track of which groups are visible
*/
Set<String> groups = seq.getFeatures().getFeatureGroups(true);
- Set<String> visibleGroups = new HashSet<String>();
+ Set<String> visibleGroups = new HashSet<>();
for (String group : groups)
{
// if (group == null || fr.checkGroupVisibility(group, true))
fr.setFeaturePriority(data);
- ap.paintAlignment(updateOverview);
+ ap.paintAlignment(updateOverview, updateOverview);
}
MyCheckbox selectedCheck;
{
featurePanel.removeAll();
resetTable(false);
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
@Override
public void adjustmentValueChanged(AdjustmentEvent evt)
{
fr.setTransparency((100 - transparency.getValue()) / 100f);
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
class MyCheckbox extends Checkbox
{
ap.av.setCharWidth(oldCharWidth);
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, false);
}
else if (tp != null)
{
// TODO: add in group link parameter
// make a list of label,url pairs
- HashMap<String, String> urlList = new HashMap<String, String>();
+ HashMap<String, String> urlList = new HashMap<>();
if (viewport.applet != null)
{
for (int i = 1; i < 10; i++)
}
lastid = seq;
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
}
@Override
}
else
{
- nlinks = new ArrayList<String>();
+ nlinks = new ArrayList<>();
}
for (SequenceFeature sf : sq.getFeatures().getNonPositionalFeatures())
selectSeq(seq);
}
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
}
void selectSeq(int seq)
running = false;
}
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
try
{
Thread.sleep(100);
import java.awt.CheckboxMenuItem;
import java.awt.Cursor;
import java.awt.Dimension;
+import java.awt.Frame;
import java.awt.Panel;
import java.awt.PopupMenu;
import java.awt.event.ComponentAdapter;
av.getAlignment().getHiddenSequences(),
av.getAlignment().getHiddenColumns());
}
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
}
try
{
av.getRanges().removePropertyChangeListener(this);
+ Frame parent = (Frame) getParent();
+ parent.dispose();
+ parent.setVisible(false);
} finally
{
av = null;
import jalview.datamodel.SequenceI;
import java.awt.Component;
-import java.util.Enumeration;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
return;
}
- for (String id : components.keySet())
+ Iterator<String> it = components.keySet().iterator();
+ while (it.hasNext())
{
- Vector<Component> comps = components.get(id);
+ Vector<Component> comps = components.get(it.next());
comps.removeElement(comp);
- if (comps.size() == 0)
+ if (comps.isEmpty())
{
- components.remove(id);
+ it.remove();
}
}
}
return;
}
- Enumeration<Component> e = comps.elements();
- while (e.hasMoreElements())
+ Iterator<Component> it = comps.iterator();
+ while (it.hasNext())
{
- comp = e.nextElement();
+ comp = it.next();
if (comp == source)
{
if (!comp.isValid())
{
- comps.removeElement(comp);
+ it.remove();
}
else if (validateSequences && comp instanceof AlignmentPanel
&& source instanceof AlignmentPanel)
float value = slider.getValue();
- List<SequenceI> redundantSequences = new ArrayList<SequenceI>();
+ List<SequenceI> redundantSequences = new ArrayList<>();
for (int i = 0; i < redundancy.length; i++)
{
if (value <= redundancy[i])
ap.av.getAlignment().getSequences());
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
if (historyList.size() == 0)
{
sg.setStartRes(min);
sg.setEndRes(max);
}
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
av.sendSelection();
}
{
av.showColumn(reveal[0]);
reveal = null;
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
av.sendSelection();
}
});
{
av.showAllHiddenColumns();
reveal = null;
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
av.sendSelection();
}
});
av.setSelectionGroup(null);
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
av.sendSelection();
}
});
if (!stretchingGroup)
{
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
return;
}
}
stretchingGroup = false;
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
av.sendSelection();
}
{
stretchingGroup = true;
cs.stretchGroup(res, sg, min, max);
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
}
sg.addSequence(sequence, false);
av.setSelectionGroup(sg);
}
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
av.sendSelection();
}
* alignment column
* @param seq
* index of sequence in alignment
- * @return position of column in sequence or -1 if at gap
*/
void setStatusMessage(SequenceI sequence, int column, int seq)
{
lastMousePress = evt.getPoint();
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
ap.annotationPanel.image = null;
return;
}
{
if (links == null)
{
- links = new Vector<String>();
+ links = new Vector<>();
}
links.addAll(sf.links);
}
}
}
PaintRefresher.Refresh(ap, av.getSequenceSetId());
- ap.paintAlignment(needOverviewUpdate);
+ ap.paintAlignment(needOverviewUpdate, needOverviewUpdate);
needOverviewUpdate = false;
changeEndRes = false;
changeStartRes = false;
@Override
public void mouseReleased(MouseEvent evt)
{
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
@Override
createSplitFrameWindow(embedded, applet);
validate();
topFrame.alignPanel.adjustAnnotationHeight();
- topFrame.alignPanel.paintAlignment(true);
+ topFrame.alignPanel.paintAlignment(true, true);
bottomFrame.alignPanel.adjustAnnotationHeight();
- bottomFrame.alignPanel.paintAlignment(true);
+ bottomFrame.alignPanel.paintAlignment(true, true);
}
/**
Button selectedButton;
- Vector<Color> oldColours = new Vector<Color>();
+ Vector<Color> oldColours = new Vector<>();
ColourSchemeI oldColourScheme;
ap.av.isIgnoreGapsConsensus());
}
ap.seqPanel.seqCanvas.img = null;
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
else if (jmol != null)
{
{
ap.av.setGlobalColourScheme(oldColourScheme);
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
frame.setVisible(false);
*/
private AlignViewControllerGuiI avcg;
- @Override
- protected void finalize() throws Throwable
- {
- viewport = null;
- alignPanel = null;
- avcg = null;
- };
-
public AlignViewController(AlignViewControllerGuiI alignFrame,
AlignViewportI viewport, AlignmentViewPanel alignPanel)
{
if (changed)
{
viewport.setColumnSelection(cs);
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
int columnCount = invert
? (sqcol.getEndRes() - sqcol.getStartRes() + 1)
- bs.cardinality()
if (!extendCurrent)
{
cs.clear();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
}
return false;
AlignmentSorter.sortByFeature(typ, gps, start, stop, al, method);
avcg.addHistoryItem(new OrderCommand(methodText, oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
{
avcg.getFeatureSettingsUI().discoverAllFeatureData();
}
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
return featuresFile;
if (changed)
{
viewport.setColumnSelection(cs);
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
int columnCount = invert
? (sqcol.getEndRes() - sqcol.getStartRes() + 1)
- bs.cardinality()
if (!extendCurrent)
{
cs.clear();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
}
return false;
private boolean isrna;
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#finalize()
- */
- @Override
- protected void finalize() throws Throwable
- {
- sequenceRef = null;
- groupRef = null;
- super.finalize();
- }
-
public static int getGraphValueFromString(String string)
{
if (string.equalsIgnoreCase("BAR_GRAPH"))
to = tto;
}
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#finalize()
- */
- @Override
- protected void finalize() throws Throwable
- {
- map = null;
- to = null;
- super.finalize();
- }
-
/**
* Returns an iterator which can serve up the aligned codon column positions
* and their corresponding peptide products
import java.util.ListIterator;
import java.util.Vector;
-import com.stevesoft.pat.Regex;
-
import fr.orsay.lri.varna.models.rna.RNA;
/**
*/
public class Sequence extends ASequence implements SequenceI
{
- private static final Regex limitrx = new Regex(
- "[/][0-9]{1,}[-][0-9]{1,}$");
-
- private static final Regex endrx = new Regex("[0-9]{1,}$");
-
SequenceI datasetSequence;
String name;
*/
int index = -1;
- private SequenceFeatures sequenceFeatureStore;
+ private SequenceFeaturesI sequenceFeatureStore;
/*
* A cursor holding the approximate current view position to the sequence,
checkValidRange();
}
+ /**
+ * If 'name' ends in /i-j, where i >= j > 0 are integers, extracts i and j as
+ * start and end respectively and removes the suffix from the name
+ */
void parseId()
{
if (name == null)
"POSSIBLE IMPLEMENTATION ERROR: null sequence name passed to constructor.");
name = "";
}
- // Does sequence have the /start-end signature?
- if (limitrx.search(name))
+ int slashPos = name.lastIndexOf('/');
+ if (slashPos > -1 && slashPos < name.length() - 1)
{
- name = limitrx.left();
- endrx.search(limitrx.stringMatched());
- setStart(Integer.parseInt(limitrx.stringMatched().substring(1,
- endrx.matchedFrom() - 1)));
- setEnd(Integer.parseInt(endrx.stringMatched()));
+ String suffix = name.substring(slashPos + 1);
+ String[] range = suffix.split("-");
+ if (range.length == 2)
+ {
+ try
+ {
+ int from = Integer.valueOf(range[0]);
+ int to = Integer.valueOf(range[1]);
+ if (from > 0 && to >= from)
+ {
+ name = name.substring(0, slashPos);
+ setStart(from);
+ setEnd(to);
+ checkValidRange();
+ }
+ } catch (NumberFormatException e)
+ {
+ // leave name unchanged if suffix is invalid
+ }
+ }
}
}
+ /**
+ * Ensures that 'end' is not before the end of the sequence, that is,
+ * (end-start+1) is at least as long as the count of ungapped positions. Note
+ * that end is permitted to be beyond the end of the sequence data.
+ */
void checkValidRange()
{
// Note: JAL-774 :
int endRes = 0;
for (int j = 0; j < sequence.length; j++)
{
- if (!jalview.util.Comparison.isGap(sequence[j]))
+ if (!Comparison.isGap(sequence[j]))
{
endRes++;
}
}
/**
- * DOCUMENT ME!
+ * Sets the sequence name. If the name ends in /start-end, then the start-end
+ * values are parsed out and set, and the suffix is removed from the name.
*
- * @param name
- * DOCUMENT ME!
+ * @param theName
*/
@Override
- public void setName(String name)
+ public void setName(String theName)
{
- this.name = name;
+ this.name = theName;
this.parseId();
}
* and we may have included adjacent or enclosing features;
* remove any that are not enclosing, non-contact features
*/
- if (endPos > this.end || Comparison.isGap(sequence[toColumn - 1]))
+ boolean endColumnIsGapped = toColumn > 0 && toColumn <= sequence.length
+ && Comparison.isGap(sequence[toColumn - 1]);
+ if (endPos > this.end || endColumnIsGapped)
{
ListIterator<SequenceFeature> it = result.listIterator();
while (it.hasNext())
}
Set<String> featureTypes = getFeatureTypes(ontologyTerm);
+ if (featureTypes.isEmpty())
+ {
+ /*
+ * no features of the specified type or any sub-type
+ */
+ return new ArrayList<>();
+ }
+
return getAllFeatures(featureTypes.toArray(new String[featureTypes
.size()]));
}
}
/**
- * Converts a query, which may contain one or more gene or transcript
- * identifiers, into a non-redundant list of gene identifiers.
+ * Converts a query, which may contain one or more gene, transcript, or
+ * external (to Ensembl) identifiers, into a non-redundant list of gene
+ * identifiers.
*
* @param accessions
* @return
for (String acc : accessions.split(getAccessionSeparator()))
{
- if (isGeneIdentifier(acc))
- {
- if (!geneIds.contains(acc))
- {
- geneIds.add(acc);
- }
- }
-
/*
- * if given a transcript id, look up its gene parent
+ * First try lookup as an Ensembl (gene or transcript) identifier
*/
- else if (isTranscriptIdentifier(acc))
+ String geneId = new EnsemblLookup(getDomain()).getGeneId(acc);
+ if (geneId != null)
{
- String geneId = new EnsemblLookup(getDomain()).getParent(acc);
- if (geneId != null && !geneIds.contains(geneId))
+ if (!geneIds.contains(geneId))
{
geneIds.add(geneId);
}
}
- else if (isProteinIdentifier(acc))
- {
- String tscriptId = new EnsemblLookup(getDomain()).getParent(acc);
- if (tscriptId != null)
- {
- String geneId = new EnsemblLookup(getDomain())
- .getParent(tscriptId);
-
- if (geneId != null && !geneIds.contains(geneId))
- {
- geneIds.add(geneId);
- }
- }
- // NOTE - acc is lost if it resembles an ENS.+ ID but isn't actually
- // resolving to one... e.g. ENSMICP00000009241
- }
- /*
- * if given a gene or other external name, lookup and fetch
- * the corresponding gene for all model organisms
- */
else
{
+ /*
+ * if given a gene or other external name, lookup and fetch
+ * the corresponding gene for all model organisms
+ */
List<String> ids = new EnsemblSymbol(getDomain(), getDbSource(),
- getDbVersion()).getIds(acc);
- for (String geneId : ids)
+ getDbVersion()).getGeneIds(acc);
+ for (String id : ids)
{
- if (!geneIds.contains(geneId))
+ if (!geneIds.contains(id))
{
- geneIds.add(geneId);
+ geneIds.add(id);
}
}
}
}
/**
- * Attempts to get Ensembl stable identifiers for model organisms for a gene
- * name by calling the xrefs symbol REST service to resolve the gene name.
- *
- * @param query
- * @return
- */
- protected String getGeneIdentifiersForName(String query)
- {
- List<String> ids = new EnsemblSymbol(getDomain(), getDbSource(),
- getDbVersion()).getIds(query);
- if (ids != null)
- {
- for (String id : ids)
- {
- if (isGeneIdentifier(id))
- {
- return id;
- }
- }
- }
- return null;
- }
-
- /**
* Constructs all transcripts for the gene, as identified by "transcript"
* features whose Parent is the requested gene. The coding transcript
* sequences (i.e. with introns omitted) are added to the alignment.
/**
* Returns a list of the transcript features on the sequence whose Parent is
* the gene for the accession id.
+ * <p>
+ * Transcript features are those of type "transcript", or any of its sub-types
+ * in the Sequence Ontology e.g. "mRNA", "processed_transcript". We also
+ * include "NMD_transcript_variant", because this type behaves like a
+ * transcript identifier in Ensembl, although strictly speaking it is not in
+ * the SO.
*
* @param accId
* @param geneSequence
List<SequenceFeature> transcriptFeatures = new ArrayList<SequenceFeature>();
String parentIdentifier = GENE_PREFIX + accId;
- // todo optimise here by transcript type!
+
List<SequenceFeature> sfs = geneSequence.getFeatures()
- .getPositionalFeatures();
+ .getFeaturesByOntology(SequenceOntologyI.TRANSCRIPT);
+ sfs.addAll(geneSequence.getFeatures().getPositionalFeatures(
+ SequenceOntologyI.NMD_TRANSCRIPT_VARIANT));
for (SequenceFeature sf : sfs)
{
- if (isTranscript(sf.getType()))
+ String parent = (String) sf.getValue(PARENT);
+ if (parentIdentifier.equals(parent))
{
- String parent = (String) sf.getValue(PARENT);
- if (parentIdentifier.equals(parent))
- {
- transcriptFeatures.add(sf);
- }
+ transcriptFeatures.add(sf);
}
}
}
@Override
- public boolean isGeneIdentifier(String query)
- {
- return true;
- }
-
- @Override
public String getDbName()
{
return "EnsemblGenomes";
}
+ private String Wrong[];
@Override
public String getTestQuery()
{
// flag set to true if REST major version is not the one expected
boolean restMajorVersionMismatch;
- /*
- * absolute time to wait till if we overloaded the REST service
- */
- long retryAfter;
-
/**
* Constructor given expected REST version number e.g 4.5 or 3.4.3
*
public class EnsemblLookup extends EnsemblRestClient
{
+ private static final String OBJECT_TYPE_TRANSLATION = "Translation";
+ private static final String PARENT = "Parent";
+ private static final String OBJECT_TYPE_TRANSCRIPT = "Transcript";
+ private static final String ID = "id";
+ private static final String OBJECT_TYPE_GENE = "Gene";
+ private static final String OBJECT_TYPE = "object_type";
+
/**
* Default constructor (to use rest.ensembl.org)
*/
protected URL getUrl(String identifier)
{
String url = getDomain() + "/lookup/id/" + identifier
- + "?content-type=application/json";
+ + CONTENT_TYPE_JSON;
try
{
return new URL(url);
* @param identifier
* @return
*/
- public String getParent(String identifier)
+ public String getGeneId(String identifier)
{
List<String> ids = Arrays.asList(new String[] { identifier });
{
br = getHttpResponse(url, ids);
}
- return (parseResponse(br));
+ return br == null ? null : parseResponse(br);
} catch (IOException e)
{
// ignore
}
/**
- * Parses "Parent" from the JSON response and returns the value, or null if
- * not found
+ * Parses the JSON response and returns the gene identifier, or null if not
+ * found. If the returned object_type is Gene, returns the id, if Transcript
+ * returns the Parent. If it is Translation (peptide identifier), then the
+ * Parent is the transcript identifier, so we redo the search with this value.
*
* @param br
* @return
*/
protected String parseResponse(BufferedReader br) throws IOException
{
- String parent = null;
+ String geneId = null;
JSONParser jp = new JSONParser();
try
{
JSONObject val = (JSONObject) jp.parse(br);
- parent = val.get("Parent").toString();
+ String type = val.get(OBJECT_TYPE).toString();
+ if (OBJECT_TYPE_GENE.equalsIgnoreCase(type))
+ {
+ geneId = val.get(ID).toString();
+ }
+ else if (OBJECT_TYPE_TRANSCRIPT.equalsIgnoreCase(type))
+ {
+ geneId = val.get(PARENT).toString();
+ }
+ else if (OBJECT_TYPE_TRANSLATION.equalsIgnoreCase(type))
+ {
+ String transcriptId = val.get(PARENT).toString();
+ try
+ {
+ geneId = getGeneId(transcriptId);
+ } catch (StackOverflowError e)
+ {
+ /*
+ * unlikely data condition error!
+ */
+ System.err
+ .println("** Ensembl lookup "
+ + getUrl(transcriptId).toString()
+ + " looping on Parent!");
+ }
+ }
} catch (ParseException e)
{
// ignore
}
- return parent;
+ return geneId;
}
}
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceFeature;
-import java.util.List;
-
import com.stevesoft.pat.Regex;
/**
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
+import java.net.ProtocolException;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
-import com.stevesoft.pat.Regex;
-
/**
* Base class for Ensembl REST service clients
*
private static final int CONNECT_TIMEOUT_MS = 10 * 1000; // 10 seconds
+ private static final int MAX_RETRIES = 3;
+
+ private static final int HTTP_OK = 200;
+
+ private static final int HTTP_OVERLOAD = 429;
+
/*
* update these constants when Jalview has been checked / updated for
* changes to Ensembl REST API (ref JAL-2105)
* @see https://github.com/Ensembl/ensembl-rest/wiki/Change-log
* @see http://rest.ensembl.org/info/rest?content-type=application/json
*/
- private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "5.0";
+ private static final String LATEST_ENSEMBLGENOMES_REST_VERSION = "6.0";
- private static final String LATEST_ENSEMBL_REST_VERSION = "5.0";
+ private static final String LATEST_ENSEMBL_REST_VERSION = "6.1";
private static final String REST_CHANGE_LOG = "https://github.com/Ensembl/ensembl-rest/wiki/Change-log";
private final static long VERSION_RETEST_INTERVAL = 1000L * 3600; // 1 hr
- private static final Regex PROTEIN_REGEX = new Regex(
- "(ENS)([A-Z]{3}|)P[0-9]{11}$");
-
- private static final Regex TRANSCRIPT_REGEX = new Regex(
- "(ENS)([A-Z]{3}|)T[0-9]{11}$");
-
- private static final Regex GENE_REGEX = new Regex(
- "(ENS)([A-Z]{3}|)G[0-9]{11}$");
+ protected static final String CONTENT_TYPE_JSON = "?content-type=application/json";
static
{
- domainData = new HashMap<String, EnsemblInfo>();
+ domainData = new HashMap<>();
domainData.put(ENSEMBL_REST,
new EnsemblInfo(ENSEMBL_REST, LATEST_ENSEMBL_REST_VERSION));
domainData.put(ENSEMBL_GENOMES_REST, new EnsemblInfo(
setDomain(d);
}
- /**
- * Answers true if the query matches the regular expression pattern for an
- * Ensembl transcript stable identifier
- *
- * @param query
- * @return
- */
- public boolean isTranscriptIdentifier(String query)
- {
- return query == null ? false : TRANSCRIPT_REGEX.search(query);
- }
-
- /**
- * Answers true if the query matches the regular expression pattern for an
- * Ensembl protein stable identifier
- *
- * @param query
- * @return
- */
- public boolean isProteinIdentifier(String query)
- {
- return query == null ? false : PROTEIN_REGEX.search(query);
- }
-
- /**
- * Answers true if the query matches the regular expression pattern for an
- * Ensembl gene stable identifier
- *
- * @param query
- * @return
- */
- public boolean isGeneIdentifier(String query)
- {
- return query == null ? false : GENE_REGEX.search(query);
- }
-
@Override
public boolean queryInProgress()
{
* @see http://rest.ensembl.org/documentation/info/ping
* @return
*/
- private boolean checkEnsembl()
+ boolean checkEnsembl()
{
BufferedReader br = null;
try
{
// note this format works for both ensembl and ensemblgenomes
// info/ping.json works for ensembl only (March 2016)
- URL ping = new URL(
- getDomain() + "/info/ping?content-type=application/json");
+ URL ping = new URL(getDomain() + "/info/ping" + CONTENT_TYPE_JSON);
/*
* expect {"ping":1} if ok
* if ping takes more than 2 seconds to respond, treat as if unavailable
*/
br = getHttpResponse(ping, null, 2 * 1000);
+ if (br == null)
+ {
+ // error reponse status
+ return false;
+ }
JSONParser jp = new JSONParser();
JSONObject val = (JSONObject) jp.parse(br);
String pingString = val.get("ping").toString();
}
/**
- * Writes the HTTP request and gets the response as a reader.
+ * Sends the HTTP request and gets the response as a reader
*
* @param url
* @param ids
protected BufferedReader getHttpResponse(URL url, List<String> ids,
int readTimeout) throws IOException
{
- // long now = System.currentTimeMillis();
+ int retriesLeft = MAX_RETRIES;
+ HttpURLConnection connection = null;
+ int responseCode = 0;
+
+ while (retriesLeft > 0)
+ {
+ connection = tryConnection(url, ids, readTimeout);
+ responseCode = connection.getResponseCode();
+ if (responseCode == HTTP_OVERLOAD) // 429
+ {
+ retriesLeft--;
+ checkRetryAfter(connection);
+ }
+ else
+ {
+ retriesLeft = 0;
+ }
+ }
+ if (responseCode != HTTP_OK) // 200
+ {
+ /*
+ * note: a GET request for an invalid id returns an error code e.g. 415
+ * but POST request returns 200 and an empty Fasta response
+ */
+ System.err.println("Response code " + responseCode + " for " + url);
+ return null;
+ }
+
+ InputStream response = connection.getInputStream();
+
+ // System.out.println(getClass().getName() + " took "
+ // + (System.currentTimeMillis() - now) + "ms to fetch");
+
+ BufferedReader reader = null;
+ reader = new BufferedReader(new InputStreamReader(response, "UTF-8"));
+ return reader;
+ }
+
+ /**
+ * @param url
+ * @param ids
+ * @param readTimeout
+ * @return
+ * @throws IOException
+ * @throws ProtocolException
+ */
+ protected HttpURLConnection tryConnection(URL url, List<String> ids,
+ int readTimeout) throws IOException, ProtocolException
+ {
+ // System.out.println(System.currentTimeMillis() + " " + url);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
/*
{
writePostBody(connection, ids);
}
-
- int responseCode = connection.getResponseCode();
-
- if (responseCode != 200)
- {
- /*
- * note: a GET request for an invalid id returns an error code e.g. 415
- * but POST request returns 200 and an empty Fasta response
- */
- System.err.println("Response code " + responseCode + " for " + url);
- return null;
- }
- // get content
- InputStream response = connection.getInputStream();
-
- // System.out.println(getClass().getName() + " took "
- // + (System.currentTimeMillis() - now) + "ms to fetch");
-
- checkRateLimits(connection);
-
- BufferedReader reader = null;
- reader = new BufferedReader(new InputStreamReader(response, "UTF-8"));
- return reader;
+ return connection;
}
/**
- * Inspect response headers for any sign of server overload and respect any
- * 'retry-after' directive
+ * Inspects response headers for a 'retry-after' directive, and waits for the
+ * directed period (if less than 10 seconds)
*
* @see https://github.com/Ensembl/ensembl-rest/wiki/Rate-Limits
* @param connection
*/
- void checkRateLimits(HttpURLConnection connection)
+ void checkRetryAfter(HttpURLConnection connection)
{
- // number of requests allowed per time interval:
- String limit = connection.getHeaderField("X-RateLimit-Limit");
- // length of quota time interval in seconds:
- // String period = connection.getHeaderField("X-RateLimit-Period");
- // seconds remaining until usage quota is reset:
- String reset = connection.getHeaderField("X-RateLimit-Reset");
- // number of requests remaining from quota for current period:
- String remaining = connection.getHeaderField("X-RateLimit-Remaining");
- // number of seconds to wait before retrying (if remaining == 0)
String retryDelay = connection.getHeaderField("Retry-After");
// to test:
// retryDelay = "5";
- EnsemblInfo info = domainData.get(getDomain());
if (retryDelay != null)
{
- System.err.println("Ensembl REST service rate limit exceeded, wait "
- + retryDelay + " seconds before retrying");
try
{
- info.retryAfter = System.currentTimeMillis()
- + (1000 * Integer.valueOf(retryDelay));
- } catch (NumberFormatException e)
+ int retrySecs = Integer.valueOf(retryDelay);
+ if (retrySecs > 0 && retrySecs < 10)
+ {
+ System.err
+ .println("Ensembl REST service rate limit exceeded, waiting "
+ + retryDelay + " seconds before retrying");
+ Thread.sleep(1000 * retrySecs);
+ }
+ } catch (NumberFormatException | InterruptedException e)
{
- System.err
- .println("Unexpected value for Retry-After: " + retryDelay);
+ System.err.println("Error handling Retry-After: " + e.getMessage());
}
}
- else
- {
- info.retryAfter = 0;
- // debug:
- // System.out.println(String.format(
- // "%s Ensembl requests remaining of %s (reset in %ss)",
- // remaining, limit, reset));
- }
}
/**
long now = System.currentTimeMillis();
/*
- * check if we are waiting for 'Retry-After' to expire
- */
- if (info.retryAfter > now)
- {
- System.err.println("Still " + (1 + (info.retryAfter - now) / 1000)
- + " secs to wait before retrying Ensembl");
- return false;
- }
- else
- {
- info.retryAfter = 0;
- }
-
- /*
* recheck if Ensembl is up if it was down, or the recheck period has elapsed
*/
boolean retestAvailability = (now
URL url = null;
try
{
- url = new URL(
- getDomain() + "/info/rest?content-type=application/json");
+ url = new URL(getDomain() + "/info/rest" + CONTENT_TYPE_JSON);
BufferedReader br = getHttpResponse(url, null);
+ if (br == null)
+ {
+ return;
+ }
JSONObject val = (JSONObject) jp.parse(br);
String version = val.get("release").toString();
String majorVersion = version.substring(0, version.indexOf("."));
{
JSONParser jp = new JSONParser();
URL url = null;
+ BufferedReader br = null;
+
try
{
- url = new URL(
- getDomain() + "/info/data?content-type=application/json");
- BufferedReader br = getHttpResponse(url, null);
- JSONObject val = (JSONObject) jp.parse(br);
- JSONArray versions = (JSONArray) val.get("releases");
- domainData.get(getDomain()).dataVersion = versions.get(0).toString();
+ url = new URL(getDomain() + "/info/data" + CONTENT_TYPE_JSON);
+ br = getHttpResponse(url, null);
+ if (br != null)
+ {
+ JSONObject val = (JSONObject) jp.parse(br);
+ JSONArray versions = (JSONArray) val.get("releases");
+ domainData.get(getDomain()).dataVersion = versions.get(0)
+ .toString();
+ }
} catch (Throwable t)
{
System.err.println(
"Error checking Ensembl data version: " + t.getMessage());
+ } finally
+ {
+ if (br != null)
+ {
+ try
+ {
+ br.close();
+ } catch (IOException e)
+ {
+ // ignore
+ }
+ }
}
}
*/
public class EnsemblSymbol extends EnsemblXref
{
+ private static final String GENE = "gene";
+ private static final String TYPE = "type";
+ private static final String ID = "id";
+
/**
* Constructor given the target domain to fetch data from
*
while (rvals.hasNext())
{
JSONObject val = (JSONObject) rvals.next();
- String id = val.get("id").toString();
- if (id != null && isGeneIdentifier(id))
+ String id = val.get(ID).toString();
+ String type = val.get(TYPE).toString();
+ if (id != null && GENE.equals(type))
{
result = id;
break;
return result;
}
- protected URL getUrl(String id, Species species)
+ /**
+ * Constructs the URL for the REST symbol endpoint
+ *
+ * @param id
+ * the accession id (Ensembl or external)
+ * @param species
+ * a species name recognisable by Ensembl
+ * @param type
+ * an optional type to filter the response (gene, transcript,
+ * translation)
+ * @return
+ */
+ protected URL getUrl(String id, Species species, String... type)
{
- String url = getDomain() + "/xrefs/symbol/" + species.toString() + "/"
- + id + "?content-type=application/json";
+ StringBuilder sb = new StringBuilder();
+ sb.append(getDomain()).append("/xrefs/symbol/")
+ .append(species.toString()).append("/").append(id)
+ .append(CONTENT_TYPE_JSON);
+ for (String t : type)
+ {
+ sb.append("&object_type=").append(t);
+ }
try
{
+ String url = sb.toString();
return new URL(url);
} catch (MalformedURLException e)
{
* @param identifier
* @return
*/
- public List<String> getIds(String identifier)
+ public List<String> getGeneIds(String identifier)
{
List<String> result = new ArrayList<String>();
List<String> ids = new ArrayList<String>();
{
for (String query : queries)
{
- for (Species taxon : Species.values())
+ for (Species taxon : Species.getModelOrganisms())
{
- if (taxon.isModelOrganism())
+ URL url = getUrl(query, taxon, GENE);
+ if (url != null)
{
- URL url = getUrl(query, taxon);
- if (url != null)
- {
- br = getHttpResponse(url, ids);
- }
- String geneId = parseSymbolResponse(br);
- if (geneId != null)
+ br = getHttpResponse(url, ids);
+ if (br != null)
{
- result.add(geneId);
+ String geneId = parseSymbolResponse(br);
+ System.out.println(url + " returned " + geneId);
+ if (geneId != null && !result.contains(geneId))
+ {
+ result.add(geneId);
+ }
}
}
}
if (url != null)
{
br = getHttpResponse(url, ids);
+ if (br != null)
+ {
+ result = parseResponse(br);
+ }
}
- return (parseResponse(br));
} catch (IOException e)
{
// ignore
while (rvals.hasNext())
{
JSONObject val = (JSONObject) rvals.next();
- String dbName = val.get("dbname").toString();
- if (dbName.equals(GO_GENE_ONTOLOGY))
- {
- continue;
- }
+ String db = val.get("dbname").toString();
String id = val.get("primary_id").toString();
- if (dbName != null && id != null)
+ if (db != null && id != null
+ && !GO_GENE_ONTOLOGY.equals(db))
{
- dbName = DBRefUtils.getCanonicalName(dbName);
- DBRefEntry dbref = new DBRefEntry(dbName, getXRefVersion(), id);
+ db = DBRefUtils.getCanonicalName(db);
+ DBRefEntry dbref = new DBRefEntry(db, getXRefVersion(), id);
result.add(dbref);
}
}
protected URL getUrl(String identifier)
{
String url = getDomain() + "/xrefs/id/" + identifier
- + "?content-type=application/json&all_levels=1";
+ + CONTENT_TYPE_JSON + "&all_levels=1";
try
{
return new URL(url);
*/
package jalview.ext.ensembl;
+import java.util.HashSet;
+import java.util.Set;
+
/**
* Selected species identifiers used by Ensembl
*
chimpanzee(false), cat(false), zebrafish(true), chicken(true),
dmelanogaster(true);
+ static Set<Species> modelOrganisms = new HashSet<>();
+
+ static
+ {
+ for (Species s : values())
+ {
+ if (s.isModelOrganism())
+ {
+ modelOrganisms.add(s);
+ }
+ }
+ }
boolean modelOrganism;
private Species(boolean model)
{
return modelOrganism;
}
+
+ public static Set<Species> getModelOrganisms()
+ {
+ return modelOrganisms;
+ }
}
import jalview.datamodel.HiddenColumns;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
+import jalview.gui.IProgressIndicator;
import jalview.io.DataSourceType;
import jalview.io.StructureFile;
import jalview.schemes.ColourSchemeI;
*/
private boolean associateNewStructs = false;
- Vector<String> atomsPicked = new Vector<String>();
+ Vector<String> atomsPicked = new Vector<>();
private List<String> chainNames;
}
if (modelFileNames == null)
{
- List<String> mset = new ArrayList<String>();
+ List<String> mset = new ArrayList<>();
_modelFileNameMap = new int[viewer.ms.mc];
String m = viewer.ms.getModelFileName(0);
if (m != null)
@Override
public synchronized String[] getStructureFiles()
{
- List<String> mset = new ArrayList<String>();
+ List<String> mset = new ArrayList<>();
if (viewer == null)
{
return new String[0];
notifyAtomPicked(((Integer) data[2]).intValue(), (String) data[1],
(String) data[0]);
// also highlight in alignment
+ // deliberate fall through
case HOVER:
notifyAtomHovered(((Integer) data[2]).intValue(), (String) data[1],
(String) data[0]);
fileLoadingError = null;
String[] oldmodels = modelFileNames;
modelFileNames = null;
- chainNames = new ArrayList<String>();
- chainFile = new Hashtable<String, String>();
+ chainNames = new ArrayList<>();
+ chainFile = new Hashtable<>();
boolean notifyLoaded = false;
String[] modelfilenames = getStructureFiles();
// first check if we've lost any structures
// see JAL-623 - need method of matching pasted data up
{
pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
- pdbfile, DataSourceType.PASTE);
+ pdbfile, DataSourceType.PASTE,
+ getIProgressIndicator());
getPdbEntry(modelnum).setFile("INLINE" + pdb.getId());
matches = true;
foundEntry = true;
}
// Explicitly map to the filename used by Jmol ;
pdb = getSsm().setMapping(getSequence()[pe], getChains()[pe],
- fileName, protocol);
+ fileName, protocol, getIProgressIndicator());
// pdbentry[pe].getFile(), protocol);
}
return chainNames;
}
+ protected abstract IProgressIndicator getIProgressIndicator();
+
public void notifyNewPickingModeMeasurement(int iatom, String strMeasure)
{
notifyAtomPicked(iatom, strMeasure, null);
for (String chain : modelData.keySet())
{
- chain = chain.trim();
+ chain = " ".equals(chain) ? chain : chain.trim();
List<int[]> rangeList = modelData.get(chain);
{
sb.append(start).append("-").append(end);
}
- if (chain.length() > 0)
- {
- sb.append(".").append(chain);
+
+ sb.append(".");
+ if (!" ".equals(chain)) {
+ sb.append(chain);
}
}
}
private static final String PDB_FTS_CACHE_KEY = "CACHE.PDB_FTS";
- public PDBFTSPanel(SequenceFetcher seqFetcher)
+ public PDBFTSPanel(SequenceFetcher fetcher)
{
super();
pageLimit = PDBFTSRestClient.getInstance().getDefaultResponsePageSize();
- this.seqFetcher = seqFetcher;
- this.progressIndicator = (seqFetcher == null) ? null
- : seqFetcher.getProgressIndicator();
+ this.seqFetcher = fetcher;
+ this.progressIndicator = (fetcher == null) ? null
+ : fetcher.getProgressIndicator();
}
@Override
request.setSearchTerm(searchTerm + ")");
request.setOffSet(offSet);
request.setWantedFields(wantedFields);
- FTSRestClientI pdbRestCleint = PDBFTSRestClient.getInstance();
+ FTSRestClientI pdbRestClient = PDBFTSRestClient.getInstance();
FTSRestResponse resultList;
try
{
- resultList = pdbRestCleint.executeRequest(request);
+ resultList = pdbRestClient.executeRequest(request);
} catch (Exception e)
{
setErrorMessage(e.getMessage());
checkForErrors();
+ setSearchInProgress(false);
return;
}
private static FTSRestClientI instance = null;
- public static final String PDB_SEARCH_ENDPOINT = "http://www.ebi.ac.uk/pdbe/search/pdb/select?";
+ public static final String PDB_SEARCH_ENDPOINT = "https://www.ebi.ac.uk/pdbe/search/pdb/select?";
protected PDBFTSRestClient()
{
private static String defaultFTSFrameTitle = MessageManager
.getString("label.uniprot_sequence_fetcher");
- private static Map<String, Integer> tempUserPrefs = new HashMap<String, Integer>();
+ private static Map<String, Integer> tempUserPrefs = new HashMap<>();
private static final String UNIPROT_FTS_CACHE_KEY = "CACHE.UNIPROT_FTS";
- public UniprotFTSPanel(SequenceFetcher seqFetcher)
+ public UniprotFTSPanel(SequenceFetcher fetcher)
{
super();
pageLimit = UniProtFTSRestClient.getInstance()
.getDefaultResponsePageSize();
- this.seqFetcher = seqFetcher;
- this.progressIndicator = (seqFetcher == null) ? null
- : seqFetcher.getProgressIndicator();
+ this.seqFetcher = fetcher;
+ this.progressIndicator = (fetcher == null) ? null
+ : fetcher.getProgressIndicator();
}
@Override
request.setSearchTerm(searchTerm);
request.setOffSet(offSet);
request.setWantedFields(wantedFields);
- FTSRestClientI uniProtRestCleint = UniProtFTSRestClient
+ FTSRestClientI uniProtRestClient = UniProtFTSRestClient
.getInstance();
FTSRestResponse resultList;
try
{
- resultList = uniProtRestCleint.executeRequest(request);
+ resultList = uniProtRestClient.executeRequest(request);
} catch (Exception e)
{
- e.printStackTrace();
setErrorMessage(e.getMessage());
checkForErrors();
+ setSearchInProgress(false);
return;
}
{
disableActionButtons();
StringBuilder selectedIds = new StringBuilder();
- HashSet<String> selectedIdsSet = new HashSet<String>();
+ HashSet<String> selectedIdsSet = new HashSet<>();
int primaryKeyColIndex = 0;
try
{
AlignViewport viewport;
- ViewportRanges vpRanges;
-
public AlignViewControllerI avc;
List<AlignmentPanel> alignPanels = new ArrayList<>();
progressBar = new ProgressBar(this.statusPanel, this.statusBar);
}
- vpRanges = viewport.getRanges();
avc = new jalview.controller.AlignViewController(this, viewport,
alignPanel);
if (viewport.getAlignmentConservationAnnotation() == null)
{ (viewport.cursorMode ? "on" : "off") }));
if (viewport.cursorMode)
{
- alignPanel.getSeqPanel().seqCanvas.cursorX = vpRanges
+ ViewportRanges ranges = viewport.getRanges();
+ alignPanel.getSeqPanel().seqCanvas.cursorX = ranges
.getStartRes();
- alignPanel.getSeqPanel().seqCanvas.cursorY = vpRanges
+ alignPanel.getSeqPanel().seqCanvas.cursorY = ranges
.getStartSeq();
}
alignPanel.getSeqPanel().seqCanvas.repaint();
break;
}
case KeyEvent.VK_PAGE_UP:
- vpRanges.pageUp();
+ viewport.getRanges().pageUp();
break;
case KeyEvent.VK_PAGE_DOWN:
- vpRanges.pageDown();
+ viewport.getRanges().pageDown();
break;
}
}
}
viewport.getAlignment().moveSelectedSequencesByOne(sg,
viewport.getHiddenRepSequences(), up);
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
synchronized void slideSequences(boolean right, int size)
{
// propagate alignment changed.
- vpRanges.setEndSeq(alignment.getHeight());
+ viewport.getRanges().setEndSeq(alignment.getHeight());
if (annotationAdded)
{
// Duplicate sequence annotation in all views.
{
PaintRefresher.Refresh(this, viewport.getSequenceSetId());
alignPanel.updateAnnotation();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
}
// JAL-2034 - should delegate to
// alignPanel to decide if overview needs
// updating.
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
}
// JAL-2034 - should delegate to
// alignPanel to decide if overview needs
// updating.
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
viewport.sendSelection();
}
// alignPanel to decide if overview needs
// updating.
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
viewport.sendSelection();
}
public void invertColSel_actionPerformed(ActionEvent e)
{
viewport.invertColumnSelection();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
viewport.sendSelection();
}
{
trimRegion = new TrimRegionCommand("Remove Left", true, seqs,
column, viewport.getAlignment());
- vpRanges.setStartRes(0);
+ viewport.getRanges().setStartRes(0);
}
else
{
// This is to maintain viewport position on first residue
// of first sequence
SequenceI seq = viewport.getAlignment().getSequenceAt(0);
- int startRes = seq.findPosition(vpRanges.getStartRes());
+ ViewportRanges ranges = viewport.getRanges();
+ int startRes = seq.findPosition(ranges.getStartRes());
// ShiftList shifts;
// viewport.getAlignment().removeGaps(shifts=new ShiftList());
// edit.alColumnChanges=shifts.getInverse();
// if (viewport.hasHiddenColumns)
// viewport.getColumnSelection().compensateForEdits(shifts);
- vpRanges.setStartRes(seq.findIndex(startRes) - 1);
+ ranges.setStartRes(seq.findIndex(startRes) - 1);
viewport.firePropertyChange("alignment", null,
viewport.getAlignment().getSequences());
// This is to maintain viewport position on first residue
// of first sequence
SequenceI seq = viewport.getAlignment().getSequenceAt(0);
- int startRes = seq.findPosition(vpRanges.getStartRes());
+ int startRes = seq.findPosition(viewport.getRanges().getStartRes());
addHistoryItem(new RemoveGapsCommand("Remove Gaps", seqs, start, end,
viewport.getAlignment()));
- vpRanges.setStartRes(seq.findIndex(startRes) - 1);
+ viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
viewport.firePropertyChange("alignment", null,
viewport.getAlignment().getSequences());
/*
* Create a new AlignmentPanel (with its own, new Viewport)
*/
- AlignmentPanel newap = new Jalview2XML().copyAlignPanel(alignPanel,
- true);
+ AlignmentPanel newap = new Jalview2XML().copyAlignPanel(alignPanel);
if (!copyAnnotation)
{
/*
alignPanel.getIdPanel().getIdCanvas()
.setPreferredSize(alignPanel.calculateIdWidth());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
@Override
public void idRightAlign_actionPerformed(ActionEvent e)
{
viewport.setRightAlignIds(idRightAlign.isSelected());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
@Override
public void centreColumnLabels_actionPerformed(ActionEvent e)
{
viewport.setCentreColumnLabels(centreColumnLabelsMenuItem.getState());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
/*
protected void colourTextMenuItem_actionPerformed(ActionEvent e)
{
viewport.setColourText(colourTextMenuItem.isSelected());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
/**
public void showAllColumns_actionPerformed(ActionEvent e)
{
viewport.showAllHiddenColumns();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
viewport.expandColSelection(sg, false);
viewport.hideAllSelectedSeqs();
viewport.hideSelectedColumns();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
{
viewport.showAllHiddenColumns();
viewport.showAllHiddenSeqs();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
public void hideSelColumns_actionPerformed(ActionEvent e)
{
viewport.hideSelectedColumns();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
viewport.sendSelection();
}
protected void scaleAbove_actionPerformed(ActionEvent e)
{
viewport.setScaleAboveWrapped(scaleAbove.isSelected());
- alignPanel.paintAlignment(true);
+ // TODO: do we actually need to update overview for scale above change ?
+ alignPanel.paintAlignment(true, false);
}
/**
protected void scaleLeft_actionPerformed(ActionEvent e)
{
viewport.setScaleLeftWrapped(scaleLeft.isSelected());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
/**
protected void scaleRight_actionPerformed(ActionEvent e)
{
viewport.setScaleRightWrapped(scaleRight.isSelected());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
/**
public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
{
viewport.setShowBoxes(viewBoxesMenuItem.isSelected());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
/**
public void viewTextMenuItem_actionPerformed(ActionEvent e)
{
viewport.setShowText(viewTextMenuItem.isSelected());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
/**
protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
{
viewport.setRenderGaps(renderGapsMenuItem.isSelected());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
public FeatureSettings featureSettings;
public void showSeqFeatures_actionPerformed(ActionEvent evt)
{
viewport.setShowSequenceFeatures(showSeqFeatures.isSelected());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
/**
viewport.setGlobalColourScheme(cs);
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
/**
viewport.getAlignment().getSequenceAt(0));
addHistoryItem(new OrderCommand("Pairwise Sort", oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
/**
AlignmentSorter.sortByID(viewport.getAlignment());
addHistoryItem(
new OrderCommand("ID Sort", oldOrder, viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
/**
AlignmentSorter.sortByLength(viewport.getAlignment());
addHistoryItem(new OrderCommand("Length Sort", oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
/**
addHistoryItem(new OrderCommand("Group Sort", oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
/**
addHistoryItem(new OrderCommand(order.getName(), oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
});
}
viewport.getAlignment());// ,viewport.getSelectionGroup());
addHistoryItem(new OrderCommand("Sort by " + scoreLabel, oldOrder,
viewport.getAlignment()));
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
}
});
}
addHistoryItem(new OrderCommand(undoname, oldOrder,
viewport.getAlignment()));
}
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, false);
return true;
}
assocfiles++;
}
}
- alignPanel.paintAlignment(true);
+ // TODO: do we need to update overview ? only if features are
+ // shown I guess
+ alignPanel.paintAlignment(true, false);
}
}
}
{
if (parseFeaturesFile(file, sourceType))
{
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
}
else
alignPanel.adjustAnnotationHeight();
viewport.updateSequenceIdColours();
buildSortByAnnotationScoresMenu();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
} catch (Exception ex)
{
protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
{
viewport.setShowUnconserved(showNonconservedMenuItem.getState());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
/*
{
PaintRefresher.Refresh(this, viewport.getSequenceSetId());
alignPanel.updateAnnotation();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
}
viewport.getAlignment().setSeqrep(null);
PaintRefresher.Refresh(this, viewport.getSequenceSetId());
alignPanel.updateAnnotation();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
}
}
this.alignPanel.av.setSortAnnotationsBy(getAnnotationSortOrder());
this.alignPanel.av
.setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(false, false);
}
/**
{
Font font;
- TreeModel currentTree = null;
-
boolean cursorMode = false;
boolean antiAlias = false;
}
/**
- * DOCUMENT ME!
- *
- * @param tree
- * DOCUMENT ME!
- */
- public void setCurrentTree(TreeModel tree)
- {
- currentTree = tree;
- }
-
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- public TreeModel getCurrentTree()
- {
- return currentTree;
- }
-
- /**
* returns the visible column regions of the alignment
*
* @param selectedRegionOnly
}
fr.setTransparency(featureSettings.getTransparency());
}
-
}
{
public AlignViewport av;
- ViewportRanges vpRanges;
-
OverviewPanel overviewPanel;
private SeqPanel seqPanel;
private AnnotationLabels alabels;
- // this value is set false when selection area being dragged
- boolean fastPaint = true;
-
private int hextent = 0;
private int vextent = 0;
{
alignFrame = af;
this.av = av;
- vpRanges = av.getRanges();
setSeqPanel(new SeqPanel(av, this));
setIdPanel(new IdPanel(av, this));
// reset the viewport ranges when the alignment panel is resized
// in particular, this initialises the end residue value when Jalview
// is initialised
+ ViewportRanges ranges = av.getRanges();
if (av.getWrapAlignment())
{
int widthInRes = getSeqPanel().seqCanvas.getWrappedCanvasWidth(
getSeqPanel().seqCanvas.getWidth());
- vpRanges.setViewportWidth(widthInRes);
+ ranges.setViewportWidth(widthInRes);
}
else
{
int heightInSeq = getSeqPanel().seqCanvas.getHeight()
/ av.getCharHeight();
- vpRanges.setViewportWidth(widthInRes);
- vpRanges.setViewportHeight(heightInSeq);
+ ranges.setViewportWidth(widthInRes);
+ ranges.setViewportHeight(heightInSeq);
}
}
alignFrame.updateEditMenuBar();
- paintAlignment(true);
+ // no idea if we need to update structure
+ paintAlignment(true, true);
}
int verticalOffset, boolean redrawOverview, boolean centre)
{
int startv, endv, starts, ends;
+ ViewportRanges ranges = av.getRanges();
if (results == null || results.isEmpty() || av == null
|| av.getAlignment() == null)
*/
if (centre)
{
- int offset = (vpRanges.getEndRes() - vpRanges.getStartRes() + 1) / 2 - 1;
+ int offset = (ranges.getEndRes() - ranges.getStartRes() + 1) / 2 - 1;
start = Math.max(start - offset, 0);
end = end + offset - 1;
}
if (!av.getWrapAlignment())
{
- if ((startv = vpRanges.getStartRes()) >= start)
+ if ((startv = ranges.getStartRes()) >= start)
{
/*
* Scroll left to make start of search results visible
*/
setScrollValues(start, seqIndex);
}
- else if ((endv = vpRanges.getEndRes()) <= end)
+ else if ((endv = ranges.getEndRes()) <= end)
{
/*
* Scroll right to make end of search results visible
*/
setScrollValues(startv + end - endv, seqIndex);
}
- else if ((starts = vpRanges.getStartSeq()) > seqIndex)
+ else if ((starts = ranges.getStartSeq()) > seqIndex)
{
/*
* Scroll up to make start of search results visible
*/
- setScrollValues(vpRanges.getStartRes(), seqIndex);
+ setScrollValues(ranges.getStartRes(), seqIndex);
}
- else if ((ends = vpRanges.getEndSeq()) <= seqIndex)
+ else if ((ends = ranges.getEndSeq()) <= seqIndex)
{
/*
* Scroll down to make end of search results visible
*/
- setScrollValues(vpRanges.getStartRes(), starts + seqIndex - ends
+ setScrollValues(ranges.getStartRes(), starts + seqIndex - ends
+ 1);
}
/*
}
else
{
- scrollNeeded = vpRanges.scrollToWrappedVisible(start);
+ scrollNeeded = ranges.scrollToWrappedVisible(start);
}
- paintAlignment(redrawOverview);
+ paintAlignment(redrawOverview, false);
return scrollNeeded;
}
}
validateAnnotationDimensions(true);
addNotify();
- paintAlignment(true);
+ // TODO: many places call this method and also paintAlignment with various
+ // different settings. this means multiple redraws are triggered...
+ paintAlignment(true, false);
}
/**
fontChanged();
setAnnotationVisible(av.isShowAnnotation());
boolean wrap = av.getWrapAlignment();
- vpRanges.setStartSeq(0);
+ ViewportRanges ranges = av.getRanges();
+ ranges.setStartSeq(0);
scalePanelHolder.setVisible(!wrap);
hscroll.setVisible(!wrap);
idwidthAdjuster.setVisible(!wrap);
{
int widthInRes = getSeqPanel().seqCanvas
.getWrappedCanvasWidth(canvasWidth);
- vpRanges.setViewportWidth(widthInRes);
+ ranges.setViewportWidth(widthInRes);
}
else
{
int heightInSeq = (getSeqPanel().seqCanvas.getHeight()
/ av.getCharHeight());
- vpRanges.setViewportWidth(widthInRes);
- vpRanges.setViewportHeight(heightInSeq);
+ ranges.setViewportWidth(widthInRes);
+ ranges.setViewportHeight(heightInSeq);
}
}
return;
}
+ ViewportRanges ranges = av.getRanges();
+
if (evt.getSource() == hscroll)
{
- int oldX = vpRanges.getStartRes();
- int oldwidth = vpRanges.getViewportWidth();
+ int oldX = ranges.getStartRes();
+ int oldwidth = ranges.getViewportWidth();
int x = hscroll.getValue();
int width = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
{
return;
}
- vpRanges.setViewportStartAndWidth(x, width);
+ ranges.setViewportStartAndWidth(x, width);
}
else if (evt.getSource() == vscroll)
{
- int oldY = vpRanges.getStartSeq();
- int oldheight = vpRanges.getViewportHeight();
+ int oldY = ranges.getStartSeq();
+ int oldheight = ranges.getViewportHeight();
int y = vscroll.getValue();
int height = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight();
{
return;
}
- vpRanges.setViewportStartAndHeight(y, height);
- }
- if (!fastPaint)
- {
- repaint();
+ ranges.setViewportStartAndHeight(y, height);
}
+ repaint();
}
/**
{
return; // no horizontal scroll when wrapped
}
+ final ViewportRanges ranges = av.getRanges();
+
if (evt.getSource() == vscroll)
{
int newY = vscroll.getValue();
* this prevents infinite recursion of events when the scroll/viewport
* ranges values are the same
*/
- int oldX = vpRanges.getStartRes();
- int oldY = vpRanges.getWrappedScrollPosition(oldX);
+ int oldX = ranges.getStartRes();
+ int oldY = ranges.getWrappedScrollPosition(oldX);
if (oldY == newY)
{
return;
/*
* limit page up/down to one width's worth of positions
*/
- int rowSize = vpRanges.getViewportWidth();
+ int rowSize = ranges.getViewportWidth();
int newX = newY > oldY ? oldX + rowSize : oldX - rowSize;
- vpRanges.setViewportStartAndWidth(Math.max(0, newX), rowSize);
+ ranges.setViewportStartAndWidth(Math.max(0, newX), rowSize);
}
}
else
"Unexpected path through code: Wrapped jar file opened with wrap alignment set in preferences");
// scroll to start of panel
- vpRanges.setStartRes(0);
- vpRanges.setStartSeq(0);
+ ranges.setStartRes(0);
+ ranges.setStartSeq(0);
}
});
}
repaint();
}
- /**
- * Repaint the alignment including the annotations and overview panels (if
- * shown).
+ /* (non-Javadoc)
+ * @see jalview.api.AlignmentViewPanel#paintAlignment(boolean)
*/
@Override
- public void paintAlignment(boolean updateOverview)
+ public void paintAlignment(boolean updateOverview,
+ boolean updateStructures)
{
final AnnotationSorter sorter = new AnnotationSorter(getAlignment(),
av.isShowAutocalculatedAbove());
av.getSortAnnotationsBy());
repaint();
- if (updateOverview)
+ if (updateStructures)
{
- // TODO: determine if this paintAlignment changed structure colours
av.getStructureSelectionManager().sequenceColoursChanged(this);
+ }
+ if (updateOverview)
+ {
if (overviewPanel != null)
{
/*
* set scroll bar positions
*/
- setScrollValues(vpRanges.getStartRes(), vpRanges.getStartSeq());
+ ViewportRanges ranges = av.getRanges();
+ setScrollValues(ranges.getStartRes(), ranges.getStartSeq());
}
/**
*/
private void setScrollingForWrappedPanel(int topLeftColumn)
{
- int scrollPosition = vpRanges.getWrappedScrollPosition(topLeftColumn);
- int maxScroll = vpRanges.getWrappedMaxScroll(topLeftColumn);
+ ViewportRanges ranges = av.getRanges();
+ int scrollPosition = ranges.getWrappedScrollPosition(topLeftColumn);
+ int maxScroll = ranges.getWrappedMaxScroll(topLeftColumn);
/*
* a scrollbar's value can be set to at most (maximum-extent)
if (annotationPanel != null)
{
annotationPanel.dispose();
+ annotationPanel = null;
}
if (av != null)
{
av.removePropertyChangeListener(propertyChangeListener);
- jalview.structure.StructureSelectionManager ssm = av
- .getStructureSelectionManager();
+ propertyChangeListener = null;
+ StructureSelectionManager ssm = av.getStructureSelectionManager();
ssm.removeStructureViewerListener(getSeqPanel(), null);
ssm.removeSelectionListener(getSeqPanel());
ssm.removeCommandListener(av);
*/
protected void closeChildFrames()
{
+ if (overviewPanel != null)
+ {
+ overviewPanel.dispose();
+ overviewPanel = null;
+ }
if (calculationDialog != null)
{
calculationDialog.closeFrame();
+ calculationDialog = null;
}
}
if (adjustHeight)
{
// sort, repaint, update overview
- paintAlignment(true);
+ paintAlignment(true, false);
}
else
{
public void propertyChange(PropertyChangeEvent evt)
{
// update this panel's scroll values based on the new viewport ranges values
- int x = vpRanges.getStartRes();
- int y = vpRanges.getStartSeq();
+ ViewportRanges ranges = av.getRanges();
+ int x = ranges.getStartRes();
+ int y = ranges.getStartSeq();
setScrollValues(x, y);
// now update any complementary alignment (its viewport ranges object
private boolean applyToUnselectedSequences;
// currently selected 'annotation type' checkboxes
- private Map<String, String> selectedTypes = new HashMap<String, String>();
+ private Map<String, String> selectedTypes = new HashMap<>();
/**
* Constructor.
// this.ap.alabels.setSize(this.ap.alabels.getSize().width,
// this.ap.annotationPanel.getSize().height);
// this.ap.validate();
- this.ap.paintAlignment(true);
+ this.ap.paintAlignment(true, false);
}
/**
// this.ap.alabels.setSize(this.ap.alabels.getSize().width,
// this.ap.annotationPanel.getSize().height);
// this.ap.validate();
- this.ap.paintAlignment(true);
+ this.ap.paintAlignment(true, false);
}
/**
this.ap.updateAnnotation();
// this.ap.annotationPanel.adjustPanelHeight();
- this.ap.paintAlignment(true);
+ this.ap.paintAlignment(true, false);
}
/**
public static List<String> getAnnotationTypes(AlignmentI alignment,
boolean sequenceSpecificOnly)
{
- List<String> result = new ArrayList<String>();
+ List<String> result = new ArrayList<>();
for (AlignmentAnnotation aa : alignment.getAlignmentAnnotation())
{
if (!sequenceSpecificOnly || aa.sequenceRef != null)
oldcs = av.getGlobalColourScheme();
if (av.getAlignment().getGroups() != null)
{
- oldgroupColours = new Hashtable<SequenceGroup, ColourSchemeI>();
+ oldgroupColours = new Hashtable<>();
for (SequenceGroup sg : ap.av.getAlignment().getGroups())
{
if (sg.getColourScheme() != null)
}
Vector<String> annotItems = getAnnotationItems(
seqAssociated.isSelected());
- annotations = new JComboBox<String>(annotItems);
+ annotations = new JComboBox<>(annotItems);
populateThresholdComboBox(threshold);
getCurrentAnnotation().threshold.value = slider.getValue() / 1000f;
propagateSeqAssociatedThreshold(updateAllAnnotation,
getCurrentAnnotation());
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
}
colorAlignmentContaining(getCurrentAnnotation(), selectedThresholdItem);
ap.alignmentChanged();
- // ensure all associated views (overviews, structures, etc) are notified of
- // updated colours.
- ap.paintAlignment(true);
}
- protected boolean colorAlignmentContaining(AlignmentAnnotation currentAnn,
+ protected void colorAlignmentContaining(AlignmentAnnotation currentAnn,
int selectedThresholdOption)
{
acg.getInstance(sg, ap.av.getHiddenRepSequences()));
}
}
- return false;
}
}
av.getAlignment().setHiddenColumns(oldHidden);
}
av.sendSelection();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
}
updateView();
propagateSeqAssociatedThreshold(updateAllAnnotation,
getCurrentAnnotation());
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
}
av.getColumnSelection().filterAnnotations(
getCurrentAnnotation().annotations, filterParams);
- if (getActionOption() == ACTION_OPTION_HIDE)
+ boolean hideCols = getActionOption() == ACTION_OPTION_HIDE;
+ if (hideCols)
{
av.hideSelectedColumns();
}
filterParams = null;
av.setAnnotationColumnSelectionState(this);
- ap.paintAlignment(true);
+ // only update overview and structures if columns were hidden
+ ap.paintAlignment(hideCols, hideCols);
}
public HiddenColumns getOldHiddenColumns()
d = ap.annotationSpaceFillerHolder.getPreferredSize();
ap.annotationSpaceFillerHolder
.setPreferredSize(new Dimension(d.width, d.height - dif));
- ap.paintAlignment(true);
+ ap.paintAlignment(true, false);
}
ap.addNotify();
}
}
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
ap.av.sendSelection();
}
sg.addSequence(aa[selectedRow].sequenceRef, false);
}
ap.av.setSelectionGroup(sg);
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
PaintRefresher.Refresh(ap, ap.av.getSequenceSetId());
ap.av.sendSelection();
}
}
graphStretchY = evt.getY();
adjustPanelHeight();
- ap.paintAlignment(true);
+ ap.paintAlignment(false, false);
}
else
{
*/
protected boolean sliderDragging = false;
- protected JComboBox<String> threshold = new JComboBox<String>();
+ protected JComboBox<String> threshold = new JComboBox<>();
protected JComboBox<String> annotations;
sliderDragging = false;
valueChanged(true);
}
- ap.paintAlignment(true);
}
});
}
*/
public Vector<String> getAnnotationItems(boolean isSeqAssociated)
{
- annotationLabels = new HashMap<AlignmentAnnotation, String>();
+ annotationLabels = new HashMap<>();
- Vector<String> list = new Vector<String>();
+ Vector<String> list = new Vector<>();
int index = 1;
int[] anmap = new int[av.getAlignment()
.getAlignmentAnnotation().length];
public void cancel_actionPerformed()
{
reset();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
try
{
frame.setClosed(true);
this.currentAnnotation = annotation;
}
+ /**
+ * update associated view model and trigger any necessary repaints.
+ *
+ * @param updateAllAnnotation
+ */
protected abstract void valueChanged(boolean updateAllAnnotation);
protected abstract void updateView();
IProgressIndicator progressBar = null;
+ @Override
+ protected IProgressIndicator getIProgressIndicator()
+ {
+ return progressBar;
+ }
/**
* add a single PDB structure to a new or existing Jmol view
*
@Override
protected List<StructureViewerBase> getViewersFor(AlignmentPanel apanel)
{
- List<StructureViewerBase> result = new ArrayList<StructureViewerBase>();
+ List<StructureViewerBase> result = new ArrayList<>();
JInternalFrame[] frames = Desktop.instance.getAllFrames();
for (JInternalFrame frame : frames)
@Override
void showSelectedChains()
{
- Vector<String> toshow = new Vector<String>();
+ Vector<String> toshow = new Vector<>();
for (int i = 0; i < chainMenu.getItemCount(); i++)
{
if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)
// todo - record which pdbids were successfully imported.
StringBuilder errormsgs = new StringBuilder();
- List<String> files = new ArrayList<String>();
+ List<String> files = new ArrayList<>();
String pdbid = "";
try
{
}
@Override
+ protected IProgressIndicator getIProgressIndicator()
+ {
+ return appJmolWindow.progressBar;
+ }
+
+ @Override
public SequenceRenderer getSequenceRenderer(AlignmentViewPanel alignment)
{
return new SequenceRenderer(((AlignmentPanel) alignment).av);
--- /dev/null
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jalview.gui;
+
+import java.awt.Container;
+import java.beans.PropertyVetoException;
+import java.util.Vector;
+
+import javax.swing.DefaultDesktopManager;
+import javax.swing.DesktopManager;
+import javax.swing.JInternalFrame;
+
+/**
+ * Based on AquaInternalFrameManager
+ *
+ * DesktopManager implementation for Aqua
+ *
+ * Mac is more like Windows than it's like Motif/Basic
+ *
+ * From WindowsDesktopManager:
+ *
+ * This class implements a DesktopManager which more closely follows the MDI
+ * model than the DefaultDesktopManager. Unlike the DefaultDesktopManager
+ * policy, MDI requires that the selected and activated child frames are the
+ * same, and that that frame always be the top-most window.
+ * <p>
+ * The maximized state is managed by the DesktopManager with MDI, instead of
+ * just being a property of the individual child frame. This means that if the
+ * currently selected window is maximized and another window is selected, that
+ * new window will be maximized.
+ *
+ * Downloaded from
+ * https://raw.githubusercontent.com/frohoff/jdk8u-jdk/master/src/macosx/classes/com/apple/laf/AquaInternalFrameManager.java
+ *
+ * Patch from Jim Procter - when the most recently opened frame is closed,
+ * correct behaviour is to go to the next most recent frame, rather than wrap
+ * around to the bottom of the window stack (as the original implementation
+ * does)
+ *
+ * @see com.sun.java.swing.plaf.windows.WindowsDesktopManager
+ */
+public class AquaInternalFrameManager extends DefaultDesktopManager
+{
+ // Variables
+
+ /* The frame which is currently selected/activated.
+ * We store this value to enforce Mac's single-selection model.
+ */
+ JInternalFrame fCurrentFrame;
+
+ JInternalFrame fInitialFrame;
+
+ /* The list of frames, sorted by order of creation.
+ * This list is necessary because by default the order of
+ * child frames in the JDesktopPane changes during frame
+ * activation (the activated frame is moved to index 0).
+ * We preserve the creation order so that "next" and "previous"
+ * frame actions make sense.
+ */
+ Vector<JInternalFrame> fChildFrames = new Vector<>(1);
+
+ /**
+ * keep a reference to the original LAF manager so we can iconise/de-iconise
+ * correctly
+ */
+ private DesktopManager ourManager;
+
+ public AquaInternalFrameManager(DesktopManager desktopManager)
+ {
+ ourManager = desktopManager;
+ }
+
+ @Override
+ public void closeFrame(final JInternalFrame f)
+ {
+ if (f == fCurrentFrame)
+ {
+ boolean mostRecentFrame = fChildFrames
+ .indexOf(f) == fChildFrames.size() - 1;
+ if (!mostRecentFrame)
+ {
+ activateNextFrame();
+ }
+ else
+ {
+ activatePreviousFrame();
+ }
+ }
+ fChildFrames.removeElement(f);
+ super.closeFrame(f);
+ }
+
+ @Override
+ public void deiconifyFrame(final JInternalFrame f)
+ {
+ JInternalFrame.JDesktopIcon desktopIcon;
+
+ desktopIcon = f.getDesktopIcon();
+ // If the icon moved, move the frame to that spot before expanding it
+ // reshape does delta checks for us
+ f.reshape(desktopIcon.getX(), desktopIcon.getY(), f.getWidth(),
+ f.getHeight());
+ ourManager.deiconifyFrame(f);
+ }
+
+ void addIcon(final Container c,
+ final JInternalFrame.JDesktopIcon desktopIcon)
+ {
+ c.add(desktopIcon);
+ }
+
+ /**
+ * Removes the frame from its parent and adds its desktopIcon to the parent.
+ */
+ @Override
+ public void iconifyFrame(final JInternalFrame f)
+ {
+ ourManager.iconifyFrame(f);
+ }
+
+ // WindowsDesktopManager code
+ @Override
+ public void activateFrame(final JInternalFrame f)
+ {
+ try
+ {
+ if (f != null)
+ {
+ super.activateFrame(f);
+ }
+
+ // If this is the first activation, add to child list.
+ if (fChildFrames.indexOf(f) == -1)
+ {
+ fChildFrames.addElement(f);
+ }
+
+ if (fCurrentFrame != null && f != fCurrentFrame)
+ {
+ if (fCurrentFrame.isSelected())
+ {
+ fCurrentFrame.setSelected(false);
+ }
+ }
+
+ if (f != null && !f.isSelected())
+ {
+ f.setSelected(true);
+ }
+
+ fCurrentFrame = f;
+ } catch (final PropertyVetoException e)
+ {
+ }
+ }
+
+ private void switchFrame(final boolean next)
+ {
+ if (fCurrentFrame == null)
+ {
+ // initialize first frame we find
+ if (fInitialFrame != null)
+ {
+ activateFrame(fInitialFrame);
+ }
+ return;
+ }
+
+ final int count = fChildFrames.size();
+ if (count <= 1)
+ {
+ // No other child frames.
+ return;
+ }
+
+ final int currentIndex = fChildFrames.indexOf(fCurrentFrame);
+ if (currentIndex == -1)
+ {
+ // the "current frame" is no longer in the list
+ fCurrentFrame = null;
+ return;
+ }
+
+ int nextIndex;
+ if (next)
+ {
+ nextIndex = currentIndex + 1;
+ if (nextIndex == count)
+ {
+ nextIndex = 0;
+ }
+ }
+ else
+ {
+ nextIndex = currentIndex - 1;
+ if (nextIndex == -1)
+ {
+ nextIndex = count - 1;
+ }
+ }
+ final JInternalFrame f = fChildFrames.elementAt(nextIndex);
+ activateFrame(f);
+ fCurrentFrame = f;
+ }
+
+ /**
+ * Activate the next child JInternalFrame, as determined by the frames'
+ * Z-order. If there is only one child frame, it remains activated. If there
+ * are no child frames, nothing happens.
+ */
+ public void activateNextFrame()
+ {
+ switchFrame(true);
+ }
+
+ /**
+ * same as above but will activate a frame if none have been selected
+ */
+ public void activateNextFrame(final JInternalFrame f)
+ {
+ fInitialFrame = f;
+ switchFrame(true);
+ }
+
+ /**
+ * Activate the previous child JInternalFrame, as determined by the frames'
+ * Z-order. If there is only one child frame, it remains activated. If there
+ * are no child frames, nothing happens.
+ */
+ public void activatePreviousFrame()
+ {
+ switchFrame(false);
+ }
+}
\ No newline at end of file
List<String> tips = new ArrayList<String>();
+ /*
+ * the most recently opened PCA results panel
+ */
+ private PCAPanel pcaPanel;
+
/**
* Constructor
*
JvOptionPane.WARNING_MESSAGE);
return;
}
- new PCAPanel(af.alignPanel, modelName, params);
+ pcaPanel = new PCAPanel(af.alignPanel, modelName, params);
}
/**
{
}
}
+
+ public PCAPanel getPcaPanel()
+ {
+ return pcaPanel;
+ }
}
@Override
protected List<StructureViewerBase> getViewersFor(AlignmentPanel ap)
{
- List<StructureViewerBase> result = new ArrayList<StructureViewerBase>();
+ List<StructureViewerBase> result = new ArrayList<>();
JInternalFrame[] frames = Desktop.instance.getAllFrames();
for (JInternalFrame frame : frames)
@Override
void showSelectedChains()
{
- List<String> toshow = new ArrayList<String>();
+ List<String> toshow = new ArrayList<>();
for (int i = 0; i < chainMenu.getItemCount(); i++)
{
if (chainMenu.getItem(i) instanceof JCheckBoxMenuItem)
// todo - record which pdbids were successfully imported.
StringBuilder errormsgs = new StringBuilder(128);
StringBuilder files = new StringBuilder(128);
- List<PDBEntry> filePDB = new ArrayList<PDBEntry>();
- List<Integer> filePDBpos = new ArrayList<Integer>();
+ List<PDBEntry> filePDB = new ArrayList<>();
+ List<Integer> filePDBpos = new ArrayList<>();
PDBEntry thePdbEntry = null;
StructureFile pdb = null;
try
stopProgressBar("", startTime);
}
// Explicitly map to the filename used by Chimera ;
+
pdb = jmb.getSsm().setMapping(jmb.getSequence()[pos],
- jmb.getChains()[pos], pe.getFile(), protocol);
+ jmb.getChains()[pos], pe.getFile(), protocol,
+ progressBar);
stashFoundChains(pdb, pe.getFile());
+
} catch (OutOfMemoryError oomerror)
{
new OOMWarning(
/**
* Fetch PDB data and save to a local file. Returns the full path to the file,
- * or null if fetch fails.
+ * or null if fetch fails. TODO: refactor to common with Jmol ? duplication
*
* @param processingEntry
* @return
}
return reply;
}
+
+ @Override
+ protected IProgressIndicator getIProgressIndicator()
+ {
+ return progressBar;
+ }
}
import java.awt.dnd.DropTargetListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
desktop.setDesktopManager(
new MyDesktopManager(
(Platform.isWindows() ? new DefaultDesktopManager()
- : desktop.getDesktopManager())));
+ : Platform.isAMac()
+ ? new AquaInternalFrameManager(
+ desktop.getDesktopManager())
+ : desktop.getDesktopManager())));
Rectangle dims = getLastKnownDimensions("");
if (dims != null)
});
desktop.addMouseListener(ma);
- this.addFocusListener(new FocusListener()
- {
-
- @Override
- public void focusLost(FocusEvent e)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void focusGained(FocusEvent e)
- {
- Cache.log.debug("Relaying windows after focus gain");
- // make sure that we sort windows properly after we gain focus
- instance.relayerWindows();
- }
- });
this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
// Spawn a thread that shows the splashscreen
SwingUtilities.invokeLater(new Runnable()
JInternalFrame itf = desktop.getSelectedFrame();
if (itf != null)
{
+ if (itf instanceof AlignFrame)
+ {
+ Jalview.setCurrentAlignFrame((AlignFrame) itf);
+ }
itf.requestFocus();
}
}
menuItem.removeActionListener(menuItem.getActionListeners()[0]);
}
windowMenu.remove(menuItem);
- JInternalFrame itf = desktop.getSelectedFrame();
- if (itf != null)
- {
- itf.requestFocus();
- if (itf instanceof AlignFrame)
- {
- Jalview.setCurrentAlignFrame((AlignFrame) itf);
- }
- }
+
System.gc();
};
});
{
String link = li.next();
if (link.contains(SEQUENCE_ID)
- && !link.equals(UrlConstants.DEFAULT_STRING))
+ && !UrlConstants.isDefaultString(link))
{
check = true;
int barPos = link.indexOf("|");
}
}
- /**
- * fixes stacking order after a modal dialog to ensure windows that should be
- * on top actually are
- */
- public void relayerWindows()
- {
-
- }
/**
* Accessor method to quickly get all the AlignmentFrames loaded.
*/
if (ap != null)
{
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
}
});
* feature type, and repaints the alignment, and optionally the Overview
* and/or structure viewer if open
*
- * @param updateOverview
+ * @param updateStructsAndOverview
*/
- void changeColour(boolean updateOverview)
+ void changeColour(boolean updateStructsAndOverview)
{
// Check if combobox is still adjusting
if (adjusting)
}
fr.setColour(type, acg);
cs = acg;
- ap.paintAlignment(updateOverview);
+ ap.paintAlignment(updateStructsAndOverview, updateStructsAndOverview);
}
@Override
void reset()
{
fr.setColour(type, oldcs);
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
cs = null;
}
/*
* force repaint of any Overview window or structure
*/
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
} catch (NumberFormatException ex)
{
}
JPanel choosePanel = new JPanel();
choosePanel.add(new JLabel(
MessageManager.getString("label.select_feature") + ":"));
- final JComboBox<String> overlaps = new JComboBox<String>();
+ final JComboBox<String> overlaps = new JComboBox<>();
List<String> added = new ArrayList<>();
for (SequenceFeature sf : features)
{
featuresAdded();
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
return true;
}
}
}
- alignPanel.paintAlignment(true);
+ alignPanel.paintAlignment(true, true);
return true;
}
private static final int MIN_WIDTH = 400;
private static final int MIN_HEIGHT = 400;
+
+ /**
+ * when true, constructor is still executing - so ignore UI events
+ */
+ protected volatile boolean inConstruction = true;
/**
* Constructor
};
});
frame.setLayer(JLayeredPane.PALETTE_LAYER);
+ inConstruction = false;
}
protected void popupSort(final int selectedRow, final String type,
@Override
synchronized public void discoverAllFeatureData()
{
- Set<String> allGroups = new HashSet<String>();
+ Set<String> allGroups = new HashSet<>();
AlignmentI alignment = af.getViewport().getAlignment();
for (int i = 0; i < alignment.getHeight(); i++)
public void itemStateChanged(ItemEvent evt)
{
fr.setGroupVisibility(check.getText(), check.isSelected());
- af.alignPanel.getSeqPanel().seqCanvas.repaint();
- if (af.alignPanel.overviewPanel != null)
- {
- af.alignPanel.overviewPanel.updateOverviewImage();
- }
-
resetTable(new String[] { grp });
+ af.alignPanel.paintAlignment(true, true);
}
});
groupPanel.add(check);
return;
}
resettingTable = true;
- typeWidth = new Hashtable<String, float[]>();
+ typeWidth = new Hashtable<>();
// TODO: change avWidth calculation to 'per-sequence' average and use long
// rather than float
- Set<String> displayableTypes = new HashSet<String>();
- Set<String> foundGroups = new HashSet<String>();
+ Set<String> displayableTypes = new HashSet<>();
+ Set<String> foundGroups = new HashSet<>();
/*
* determine which feature types may be visible depending on
* and keep track of which groups are visible
*/
Set<String> groups = seq.getFeatures().getFeatureGroups(true);
- Set<String> visibleGroups = new HashSet<String>();
+ Set<String> visibleGroups = new HashSet<>();
for (String group : groups)
{
if (group == null || checkGroupState(group))
{
if (fr.setFeaturePriority(data, visibleNew))
{
- af.alignPanel.paintAlignment(true);
+ af.alignPanel.paintAlignment(true, true);
}
}
@Override
public void stateChanged(ChangeEvent evt)
{
- fr.setTransparency((100 - transparency.getValue()) / 100f);
- af.alignPanel.paintAlignment(true);
+ if (!inConstruction)
+ {
+ fr.setTransparency((100 - transparency.getValue()) / 100f);
+ af.alignPanel.paintAlignment(true,true);
+ }
}
});
{
ap.av.antiAlias = smoothFont.isSelected();
ap.getAnnotationPanel().image = null;
- ap.paintAlignment(true);
+ ap.paintAlignment(true, false);
if (ap.av.getCodingComplement() != null && ap.av.isProteinFontAsCdna())
{
((AlignViewport) ap.av
ap.av.setScaleProteinAsCdna(oldProteinScale);
ap.av.setProteinFontAsCdna(oldMirrorFont);
ap.av.antiAlias = oldSmoothFont;
- ap.paintAlignment(true);
+ ap.fontChanged();
if (scaleAsCdna.isVisible() && scaleAsCdna.isEnabled())
{
* is removed with a second call with same ID.
*
* @param message
- * - displayed message for operation
+ * - displayed message for operation. Please ensure message is
+ * internationalised.
* @param id
* - unique handle for this indicator
*/
}
lastid = seq;
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
}
/**
{
av.getRanges().scrollRight(true);
}
- else if (!av.getWrapAlignment())
+ else
{
av.getRanges().scrollUp(false);
}
{
av.getRanges().scrollRight(false);
}
- else if (!av.getWrapAlignment())
+ else
{
av.getRanges().scrollUp(true);
}
av.isSelectionGroupChanged(true);
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
}
/**
running = false;
}
- alignPanel.paintAlignment(false);
+ alignPanel.paintAlignment(false, false);
try
{
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mousePressed(MouseEvent evt)
{
oldX = evt.getX();
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseReleased(MouseEvent evt)
{
active = false;
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseEntered(MouseEvent evt)
{
active = true;
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseExited(MouseEvent evt)
{
active = false;
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseDragged(MouseEvent evt)
{
active = true;
{
viewport.setIdWidth(newWidth);
- ap.paintAlignment(true);
+ ap.paintAlignment(true, false);
}
oldX = evt.getX();
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseMoved(MouseEvent evt)
{
}
* @param evt
* DOCUMENT ME!
*/
+ @Override
public void mouseClicked(MouseEvent evt)
{
}
* @param g
* DOCUMENT ME!
*/
+ @Override
public void paintComponent(Graphics g)
{
g.setColor(Color.white);
}
}
- void clearSeqRefs()
- {
- if (_cleartables)
- {
- if (seqRefIds != null)
- {
- seqRefIds.clear();
- }
- if (seqsToIds != null)
- {
- seqsToIds.clear();
- }
- if (incompleteSeqs != null)
- {
- incompleteSeqs.clear();
- }
- // seqRefIds = null;
- // seqsToIds = null;
- }
- else
- {
- // do nothing
- warn("clearSeqRefs called when _cleartables was not set. Doing nothing.");
- // seqRefIds = new Hashtable();
- // seqsToIds = new IdentityHashMap();
- }
- }
-
void initSeqRefs()
{
if (seqsToIds == null)
// SAVE TREES
// /////////////////////////////////
- if (!storeDS && av.currentTree != null)
+ if (!storeDS && av.getCurrentTree() != null)
{
// FIND ANY ASSOCIATED TREES
// NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
{
Tree tree = new Tree();
tree.setTitle(tp.getTitle());
- tree.setCurrentTree((av.currentTree == tp.getTree()));
+ tree.setCurrentTree((av.getCurrentTree() == tp.getTree()));
tree.setNewick(tp.getTree().print());
tree.setThreshold(tp.treeCanvas.threshold);
jarInputStreamProvider jprovider = createjarInputStreamProvider(file);
af = loadJalviewAlign(jprovider);
+ af.setMenusForViewport();
} catch (MalformedURLException e)
{
StructureData filedat = oldFiles.get(id);
String pdbFile = filedat.getFilePath();
SequenceI[] seq = filedat.getSeqList().toArray(new SequenceI[0]);
- binding.getSsm().setMapping(seq, null, pdbFile, DataSourceType.FILE);
+ binding.getSsm().setMapping(seq, null, pdbFile, DataSourceType.FILE,
+ null);
binding.addSequenceForStructFile(pdbFile, seq);
}
// and add the AlignmentPanel's reference to the view panel
}
- public jalview.gui.AlignmentPanel copyAlignPanel(AlignmentPanel ap,
- boolean keepSeqRefs)
+ /**
+ * Provides a 'copy' of an alignment view (on action New View) by 'saving' the
+ * view as XML (but not to file), and then reloading it
+ *
+ * @param ap
+ * @return
+ */
+ public AlignmentPanel copyAlignPanel(AlignmentPanel ap)
{
initSeqRefs();
JalviewModel jm = saveState(ap, null, null, null);
- if (!keepSeqRefs)
- {
- clearSeqRefs();
- jm.getJalviewModelSequence().getViewport(0).setSequenceSetId(null);
- }
- else
- {
- uniqueSetSuffix = "";
- jm.getJalviewModelSequence().getViewport(0).setId(null); // we don't
- // overwrite the
- // view we just
- // copied
- }
+ uniqueSetSuffix = "";
+ jm.getJalviewModelSequence().getViewport(0).setId(null);
+ // we don't overwrite the view we just copied
+
if (this.frefedSequence == null)
{
- frefedSequence = new Vector();
+ frefedSequence = new Vector<SeqFref>();
}
viewportsAdded.clear();
return af.alignPanel;
}
- /**
- * flag indicating if hashtables should be cleared on finalization TODO this
- * flag may not be necessary
- */
- private final boolean _cleartables = true;
-
private Hashtable jvids2vobj;
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#finalize()
- */
- @Override
- protected void finalize() throws Throwable
- {
- // really make sure we have no buried refs left.
- if (_cleartables)
- {
- clearSeqRefs();
- }
- this.seqRefIds = null;
- this.seqsToIds = null;
- super.finalize();
- }
-
private void warn(String msg)
{
warn(msg, null);
@Override
public void paintComponent(Graphics g)
{
+ // super.paintComponent(g);
+
if (restart)
{
if (lastMiniMe == null)
&& ((getWidth() != od.getWidth())
|| (getHeight() != od.getHeight())))
{
- // if there is annotation, scale the alignment and annotation separately
+ // if there is annotation, scale the alignment and annotation
+ // separately
if (od.getGraphHeight() > 0)
{
BufferedImage topImage = lastMiniMe.getSubimage(0, 0,
od.setHeight(getHeight());
}
- // scale lastMiniMe to the new size
- g.drawImage(lastMiniMe, 0, 0, getWidth(), getHeight(), this);
-
// make sure the box is in the right place
od.setBoxPosition(av.getAlignment().getHiddenSequences(),
av.getAlignment().getHiddenColumns());
}
- else // not a resize
- {
- // fall back to normal behaviour
- g.drawImage(lastMiniMe, 0, 0, getWidth(), getHeight(), this);
- }
+ // fall back to normal behaviour
+ g.drawImage(lastMiniMe, 0, 0, getWidth(), getHeight(), this);
}
-
+ else
+ {
+ g.drawImage(lastMiniMe, 0, 0, getWidth(), getHeight(), this);
+ }
+
// draw the box
g.setColor(Color.red);
od.drawBox(g);
}
+
public void dispose()
{
dispose = true;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.beans.PropertyChangeEvent;
+import java.beans.PropertyVetoException;
import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
* changed
*
*/
+ private void setBoxPositionOnly()
+ {
+ if (od != null)
+ {
+ int oldX = od.getBoxX();
+ int oldY = od.getBoxY();
+ int oldWidth = od.getBoxWidth();
+ int oldHeight = od.getBoxHeight();
+ od.setBoxPosition(av.getAlignment().getHiddenSequences(),
+ av.getAlignment().getHiddenColumns());
+ repaint(oldX - 1, oldY - 1, oldWidth + 2, oldHeight + 2);
+ repaint(od.getBoxX(), od.getBoxY(), od.getBoxWidth(),
+ od.getBoxHeight());
+ }
+ }
+
private void setBoxPosition()
{
if (od != null)
@Override
public void propertyChange(PropertyChangeEvent evt)
{
- setBoxPosition();
+ setBoxPositionOnly();
}
/**
{
try
{
- av.getRanges().removePropertyChangeListener(this);
+ if (av != null)
+ {
+ av.getRanges().removePropertyChangeListener(this);
+ }
+
oviewCanvas.dispose();
+
+ /*
+ * close the parent frame (which also removes it from the
+ * Desktop Windows menu)
+ */
+ ((JInternalFrame) SwingUtilities.getAncestorOfClass(
+ JInternalFrame.class, (this))).setClosed(true);
+ } catch (PropertyVetoException e)
+ {
+ // ignore
} finally
{
progressPanel = null;
int top = 0;
+ private boolean working;
+
/**
* Creates a new PCAPanel object using default score model and parameters
*
message = MessageManager.getString("label.pca_calculating");
}
progress.setProgressBar(message, progId);
+ working = true;
try
{
calcSettings.setEnabled(false);
} catch (OutOfMemoryError er)
{
new OOMWarning("calculating PCA", er);
+ working = false;
return;
} finally
{
.getString("label.principal_component_analysis"), 475, 450);
this.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
}
+ working = false;
}
@Override
top = t;
zCombobox.setSelectedIndex(2);
}
+
+ /**
+ * Answers true if PCA calculation is in progress, else false
+ *
+ * @return
+ */
+ public boolean isWorking()
+ {
+ return working;
+ }
}
import java.awt.Component;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
/**
* Route datamodel/view update events for a sequence set to any display
*/
public static void RemoveComponent(Component comp)
{
- List<String> emptied = new ArrayList<String>();
- for (Entry<String, List<Component>> registered : components.entrySet())
+ if (components == null)
{
- String id = registered.getKey();
- List<Component> comps = components.get(id);
+ return;
+ }
+
+ Iterator<String> it = components.keySet().iterator();
+ while (it.hasNext())
+ {
+ List<Component> comps = components.get(it.next());
comps.remove(comp);
if (comps.isEmpty())
{
- emptied.add(id);
+ it.remove();
}
}
-
- /*
- * Remove now empty ids after the above (to avoid
- * ConcurrentModificationException).
- */
- for (String id : emptied)
- {
- components.remove(id);
- }
}
public static void Refresh(Component source, String id)
import jalview.analysis.AlignSeq;
import jalview.datamodel.Alignment;
-import jalview.datamodel.Sequence;
+import jalview.datamodel.AlignmentView;
+import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.jbgui.GPairwiseAlignPanel;
import jalview.util.MessageManager;
public class PairwiseAlignPanel extends GPairwiseAlignPanel
{
+ private static final String DASHES = "---------------------\n";
+
AlignmentViewport av;
- Vector sequences;
+ Vector<SequenceI> sequences;
/**
* Creates a new PairwiseAlignPanel object.
*
- * @param av
+ * @param viewport
* DOCUMENT ME!
*/
- public PairwiseAlignPanel(AlignmentViewport av)
+ public PairwiseAlignPanel(AlignmentViewport viewport)
{
super();
- this.av = av;
+ this.av = viewport;
- sequences = new Vector();
+ sequences = new Vector<SequenceI>();
- SequenceI[] seqs;
- String[] seqStrings = av.getViewAsString(true);
+ SequenceGroup selectionGroup = viewport.getSelectionGroup();
+ boolean isSelection = selectionGroup != null
+ && selectionGroup.getSize() > 0;
+ AlignmentView view = viewport.getAlignmentView(isSelection);
+ // String[] seqStrings = viewport.getViewAsString(true);
+ String[] seqStrings = view.getSequenceStrings(viewport
+ .getGapCharacter());
- if (av.getSelectionGroup() == null)
+ SequenceI[] seqs;
+ if (isSelection)
{
- seqs = av.getAlignment().getSequencesArray();
+ seqs = (SequenceI[]) view.getAlignmentAndHiddenColumns(viewport
+ .getGapCharacter())[0];
}
else
{
- seqs = av.getSelectionGroup().getSequencesInOrder(av.getAlignment());
+ seqs = av.getAlignment().getSequencesArray();
}
- String type = (av.getAlignment().isNucleotide()) ? AlignSeq.DNA
+ String type = (viewport.getAlignment().isNucleotide()) ? AlignSeq.DNA
: AlignSeq.PEP;
float[][] scores = new float[seqs.length][seqs.length];
- double totscore = 0;
+ double totscore = 0D;
int count = seqs.length;
-
- Sequence seq;
+ boolean first = true;
for (int i = 1; i < count; i++)
{
for (int j = 0; j < i; j++)
{
-
AlignSeq as = new AlignSeq(seqs[i], seqStrings[i], seqs[j],
seqStrings[j], type);
as.calcScoreMatrix();
as.traceAlignment();
+ if (!first)
+ {
+ System.out.println(DASHES);
+ textarea.append(DASHES);
+ }
+ first = false;
as.printAlignment(System.out);
- scores[i][j] = (float) as.getMaxScore()
- / (float) as.getASeq1().length;
+ scores[i][j] = as.getMaxScore()
+ / as.getASeq1().length;
totscore = totscore + scores[i][j];
textarea.append(as.getOutput());
if (count > 2)
{
- System.out.println(
- "Pairwise alignment scaled similarity score matrix\n");
+ printScoreMatrix(seqs, scores, totscore);
+ }
+ }
- for (int i = 0; i < count; i++)
- {
- jalview.util.Format.print(System.out, "%s \n",
- ("" + i) + " " + seqs[i].getName());
- }
+ /**
+ * Prints a matrix of seqi-seqj pairwise alignment scores to sysout
+ *
+ * @param seqs
+ * @param scores
+ * @param totscore
+ */
+ protected void printScoreMatrix(SequenceI[] seqs, float[][] scores,
+ double totscore)
+ {
+ System.out
+ .println("Pairwise alignment scaled similarity score matrix\n");
- System.out.println("\n");
+ for (int i = 0; i < seqs.length; i++)
+ {
+ System.out.println(String.format("%3d %s", i + 1,
+ seqs[i].getDisplayId(true)));
+ }
+
+ /*
+ * table heading columns for sequences 1, 2, 3...
+ */
+ System.out.print("\n ");
+ for (int i = 0; i < seqs.length; i++)
+ {
+ System.out.print(String.format("%7d", i + 1));
+ }
+ System.out.println();
- for (int i = 0; i < count; i++)
+ for (int i = 0; i < seqs.length; i++)
+ {
+ System.out.print(String.format("%3d", i + 1));
+ for (int j = 0; j < i; j++)
{
- for (int j = 0; j < i; j++)
- {
- jalview.util.Format.print(System.out, "%7.3f",
- scores[i][j] / totscore);
- }
+ /*
+ * as a fraction of tot score, outputs are 0 <= score <= 1
+ */
+ System.out.print(String.format("%7.3f", scores[i][j] / totscore));
}
-
- System.out.println("\n");
+ System.out.println();
}
+
+ System.out.println("\n");
}
/**
* @param e
* DOCUMENT ME!
*/
+ @Override
protected void viewInEditorButton_actionPerformed(ActionEvent e)
{
- Sequence[] seq = new Sequence[sequences.size()];
+ SequenceI[] seq = new SequenceI[sequences.size()];
for (int i = 0; i < sequences.size(); i++)
{
- seq[i] = (Sequence) sequences.elementAt(i);
+ seq[i] = sequences.elementAt(i);
}
AlignFrame af = new AlignFrame(new Alignment(seq),
}
sequence.setName(dialog.getName().replace(' ', '_'));
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
sequence.setDescription(dialog.getDescription());
}
this.statusPanel = container;
this.statusBar = statusBar;
- this.progressBars = new Hashtable<Long, JPanel>();
- this.progressBarHandlers = new Hashtable<Long, IProgressIndicatorHandler>();
+ this.progressBars = new Hashtable<>();
+ this.progressBarHandlers = new Hashtable<>();
}
* execution.
*/
@Override
- public void setProgressBar(String message, long id)
+ public void setProgressBar(final String message, final long id)
{
- Long longId = Long.valueOf(id);
-
- JPanel progressPanel = progressBars.get(longId);
- if (progressPanel != null)
+ SwingUtilities.invokeLater(new Runnable()
{
- /*
- * Progress bar is displayed for this id - remove it now, and any handler
- */
- progressBars.remove(id);
- if (message != null && statusBar != null)
- {
- statusBar.setText(message);
- }
- if (progressBarHandlers.containsKey(longId))
+ @Override
+ public void run()
{
- progressBarHandlers.remove(longId);
- }
- removeRow(progressPanel);
- }
- else
- {
- /*
- * No progress bar for this id - add one now
- */
- progressPanel = new JPanel(new BorderLayout(10, 5));
+ JPanel progressPanel = progressBars.get(id);
+ if (progressPanel != null)
+ {
+ /*
+ * Progress bar is displayed for this id - remove it now, and any handler
+ */
+ progressBars.remove(id);
+ if (message != null && statusBar != null)
+ {
+ statusBar.setText(message);
+ }
+ if (progressBarHandlers.containsKey(id))
+ {
+ progressBarHandlers.remove(id);
+ }
+ removeRow(progressPanel);
+ }
+ else
+ {
+ /*
+ * No progress bar for this id - add one now
+ */
+ progressPanel = new JPanel(new BorderLayout(10, 5));
- JProgressBar progressBar = new JProgressBar();
- progressBar.setIndeterminate(true);
+ JProgressBar progressBar = new JProgressBar();
+ progressBar.setIndeterminate(true);
- progressPanel.add(new JLabel(message), BorderLayout.WEST);
- progressPanel.add(progressBar, BorderLayout.CENTER);
+ progressPanel.add(new JLabel(message), BorderLayout.WEST);
+ progressPanel.add(progressBar, BorderLayout.CENTER);
- addRow(progressPanel);
+ addRow(progressPanel);
- progressBars.put(longId, progressPanel);
- }
+ progressBars.put(id, progressPanel);
+ }
+
+ refreshLayout();
+ }
+ });
- refreshLayout();
}
/**
public void registerHandler(final long id,
final IProgressIndicatorHandler handler)
{
- Long longId = Long.valueOf(id);
- final JPanel progressPanel = progressBars.get(longId);
- if (progressPanel == null)
- {
- System.err.println(
- "call setProgressBar before registering the progress bar's handler.");
- return;
- }
-
- /*
- * Nothing useful to do if not a Cancel handler
- */
- if (!handler.canCancel())
- {
- return;
- }
-
- progressBarHandlers.put(longId, handler);
- JButton cancel = new JButton(MessageManager.getString("action.cancel"));
final IProgressIndicator us = this;
- cancel.addActionListener(new ActionListener()
- {
+ SwingUtilities.invokeLater(new Runnable()
+ {
@Override
- public void actionPerformed(ActionEvent e)
+ public void run()
{
- handler.cancelActivity(id);
- us.setProgressBar(MessageManager
- .formatMessage("label.cancelled_params", new Object[]
- { ((JLabel) progressPanel.getComponent(0)).getText() }),
- id);
+ final JPanel progressPanel = progressBars.get(id);
+ if (progressPanel == null)
+ {
+ System.err.println(
+ "call setProgressBar before registering the progress bar's handler.");
+ return;
+ }
+
+ /*
+ * Nothing useful to do if not a Cancel handler
+ */
+ if (!handler.canCancel())
+ {
+ return;
+ }
+
+ progressBarHandlers.put(id, handler);
+ JButton cancel = new JButton(
+ MessageManager.getString("action.cancel"));
+ cancel.addActionListener(new ActionListener()
+ {
+
+ @Override
+ public void actionPerformed(ActionEvent e)
+ {
+ handler.cancelActivity(id);
+ us.setProgressBar(MessageManager
+ .formatMessage("label.cancelled_params", new Object[]
+ { ((JLabel) progressPanel.getComponent(0)).getText() }),
+ id);
+ }
+ });
+ progressPanel.add(cancel, BorderLayout.EAST);
+ refreshLayout();
+
}
});
- progressPanel.add(cancel, BorderLayout.EAST);
- refreshLayout();
}
}
import java.awt.Component;
-import javax.swing.JOptionPane;
-
public class PromptUserConfig implements Runnable
{
/**
this.allowCancel = allowCancel;
}
+ @Override
public void run()
{
if (property == null)
(allowCancel) ? JvOptionPane.YES_NO_CANCEL_OPTION
: JvOptionPane.YES_NO_OPTION,
JvOptionPane.QUESTION_MESSAGE);
- // now, ask the desktop to relayer any external windows that might have
- // been obsured
- if (Desktop.instance != null)
- {
- Desktop.instance.relayerWindows();
- }
+
// and finish parsing the result
jalview.bin.Cache.log.debug("Got response : " + reply);
if (reply == JvOptionPane.YES_OPTION)
AlignmentPanel ap;
- Stack<CommandI> historyList = new Stack<CommandI>();
+ Stack<CommandI> historyList = new Stack<>();
// simpler than synching with alignFrame.
}
float value = slider.getValue();
- List<SequenceI> redundantSequences = new ArrayList<SequenceI>();
+ List<SequenceI> redundantSequences = new ArrayList<>();
for (int i = 0; i < redundancy.length; i++)
{
if (value <= redundancy[i])
af.updateEditMenuBar();
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
if (historyList.size() == 0)
{
{
av.showColumn(reveal[0]);
reveal = null;
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
av.sendSelection();
}
});
{
av.showAllHiddenColumns();
reveal = null;
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
av.sendSelection();
}
});
av.setSelectionGroup(null);
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
av.sendSelection();
}
});
sg.setEndRes(max);
}
av.setSelectionGroup(sg);
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
av.sendSelection();
}
}
else
{
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
return;
}
}
}
stretchingGroup = false;
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
av.sendSelection();
}
{
stretchingGroup = true;
cs.stretchGroup(res, sg, min, max);
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
}
import jalview.datamodel.SequenceI;
import jalview.renderer.ScaleRenderer;
import jalview.renderer.ScaleRenderer.ScaleMark;
+import jalview.util.Comparison;
import jalview.viewmodel.ViewportListenerI;
import jalview.viewmodel.ViewportRanges;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.util.Iterator;
+import java.util.List;
import javax.swing.JComponent;
/**
- * DOCUMENT ME!
+ * The Swing component on which the alignment sequences, and annotations (if
+ * shown), are drawn. This includes scales above, left and right (if shown) in
+ * Wrapped mode, but not the scale above in Unwrapped mode.
*
- * @author $author$
- * @version $Revision$
*/
public class SeqCanvas extends JComponent implements ViewportListenerI
{
- private static String ZEROS = "0000000000";
+ private static final String ZEROS = "0000000000";
final FeatureRenderer fr;
- final SequenceRenderer seqRdr;
-
BufferedImage img;
- Graphics2D gg;
-
AlignViewport av;
- boolean fastPaint = false;
+ int cursorX = 0;
- int labelWidthWest;
+ int cursorY = 0;
- int labelWidthEast;
+ private final SequenceRenderer seqRdr;
- int cursorX = 0;
+ private boolean fastPaint = false;
- int cursorY = 0;
+ private boolean fastpainting = false;
- int charHeight = 0;
+ private AnnotationPanel annotations;
- int charWidth = 0;
+ /*
+ * measurements for drawing a wrapped alignment
+ */
+ private int labelWidthEast; // label right width in pixels if shown
+
+ private int labelWidthWest; // label left width in pixels if shown
- boolean fastpainting = false;
+ private int wrappedSpaceAboveAlignment; // gap between widths
- AnnotationPanel annotations;
+ private int wrappedRepeatHeightPx; // height in pixels of wrapped width
+
+ private int wrappedVisibleWidths; // number of wrapped widths displayed
+
+ private Graphics2D gg;
/**
* Creates a new SeqCanvas object.
*
- * @param av
- * DOCUMENT ME!
+ * @param ap
*/
public SeqCanvas(AlignmentPanel ap)
{
this.av = ap.av;
- updateViewport();
fr = new FeatureRenderer(ap);
seqRdr = new SequenceRenderer(av);
setLayout(new BorderLayout());
return fr;
}
- private void updateViewport()
- {
- charHeight = av.getCharHeight();
- charWidth = av.getCharWidth();
- }
-
/**
- * DOCUMENT ME!
+ * Draws the scale above a region of a wrapped alignment, consisting of a
+ * column number every major interval (10 columns).
*
* @param g
- * DOCUMENT ME!
+ * the graphics context to draw on, positioned at the start (bottom
+ * left) of the line on which to draw any scale marks
* @param startx
- * DOCUMENT ME!
+ * start alignment column (0..)
* @param endx
- * DOCUMENT ME!
+ * end alignment column (0..)
* @param ypos
- * DOCUMENT ME!
+ * y offset to draw at
*/
private void drawNorthScale(Graphics g, int startx, int endx, int ypos)
{
- updateViewport();
- for (ScaleMark mark : new ScaleRenderer().calculateMarks(av, startx,
- endx))
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+
+ /*
+ * white fill the scale space (for the fastPaint case)
+ */
+ g.setColor(Color.white);
+ g.fillRect(0, ypos - charHeight - charHeight / 2, getWidth(),
+ charHeight * 3 / 2 + 2);
+ g.setColor(Color.black);
+
+ List<ScaleMark> marks = new ScaleRenderer().calculateMarks(av, startx,
+ endx);
+ for (ScaleMark mark : marks)
{
int mpos = mark.column; // (i - startx - 1)
if (mpos < 0)
{
g.drawString(mstring, mpos * charWidth, ypos - (charHeight / 2));
}
- g.drawLine((mpos * charWidth) + (charWidth / 2),
- (ypos + 2) - (charHeight / 2),
- (mpos * charWidth) + (charWidth / 2), ypos - 2);
+
+ /*
+ * draw a tick mark below the column number, centred on the column;
+ * height of tick mark is 4 pixels less than half a character
+ */
+ int xpos = (mpos * charWidth) + (charWidth / 2);
+ g.drawLine(xpos, (ypos + 2) - (charHeight / 2), xpos, ypos - 2);
}
}
}
/**
- * DOCUMENT ME!
+ * Draw the scale to the left or right of a wrapped alignment
*
* @param g
- * DOCUMENT ME!
+ * graphics context, positioned at the start of the scale to be drawn
* @param startx
- * DOCUMENT ME!
+ * first column of wrapped width (0.. excluding any hidden columns)
* @param endx
- * DOCUMENT ME!
+ * last column of wrapped width (0.. excluding any hidden columns)
* @param ypos
- * DOCUMENT ME!
+ * vertical offset at which to begin the scale
+ * @param left
+ * if true, scale is left of residues, if false, scale is right
*/
- void drawWestScale(Graphics g, int startx, int endx, int ypos)
+ void drawVerticalScale(Graphics g, final int startx, final int endx,
+ final int ypos, final boolean left)
{
- FontMetrics fm = getFontMetrics(av.getFont());
- ypos += charHeight;
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
- if (av.hasHiddenColumns())
- {
- startx = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(startx);
- endx = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(endx);
- }
+ int yPos = ypos + charHeight;
+ int startX = startx;
+ int endX = endx;
- int maxwidth = av.getAlignment().getWidth();
if (av.hasHiddenColumns())
{
- maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth) - 1;
+ HiddenColumns hiddenColumns = av.getAlignment().getHiddenColumns();
+ startX = hiddenColumns.adjustForHiddenColumns(startx);
+ endX = hiddenColumns.adjustForHiddenColumns(endx);
}
+ FontMetrics fm = getFontMetrics(av.getFont());
- // WEST SCALE
for (int i = 0; i < av.getAlignment().getHeight(); i++)
{
SequenceI seq = av.getAlignment().getSequenceAt(i);
- int index = startx;
- int value = -1;
- while (index < endx)
+ /*
+ * find sequence position of first non-gapped position -
+ * to the right if scale left, to the left if scale right
+ */
+ int index = left ? startX : endX;
+ int value = -1;
+ while (index >= startX && index <= endX)
{
- if (jalview.util.Comparison.isGap(seq.getCharAt(index)))
+ if (!Comparison.isGap(seq.getCharAt(index)))
+ {
+ value = seq.findPosition(index);
+ break;
+ }
+ if (left)
{
index++;
-
- continue;
}
-
- value = av.getAlignment().getSequenceAt(i).findPosition(index);
-
- break;
- }
-
- if (value != -1)
- {
- int x = labelWidthWest - fm.stringWidth(String.valueOf(value))
- - charWidth / 2;
- g.drawString(value + "", x,
- (ypos + (i * charHeight)) - (charHeight / 5));
- }
- }
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param g
- * DOCUMENT ME!
- * @param startx
- * DOCUMENT ME!
- * @param endx
- * DOCUMENT ME!
- * @param ypos
- * DOCUMENT ME!
- */
- void drawEastScale(Graphics g, int startx, int endx, int ypos)
- {
- ypos += charHeight;
-
- if (av.hasHiddenColumns())
- {
- endx = av.getAlignment().getHiddenColumns()
- .adjustForHiddenColumns(endx);
- }
-
- SequenceI seq;
- // EAST SCALE
- for (int i = 0; i < av.getAlignment().getHeight(); i++)
- {
- seq = av.getAlignment().getSequenceAt(i);
- int index = endx;
- int value = -1;
-
- while (index > startx)
- {
- if (jalview.util.Comparison.isGap(seq.getCharAt(index)))
+ else
{
index--;
-
- continue;
}
-
- value = seq.findPosition(index);
-
- break;
}
+ /*
+ * white fill the space for the scale
+ */
+ g.setColor(Color.white);
+ int y = (yPos + (i * charHeight)) - (charHeight / 5);
+ // fillRect origin is top left of rectangle
+ g.fillRect(0, y - charHeight, left ? labelWidthWest : labelWidthEast,
+ charHeight + 1);
+
if (value != -1)
{
- g.drawString(String.valueOf(value), 0,
- (ypos + (i * charHeight)) - (charHeight / 5));
+ /*
+ * draw scale value, right justified within its width less half a
+ * character width padding on the right
+ */
+ int labelSpace = left ? labelWidthWest : labelWidthEast;
+ labelSpace -= charWidth / 2; // leave space to the right
+ String valueAsString = String.valueOf(value);
+ int labelLength = fm.stringWidth(valueAsString);
+ int xOffset = labelSpace - labelLength;
+ g.setColor(Color.black);
+ g.drawString(valueAsString, xOffset, y);
}
}
}
-
/**
- * need to make this thread safe move alignment rendering in response to
- * slider adjustment
+ * Does a fast paint of an alignment in response to a scroll. Most of the
+ * visible region is simply copied and shifted, and then any newly visible
+ * columns or rows are drawn. The scroll may be horizontal or vertical, but
+ * not both at once. Scrolling may be the result of
+ * <ul>
+ * <li>dragging a scroll bar</li>
+ * <li>clicking in the scroll bar</li>
+ * <li>scrolling by trackpad, middle mouse button, or other device</li>
+ * <li>by moving the box in the Overview window</li>
+ * <li>programmatically to make a highlighted position visible</li>
+ * </ul>
*
* @param horizontal
- * shift along
+ * columns to shift right (positive) or left (negative)
* @param vertical
- * shift up or down in repaint
+ * rows to shift down (positive) or up (negative)
*/
public void fastPaint(int horizontal, int vertical)
{
}
fastpainting = true;
fastPaint = true;
- updateViewport();
- ViewportRanges ranges = av.getRanges();
- int startRes = ranges.getStartRes();
- int endRes = ranges.getEndRes();
- int startSeq = ranges.getStartSeq();
- int endSeq = ranges.getEndSeq();
- int transX = 0;
- int transY = 0;
+ try
+ {
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+
+ ViewportRanges ranges = av.getRanges();
+ int startRes = ranges.getStartRes();
+ int endRes = ranges.getEndRes();
+ int startSeq = ranges.getStartSeq();
+ int endSeq = ranges.getEndSeq();
+ int transX = 0;
+ int transY = 0;
gg.copyArea(horizontal * charWidth, vertical * charHeight,
img.getWidth(), img.getHeight(), -horizontal * charWidth,
gg.translate(-transX, -transY);
repaint();
- fastpainting = false;
+ } finally
+ {
+ fastpainting = false;
+ }
}
@Override
public void paintComponent(Graphics g)
{
- super.paintComponent(g);
-
- updateViewport();
+ super.paintComponent(g);
+
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
ViewportRanges ranges = av.getRanges();
g.drawImage(lcimg, 0, 0, this);
}
}
-
+
/**
* Draw an alignment panel for printing
*
{
BufferedImage lcimg = null;
+ int charWidth = av.getCharWidth();
+ int charHeight = av.getCharHeight();
+
int width = getWidth();
int height = getHeight();
*/
public int getWrappedCanvasWidth(int canvasWidth)
{
- FontMetrics fm = getFontMetrics(av.getFont());
+ int charWidth = av.getCharWidth();
- labelWidthEast = 0;
- labelWidthWest = 0;
+ FontMetrics fm = getFontMetrics(av.getFont());
- if (av.getScaleRightWrapped())
+ int labelWidth = 0;
+
+ if (av.getScaleRightWrapped() || av.getScaleLeftWrapped())
{
- labelWidthEast = getLabelWidth(fm);
+ labelWidth = getLabelWidth(fm);
}
- if (av.getScaleLeftWrapped())
- {
- labelWidthWest = labelWidthEast > 0 ? labelWidthEast
- : getLabelWidth(fm);
- }
+ labelWidthEast = av.getScaleRightWrapped() ? labelWidth : 0;
+
+ labelWidthWest = av.getScaleLeftWrapped() ? labelWidth : 0;
return (canvasWidth - labelWidthEast - labelWidthWest) / charWidth;
}
/**
- * Returns a pixel width suitable for showing the largest sequence coordinate
- * (end position) in the alignment. Returns 2 plus the number of decimal
- * digits to be shown (3 for 1-10, 4 for 11-99 etc).
+ * Returns a pixel width sufficient to show the largest sequence coordinate
+ * (end position) in the alignment, calculated as the FontMetrics width of
+ * zeroes "0000000" limited to the number of decimal digits to be shown (3 for
+ * 1-10, 4 for 11-99 etc). One character width is added to this, to allow for
+ * half a character width space on either side.
*
* @param fm
* @return
maxWidth = Math.max(maxWidth, alignment.getSequenceAt(i).getEnd());
}
- int length = 2;
+ int length = 0;
for (int i = maxWidth; i > 0; i /= 10)
{
length++;
}
- return fm.stringWidth(ZEROS.substring(0, length));
+ return fm.stringWidth(ZEROS.substring(0, length)) + av.getCharWidth();
}
/**
- * DOCUMENT ME!
+ * Draws as many widths of a wrapped alignment as can fit in the visible
+ * window
*
* @param g
- * DOCUMENT ME!
* @param canvasWidth
- * DOCUMENT ME!
+ * available width in pixels
* @param canvasHeight
- * DOCUMENT ME!
- * @param startRes
- * DOCUMENT ME!
+ * available height in pixels
+ * @param startColumn
+ * the first column (0...) of the alignment to draw
*/
- private void drawWrappedPanel(Graphics g, int canvasWidth,
- int canvasHeight, int startRes)
+ public void drawWrappedPanel(Graphics g, int canvasWidth,
+ int canvasHeight, final int startColumn)
{
- updateViewport();
- AlignmentI al = av.getAlignment();
+ int wrappedWidthInResidues = calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
- int labelWidth = 0;
- if (av.getScaleRightWrapped() || av.getScaleLeftWrapped())
+ av.setWrappedWidth(wrappedWidthInResidues);
+
+ ViewportRanges ranges = av.getRanges();
+ ranges.setViewportStartAndWidth(startColumn, wrappedWidthInResidues);
+
+ /*
+ * draw one width at a time (including any scales or annotation shown),
+ * until we have run out of either alignment or vertical space available
+ */
+ int ypos = wrappedSpaceAboveAlignment;
+ int maxWidth = ranges.getVisibleAlignmentWidth();
+
+ int start = startColumn;
+ int currentWidth = 0;
+ while ((currentWidth < wrappedVisibleWidths) && (start < maxWidth))
{
- FontMetrics fm = getFontMetrics(av.getFont());
- labelWidth = getLabelWidth(fm);
+ int endColumn = Math
+ .min(maxWidth, start + wrappedWidthInResidues - 1);
+ drawWrappedWidth(g, ypos, start, endColumn, canvasHeight);
+ ypos += wrappedRepeatHeightPx;
+ start += wrappedWidthInResidues;
+ currentWidth++;
}
- labelWidthEast = av.getScaleRightWrapped() ? labelWidth : 0;
- labelWidthWest = av.getScaleLeftWrapped() ? labelWidth : 0;
+ drawWrappedDecorators(g, startColumn);
+ }
- int hgap = charHeight;
- if (av.getScaleAboveWrapped())
+ /**
+ * Calculates and saves values needed when rendering a wrapped alignment.
+ * These depend on many factors, including
+ * <ul>
+ * <li>canvas width and height</li>
+ * <li>number of visible sequences, and height of annotations if shown</li>
+ * <li>font and character width</li>
+ * <li>whether scales are shown left, right or above the alignment</li>
+ * </ul>
+ *
+ * @param canvasWidth
+ * @param canvasHeight
+ * @return the number of residue columns in each width
+ */
+ protected int calculateWrappedGeometry(int canvasWidth, int canvasHeight)
+ {
+ int charHeight = av.getCharHeight();
+
+ /*
+ * vertical space in pixels between wrapped widths of alignment
+ * - one character height, or two if scale above is drawn
+ */
+ wrappedSpaceAboveAlignment = charHeight
+ * (av.getScaleAboveWrapped() ? 2 : 1);
+
+ /*
+ * height in pixels of the wrapped widths
+ */
+ wrappedRepeatHeightPx = wrappedSpaceAboveAlignment;
+ // add sequences
+ wrappedRepeatHeightPx += av.getRanges().getViewportHeight()
+ * charHeight;
+ // add annotations panel height if shown
+ wrappedRepeatHeightPx += getAnnotationHeight();
+
+ /*
+ * number of visible widths (the last one may be part height),
+ * ensuring a part height includes at least one sequence
+ */
+ ViewportRanges ranges = av.getRanges();
+ wrappedVisibleWidths = canvasHeight / wrappedRepeatHeightPx;
+ int remainder = canvasHeight % wrappedRepeatHeightPx;
+ if (remainder >= (wrappedSpaceAboveAlignment + charHeight))
{
- hgap += charHeight;
+ wrappedVisibleWidths++;
}
- int cWidth = (canvasWidth - labelWidthEast - labelWidthWest) / charWidth;
- int cHeight = av.getAlignment().getHeight() * charHeight;
+ /*
+ * compute width in residues; this also sets East and West label widths
+ */
+ int wrappedWidthInResidues = getWrappedCanvasWidth(canvasWidth);
- av.setWrappedWidth(cWidth);
+ /*
+ * limit visibleWidths to not exceed width of alignment
+ */
+ int xMax = ranges.getVisibleAlignmentWidth();
+ int startToEnd = xMax - ranges.getStartRes();
+ int maxWidths = startToEnd / wrappedWidthInResidues;
+ if (startToEnd % wrappedWidthInResidues > 0)
+ {
+ maxWidths++;
+ }
+ wrappedVisibleWidths = Math.min(wrappedVisibleWidths, maxWidths);
- av.getRanges().setViewportStartAndWidth(startRes, cWidth);
+ return wrappedWidthInResidues;
+ }
- int endx;
- int ypos = hgap;
- int maxwidth = av.getAlignment().getWidth();
+ /**
+ * Draws one width of a wrapped alignment, including sequences and
+ * annnotations, if shown, but not scales or hidden column markers
+ *
+ * @param g
+ * @param ypos
+ * @param startColumn
+ * @param endColumn
+ * @param canvasHeight
+ */
+ protected void drawWrappedWidth(Graphics g, int ypos, int startColumn,
+ int endColumn, int canvasHeight)
+ {
+ ViewportRanges ranges = av.getRanges();
+ int viewportWidth = ranges.getViewportWidth();
- if (av.hasHiddenColumns())
+ int endx = Math.min(startColumn + viewportWidth - 1, endColumn);
+
+ /*
+ * move right before drawing by the width of the scale left (if any)
+ * plus column offset from left margin (usually zero, but may be non-zero
+ * when fast painting is drawing just a few columns)
+ */
+ int charWidth = av.getCharWidth();
+ int xOffset = labelWidthWest
+ + ((startColumn - ranges.getStartRes()) % viewportWidth)
+ * charWidth;
+ g.translate(xOffset, 0);
+
+ // When printing we have an extra clipped region,
+ // the Printable page which we need to account for here
+ Shape clip = g.getClip();
+
+ if (clip == null)
{
- maxwidth = av.getAlignment().getHiddenColumns()
- .findColumnPosition(maxwidth);
+ g.setClip(0, 0, viewportWidth * charWidth, canvasHeight);
+ }
+ else
+ {
+ g.setClip(0, (int) clip.getBounds().getY(),
+ viewportWidth * charWidth, (int) clip.getBounds().getHeight());
}
- int annotationHeight = getAnnotationHeight();
+ /*
+ * white fill the region to be drawn (so incremental fast paint doesn't
+ * scribble over an existing image)
+ */
+ gg.setColor(Color.white);
+ gg.fillRect(0, ypos, (endx - startColumn + 1) * charWidth,
+ wrappedRepeatHeightPx);
- while ((ypos <= canvasHeight) && (startRes < maxwidth))
- {
- endx = startRes + cWidth - 1;
+ drawPanel(g, startColumn, endx, 0, av.getAlignment().getHeight() - 1,
+ ypos);
- if (endx > maxwidth)
+ int cHeight = av.getAlignment().getHeight() * av.getCharHeight();
+
+ if (av.isShowAnnotation())
+ {
+ g.translate(0, cHeight + ypos + 3);
+ if (annotations == null)
{
- endx = maxwidth;
+ annotations = new AnnotationPanel(av);
}
- g.setFont(av.getFont());
- g.setColor(Color.black);
+ annotations.renderer.drawComponent(annotations, av, g, -1,
+ startColumn, endx + 1);
+ g.translate(0, -cHeight - ypos - 3);
+ }
+ g.setClip(clip);
+ g.translate(-xOffset, 0);
+ }
+
+ /**
+ * Draws scales left, right and above (if shown), and any hidden column
+ * markers, on all widths of the wrapped alignment
+ *
+ * @param g
+ * @param startColumn
+ */
+ protected void drawWrappedDecorators(Graphics g, final int startColumn)
+ {
+ int charWidth = av.getCharWidth();
+
+ g.setFont(av.getFont());
+ g.setColor(Color.black);
+
+ int ypos = wrappedSpaceAboveAlignment;
+ ViewportRanges ranges = av.getRanges();
+ int viewportWidth = ranges.getViewportWidth();
+ int maxWidth = ranges.getVisibleAlignmentWidth();
+ int widthsDrawn = 0;
+ int startCol = startColumn;
+
+ while (widthsDrawn < wrappedVisibleWidths)
+ {
+ int endColumn = Math.min(maxWidth, startCol + viewportWidth - 1);
if (av.getScaleLeftWrapped())
{
- drawWestScale(g, startRes, endx, ypos);
+ drawVerticalScale(g, startCol, endColumn - 1, ypos, true);
}
if (av.getScaleRightWrapped())
{
- g.translate(canvasWidth - labelWidthEast, 0);
- drawEastScale(g, startRes, endx, ypos);
- g.translate(-(canvasWidth - labelWidthEast), 0);
+ int x = labelWidthWest + viewportWidth * charWidth;
+ g.translate(x, 0);
+ drawVerticalScale(g, startCol, endColumn, ypos, false);
+ g.translate(-x, 0);
}
+ /*
+ * white fill region of scale above and hidden column markers
+ * (to support incremental fast paint of image)
+ */
+ g.translate(labelWidthWest, 0);
+ g.setColor(Color.white);
+ g.fillRect(0, ypos - wrappedSpaceAboveAlignment, viewportWidth
+ * charWidth + labelWidthWest, wrappedSpaceAboveAlignment);
+ g.setColor(Color.black);
+ g.translate(-labelWidthWest, 0);
+
g.translate(labelWidthWest, 0);
if (av.getScaleAboveWrapped())
{
- drawNorthScale(g, startRes, endx, ypos);
+ drawNorthScale(g, startCol, endColumn, ypos);
}
if (av.hasHiddenColumns() && av.getShowHiddenMarkers())
{
- g.setColor(Color.blue);
- int res;
- HiddenColumns hidden = av.getAlignment().getHiddenColumns();
-
- Iterator<Integer> it = hidden.getBoundedStartIterator(startRes,
- endx + 1);
- while (it.hasNext())
- {
- res = it.next() - startRes;
- gg.fillPolygon(
- new int[]
- { res * charWidth - charHeight / 4,
- res * charWidth + charHeight / 4, res * charWidth },
- new int[]
- { ypos - (charHeight / 2), ypos - (charHeight / 2),
- ypos - (charHeight / 2) + 8 }, 3);
- }
+ drawHiddenColumnMarkers(g, ypos, startCol, endColumn);
}
- // When printing we have an extra clipped region,
- // the Printable page which we need to account for here
- Shape clip = g.getClip();
+ g.translate(-labelWidthWest, 0);
- if (clip == null)
- {
- g.setClip(0, 0, cWidth * charWidth, canvasHeight);
- }
- else
- {
- g.setClip(0, (int) clip.getBounds().getY(), cWidth * charWidth,
- (int) clip.getBounds().getHeight());
- }
+ ypos += wrappedRepeatHeightPx;
+ startCol += viewportWidth;
+ widthsDrawn++;
+ }
+ }
- drawPanel(g, startRes, endx, 0, al.getHeight() - 1, ypos);
+ /**
+ * Draws markers (triangles) above hidden column positions between startColumn
+ * and endColumn.
+ *
+ * @param g
+ * @param ypos
+ * @param startColumn
+ * @param endColumn
+ */
+ protected void drawHiddenColumnMarkers(Graphics g, int ypos,
+ int startColumn, int endColumn)
+ {
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
- if (av.isShowAnnotation())
- {
- g.translate(0, cHeight + ypos + 3);
- if (annotations == null)
- {
- annotations = new AnnotationPanel(av);
- }
+ g.setColor(Color.blue);
+ int res;
+ HiddenColumns hidden = av.getAlignment().getHiddenColumns();
- annotations.renderer.drawComponent(annotations, av, g, -1, startRes,
- endx + 1);
- g.translate(0, -cHeight - ypos - 3);
- }
- g.setClip(clip);
- g.translate(-labelWidthWest, 0);
+ Iterator<Integer> it = hidden.getBoundedStartIterator(startColumn,
+ endColumn);
+ while (it.hasNext())
+ {
+ res = it.next() - startColumn;
- ypos += cHeight + annotationHeight + hgap;
+ if (res < 0 || res > endColumn - startColumn + 1)
+ {
+ continue;
+ }
- startRes += cWidth;
+ /*
+ * draw a downward-pointing triangle at the hidden columns location
+ * (before the following visible column)
+ */
+ int xMiddle = res * charWidth;
+ int[] xPoints = new int[] { xMiddle - charHeight / 4,
+ xMiddle + charHeight / 4, xMiddle };
+ int yTop = ypos - (charHeight / 2);
+ int[] yPoints = new int[] { yTop, yTop, yTop + 8 };
+ g.fillPolygon(xPoints, yPoints, 3);
}
}
int canvasWidth,
int canvasHeight, int startRes)
{
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+
// height gap above each panel
int hgap = charHeight;
if (av.getScaleAboveWrapped())
* marker.
*
* @param g1
- * Graphics object to draw with
+ * the graphics context, positioned at the first residue to be drawn
* @param startRes
- * offset of the first column in the visible region (0..)
+ * offset of the first column to draw (0..)
* @param endRes
- * offset of the last column in the visible region (0..)
+ * offset of the last column to draw (0..)
* @param startSeq
- * offset of the first sequence in the visible region (0..)
+ * offset of the first sequence to draw (0..)
* @param endSeq
- * offset of the last sequence in the visible region (0..)
+ * offset of the last sequence to draw (0..)
* @param yOffset
* vertical offset at which to draw (for wrapped alignments)
*/
public void drawPanel(Graphics g1, final int startRes, final int endRes,
final int startSeq, final int endSeq, final int yOffset)
{
- updateViewport();
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+
if (!av.hasHiddenColumns())
{
draw(g1, startRes, endRes, startSeq, endSeq, yOffset);
private void draw(Graphics g, int startRes, int endRes, int startSeq,
int endSeq, int offset)
{
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+
g.setFont(av.getFont());
seqRdr.prepare(g, av.isRenderGaps());
private void drawUnwrappedSelection(Graphics2D g, SequenceGroup group,
int startRes, int endRes, int startSeq, int endSeq, int offset)
{
+ int charWidth = av.getCharWidth();
+
if (!av.hasHiddenColumns())
{
drawPartialGroupOutline(g, group, startRes, endRes, startSeq, endSeq,
int startRes, int endRes, int startSeq, int endSeq,
int verticalOffset)
{
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+
int visWidth = (endRes - startRes + 1) * charWidth;
int oldY = -1;
return false;
}
boolean wrapped = av.getWrapAlignment();
-
try
{
fastPaint = !noFastPaint;
fastpainting = fastPaint;
- updateViewport();
-
/*
* to avoid redrawing the whole visible region, we instead
* redraw just the minimal regions to remove previous highlights
{
fastPaint = true;
repaint();
+ return;
}
- else if (av.getWrapAlignment())
+
+ int scrollX = 0;
+ if (eventName.equals(ViewportRanges.STARTRES))
{
- if (eventName.equals(ViewportRanges.STARTRES))
+ // Make sure we're not trying to draw a panel
+ // larger than the visible window
+ ViewportRanges vpRanges = av.getRanges();
+ scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+ int range = vpRanges.getViewportWidth();
+ if (scrollX > range)
{
- repaint();
+ scrollX = range;
+ }
+ else if (scrollX < -range)
+ {
+ scrollX = -range;
}
}
- else
+
+ // 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.
+
+ // scroll - startres and endres both change
+ if (eventName.equals(ViewportRanges.STARTRES))
{
- int scrollX = 0;
- if (eventName.equals(ViewportRanges.STARTRES))
+ if (av.getWrapAlignment())
{
- // Make sure we're not trying to draw a panel
- // larger than the visible window
- ViewportRanges vpRanges = av.getRanges();
- scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
- int range = vpRanges.getEndRes() - vpRanges.getStartRes();
- if (scrollX > range)
- {
- scrollX = range;
- }
- else if (scrollX < -range)
- {
- scrollX = -range;
- }
+ fastPaintWrapped(scrollX);
}
-
- // 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))
+ else
{
- // scroll - startres and endres both change
fastPaint(scrollX, 0);
}
- else if (eventName.equals(ViewportRanges.STARTSEQ))
+ }
+ else if (eventName.equals(ViewportRanges.STARTSEQ))
+ {
+ // scroll
+ fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ }
+ }
+
+ /**
+ * Does a minimal update of the image for a scroll movement. This method
+ * handles scroll movements of up to one width of the wrapped alignment (one
+ * click in the vertical scrollbar). Larger movements (for example after a
+ * scroll to highlight a mapped position) trigger a full redraw instead.
+ *
+ * @param scrollX
+ * number of positions scrolled (right if positive, left if negative)
+ */
+ protected void fastPaintWrapped(int scrollX)
+ {
+ ViewportRanges ranges = av.getRanges();
+
+ if (Math.abs(scrollX) > ranges.getViewportWidth())
+ {
+ /*
+ * shift of more than one view width is
+ * overcomplicated to handle in this method
+ */
+ fastPaint = false;
+ repaint();
+ return;
+ }
+
+ if (fastpainting || gg == null)
+ {
+ return;
+ }
+
+ fastPaint = true;
+ fastpainting = true;
+
+ try
+ {
+ calculateWrappedGeometry(getWidth(), getHeight());
+
+ /*
+ * relocate the regions of the alignment that are still visible
+ */
+ shiftWrappedAlignment(-scrollX);
+
+ /*
+ * add new columns (sequence, annotation)
+ * - at top left if scrollX < 0
+ * - at right of last two widths if scrollX > 0
+ */
+ if (scrollX < 0)
+ {
+ int startRes = ranges.getStartRes();
+ drawWrappedWidth(gg, wrappedSpaceAboveAlignment, startRes, startRes
+ - scrollX - 1, getHeight());
+ }
+ else
{
- // scroll
- fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ fastPaintWrappedAddRight(scrollX);
}
+
+ /*
+ * draw all scales (if shown) and hidden column markers
+ */
+ drawWrappedDecorators(gg, ranges.getStartRes());
+
+ repaint();
+ } finally
+ {
+ fastpainting = false;
+ }
+ }
+
+ /**
+ * Draws the specified number of columns at the 'end' (bottom right) of a
+ * wrapped alignment view, including sequences and annotations if shown, but
+ * not scales. Also draws the same number of columns at the right hand end of
+ * the second last width shown, if the last width is not full height (so
+ * cannot simply be copied from the graphics image).
+ *
+ * @param columns
+ */
+ protected void fastPaintWrappedAddRight(int columns)
+ {
+ if (columns == 0)
+ {
+ return;
+ }
+
+ ViewportRanges ranges = av.getRanges();
+ int viewportWidth = ranges.getViewportWidth();
+ int charWidth = av.getCharWidth();
+
+ /**
+ * draw full height alignment in the second last row, last columns, if the
+ * last row was not full height
+ */
+ int visibleWidths = wrappedVisibleWidths;
+ int canvasHeight = getHeight();
+ boolean lastWidthPartHeight = (wrappedVisibleWidths * wrappedRepeatHeightPx) > canvasHeight;
+
+ if (lastWidthPartHeight)
+ {
+ int widthsAbove = Math.max(0, visibleWidths - 2);
+ int ypos = wrappedRepeatHeightPx * widthsAbove
+ + wrappedSpaceAboveAlignment;
+ int endRes = ranges.getEndRes();
+ endRes += widthsAbove * viewportWidth;
+ int startRes = endRes - columns;
+ int xOffset = ((startRes - ranges.getStartRes()) % viewportWidth)
+ * charWidth;
+
+ /*
+ * white fill first to erase annotations
+ */
+ gg.translate(xOffset, 0);
+ gg.setColor(Color.white);
+ gg.fillRect(labelWidthWest, ypos,
+ (endRes - startRes + 1) * charWidth, wrappedRepeatHeightPx);
+ gg.translate(-xOffset, 0);
+
+ drawWrappedWidth(gg, ypos, startRes, endRes, canvasHeight);
+ }
+
+ /*
+ * draw newly visible columns in last wrapped width (none if we
+ * have reached the end of the alignment)
+ * y-offset for drawing last width is height of widths above,
+ * plus one gap row
+ */
+ int widthsAbove = visibleWidths - 1;
+ int ypos = wrappedRepeatHeightPx * widthsAbove
+ + wrappedSpaceAboveAlignment;
+ int endRes = ranges.getEndRes();
+ endRes += widthsAbove * viewportWidth;
+ int startRes = endRes - columns + 1;
+
+ /*
+ * white fill first to erase annotations
+ */
+ int xOffset = ((startRes - ranges.getStartRes()) % viewportWidth)
+ * charWidth;
+ gg.translate(xOffset, 0);
+ gg.setColor(Color.white);
+ int width = viewportWidth * charWidth - xOffset;
+ gg.fillRect(labelWidthWest, ypos, width, wrappedRepeatHeightPx);
+ gg.translate(-xOffset, 0);
+
+ gg.setFont(av.getFont());
+ gg.setColor(Color.black);
+
+ if (startRes < ranges.getVisibleAlignmentWidth())
+ {
+ drawWrappedWidth(gg, ypos, startRes, endRes, canvasHeight);
+ }
+
+ /*
+ * and finally, white fill any space below the visible alignment
+ */
+ int heightBelow = canvasHeight - visibleWidths * wrappedRepeatHeightPx;
+ if (heightBelow > 0)
+ {
+ gg.setColor(Color.white);
+ gg.fillRect(0, canvasHeight - heightBelow, getWidth(), heightBelow);
}
}
/**
+ * Shifts the visible alignment by the specified number of columns - left if
+ * negative, right if positive. Copies and moves sequences and annotations (if
+ * shown). Scales, hidden column markers and any newly visible columns must be
+ * drawn separately.
+ *
+ * @param positions
+ */
+ protected void shiftWrappedAlignment(int positions)
+ {
+ if (positions == 0)
+ {
+ return;
+ }
+ int charWidth = av.getCharWidth();
+
+ int canvasHeight = getHeight();
+ ViewportRanges ranges = av.getRanges();
+ int viewportWidth = ranges.getViewportWidth();
+ int widthToCopy = (ranges.getViewportWidth() - Math.abs(positions))
+ * charWidth;
+ int heightToCopy = wrappedRepeatHeightPx - wrappedSpaceAboveAlignment;
+ int xMax = ranges.getVisibleAlignmentWidth();
+
+ if (positions > 0)
+ {
+ /*
+ * shift right (after scroll left)
+ * for each wrapped width (starting with the last), copy (width-positions)
+ * columns from the left margin to the right margin, and copy positions
+ * columns from the right margin of the row above (if any) to the
+ * left margin of the current row
+ */
+
+ /*
+ * get y-offset of last wrapped width, first row of sequences
+ */
+ int y = canvasHeight / wrappedRepeatHeightPx * wrappedRepeatHeightPx;
+ y += wrappedSpaceAboveAlignment;
+ int copyFromLeftStart = labelWidthWest;
+ int copyFromRightStart = copyFromLeftStart + widthToCopy;
+
+ while (y >= 0)
+ {
+ gg.copyArea(copyFromLeftStart, y, widthToCopy, heightToCopy,
+ positions * charWidth, 0);
+ if (y > 0)
+ {
+ gg.copyArea(copyFromRightStart, y - wrappedRepeatHeightPx,
+ positions * charWidth, heightToCopy, -widthToCopy,
+ wrappedRepeatHeightPx);
+ }
+
+ y -= wrappedRepeatHeightPx;
+ }
+ }
+ else
+ {
+ /*
+ * shift left (after scroll right)
+ * for each wrapped width (starting with the first), copy (width-positions)
+ * columns from the right margin to the left margin, and copy positions
+ * columns from the left margin of the row below (if any) to the
+ * right margin of the current row
+ */
+ int xpos = av.getRanges().getStartRes();
+ int y = wrappedSpaceAboveAlignment;
+ int copyFromRightStart = labelWidthWest - positions * charWidth;
+
+ while (y < canvasHeight)
+ {
+ gg.copyArea(copyFromRightStart, y, widthToCopy, heightToCopy,
+ positions * charWidth, 0);
+ if (y + wrappedRepeatHeightPx < canvasHeight - wrappedRepeatHeightPx
+ && (xpos + viewportWidth <= xMax))
+ {
+ gg.copyArea(labelWidthWest, y + wrappedRepeatHeightPx, -positions
+ * charWidth, heightToCopy, widthToCopy,
+ -wrappedRepeatHeightPx);
+ }
+
+ y += wrappedRepeatHeightPx;
+ xpos += viewportWidth;
+ }
+ }
+ }
+
+
+ /**
* Redraws any positions in the search results in the visible region of a
* wrapped alignment. Any highlights are drawn depending on the search results
* set on the Viewport, not the <code>results</code> argument. This allows
{
return false;
}
-
+ int charHeight = av.getCharHeight();
+
boolean matchFound = false;
+ calculateWrappedGeometry(getWidth(), getHeight());
int wrappedWidth = av.getWrappedWidth();
- int wrappedHeight = getRepeatHeightWrapped();
+ int wrappedHeight = wrappedRepeatHeightPx;
ViewportRanges ranges = av.getRanges();
int canvasHeight = getHeight();
}
/**
- * Answers the height in pixels of a repeating section of the wrapped
- * alignment, including space above, scale above if shown, sequences, and
- * annotation panel if shown
+ * Answers the width in pixels of the left scale labels (0 if not shown)
*
* @return
*/
- protected int getRepeatHeightWrapped()
+ int getLabelWidthWest()
{
- // gap (and maybe scale) above
- int repeatHeight = charHeight * (av.getScaleAboveWrapped() ? 2 : 1);
-
- // add sequences
- repeatHeight += av.getRanges().getViewportHeight() * charHeight;
-
- // add annotations panel height if shown
- repeatHeight += getAnnotationHeight();
-
- return repeatHeight;
+ return labelWidthWest;
}
}
+ hgap + seqCanvas.getAnnotationHeight();
int y = evt.getY();
- y -= hgap;
- x = Math.max(0, x - seqCanvas.labelWidthWest);
+ y = Math.max(0, y - hgap);
+ x = Math.max(0, x - seqCanvas.getLabelWidthWest());
int cwidth = seqCanvas.getWrappedCanvasWidth(this.getWidth());
if (cwidth < 1)
av.setSelectionGroup(sg);
}
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
av.sendSelection();
}
}
/**
- * DOCUMENT ME!
+ * Action on mouse movement is to update the status bar to show the current
+ * sequence position, and (if features are shown) to show any features at the
+ * position in a tooltip. Does nothing if the mouse move does not change
+ * residue position.
*
* @param evt
- * DOCUMENT ME!
*/
@Override
public void mouseMoved(MouseEvent evt)
}
final int column = findColumn(evt);
- int seq = findSeq(evt);
+ final int seq = findSeq(evt);
+
if (column < 0 || seq < 0 || seq >= av.getAlignment().getHeight())
{
lastMouseSeq = -1;
/**
* set when the current UI interaction has resulted in a change that requires
- * overview shading to be recalculated. this could be changed to something
- * more expressive that indicates what actually has changed, so selective
- * redraws can be applied
+ * shading in overviews and structures to be recalculated. this could be
+ * changed to a something more expressive that indicates what actually has
+ * changed, so selective redraws can be applied (ie. only structures, only
+ * overview, etc)
*/
- private boolean needOverviewUpdate = false; // TODO: refactor to avcontroller
+ private boolean updateOverviewAndStructs = false; // TODO: refactor to avcontroller
/**
* set if av.getSelectionGroup() refers to a group that is defined on the
}
if (newWidth > 0)
{
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
if (copyChanges)
{
/*
av.getRanges().scrollRight(true);
}
- else if (!av.getWrapAlignment())
+ else
{
av.getRanges().scrollUp(false);
}
{
av.getRanges().scrollRight(false);
}
- else if (!av.getWrapAlignment())
+ else
{
av.getRanges().scrollUp(true);
}
}
- // TODO Update tooltip for new position.
+
+ /*
+ * update status bar and tooltip for new position
+ * (need to synthesize a mouse movement to refresh tooltip)
+ */
+ mouseMoved(e);
+ ToolTipManager.sharedInstance().mouseMoved(e);
}
/**
final int res = findColumn(evt);
final int seq = findSeq(evt);
oldSeq = seq;
- needOverviewUpdate = false;
+ updateOverviewAndStructs = false;
startWrapBlock = wrappedBlock;
// always do this - annotation has own state
// but defer colourscheme update until hidden sequences are passed in
boolean vischange = stretchGroup.recalcConservation(true);
- needOverviewUpdate |= vischange && av.isSelectionDefinedGroup()
+ updateOverviewAndStructs |= vischange && av.isSelectionDefinedGroup()
&& afterDrag;
if (stretchGroup.cs != null)
{
}
}
PaintRefresher.Refresh(this, av.getSequenceSetId());
- ap.paintAlignment(needOverviewUpdate);
- needOverviewUpdate = false;
+ // TODO: structure colours only need updating if stretchGroup used to or now
+ // does contain sequences with structure views
+ ap.paintAlignment(updateOverviewAndStructs, updateOverviewAndStructs);
+ updateOverviewAndStructs = false;
changeEndRes = false;
changeStartRes = false;
stretchGroup = null;
if (res > (stretchGroup.getStartRes() - 1))
{
stretchGroup.setEndRes(res);
- needOverviewUpdate |= av.isSelectionDefinedGroup();
+ updateOverviewAndStructs |= av.isSelectionDefinedGroup();
}
}
else if (changeStartRes)
if (res < (stretchGroup.getEndRes() + 1))
{
stretchGroup.setStartRes(res);
- needOverviewUpdate |= av.isSelectionDefinedGroup();
+ updateOverviewAndStructs |= av.isSelectionDefinedGroup();
}
}
if (stretchGroup.getSequences(null).contains(nextSeq))
{
stretchGroup.deleteSequence(seq, false);
- needOverviewUpdate |= av.isSelectionDefinedGroup();
+ updateOverviewAndStructs |= av.isSelectionDefinedGroup();
}
else
{
}
stretchGroup.addSequence(nextSeq, false);
- needOverviewUpdate |= av.isSelectionDefinedGroup();
+ updateOverviewAndStructs |= av.isSelectionDefinedGroup();
}
}
@Override
public void mouseReleased(MouseEvent evt)
{
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
});
Collection<FTSDataColumnI> wantedFields = pdbDocFieldPrefs
.getStructureSummaryFields();
- discoveredStructuresSet = new LinkedHashSet<FTSData>();
- HashSet<String> errors = new HashSet<String>();
+ discoveredStructuresSet = new LinkedHashSet<>();
+ HashSet<String> errors = new HashSet<>();
for (SequenceI seq : selectedSequences)
{
FTSRestRequest pdbRequest = new FTSRestRequest();
public void loadLocalCachedPDBEntries()
{
- ArrayList<CachedPDB> entries = new ArrayList<CachedPDB>();
+ ArrayList<CachedPDB> entries = new ArrayList<>();
for (SequenceI seq : selectedSequences)
{
if (seq.getDatasetSequence() != null
boolean isPDBRefsFound = false;
boolean isUniProtRefsFound = false;
StringBuilder queryBuilder = new StringBuilder();
- Set<String> seqRefs = new LinkedHashSet<String>();
+ Set<String> seqRefs = new LinkedHashSet<>();
if (seq.getAllPDBEntries() != null
&& queryBuilder.length() < MAX_QLENGTH)
lbl_loading.setVisible(true);
Collection<FTSDataColumnI> wantedFields = pdbDocFieldPrefs
.getStructureSummaryFields();
- Collection<FTSData> filteredResponse = new HashSet<FTSData>();
- HashSet<String> errors = new HashSet<String>();
+ Collection<FTSData> filteredResponse = new HashSet<>();
+ HashSet<String> errors = new HashSet<>();
for (SequenceI seq : selectedSequences)
{
if (!filteredResponse.isEmpty())
{
final int filterResponseCount = filteredResponse.size();
- Collection<FTSData> reorderedStructuresSet = new LinkedHashSet<FTSData>();
+ Collection<FTSData> reorderedStructuresSet = new LinkedHashSet<>();
reorderedStructuresSet.addAll(filteredResponse);
reorderedStructuresSet.addAll(discoveredStructuresSet);
getResultTable().setModel(FTSRestResponse
@Override
public void ok_ActionPerformed()
{
- final long progressSessionId = System.currentTimeMillis();
final StructureSelectionManager ssm = ap.getStructureSelectionManager();
+
final int preferredHeight = pnl_filter.getHeight();
- ssm.setProgressIndicator(this);
- ssm.setProgressSessionId(progressSessionId);
+
new Thread(new Runnable()
{
@Override
int[] selectedRows = getResultTable().getSelectedRows();
PDBEntry[] pdbEntriesToView = new PDBEntry[selectedRows.length];
int count = 0;
- List<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
+ List<SequenceI> selectedSeqsToView = new ArrayList<>();
for (int row : selectedRows)
{
String pdbIdStr = getResultTable()
pdbEntry = getFindEntry(pdbIdStr,
selectedSeq.getAllPDBEntries());
}
+
if (pdbEntry == null)
{
pdbEntry = new PDBEntry();
.getModelIndex();
int refSeqColIndex = tbl_local_pdb.getColumn("Ref Sequence")
.getModelIndex();
- List<SequenceI> selectedSeqsToView = new ArrayList<SequenceI>();
+ List<SequenceI> selectedSeqsToView = new ArrayList<>();
for (int row : selectedRows)
{
PDBEntry pdbEntry = (PDBEntry) tbl_local_pdb.getValueAt(row,
{
selectedSequence = userSelectedSeq;
}
-
String pdbIdStr = txt_search.getText();
PDBEntry pdbEntry = selectedSequence.getPDBEntry(pdbIdStr);
if (pdbEntry == null)
{ selectedSequence });
}
closeAction(preferredHeight);
+ mainFrame.dispose();
}
}).start();
}
final PDBEntry[] pdbEntriesToView,
final AlignmentPanel alignPanel, SequenceI[] sequences)
{
- ssm.setProgressBar(MessageManager
- .getString("status.launching_3d_structure_viewer"));
+ long progressId = sequences.hashCode();
+ setProgressBar(MessageManager
+ .getString("status.launching_3d_structure_viewer"), progressId);
final StructureViewer sViewer = new StructureViewer(ssm);
+ setProgressBar(null, progressId);
if (SiftsSettings.isMapWithSifts())
{
- List<SequenceI> seqsWithoutSourceDBRef = new ArrayList<SequenceI>();
+ List<SequenceI> seqsWithoutSourceDBRef = new ArrayList<>();
int p = 0;
// TODO: skip PDBEntry:Sequence pairs where PDBEntry doesn't look like a
// real PDB ID. For moment, we can also safely do this if there is already
if (!seqsWithoutSourceDBRef.isEmpty())
{
int y = seqsWithoutSourceDBRef.size();
- ssm.setProgressBar(null);
- ssm.setProgressBar(MessageManager.formatMessage(
+ setProgressBar(MessageManager.formatMessage(
"status.fetching_dbrefs_for_sequences_without_valid_refs",
- y));
+ y), progressId);
SequenceI[] seqWithoutSrcDBRef = new SequenceI[y];
int x = 0;
for (SequenceI fSeq : seqsWithoutSourceDBRef)
{
seqWithoutSrcDBRef[x++] = fSeq;
}
+
DBRefFetcher dbRefFetcher = new DBRefFetcher(seqWithoutSrcDBRef);
dbRefFetcher.fetchDBRefs(true);
+
+ setProgressBar("Fetch complete.", progressId); // todo i18n
}
}
if (pdbEntriesToView.length > 1)
{
- ArrayList<SequenceI[]> seqsMap = new ArrayList<SequenceI[]>();
+ ArrayList<SequenceI[]> seqsMap = new ArrayList<>();
for (SequenceI seq : sequences)
{
seqsMap.add(new SequenceI[] { seq });
}
SequenceI[][] collatedSeqs = seqsMap.toArray(new SequenceI[0][0]);
- ssm.setProgressBar(null);
- ssm.setProgressBar(MessageManager.getString(
- "status.fetching_3d_structures_for_selected_entries"));
+
+ setProgressBar(MessageManager
+ .getString("status.fetching_3d_structures_for_selected_entries"), progressId);
sViewer.viewStructures(pdbEntriesToView, collatedSeqs, alignPanel);
}
else
{
- ssm.setProgressBar(null);
- ssm.setProgressBar(MessageManager.formatMessage(
+ setProgressBar(MessageManager.formatMessage(
"status.fetching_3d_structures_for",
- pdbEntriesToView[0].getId()));
+ pdbEntriesToView[0].getId()),progressId);
sViewer.viewStructures(pdbEntriesToView[0], sequences, alignPanel);
}
+ setProgressBar(null, progressId);
}
/**
String searchTerm = txt_search.getText().toLowerCase();
searchTerm = searchTerm.split(":")[0];
// System.out.println(">>>>> search term : " + searchTerm);
- List<FTSDataColumnI> wantedFields = new ArrayList<FTSDataColumnI>();
+ List<FTSDataColumnI> wantedFields = new ArrayList<>();
FTSRestRequest pdbRequest = new FTSRestRequest();
pdbRequest.setAllowEmptySeq(false);
pdbRequest.setResponseSize(1);
public PDBEntryTableModel(List<CachedPDB> pdbEntries)
{
- this.pdbEntries = new ArrayList<CachedPDB>(pdbEntries);
+ this.pdbEntries = new ArrayList<>(pdbEntries);
}
@Override
/**
* list of sequenceSet ids associated with the view
*/
- protected List<String> _aps = new ArrayList<String>();
+ protected List<String> _aps = new ArrayList<>();
/**
* list of alignment panels to use for superposition
*/
- protected Vector<AlignmentPanel> _alignwith = new Vector<AlignmentPanel>();
+ protected Vector<AlignmentPanel> _alignwith = new Vector<>();
/**
* list of alignment panels that are used for colouring structures by aligned
* sequences
*/
- protected Vector<AlignmentPanel> _colourwith = new Vector<AlignmentPanel>();
+ protected Vector<AlignmentPanel> _colourwith = new Vector<>();
private String viewId = null;
{
if (_alignwith == null)
{
- _alignwith = new Vector<AlignmentPanel>();
+ _alignwith = new Vector<>();
}
if (_alignwith.size() == 0 && ap != null)
{
public abstract ViewerType getViewerType();
+ protected abstract IProgressIndicator getIProgressIndicator();
+
/**
* add a new structure (with associated sequences and chains) to this viewer,
* retrieving it if necessary first.
* create the mappings
*/
apanel.getStructureSelectionManager().setMapping(seq, chains,
- pdbFilename, DataSourceType.FILE);
+ pdbFilename, DataSourceType.FILE, getIProgressIndicator());
/*
* alert the FeatureRenderer to show new (PDB RESNUM) features
if (apanel.getSeqPanel().seqCanvas.fr != null)
{
apanel.getSeqPanel().seqCanvas.fr.featuresAdded();
- apanel.paintAlignment(true);
+ // note - we don't do a refresh for structure here because we do it
+ // explicitly for all panels later on
+ apanel.paintAlignment(true, false);
}
/*
if (_colourwith == null)
{
- _colourwith = new Vector<AlignmentPanel>();
+ _colourwith = new Vector<>();
}
if (_alignwith == null)
{
- _alignwith = new Vector<AlignmentPanel>();
+ _alignwith = new Vector<>();
}
ViewSelectionMenu seqColourBy = new ViewSelectionMenu(
binding.setColourBySequence(seqColour.isSelected());
if (_colourwith == null)
{
- _colourwith = new Vector<AlignmentPanel>();
+ _colourwith = new Vector<>();
}
if (binding.isColourBySequence())
{
*/
protected void saveInitialSettings()
{
- groupColour1 = new HashMap<SequenceGroup, Color>();
- groupColour2 = new HashMap<SequenceGroup, Color>();
- groupThreshold = new HashMap<SequenceGroup, Integer>();
+ groupColour1 = new HashMap<>();
+ groupColour2 = new HashMap<>();
+ groupThreshold = new HashMap<>();
if (sg == null)
{
sg.textColour = col;
}
- ap.paintAlignment(true);
+ ap.paintAlignment(false, false);
}
void colour2Changed(Color col)
sg.textColour2 = col;
}
- ap.paintAlignment(true);
+ ap.paintAlignment(false, false);
}
void thresholdChanged(int value)
sg.thresholdTextColour = value;
}
- ap.paintAlignment(true);
+ ap.paintAlignment(false, false);
}
void setGroupTextColour()
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import javax.swing.ButtonGroup;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
+import javax.swing.event.InternalFrameAdapter;
+import javax.swing.event.InternalFrameEvent;
import org.jibble.epsgraphics.EpsGraphics2D;
buildAssociatedViewMenu();
- av.addPropertyChangeListener(new java.beans.PropertyChangeListener()
+ final PropertyChangeListener listener = addAlignmentListener();
+
+ /*
+ * remove listener when window is closed, so that this
+ * panel can be garbage collected
+ */
+ addInternalFrameListener(new InternalFrameAdapter()
+ {
+ @Override
+ public void internalFrameClosed(InternalFrameEvent evt)
+ {
+ if (av != null)
+ {
+ av.removePropertyChangeListener(listener);
+ }
+ }
+ });
+
+ TreeLoader tl = new TreeLoader(newTree, inputData);
+ tl.start();
+
+ }
+
+ /**
+ * @return
+ */
+ protected PropertyChangeListener addAlignmentListener()
+ {
+ final PropertyChangeListener listener = new PropertyChangeListener()
{
@Override
public void propertyChange(PropertyChangeEvent evt)
repaint();
}
}
- });
-
- TreeLoader tl = new TreeLoader(newTree, inputData);
- tl.start();
-
+ };
+ av.addPropertyChangeListener(listener);
+ return listener;
}
@Override
if (treeCanvas.applyToAllViews)
{
- final ArrayList<CommandI> commands = new ArrayList<CommandI>();
+ final ArrayList<CommandI> commands = new ArrayList<>();
for (AlignmentPanel ap : PaintRefresher
.getAssociatedPanels(av.getSequenceSetId()))
{
public CommandI sortAlignmentIn(AlignmentPanel ap)
{
+ // TODO: move to alignment view controller
AlignmentViewport viewport = ap.av;
SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
AlignmentSorter.sortByTree(viewport.getAlignment(), tree);
CommandI undo;
undo = new OrderCommand("Tree Sort", oldOrder, viewport.getAlignment());
- ap.paintAlignment(true);
+ ap.paintAlignment(true, false);
return undo;
}
UserDefinedColours()
{
super();
- selectedButtons = new ArrayList<JButton>();
+ selectedButtons = new ArrayList<>();
}
void showFrame()
if (upperCaseButtons == null)
{
- upperCaseButtons = new ArrayList<JButton>();
+ upperCaseButtons = new ArrayList<>();
}
for (int i = 0; i < 20; i++)
if (lowerCaseButtons == null)
{
- lowerCaseButtons = new ArrayList<JButton>();
+ lowerCaseButtons = new ArrayList<>();
}
for (int i = 0; i < 20; i++)
@Override
protected void loadbutton_actionPerformed()
{
- upperCaseButtons = new ArrayList<JButton>();
- lowerCaseButtons = new ArrayList<JButton>();
+ upperCaseButtons = new ArrayList<>();
+ lowerCaseButtons = new ArrayList<>();
JalviewFileChooser chooser = new JalviewFileChooser("jc",
"Jalview User Colours");
protected void cancelButton_actionPerformed()
{
ap.alignFrame.changeColour(oldColourScheme);
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
try
{
private ItemListener _handler;
- @Override
- protected void finalize() throws Throwable
- {
- _selectedviews = null;
- _handler = null;
- _allviews = null;
- super.finalize();
- }
-
/**
* create a new view selection menu. This menu has some standard entries
* (select all, invert selection), and a checkbox for every view. Mousing over
return tempStructFile.toString();
}
- /*
- * (non-Javadoc)
- *
- * @see java.lang.Object#finalize()
- */
- @Override
- protected void finalize() throws Throwable
- {
- source = null;
- alignFrame = null;
- viewport = null;
- super.finalize();
- }
-
}
error = false;
}
- @Override
- protected void finalize() throws Throwable
- {
- dataIn = null;
- super.finalize();
- }
-
}
}
}
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, false);
}
jvlite.setExecutor(this);
}
- @Override
- protected void finalize() throws Throwable
- {
- jvlite = null;
- executor = null;
- if (jsExecQueue != null)
- {
- jsExecQueue.clear();
- }
- jsExecQueue = null;
- super.finalize();
- }
-
private Vector jsExecQueue;
private Thread executor = null;
}
@Override
- public void finalize() throws Throwable
- {
- jvlite = null;
- super.finalize();
- }
-
- @Override
public void releaseReferences(Object svl)
{
*/
public class ScaleRenderer
{
+ /**
+ * Represents one major or minor scale mark
+ */
public final class ScaleMark
{
+ /**
+ * true for a major scale mark, false for minor
+ */
public final boolean major;
+ /**
+ * visible column position (0..) e.g. 19
+ */
public final int column;
+ /**
+ * text (if any) to show e.g. "20"
+ */
public final String text;
ScaleMark(boolean isMajor, int col, String txt)
return null;
}
- if (Comparison.isGap(seq.getCharAt(column)))
+ // column is 'base 1' but getCharAt is an array index (ie from 0)
+ if (Comparison.isGap(seq.getCharAt(column - 1)))
{
/*
* returning null allows the colour scheme to provide gap colour
}
/**
-<<<<<<< HEAD
-=======
- * Answers true if the feature belongs to a feature group which is not
- * currently displayed, else false
- *
- * @param sequenceFeature
- * @return
- */
- @Override
- protected boolean featureGroupNotShown(
- final SequenceFeature sequenceFeature)
- {
- return featureGroups != null && sequenceFeature.featureGroup != null
- && sequenceFeature.featureGroup.length() != 0
- && featureGroups.containsKey(sequenceFeature.featureGroup)
- && !featureGroups.get(sequenceFeature.featureGroup)
- .booleanValue();
- }
-
- /**
->>>>>>> refs/heads/develop
* Called when alignment in associated view has new/modified features to
* discover and display.
*
oldcs = av.getGlobalColourScheme();
if (av.getAlignment().getGroups() != null)
{
- oldgroupColours = new Hashtable<SequenceGroup, ColourSchemeI>();
+ oldgroupColours = new Hashtable<>();
for (SequenceGroup sg : ap.getAlignment().getGroups())
{
if (sg.getColourScheme() != null)
this.ap = ap;
adjusting = true;
- Vector<String> list = new Vector<String>();
+ Vector<String> list = new Vector<>();
int index = 1;
AlignmentAnnotation[] anns = av.getAlignment().getAlignmentAnnotation();
if (anns != null)
av.setGlobalColourScheme(rhc);
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
}
static IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager> instances;
- private List<StructureMapping> mappings = new ArrayList<StructureMapping>();
+ private List<StructureMapping> mappings = new ArrayList<>();
private boolean processSecondaryStructure = false;
private boolean addTempFacAnnot = false;
- private IProgressIndicator progressIndicator;
-
private SiftsClient siftsClient = null;
- private long progressSessionId;
-
/*
* Set of any registered mappings between (dataset) sequences.
*/
- private List<AlignedCodonFrame> seqmappings = new ArrayList<AlignedCodonFrame>();
+ private List<AlignedCodonFrame> seqmappings = new ArrayList<>();
- private List<CommandListener> commandListeners = new ArrayList<CommandListener>();
+ private List<CommandListener> commandListeners = new ArrayList<>();
- private List<SelectionListener> sel_listeners = new ArrayList<SelectionListener>();
+ private List<SelectionListener> sel_listeners = new ArrayList<>();
/**
* @return true if will try to use external services for processing secondary
* map between the PDB IDs (or structure identifiers) used by Jalview and the
* absolute filenames for PDB data that corresponds to it
*/
- Map<String, String> pdbIdFileName = new HashMap<String, String>();
+ Map<String, String> pdbIdFileName = new HashMap<>();
- Map<String, String> pdbFileNameId = new HashMap<String, String>();
+ Map<String, String> pdbFileNameId = new HashMap<>();
public void registerPDBFile(String idForFile, String absoluteFile)
{
}
if (instances == null)
{
- instances = new java.util.IdentityHashMap<StructureSelectionManagerProvider, StructureSelectionManager>();
+ instances = new java.util.IdentityHashMap<>();
}
StructureSelectionManager instance = instances.get(context);
if (instance == null)
* @return null or the structure data parsed as a pdb file
*/
synchronized public StructureFile setMapping(SequenceI[] sequence,
- String[] targetChains, String pdbFile, DataSourceType protocol)
+ String[] targetChains, String pdbFile, DataSourceType protocol,
+ IProgressIndicator progress)
{
- return setMapping(true, sequence, targetChains, pdbFile, protocol);
+ return computeMapping(true, sequence, targetChains, pdbFile, protocol,
+ progress);
}
/**
SequenceI[] sequenceArray, String[] targetChainIds,
String pdbFile, DataSourceType sourceType)
{
+ return computeMapping(forStructureView, sequenceArray, targetChainIds,
+ pdbFile, sourceType, null);
+ }
+
+ synchronized public StructureFile computeMapping(
+ boolean forStructureView, SequenceI[] sequenceArray,
+ String[] targetChainIds, String pdbFile, DataSourceType sourceType,
+ IProgressIndicator progress)
+ {
+ long progressSessionId = System.currentTimeMillis() * 3;
/*
* There will be better ways of doing this in the future, for now we'll use
* the tried and tested MCview pdb mapping
pdbFile = "INLINE" + pdb.getId();
}
- List<StructureMapping> seqToStrucMapping = new ArrayList<StructureMapping>();
+ List<StructureMapping> seqToStrucMapping = new ArrayList<>();
if (isMapUsingSIFTs && seq.isProtein())
{
- setProgressBar(null);
- setProgressBar(MessageManager
- .getString("status.obtaining_mapping_with_sifts"));
+ if (progress!=null) {
+ progress.setProgressBar(MessageManager
+ .getString("status.obtaining_mapping_with_sifts"),
+ progressSessionId);
+ }
jalview.datamodel.Mapping sqmpping = maxAlignseq
.getMappingFromS1(false);
if (targetChainId != null && !targetChainId.trim().isEmpty())
}
else
{
- List<StructureMapping> foundSiftsMappings = new ArrayList<StructureMapping>();
+ List<StructureMapping> foundSiftsMappings = new ArrayList<>();
for (PDBChain chain : pdb.getChains())
{
try
}
else
{
- setProgressBar(null);
- setProgressBar(MessageManager
- .getString("status.obtaining_mapping_with_nw_alignment"));
+ if (progress != null)
+ {
+ progress.setProgressBar(MessageManager
+ .getString("status.obtaining_mapping_with_nw_alignment"),
+ progressSessionId);
+ }
StructureMapping nwMapping = getNWMappings(seq, pdbFile, maxChainId,
maxChain, pdb, maxAlignseq);
seqToStrucMapping.add(nwMapping);
ds.addPDBId(maxChain.sequence.getAllPDBEntries().get(0));
-
}
-
if (forStructureView)
{
mappings.addAll(seqToStrucMapping);
}
+ if (progress != null)
+ {
+ progress.setProgressBar(null, progressSessionId);
+ }
}
return pdb;
}
.getMappingFromS1(false);
maxChain.transferRESNUMFeatures(seq, null);
- HashMap<Integer, int[]> mapping = new HashMap<Integer, int[]>();
+ HashMap<Integer, int[]> mapping = new HashMap<>();
int resNum = -10000;
int index = 0;
char insCode = ' ';
* Remove mappings to the closed listener's PDB files, but first check if
* another listener is still interested
*/
- List<String> pdbs = new ArrayList<String>(Arrays.asList(pdbfiles));
+ List<String> pdbs = new ArrayList<>(Arrays.asList(pdbfiles));
StructureListener sl;
for (int i = 0; i < listeners.size(); i++)
*/
if (pdbs.size() > 0)
{
- List<StructureMapping> tmp = new ArrayList<StructureMapping>();
+ List<StructureMapping> tmp = new ArrayList<>();
for (StructureMapping sm : mappings)
{
if (!pdbs.contains(sm.pdbfile))
&& sm.pdbchain.equals(atom.getChain()))
{
int indexpos = sm.getSeqPos(atom.getPdbResNum());
- if (lastipos != indexpos && lastseq != sm.sequence)
+ if (lastipos != indexpos || lastseq != sm.sequence)
{
results.addResult(sm.sequence, indexpos, indexpos);
lastipos = indexpos;
return;
}
int atomNo;
- List<AtomSpec> atoms = new ArrayList<AtomSpec>();
+ List<AtomSpec> atoms = new ArrayList<>();
for (StructureMapping sm : mappings)
{
if (sm.sequence == seq || sm.sequence == seq.getDatasetSequence()
public StructureMapping[] getMapping(String pdbfile)
{
- List<StructureMapping> tmp = new ArrayList<StructureMapping>();
+ List<StructureMapping> tmp = new ArrayList<>();
for (StructureMapping sm : mappings)
{
if (sm.pdbfile.equals(pdbfile))
}
}
- Vector<AlignmentViewPanelListener> view_listeners = new Vector<AlignmentViewPanelListener>();
+ Vector<AlignmentViewPanelListener> view_listeners = new Vector<>();
public synchronized void sendViewPosition(
jalview.api.AlignmentViewPanel source, int startRes, int endRes,
return null;
}
- public IProgressIndicator getProgressIndicator()
- {
- return progressIndicator;
- }
-
- public void setProgressIndicator(IProgressIndicator progressIndicator)
- {
- this.progressIndicator = progressIndicator;
- }
-
- public long getProgressSessionId()
- {
- return progressSessionId;
- }
-
- public void setProgressSessionId(long progressSessionId)
- {
- this.progressSessionId = progressSessionId;
- }
-
- public void setProgressBar(String message)
- {
- if (progressIndicator == null)
- {
- return;
- }
- progressIndicator.setProgressBar(message, progressSessionId);
- }
-
public List<AlignedCodonFrame> getSequenceMappings()
{
return seqmappings;
*/
private void upgradeOldLinks(HashMap<String, UrlLink> urls)
{
+ boolean upgrade = false;
// upgrade old SRS link
if (urls.containsKey(SRS_LABEL))
{
urls.remove(SRS_LABEL);
+ upgrade = true;
+ }
+ // upgrade old EBI link - easier just to remove and re-add than faffing
+ // around checking exact url
+ if (urls.containsKey(UrlConstants.DEFAULT_LABEL))
+ {
+ // note because this is called separately for selected and nonselected
+ // urls, the default url will not always be present
+ urls.remove(UrlConstants.DEFAULT_LABEL);
+ upgrade = true;
+ }
+ if (upgrade)
+ {
UrlLink link = new UrlLink(UrlConstants.DEFAULT_STRING);
link.setLabel(UrlConstants.DEFAULT_LABEL);
urls.put(UrlConstants.DEFAULT_LABEL, link);
}
return copy;
}
+
+ /**
+ * Removes the specified number of positions from the given ranges. Provided
+ * to allow a stop codon to be stripped from a CDS sequence so that it matches
+ * the peptide translation length.
+ *
+ * @param positions
+ * @param ranges
+ * a list of (single) [start, end] ranges
+ * @return
+ */
+ public static void removeEndPositions(int positions,
+ List<int[]> ranges)
+ {
+ int toRemove = positions;
+ Iterator<int[]> it = new ReverseListIterator<>(ranges);
+ while (toRemove > 0)
+ {
+ int[] endRange = it.next();
+ if (endRange.length != 2)
+ {
+ /*
+ * not coded for [start1, end1, start2, end2, ...]
+ */
+ System.err
+ .println("MappingUtils.removeEndPositions doesn't handle multiple ranges");
+ return;
+ }
+
+ int length = endRange[1] - endRange[0] + 1;
+ if (length <= 0)
+ {
+ /*
+ * not coded for a reverse strand range (end < start)
+ */
+ System.err
+ .println("MappingUtils.removeEndPositions doesn't handle reverse strand");
+ return;
+ }
+ if (length > toRemove)
+ {
+ endRange[1] -= toRemove;
+ toRemove = 0;
+ }
+ else
+ {
+ toRemove -= length;
+ it.remove();
+ }
+ }
+ }
}
* Default sequence URL link string for EMBL-EBI search
*/
public static final String DEFAULT_STRING = DEFAULT_LABEL
- + "|http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$";
+ + "|https://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$SEQUENCE_ID$";
+
+ private static final String COLON = ":";
/*
* not instantiable
private UrlConstants()
{
}
+
+ public static boolean isDefaultString(String link)
+ {
+ String sublink = link.substring(link.indexOf(COLON) + 1);
+ String subdefault = DEFAULT_STRING
+ .substring(DEFAULT_STRING.indexOf(COLON) + 1);
+ return sublink.equalsIgnoreCase(subdefault);
+ }
}
import jalview.analysis.AnnotationSorter.SequenceAnnotationOrder;
import jalview.analysis.Conservation;
+import jalview.analysis.TreeModel;
import jalview.api.AlignCalcManagerI;
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
import jalview.datamodel.Annotation;
-import jalview.datamodel.CigarArray;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.HiddenColumns;
import jalview.datamodel.HiddenSequences;
public abstract class AlignmentViewport
implements AlignViewportI, CommandListener, VamsasSource
{
- final protected ViewportRanges ranges;
+ protected ViewportRanges ranges;
protected ViewStyleI viewStyle = new ViewStyle();
groupConsensus = null;
groupConservation = null;
hconsensus = null;
+ hconservation = null;
hcomplementConsensus = null;
- // colour scheme may hold reference to consensus
- residueShading = null;
- // TODO remove listeners from changeSupport?
+ gapcounts = null;
+ calculator = null;
+ residueShading = null; // may hold a reference to Consensus
changeSupport = null;
+ ranges = null;
+ currentTree = null;
+ selectionGroup = null;
setAlignment(null);
}
public void removePropertyChangeListener(
java.beans.PropertyChangeListener listener)
{
- changeSupport.removePropertyChangeListener(listener);
+ if (changeSupport != null)
+ {
+ changeSupport.removePropertyChangeListener(listener);
+ }
}
/**
}
@Override
- public CigarArray getViewAsCigars(boolean selectedRegionOnly)
- {
- return new CigarArray(alignment, alignment.getHiddenColumns(),
- (selectedRegionOnly ? selectionGroup : null));
- }
-
- @Override
public jalview.datamodel.AlignmentView getAlignmentView(
boolean selectedOnly)
{
*/
private SearchResultsI searchResults = null;
+ protected TreeModel currentTree = null;
+
@Override
public boolean hasSearchResults()
{
+ ((ignoreGapsInConsensusCalculation) ? " without gaps" : ""));
return sq;
}
+
+ @Override
+ public void setCurrentTree(TreeModel tree)
+ {
+ currentTree = tree;
+ }
+
+ @Override
+ public TreeModel getCurrentTree()
+ {
+ return currentTree;
+ }
}
*/
public boolean scrollUp(boolean up)
{
+ /*
+ * if in unwrapped mode, scroll up or down one sequence row;
+ * if in wrapped mode, scroll by one visible width of columns
+ */
if (up)
{
- if (startSeq < 1)
+ if (wrappedMode)
{
- return false;
+ pageUp();
+ }
+ else
+ {
+ if (startSeq < 1)
+ {
+ return false;
+ }
+ setStartSeq(startSeq - 1);
}
-
- setStartSeq(startSeq - 1);
}
else
{
- if (endSeq >= getVisibleAlignmentHeight() - 1)
+ if (wrappedMode)
{
- return false;
+ pageDown();
+ }
+ else
+ {
+ if (endSeq >= getVisibleAlignmentHeight() - 1)
+ {
+ return false;
+ }
+ setStartSeq(startSeq + 1);
}
-
- setStartSeq(startSeq + 1);
}
return true;
}
AnnotationProviderI counter)
{
super(viewport, panel);
- ourAnnots = new ArrayList<AlignmentAnnotation>();
+ ourAnnots = new ArrayList<>();
this.counter = counter;
calcMan.registerWorker(this);
}
if (ap != null)
{
ap.adjustAnnotationHeight();
- ap.paintAlignment(true);
+ // TODO: only need to update colour and geometry if panel height changes
+ // and view is coloured by annotation, and the annotation is actually
+ // changed!
+ ap.paintAlignment(true, true);
}
}
AlignmentViewPanel panel, FeatureSetCounterI counter)
{
super(viewport, panel);
- ourAnnots = new ArrayList<AlignmentAnnotation>();
+ ourAnnots = new ArrayList<>();
this.counter = counter;
calcMan.registerWorker(this);
}
{
ap.adjustAnnotationHeight();
}
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
}
{
if (ap != null)
{
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
Thread.sleep(200);
} catch (Exception ex)
if (ap != null)
{
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
} catch (OutOfMemoryError error)
{
abortAndDestroy();
return;
}
- List<AlignmentAnnotation> ourAnnot = new ArrayList<AlignmentAnnotation>();
+ List<AlignmentAnnotation> ourAnnot = new ArrayList<>();
AlignmentI alignment = alignViewport.getAlignment();
conservation = alignViewport.getAlignmentConservationAnnotation();
quality = alignViewport.getAlignmentQualityAnnot();
}
if (ap != null)
{
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
}
calcMan.workerComplete(this);
if (ap != null)
{
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
}
}
boolean useJDasMultiThread)
{
this.useJDASMultiThread = useJDasMultiThread;
- this.selectedSources = new ArrayList<jalviewSourceI>();
+ this.selectedSources = new ArrayList<>();
// filter both sequences and sources to eliminate duplicates
for (jalviewSourceI src : selectedSources2)
{
FeaturesClientMultipleSources fc = new FeaturesClientMultipleSources();
fc.setConnProps(sourceRegistry.getSessionHandler());
// Now sending requests one at a time to each server
- ArrayList<jalviewSourceI> srcobj = new ArrayList<jalviewSourceI>();
- ArrayList<String> src = new ArrayList<String>();
- List<List<String>> ids = new ArrayList<List<String>>();
- List<List<DBRefEntry>> idobj = new ArrayList<List<DBRefEntry>>();
- List<Map<String, SequenceI>> sqset = new ArrayList<Map<String, SequenceI>>();
+ ArrayList<jalviewSourceI> srcobj = new ArrayList<>();
+ ArrayList<String> src = new ArrayList<>();
+ List<List<String>> ids = new ArrayList<>();
+ List<List<DBRefEntry>> idobj = new ArrayList<>();
+ List<Map<String, SequenceI>> sqset = new ArrayList<>();
for (jalviewSourceI _sr : selectedSources)
{
- Map<String, SequenceI> slist = new HashMap<String, SequenceI>();
- List<DBRefEntry> idob = new ArrayList<DBRefEntry>();
- List<String> qset = new ArrayList<String>();
+ Map<String, SequenceI> slist = new HashMap<>();
+ List<DBRefEntry> idob = new ArrayList<>();
+ List<String> qset = new ArrayList<>();
for (SequenceI seq : sequences)
{
sqset.add(slist);
}
}
- Map<String, Map<List<String>, Exception>> errors = new HashMap<String, Map<List<String>, Exception>>();
- Map<String, Map<List<String>, DasGFFAdapter>> results = new HashMap<String, Map<List<String>, DasGFFAdapter>>();
+ Map<String, Map<List<String>, Exception>> errors = new HashMap<>();
+ Map<String, Map<List<String>, DasGFFAdapter>> results = new HashMap<>();
if (!useJDASMultiThread)
{
Iterator<String> sources = src.iterator();
if (ers == null)
{
results.put(source,
- ers = new HashMap<List<String>, DasGFFAdapter>());
+ ers = new HashMap<>());
}
ers.put(qid, dga);
} catch (Exception ex)
if (ers == null)
{
errors.put(source,
- ers = new HashMap<List<String>, Exception>());
+ ers = new HashMap<>());
}
ers.put(qid, ex);
}
Map<List<String>, DasGFFAdapter> results,
Map<List<String>, Exception> errors)
{
- Set<SequenceI> sequences = new HashSet<SequenceI>();
+ Set<SequenceI> sequences = new HashSet<>();
String source = jvsource.getSourceURL();
// process features
DasGFFAdapter result = (results == null) ? null : results.get(ids);
if (seq == af.getViewport().getAlignment().getSequenceAt(index)
.getDatasetSequence())
{
- af.alignPanel.paintAlignment(true);
+ af.alignPanel.paintAlignment(true, true);
index = end;
break;
}
// TODO: minimal list of DAS queries to make by querying with untyped ID if
// distinct from any typed IDs
- List<DBRefEntry> ids = new ArrayList<DBRefEntry>();
- List<String> qstring = new ArrayList<String>();
+ List<DBRefEntry> ids = new ArrayList<>();
+ List<String> qstring = new ArrayList<>();
boolean dasCoordSysFound = false;
if (uprefs != null)
import jalview.datamodel.xdb.uniprot.UniprotEntry;
import jalview.datamodel.xdb.uniprot.UniprotFeature;
import jalview.datamodel.xdb.uniprot.UniprotFile;
-import jalview.ws.ebi.EBIFetchClient;
import jalview.ws.seqfetcher.DbSourceProxyImpl;
-import java.io.File;
-import java.io.FileReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
+import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Vector;
queries = queries.toUpperCase().replaceAll(
"(UNIPROT\\|?|UNIPROT_|UNIREF\\d+_|UNIREF\\d+\\|?)", "");
AlignmentI al = null;
- EBIFetchClient ebi = new EBIFetchClient();
- // uniprotxml parameter required since december 2007
- // uniprotkb dbname changed introduced december 2008
- File file = ebi.fetchDataAsFile("uniprotkb:" + queries, "uniprotxml",
- "xml");
+
+ String downloadstring = "http://www.uniprot.org/uniprot/" + queries
+ + ".xml";
+ URL url = null;
+ URLConnection urlconn = null;
+
+ url = new URL(downloadstring);
+ urlconn = url.openConnection();
+ InputStream istr = urlconn.getInputStream();
Vector<UniprotEntry> entries = getUniprotEntries(
- new FileReader(file));
+ new InputStreamReader(istr, "UTF-8"));
if (entries != null)
{
- ArrayList<SequenceI> seqs = new ArrayList<SequenceI>();
+ ArrayList<SequenceI> seqs = new ArrayList<>();
for (UniprotEntry entry : entries)
{
seqs.add(uniprotEntryToSequenceI(entry));
return al;
} catch (Exception e)
{
- stopQuery();
throw (e);
+ } finally
+ {
+ stopQuery();
}
}
sequence.setDescription(getUniprotEntryDescription(entry));
final String dbVersion = getDbVersion();
- ArrayList<DBRefEntry> dbRefs = new ArrayList<DBRefEntry>();
+ ArrayList<DBRefEntry> dbRefs = new ArrayList<>();
for (String accessionId : entry.getAccession())
{
DBRefEntry dbRef = new DBRefEntry(DBRefSource.UNIPROT, dbVersion,
dbRefs.add(dbRef);
}
- Vector<PDBEntry> onlyPdbEntries = new Vector<PDBEntry>();
+ Vector<PDBEntry> onlyPdbEntries = new Vector<>();
for (PDBEntry pdb : entry.getDbReference())
{
DBRefEntry dbr = new DBRefEntry();
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
+import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
{
URL rcall = new URL(url);
- InputStream is = new BufferedInputStream(rcall.openStream());
+ HttpURLConnection conn = (HttpURLConnection) rcall.openConnection();
+ int responseCode = conn.getResponseCode();
+ if (responseCode != 200)
+ {
+ System.err.println("Warning: response code " + responseCode
+ + " for " + url);
+ }
+ InputStream is = new BufferedInputStream(conn.getInputStream());
if (outFile != null)
{
FileOutputStream fio = new FileOutputStream(outFile);
if (database.equalsIgnoreCase(DBRefSource.EMBL)
|| database.equalsIgnoreCase(DBRefSource.EMBLCDS))
{
- url = "http://www.ebi.ac.uk/ena/data/view/" + ids.toLowerCase()
+ url = "https://www.ebi.ac.uk/ena/data/view/" + ids.toLowerCase()
+ (format != null ? "&" + format : "");
}
else
{
- url = "http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/"
+ url = "https://www.ebi.ac.uk/Tools/dbfetch/dbfetch/"
+ database.toLowerCase() + "/" + ids.toLowerCase()
+ (format != null ? "/" + format : "");
}
{
// TODO: turn this into some kind of configuration file that's a bit easier
// to edit
- featureMap = new HashMap<String, Map<String, String[]>>();
+ featureMap = new HashMap<>();
Map<String, String[]> fmap;
featureMap.put(compbio.ws.client.Services.IUPredWS.toString(),
- fmap = new HashMap<String, String[]>());
+ fmap = new HashMap<>());
fmap.put("Glob",
new String[]
{ "Globular Domain", "Predicted globular domain" });
featureMap.put(compbio.ws.client.Services.JronnWS.toString(),
- fmap = new HashMap<String, String[]>());
+ fmap = new HashMap<>());
featureMap.put(compbio.ws.client.Services.DisemblWS.toString(),
- fmap = new HashMap<String, String[]>());
+ fmap = new HashMap<>());
fmap.put("REM465", new String[] { "REM465", "Missing density" });
fmap.put("HOTLOOPS", new String[] { "HOTLOOPS", "Flexible loops" });
fmap.put("COILS", new String[] { "COILS", "Random coil" });
featureMap.put(compbio.ws.client.Services.GlobPlotWS.toString(),
- fmap = new HashMap<String, String[]>());
+ fmap = new HashMap<>());
fmap.put("GlobDoms",
new String[]
{ "Globular Domain", "Predicted globular domain" });
new String[]
{ "Protein Disorder", "Probable unstructured peptide region" });
Map<String, Map<String, Object>> amap;
- annotMap = new HashMap<String, Map<String, Map<String, Object>>>();
+ annotMap = new HashMap<>();
annotMap.put(compbio.ws.client.Services.GlobPlotWS.toString(),
- amap = new HashMap<String, Map<String, Object>>());
+ amap = new HashMap<>());
amap.put("Dydx", new HashMap<String, Object>());
amap.get("Dydx").put(DONTCOMBINE, DONTCOMBINE);
amap.get("Dydx").put(THRESHOLD, new double[] { 1, 0 });
amap.put("RawScore", new HashMap<String, Object>());
amap.get("RawScore").put(INVISIBLE, INVISIBLE);
annotMap.put(compbio.ws.client.Services.DisemblWS.toString(),
- amap = new HashMap<String, Map<String, Object>>());
+ amap = new HashMap<>());
amap.put("COILS", new HashMap<String, Object>());
amap.put("HOTLOOPS", new HashMap<String, Object>());
amap.put("REM465", new HashMap<String, Object>());
amap.get("REM465").put(RANGE, new float[] { 0, 1 });
annotMap.put(compbio.ws.client.Services.IUPredWS.toString(),
- amap = new HashMap<String, Map<String, Object>>());
+ amap = new HashMap<>());
amap.put("Long", new HashMap<String, Object>());
amap.put("Short", new HashMap<String, Object>());
amap.get("Long").put(THRESHOLD, new double[] { 1, 0.5 });
amap.get("Short").put(THRESHOLD, new double[] { 1, 0.5 });
amap.get("Short").put(RANGE, new float[] { 0, 1 });
annotMap.put(compbio.ws.client.Services.JronnWS.toString(),
- amap = new HashMap<String, Map<String, Object>>());
+ amap = new HashMap<>());
amap.put("JRonn", new HashMap<String, Object>());
amap.get("JRonn").put(THRESHOLD, new double[] { 1, 0.5 });
amap.get("JRonn").put(RANGE, new float[] { 0, 1 });
Map<String, Map<String, Object>> annotTypeMap = annotMap
.get(service.serviceType);
boolean dispFeatures = false;
- Map<String, Object> fc = new Hashtable<String, Object>();
- List<AlignmentAnnotation> ourAnnot = new ArrayList<AlignmentAnnotation>();
+ Map<String, Object> fc = new Hashtable<>();
+ List<AlignmentAnnotation> ourAnnot = new ArrayList<>();
/**
* grouping for any annotation rows created
*/
// only do this if the alignFrame is currently showing this view.
af.setShowSeqFeatures(true);
}
- ap.paintAlignment(true);
}
if (ourAnnot.size() > 0)
{
// new alignment annotation rows created.
updateOurAnnots(ourAnnot);
ap.adjustAnnotationHeight();
+ ap.paintAlignment(true, true);
}
}
}
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
import jalview.gui.IProgressIndicator;
+import jalview.gui.IProgressIndicatorHandler;
import jalview.schemes.ResidueProperties;
import jalview.workers.AlignCalcWorker;
import jalview.ws.jws2.dm.AAConSettings;
progressId = System.currentTimeMillis());
}
rslt = submitToService(seqs);
+ if (guiProgress != null)
+ {
+ guiProgress.registerHandler(progressId,
+ new IProgressIndicatorHandler()
+ {
+ @Override
+ public boolean cancelActivity(long id)
+ {
+ cancelCurrentJob();
+ return true;
+ }
+
+ @Override
+ public boolean canCancel()
+ {
+ return true;
+ }
+ });
+ }
boolean finished = false;
long rpos = 0;
do
{
guiProgress.setProgressBar("", progressId);
}
- ap.paintAlignment(true);
+ // TODO: may not need to paintAlignment again !
+ ap.paintAlignment(false, false);
}
if (msg.length() > 0)
{
protected boolean checkDone()
{
calcMan.notifyStart(this);
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
while (!calcMan.notifyWorking(this))
{
if (calcMan.isWorking(this))
{
if (ap != null)
{
- ap.paintAlignment(false);
+ ap.paintAlignment(false, false);
}
Thread.sleep(200);
{
try
{
- Closeable svc = (Closeable) service;
- service = null;
- svc.close();
- } catch (Exception e)
+ ((Closeable) service).close();
+ } catch (Throwable t)
{
+ // ignore
}
- ;
}
super.finalize();
}
import jalview.gui.JvOptionPane;
import jalview.io.FastaFile;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.PrintStream;
import java.util.Arrays;
import java.util.Random;
import org.testng.annotations.BeforeClass;
/**
- * Generates, and outputs in Fasta format, a random DNA alignment for given
+ * Generates, and outputs in Fasta format, a random peptide or nucleotide alignment for given
* sequence length and count. Will regenerate the same alignment each time if
* the same random seed is used (so may be used for reproducible unit tests).
* Not guaranteed to reproduce the same results between versions, as the rules
* may get tweaked to produce more 'realistic' results.
*
- * Arguments:
- * <ul>
- * <li>length (number of bases in each sequence)</li>
- * <li>height (number of sequences)</li>
- * <li>a whole number random seed</li>
- * <li>percentage of gaps to include (0-100)</li>
- * <li>percentage chance of variation of each position (0-100)</li>
- * </ul>
- *
* @author gmcarstairs
- *
*/
public class AlignmentGenerator
{
- @BeforeClass(alwaysRun = true)
- public void setUpJvOptionPane()
- {
- JvOptionPane.setInteractiveMode(false);
- JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
- }
-
private static final char GAP = '-';
private static final char ZERO = '0';
private Random random;
+ private PrintStream ps;
/**
- * Outputs a DNA 'alignment' where each position is a random choice from
- * 'GTCA-'.
+ * Outputs a pseudo-randomly generated nucleotide or peptide alignment
+ * Arguments:
+ * <ul>
+ * <li>n (for nucleotide) or p (for peptide)</li>
+ * <li>length (number of bases in each sequence)</li>
+ * <li>height (number of sequences)</li>
+ * <li>a whole number random seed</li>
+ * <li>percentage of gaps to include (0-100)</li>
+ * <li>percentage chance of variation of each position (0-100)</li>
+ * <li>(optional) path to a file to write the alignment to</li>
+ * </ul>
+ *
*
* @param args
+ * @throws FileNotFoundException
*/
- public static void main(String[] args)
+ public static void main(String[] args) throws FileNotFoundException
{
- if (args.length != 6)
+ if (args.length != 6 && args.length != 7)
{
usage();
return;
}
+
+ PrintStream ps = System.out;
+ if (args.length == 7)
+ {
+ ps = new PrintStream(new File(args[6]));
+ }
+
boolean nucleotide = args[0].toLowerCase().startsWith("n");
int width = Integer.parseInt(args[1]);
int height = Integer.parseInt(args[2]);
long randomSeed = Long.valueOf(args[3]);
int gapPercentage = Integer.valueOf(args[4]);
int changePercentage = Integer.valueOf(args[5]);
- AlignmentI al = new AlignmentGenerator(nucleotide).generate(width,
- height,
- randomSeed, gapPercentage, changePercentage);
- System.out.println("; " + height + " sequences of " + width
+ ps.println("; " + height + " sequences of " + width
+ " bases with " + gapPercentage + "% gaps and "
+ changePercentage + "% mutations (random seed = " + randomSeed
+ ")");
- System.out.println(new FastaFile().print(al.getSequencesArray(), true));
+
+ new AlignmentGenerator(nucleotide, ps).generate(width, height,
+ randomSeed, gapPercentage, changePercentage);
+
+ if (ps != System.out)
+ {
+ ps.close();
+ }
}
/**
- * Print parameter help.
+ * Prints parameter help
*/
private static void usage()
{
System.out.println("Usage:");
System.out.println("arg0: n (for nucleotide) or p (for peptide)");
System.out.println("arg1: number of (non-gap) bases per sequence");
- System.out.println("arg2: number sequences");
+ System.out.println("arg2: number of sequences");
System.out
.println("arg3: an integer as random seed (same seed = same results)");
System.out.println("arg4: percentage of gaps to (randomly) generate");
System.out
.println("arg5: percentage of 'mutations' to (randomly) generate");
+ System.out
+ .println("arg6: (optional) path to output file (default is sysout)");
System.out.println("Example: AlignmentGenerator n 12 15 387 10 5");
System.out
.println("- 15 nucleotide sequences of 12 bases each, approx 10% gaps and 5% mutations, random seed = 387");
}
/**
- * Constructor that sets nucleotide or peptide symbol set
+ * Constructor that sets nucleotide or peptide symbol set, and also writes the
+ * generated alignment to sysout
*/
public AlignmentGenerator(boolean nuc)
{
- BASES = nuc ? NUCS : PEPS;
+ this(nuc, System.out);
+ }
+
+ /**
+ * Constructor that sets nucleotide or peptide symbol set, and also writes the
+ * generated alignment to the specified output stream (if not null). This can
+ * be used to write the alignment to a file or sysout.
+ */
+ public AlignmentGenerator(boolean nucleotide, PrintStream printStream)
+ {
+ BASES = nucleotide ? NUCS : PEPS;
+ ps = printStream;
}
/**
- * Outputs a DNA 'alignment' of given width and height, where each position is
- * a random choice from 'GTCA-'.
+ * Outputs an 'alignment' of given width and height, where each position is a
+ * random choice from the symbol alphabet, or - for gap
*
* @param width
* @param height
seqno + 1, width, changePercentage);
}
AlignmentI al = new Alignment(seqs);
+
+ if (ps != null)
+ {
+ ps.println(new FastaFile().print(al.getSequencesArray(), true));
+ }
+
return al;
}
assertEquals(s_as3, uas3.getSequenceAsString());
}
+ /**
+ * Tests for the method that maps nucleotide to protein based on CDS features
+ */
+ @Test(groups = "Functional")
+ public void testMapCdsToProtein()
+ {
+ SequenceI peptide = new Sequence("pep", "KLQ");
+
+ /*
+ * Case 1: CDS 3 times length of peptide
+ * NB method only checks lengths match, not translation
+ */
+ SequenceI dna = new Sequence("dna", "AACGacgtCTCCT");
+ dna.createDatasetSequence();
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 1, 4, null));
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 9, 13, null));
+ MapList ml = AlignmentUtils.mapCdsToProtein(dna, peptide);
+ assertEquals(3, ml.getFromRatio());
+ assertEquals(1, ml.getToRatio());
+ assertEquals("[[1, 3]]",
+ Arrays.deepToString(ml.getToRanges().toArray()));
+ assertEquals("[[1, 4], [9, 13]]",
+ Arrays.deepToString(ml.getFromRanges().toArray()));
+
+ /*
+ * Case 2: CDS 3 times length of peptide + stop codon
+ * (note code does not currently check trailing codon is a stop codon)
+ */
+ dna = new Sequence("dna", "AACGacgtCTCCTTGA");
+ dna.createDatasetSequence();
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 1, 4, null));
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 9, 16, null));
+ ml = AlignmentUtils.mapCdsToProtein(dna, peptide);
+ assertEquals(3, ml.getFromRatio());
+ assertEquals(1, ml.getToRatio());
+ assertEquals("[[1, 3]]",
+ Arrays.deepToString(ml.getToRanges().toArray()));
+ assertEquals("[[1, 4], [9, 13]]",
+ Arrays.deepToString(ml.getFromRanges().toArray()));
+
+ /*
+ * Case 3: CDS not 3 times length of peptide - no mapping is made
+ */
+ dna = new Sequence("dna", "AACGacgtCTCCTTG");
+ dna.createDatasetSequence();
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 1, 4, null));
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 9, 15, null));
+ ml = AlignmentUtils.mapCdsToProtein(dna, peptide);
+ assertNull(ml);
+
+ /*
+ * Case 4: incomplete start codon corresponding to X in peptide
+ */
+ dna = new Sequence("dna", "ACGacgtCTCCTTGG");
+ dna.createDatasetSequence();
+ SequenceFeature sf = new SequenceFeature("CDS", "", 1, 3, null);
+ sf.setPhase("2"); // skip 2 positions (AC) to start of next codon (GCT)
+ dna.addSequenceFeature(sf);
+ dna.addSequenceFeature(new SequenceFeature("CDS", "", 8, 15, null));
+ peptide = new Sequence("pep", "XLQ");
+ ml = AlignmentUtils.mapCdsToProtein(dna, peptide);
+ assertEquals("[[2, 3]]",
+ Arrays.deepToString(ml.getToRanges().toArray()));
+ assertEquals("[[3, 3], [8, 12]]",
+ Arrays.deepToString(ml.getFromRanges().toArray()));
+ }
+
}
s2 = new Sequence("Seq2", "ASDFA");
s2.setStart(5);
s2.setEnd(9);
- s3 = new Sequence("Seq1", "SDFAQQQSSS");
+ s3 = new Sequence("Seq3", "SDFAQQQSSS");
}
};
as.printAlignment(ps);
- String expected = "Score = 320.0\nLength of alignment = 10\nSequence Seq1 : 3 - 18 (Sequence length = 14)\nSequence Seq1 : 1 - 10 (Sequence length = 10)\n\n"
- + "Seq1 SDFAQQQRRR\n"
- + " ||||||| \n"
- + "Seq1 SDFAQQQSSS\n\n" + "Percentage ID = 70.00\n";
+ String expected = "Score = 320.0\nLength of alignment = 10\nSequence Seq1/4-13 (Sequence length = 14)\nSequence Seq3/1-10 (Sequence length = 10)\n\n"
+ + "Seq1/4-13 SDFAQQQRRR\n"
+ + " ||||||| \n"
+ + "Seq3/1-10 SDFAQQQSSS\n\n" + "Percentage ID = 70.00\n\n";
assertEquals(expected, baos.toString());
}
}
}
@Test(groups = "Functional")
- public void TestConstructor()
+ public void testConstructor()
{
SequenceI seq1 = new Sequence("sq1",
"ASFDDABACBACBACBACBACBACBABCABCBACBABCAB");
sg1.setStartRes(2);
sg1.setEndRes(23);
- CigarArray cig = new CigarArray(al, hc, sg1);
+ // Cigar array meanings:
+ // M = match
+ // D = deletion
+ // I = insertion
+ // number preceding M/D/I is the number of residues which
+ // match/are deleted/are inserted
+ // In the CigarArray constructor only matches or deletions are created, as
+ // we are comparing a sequence to its own subsequence (the group) + hidden
+ // columns.
+
+ // no hidden columns case
+ CigarArray cig = new CigarArray(al, null, sg1);
String result = cig.getCigarstring();
+ assertEquals(result, "22M");
+
+ cig = new CigarArray(al, hc, sg1);
+ result = cig.getCigarstring();
assertEquals(result, "1M4D9M5D3M");
// group starts at hidden cols
assertTrue(bs.equals(expected));
}
+
+ public void testFindFeatures_largeEndPos()
+ {
+ /*
+ * imitate a PDB sequence where end is larger than end position
+ */
+ SequenceI sq = new Sequence("test", "-ABC--DEF--", 1, 20);
+ sq.createDatasetSequence();
+
+ assertTrue(sq.findFeatures(1, 9).isEmpty());
+ // should be no array bounds exception - JAL-2772
+ assertTrue(sq.findFeatures(1, 15).isEmpty());
+
+ // add feature on BCD
+ SequenceFeature sfBCD = new SequenceFeature("Cath", "desc", 2, 4, 2f,
+ null);
+ sq.addSequenceFeature(sfBCD);
+
+ // no features in columns 1-2 (-A)
+ List<SequenceFeature> found = sq.findFeatures(1, 2);
+ assertTrue(found.isEmpty());
+
+ // columns 1-6 (-ABC--) includes BCD
+ found = sq.findFeatures(1, 6);
+ assertEquals(1, found.size());
+ assertTrue(found.contains(sfBCD));
+
+ // columns 10-11 (--) should find nothing
+ found = sq.findFeatures(10, 11);
+ assertEquals(0, found.size());
+ }
+
+ @Test(groups = { "Functional" })
+ public void testSetName()
+ {
+ SequenceI sq = new Sequence("test", "-ABC---DE-F--");
+ assertEquals("test", sq.getName());
+ assertEquals(1, sq.getStart());
+ assertEquals(6, sq.getEnd());
+
+ sq.setName("testing");
+ assertEquals("testing", sq.getName());
+
+ sq.setName("test/8-10");
+ assertEquals("test", sq.getName());
+ assertEquals(8, sq.getStart());
+ assertEquals(13, sq.getEnd()); // note end is recomputed
+
+ sq.setName("testing/7-99");
+ assertEquals("testing", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd()); // end may be beyond physical end
+
+ sq.setName("/2-3");
+ assertEquals("", sq.getName());
+ assertEquals(2, sq.getStart());
+ assertEquals(7, sq.getEnd());
+
+ sq.setName("test/"); // invalid
+ assertEquals("test/", sq.getName());
+ assertEquals(2, sq.getStart());
+ assertEquals(7, sq.getEnd());
+
+ sq.setName("test/6-13/7-99");
+ assertEquals("test/6-13", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/0-5"); // 0 is invalid - ignored
+ assertEquals("test/0-5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/a-5"); // a is invalid - ignored
+ assertEquals("test/a-5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/6-5"); // start > end is invalid - ignored
+ assertEquals("test/6-5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/5"); // invalid - ignored
+ assertEquals("test/5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/-5"); // invalid - ignored
+ assertEquals("test/-5", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/5-"); // invalid - ignored
+ assertEquals("test/5-", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName("test/5-6-7"); // invalid - ignored
+ assertEquals("test/5-6-7", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+
+ sq.setName(null); // invalid, gets converted to space
+ assertEquals("", sq.getName());
+ assertEquals(7, sq.getStart());
+ assertEquals(99, sq.getEnd());
+ }
+
+ @Test(groups = { "Functional" })
+ public void testCheckValidRange()
+ {
+ Sequence sq = new Sequence("test/7-12", "-ABC---DE-F--");
+ assertEquals(7, sq.getStart());
+ assertEquals(12, sq.getEnd());
+
+ /*
+ * checkValidRange ensures end is at least the last residue position
+ */
+ PA.setValue(sq, "end", 2);
+ sq.checkValidRange();
+ assertEquals(12, sq.getEnd());
+
+ /*
+ * end may be beyond the last residue position
+ */
+ PA.setValue(sq, "end", 22);
+ sq.checkValidRange();
+ assertEquals(22, sq.getEnd());
+ }
}
assertEquals(features.size(), 2);
assertTrue(features.contains(sf2));
assertTrue(features.contains(sf3));
+
+ features = store.getFeaturesByOntology("sequence_variant");
+ assertTrue(features.isEmpty());
}
@Test(groups = "Functional")
assertEquals(-1, fc.compare("coding_exon", "feature_variant"));
assertEquals(1f, fc.getTransparency());
}
+
+ @Test(groups = "Network")
+ public void testGetGeneIds()
+ {
+ /*
+ * ENSG00000158828 gene id PINK1 human
+ * ENST00000321556 transcript for the same gene - should not be duplicated
+ * P30419 Uniprot identifier for ENSG00000136448
+ * ENST00000592782 transcript for Uniprot gene - should not be duplicated
+ * BRAF - gene name resolvabe (at time of writing) for 6 model species
+ */
+ String ids = "ENSG00000158828 ENST00000321556 P30419 ENST00000592782 BRAF";
+ EnsemblGene testee = new EnsemblGene();
+ List<String> geneIds = testee.getGeneIds(ids);
+ assertEquals(8, geneIds.size());
+ assertTrue(geneIds.contains("ENSG00000158828"));
+ assertTrue(geneIds.contains("ENSG00000136448"));
+ assertTrue(geneIds.contains("ENSG00000157764")); // BRAF human
+ assertTrue(geneIds.contains("ENSMUSG00000002413")); // mouse
+ assertTrue(geneIds.contains("ENSRNOG00000010957")); // rat
+ assertTrue(geneIds.contains("ENSXETG00000004845")); // xenopus
+ assertTrue(geneIds.contains("ENSDARG00000017661")); // zebrafish
+ assertTrue(geneIds.contains("ENSGALG00000012865")); // chicken
+ }
}
*/
package jalview.ext.ensembl;
+import static org.testng.Assert.assertTrue;
+
import jalview.datamodel.AlignmentI;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
+import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class EnsemblRestClientTest
{
+ private EnsemblRestClient sf;
@Test(suiteName = "live")
public void testIsEnsemblAvailable()
{
- EnsemblRestClient sf = new EnsemblRestClient()
+ boolean isAvailable = sf.isEnsemblAvailable();
+ if (isAvailable)
+ {
+ System.out.println("Ensembl is UP!");
+ }
+ else
+ {
+ System.err
+ .println("Ensembl is DOWN or unreachable ******************* BAD!");
+ }
+ }
+
+ @BeforeMethod(alwaysRun = true)
+ protected void setUp()
+ {
+ sf = new EnsemblRestClient()
{
@Override
}
};
- boolean isAvailable = sf.isEnsemblAvailable();
- if (isAvailable)
- {
- System.out.println("Ensembl is UP!");
- }
- else
+ }
+
+ @Test(groups = "Network")
+ public void testCheckEnsembl_overload()
+ {
+ for (int i = 0; i < 20; i++)
{
- System.err
- .println("Ensembl is DOWN or unreachable ******************* BAD!");
+ assertTrue(sf.checkEnsembl(), "Error on " + (i + 1) + "th ping");
}
}
-
}
}
- @Test(groups = "Functional")
- public void testIsTranscriptIdentifier()
- {
- EnsemblSeqProxy testee = new EnsemblGene();
- assertFalse(testee.isTranscriptIdentifier(null));
- assertFalse(testee.isTranscriptIdentifier(""));
- assertFalse(testee.isTranscriptIdentifier("ENSG00000012345"));
- assertTrue(testee.isTranscriptIdentifier("ENST00000012345"));
- assertTrue(testee.isTranscriptIdentifier("ENSMUST00000012345"));
- assertFalse(testee.isTranscriptIdentifier("enst00000012345"));
- assertFalse(testee.isTranscriptIdentifier("ENST000000123456"));
- assertFalse(testee.isTranscriptIdentifier("ENST0000001234"));
- }
-
- @Test(groups = "Functional")
- public void testIsGeneIdentifier()
- {
- EnsemblSeqProxy testee = new EnsemblGene();
- assertFalse(testee.isGeneIdentifier(null));
- assertFalse(testee.isGeneIdentifier(""));
- assertFalse(testee.isGeneIdentifier("ENST00000012345"));
- assertTrue(testee.isGeneIdentifier("ENSG00000012345"));
- assertTrue(testee.isGeneIdentifier("ENSMUSG00000012345"));
- assertFalse(testee.isGeneIdentifier("ensg00000012345"));
- assertFalse(testee.isGeneIdentifier("ENSG000000123456"));
- assertFalse(testee.isGeneIdentifier("ENSG0000001234"));
- }
-
/**
* Test the method that appends a single allele's reverse complement to a
* string buffer
--- /dev/null
+package jalview.ext.ensembl;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Set;
+
+import org.testng.annotations.Test;
+
+public class SpeciesTest
+{
+ @Test
+ public void testGetModelOrganisms()
+ {
+ Set<Species> models = Species.getModelOrganisms();
+ assertTrue(models.contains(Species.human));
+ assertFalse(models.contains(Species.horse));
+ for (Species s : Species.values())
+ {
+ if (s.isModelOrganism())
+ {
+ assertTrue(models.contains(s));
+ }
+ else
+ {
+ assertFalse(models.contains(s));
+ }
+ }
+ }
+}
assertEquals(model.getAtomSpec(), "#0:1-4.B,5-9.C|#1:2-5.A,8.A,5-10.B");
model.addRange(0, 3, 10, "C"); // subsumes 5-9
assertEquals(model.getAtomSpec(), "#0:1-4.B,3-10.C|#1:2-5.A,8.A,5-10.B");
+ model.addRange(5, 25, 35, " "); // empty chain code - e.g. from homology
+ // modelling
+ assertEquals(model.getAtomSpec(),
+ "#0:1-4.B,3-10.C|#1:2-5.A,8.A,5-10.B|#5:25-35.");
+
}
}
--- /dev/null
+package jalview.gui;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import jalview.analysis.AlignmentGenerator;
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceGroup;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class FreeUpMemoryTest
+{
+ private static final int ONE_MB = 1000 * 1000;
+
+ /**
+ * Configure (read-only) Jalview property settings for test
+ */
+ @BeforeClass(alwaysRun = true)
+ public void setUp()
+ {
+ Jalview.main(new String[] { "-nonews", "-props",
+ "test/jalview/testProps.jvprops" });
+ Cache.applicationProperties.setProperty("SHOW_ANNOTATIONS",
+ Boolean.TRUE.toString());
+ Cache.applicationProperties.setProperty("SHOW_QUALITY",
+ Boolean.TRUE.toString());
+ Cache.applicationProperties.setProperty("SHOW_CONSERVATION",
+ Boolean.TRUE.toString());
+ Cache.applicationProperties.setProperty("SHOW_OCCUPANCY",
+ Boolean.TRUE.toString());
+ Cache.applicationProperties.setProperty("SHOW_IDENTITY",
+ Boolean.TRUE.toString());
+ }
+
+ /**
+ * A simple test that memory is released when all windows are closed.
+ * <ul>
+ * <li>generates a reasonably large alignment and loads it</li>
+ * <li>performs various operations on the alignment</li>
+ * <li>closes all windows</li>
+ * <li>requests garbage collection</li>
+ * <li>asserts that the remaining memory footprint (heap usage) is 'not large'
+ * </li>
+ * </ul>
+ * If the test fails, this suggests that a reference to some large object
+ * (perhaps the alignment data, or some annotation / Tree / PCA data) has
+ * failed to be garbage collected. If this is the case, the heap will need to
+ * be inspected manually (suggest using jvisualvm) in order to track down
+ * where large objects are still referenced. The code (for example
+ * AlignmentViewport.dispose()) should then be updated to ensure references to
+ * large objects are set to null when they are no longer required.
+ *
+ * @throws IOException
+ */
+ @Test(groups = "Memory")
+ public void testFreeMemoryOnClose() throws IOException
+ {
+ File f = generateAlignment();
+ f.deleteOnExit();
+
+ doStuffInJalview(f);
+
+ Desktop.instance.closeAll_actionPerformed(null);
+
+ checkUsedMemory(35L);
+ }
+
+ /**
+ * Requests garbage collection and then checks whether remaining memory in use
+ * is less than the expected value (in Megabytes)
+ *
+ * @param expectedMax
+ */
+ protected void checkUsedMemory(long expectedMax)
+ {
+ /*
+ * request garbage collection and wait briefly for it to run;
+ * NB there is no guarantee when, or whether, it will do so
+ */
+ System.gc();
+ waitFor(100);
+
+ /*
+ * a second gc() call should not be necessary - but it is!
+ * the test passes with it, and fails without it
+ */
+ System.gc();
+ waitFor(100);
+
+ /*
+ * check used memory is 'reasonably low'
+ */
+ long availableMemory = Runtime.getRuntime().totalMemory() / ONE_MB;
+ long freeMemory = Runtime.getRuntime().freeMemory() / ONE_MB;
+ long usedMemory = availableMemory - freeMemory;
+
+ /*
+ * sanity check - fails if any frame was added after
+ * closeAll_actionPerformed
+ */
+ assertEquals(Desktop.instance.getAllFrames().length, 0);
+
+ /*
+ * if this assertion fails
+ * - set a breakpoint here
+ * - run jvisualvm to inspect a heap dump of Jalview
+ * - identify large objects in the heap and their referers
+ * - fix code as necessary to null the references on close
+ */
+ System.out.println("Used memory after gc = " + usedMemory + "MB");
+ assertTrue(usedMemory < expectedMax, String.format(
+ "Used memory %d should be less than %d (Recommend running test manually to verify)",
+ usedMemory,
+ expectedMax));
+ }
+
+ /**
+ * Loads an alignment from file and exercises various operations in Jalview
+ *
+ * @param f
+ */
+ protected void doStuffInJalview(File f)
+ {
+ /*
+ * load alignment, wait for consensus and other threads to complete
+ */
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(f.getPath(),
+ DataSourceType.FILE);
+ while (af.getViewport().isCalcInProgress())
+ {
+ waitFor(200);
+ }
+
+ /*
+ * set a selection group - potential memory leak if it retains
+ * a reference to the alignment
+ */
+ SequenceGroup sg = new SequenceGroup();
+ sg.setStartRes(0);
+ sg.setEndRes(100);
+ AlignmentI al = af.viewport.getAlignment();
+ for (int i = 0; i < al.getHeight(); i++)
+ {
+ sg.addSequence(al.getSequenceAt(i), false);
+ }
+ af.viewport.setSelectionGroup(sg);
+
+ /*
+ * compute Tree and PCA (on all sequences, 100 columns)
+ */
+ af.openTreePcaDialog();
+ CalculationChooser dialog = af.alignPanel.getCalculationDialog();
+ dialog.openPcaPanel("BLOSUM62", dialog.getSimilarityParameters(true));
+ dialog.openTreePanel("BLOSUM62", dialog.getSimilarityParameters(false));
+
+ /*
+ * wait until Tree and PCA have been computed
+ */
+ while (af.viewport.getCurrentTree() == null
+ && dialog.getPcaPanel().isWorking())
+ {
+ waitFor(10);
+ }
+
+ /*
+ * give Swing time to add the PCA panel (?!?)
+ */
+ waitFor(100);
+ }
+
+ /**
+ * Wait for waitMs miliseconds
+ *
+ * @param waitMs
+ */
+ protected void waitFor(int waitMs)
+ {
+ try
+ {
+ Thread.sleep(waitMs);
+ } catch (InterruptedException e)
+ {
+ }
+ }
+
+ /**
+ * Generates an alignment and saves it in a temporary file, to be loaded by
+ * Jalview. We use a peptide alignment (so Conservation and Quality are
+ * calculated), which is wide enough to ensure Consensus, Conservation and
+ * Occupancy have a significant memory footprint (if not removed from the
+ * heap).
+ *
+ * @return
+ * @throws IOException
+ */
+ private File generateAlignment() throws IOException
+ {
+ File f = File.createTempFile("MemoryTest", "fa");
+ PrintStream ps = new PrintStream(f);
+ AlignmentGenerator ag = new AlignmentGenerator(false, ps);
+ int width = 100000;
+ int height = 100;
+ ag.generate(width, height, 0, 10, 15);
+ return f;
+ }
+}
--- /dev/null
+package jalview.gui;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceGroup;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+
+import javax.swing.JTextArea;
+
+import junit.extensions.PA;
+
+import org.testng.annotations.Test;
+
+public class PairwiseAlignmentPanelTest
+{
+ @Test(groups = "Functional")
+ public void testConstructor_withSelectionGroup()
+ {
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", DataSourceType.FILE);
+ AlignViewport viewport = af.getViewport();
+ AlignmentI al = viewport.getAlignment();
+
+ /*
+ * select columns 29-36 of sequences 4 and 5 for alignment
+ * Q93XJ9_SOLTU/23-29 L-KAISNV
+ * FER1_PEA/26-32 V-TTTKAF
+ */
+ SequenceGroup sg = new SequenceGroup();
+ sg.addSequence(al.getSequenceAt(3), false);
+ sg.addSequence(al.getSequenceAt(4), false);
+ sg.setStartRes(28);
+ sg.setEndRes(35);
+ viewport.setSelectionGroup(sg);
+
+ PairwiseAlignPanel testee = new PairwiseAlignPanel(viewport);
+
+ String text = ((JTextArea) PA.getValue(testee, "textarea")).getText();
+ String expected = "Score = 80.0\n" + "Length of alignment = 4\n"
+ + "Sequence FER1_PEA/29-32 (Sequence length = 7)\n"
+ + "Sequence Q93XJ9_SOLTU/23-26 (Sequence length = 7)\n\n"
+ + " FER1_PEA/29-32 TKAF\n" + " ||.\n"
+ + "Q93XJ9_SOLTU/23-26 LKAI\n\n" + "Percentage ID = 50.00\n\n";
+ assertEquals(text, expected);
+ }
+
+ /**
+ * This test aligns the same sequences as testConstructor_withSelectionGroup
+ * but as a complete alignment (no selection). Note that in fact the user is
+ * currently required to make a selection in order to calculate pairwise
+ * alignments, so this case does not arise.
+ */
+ @Test(groups = "Functional")
+ public void testConstructor_noSelectionGroup()
+ {
+ String seqs = ">Q93XJ9_SOLTU/23-29\nL-KAISNV\n>FER1_PEA/26-32\nV-TTTKAF\n";
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(seqs,
+ DataSourceType.PASTE);
+ AlignViewport viewport = af.getViewport();
+
+ PairwiseAlignPanel testee = new PairwiseAlignPanel(viewport);
+
+ String text = ((JTextArea) PA.getValue(testee, "textarea")).getText();
+ String expected = "Score = 80.0\n" + "Length of alignment = 4\n"
+ + "Sequence FER1_PEA/29-32 (Sequence length = 7)\n"
+ + "Sequence Q93XJ9_SOLTU/23-26 (Sequence length = 7)\n\n"
+ + " FER1_PEA/29-32 TKAF\n" + " ||.\n"
+ + "Q93XJ9_SOLTU/23-26 LKAI\n\n" + "Percentage ID = 50.00\n\n";
+ assertEquals(text, expected);
+ }
+}
import javax.swing.JLabel;
import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
* @param layout
* @param msgs
*/
- private void verifyProgress(GridLayout layout, String[] msgs)
+ private void verifyProgress(final GridLayout layout, final String[] msgs)
{
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable()
+ {
+ @Override
+ public void run()
+ {
int msgCount = msgs.length;
assertEquals(1 + msgCount, layout.getRows());
assertEquals(msgCount, statusPanel.getComponentCount());
assertEquals(msgs[i++],
((JLabel) ((JPanel) c).getComponent(0)).getText());
}
+ }
+ });
+ } catch (Exception e)
+ {
+ throw new AssertionError(
+ "Unexpected exception waiting for progress bar validation",
+ e);
+ }
}
}
--- /dev/null
+package jalview.gui;
+
+import static org.testng.Assert.assertEquals;
+
+import jalview.datamodel.AlignmentI;
+import jalview.io.DataSourceType;
+import jalview.io.FileLoader;
+
+import java.awt.Font;
+import java.awt.FontMetrics;
+
+import junit.extensions.PA;
+
+import org.testng.annotations.Test;
+
+import sun.swing.SwingUtilities2;
+
+public class SeqCanvasTest
+{
+ /**
+ * Test the method that computes wrapped width in residues, height of wrapped
+ * widths in pixels, and the number of widths visible
+ */
+ @Test(groups = "Functional")
+ public void testCalculateWrappedGeometry_noAnnotations()
+ {
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", DataSourceType.FILE);
+ AlignViewport av = af.getViewport();
+ AlignmentI al = av.getAlignment();
+ assertEquals(al.getWidth(), 157);
+ assertEquals(al.getHeight(), 15);
+
+ av.setWrapAlignment(true);
+ av.getRanges().setStartEndSeq(0, 14);
+ av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+ assertEquals(charHeight, 17);
+ assertEquals(charWidth, 12);
+
+ SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
+
+ /*
+ * first with scales above, left, right
+ */
+ av.setShowAnnotation(false);
+ av.setScaleAboveWrapped(true);
+ av.setScaleLeftWrapped(true);
+ av.setScaleRightWrapped(true);
+ FontMetrics fm = SwingUtilities2.getFontMetrics(testee, av.getFont());
+ int labelWidth = fm.stringWidth("000") + charWidth;
+ assertEquals(labelWidth, 39); // 3 x 9 + charWidth
+
+ /*
+ * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
+ * take the whole multiple of character widths
+ */
+ int canvasWidth = 400;
+ int canvasHeight = 300;
+ int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
+ int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(wrappedWidth, residueColumns);
+ assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
+ assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
+ assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
+ 2 * charHeight);
+ int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
+ assertEquals(repeatingHeight, charHeight * (2 + al.getHeight()));
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
+
+ /*
+ * repeat height is 17 * (2 + 15) = 289
+ * make canvas height 2 * 289 + 3 * charHeight so just enough to
+ * draw 2 widths and the first sequence of a third
+ */
+ canvasHeight = charHeight * (17 * 2 + 3);
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
+
+ /*
+ * reduce canvas height by 1 pixel - should not be enough height
+ * to draw 3 widths
+ */
+ canvasHeight -= 1;
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
+
+ /*
+ * turn off scale above - can now fit in 2 and a bit widths
+ */
+ av.setScaleAboveWrapped(false);
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
+
+ /*
+ * reduce height to enough for 2 widths and not quite a third
+ * i.e. two repeating heights + spacer + sequence - 1 pixel
+ */
+ canvasHeight = charHeight * (16 * 2 + 2) - 1;
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
+
+ /*
+ * make canvas width enough for scales and 20 residues
+ */
+ canvasWidth = 2 * labelWidth + 20 * charWidth;
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 20);
+
+ /*
+ * reduce width by 1 pixel - rounds down to 19 residues
+ */
+ canvasWidth -= 1;
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 19);
+
+ /*
+ * turn off West scale - adds labelWidth (39) to available for residues
+ * which with the 11 remainder makes 50 which is 4 more charWidths rem 2
+ */
+ av.setScaleLeftWrapped(false);
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 23);
+
+ /*
+ * add 10 pixels to width to fit in another whole residue column
+ */
+ canvasWidth += 9;
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 23);
+ canvasWidth += 1;
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 24);
+
+ /*
+ * turn off East scale to gain 39 more pixels (3 columns remainder 3)
+ */
+ av.setScaleRightWrapped(false);
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 27);
+
+ /*
+ * add 9 pixels to width to gain a residue column
+ */
+ canvasWidth += 8;
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 27);
+ canvasWidth += 1;
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 28);
+
+ /*
+ * now West but not East scale - lose 39 pixels or 4 columns
+ */
+ av.setScaleLeftWrapped(true);
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 24);
+
+ /*
+ * adding 3 pixels to width regains one column
+ */
+ canvasWidth += 2;
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 24);
+ canvasWidth += 1;
+ wrappedWidth = testee.calculateWrappedGeometry(canvasWidth,
+ canvasHeight);
+ assertEquals(wrappedWidth, 25);
+
+ /*
+ * turn off scales left and right, make width exactly 157 columns
+ */
+ av.setScaleLeftWrapped(false);
+ canvasWidth = al.getWidth() * charWidth;
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
+ }
+
+ /**
+ * Test the method that computes wrapped width in residues, height of wrapped
+ * widths in pixels, and the number of widths visible
+ */
+ @Test(groups = "Functional")
+ public void testCalculateWrappedGeometry_withAnnotations()
+ {
+ AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
+ "examples/uniref50.fa", DataSourceType.FILE);
+ AlignViewport av = af.getViewport();
+ AlignmentI al = av.getAlignment();
+ assertEquals(al.getWidth(), 157);
+ assertEquals(al.getHeight(), 15);
+
+ av.setWrapAlignment(true);
+ av.getRanges().setStartEndSeq(0, 14);
+ av.setFont(new Font("SansSerif", Font.PLAIN, 14), true);
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+ assertEquals(charHeight, 17);
+ assertEquals(charWidth, 12);
+
+ SeqCanvas testee = af.alignPanel.getSeqPanel().seqCanvas;
+
+ /*
+ * first with scales above, left, right
+ */
+ av.setShowAnnotation(true);
+ av.setScaleAboveWrapped(true);
+ av.setScaleLeftWrapped(true);
+ av.setScaleRightWrapped(true);
+ FontMetrics fm = SwingUtilities2.getFontMetrics(testee, av.getFont());
+ int labelWidth = fm.stringWidth("000") + charWidth;
+ assertEquals(labelWidth, 39); // 3 x 9 + charWidth
+ int annotationHeight = testee.getAnnotationHeight();
+
+ /*
+ * width 400 pixels leaves (400 - 2*labelWidth) for residue columns
+ * take the whole multiple of character widths
+ */
+ int canvasWidth = 400;
+ int canvasHeight = 300;
+ int residueColumns = (canvasWidth - 2 * labelWidth) / charWidth;
+ int wrappedWidth = testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(wrappedWidth, residueColumns);
+ assertEquals(PA.getValue(testee, "labelWidthWest"), labelWidth);
+ assertEquals(PA.getValue(testee, "labelWidthEast"), labelWidth);
+ assertEquals(PA.getValue(testee, "wrappedSpaceAboveAlignment"),
+ 2 * charHeight);
+ int repeatingHeight = (int) PA.getValue(testee, "wrappedRepeatHeightPx");
+ assertEquals(repeatingHeight, charHeight * (2 + al.getHeight())
+ + annotationHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 1);
+
+ /*
+ * repeat height is 17 * (2 + 15) = 289 + annotationHeight = 507
+ * make canvas height 2 * 289 + 3 * charHeight so just enough to
+ * draw 2 widths and the first sequence of a third
+ */
+ canvasHeight = charHeight * (17 * 2 + 3) + 2 * annotationHeight;
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
+
+ /*
+ * reduce canvas height by 1 pixel - should not be enough height
+ * to draw 3 widths
+ */
+ canvasHeight -= 1;
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
+
+ /*
+ * turn off scale above - can now fit in 2 and a bit widths
+ */
+ av.setScaleAboveWrapped(false);
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
+
+ /*
+ * reduce height to enough for 2 widths and not quite a third
+ * i.e. two repeating heights + spacer + sequence - 1 pixel
+ */
+ canvasHeight = charHeight * (16 * 2 + 2) + 2 * annotationHeight - 1;
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 2);
+
+ /*
+ * add 1 pixel to height - should now get 3 widths drawn
+ */
+ canvasHeight += 1;
+ testee.calculateWrappedGeometry(canvasWidth, canvasHeight);
+ assertEquals(PA.getValue(testee, "wrappedVisibleWidths"), 3);
+ }
+}
AlignViewport av = af.getViewport();
/*
- * scale has minor ticks at 5 and 15, major at 10 and 20
+ * scale has minor ticks at 5, 15, 25, major at 10 and 20
* (these are base 1, ScaleMark holds base 0 values)
*/
List<ScaleMark> marks = new ScaleRenderer().calculateMarks(av, 0, 25);
- assertEquals(marks.size(), 4);
+ assertEquals(marks.size(), 5);
assertFalse(marks.get(0).major);
assertEquals(marks.get(0).column, 4);
assertEquals(marks.get(3).column, 19);
assertEquals(marks.get(3).text, "20");
+ assertFalse(marks.get(4).major);
+ assertEquals(marks.get(4).column, 24);
+ assertNull(marks.get(4).text);
+
/*
* now hide columns 9-11 and 18-20 (base 1)
* scale marks are now in the same columns as before, but
av.hideColumns(8, 10);
av.hideColumns(17, 19);
marks = new ScaleRenderer().calculateMarks(av, 0, 25);
- assertEquals(marks.size(), 4);
+ assertEquals(marks.size(), 5);
assertFalse(marks.get(0).major);
assertEquals(marks.get(0).column, 4);
assertNull(marks.get(0).text);
assertTrue(marks.get(3).major);
assertEquals(marks.get(3).column, 19);
assertEquals(marks.get(3).text, "26"); // +6 hidden columns
+ assertFalse(marks.get(4).major);
+ assertEquals(marks.get(4).column, 24);
+ assertNull(marks.get(4).text);
}
}
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
}
@Test(groups = "Functional")
+ public void testFindFeatureAtEnd()
+ {
+ /*
+ * terminal residue feature
+ */
+ seq.addSequenceFeature(new SequenceFeature("PDBRESNUM", "pdb res 1",
+ seq.getEnd(), seq.getEnd(), Float.NaN, "1seq.pdb"));
+ fr.setColour("PDBRESNUM", new FeatureColour(Color.red));
+ fr.featuresAdded();
+ av.setShowSequenceFeatures(true);
+
+ /*
+ * final column should have PDBRESNUM feature, the others not
+ */
+ Color c = finder.findFeatureColour(Color.blue, seq,
+ seq.getLength() - 2);
+ assertNotEquals(c, Color.red);
+ c = finder.findFeatureColour(Color.blue, seq, seq.getLength() - 1);
+ assertEquals(c, Color.red);
+ }
+
+ @Test(groups = "Functional")
public void testFindFeatureColour_graduatedFeatureColour()
{
seq.addSequenceFeature(new SequenceFeature("kd", "hydrophobicity", 2,
StructureSelectionManager ssm = new StructureSelectionManager();
ssm.setMapping(new SequenceI[] { seq1a, seq1b }, null, PDB_1,
- DataSourceType.PASTE);
+ DataSourceType.PASTE, null);
ssm.setMapping(new SequenceI[] { seq2 }, null, PDB_2,
- DataSourceType.PASTE);
+ DataSourceType.PASTE, null);
ssm.setMapping(new SequenceI[] { seq3 }, null, PDB_3,
- DataSourceType.PASTE);
+ DataSourceType.PASTE, null);
testee = new AAStructureBindingModel(ssm, pdbFiles, seqs, null)
{
assertEquals("[12, 11, 8, 4]", Arrays.toString(ranges));
}
+ @Test(groups = "Functional")
+ public void testRemoveEndPositions()
+ {
+ List<int[]> ranges = new ArrayList<>();
+
+ /*
+ * case 1: truncate last range
+ */
+ ranges.add(new int[] { 1, 10 });
+ ranges.add(new int[] { 20, 30 });
+ MappingUtils.removeEndPositions(5, ranges);
+ assertEquals(2, ranges.size());
+ assertEquals(25, ranges.get(1)[1]);
+
+ /*
+ * case 2: remove last range
+ */
+ ranges.clear();
+ ranges.add(new int[] { 1, 10 });
+ ranges.add(new int[] { 20, 22 });
+ MappingUtils.removeEndPositions(3, ranges);
+ assertEquals(1, ranges.size());
+ assertEquals(10, ranges.get(0)[1]);
+
+ /*
+ * case 3: truncate penultimate range
+ */
+ ranges.clear();
+ ranges.add(new int[] { 1, 10 });
+ ranges.add(new int[] { 20, 21 });
+ MappingUtils.removeEndPositions(3, ranges);
+ assertEquals(1, ranges.size());
+ assertEquals(9, ranges.get(0)[1]);
+
+ /*
+ * case 4: remove last two ranges
+ */
+ ranges.clear();
+ ranges.add(new int[] { 1, 10 });
+ ranges.add(new int[] { 20, 20 });
+ ranges.add(new int[] { 30, 30 });
+ MappingUtils.removeEndPositions(3, ranges);
+ assertEquals(1, ranges.size());
+ assertEquals(9, ranges.get(0)[1]);
+ }
}
}
}
}
+
+ @Test(groups = { "Functional" })
+ public void testScrollUp_wrapped()
+ {
+ /*
+ * alignment 30 tall and 45 wide
+ */
+ AlignmentI al2 = gen.generate(45, 30, 1, 0, 5);
+
+ /*
+ * wrapped view, 5 sequences high, start at sequence offset 1
+ */
+ ViewportRanges vr = new ViewportRanges(al2);
+ vr.setWrappedMode(true);
+ vr.setViewportStartAndHeight(1, 5);
+
+ /*
+ * offset wrapped view to column 3
+ */
+ vr.setStartEndRes(3, 22);
+
+ int startRes = vr.getStartRes();
+ int width = vr.getViewportWidth();
+ assertEquals(startRes, 3);
+ assertEquals(width, 20);
+
+ // in wrapped mode, we change startRes but not startSeq
+ // scroll down:
+ vr.scrollUp(false);
+ assertEquals(vr.getStartSeq(), 1);
+ assertEquals(vr.getStartRes(), 23);
+
+ // scroll up returns to original position
+ vr.scrollUp(true);
+ assertEquals(vr.getStartSeq(), 1);
+ assertEquals(vr.getStartRes(), 3);
+
+ // scroll up again returns to 'origin'
+ vr.scrollUp(true);
+ assertEquals(vr.getStartSeq(), 1);
+ assertEquals(vr.getStartRes(), 0);
+
+ /*
+ * offset 3 columns once more and do some scroll downs
+ */
+ vr.setStartEndRes(3, 22);
+ vr.scrollUp(false);
+ assertEquals(vr.getStartSeq(), 1);
+ assertEquals(vr.getStartRes(), 23);
+ vr.scrollUp(false);
+ assertEquals(vr.getStartSeq(), 1);
+ assertEquals(vr.getStartRes(), 43);
+
+ /*
+ * scroll down beyond end of alignment does nothing
+ */
+ vr.scrollUp(false);
+ assertEquals(vr.getStartSeq(), 1);
+ assertEquals(vr.getStartRes(), 43);
+ }
}
// mock listener for property change events
/*
* EMBL
*/
- assertEquals("http://www.ebi.ac.uk/ena/data/view/x53838&display=xml",
+ assertEquals("https://www.ebi.ac.uk/ena/data/view/x53838&display=xml",
EBIFetchClient.buildUrl("X53838", "EMBL", "display=xml"));
/*
* EMBLCDS
*/
- assertEquals("http://www.ebi.ac.uk/ena/data/view/caa37824&display=xml",
+ assertEquals("https://www.ebi.ac.uk/ena/data/view/caa37824&display=xml",
EBIFetchClient.buildUrl("CAA37824", "EMBL", "display=xml"));
/*
- * Uniprot
- */
- assertEquals(
- "http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/uniprot/p00340/uniprotxml",
- EBIFetchClient.buildUrl("P00340", "UNIPROT", "uniprotxml"));
-
- /*
* PDB / pdb
*/
- assertEquals("http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/pdb/3a6s/pdb",
+ assertEquals("https://www.ebi.ac.uk/Tools/dbfetch/dbfetch/pdb/3a6s/pdb",
EBIFetchClient.buildUrl("3A6S", "PDB", "pdb"));
/*
* PDB / mmCIF
*/
assertEquals(
- "http://www.ebi.ac.uk/Tools/dbfetch/dbfetch/pdb/3a6s/mmCIF",
+ "https://www.ebi.ac.uk/Tools/dbfetch/dbfetch/pdb/3a6s/mmCIF",
EBIFetchClient.buildUrl("3A6S", "PDB", "mmCIF"));
}
<!--
Suppress check of externally sourced code
-->
- <suppress checks="[a-zA-Z0-9]*" files="com[\\/]*"/>
- <suppress checks="[a-zA-Z0-9]*" files="ext[\\/]*"/>
- <suppress checks="[a-zA-Z0-9]*" files="org[\\/]*"/>
- <suppress checks="[a-zA-Z0-9]*" files="uk[\\/]*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]com[\\/]github*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]com[\\/]stevesoft*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]ext[\\/]edu*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]ext[\\/]vamsas*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]org[\\/]jibble*"/>
+ <suppress checks="[a-zA-Z0-9]*" files="[\\/]uk[\\/]ac*"/>
<!--
ImportControl can only handle one top level package
<subpackage name="datamodel">
<disallow pkg="jalview.gui"/>
<allow pkg="fr.orsay.lri.varna"/>
- <subpackage name="xdb">
- <subpackage name="embl">
- <allow pkg="org.exolab.castor"/>
- </subpackage>
+ <subpackage name="xdb.embl">
+ <allow pkg="org.exolab.castor"/>
</subpackage>
</subpackage>
+ <subpackage name="ext">
+ <subpackage name="ensembl">
+ <allow pkg="javax.ws"/>
+ <allow pkg="org.json"/>
+ </subpackage>
+ <subpackage name="htsjdk">
+ <allow pkg="htsjdk"/>
+ </subpackage>
+ <subpackage name="jmol">
+ <allow pkg="MCview"/>
+ <allow pkg="org.jmol"/>
+ </subpackage>
+ <subpackage name="paradise">
+ <allow pkg="org.apache"/>
+ <allow pkg="org.json"/>
+ </subpackage>
+ <subpackage name="rbvi">
+ <allow pkg="ext.edu.ucsf"/>
+ <allow pkg="javax.servlet"/>
+ </subpackage>
+ <subpackage name="so">
+ <allow pkg="org.biojava"/>
+ </subpackage>
+ <subpackage name="varna">
+ <allow pkg="fr.orsay"/>
+ </subpackage>
+ </subpackage>
+
<subpackage name="fts">
<allow pkg="javax.swing"/>
<allow pkg="javax.ws"/>
</subpackage>
<subpackage name="schemes">
- <allow pkg="org.exolab.castor"/>
+ <allow pkg="org.exolab.castor" class="jalview.schemes.ColourSchemeLoader"/>
</subpackage>
<subpackage name="structure">