id 'application'
id 'eclipse'
id "com.diffplug.gradle.spotless" version "3.28.0"
- id 'com.github.johnrengelman.shadow' version '4.0.3'
+ id 'com.github.johnrengelman.shadow' version '7.1.2'
id 'com.install4j.gradle' version '10.0.3'
id 'com.dorongold.task-tree' version '2.1.1' // only needed to display task dependency tree with gradle task1 [task2 ...] taskTree
id 'com.palantir.git-version' version '0.13.0' apply false
}
}
+task testTask2(type: Test) {
+ group = "Verification"
+ description = "Tests that need to be isolated from the main test run"
+ useTestNG() {
+ includeGroups name
+ excludeGroups testng_excluded_groups.split(",")
+ preserveOrder true
+ useDefaultListeners=true
+ }
+}
+task testTask3(type: Test) {
+ group = "Verification"
+ description = "Tests that need to be isolated from the main test run"
+ useTestNG() {
+ includeGroups name
+ excludeGroups testng_excluded_groups.split(",")
+ preserveOrder true
+ useDefaultListeners=true
+ }
+}
+
/* insert more testTaskNs here -- change N to next digit or other string */
/*
task testTaskN(type: Test) {
showExceptions true
showCauses true
showStackTraces true
-
+ if (test_output) {
+ showStandardStreams true
+ }
info.events = [ TestLogEvent.FAILED ]
}
if (buildDist) {
dependsOn makeDist
}
- from ("${jalviewDir}/${libDistDir}") {
- include("*.jar")
- }
- manifest {
- attributes "Implementation-Version": JALVIEW_VERSION,
- "Application-Name": applicationName
+
+ def jarFiles = fileTree(dir: "${jalviewDir}/${libDistDir}", include: "*.jar", exclude: "regex.jar").getFiles()
+ def groovyJars = jarFiles.findAll {it1 -> file(it1).getName().startsWith("groovy-swing")}
+ def otherJars = jarFiles.findAll {it2 -> !file(it2).getName().startsWith("groovy-swing")}
+ from groovyJars
+ from otherJars
+
+ // we need to include the groovy-swing Include-Package for it to run in the shadowJar
+ doFirst {
+ def jarFileManifests = []
+ groovyJars.each { jarFile ->
+ def mf = zipTree(jarFile).getFiles().find { it.getName().equals("MANIFEST.MF") }
+ if (mf != null) {
+ jarFileManifests += mf
+ }
+ }
+
+ manifest {
+ attributes "Implementation-Version": JALVIEW_VERSION, "Application-Name": applicationName
+ from (jarFileManifests) {
+ eachEntry { details ->
+ if (!details.key.equals("Import-Package")) {
+ details.exclude()
+ }
+ }
+ }
+ }
}
duplicatesStrategy "INCLUDE"
You can run different defined groups of tests with
```bash
-gradle test -PtestngGroups=Network
+gradle test -Ptestng_groups=Network
```
Available groups include Functional (default), Network, External.
To exclude one or more groups of tests, add them as a comma separated list in testngExcludedGroups.
```bash
-gradle test -PtestngExcludedGroups=Not-bamboo
+gradle test -Ptestng_excluded_groups=Not-bamboo
```
+#### Viewing stdout and stderr for tests
+By default, gradle doesn't report any of the output or error streams produced by tests. You can enable output by setting the following:
+
+```bash
+gradle test -Ptest_output=1
+```
### Installer packaging with *install4j*
import jalview.datamodel.SequenceFeature
import jalview.gui.Desktop
-def af = jalview.bin.Jalview.currentAlignFrame
+def af = Jalview.getCurrentAlignFrame()
def av = af.viewport
def fr = Desktop.getAlignFrameFor(av.codingComplement).getFeatureRenderer()
def counts = 0
}
af.getFeatureRenderer().featuresAdded()
af.alignPanel.paintAlignment(true, true)
-println "Added " + countm + " missense and " + counts + " synonymous variants"
\ No newline at end of file
+println "Added " + countm + " missense and " + counts + " synonymous variants"
import jalview.gui.*;
import jalview.io.*;
-def class JvLoadTest {
+class JvLoadTest {
FileLoader fl = null;
def String safename = null;
JvLoadTest(String sname) {
System.gc();
jalview.gui.Desktop.instance.desktop.showMemoryUsage(true);
return new JvLoadTest(tempFile)
-}
\ No newline at end of file
+}
void printSimilarityMatrix(boolean selview=false, boolean includeids=true, SimilarityParams pidMethod) {
- def currentAlignFrame = jalview.bin.Jalview.getCurrentAlignFrame()
+ def currentAlignFrame = Jalview.getCurrentAlignFrame()
jalview.gui.AlignViewport av = currentAlignFrame.getCurrentView()
print "\n"
}
-}
\ No newline at end of file
+}
*/
// run an alignment on the current alignFrame
import jalview.ws.jws2.*;
+import jalview.ws.jws2.jabaws2.Jws2Instance;
import jalview.datamodel.*;
// First get the JABA service discoverer and see if there are any services.
disc.run();
}
-for (jalview.ws.jws2.Jws2Discoverer.Jws2Instance service: disc.getServices()) {
+for (jalview.ws.jws2.jabaws2.Jws2Instance service: disc.getServices()) {
if (service.serviceType.indexOf("uscle")>-1) {
// now - go through the services if any, and find a Muscle service
import static java.awt.Toolkit.*
-def curviewport = Jalview.getAlignFrames()[Jalview.getAlignFrames().length-1].getViewport();
+def curviewport = Jalview.getCurrentAlignFrame().getViewport();
// TSV output by default.
// change "\t" to "," to output CSV file
/*
* 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
+ * 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
+ *
+ * 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.gui.AlignFrame;
import jalview.gui.AlignViewport;
-def af = Jalview.getAlignFrames();
-def al = af[0].viewport.alignment;
+def al = Jalview.getCurrentAlignFrame().viewport.alignment;
ParseProperties pp = new ParseProperties(al);
-pp.getScoresFromDescription("Score", "ScanPS Raw Score", "([-0-9.+]+)");
+pp.getScoresFromDescription("Score", "ScanPS Raw Score", "([-0-9.+]+)", true);
def sqs = al.getSequenceAt(0);
def annots = sqs.getAnnotation();
/*
* 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
+ * 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
+ *
+ * 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.
*/
// do something groovy in jalview
println "Hello World.\n"
-println "First sequence is " + currentAlFrame.viewport.alignment.getSequenceAt(0).getDisplayId(true)
+println "First sequence is " + Jalview.getCurrentAlignFrame().viewport.alignment.getSequenceAt(0).getDisplayId(true)
def alf = Jalview.getAlignFrames()
for (ala in alf)
{
- // ala is an jalview.gui.AlignFrame object
+ // ala is an jalview.gui.AlignFrame object
println ala.getTitle()
// get the parent jalview.datamodel.Alignment from the alignment viewport
def alignment = ala.viewport.alignment
// get the first sequence from the jalview.datamodel.Alignment object
- def seq = alignment.getSequenceAt(0)
+ def seq = alignment.getSequenceAt(0)
}
Jalview.quit()
import jalview.gui.AlignFrame;
import jalview.gui.AlignViewport;
import java.util.BitSet;
-import javax.swing.JOptionPane;
+import jalview.gui.JvOptionPane;
import groovy.swing.SwingBuilder;
def toselect = getFeatureInput(); // change this to select the desired feature type
cs.addElement(i);
}
ala.viewport.setColumnSelection(cs);
- ala.alignPanel.paintAlignment(true);
+ ala.alignPanel.paintAlignment(true, true);
ala.statusBar.setText("Marked "+bs.cardinality()+" columns containing features of type "+toselect)
} else {
ala.statusBar.setText("No features of type "+toselect+" found.");
null, 'Select columns by feature by type','Enter type of feature', JvOptionPane.OK_OPTION)
return response
- }
\ No newline at end of file
+ }
import java.awt.datatransfer.StringSelection
import static java.awt.Toolkit.*
-def curviewport = Jalview.getAlignFrames()[Jalview.getAlignFrames().length-1].getViewport()
+def curviewport = Jalview.getCurrentAlignFrame().getViewport()
def debug = false
for (ala in af)
{
- def al = ala.viewport.alignment;
+ def al = ala.getViewport().getAlignment();
if (al!=null)
{
SequenceI[] seqs = al.getSequencesArray();
}
}
}
+ ala.repaint();
}
-
\ No newline at end of file
+
/*
* 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
+ * 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
+ *
+ * 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.bin.Jalview
import jalview.workers.FeatureSetCounterI
import jalview.workers.AlignmentAnnotationFactory
/*
* Demonstration of FeatureSetCounterI
- * compute annotation tracks counting number of displayed
+ * compute annotation tracks counting number of displayed
* features of each type in each column
*/
/*
* discover features on the current view
*/
-
-def featuresDisp=Jalview.currentAlignFrame.currentView.featuresDisplayed
+
+def featuresDisp=Jalview.getCurrentAlignFrame().currentView.featuresDisplayed
if (featuresDisp == null) {
print 'Need at least one feature visible on alignment'
}
assert 'java.util.ArrayList' == visibleFeatures.class.name
/*
- * A closure that returns an array of features present
+ * A closure that returns an array of features present
* for each feature type in visibleFeatures
- * Argument 'features' will be a list of SequenceFeature
+ * Argument 'features' will be a list of SequenceFeature
*/
-def getCounts =
- { features ->
+def getCounts =
+ { features ->
int[] obs = new int[visibleFeatures.size]
for (sf in features)
{
* or sf.getValue(attributeName) for GFF 'column 9' properties
*/
int pos = 0
- for (type in visibleFeatures)
+ for (type in visibleFeatures)
{
- if (type.equals(sf.type))
+ if (type.equals(sf.type))
{
obs[pos]++
}
}
obs
}
-
+
/*
* Define something that counts each visible feature type
*/
def columnSetCounter =
[
- getNames: { visibleFeatures as String[] },
+ getNames: { visibleFeatures as String[] },
getDescriptions: { visibleFeatures as String[] },
getMinColour: { [0, 255, 255] as int[] }, // cyan
getMaxColour: { [0, 0, 255] as int[] }, // blue
- count:
- { res, feats ->
- getCounts.call(feats)
+ count:
+ { res, feats ->
+ getCounts.call(feats)
}
] as FeatureSetCounterI
-1.8.3-1.3.0_FJVL
+1.8.3-1.3.1_FJVL
-1.8.3-1.3.0_JVL
+1.8.3-1.3.1_JVL
<parent>
<groupId>com.threerings.getdown</groupId>
<artifactId>getdown</artifactId>
- <version>1.8.3-1.3.0_FJVL</version>
+ <version>1.8.3-1.3.1_FJVL</version>
</parent>
<artifactId>getdown-ant</artifactId>
<parent>
<groupId>com.threerings.getdown</groupId>
<artifactId>getdown</artifactId>
- <version>1.8.3-1.3.0_FJVL</version>
+ <version>1.8.3-1.3.1_FJVL</version>
</parent>
<artifactId>getdown-core</artifactId>
String query = jalviewUri.getQuery();
_appargs.clear();
- _appargs.add("-open");
if (host != null && host.length() > 0) {
URL newUrl = new URL(
(https?"https":"http")
}
if (ext != null && LOCATOR_FILE_EXTENSION.equals(ext.toLowerCase(Locale.ROOT))) {
// this file extension should have been dealt with in Getdown class
- } else {
- _appargs.add(0, "-open");
}
}
<parent>
<groupId>com.threerings.getdown</groupId>
<artifactId>getdown</artifactId>
- <version>1.8.3-1.3.0_FJVL</version>
+ <version>1.8.3-1.3.1_FJVL</version>
</parent>
<artifactId>getdown-launcher</artifactId>
if [ x$JVLVERSION != x ]; then
export VERSION=$JVLVERSION
else
- export VERSION=1.8.3-1.3.0_JVL
+ export VERSION=1.8.3-1.3.1_JVL
fi
if [ x${VERSION%_JVL} = x$VERSION ]; then
<groupId>com.threerings.getdown</groupId>
<artifactId>getdown</artifactId>
<packaging>pom</packaging>
- <version>1.8.3-1.3.0_FJVL</version>
+ <version>1.8.3-1.3.1_FJVL</version>
<name>getdown</name>
<description>An application installer and updater.</description>
testng_groups = Functional
testng_excluded_groups =
+test_output =
+
j8libDir = j8lib
j11libDir = j11lib
<p>
In addition to the definition of groups and sequence features,
- Jalview can display symbols and graphs under the columns of an
+ Jalview can display symbols, line graphs, histograms and heatmaps under the columns of an
alignment. These annotation tracks are displayed in the annotation
area below the alignment. The annotation area's visibility is
controlled with the <strong>View→Show Annotation</strong>
<ul>
<li><a name="seqannots"><strong>Sequence
associated annotation.</strong></a><br />Data displayed on sequence
- annotation rows are associated with the positions of a sequence.
+ associated annotation rows are associated with the positions of a sequence.
Often this is 'Reference annotation' such as secondary structure
information derived from 3D structure data, or from the results of
sequence based prediction of <a href="../webServices/jnet.html">secondary
structure</a> and <a href="../webServices/proteinDisorder.html">disorder</a>.
- If reference annotation is available for a the currently selected
- sequences, it can be shown by selecting the <strong>Add
+ If reference annotations are available for a particular sequence or the current selections, they can be shown by selecting the <strong>Add
Reference Annotation</strong> option in the sequence or selection popup
- menu.</li>
+ menu.<br/>Jalview currently supports the following sources of sequence associated annotation:<ul><li>Protein and RNA Secondary Structure<br/>These can be obtained from JPred and RNAAliFold secondary structure prediction services, and also for imported 3D Structure data.</li><li>Temperature factor, Model Quality or AlphaFold Reliability</br>Jalview extracts and displays values from the 'Temperature Factor' column of PDB and mmCIF files, interpreted in various ways. For regular PDB files, these are imported directly as 'Temperature Factor', but for structures from computational methods such as EBI-AlphaFold, these values are interpreted and shown as 'AlphaFold Reliability' or 'Model Quality' according to the source.</li><li><a href="paematrices.html">Predicted Alignment Error</a> heatmaps<br/>These are displayed for models retrieved from EBI-AlphaFold or when a supported JSON format PAE file is provided when importing a <a href="structurechooser.html#loadpdbfile">local 3D structure file</a>.</li></ul></li>
<li><strong>Group associated annotation.</strong><br />Data can
be associated with groups defined on the alignment. If sequence
groups are defined, <a href="../calculations/conservation.html">Conservation</a>
alignment</a>. Annotations can also be used to <a
href="../features/columnFilterByAnnotation.html">select or
hide columns</a> via the dialog opened from the <strong>Selection</strong>
- menu.
+ menu. You can also colour, select or hide columns of the alignment using any displayed annotation row by right-clicking its label and selecting the option from the displayed pop-up menu.
</p>
<p>
+ <strong>Adjusting the height of histograms, line graphs and heatmaps</strong><br/>The height of line graphs, bar charts and <a href="paematrices.html">predicted alignment error (PAE) matrix heatmaps</a> can be adjusted simply by click-dragging them up or down to increase or decrease the height. Hold down <em><strong>SHIFT</strong></em> to adjust the height of all instances of a particular type of annotation row.</p>
+ <p>
<strong>Sequence Highlighting and Selection from Annotation</strong>
</p>
<p>
(Mac CMD) double-click</strong> will toggle inclusion of associated
sequences in the selection.
<p>
+ <strong>Selecting, analysing and exploring heatmap annotation</strong>
+ </p><p>Mouseovers on heap annotation tracks result in a tooltip displaying information about the range of values under the mouse, and their associated row and column in the heatmap.<br/>For <a href="paematrices.html">Predicted Alignment Error (PAE) matrices</a>, the only form of heatmap annotation currently supported by Jalview, both the vertical and horizontal positions in the heatmap correspond to positions in linked 3D structures and the associated sequence in the alignment - so clicking any position in a heatmap will select columns in the alignment corresponding to the selected row(s) and column under the mouse.
+ <ul>
+ <li>Rows and columns in the heatmap corresponding to currently selected columns in the alignment are shown as red horizontal and vertical bands.</li>
+ <li><em>Rectangular Selections</em> can be created by pressing <em>CMD (or Window/Meta key)</em> whilst click-dragging across an area of the annotation.</li>
+ <li><em>Data driven selections</em> - e.g. selecting regions of low values of Predicted Alignment Error in a heatmap can be dome by pressing <em>CTRL</em> whilst clicking a region of an alignment.</li>
+ </ul>
+ Heatmap annotations can also be clustered, enabling columns of the alignment to be grouped based on similarity of the sets of values in the heatmap. <em>Double clicking</em> a region of a clustered heatmap annotation will select both the row and columns of the alignment grouped by the clustering. See <a href="paematrices.html#clustering">clustering PAE matrices</a> for more information.
+ <p>
<strong>Interactive Alignment Annotation</strong>
</p>
<p>
in 2.5)</em><br> <em>Selecting this toggles whether column
labels will be shrunk to fit within each column, or displayed
using the view's standard font size.</em></li>
+ <li><strong></strong><em>(introduced in 2.11.3)</em><br/><em></em></li>
+ <li><strong></strong><em>(introduced in 2.11.3)</em><br/><em></em></li>
+ <li><strong></strong><em>(introduced in 2.11.3)</em><br/><em></em></li>
+ <li><strong></strong><em>(introduced in 2.11.3)</em><br/><em></em></li>
+ <li><strong></strong><em>(introduced in 2.11.3)</em><br/><em></em></li>
+ <li><strong></strong><em>(introduced in 2.11.3)</em><br/><em></em></li>
+
</ul>
<p>
<strong>Editing labels and secondary structure annotation
</tr>
<tr valign="top">
+ <td><code>‑‑javaconsole / ‑‑nojavaconsole</code></td>
+ <td>Show (/ or don't show) the Java Console. Using one of these overrides any saved Preference.</td>
+ </tr>
+
+ <tr valign="top">
<td><code>‑‑questionnaire / ‑‑noquestionnaire</code></td>
<td>Show (/ or don't show) the questionnaire if one is available.</td>
</tr>
* The Jalview Authors are detailed in the 'AUTHORS' file.
-->
<head>
-<title>Groovy Shell</title>
+<title>Groovy Console</title>
</head>
<body>
<p>
- <strong>The Groovy Shell</strong>
+ <strong>The Groovy Console</strong>
</p>
<p>
Groovy (<a href="http://www.groovy-lang.org/">www.groovy-lang.org</a>)
short pause, you should then see the <a
href="https://groovy-lang.org/groovyconsole.html">Groovy
Console</a> appear. This allows you to interactively execute Groovy
- scripts whilst Jalview is running. We've also provided a <strong>Calculations→Execute
- Groovy Script</strong> button so you can execute the currently loaded
+ scripts whilst Jalview is running. We've also provided a <strong>Calculations→Run
+ Groovy Console Script</strong> button so you can execute the currently loaded
groovy script whilst viewing an alignment.
</p>
<p>
we recommend you also take a look at Jalview's source, since all the
public methods of the jalview class hierarchy can be called from
Groovy scripts. In addition, the following objects are also defined:
+ </p>
-
-
<ul>
- <li><strong>Jalview</strong> - this is bound to <code>jalview.bin.Jalview</code>.<br />Useful
- methods include:
+ <li><strong>Jalview</strong> - this is bound to <code>jalview.bin.groovy.JalviewObject</code> providing access to the following useful
+ methods:
<ul>
<li>Jalview.getAlignFrames() - returns a list of
jalview.gui.AlignFrame objects</li>
<li>Jalview.getCurrentAlignFrame() - returns the alignment
- window which is currently being looked at by the user</li>
+ window which has most recently been in focus. If you change focus to another alignment window then re-running <code>Jalview.getCurrentAlignFrame()</code> will return the new <code>AlignFrame</code>.</li>
</ul></li>
- <li><strong>currentAlFrame</strong> - this is only defined when
- running a Groovy script via the --groovy command line argument. It
- returns the first alignment window created after acting on the
- other arguments passed on the command line.</li>
+ <li><strong>currentAlFrame</strong> When used on the command line this refers to the current opened alignment.
+ <br/>
+ When used from the Groovy Console, it refers to the alignment that was in focus when the Groovy Console was opened.
+ <br/>
+ When a Groovy Console script is run from <em>Calculate</em>-><em>Run Groovy Console Script</em>, <code>currentAlFrame</code> us updated to that alignment.</li>
</ul>
<p>
+ If you specify a <code>--groovy</code> argument before an <code>--open</code> argument
+ then you should ensure your script doesn't refer to <code>currentAlFrame</code>.
+ <p>
+
+ <p>
<em>A simple script</em><br />
<ul>
<li>Getting the title, alignment and first sequence from the
current alignFrame<br> <pre>
-def alf = Jalview.getAlignFrames();
-print alf[0].getTitle();
-def alignment = alf[0].viewport.alignment;
+def al = Jalview.getCurrentAlignFrame();
+print al.getTitle();
+def alignment = al.viewport.alignment;
def seq = alignment.getSequenceAt(0);
</pre>
</li>
href="https://alphafold.ebi.ac.uk/entry/O04090">O04090 3D model</a>
at EBI-AlphaFoldDB).
</p>
- <div style="display:flex; flex-wrap:wrap;"align="center" width="100%">
- <figure><img src="../structures/epas1_annotdetail.png" height="300"/><figcaption>Alignment of EPAS1 homologs from Human, Rat and Cow, with predicted alignment error shown in Jalview</figcaption></figure>
- <figure><img src="../structures/epas1_pae_ebiaf.png" height="300"/><figcaption>Predicted Alignment Error Matrix<br/>from <a href="https://alphafold.ebi.ac.uk/entry/Q99814">https://alphafold.ebi.ac.uk/entry/Q99814</a></figcaption></figure>
+ <div style="display: flex; flex-wrap: wrap;" align="center"
+ width="100%">
+ <figure>
+ <img src="../structures/epas1_annotdetail.png" height="300" />
+ <figcaption>
+ Alignment of EPAS1 homologs from Human, Rat and Cow<br />with
+ predicted alignment error shown for Human
+ </figcaption>
+ </figure>
+ <figure>
+ <img src="../structures/epas1_pae_ebiaf.png" height="300" />
+ <figcaption>
+ Predicted Alignment Error for Human EPAS1<br />from <a
+ href="https://alphafold.ebi.ac.uk/entry/Q99814">https://alphafold.ebi.ac.uk/entry/Q99814</a>
+ </figcaption>
+ </figure>
</div>
<p>
<strong>Importing PAE Matrices</strong>
href="../features/structurechooser.html">Jalview's structure
chooser</a> GUI. If you have produced your own models and accompanying
PAE matrices using a pipeline such as ColabFold, then you can load
- them both together via the
- <a href="../features/structurechooser.html#loadpdbfile">Load PDB
- File</a> dropdown menu in the 3D structure chooser, providing it is
- in a
+ them both together via the <a
+ href="../features/structurechooser.html#loadpdbfile">Load PDB
+ File</a> dropdown menu in the 3D structure chooser, providing it is in a
<a href="../io/paematrixformat.html">supported PAE format</a>.
</p>
<p>
sequences and locate the option in the Selection submenu. You can do
this in any alignment window (or view) where a sequence with
associated PAE data appears.</p>
- <p></p>
+ <p>
+ <strong>Adjusting the height of PAE matrix annotations</strong>
+ </p>
+ <p>
+ PAE annotations behave in the same way as Jalview's line graph and
+ histogram tracks. Click+dragging up and down with the left (select)
+ mouse button held down will increase or decrease the height of the
+ annotation. You can also hold down <strong><em>SHIFT</em></strong>
+ whilst doing this to adjust the height of all PAE rows at once.
+ </p>
+ <p>PAE matrix annotation rows behave like any other sequence
+ associated annotation, with the following additional features:</p>
+ <ul>
+ <li>The vertical axis of the PAE heatmap is mapped to positions
+ on the linked 3D structure.
+ <ul>
+ <li>Mousing over the matrix shows a tooltip giving information
+ on the range of values under the mouse.<br />Positions in the
+ associated 3D structure are also highlighted in any linked views.
+ </li>
+ <li>Clicking on positions in the matrix selects columns of the
+ alignment corresponding to the row and column in the matrix.</li>
+ </ul>
+ </li>
+ <li>Rectangular selections (created by Cmd (or Alt)+Click
+ dragging on the matrix) can be created to select multiple ranges of
+ columns at once.</li>
+ <li>Columns corresponding to adjacent regions with similarly low
+ levels of predicted alignment error can be selected by Ctrl+Clicking
+ on a region in the matrix.</li>
+ <li>Columns of an alignment showing a PAE matrix can be grouped
+ and selected by clustering the matrix.</li>
+ </ul>
+ <p>
+ <strong><a name="clustering">Clustering PAE Matrices</a></strong>
+ </p>
+ <p>PAE matrices are useful for identifying regions of 3D structure
+ predictions that are likely to be positioned in space in the same or
+ similar way as shown in the predicted structure data. Regions of low
+ PAE often correlate with high alphafold reliability (PLDDT) scores,
+ but also complement them since they highlight well-folded regions such
+ as domains, and how well those regions have been predicted to be
+ positioned relative to eachother, which is important when evaluating
+ whether domain-domain interactions or other contacts can be trusted.</p>
+ <p>To make it more easy to identify regions of low PAE, Jalview can
+ cluster the PAE matrix, allowing columns of the matrix to be grouped
+ according to their similarity, using an Average Distance (UPGMA) tree
+ algorithm and the sum of differences between each column's PAE values.</p>
+ <p>
+ <strong><em>dist<sub>ij</sub></em> = ∥ <em><u>p</u><sub>i</sub>-<u>p</u><sub>j</sub></em>
+ ∥</strong>
+ </p>
+ <p>
+ To create a PAE matrix tree, right click on a PAE annotation's label
+ to open the annotation popup menu, and select <strong><em>Cluster
+ Matrix</em></strong>. Once the calculation has finished, a tree viewer will open,
+ and columns of the matrix are then partitioned into groups such that
+ the third left-most node from the root is placed in its own group.
+ Colours are randomly assigned to each group, and by default these will
+ also be overlaid on the matrix annotation row.
+ <p>
+ <ul>
+ <li>The PAE matrix tree viewer behaves like other tree views in
+ Jalview, except selecting nodes or groups of nodes in the tree select
+ columns in the alignment rather than sequences, and clicking adjust
+ the matrix's partition.</li>
+ <li>Only one tree and clustering can be defined for a PAE matrix,
+ regardless of whether it is displayed in different views or
+ alignments.</li>
+ <li>Double clicking on a position in the PAE annotation where a
+ clustering has been defined will select both the row and column
+ clusters for the clicked position. This makes it easy to select
+ clusters corresponding to pairs of interacting regions.</li>
+ <li>Cluster colours for a PAE matrix can be used to colour
+ sequences or columns of the alignment via the <strong><em><a
+ href="../colourSchemes/annotationColouring.html">Colour by
+ Annotation.. dialog</a></em></strong>
+ (opened by right-clicking the annotation label
+ and selecting from the popup menu).
+ </li>
+ </ul>
+ <p>
+ <strong>PAE matrices and Jalview Projects</strong>
+ </p>
+ <p>Any PAE matrices imported to Jalview are saved along side any
+ trees and clustering defined on them in Jalview Projects.</p>
<p>
<em>Support for visualision and analysis of predicted alignment
error matrices was added in Jalview 2.11.3. </em>
</p>
<p>The search box is displayed by pressing Control and F or
selecting "Find..." from the "Search" menu.</p>
- <img src="search.png" width="400" height="152">
+ <img src="search.png" height="152">
<p>"Find next" will find the next occurrence of the
query and adjust the alignment window view to show it, and
"Find all" highlights all matches for a query. The
<ul>
<li>The search uses regular expressions. (understands a mixture
of posix and perl style regex - see below for a summary)</li>
- <li>Gaps are ignored when matching the query to the sequences
- in the alignment.</li>
- <li>Hidden columns can optionally be ignored (<em>since Jalview 2.11</em>)</li>
- <li>The search is applied to both sequences and their IDs. It can
- optionally also be applied to the description string (<em>since Jalview
- 2.10</em>), and sequence feature descriptions (<em>since Jalview 2.11.2.5</em>).
- </li>
- <li>If a region is selected, then search will <strong>only</strong>
+ <li>If a region is selected, then search will <strong>only</strong>
be performed on that region.<br />
<em>Tip: to quickly clear the current selection, click the
alignment view you wish to search, then press 'Escape'.</em>
</li>
+ <li>Gaps are ignored when matching the query to the sequences
+ in the alignment.</li>
+ <li>Hidden columns can optionally be ignored (<em>since Jalview 2.11</em>)</li>
+ <li>The search is applied to both sequences and their IDs. <br />
+ Check boxes also enable searching of:
+ <ul>
+ <li><strong>Sequence description</strong> (<em>since Jalview 2.10</em>)
+ </li>
+ <li><strong>Sequence Feature</strong> type and description for currently displayed features (<em>since Jalview
+ 2.11.3.0</em>)
+ </li>
+ </ul>
+ </li>
<li>Tick the "Match Case" box to perform a case
sensitive search.</li>
<li>To access a <a href="#queryhistory">previously used
<strong>Copying highlighted regions to a new alignment</strong>
</p>
<p>
- You can copy the currently highlighted matching regions of sequences to the clipboard with alt-Command-C.
+ Press <strong>Copy</strong> button or type Ctrl (Cmd on OSX) + Shift +
+ C to copy highlighted search results to the clipboard, enabling them
+ to be pasted to a new alignment (via Shift+Ctrl (or Cmd) + V).
</p>
- <p>
+ <p>
<strong>A quick Regular Expression Guide</strong>
</p>
<strong>Structure Viewers in the Jalview Desktop</strong><br /> The
<a href="jmol.html">Jmol viewer</a> has been included since Jalview
2.3. Jalview 2.8.2 included support for <a href="chimera.html">Chimera</a>,
- provided it is installed and can be launched by Jalview. ChimeraX and PyMOL
+ provided it is installed and can be launched by Jalview. ChimeraX and <a href="pymol.html">PyMOL</a>
support is included from Jalview 2.11.2. The default
viewer can be configured in the <a href="preferences.html#structure">Structure
tab</a> in the <strong>Tools→Preferences</strong> dialog box.
un-tick the <strong>Superpose Structures</strong> checkbox.
</p>
- <p>
- <em>Superposing structures</em><br/>Jalview superposes structures using
- the visible portions of any associated sequence alignments. A
- message in the structure viewer's status bar will be shown if not
- enough aligned columns were available to perform a superposition.
- </p>
- <p>
- See the <a href="jmol.html">Jmol
- </a> and <a href="chimera.html">Chimera</a> help pages for
- more information about their capabilities.</p>
-
-
- <p>
+ <p>
+ <em>Superposing structures</em><br />Jalview superposes structures
+ using the currently selected columns (if more than 3 columns are
+ selected), or the visible portions of any associated sequence
+ alignments. Depending on the viewer, Root Mean Squared Deviation (RMS
+ or RMSD) for each pair of superpositions may be output in the
+ structure viewer's console.
+ </p>
+ <p>A message in the structure viewer's status bar will be shown if
+ not enough aligned columns were available to perform a superposition.
+ </p>
+ <p>
+ See the <a href="jmol.html">Jmol</a>, <a href="chimera.html">Chimera/X</a>
+ and <a href="pymol.html">Pymol</a> help pages for more information
+ about their individual capabilities.
+ </p>
+ <p>
<strong>Retrieving sequences from the PDB</strong><br>You can
retrieve sequences from the PDB using the <a
href="pdbsequencefetcher.html">Sequence Fetcher</a>. The sequences
<li>Copy and paste it into the groovy script console</li>
<li>Load the example Feredoxin project (the one that opens by
default when you first launched Jalview)</li>
- <li>Select <strong>Calculations→Execute Groovy
+ <li>Select <strong>Calculations→Run Groovy Console
Script</strong> from the alignment window's menu bar to run the script on
the current view.
</li>
highly variable regions.</em></li>
<li>
+ </li>
<li><strong>Copy Consensus Sequence</strong><br>
Copies the consensus sequence to the clipboard in Fasta
format, to allow the consensus sequence to be added to an
---
version: 2.11.3.0
-date: 2023-07-19
+date: 2023-10-03
channel: "release"
---
## New Features
- <!-- JAL-4064 --> Native M1 build for macOS using Adoptium JRE 11 macos-aarch64
-- <!-- JAL-4054 --> Installers built with install4j10
-- <!-- JAL-3676 --> Allow log level configuration via Jalview's Java Console, and a Copy to Clipboard button
-- <!-- JAL-3416 --> FlatLAF default look and feel on Linux, OSX and everywhere else
-
+- <!-- JAL-3416 --> Jalview now uses a standard 'look and feel' (FlatLaf) on Linux, OSX and everywhere else
- <!-- JAL-4019 --> Ambiguous Base Colourscheme
- <!-- JAL-4061 --> Find can search sequence features' type and description
- <!-- JAL-4062 --> Hold down Shift + CMD/CTRL C to copy highlighted regions as new sequences
-- <!-- JAL-1556 --> Quickly enable select and/or colour by for displayed annotation row via its popup menu
+- <!-- JAL-1556 --> Quickly enable select and/or colour by for displayed annotation row via annotation panel popup menu
- <!-- JAL-4094 --> Shift+Click+Drag to adjust height of all annotation tracks of same type
- <!-- JAL-4190 --> Pressing escape in tree panel clears any current selection
-
- <!-- JAL-4089 --> Use selected columns for superposition
- <!-- JAL-4086 --> Highlight aligned positions on all associated structures when mousing over a column
-
- <!-- JAL-4221 --> sequence descriptions are updated from database reference sources if not already defined
- <!-- JAL-4273 --> Visible adjuster marks to grab and adjust annotation panel height and id width
- <!-- JAL-4260 --> Adjustable ID margin when alignment is wrapped
-
- <!-- JAL-4274 --> Command line options and configurable bitmap export preferences for height, width and scale factor
### Improved support for working with computationally determined models
-
- <!-- JAL-3895 --> Alphafold red/orange/yellow/green colourscheme for structures
- <!-- JAL-4095 --> Interactive picking of low pAE score regions
- <!-- JAL-4027 --> contact matrix datatype in Jalview
- <!-- JAL-4033 --> Selections with visual feedback via contact matrix annotation
-
- <!-- JAL-3855 --> Discover and import alphafold2 models and metadata from https://alphafold.ebi.ac.uk/
-
- <!-- JAL-4091 --> Visual indication of relationship with associated sequence to distinguish different sequence associated annotation rows
- <!-- JAL-4123 --> GUI and command line allows configuration of how temperature factor in imported 3D structure data should be interpreted
- <!-- JAL-3914 --> Import model reliability scores encoded as temperature factor annotation with their correct name and semantics
- <!-- JAL-4124 --> Store/Restore PAE data and visualisation settings from Jalview Project
- <!-- JAL-4083 --> Multiple residue sidechain highlighting in structure viewers from PAE mouseovers
-
### Jalview on the command line
-
- <!-- JAL-4160,JAL-629,JAL-4262,JAL-4265, --> New command line argument framework allowing flexible batch processing, import of structures, pae matrices and other sequence associated data, and alignment and structure figure generation.
+- <!-- JAL-3830 --> Command-line wrapper script for macOS bundle, linux and Windows installations (bash, powershell and .bat wrappers)
- <!-- JAL-4121 --> Assume --headless when jalview is run with a command line argument that generates output
- <!-- JAL-244 --> Automatically adjust Left margin on import to avoid cropping of annotation labels & sequence IDs
- <!-- JAL-901 --> Specify alignment title on import via --title argument
+- <!-- JAL-4195,JAL-4194,JAL-4193 --> sensible responses from the CLI when things go wrong during image export
+- Add a command line option to set Jalview properties for this session only
+- Add a command line option to suppress opening the startup file for this session
### Other improvements
-
-
- <!-- JAL-4250 --> Secondary structure annotation glyphs are rendered anti-aliasing when enabled
- <!-- JAL-325 --> Helix and Sheet glyphs vertically centered with respect to grey coil secondary structure annotation track
- <!-- JAL-4253 --> Lower line of the sequence group border does not align with vertical and background residue box
- <!-- JAL-3119 --> Name of alignment and view included in overview window's title
- <!-- JAL-4213 --> "add reference annotation" add all positions in reference annotation tracks, not just positions in the currently highlighted columns/selection range
- <!-- JAL-4119 --> EMBL-EBI SIFTS file downloads now use split directories
-
-- <!-- JAL-4195,JAL-4194,JAL-4193 --> sensible responses from the CLI when things go wrong during image export
-Add a command line option to set Jalview properties for this session only
-Add a command line option to suppress opening the startup file for this session
-
-
-JAL-4187 Powershell launcher script fails when given no arguments with the old ArgsParser
-
-known issue ? <!-- JAL-4127 --> 'Reload' for a jalview project results in all windows being duplicated
-
-
-- <!-- JAL-3830 --> Command-line wrapper script for macOS bundle, linux and Windows installations (bash, powershell and .bat wrappers)
- <!-- JAL-3820 --> In Linux desktops' task-managers, the grouped Jalview windows get a generic name
- <!-- JAL-4206 --> Improved file chooser's 'recent files' view and added filter for 'All known alignment files'
- <!-- JAL-4206 --> Relative files added to recent files list via import from command line are selected when Jalview opened from same location
-
-
-
-## Still in progress (delete on release)
-
-- <!-- JAL-2382 --> Import and display sequence-associated contact predictions in CASP-RR format
-- <!-- JAL-2349 --> Contact prediction visualisation
-- <!-- JAL-2348 --> modularise annotation renderer
+- <!-- JAL-3676 --> Allow log level configuration via Jalview's Java Console, and a Copy to Clipboard button
### Development and Deployment
-
+- <!-- JAL-4054 --> Installers built with install4j10
- <!-- JAL-4167 --> Create separate gradle test task for some tests
- <!-- JAL-4212 --> Prevent gradle test on macOS continuously grabbing focus
- <!-- JAL-4111 --> Allow gradle build to create suffixed DEVELOP-... builds with channel appbase
- <!-- JAL-4243 --> Jalview bio.tools description maintained under jalview's git repo and bundled with source release
-
## Issues Resolved
- <!-- JAL-2961 --> Jmol view not always centred on structures when multiple structures are viewed
- <!-- JAL-3776 --> Cancelling interactive calculation leaves empty progress bar.
- <!-- JAL-4189 --> macOS Dock and KDE taskbar names Jalview icon "java" when running
- <!-- JAL-2910 --> HeadlessException in console in headless mode (actually fixed in 2.11.{0,1,2))
-
## New Known defects
+- <!-- JAL-4303 --> EBI-AlphaFold PLDDT colours cannot be overlaid on alignment via 'Colour by annotation' unless the alignment's colourscheme has been set to 'None' via the Colours menu.
+- <!-- JAL-4302 --> Tree renderer doesn't show bottom-most leaves of tree when Fit-To-Window is enabled.
- <!-- JAL-4178 --> Cannot cancel structure view open action once it has been started via the structure chooser dialog
- <!-- JAL-4142 --> Example project's multiple views do not open in distinct locations when eXpand views is used to show them all separately
+- <!-- JAL-4127 --> 'Reload' for a jalview project results in all windows being duplicated
- <!-- JAL-4165 --> Missing last letter when copying consensus sequence from alignment if first column is hidden
- <!-- JAL-4261 --> Last sequence ID in alignment not shown and annotation labels are misaligned in HTML export
- <!-- JAL-3024 --> Files opened via command line with a relative path are added as relative paths to Recent files list (since 2.0.x)
-The 2.11.3 Jalview release features a new and more powerful command line interface, support for in-depth exploration of predicted alignment error (PAE) matrices from AlphaFold in the context of multiple alignments, AlphaFold's standard Blue-Orange-Red confidence colourscheme, and a host of minor improvements and bug fixes.
+The 2.11.3 Jalview release features a new and more powerful command line interface, support for in-depth exploration of predicted alignment error (PAE) matrices from AlphaFold in the context of multiple alignments, AlphaFold's standard Blue-Orange-Red confidence colourscheme, and a host of [minor improvements and bug fixes](releases.html#Jalview.2.11.3.0)
**Interactive exploration of AlphaFold Predicted Alignment Error Matrices**
<strong>Welcome to Jalview Version __VERSION__ (released __DISPLAY_DATE__)!!</strong><br/>
</p>
__WHATS_NEW__
- <p>
- The 2.11.2 release series provides support for two popular 3D
- structure visualisation tools, new features for discovery of 3D
- structures, improved platform integration and a new command line
- tool allowing Jalview to be more easily called from scripts.</p>
-
- <p>
- <strong>View predicted protein structures via 3D-Beacons</strong> <br>
- Jalview 2.11.2's <a href="features/structurechooser.html">Structure
- Chooser includes a client for the 3D-Beacons Network</a>. Launched in
- 2021, the 3D-Beacons network (<a
- href="https://www.ebi.ac.uk/pdbe/pdbe-kb/3dbeacons/">www.ebi.ac.uk/pdbe/pdbe-kb/3dbeacons/</a>)
- provides a central point for the retrieval of predicted and observed
- 3D structures for sequences in Uniprot, including homology models
- from Swiss-model and deep learning based predictions from the EBI's
- Alphafold database (Orengo et al. 2020, <a
- href="https://doi.org/10.12688/f1000research.20559.1">doi:10.12688/f1000research.20559.1</a>).<br>
- </p>
-
- <p>
- <strong>Support for viewing structures with ChimeraX and
- Pymol</strong><br> Jalview's 3D structure viewer system has been
- re-architected to allow easier integration of external structure
- viewers, and takes advantage of the strucViz2 Chimera communications
- library developed by Scooter Morris (<a
- href="https://doi.org/10.1093/bioinformatics/btm329">doi:10.1093/bioinformatics/btm329</a>).<br /> <br />
- The <a href="features/preferences.html#structure">Structures
- Preferences tab</a> provides new options allowing ChimeraX and
- Pymol to be used for visualising external 3D structures. Views
- from all structure viewers are saved in Jalview Projects, allowing
- them to be shared with others using Jalview 2.11.2 or later,
- providing they have the same viewer installed and configured to be
- used with Jalview.<br/><br/>Jalview
- 2.11.2 has been tested with <strong>Pymol 2.5.0 (community)</strong> and <strong>2.5.2
- (incentive)</strong>. For <strong>ChimeraX, we recommend using v1.3 or later</strong>.
- </p>
- <p>Other highlights include:</p>
- <ul>
- <li>Import of annotated DNA and RNA loci via GenBank and EMBL
- style flatfile</li>
- <li><strong>Easier configuration of <a
- href="features/preferences.html#startup">Jalview's memory
- allocation</a></strong></li>
- <li>Scripts for <a href="features/commandline.html">running
- Jalview via the command line</a> on macOS, Linux/Unix and Windows.
- </li>
- </ul>
-
-
- <p>
- For the full details, see <a
- href="releases.html#Jalview.2.11.2">the Jalview 2.11.2 series
- release notes</a>.
- </p>
- <p>
- <strong>Known Issues</strong> <br />The following known issues will
- be addressed in a minor patch release.
-
- <ul>
- <li>Display of RESNUM sequence features are not suppressed when
- structures associated with a sequence are viewed with an external
- viewer (Regression from 2.11.1 series)</li>
- </ul>
- <p></p>
</body>
</html>
status.cancelled_image_export_operation = Cancelled {0} export operation
info.error_creating_file = Error creating {0} file
exception.outofmemory_loading_mmcif_file = Out of memory loading mmCIF File
-label.run_groovy = Run Groovy console script
-label.run_groovy_tip = Run the script in the Groovy console over this alignment
+label.run_groovy = Run Groovy Console Script
+label.run_groovy_tip = Run the script in the Groovy Console over this alignment
label.couldnt_run_groovy_script = Failed to run Groovy script
label.uniprot_sequence_fetcher = UniProt Sequence Fetcher
action.next_page= >>
if ((nd.left() == null) && (nd.right() == null))
{
+ // TODO FIX FOR COLUMN TREES
jalview.bin.Console.outPrintln("Leaf = " + ((SequenceI) nd.element()).getName());
jalview.bin.Console.outPrintln("Dist " + nd.dist);
jalview.bin.Console.outPrintln("Boot " + nd.getBootstrap());
if ((nd.left() == null) && (nd.right() == null))
{
- nd.height = ((BinaryNode) nd.parent()).height + nd.dist;
+ nd.height = nd.parent().height + nd.dist;
if (nd.height > maxheight)
{
{
if (nd.parent() != null)
{
- nd.height = ((BinaryNode) nd.parent()).height + nd.dist;
+ nd.height = nd.parent().height + nd.dist;
}
else
{
import javax.swing.UIManager;
import jalview.analytics.Plausible;
+import jalview.bin.argparser.Arg;
+import jalview.bin.argparser.ArgParser;
import jalview.datamodel.PDBEntry;
import jalview.gui.Preferences;
import jalview.gui.UserDefinedColours;
}
if (file == null || !file.exists())
{
+ if (file != null)
+ {
+ jalview.bin.Console
+ .errPrintln("Could not load bootstrap preferences file '"
+ + file.getPath() + "'");
+ }
String channelPrefsFilename = ChannelProperties
.getProperty("preferences.filename");
String propertiesFilename = System.getProperty("user.home")
+ File.separatorChar + channelPrefsFilename;
+ jalview.bin.Console.errPrintln(
+ "Using default properties file '" + propertiesFilename + "'");
file = new File(propertiesFilename);
}
if (file == null || !file.exists())
+
{
String releasePrefsFilename = fallbackPropertiesFile;
String releasePropertiesFilename = System.getProperty("user.home")
+ File.separatorChar + releasePrefsFilename;
+ jalview.bin.Console.errPrintln("Falling back to properties file '"
+ + releasePropertiesFilename + "'");
file = new File(releasePropertiesFilename);
}
- if (filename == null)
- return null;
if (!file.exists())
{
jalview.bin.Console
.errPrintln("Could not load bootstrap preferences file '"
- + filename + "'");
+ + file.getPath() + "'");
return null;
}
{
return key == null ? null : sessionProperties.get(key);
}
+
+ public static boolean getArgCacheDefault(Arg a, String pref, boolean def)
+ {
+ ArgParser ap = Jalview.getInstance().getArgParser();
+ return ap.isSet(a) ? ap.getBoolean(a) : getDefault(pref, def);
+ }
}
// RESTORE SESSION AFTER EXPORT IF NEED BE
if (sessionToRestore != null)
{
- Console.debug("Restoring session from "
- + sessionToRestore);
-
- sview.getBinding().restoreSession(sessionToRestore.getAbsolutePath());
+ Console.debug(
+ "Restoring session from " + sessionToRestore);
+
+ sview.getBinding().restoreSession(
+ sessionToRestore.getAbsolutePath());
}
} catch (ImageOutputException ioexec)
continue;
} finally
{
- try {
+ try
+ {
this.colourAlignFrame(af, originalColourScheme);
} catch (Exception t)
{
- addError("Unexpected error when restoring colourscheme to alignment after temporary change for export.",t);
+ addError(
+ "Unexpected error when restoring colourscheme to alignment after temporary change for export.",
+ t);
}
}
}
ArgValuesMap avm = argParser.getLinkedArgs(id);
AlignFrame af = afMap.get(id);
- if (af == null)
+ if (avm != null && !avm.containsArg(Arg.GROOVY))
{
- addWarn("Did not have an alignment window for id=" + id);
+ // nothing to do
return;
}
+ if (af == null)
+ {
+ addWarn("Groovy script does not have an alignment window. Proceeding with caution!");
+ }
+
if (avm.containsArg(Arg.GROOVY))
{
- String groovyscript = avm.getValue(Arg.GROOVY);
- if (groovyscript != null)
+ for (ArgValue groovyAv : avm.getArgValueList(Arg.GROOVY))
{
- // Execute the groovy script after we've done all the rendering stuff
- // and before any images or figures are generated.
- Console.info("Executing script " + groovyscript);
- Jalview.getInstance().executeGroovyScript(groovyscript, af);
+ String groovyscript = groovyAv.getValue();
+ if (groovyscript != null)
+ {
+ // Execute the groovy script after we've done all the rendering stuff
+ // and before any images or figures are generated.
+ Console.info("Executing script " + groovyscript);
+ Jalview.getInstance().executeGroovyScript(groovyscript, af);
+ }
}
}
}
ArgValuesMap avm = argParser.getLinkedArgs(id);
AlignFrame af = afMap.get(id);
+ if (avm != null && !avm.containsArg(Arg.IMAGE))
+ {
+ // nothing to do
+ return true;
+ }
+
if (af == null)
{
- addWarn("Did not have an alignment window for id=" + id);
+ addWarn("Do not have an alignment window to create image from (id="
+ + id + "). Not proceeding.");
return false;
}
ArgValuesMap avm = argParser.getLinkedArgs(id);
AlignFrame af = afMap.get(id);
+ if (avm != null && !avm.containsArg(Arg.OUTPUT))
+ {
+ // nothing to do
+ return true;
+ }
+
if (af == null)
{
- addWarn("Did not have an alignment window for id=" + id);
+ addWarn("Do not have an alignment window (id=" + id
+ + "). Not proceeding.");
return false;
}
package jalview.bin;
import java.io.PrintStream;
-import java.util.Locale;
import jalview.log.JLogger;
-import jalview.log.JLoggerI;
import jalview.log.JLoggerI.LogLevel;
import jalview.log.JLoggerLog4j;
import jalview.util.ChannelProperties;
{
JLogger.LogLevel logLevel = JLogger.LogLevel.INFO;
- if (JLogger.isLevel(providedLogLevel))
+ if (providedLogLevel != null && JLogger.isLevel(providedLogLevel))
{
logLevel = Console.getLogLevel(providedLogLevel);
}
public static void setLogLevel(String logLevelString)
{
- for (LogLevel logLevel : JLoggerI.LogLevel.values())
+ LogLevel l = null;
+ try
+ {
+ l = LogLevel.valueOf(logLevelString);
+ } catch (IllegalArgumentException | NullPointerException e1)
+ {
+ Console.debug("Invalid log level '" + logLevelString + "'");
+ return;
+ }
+ if (l != null)
{
- if (logLevel.toString().toLowerCase(Locale.ROOT)
- .equals(logLevelString.toLowerCase(Locale.ROOT)))
+ log.setLevel(l);
+ if (!Platform.isJS())
{
- log.setLevel(logLevel);
- if (!Platform.isJS())
- {
- Log4j.init(logLevel);
- }
- JLoggerLog4j.getLogger("org.apache.axis", logLevel);
- break;
+ Log4j.init(l);
}
+ JLoggerLog4j.getLogger("org.apache.axis", l);
}
}
import jalview.bin.argparser.Arg.Type;
import jalview.bin.argparser.ArgParser;
import jalview.bin.argparser.BootstrapArgs;
+import jalview.bin.groovy.JalviewObject;
+import jalview.bin.groovy.JalviewObjectI;
import jalview.ext.so.SequenceOntology;
import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
* @author $author$
* @version $Revision$
*/
-public class Jalview
+public class Jalview implements JalviewObjectI
{
static
{
protected Commands cmds;
- public static AlignFrame currentAlignFrame;
+ public AlignFrame currentAlignFrame = null;
private ArgParser argparser = null;
}
else if (bootstrapArgs.contains(Arg.DEBUG))
{
- logLevel = "DEBUG";
+ logLevel = bootstrapArgs.getBoolean(Arg.DEBUG) ? "DEBUG" : "INFO";
}
if (logLevel == null && !(bootstrapProperties == null))
{
try
{
Console.initLogger();
- } catch (
-
- NoClassDefFoundError error)
+ } catch (NoClassDefFoundError error)
{
error.printStackTrace();
String message = "\nEssential logging libraries not found."
+ "\nUse: java -classpath \"$PATH_TO_LIB$/*:$PATH_TO_CLASSES$\" jalview.bin.Jalview";
- Jalview.exit(message, ExitCode.OK);
+ Jalview.exit(message, ExitCode.NO_LOGGING);
}
desktop = null;
PromptUserConfig prompter = new PromptUserConfig(Desktop.desktop,
"USAGESTATS",
MessageManager.getString("prompt.analytics_title"),
- MessageManager.getString("prompt.analytics"),
- new Runnable()
+ MessageManager.getString("prompt.analytics"), new Runnable()
{
@Override
public void run()
}
try
{
+ JalviewObjectI j = new JalviewObject(this);
Map<String, java.lang.Object> vbinding = new HashMap<>();
- vbinding.put("Jalview", this);
- if (af != null)
- {
- vbinding.put("currentAlFrame", af);
- }
+ vbinding.put(JalviewObjectI.jalviewObjectName, j);
+ vbinding.put(JalviewObjectI.currentAlFrameName,
+ af != null ? af : getCurrentAlignFrame());
Binding gbinding = new Binding(vbinding);
GroovyScriptEngine gse = new GroovyScriptEngine(new URL[] { sfile });
gse.run(sfile.toString(), gbinding);
.errPrintln("Exception Whilst trying to execute file " + sfile
+ " as a groovy script.");
e.printStackTrace(System.err);
-
}
}
return false;
}
+ @Override
public AlignFrame[] getAlignFrames()
{
return desktop == null ? new AlignFrame[] { getCurrentAlignFrame() }
- : Desktop.getAlignFrames();
-
+ : Desktop.getDesktopAlignFrames();
}
/**
* jalview.bin.Jalview.quit() will just run the non-GUI shutdownHook and exit
*/
+ @Override
public void quit()
{
// System.exit will run the shutdownHook first
Jalview.exit("Quitting now. Bye!", ExitCode.OK);
}
- public static AlignFrame getCurrentAlignFrame()
+ @Override
+ public AlignFrame getCurrentAlignFrame()
{
- return Jalview.currentAlignFrame;
+ return currentAlignFrame;
}
- public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
+ public void setCurrentAlignFrame(AlignFrame af)
{
- Jalview.currentAlignFrame = currentAlignFrame;
+ this.currentAlignFrame = af;
}
public Commands getCommands()
// only add new ones to the end of the list (to preserve ordinal values)
OK, FILE_NOT_FOUND, FILE_NOT_READABLE, NO_FILES, INVALID_FORMAT,
INVALID_ARGUMENT, INVALID_VALUE, MIXED_CLI_ARGUMENTS,
- ERROR_RUNNING_COMMANDS;
+ ERROR_RUNNING_COMMANDS, NO_LOGGING, GROOVY_ERROR;
}
/******************************
j.getArgParser().getMixedExamples());
String quit = MessageManager.getString("action.quit");
- Desktop.instance.nonBlockingDialog(title, warning, quit,
- JvOptionPane.WARNING_MESSAGE, false, true);
+ Desktop.instance.nonBlockingDialog(title, warning, null, quit,
+ JvOptionPane.WARNING_MESSAGE, false, false, true, 30000);
Jalview.exit(
"Exiting due to mixed old and new command line arguments.",
{
String cont = MessageManager.getString("label.continue");
- Desktop.instance.nonBlockingDialog(32, 2, title, warning, url, cont,
- JvOptionPane.WARNING_MESSAGE, false, true, true);
+ Desktop.instance.nonBlockingDialog(title, warning, url, cont,
+ JvOptionPane.WARNING_MESSAGE, false, true, true, 30000);
}
}
if (j.getCommands() != null && j.getCommands().getErrors().size() > 0)
Math.max(message.length(), Math.min(60, shortest)),
Math.min(errors.size(), 20), title, message,
j.getCommands().errorsToString(), ok,
- JvOptionPane.WARNING_MESSAGE, true, false, true);
+ JvOptionPane.WARNING_MESSAGE, true, false, true, -1);
}
}
}
QUESTIONNAIRE(Type.CONFIG,
"Show (or don't show) the questionnaire if one is available.",
true, Opt.BOOLEAN, Opt.BOOTSTRAP),
+ JAVACONSOLE(Type.CONFIG, "Show (or don't show) the Java Console.", false,
+ Opt.BOOLEAN, Opt.BOOTSTRAP),
NOUSAGESTATS(Type.CONFIG, "Don't send initial launch usage stats.",
Opt.UNARY, Opt.BOOTSTRAP),
NOSTARTUPFILE(Type.CONFIG, "Don't show the default startup file.",
}
if (bsa != null)
+ {
this.bootstrapArgs = bsa;
+ }
else
+ {
this.bootstrapArgs = BootstrapArgs.getBootstrapArgs(args);
+ }
parse(args, initsubstitutions, allowPrivate);
}
}
}
}
+
+ // if in an argfile, remove it from the hashset so it can be re-used in
+ // another argfile
+ if (inArgFile != null)
+ {
+ argFiles.remove(inArgFile);
+ }
}
public boolean contains(Arg a)
--- /dev/null
+package jalview.bin.groovy;
+
+import jalview.bin.Jalview.ExitCode;
+import jalview.gui.AlignFrame;
+
+public class JalviewObject implements JalviewObjectI
+{
+ private JalviewObjectI object = null;
+
+ public JalviewObject(JalviewObjectI j)
+ {
+ this.object = j;
+ }
+
+ @Override
+ public AlignFrame[] getAlignFrames()
+ {
+ return object == null ? null : object.getAlignFrames();
+ }
+
+ @Override
+ public AlignFrame getCurrentAlignFrame()
+ {
+ return object == null ? null : object.getCurrentAlignFrame();
+ }
+
+ @Override
+ public void quit()
+ {
+ if (object != null)
+ {
+ object.quit();
+ }
+ else
+ {
+ jalview.bin.Jalview.exit(
+ "Groovy console quit without Jalview object.",
+ ExitCode.GROOVY_ERROR);
+ }
+ }
+
+}
--- /dev/null
+package jalview.bin.groovy;
+
+import jalview.gui.AlignFrame;
+
+public interface JalviewObjectI
+{
+ public AlignFrame[] getAlignFrames();
+
+ public AlignFrame getCurrentAlignFrame();
+
+ public final static String currentAlFrameName = "currentAlFrame";
+
+ public final static String jalviewObjectName = "Jalview";
+
+ public void quit();
+}
/**
* Returns a read-only view of the (possibly empty) list of selected columns
+ * (base 1)
* <p>
- * The list contains no duplicates but is not necessarily ordered. It also may
- * include columns hidden from the current view. To modify (for example sort)
- * the list, you should first make a copy.
+ * The list contains no duplicates but is not necessarily ordered. Columns are
+ * reported in alignment coordinates (base 1), so may also include columns
+ * hidden from the current view. To modify (for example sort) the list, you
+ * should first make a copy.
* <p>
* The list is not thread-safe: iterating over it could result in
* ConcurrentModificationException if it is modified by another thread.
* @return
*/
boolean contains(SequenceI seq, int start, int end);
+
+ /**
+ *
+ * @param seq
+ * @param from - first position to highlight
+ * @param to - last position to highlight (assumed higher than from)
+ * @return true iff from-to intersects or marks positions either side of start/end
+ */
+ boolean adjacent(SequenceI seq, int from, int to);
}
\ No newline at end of file
{
private int count;
- private List<SearchResultMatchI> matches = new ArrayList<>();
+ private ArrayList<SearchResultMatchI> matches = new ArrayList<>();
/**
* One match consists of a sequence reference, start and end positions.
* Discontiguous ranges in a sequence require two or more Match objects.
*/
- public class Match implements SearchResultMatchI
+ public class Match implements SearchResultMatchI, Comparable<SearchResultMatchI>
{
final SequenceI sequence;
{
return (sequence == seq && start <= from && end >= to);
}
+ @Override
+ public boolean adjacent(SequenceI seq, int from, int to)
+ {
+ return (sequence == seq && ((start <= from && end >= to) || (from<=(end+1) && to >=(end+1)) || (from<=(start-1) && to>=(start-1))));
+ }
+
+ @Override
+ public int compareTo(SearchResultMatchI o)
+ {
+ if (start<o.getStart())
+ {
+ return -1;
+ }
+ if (start > o.getStart())
+ {
+ return +1;
+ }
+ if (end < o.getEnd())
+ {
+ return -1;
+ }
+ if (end > o.getEnd())
+ {
+ return +1;
+ }
+ if (sequence!=o.getSequence())
+ {
+ int hashc =sequence.hashCode(),oseq=o.getSequence().hashCode();
+ return (hashc < oseq) ? -1 : 1;
+ }
+ return 0;
+ }
+
}
@Override
count = beforeCount + 1;
}
}
+
@Override
+ public boolean appendResult(SequenceI sequence, int start, int end)
+ {
+
+ Match m = new Match(sequence, start, end);
+
+ boolean appending=false;
+
+ // we dynamically maintain an interval to add as we test each range in the list
+
+ int cstart=start,cend=end;
+ List<SearchResultMatchI> toRemove=new ArrayList<>();
+ for (SearchResultMatchI thatm:matches)
+ {
+ if (thatm.getSequence()==sequence)
+ {
+ if (thatm.contains(sequence,cstart,cend))
+ {
+ // found a match containing the current range. nothing else to do except report if we operated on the list
+ return appending;
+ }
+ if (thatm.adjacent(sequence, cstart, cend))
+ {
+ // update the match to add with the adjacent start/end
+ start = Math.min(m.start, thatm.getStart());
+ end = Math.max(m.end, thatm.getEnd());
+ // and check if we keep or remove the old one
+ if (thatm.getStart()!=start || thatm.getEnd()!=end)
+ {
+ toRemove.add(thatm);
+ count--;
+ cstart = start;
+ cend = end;
+ appending=true;
+ } else {
+ return false;
+ }
+ }
+ }
+ }
+ matches.removeAll(toRemove);
+ {
+ matches.add(new Match(sequence,cstart,cend));
+ count++;
+ }
+ return appending;
+ }
+ @Override
public boolean involvesSequence(SequenceI sequence)
{
final int start = sequence.getStart();
}
return seqs;
}
+
}
*/
void addResult(SequenceI seq, int[] positions);
+
+ /**
+ * Adds the given start/end region to this search result. If sequence already
+ * has a search result and the range is adjacent to already highlighted
+ * positions, they will be merged
+ *
+ * @param sequence
+ * @param start
+ * @param end
+ * @return true if an existing range was updated with this one
+ */
+ boolean appendResult(SequenceI sequence, int start, int end);
+
/**
* adds all match results in the argument to this set
*
{
if (atoms != null)
{
- boolean useScriptWait = atoms.size() > 1;
if (resetLastRes.length() > 0)
{
- jmolScript(resetLastRes.toString(), useScriptWait);
+ jmolScript(resetLastRes.toString());
resetLastRes.setLength(0);
}
+ StringBuilder highlightCommands=null;
for (AtomSpec atom : atoms)
{
- highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(),
- atom.getChain(), atom.getPdbFile(), useScriptWait);
+ StringBuilder thisAtom = highlightAtom(atom.getAtomIndex(), atom.getPdbResNum(),
+ atom.getChain(), atom.getPdbFile());
+ if (thisAtom!=null) {
+ if (highlightCommands==null)
+ {
+ highlightCommands=thisAtom;
+ } else {
+ highlightCommands.append(thisAtom);
+ }
+ }
+ }
+ if (highlightCommands!=null)
+ {
+ jmolHistory(false);
+ jmolScript(highlightCommands.toString());
+ jmolHistory(true);
}
// Highlight distances between atoms with a 'measure' command - not yet
// working
}
// jmol/ssm only
- public void highlightAtom(int atomIndex, int pdbResNum, String chain,
- String pdbfile, boolean useScriptWait)
+ private StringBuilder highlightAtom(int atomIndex, int pdbResNum, String chain,
+ String pdbfile)
{
String modelId = getModelIdForFile(pdbfile);
if (modelId.isEmpty())
{
- return;
+ return null;
}
- jmolHistory(false, useScriptWait);
-
StringBuilder selection = new StringBuilder(32);
StringBuilder cmd = new StringBuilder(64);
selection.append("select ").append(String.valueOf(pdbResNum));
resetLastRes.append(selection).append(";wireframe 0;").append(selection)
.append(" and not hetero; spacefill 0;");
- jmolScript(cmd.toString(), useScriptWait);
- jmolHistory(true, useScriptWait);
+ return cmd;
}
private boolean debug = true;
import jalview.bin.Cache;
import jalview.bin.Console;
import jalview.bin.Jalview;
+import jalview.bin.groovy.JalviewObjectI;
import jalview.commands.CommandI;
import jalview.commands.EditCommand;
import jalview.commands.EditCommand.Action;
@Override
public void focusGained(FocusEvent e)
{
- Jalview.setCurrentAlignFrame(AlignFrame.this);
+ Jalview.getInstance().setCurrentAlignFrame(AlignFrame.this);
}
});
@Override
protected void runGroovy_actionPerformed()
{
- Jalview.setCurrentAlignFrame(this);
- groovy.ui.Console console = Desktop.getGroovyConsole();
+ Jalview.getInstance().setCurrentAlignFrame(this);
+ groovy.console.ui.Console console = Desktop.getGroovyConsole();
if (console != null)
{
try
{
+ console.setVariable(JalviewObjectI.currentAlFrameName, this);
console.runScript();
} catch (Exception ex)
{
*/
protected boolean noReferencesTo(AlignedCodonFrame acf)
{
- AlignFrame[] frames = Desktop.getAlignFrames();
+ AlignFrame[] frames = Desktop.getDesktopAlignFrames();
if (frames == null)
{
return true;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import javax.swing.text.DefaultCaret;
private JComboBox<LogLevel> logLevelCombo = new JComboBox<LogLevel>();
- protected LogLevel startingLogLevel = LogLevel.INFO;
+ protected LogLevel startingLogLevel = null;
public Console()
{
scrollPane.setBorder(noBorder);
textArea.addMouseListener(new MouseAdapter()
{
+ @Override
public void mouseClicked(MouseEvent e)
{
if (e.getButton() == MouseEvent.BUTTON1)
MessageManager.getString("label.copy_to_clipboard"));
copyToClipboardButton.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
copyConsoleTextToClipboard();
private Color fg = textArea.getForeground();
+ @Override
public void mousePressed(MouseEvent e)
{
textArea.setBackground(textArea.getSelectionColor());
textArea.setForeground(textArea.getSelectedTextColor());
}
+ @Override
public void mouseReleased(MouseEvent e)
{
textArea.setBackground(bg);
// logLevelCombo.addItem(LogLevel.ERROR);
// logLevelCombo.addItem(LogLevel.OFF);
// set startingLogLevel
- startingLogLevel = jalview.bin.Console.log == null ? LogLevel.INFO
- : jalview.bin.Console.log.getLevel();
+
+ if (jalview.bin.Console.getLogger() == null)
+ {
+ startingLogLevel = jalview.bin.Console.getCachedLogLevel();
+ }
+ else
+ {
+ startingLogLevel = jalview.bin.Console.getLogger().getLevel();
+ }
setChosenLogLevelCombo();
logLevelCombo.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent e)
{
if (jalview.bin.Console.log != null)
boolean added = false;
for (int i = 0; i < logLevelCombo.getItemCount(); i++)
{
- LogLevel l = (LogLevel) logLevelCombo.getItemAt(i);
+ LogLevel l = logLevelCombo.getItemAt(i);
if (l.compareTo(setLogLevel) >= 0)
{
logLevelCombo.insertItemAt(setLogLevel, i);
*/
public Console(Desktop desktop)
{
- this(desktop, true);
- }
-
- /**
- * attach a console to the desktop - the desktop will open it if requested.
- *
- * @param desktop
- * @param showjconsole
- * - if true, then redirect stdout immediately
- */
- public Console(Desktop desktop, boolean showjconsole)
- {
parent = desktop;
// window name - get x,y,width, height possibly scaled
- Rectangle bounds = desktop.getLastKnownDimensions("JAVA_CONSOLE_");
- if (bounds == null)
+ Rectangle bounds = parent == null ? null
+ : parent.getLastKnownDimensions("JAVA_CONSOLE_");
+ if (bounds != null)
{
frame = initFrame(
ChannelProperties.getProperty("app_name") + " Java Console",
- desktop.getWidth() / 2, desktop.getHeight() / 4,
- desktop.getX(), desktop.getY());
+ bounds.width, bounds.height, bounds.x, bounds.y);
+ }
+ else if (parent != null && parent.getWidth() > 0
+ && parent.getHeight() > 0)
+ {
+ frame = initFrame(
+ ChannelProperties.getProperty("app_name") + " Java Console",
+ parent.getWidth() / 2, parent.getHeight() / 4, parent.getX(),
+ parent.getY());
}
else
{
frame = initFrame(
ChannelProperties.getProperty("app_name") + " Java Console",
- bounds.width, bounds.height, bounds.x, bounds.y);
+ MIN_WIDTH, MIN_HEIGHT, 10, 10);
}
frame.setMinimumSize(new Dimension(MIN_WIDTH, MIN_HEIGHT));
- // desktop.add(frame);
+ // parent.add(frame);
initConsole(false);
LogLevel level = (LogLevel) logLevelCombo.getSelectedItem();
if (!Platform.isJS())
pin.close();
} catch (Exception e)
{
+ jalview.bin.Console.debug("pin.close() error", e);
}
try
{
pin2.close();
} catch (Exception e)
{
+ jalview.bin.Console.debug("pin2.close() error", e);
}
try
{
textAppender.join(10);
} catch (Exception e)
{
+ jalview.bin.Console.debug("textAppender.join(10) error", e);
}
}
/*
try
{
this.wait(100);
- if (pin.available() == 0)
- {
- trimBuffer(false);
- }
} catch (InterruptedException ie)
{
+ jalview.bin.Console.debug("pin.available() error", ie);
}
}
{
try
{
- this.wait(100);
+ this.wait(100); // ##### implicated BLOCKED
if (pin2.available() == 0)
{
trimBuffer(false);
}
} catch (InterruptedException ie)
{
+ jalview.bin.Console.debug("pin.available() error", ie);
}
}
while (pin2.available() != 0)
// check string buffer - if greater than console, clear console and
// replace with last segment of content, otherwise, append all to
// content.
- long count;
while (displayPipe.length() > 0)
{
- count = 0;
StringBuffer tmp = new StringBuffer(), replace;
synchronized (displayPipe)
{
replace = displayPipe;
displayPipe = tmp;
}
- // simply append whole buffer
- textArea.append(replace.toString());
- count += replace.length();
- if (count > byteslim)
+ // Append formatted message to textarea using the Swing Thread.
+ SwingUtilities.invokeLater(new Runnable()
{
- trimBuffer(false);
- }
+ public void run()
+ {
+ textArea.append(replace.toString());
+ trimBuffer(false);
+ }
+ });
}
if (displayPipe.length() == 0)
{
this.wait(100);
if (displayPipe.length() == 0)
{
- trimBuffer(false);
+ // post a trim on Swing Thread.
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ trimBuffer(false);
+ }
+ });
}
} catch (InterruptedException e)
{
+ jalview.bin.Console.debug("displayPipe.length() error", e);
}
}
}
this.wait(100);
} catch (InterruptedException e)
{
-
+ jalview.bin.Console.debug("this.wait(100) error", e);
}
}
if (quit)
this.wait(1000);
} catch (InterruptedException ie)
{
+ jalview.bin.Console.debug("this.wait(1000) error", ie);
}
throw new NullPointerException(
MessageManager.getString("exception.application_test_npe"));
@Override
public void run()
{
- displayPipe.append(input); // change to stringBuffer
- // displayPipe.flush();
-
+ displayPipe.append(input);
}
});
// stderr.println("Time taken to Spawnappend:\t" + (System.nanoTime() -
+ "\nTruncated...\n";
} catch (Exception e)
{
- e.printStackTrace();
+ jalview.bin.Console.warn("textArea Exception", e);
}
}
// trim the buffer
}
} catch (Exception e)
{
- e.printStackTrace();
+ jalview.bin.Console.warn("textArea Exception", e);
}
// lines = textArea.getLineCount();
}
import jalview.bin.Cache;
import jalview.bin.Jalview;
import jalview.bin.Jalview.ExitCode;
+import jalview.bin.argparser.Arg;
+import jalview.bin.groovy.JalviewObject;
+import jalview.bin.groovy.JalviewObjectI;
import jalview.datamodel.Alignment;
import jalview.datamodel.HiddenColumns;
import jalview.datamodel.Sequence;
*/
public class Desktop extends jalview.jbgui.GDesktop
implements DropTargetListener, ClipboardOwner, IProgressIndicator,
- jalview.api.StructureSelectionManagerProvider
+ jalview.api.StructureSelectionManagerProvider, JalviewObjectI
{
private static final String CITATION;
static
boolean selmemusage = Cache.getDefault("SHOW_MEMUSAGE", false);
- boolean showjconsole = Cache.getDefault("SHOW_JAVA_CONSOLE", false);
+ boolean showjconsole = Cache.getArgCacheDefault(Arg.JAVACONSOLE,
+ "SHOW_JAVA_CONSOLE", false);
+
+ // start dialogue queue for single dialogues
+ startDialogQueue();
+
+ if (!Platform.isJS())
+ /**
+ * Java only
+ *
+ * @j2sIgnore
+ */
+ {
+ Desktop.instance.acquireDialogQueue();
+
+ jconsole = new Console(this);
+ jconsole.setHeader(Cache.getVersionDetailsForConsole());
+ showConsole(showjconsole);
+
+ Desktop.instance.releaseDialogQueue();
+ }
+
desktop = new MyDesktopPane(selmemusage);
showMemusage.setSelected(selmemusage);
setBounds(xPos, yPos, 900, 650);
}
- // start dialogue queue for single dialogues
- startDialogQueue();
-
if (!Platform.isJS())
/**
* Java only
* @j2sIgnore
*/
{
- jconsole = new Console(this, showjconsole);
- jconsole.setHeader(Cache.getVersionDetailsForConsole());
- showConsole(showjconsole);
-
showNews.setVisible(false);
experimentalFeatures.setSelected(showExperimental());
iw = (int) (iw * sw);
iy = (int) (iy * sh);
ih = (int) (ih * sh);
- while (ix >= screenSize.width)
+ if (ix >= screenSize.width)
{
jalview.bin.Console.debug(
"Window geometry location recall error: shifting horizontal to within screenbounds.");
- ix -= screenSize.width;
+ ix = ix % screenSize.width;
}
- while (iy >= screenSize.height)
+ if (iy >= screenSize.height)
{
jalview.bin.Console.debug(
"Window geometry location recall error: shifting vertical to within screenbounds.");
- iy -= screenSize.height;
+ iy = iy % screenSize.height;
}
jalview.bin.Console.debug(
"Got last known dimensions for " + windowName + ": x:" + ix
{
if (itf instanceof AlignFrame)
{
- Jalview.setCurrentAlignFrame((AlignFrame) itf);
+ Jalview.getInstance().setCurrentAlignFrame((AlignFrame) itf);
}
itf.requestFocus();
}
desktopQuit(true, false);
}
- public QuitHandler.QResponse desktopQuit(boolean ui, boolean disposeFlag)
- {
- final Runnable doDesktopQuit = () -> {
- Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
- Cache.setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
- Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height + "");
- storeLastKnownDimensions("", new Rectangle(getBounds().x,
- getBounds().y, getWidth(), getHeight()));
+ /**
+ * close everything, stash window geometries, and shut down all associated threads/workers
+ * @param dispose - sets the dispose on close flag - JVM may terminate when set
+ * @param terminateJvm - quit with prejudice - stops the JVM.
+ */
+ public void quitTheDesktop(boolean dispose, boolean terminateJvm) {
+ Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
+ Cache.setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
+ Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height + "");
+ storeLastKnownDimensions("", new Rectangle(getBounds().x,
+ getBounds().y, getWidth(), getHeight()));
- if (jconsole != null)
- {
- storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
- jconsole.stopConsole();
- }
+ if (jconsole != null)
+ {
+ storeLastKnownDimensions("JAVA_CONSOLE_", jconsole.getBounds());
+ jconsole.stopConsole();
+ }
- if (jvnews != null)
- {
- storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
- }
+ if (jvnews != null)
+ {
+ storeLastKnownDimensions("JALVIEW_RSS_WINDOW_", jvnews.getBounds());
+ }
- // Frames should all close automatically. Keeping external
- // viewers open should already be decided by user.
- closeAll_actionPerformed(null);
+ // Frames should all close automatically. Keeping external
+ // viewers open should already be decided by user.
+ closeAll_actionPerformed(null);
- // check for aborted quit
- if (QuitHandler.quitCancelled())
- {
- jalview.bin.Console.debug("Desktop aborting quit");
- return;
- }
+ if (dialogExecutor != null)
+ {
+ dialogExecutor.shutdownNow();
+ }
- if (dialogExecutor != null)
- {
- dialogExecutor.shutdownNow();
- }
+ if (groovyConsole != null)
+ {
+ // suppress a possible repeat prompt to save script
+ groovyConsole.setDirty(false);
+ groovyConsole.exit();
+ }
- if (groovyConsole != null)
- {
- // suppress a possible repeat prompt to save script
- groovyConsole.setDirty(false);
- groovyConsole.exit();
- }
+ if (terminateJvm)
+ {
+ // note that shutdown hook will not be run
+ jalview.bin.Console.debug("Force Quit selected by user");
+ Runtime.getRuntime().halt(0);
+ }
- if (QuitHandler.gotQuitResponse() == QResponse.FORCE_QUIT)
- {
- // note that shutdown hook will not be run
- jalview.bin.Console.debug("Force Quit selected by user");
- Runtime.getRuntime().halt(0);
- }
+ jalview.bin.Console.debug("Quit selected by user");
+ if (dispose)
+ {
+ instance.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+ // instance.dispose();
+ }
+ }
+ public QuitHandler.QResponse desktopQuit(boolean ui, boolean disposeFlag)
+ {
+ final Runnable doDesktopQuit = () -> {
- jalview.bin.Console.debug("Quit selected by user");
- if (disposeFlag)
+ // FIRST !! check for aborted quit
+ if (QuitHandler.quitCancelled())
{
- instance.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- // instance.dispose();
+ jalview.bin.Console.debug("Quit was cancelled - Desktop aborting quit");
+ return;
}
+
+ // Proceed with quitting
+ quitTheDesktop(disposeFlag, QuitHandler.gotQuitResponse() == QResponse.FORCE_QUIT);
+ // and exit the JVM
instance.quit();
};
}
/**
- * Don't call this directly, use desktopQuit() above. Exits the program.
+ * Exits the program and the JVM.
+ *
+ * Don't call this directly
+ *
+ * - use desktopQuit() above to tidy up first.
+ *
+ * - use closeDesktop() to shutdown Jalview without shutting down the JVM
+ *
*/
@Override
public void quit()
{
}
}
- Jalview.setCurrentAlignFrame(null);
+ Jalview.getInstance().setCurrentAlignFrame(null);
jalview.bin.Console.info("ALL CLOSED");
/*
return null;
}
List<AlignmentPanel> aps = new ArrayList<>();
- AlignFrame[] frames = getAlignFrames();
+ AlignFrame[] frames = Desktop.getDesktopAlignFrames();
if (frames == null)
{
return null;
List<AlignmentViewport> viewp = new ArrayList<>();
if (desktop != null)
{
- AlignFrame[] frames = Desktop.getAlignFrames();
+ AlignFrame[] frames = Desktop.getDesktopAlignFrames();
for (AlignFrame afr : frames)
{
*
* @return an array of AlignFrame, or null if none found
*/
- public static AlignFrame[] getAlignFrames()
+ @Override
+ public AlignFrame[] getAlignFrames()
{
- if (Jalview.isHeadlessMode())
+ if (desktop == null)
{
- // Desktop.desktop is null in headless mode
- return new AlignFrame[] { Jalview.currentAlignFrame };
+ return null;
}
JInternalFrame[] frames = Desktop.desktop.getAllFrames();
}
/**
+ * static version
+ */
+ public static AlignFrame[] getDesktopAlignFrames()
+ {
+ if (Jalview.isHeadlessMode())
+ {
+ // Desktop.desktop is null in headless mode
+ return Jalview.getInstance().getAlignFrames();
+ }
+
+ if (instance != null && desktop != null)
+ {
+ return instance.getAlignFrames();
+ }
+
+ return null;
+ }
+
+ /**
* Returns an array of any AppJmol frames in the Desktop (or null if none).
*
* @return
openGroovyConsole();
} catch (Exception ex)
{
- jalview.bin.Console.error("Groovy Shell Creation failed.", ex);
+ jalview.bin.Console.error("Groovy Console creation failed.", ex);
JvOptionPane.showInternalMessageDialog(Desktop.desktop,
MessageManager.getString("label.couldnt_create_groovy_shell"),
{
if (groovyConsole == null)
{
- groovyConsole = new groovy.ui.Console();
- groovyConsole.setVariable("Jalview", this);
+ JalviewObjectI j = new JalviewObject(this);
+ groovyConsole = new groovy.console.ui.Console();
+ groovyConsole.setVariable(JalviewObjectI.jalviewObjectName, j);
+ groovyConsole.setVariable(JalviewObjectI.currentAlFrameName,
+ getCurrentAlignFrame());
groovyConsole.run();
/*
*/
groovyShell.setEnabled(!enabled);
- AlignFrame[] alignFrames = getAlignFrames();
+ AlignFrame[] alignFrames = getDesktopAlignFrames();
if (alignFrames != null)
{
for (AlignFrame af : alignFrames)
*/
private Semaphore block = new Semaphore(0);
- private static groovy.ui.Console groovyConsole;
+ private static groovy.console.ui.Console groovyConsole;
/**
* add another dialog thread to the queue
myTopFrame.setDisplayedView(myTopFrame.alignPanel);
}
- public static groovy.ui.Console getGroovyConsole()
+ public static groovy.console.ui.Console getGroovyConsole()
{
return groovyConsole;
}
}
/**
- * closes the current instance window, disposes and forgets about it.
+ * closes the current instance window, but leaves the JVM running.
+ * Bypasses any shutdown prompts, but does not set window dispose on close in case JVM terminates.
*/
public static void closeDesktop()
{
if (Desktop.instance != null)
{
- Desktop.instance.closeAll_actionPerformed(null);
- Desktop.instance.setVisible(false);
Desktop us = Desktop.instance;
- Desktop.instance = null;
+ Desktop.instance.quitTheDesktop(false, false);
// call dispose in a separate thread - try to avoid indirect deadlocks
- new Thread(new Runnable()
+ if (us != null)
{
- @Override
- public void run()
+ new Thread(new Runnable()
{
- ExecutorService dex = us.dialogExecutor;
- if (dex != null)
+ @Override
+ public void run()
{
- dex.shutdownNow();
- us.dialogExecutor = null;
- us.block.drainPermits();
+ ExecutorService dex = us.dialogExecutor;
+ if (dex != null)
+ {
+ dex.shutdownNow();
+ us.dialogExecutor = null;
+ us.block.drainPermits();
+ }
+ us.dispose();
}
- us.dispose();
- }
- }).start();
+ }).start();
+ }
}
}
public void nonBlockingDialog(String title, String message, String button,
int type, boolean scrollable, boolean modal)
{
- nonBlockingDialog(32, 2, title, message, null, button, type, scrollable,
- false, modal);
+ nonBlockingDialog(title, message, null, button, type, scrollable, false,
+ modal, -1);
+ }
+
+ public void nonBlockingDialog(String title, String message,
+ String boxtext, String button, int type, boolean scrollable,
+ boolean html, boolean modal, int timeout)
+ {
+ nonBlockingDialog(32, 2, title, message, boxtext, button, type,
+ scrollable, html, modal, timeout);
}
public void nonBlockingDialog(int width, int height, String title,
String message, String boxtext, String button, int type,
- boolean scrollable, boolean html, boolean modal)
+ boolean scrollable, boolean html, boolean modal, int timeout)
{
if (type < 0)
{
jvp.setResponseHandler(JOptionPane.YES_OPTION, () -> {
});
+ jvp.setTimeout(timeout);
+ JButton jb = new JButton(button);
jvp.showDialogOnTopAsync(this, jp, title, JOptionPane.YES_OPTION, type,
null, new Object[]
- { button }, button, modal, null, false);
+ { button }, button, modal, new JButton[] { jb }, false);
}
+ @Override
+ public AlignFrame getCurrentAlignFrame()
+ {
+ return Jalview.getInstance().getCurrentAlignFrame();
+ }
}
private Map<Object, Runnable> callbacks = new HashMap<>();
+ private int timeout = -1;
+
+ public void setTimeout(int i)
+ {
+ timeout = i;
+ }
+
/*
* JalviewJS reports user choice in the dialog as the selected option (text);
* this list allows conversion to index (int)
"Supplied buttons array not the same length as supplied options array.");
break NOTNULL;
}
+
+ // run through buttons for initialValue first so we can set (and start)
+ // a final timeoutThreadF to include (and interrupt) in the button
+ // actions
+ Thread timeoutThread = null;
+ for (int i = 0; i < options.length; i++)
+ {
+ Object o = options[i];
+ JButton jb = buttons[i];
+ if (o.equals(initialValue))
+ {
+ if (timeout > 0 && jb != null && jb instanceof JButton)
+ {
+ // after timeout ms click the default button
+ timeoutThread = new Thread(() -> {
+ try
+ {
+ Thread.sleep(timeout);
+ } catch (InterruptedException e)
+ {
+ Console.debug(
+ "Dialog timeout interrupted. Probably a button pressed.");
+ }
+ jb.doClick();
+ });
+ }
+ initialValueButton = jb;
+ break;
+ }
+ }
+ final Thread timeoutThreadF = timeoutThread;
+ if (timeoutThreadF != null)
+ {
+ timeoutThreadF.start();
+ }
+
int[] buttonActions = { JOptionPane.YES_OPTION,
JOptionPane.NO_OPTION, JOptionPane.CANCEL_OPTION };
for (int i = 0; i < options.length; i++)
"Setting button " + i + " to '" + o.toString() + "'");
JButton jb = buttons[i];
- if (o.equals(initialValue))
- initialValueButton = jb;
-
int buttonAction = buttonActions[i];
Runnable action = callbacks.get(buttonAction);
jb.setText((String) o);
@Override
public void actionPerformed(ActionEvent e)
{
+ if (timeoutThreadF != null)
+ {
+ timeoutThreadF.interrupt();
+ }
Object obj = e.getSource();
if (obj == null || !(obj instanceof Component))
// A better hack which works is to create a new JFrame parent with
// setAlwaysOnTop(true)
+ boolean parentOnTop = dialogParent.isAlwaysOnTop();
dialogParent.setAlwaysOnTop(true);
parentComponent = dialogParent;
JOPTIONPANE_MESSAGETYPE, icon, options, initialValue, modal,
buttons);
+ dialogParent.setAlwaysOnTop(parentOnTop);
+
if (dispose)
{
dialogParent.setAlwaysOnTop(false);
return QResponse.QUIT;
int size = 0;
- AlignFrame[] afArray = Desktop.getAlignFrames();
+ AlignFrame[] afArray = Desktop.getDesktopAlignFrames();
if (!(afArray == null || afArray.length == 0))
{
for (int i = 0; i < afArray.length; i++)
*/
public SplashScreen(boolean isTransient)
{
- Desktop.instance.acquireDialogQueue();
this.transientDialog = isTransient;
+ if (this.transientDialog)
+ {
+ Desktop.instance.acquireDialogQueue();
+ }
if (Platform.isJS()) // BH 2019
{
protected boolean refreshText()
{
String newtext = Desktop.instance.getAboutMessage();
- // jalview.bin.Console.errPrintln("Text found: \n"+newtext+"\nEnd of newtext.");
+ // jalview.bin.Console.errPrintln("Text found: \n"+newtext+"\nEnd of
+ // newtext.");
if (oldTextLength != newtext.length())
{
iframe.setVisible(false);
}
closeSplash();
- Desktop.instance.releaseDialogQueue();
}
/**
*/
public void closeSplash()
{
+ if (this.transientDialog)
+ {
+ Desktop.instance.releaseDialogQueue();
+ }
try
{
- iframe.setClosed(true);
+ iframe.setClosed(true); // ##### implicated BLOCKED
} catch (Exception ex)
{
}
}
int ystart = (node.left() == null ? 0
- : (int) (((BinaryNode) node.left()).ycount * chunk)) + offy;
+ : (int) (node.left().ycount * chunk)) + offy;
int yend = (node.right() == null ? 0
- : (int) (((BinaryNode) node.right()).ycount * chunk)) + offy;
+ : (int) (node.right().ycount * chunk)) + offy;
Rectangle pos = new Rectangle(xend - 2, ypos - 2, 5, 5);
nodeHash.put(node, pos);
if (top.count == 0)
{
- top.count = ((BinaryNode) top.left()).count
- + ((BinaryNode) top.right()).count;
+ top.count = top.left().count
+ + top.right().count;
}
- double chunk = (double) (height - (offy)) / (double)top.count;
+ float chunk = (float) (height - (offy)) / top.count;
drawNode(g2, tree.getTopNode(), chunk, wscale, width, offx, offy);
*/
protected void updateWebServiceMenus()
{
- for (AlignFrame alignFrame : Desktop.getAlignFrames())
+ for (AlignFrame alignFrame : Desktop.getDesktopAlignFrames())
{
alignFrame.BuildWebServiceMenu();
}
{
return this != FILE;
}
+
+ public boolean isUrl()
+ {
+ return this == URL || this == RELATIVE_URL;
+ }
}
// We read the data anyway - it might make sense.
}
// BH 2018 switch to File object here instead of filename
- alignFrame = new Jalview2XML(raiseGUI && !Jalview.isBatchMode()).loadJalviewAlign(
- selectedFile == null ? file : selectedFile);
+ alignFrame = new Jalview2XML(raiseGUI && !Jalview.isBatchMode())
+ .loadJalviewAlign(
+ selectedFile == null ? file : selectedFile);
}
else
{
} catch (Exception er)
{
- jalview.bin.Console.errPrintln("Exception whilst opening file '" + file);
+ jalview.bin.Console
+ .errPrintln("Exception whilst opening file '" + file);
er.printStackTrace();
if (raiseGUI && !Jalview.isBatchMode())
{
}
});
}
- jalview.bin.Console.errPrintln("Out of memory loading file " + file + "!!");
+ jalview.bin.Console
+ .errPrintln("Out of memory loading file " + file + "!!");
}
loadtime += System.currentTimeMillis();
AlignViewport avp = af.getViewport();
if (avp == null)
return;
- avp.setSavedUpToDate(!protocol.isDynamic(),
- QuitHandler.Message.UNSAVED_ALIGNMENTS);
+ boolean upToDate = !protocol.isDynamic();
+ if (protocol.isUrl() && !Cache
+ .getDefault(PROMPT_SAVE_UNCHANGED_URL_ALIGNMENTS, true))
+ {
+ upToDate = true;
+ }
+ avp.setSavedUpToDate(upToDate,
+ upToDate ? null : QuitHandler.Message.UNSAVED_ALIGNMENTS);
}
+ public static final String PROMPT_SAVE_UNCHANGED_URL_ALIGNMENTS = "PROMPT_SAVE_UNCHANGED_URL_ALIGNMENTS";
+
public static boolean getUseDefaultFileFormat()
{
return useDefaultFileFormat;
private void buildSkipList()
{
skipList = new Hashtable();
- AlignFrame[] al = Desktop.getAlignFrames();
+ AlignFrame[] al = Desktop.getDesktopAlignFrames();
for (int f = 0; al != null && f < al.length; f++)
{
skipList.put(al[f].getViewport().getSequenceSetId(), al[f]);
*/
public void saveState(JarOutputStream jout)
{
- AlignFrame[] frames = Desktop.getAlignFrames();
+ AlignFrame[] frames = Desktop.getDesktopAlignFrames();
setStateSavedUpToDate(true);
if (stateSavedUpToDate()) // nothing happened since last project save
return true;
- AlignFrame[] frames = Desktop.getAlignFrames();
+ AlignFrame[] frames = Desktop.getDesktopAlignFrames();
if (frames != null)
{
for (int i = 0; i < frames.length; i++)
int indexpos = sm.getSeqPos(atom.getPdbResNum());
if (lastipos != indexpos || lastseq != sm.sequence)
{
- results.addResult(sm.sequence, indexpos, indexpos);
+ results.appendResult(sm.sequence, indexpos, indexpos);
lastipos = indexpos;
lastseq = sm.sequence;
// construct highlighted sequence list
{
for (int s : cs.getSelected())
{
- if (hiddenCols == null)
- {
matched.set(s);
- }
- else
- {
- matched.set(hiddenCols.visibleToAbsoluteColumn(s));
- }
}
}
else
*/
package jalview.workers;
+import java.awt.Color;
+
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
import jalview.bin.Jalview;
import jalview.datamodel.Annotation;
import jalview.gui.AlignFrame;
-import java.awt.Color;
-
/**
* Factory class with methods which allow clients (including external scripts
* such as Groovy) to 'register and forget' an alignment annotation calculator.
*/
public static void newCalculator(FeatureSetCounterI counter)
{
- AlignmentViewPanel currentAlignFrame = Jalview
+ AlignmentViewPanel currentAlignFrame = Jalview.getInstance()
.getCurrentAlignFrame().alignPanel;
if (currentAlignFrame == null)
{
{
// TODO need an interface for AlignFrame by which to access
// its AlignViewportI and AlignmentViewPanel
- AlignFrame currentAlignFrame = Jalview.getCurrentAlignFrame();
+ AlignFrame currentAlignFrame = Jalview.getInstance()
+ .getCurrentAlignFrame();
if (currentAlignFrame != null)
{
new AnnotationWorker(currentAlignFrame.getViewport(),
}
*/
- @Test(groups = "Functional", dataProvider = "cmdLines")
+ @Test(groups = {"Functional","testTask3"}, dataProvider = "cmdLines")
public void commandsOpenTest(String cmdLine, boolean cmdArgs,
int numFrames, String[] sequences)
{
Assert.assertEquals(cmds.argsWereParsed(), cmdArgs,
"Overall command parse and operation is false");
- Assert.assertEquals(Desktop.getAlignFrames().length, numFrames,
+ Assert.assertEquals(Desktop.getDesktopAlignFrames().length, numFrames,
"Wrong number of AlignFrames");
if (sequences != null)
{
Set<String> openedSequenceNames = new HashSet<>();
- AlignFrame[] afs = Desktop.getAlignFrames();
+ AlignFrame[] afs = Desktop.getDesktopAlignFrames();
for (AlignFrame af : afs)
{
openedSequenceNames.addAll(
@Test(
groups =
- { "Functional", "testTask1" },
+ { "Functional", "testTask3" },
dataProvider = "structureImageOutputFiles")
public void structureImageOutputTest(String cmdLine, String[] filenames)
throws IOException
public static boolean lookForSequenceName(String sequenceName)
{
- AlignFrame[] afs = Desktop.getAlignFrames();
+ AlignFrame[] afs = Desktop.getDesktopAlignFrames();
for (AlignFrame af : afs)
{
for (String name : af.getViewport().getAlignment().getSequenceNames())
}
;
- AlignFrame[] afs = Desktop.getAlignFrames();
+ AlignFrame[] afs = Desktop.getDesktopAlignFrames();
Assert.assertNotNull(afs);
Assert.assertTrue(afs.length > 0);
assertFalse(m.contains(null, 3, 3));
}
+ @Test(groups = { "Functional" })
+ public void testMatchAdjacent()
+ {
+ SequenceI seq1 = new Sequence("", "abcdefghijklm");
+ SequenceI seq2 = new Sequence("", "abcdefghijklm");
+ SearchResultMatchI m = new SearchResults().new Match(seq1, 2, 5);
+
+ assertTrue(m.adjacent(seq1, 2, 5));
+ assertTrue(m.adjacent(seq1, 3, 5));
+ assertTrue(m.adjacent(seq1, 2, 4));
+ assertTrue(m.adjacent(seq1, 3, 3));
+
+ assertTrue(m.adjacent(seq1, 2, 6));
+ assertTrue(m.adjacent(seq1, 1, 5));
+ assertTrue(m.adjacent(seq1, 1, 8));
+ assertFalse(m.adjacent(seq1, 0, 0));
+ assertFalse(m.adjacent(seq1, 7, 8));
+ assertTrue(m.adjacent(seq1, 6, 8));
+ assertTrue(m.adjacent(seq1, 5, 8));
+ assertTrue(m.adjacent(seq1, 0, 1));
+
+
+ assertFalse(m.adjacent(seq2, 3, 3));
+ assertFalse(m.adjacent(null, 3, 3));
+ }
+
/**
* test markColumns for creating column selections
*/
}
/**
+ * Test to verify appending creates a minimal set of results
+ */
+ @Test(groups = { "Functional" })
+ public void testAppendResult()
+ {
+ SequenceI seq1 = new Sequence("", "abcdefghijklm"),seq2=new Sequence("","defdefdefdef");
+ SearchResultsI sr = new SearchResults();
+ sr.appendResult(seq1, 3, 5);
+ assertEquals(1, sr.getCount());
+ sr.appendResult(seq1, 3, 6);
+ assertEquals(1, sr.getCount());
+ sr.appendResult(seq1, 8, 8);
+ assertEquals(2, sr.getCount());
+ sr.appendResult(seq1, 7, 7);
+ assertEquals(1, sr.getCount());
+ sr.appendResult(seq2, 7, 7);
+ assertEquals(2, sr.getCount());
+ sr.appendResult(seq2, 2, 7);
+ assertTrue(sr.appendResult(seq2, 7, 49));
+ assertTrue(sr.appendResult(seq2, 0, 30));
+ assertEquals(2, sr.getCount());
+ int c=0;
+ for (SearchResultMatchI sre: sr.getResults())
+ {
+ c++;
+ }
+ assertEquals(c,2);
+
+ }
+ /**
* Test for method that checks if search results matches a sequence region
*/
@Test(groups = { "Functional" })
{
Assert.fail("Unexpected exception " + x);
}
- AlignFrame[] alfs = Desktop.getAlignFrames();
+ AlignFrame[] alfs = Desktop.getDesktopAlignFrames();
Assert.assertEquals("Expect just 2 alignment frames", 2, alfs.length);
// internal paste should yield a new alignment window with shared dataset
AlignmentI dataset = internalSource.getViewport().getAlignment()
SequenceFetcher sf = new SequenceFetcher(Desktop.instance,
forSource, forAccession);
sf.run();
- AlignFrame[] afs = Desktop.getAlignFrames();
+ AlignFrame[] afs = Desktop.getDesktopAlignFrames();
if (afs.length == 0)
{
failedDBRetr.add("Didn't retrieve " + first);
cacheBox.addItem(testInput);
cacheBox.setSelectedItem(testInput);
cacheBox.updateCache();
-
- try
+ boolean done[]=new boolean[] { false };
+ // this event gets processed after updateCache's update event on the swing
+ // thread
+ SwingUtilities.invokeLater(() -> {
+ done[0]=true;
+ });
+ long t=0;
+ while (!done[0] && t<200)
{
- // fix for JAL-4153
- // This delay is to let cacheBox.updateCache() finish updating the cache
- SwingUtilities.invokeAndWait(() -> {
- try
- {
- Thread.sleep(1);
+ try {
+ Thread.sleep(7);
+ t++;
} catch (InterruptedException e)
{
e.printStackTrace();
}
- });
- } catch (InvocationTargetException | InterruptedException e)
+ }
+ if (!done[0])
{
- e.printStackTrace();
+ Assert.fail("Giving up after 1.4s waiting for cache to be updated.");
}
+
LinkedHashSet<String> foundCache = appCache
.getAllCachedItemsFor(TEST_CACHE_KEY);
Assert.assertTrue(foundCache.contains(testInput));
@Test(groups = { "Functional" })
public void gatherViewsHere() throws Exception
{
- int origCount = Desktop.getAlignFrames() == null ? 0
- : Desktop.getAlignFrames().length;
+ int origCount = Desktop.getDesktopAlignFrames() == null ? 0
+ : Desktop.getDesktopAlignFrames().length;
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/exampleFile_2_7.jar", DataSourceType.FILE);
assertNotNull(af, "Didn't read in the example file correctly.");
- assertTrue(Desktop.getAlignFrames().length == 1 + origCount,
+ assertTrue(Desktop.getDesktopAlignFrames().length == 1 + origCount,
"Didn't gather the views in the example file.");
}
AlignFrame af = new FileLoader().LoadFileWaitTillLoaded(
"examples/exampleFile_2_7.jar", DataSourceType.FILE);
- Assert.assertEquals(Desktop.getAlignFrames().length, 1);
+ Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 1);
String afid = af.getViewport().getSequenceSetId();
// check FileLoader returned a reference to the one alignFrame that is
Desktop.explodeViews(af);
- int oldviews = Desktop.getAlignFrames().length;
- Assert.assertEquals(Desktop.getAlignFrames().length,
+ int oldviews = Desktop.getDesktopAlignFrames().length;
+ Assert.assertEquals(Desktop.getDesktopAlignFrames().length,
Desktop.getAlignmentPanels(afid).length);
File tfile = File.createTempFile("testStoreAndRecoverExpanded", ".jvp");
try
Assert.fail("Didn't save the expanded view state", e);
}
Desktop.instance.closeAll_actionPerformed(null);
- if (Desktop.getAlignFrames() != null)
+ if (Desktop.getDesktopAlignFrames() != null)
{
- Assert.assertEquals(Desktop.getAlignFrames().length, 0);
+ Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
}
af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
DataSourceType.FILE);
Assert.assertNotNull(af);
- Assert.assertEquals(Desktop.getAlignFrames().length,
+ Assert.assertEquals(Desktop.getDesktopAlignFrames().length,
Desktop.getAlignmentPanels(
af.getViewport().getSequenceSetId()).length);
Assert.assertEquals(Desktop
Assert.fail("Didn't save the expanded view state", e);
}
Desktop.instance.closeAll_actionPerformed(null);
- if (Desktop.getAlignFrames() != null)
+ if (Desktop.getDesktopAlignFrames() != null)
{
- Assert.assertEquals(Desktop.getAlignFrames().length, 0);
+ Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
}
af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
Assert.fail("Didn't save the expanded view state", e);
}
Desktop.instance.closeAll_actionPerformed(null);
- if (Desktop.getAlignFrames() != null)
+ if (Desktop.getDesktopAlignFrames() != null)
{
- Assert.assertEquals(Desktop.getAlignFrames().length, 0);
+ Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
}
af = new FileLoader().LoadFileWaitTillLoaded(tfile.getAbsolutePath(),
Assert.fail("Didn't save the state", e);
}
Desktop.instance.closeAll_actionPerformed(null);
- if (Desktop.getAlignFrames() != null)
+ if (Desktop.getDesktopAlignFrames() != null)
{
- Assert.assertEquals(Desktop.getAlignFrames().length, 0);
+ Assert.assertEquals(Desktop.getDesktopAlignFrames().length, 0);
}
AlignFrame restoredFrame = new FileLoader().LoadFileWaitTillLoaded(
assertNotNull(af);
AlignmentI ds = null;
- for (AlignFrame alignFrame : Desktop.getAlignFrames())
+ for (AlignFrame alignFrame : Desktop.getDesktopAlignFrames())
{
if (ds == null)
{
/*
* find the complement frames (ugly)
*/
- AlignFrame[] frames = Desktop.getAlignFrames();
+ AlignFrame[] frames = Desktop.getDesktopAlignFrames();
assertEquals(frames.length, 2);
AlignViewport av1 = frames[0].getViewport();
AlignViewport av2 = frames[1].getViewport();