tmp = getOrderByTree(align, tree);
- // tmp should properly permute align with tree.
- if (lastTree != tree)
- {
- sortTreeAscending = true;
- lastTree = tree;
- }
- else
- {
- sortTreeAscending = !sortTreeAscending;
- }
+ AlignmentSorter as = getInstance();
- if (sortTreeAscending)
+ // tmp should properly permute align with tree.
+ if (as.lastTree != tree)
{
- setOrder(align, tmp);
+ as.sortTreeAscending = true;
+ as.lastTree = tree;
}
else
{
- setReverseOrder(align,
- vectorSubsetToArray(tmp, align.getSequences()));
+ as.sortTreeAscending = !as.sortTreeAscending;
}
+ set(align, tmp, as.sortTreeAscending);
}
/**
@@ -658,9 +516,12 @@ public class AlignmentSorter
}
jalview.util.QuickSort.sort(scores, seqs);
- if (lastSortByAnnotation != scoreLabel)
+
+ AlignmentSorter as = getInstance();
+
+ if (as.lastSortByAnnotation != scoreLabel)
{
- lastSortByAnnotation = scoreLabel;
+ as.lastSortByAnnotation = scoreLabel;
setOrder(alignment, seqs);
}
else
@@ -670,18 +531,6 @@ public class AlignmentSorter
}
/**
- * types of feature ordering: Sort by score : average score - or total score -
- * over all features in region Sort by feature label text: (or if null -
- * feature type text) - numerical or alphabetical Sort by feature density:
- * based on counts - ignoring individual text or scores for each feature
- */
- public static String FEATURE_SCORE = "average_score";
-
- public static String FEATURE_LABEL = "text";
-
- public static String FEATURE_DENSITY = "density";
-
- /**
* Sort sequences by feature score or density, optionally restricted by
* feature types, feature groups, or alignment start/end positions.
*
@@ -708,14 +557,15 @@ public class AlignmentSorter
if (method != FEATURE_SCORE && method != FEATURE_LABEL
&& method != FEATURE_DENSITY)
{
- String msg = String
- .format("Implementation Error - sortByFeature method must be either '%s' or '%s'",
- FEATURE_SCORE, FEATURE_DENSITY);
+ String msg = String.format(
+ "Implementation Error - sortByFeature method must be either '%s' or '%s'",
+ FEATURE_SCORE, FEATURE_DENSITY);
System.err.println(msg);
return;
}
- flipFeatureSortIfUnchanged(method, featureTypes, groups, startCol, endCol);
+ flipFeatureSortIfUnchanged(method, featureTypes, groups, startCol,
+ endCol);
SequenceI[] seqs = alignment.getSequencesArray();
@@ -734,8 +584,8 @@ public class AlignmentSorter
* get sequence residues overlapping column region
* and features for residue positions and specified types
*/
- String[] types = featureTypes == null ? null : featureTypes
- .toArray(new String[featureTypes.size()]);
+ String[] types = featureTypes == null ? null
+ : featureTypes.toArray(new String[featureTypes.size()]);
List sfs = seqs[i].findFeatures(startCol + 1,
endCol + 1, types);
@@ -809,6 +659,8 @@ public class AlignmentSorter
}
}
+ boolean doSort = false;
+
if (FEATURE_SCORE.equals(method))
{
if (hasScores == 0)
@@ -834,7 +686,7 @@ public class AlignmentSorter
}
}
}
- QuickSort.sortByDouble(scores, seqs, sortByFeatureAscending);
+ doSort = true;
}
else if (FEATURE_DENSITY.equals(method))
{
@@ -846,9 +698,13 @@ public class AlignmentSorter
// System.err.println("Sorting on Density: seq "+seqs[i].getName()+
// " Feats: "+featureCount+" Score : "+scores[i]);
}
- QuickSort.sortByDouble(scores, seqs, sortByFeatureAscending);
+ doSort = true;
+ }
+ if (doSort)
+ {
+ QuickSort.sortByDouble(scores, seqs,
+ getInstance().sortByFeatureAscending);
}
-
setOrder(alignment, seqs);
}
@@ -883,16 +739,177 @@ public class AlignmentSorter
/*
* if resorting on the same criteria, toggle sort order
*/
- if (sortByFeatureCriteria == null
- || !scoreCriteria.equals(sortByFeatureCriteria))
+ AlignmentSorter as = getInstance();
+ if (as.sortByFeatureCriteria == null
+ || !scoreCriteria.equals(as.sortByFeatureCriteria))
{
- sortByFeatureAscending = true;
+ as.sortByFeatureAscending = true;
}
else
{
- sortByFeatureAscending = !sortByFeatureAscending;
+ as.sortByFeatureAscending = !as.sortByFeatureAscending;
}
- sortByFeatureCriteria = scoreCriteria;
+ as.sortByFeatureCriteria = scoreCriteria;
+ }
+
+ /**
+ * Set the alignment's sequences list to contain the sequences from a
+ * temporary list, first adding all the elements from the tmp list, then adding all sequences in the alignment that
+ * are not in the list. Option to do the final sort either in order or in reverse order.
+ *
+ * @param align The alignment being sorted
+ * @param tmp
+ * the temporary sequence list
+ * @param ascending
+ * false for reversed order; only sequences already in
+ * the alignment will be used (which is actually already guaranteed
+ * by vectorSubsetToArray)
+ */
+ private static void set(AlignmentI align, List tmp,
+ boolean ascending)
+ {
+ set(align, vectorSubsetToArray(align.getSequences(), tmp), ascending);
+ }
+
+ /**
+ * Set the alignment's sequences list to contain these sequences, either in
+ * this order or its reverse.
+ *
+ * @param align
+ * @param seqs
+ * the new sequence array
+ * @param ascending
+ * false for reversed order; if ascending, only sequences already in
+ * the alignment will be used; if descending, then a direct 1:1
+ * replacement is made
+ */
+ private static void set(AlignmentI align, SequenceI[] seqs,
+ boolean ascending)
+ {
+ if (ascending)
+ {
+ setOrder(align, seqs);
+ }
+ else
+ {
+ setReverseOrder(align, seqs);
+ }
+
+ }
+
+ /**
+ * Replace the alignment's sequences with values in an array, clearing the
+ * alignment's sequence list and filtering for sequences that are actually in
+ * the alignment already.
+ *
+ * @param align
+ * the Alignment
+ * @param seqs
+ * the array of replacement values, of any length
+ */
+ public static void setOrder(AlignmentI align, SequenceI[] seqs)
+ {
+ // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work
+ List seqList = align.getSequences();
+ synchronized (seqList)
+ {
+ List tmp = new ArrayList<>();
+
+ for (int i = 0; i < seqs.length; i++)
+ {
+ if (seqList.contains(seqs[i]))
+ {
+ tmp.add(seqs[i]);
+ }
+ }
+
+ seqList.clear();
+ // User may have hidden seqs, then clicked undo or redo
+ for (int i = 0; i < tmp.size(); i++)
+ {
+ seqList.add(tmp.get(i));
+ }
+ }
+ }
+
+ /**
+ * Replace the alignment's sequences or a subset of those sequences with
+ * values in an array in reverse order. All sequences are replaced; no check
+ * is made that these sequences are in the alignment already.
+ *
+ * @param align
+ * the Alignment
+ * @param seqs
+ * the array of replacement values, length must be less than or equal
+ * to Alignment.sequences.size()
+ */
+ private static void setReverseOrder(AlignmentI align, SequenceI[] seqs)
+ {
+ int nSeq = seqs.length;
+
+ int len = (nSeq + (nSeq % 2)) / 2;
+ // int len = 0;
+ //
+ // if ((nSeq % 2) == 0)
+ // {
+ // len = nSeq / 2;
+ // }
+ // else
+ // {
+ // len = (nSeq + 1) / 2;
+ // }
+
+ // NOTE: DO NOT USE align.setSequenceAt() here - it will NOT work
+ List seqList = align.getSequences();
+ synchronized (seqList)
+ {
+ for (int i = 0; i < len; i++)
+ {
+ // SequenceI tmp = seqs[i];
+ seqList.set(i, seqs[nSeq - i - 1]);
+ seqList.set(nSeq - i - 1, seqs[i]);
+ }
+ }
+ }
+
+ /**
+ * Create and array of reordered sequences in order first from tmp that are
+ * present in seqList already, then, after that, any remaining sequences in
+ * seqList not in tmp. Any sequences in tmp that are not in seqList already
+ * are discarded.
+ *
+ * @param seqList
+ * thread safe collection of sequences originally in the alignment
+ * @param tmp
+ * thread safe collection of sequences or subsequences possibly in
+ * seqList
+ *
+ * @return intersect(tmp,seqList)+intersect(complement(tmp),seqList)
+ */
+ private static SequenceI[] vectorSubsetToArray(List seqList,
+ List tmp)
+ {
+ ArrayList seqs = new ArrayList<>();
+ int n = seqList.size();
+ BitSet bs = new BitSet(n);
+ bs.set(0, n);
+ for (int i = 0, nt = tmp.size(); i < nt; i++)
+ {
+ SequenceI sq = tmp.get(i);
+ int idx = seqList.indexOf(sq);
+ if (idx >= 0 && bs.get(idx))
+ {
+ seqs.add(sq);
+ bs.clear(idx);
+ }
+ }
+
+ for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i + 1))
+ {
+ seqs.add(seqList.get(i));
+ }
+
+ return seqs.toArray(new SequenceI[seqs.size()]);
}
}
diff --git a/src/jalview/analysis/CrossRef.java b/src/jalview/analysis/CrossRef.java
index c54357e..b70e9f7 100644
--- a/src/jalview/analysis/CrossRef.java
+++ b/src/jalview/analysis/CrossRef.java
@@ -31,6 +31,7 @@ import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.util.DBRefUtils;
import jalview.util.MapList;
+import jalview.ws.SequenceFetcher;
import jalview.ws.SequenceFetcherFactory;
import jalview.ws.seqfetcher.ASequenceFetcher;
@@ -402,7 +403,6 @@ public class CrossRef
private void retrieveCrossRef(List sourceRefs, SequenceI seq,
List xrfs, boolean fromDna, AlignedCodonFrame cf)
{
- ASequenceFetcher sftch = SequenceFetcherFactory.getSequenceFetcher();
SequenceI[] retrieved = null;
SequenceI dss = seq.getDatasetSequence() == null ? seq
: seq.getDatasetSequence();
@@ -418,7 +418,7 @@ public class CrossRef
}
try
{
- retrieved = sftch.getSequences(sourceRefs, !fromDna);
+ retrieved = SequenceFetcher.getInstance().getSequences(sourceRefs, !fromDna);
} catch (Exception e)
{
System.err.println(
diff --git a/src/jalview/analysis/scoremodels/ScoreModels.java b/src/jalview/analysis/scoremodels/ScoreModels.java
index ebc9a26..8700ec0 100644
--- a/src/jalview/analysis/scoremodels/ScoreModels.java
+++ b/src/jalview/analysis/scoremodels/ScoreModels.java
@@ -22,6 +22,8 @@ package jalview.analysis.scoremodels;
import jalview.api.AlignmentViewPanel;
import jalview.api.analysis.ScoreModelI;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.io.DataSourceType;
import jalview.io.FileParse;
import jalview.io.ScoreMatrixFile;
@@ -33,18 +35,8 @@ import java.util.Map;
/**
* A class that can register and serve instances of ScoreModelI
*/
-public class ScoreModels
+public class ScoreModels implements ApplicationSingletonI
{
- private final ScoreMatrix BLOSUM62;
-
- private final ScoreMatrix PAM250;
-
- private final ScoreMatrix DNA;
-
- private static ScoreModels instance;
-
- private Map models;
-
/**
* Answers the singleton instance of this class, with lazy initialisation
* (built-in score models are loaded on the first call to this method)
@@ -53,11 +45,7 @@ public class ScoreModels
*/
public static ScoreModels getInstance()
{
- if (instance == null)
- {
- instance = new ScoreModels();
- }
- return instance;
+ return (ScoreModels) ApplicationSingletonProvider.getInstance(ScoreModels.class);
}
/**
@@ -84,6 +72,14 @@ public class ScoreModels
registerScoreModel(new FeatureDistanceModel());
}
+ private final ScoreMatrix BLOSUM62;
+
+ private final ScoreMatrix PAM250;
+
+ private final ScoreMatrix DNA;
+
+ private Map models;
+
/**
* Tries to load a score matrix from the given resource file, and if
* successful, registers it.
@@ -153,7 +149,7 @@ public class ScoreModels
*/
public void reset()
{
- instance = new ScoreModels();
+ ApplicationSingletonProvider.removeInstance(this.getClass());
}
/**
diff --git a/src/jalview/api/JalviewApp.java b/src/jalview/api/JalviewApp.java
deleted file mode 100644
index e488d6e..0000000
--- a/src/jalview/api/JalviewApp.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package jalview.api;
-
-import jalview.datamodel.ColumnSelection;
-import jalview.datamodel.HiddenColumns;
-import jalview.datamodel.PDBEntry;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
-import jalview.io.DataSourceType;
-import jalview.io.NewickFile;
-import jalview.javascript.JSFunctionExec;
-import jalview.javascript.MouseOverStructureListener;
-import jalview.structure.SelectionSource;
-import jalview.structure.VamsasSource;
-
-//import java.applet.AppletContext;
-import java.io.IOException;
-import java.net.URL;
-import java.util.Hashtable;
-import java.util.Vector;
-
-import netscape.javascript.JSObject;
-
-public interface JalviewApp
-{
- public String getParameter(String name);
-
- public boolean getDefaultParameter(String name, boolean def);
-
- public URL getDocumentBase();
-
- public URL getCodeBase();
-
- public void setAlignPdbStructures(boolean defaultParameter);
-
- public void newStructureView(PDBEntry pdb, SequenceI[] seqs,
- String[] chains, DataSourceType protocol);
-
- public void alignedStructureView(PDBEntry[] pdb, SequenceI[][] seqs,
- String[][] chains, String[] protocols);
-
- public void updateForAnnotations();
-
- public AlignViewportI getViewport();
-
- public void setFeatureGroupState(String[] groups, boolean state);
-
- public boolean parseFeaturesFile(String param, DataSourceType protocol);
-
- public void newFeatureSettings();
-
- public boolean loadScoreFile(String sScoreFile) throws IOException;
-
- public void loadTree(NewickFile fin, String treeFile) throws IOException;
-
- public Vector getJsExecQueue(JSFunctionExec jsFunctionExec);
-
-// deprecated public AppletContext getAppletContext();
-
- public boolean isJsfallbackEnabled();
-
- public JSObject getJSObject();
-
- public StructureSelectionManagerProvider getStructureSelectionManagerProvider();
-
- public void updateColoursFromMouseOver(Object source,
- MouseOverStructureListener mouseOverStructureListener);
-
- public Object[] getSelectionForListener(SequenceGroup seqsel, ColumnSelection colsel,
- HiddenColumns hidden, SelectionSource source, Object alignFrame);
-
- public String arrayToSeparatorList(String[] array);
-
- public Hashtable getJSHashes();
-
- Hashtable> getJSMessages();
-
- public Object getFrameForSource(VamsasSource source);
-
- public jalview.renderer.seqfeatures.FeatureRenderer getNewFeatureRenderer(
- AlignViewportI vp);
-
-}
diff --git a/src/jalview/api/JalviewJSApi.java b/src/jalview/api/JalviewJSApi.java
new file mode 100644
index 0000000..895fd15
--- /dev/null
+++ b/src/jalview/api/JalviewJSApi.java
@@ -0,0 +1,412 @@
+package jalview.api;
+
+import java.net.URL;
+
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+
+/**
+ * JAL-3369 JalviewJS API BH 2019.07.17
+ *
+ * @author hansonr
+ *
+ */
+public interface JalviewJSApi
+{
+
+ /**
+ * bind a pdb file to a sequence in the given AlignFrame.
+ *
+ * @param sequenceId
+ * - sequenceId within the dataset or null
+ * @param pdbId
+ * - the four-character PDB ID
+ * @param pdbFile
+ * - pdb file - either a URL or a valid PDB file or null.
+ * @param alFrame
+ * - null or specific AlignFrame. This specifies the dataset that
+ * will be searched for a seuqence called sequenceId
+ *
+ * @return true if binding was success
+ */
+ public boolean addPdbFile(String sequenceId, String pdbId, String pdbFile,
+ AlignFrame alFrame);
+
+ /**
+ * Get alignment as format with or without the jalview start-end sequence
+ * suffix appended.
+ *
+ * @param format
+ * @param addSuffix
+ * (default false)
+ * @param alf
+ * (default current)
+ *
+ * @return
+ */
+ public String getAlignment(String format, boolean addSuffix,
+ AlignFrame alf);
+
+ /**
+ * Get an array of sequence IDs reflecting the order of the alignment in the
+ * specified alignment frame
+ *
+ * @param alf
+ * (default current)
+ * @return array of sequence IDs
+ */
+ public String[] getAlignmentOrder(AlignFrame alf);
+
+ /**
+ * Get alignment view alf's annotation as an annotation file
+ *
+ * @param alf
+ * (default current)
+ * @return annotation
+ */
+ public String getAnnotation(AlignFrame alf);
+
+ /**
+ * Get the URL for the location where the code is found; typically ending in
+ * "swingjs/j2s".
+ *
+ * @return web page URL
+ */
+ public URL getCodeBase();
+
+ AlignFrame getCurrentAlignFrame();
+
+ /**
+ * Get the URL for the hosting web page.
+ *
+ * @return web page URL
+ */
+ public URL getDocumentBase();
+
+ /**
+ * Get the array of feature groups for an alignment frame.
+ *
+ * @param alf
+ * AlignFrame to get feature groups for (default current)
+ * @return
+ */
+ public String[] getFeatureGroups(AlignFrame alf);
+
+ /**
+ * Get the array of feature groups for an alignment frame with a specific
+ * on/off state.
+ *
+ * @param visible
+ * (default off)
+ * @param alf
+ * align frame (default current)
+ *
+ * @return
+ */
+ public String[] getFeatureGroupsOfState(boolean visible, AlignFrame alf);
+
+ /**
+ * Get the sequence features in the alignment frame in the given format
+ * (Jalview or GFF). Two additional options can be added to the format, each
+ * starting with a semicolon:
+ *
+ * ;includeNonpositional (default) or ;positionalOnly
+ *
+ * ;includeComplement
+ *
+ * @param format
+ * case-insensitive "Jalview" or "GFF" (default "GFF")
+ * @param alf
+ * (default current)
+ * @return formatted sequence features
+ */
+ public String getFeatures(String format, AlignFrame alf);
+
+ /**
+ * Get an applet parameter as a string.
+ *
+ * @param name
+ * @return value or null
+ */
+ public String getParameter(String name);
+
+ /**
+ * Get an applet parameter object value.
+ *
+ * @param name
+ * @return value or null
+ */
+ public Object getParameterAsObject(String name);
+
+ /**
+ * @param alf
+ * AlignFrame containing selection
+ * @return String list of selected sequence IDs, each terminated by current
+ * default separator sequence
+ *
+ */
+ public SequenceI[] getSelectedSequences(AlignFrame alf);
+
+ // BH incompatibility here -- JalviewLite created an AlignFrame; Jalview
+ // creates an AlignmentPanel
+ // /**
+ // * create a new view and return the AlignFrame instance
+ // *
+ // * @return
+ // */
+ //
+ // public AlignFrame newView();
+ //
+ // /**
+ // * create a new view named name and return the AlignFrame instance
+ // *
+ // * @param name
+ // * @return
+ // */
+ //
+ // public AlignFrame newView(String name);
+ //
+ // /**
+ // * create a new view on alf and return the AlignFrame instance
+ // *
+ // * @param alf
+ // * @return
+ // */
+ // public AlignFrame newViewFrom(AlignFrame alf);
+ //
+ // /**
+ // * create a new view named name on alf
+ // *
+ // * @param alf
+ // * @param name
+ // * @return
+ // */
+ // public AlignFrame newViewFrom(AlignFrame alf, String name);
+ //
+
+ /**
+ * get sequences selected in alf and return their alignment in format 'format'
+ * either with or without suffix
+ *
+ * @param format
+ * - format of alignment file
+ * @param alf
+ * - where selection is
+ * @param suffix
+ * - true to append /start-end string to each sequence ID
+ *
+ * @return selected sequences as flat file or empty string if there was no
+ * current selection
+ */
+ public String getSelectedSequencesAsAlignment(String format,
+ boolean addSuffix, AlignFrame alf);
+
+ /**
+ *
+ * @param sequenceId
+ * id of sequence to highlight
+ * @param position
+ * integer position [ tobe implemented or range ] on sequence
+ * @param alignedPosition
+ * false, blank or something else - indicate if position is an
+ * alignment column or unaligned sequence position
+ * @param alf
+ * alignment frame (default current)
+ */
+ public void highlight(String sequenceId, String position,
+ String alignedPosition, AlignFrame alf);
+
+ /**
+ *
+ * @param data
+ * alignment data as a string
+ * @param title
+ * window title
+ * @param width
+ * desired width or 0 for default width
+ * @param height
+ * desired height or 0 for default height
+ * @return null or new alignment frame
+ */
+
+ public AlignFrame loadAlignment(String data, String title, int width,
+ int height);
+
+ /**
+ * add the given features or annotation to the given alignment view
+ *
+ * @param annotation
+ * @param alf
+ * alignment frame (default current)
+ */
+ public void loadAnnotation(String annotation, AlignFrame alf);
+
+ /**
+ * Parse the given string as a jalview feature or GFF annotation file and
+ * optionally enable feature display on the given AlignFrame.
+ *
+ * @param features
+ * - gff or features file
+ * @param autoenabledisplay
+ * - when true, feature display will be enabled if any features can
+ * be parsed from the string.
+ * @param alf
+ * alignment frame (default current)
+ *
+ * @return true if data parsed as features
+ */
+ public boolean loadFeatures(String features, boolean autoenabledisplay,
+ AlignFrame alf);
+
+ /**
+ * Load a score file.
+ *
+ * @param sScoreFile
+ * @param alf
+ * alignment frame (default current)
+ *
+ * @return
+ */
+ public boolean loadScoreFile(String sScoreFile, AlignFrame alf);
+
+ /**
+ * public static method for JalviewJS API to open a PCAPanel without
+ * necessarily using a dialog.
+ *
+ * @param modelName
+ * @param alf
+ * may be null
+ *
+ * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
+ * if number of sequences selected is inappropriate
+ */
+ public Object openPcaPanel(String modelName, AlignFrame alf);
+
+ /**
+ * Open a new Tree panel on the desktop statically. Params are standard (not
+ * set by Groovy). No dialog is opened.
+ *
+ * @param treeType
+ * @param modelName
+ * @param alf
+ * align frame (default current)
+ *
+ * @return null, or the string "label.you_need_at_least_n_sequences" if number
+ * of sequences selected is inappropriate
+ */
+ public Object openTreePanel(String treeType, String modelName,
+ AlignFrame alf);
+
+ /**
+ * re-order the given alignment using the given array of sequence IDs
+ *
+ * @param ids
+ * array of sequence IDs
+ * @param undoName
+ * - string to use when referring to ordering action in undo buffer
+ * @param alf
+ * alignment frame (default current)
+ *
+ * @return 'true' if alignment was actually reordered. empty string if
+ * alignment did not contain sequences.
+ */
+ public boolean orderAlignment(String[] ids, String undoName,
+ AlignFrame alf);
+
+ /**
+ * process commandline arguments after the JavaScript application has started
+ *
+ * @param args
+ * @return
+ */
+ public Object parseArguments(String[] args);
+
+ boolean parseFeaturesFile(String filename, AlignFrame alf);
+
+ // Bob's additions:
+
+ /**
+ * remove any callback using the given listener function and associated with
+ * the given AlignFrame (or null for all callbacks);
+ *
+ * @param listener
+ * (may be null);
+ * @param alf
+ * alignment frame (default current)
+ */
+ public void removeSelectionListener(String listener, AlignFrame af);
+
+ /**
+ * adjust horizontal/vertical scroll to make the given location the top left
+ * hand corner for the given view
+ *
+ * @param topRow
+ * -1 for current top row
+ * @param leftHandColumn
+ * -1 for current left-hand column
+ * @param alf
+ * alignment frame (default current)
+ */
+ public void scrollViewTo(int topRow, int leftHandColumn, AlignFrame alf);
+ /**
+ * select regions of the given alignment frame
+ *
+ * @param alf
+ * alignment frame (default current)
+ * @param toselect
+ * String separated list { column range, seq1...seqn sequence ids }
+ * @param sep
+ * separator between toselect fields
+ */
+ public void select(String[] sequenceIds, String[] columns,
+ AlignFrame alf);
+
+ /**
+ * Set the state (visible or not) of the selected feature groups.
+ *
+ * @param groups
+ * @param state
+ * @param alf
+ * (default current)
+ */
+ public void setFeatureGroupState(String[] groups, boolean state,
+ AlignFrame alf);
+
+ /**
+ * Register a JavaScript function to handle alignment selection events. Events
+ * are generated when the user completes a selection event, or when the user
+ * deselects all selected regions. The method is called back with the
+ * following arguments:
+ *
+ * the appletID (such as "Jalview1")
+ *
+ * the source alignment frame
+ *
+ * the SelectionSource object (for example, an AlignViewport)
+ *
+ * the sequence set ID
+ *
+ * an array of sequence IDs
+ *
+ * an array of columns (single number or hyphenated range)
+ *
+ * @param listener
+ * name of JavaScript function to be called
+ *
+ * @param alf
+ * alignment frame (default ALL)
+ */
+ public void setSelectionListener(String listener, AlignFrame alf);
+
+ public void showOverview();
+
+ /**
+ *
+ * @param pdbID
+ * @param fileType
+ * @param alf
+ * align frame (default current)
+ */
+ public void showStructure(String pdbID, String fileType, AlignFrame alf);
+
+}
diff --git a/src/jalview/appletgui/APopupMenu.java b/src/jalview/appletgui/APopupMenu.java
index e1bfbde..311f1e7 100644
--- a/src/jalview/appletgui/APopupMenu.java
+++ b/src/jalview/appletgui/APopupMenu.java
@@ -773,8 +773,7 @@ public class APopupMenu extends java.awt.PopupMenu
ap.alignFrame.addHistoryItem(editCommand);
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
}
}
}
@@ -811,8 +810,7 @@ public class APopupMenu extends java.awt.PopupMenu
ap.alignFrame.addHistoryItem(caseCommand);
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
}
}
diff --git a/src/jalview/appletgui/AlignFrame.java b/src/jalview/appletgui/AlignFrame.java
index 1a46585..fc1f26d 100644
--- a/src/jalview/appletgui/AlignFrame.java
+++ b/src/jalview/appletgui/AlignFrame.java
@@ -882,7 +882,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
}
else if (source == autoCalculate)
{
- viewport.autoCalculateConsensus = autoCalculate.getState();
+ viewport.setAutoCalculateConsensusAndConservation(autoCalculate.getState());
}
else if (source == sortByTree)
{
@@ -1701,8 +1701,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
// viewport.getColumnSelection().getHiddenColumns()
// != null;
updateEditMenuBar();
- originalSource.firePropertyChange("alignment", null,
- originalSource.getAlignment().getSequences());
+ originalSource.notifyAlignment();
}
/**
@@ -1734,8 +1733,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
// != null;
updateEditMenuBar();
- originalSource.firePropertyChange("alignment", null,
- originalSource.getAlignment().getSequences());
+ originalSource.notifyAlignment();
}
AlignmentViewport getOriginatingSource(CommandI command)
@@ -2084,8 +2082,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
viewport.getRanges().setEndSeq(viewport.getAlignment().getHeight() - 1); // BH
// 2019.04.18
viewport.getAlignment().getWidth();
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
}
@@ -2159,8 +2156,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
viewport.setSelectionGroup(null);
viewport.getAlignment().deleteGroup(sg);
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
if (viewport.getAlignment().getHeight() < 1)
{
@@ -2372,7 +2368,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
}
}
- viewport.firePropertyChange("alignment", null, al.getSequences());
+ viewport.notifyAlignment();
}
}
@@ -2416,7 +2412,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
// if (viewport.hasHiddenColumns)
// viewport.getColumnSelection().compensateForEdits(shifts);
ranges.setStartRes(seq.findIndex(startRes) - 1);
- viewport.firePropertyChange("alignment", null, al.getSequences());
+ viewport.notifyAlignment();
}
@@ -2450,7 +2446,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
ranges.setStartRes(seq.findIndex(startRes) - 1);
- viewport.firePropertyChange("alignment", null, al.getSequences());
+ viewport.notifyAlignment();
}
diff --git a/src/jalview/appletgui/AlignViewport.java b/src/jalview/appletgui/AlignViewport.java
index 0324d8c..b379c2d 100644
--- a/src/jalview/appletgui/AlignViewport.java
+++ b/src/jalview/appletgui/AlignViewport.java
@@ -352,7 +352,7 @@ public class AlignViewport extends AlignmentViewport
if (mappedCommand != null)
{
mappedCommand.doCommand(null);
- firePropertyChange("alignment", null, getAlignment().getSequences());
+ notifyAlignment();
// ap.scalePanelHolder.repaint();
// ap.repaint();
diff --git a/src/jalview/appletgui/RedundancyPanel.java b/src/jalview/appletgui/RedundancyPanel.java
index bd36b0d..6488c61 100644
--- a/src/jalview/appletgui/RedundancyPanel.java
+++ b/src/jalview/appletgui/RedundancyPanel.java
@@ -227,8 +227,7 @@ public class RedundancyPanel extends SliderPanel
ap.alignFrame.addHistoryItem(cut);
PaintRefresher.Refresh(this, ap.av.getSequenceSetId(), true, true);
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
}
}
@@ -243,8 +242,7 @@ public class RedundancyPanel extends SliderPanel
{
ap.av.getHistoryList().remove(command);
ap.alignFrame.updateEditMenuBar();
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
}
ap.paintAlignment(true, true);
diff --git a/src/jalview/appletgui/SeqPanel.java b/src/jalview/appletgui/SeqPanel.java
index 776e9ad..a1e2340 100644
--- a/src/jalview/appletgui/SeqPanel.java
+++ b/src/jalview/appletgui/SeqPanel.java
@@ -132,8 +132,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
if (editCommand != null && editCommand.getSize() > 0)
{
ap.alignFrame.addHistoryItem(editCommand);
- av.firePropertyChange("alignment", null,
- av.getAlignment().getSequences());
+ av.notifyAlignment();
}
startseq = -1;
diff --git a/src/jalview/appletgui/TreeCanvas.java b/src/jalview/appletgui/TreeCanvas.java
index cb26fb5..46d6c11 100755
--- a/src/jalview/appletgui/TreeCanvas.java
+++ b/src/jalview/appletgui/TreeCanvas.java
@@ -715,8 +715,10 @@ public class TreeCanvas extends Panel
ap.updateAnnotation();
if (av.getCodingComplement() != null)
{
- ((AlignmentViewport) av.getCodingComplement()).firePropertyChange(
- "alignment", null, ap.av.getAlignment().getSequences());
+ ((AlignmentViewport) av.getCodingComplement()).notifyAlignment();
+ // Technically, the property change is not the same because av is not necessarily getCodingComplement(),
+ // but this is the appletgui, so I am not going to worry about it. BH
+ //.firePropertyChange("alignment", null, ap.av.getAlignment().getSequences());
}
}
diff --git a/src/jalview/javascript/JSFunctionExec.java b/src/jalview/appletgui/js/JSFunctionExec.java
similarity index 99%
rename from src/jalview/javascript/JSFunctionExec.java
rename to src/jalview/appletgui/js/JSFunctionExec.java
index 29f3fa9..247552b 100644
--- a/src/jalview/javascript/JSFunctionExec.java
+++ b/src/jalview/appletgui/js/JSFunctionExec.java
@@ -18,7 +18,7 @@
* along with Jalview. If not, see .
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
-package jalview.javascript;
+package jalview.appletgui.js;
import jalview.bin.JalviewLite;
diff --git a/src/jalview/javascript/JalviewLiteJsApi.java b/src/jalview/appletgui/js/JalviewLiteJsApi.java
similarity index 99%
rename from src/jalview/javascript/JalviewLiteJsApi.java
rename to src/jalview/appletgui/js/JalviewLiteJsApi.java
index b5811aa..f62beeb 100644
--- a/src/jalview/javascript/JalviewLiteJsApi.java
+++ b/src/jalview/appletgui/js/JalviewLiteJsApi.java
@@ -18,7 +18,7 @@
* along with Jalview. If not, see .
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
-package jalview.javascript;
+package jalview.appletgui.js;
import jalview.appletgui.AlignFrame;
@@ -455,7 +455,7 @@ public interface JalviewLiteJsApi
* - separator separated list of PDB file URIs that this viewer is
* handling. These files must be in the same order they appear in
* Jmol (e.g. first one is frame 1, second is frame 2, etc).
- * @see jalview.javascript.MouseOverStructureListener
+ * @see jalview.appletgui.js.MouseOverStructureListener
*/
public abstract void setStructureListener(String listener,
String modelSet);
diff --git a/src/jalview/javascript/JsCallBack.java b/src/jalview/appletgui/js/JsCallBack.java
similarity index 97%
rename from src/jalview/javascript/JsCallBack.java
rename to src/jalview/appletgui/js/JsCallBack.java
index 76d6e8d..2fe4dac 100644
--- a/src/jalview/javascript/JsCallBack.java
+++ b/src/jalview/appletgui/js/JsCallBack.java
@@ -18,7 +18,7 @@
* along with Jalview. If not, see .
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
-package jalview.javascript;
+package jalview.appletgui.js;
public interface JsCallBack
{
diff --git a/src/jalview/javascript/JsSelectionSender.java b/src/jalview/appletgui/js/JsSelectionSender.java
similarity index 99%
rename from src/jalview/javascript/JsSelectionSender.java
rename to src/jalview/appletgui/js/JsSelectionSender.java
index c2a963e..b774813 100644
--- a/src/jalview/javascript/JsSelectionSender.java
+++ b/src/jalview/appletgui/js/JsSelectionSender.java
@@ -18,7 +18,7 @@
* along with Jalview. If not, see .
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
-package jalview.javascript;
+package jalview.appletgui.js;
import jalview.appletgui.AlignFrame;
import jalview.bin.JalviewLite;
diff --git a/src/jalview/javascript/MouseOverListener.java b/src/jalview/appletgui/js/MouseOverListener.java
similarity index 99%
rename from src/jalview/javascript/MouseOverListener.java
rename to src/jalview/appletgui/js/MouseOverListener.java
index 6a4d0f8..59c13eb 100644
--- a/src/jalview/javascript/MouseOverListener.java
+++ b/src/jalview/appletgui/js/MouseOverListener.java
@@ -18,7 +18,7 @@
* along with Jalview. If not, see .
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
-package jalview.javascript;
+package jalview.appletgui.js;
import jalview.appletgui.AlignFrame;
import jalview.bin.JalviewLite;
diff --git a/src/jalview/javascript/MouseOverStructureListener.java b/src/jalview/appletgui/js/MouseOverStructureListener.java
similarity index 99%
rename from src/jalview/javascript/MouseOverStructureListener.java
rename to src/jalview/appletgui/js/MouseOverStructureListener.java
index 6071933..7a16009 100644
--- a/src/jalview/javascript/MouseOverStructureListener.java
+++ b/src/jalview/appletgui/js/MouseOverStructureListener.java
@@ -18,12 +18,13 @@
* along with Jalview. If not, see .
* The Jalview Authors are detailed in the 'AUTHORS' file.
*/
-package jalview.javascript;
+package jalview.appletgui.js;
import jalview.api.AlignmentViewPanel;
import jalview.api.FeatureRenderer;
import jalview.api.SequenceRenderer;
import jalview.appletgui.AlignFrame;
+import jalview.appletgui.js.JsCallBack;
import jalview.bin.JalviewLite;
import jalview.datamodel.SequenceI;
import jalview.ext.jmol.JmolCommands;
diff --git a/src/jalview/bin/AppletParams.java b/src/jalview/bin/AppletParams.java
index 6a23c39..726734d 100644
--- a/src/jalview/bin/AppletParams.java
+++ b/src/jalview/bin/AppletParams.java
@@ -1,23 +1,33 @@
-package jalview.bin;
-import jalview.gui.Preferences;
+package jalview.bin;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
-import java.util.Vector;
+
+import jalview.gui.Preferences;
/**
- * Collection of all known applet tags from JalviewLite
+ * Collection of all known applet tags from JalviewLite.
+ * Three cases; can be one or more of these:
+ *
+ * CASE I. args[] name and value for ArgsParser
+ *
+ * CASE II. applet parameter for JalviewJSApp
+ *
+ * CASE III. mapped to a Preference
+ *
*
* @author hansonr
*
*/
@SuppressWarnings("serial")
-public class AppletParams extends HashMap
+public class AppletParams extends HashMap
{
- private final static String[] params = { "alignpdbfiles",
- Preferences.ANNOTATIONCOLOUR_MAX, Preferences.ANNOTATIONCOLOUR_MIN,
+ private final static String[] params = {
+ "alignpdbfiles",
+ "ANNOTATIONCOLOUR_MAX", "ANNOTATIONCOLOUR_MIN",
"annotations",
"APPLICATION_URL", "automaticScrolling", "centrecolumnlabels",
"debug", "defaultColour", "defaultColourNuc", "defaultColourProt",
@@ -37,18 +47,10 @@ public class AppletParams extends HashMap
"userDefinedColour", "widthScale", "windowHeight", "windowWidth",
"wrap", };
- public AppletParams(Map info)
- {
- for (int i = params.length; --i >= 0;)
- {
- put(params[i], info.get(params[i]));
- }
- }
-
public String getParam(String param, String def)
{
- String val = get(param);
- return (val != null ? val : def);
+ Object val = get(param);
+ return (val != null ? val.toString() : def);
}
//
public AppletParams()
{
- // TODO Auto-generated constructor stub
+ }
+
+ public static AppletParams getAppletParams(Map map,
+ List vargs)
+ {
+ AppletParams appletParams = new AppletParams();
+ String resourcePath = getString(map, "resourcePath");
+ if (resourcePath == null)
+ resourcePath = "";
+ if (resourcePath.length() > 0 && !resourcePath.endsWith("/"))
+ {
+ resourcePath += "/";
+ }
+ for (int i = params.length; --i >= 0;)
+ {
+ String prefName = params[i];
+ Object value = map.get(prefName);
+ if (value != null)
+ addParam(vargs, prefName, value, appletParams, resourcePath);
+ }
+ return appletParams;
+ }
+
+ private static String getString(Map map, String key)
+ {
+ Object o = map.get(key);
+ return (o == null ? null : o.toString());
}
public static AppletParams getAppletParams(String[] args,
- Vector vargs)
+ List vargs)
{
AppletParams appletParams = new AppletParams();
- String resourcePath = null;
+ String resourcePath = "";
for (int i = args.length; --i > 0;) // > 0 is correct, not >=0
{
if (args[i].startsWith("name=\"Info.resourcePath\""))
@@ -129,265 +157,269 @@ public class AppletParams extends HashMap
if (arg.startsWith("name="))
{
String prefName = getAttr(arg, "name");
- String appletName = prefName.toLowerCase();
- String argName = prefName;
String value = getAttr(arg, "value");
+ addParam(vargs, prefName, value, appletParams, resourcePath);
+ }
+ }
+ return appletParams;
+ }
- // note that Application arguments ARE case-sensitive, but
- // Applet.getParameter() is not.
+ private static void addParam(List vargs, String prefName,
+ Object value, AppletParams appletParams, String resourcePath)
+ {
- switch (appletName)
- {
+ // note that Application arguments ARE case-sensitive, but
+ // Applet.getParameter() is not.
- case "file":
- argName = "open";
- appletName = null;
- value = resourcePath + value;
- break;
- case "file2":
- argName = "open2";
- prefName = null;
- value = resourcePath + value;
- break;
- case "features":
- case "jnetfile":
- case "jpredfile":
- case "pdbfile":
- case "scorefile":
- case "sequence":
- // setting argName to null indicates that we want
- // JalviewAppLoader to take care of this.
- prefName = argName = null;
- value = resourcePath + value;
- break;
- case "tree":
- case "treefile":
- // setting appletName to null indicates that we want
- // Jalview.doMain to taken care of this as Jalview args
- argName = "tree";
- appletName = null;
- value = resourcePath + value;
- break;
-
- // non-loading preferences
-
- case "defaultcolour":
- prefName = Preferences.DEFAULT_COLOUR;
- break;
- case "defaultcolournuc":
- prefName = Preferences.DEFAULT_COLOUR_NUC;
- break;
- case "defaultcolourprot":
- prefName = Preferences.DEFAULT_COLOUR_PROT;
- break;
- case "annotationcolour_max":
- prefName = Preferences.ANNOTATIONCOLOUR_MAX;
- break;
- case "annotationcolour_min":
- prefName = Preferences.ANNOTATIONCOLOUR_MIN;
- break;
- case "enablesplitframe":
- prefName = Preferences.ENABLE_SPLIT_FRAME;
- break;
- case "centrecolumnlabels":
- prefName = Preferences.CENTRE_COLUMN_LABELS;
- break;
- case "sortby":
- prefName = Preferences.SORT_ALIGNMENT; // id, etc.
- break;
- case "normalisesequencelogo":
- prefName = Preferences.NORMALISE_CONSENSUS_LOGO;
- break;
- case "relaxedidmatch":
- prefName = Preferences.RELAXEDSEQIDMATCHING;
- break;
- case "scaleproteinascdna":
- prefName = Preferences.SCALE_PROTEIN_TO_CDNA;
- break;
- case "userdefinedcolour":
- argName = "colour";
- prefName = Preferences.USER_DEFINED_COLOURS;
- break;
- case "wrap":
- prefName = Preferences.WRAP_ALIGNMENT;
- break;
-
- // implemented; not tested:
-
- case "oninit":
- prefName = null;
- break;
- case "annotations":
- value = resourcePath + value;
- argName = null;
- break;
- case "hidefeaturegroups":
- // TODO
- break;
- case "pdbseq":
- argName = prefName = null;
- break;
- case "sortbytree":
- prefName = Preferences.SORT_BY_TREE;
- value = checkTF(value);
- appletName = null; // taken care of by Jalview
- break;
- case "format":
- break;
- case "alignpdbfiles":
- argName = prefName = null;
- break;
- case "separator":
- break;
-
- // TODO: probably not relevant?
-
- case "rgb":
- prefName = null; // TODO no background for application?
- break;
- case "externalstructureviewer":
- break;
- case "application_url":
- break;
- case "automaticscrolling":
- break;
- case "heightscale":
- break;
- case "jalviewhelpurl":
- break;
- case "label":
- break;
- case "linklabel_":
- prefName = "linkLabel_";
- break;
- case "linklabel_1":
- prefName = "linkLabel_1";
- break;
- case "linkurl_":
- prefName = "linkURL_";
- break;
-
- // unknown:
-
- case "nojmol":
- case "normaliselogo":
- case "resolvetocodebase":
- case "uppercase":
- case "widthscale":
- case "windowheight":
- case "windowwidth":
- argName = prefName = null;
- break;
-
- // TRUE/FALSE
-
- case "debug":
- value = checkTF(value);
- break;
- case "embedded":
- value = checkTF(value);
- break;
- case "showbutton":
- value = checkTF(value);
- break;
- case "showannotation":
- prefName = Preferences.SHOW_ANNOTATIONS;
- value = checkTF(value);
- break;
- case "showconsensus":
- prefName = Preferences.SHOW_CONSENSUS_LOGO;
- value = checkTF(value);
- break;
- case "showconsensushistogram":
- prefName = Preferences.SHOW_CONSENSUS_HISTOGRAM;
- value = checkTF(value);
- break;
- case "showconservation":
- prefName = Preferences.SHOW_CONSERVATION;
- value = checkTF(value);
- break;
- case "showgroupconsensus":
- prefName = Preferences.SHOW_GROUP_CONSENSUS;
- value = checkTF(value);
- break;
- case "showgroupconservation":
- prefName = Preferences.SHOW_GROUP_CONSERVATION;
- value = checkTF(value);
- break;
- case "showoccupancy":
- prefName = Preferences.SHOW_OCCUPANCY;
- value = checkTF(value);
- break;
- case "showquality":
- prefName = Preferences.SHOW_QUALITY;
- value = checkTF(value);
- break;
- case "showsequencelogo":
- prefName = Preferences.SHOW_CONSENSUS_LOGO;
- value = checkTF(value);
- break;
- case "showfeaturegroups":
- value = checkTF(value);
- break;
- case "showfeaturesettings":
- value = checkTF(value);
- break;
- case "showfullid":
- value = checkTF(value);
- break;
- case "showtreebootstraps":
- value = checkTF(value);
- break;
- case "showtreedistances":
- value = checkTF(value);
- break;
- case "showunconserved":
- prefName = Preferences.SHOW_UNCONSERVED;
- value = checkTF(value);
- break;
- case "showunlinkedtreenodes":
- value = checkTF(value);
- break;
- default:
- if (appletName.startsWith("pdbfile")
- || appletName.startsWith("sequence") && Character.isDigit(
- appletName.charAt(appletName.length() - 1)))
- {
- // could be pdbFile2, for example
- prefName = argName = null;
- value = resourcePath + value;
- break;
- }
- // or one of the app preference names
- break;
- }
- // put name and value into application args
- if (value != null && argName != null)
- {
- vargs.add(argName);
- if (value != "true")
- {
- vargs.add(value);
- }
- }
- if (value == null)
- {
- value = "false";
- }
- System.out.println("AppletParams propName=" + prefName + " argName="
- + argName + " appletName="
- + appletName + " value=" + value);
- if (appletName != null)
- {
- appletParams.put(appletName, value);
- }
- if (prefName != null)
- {
- Cache.setPropertyNoSave(prefName, value);
- }
+ // prefName // CASE III
+
+ String argName = null; // CASE I
+
+ String appletName = prefName.toLowerCase(); // CASE II
+
+ // by nulling one or more of these names, that route will not be used.
+
+ switch (appletName)
+ {
+
+ case "file":
+ argName = "open";
+ prefName = null;
+ value = resourcePath + value;
+ break;
+ case "file2":
+ argName = "open2";
+ prefName = null;
+ value = resourcePath + value;
+ break;
+ case "oninit":
+ case "hidefeaturegroups":
+ // applet parameter only
+ // setting argName to null indicates that we want
+ // JalviewJSApp to take care of this using getParameter or getParameterAsObject
+ prefName = argName = null;
+ break;
+ case "tree":
+ case "treefile":
+ // setting appletName to null indicates that we want
+ // Jalview.doMain to taken care of this as Jalview args
+ argName = "tree";
+ prefName = null;
+ value = resourcePath + value;
+ break;
+
+ case "features":
+ case "jnetfile":
+ case "jpredfile":
+ case "pdbfile":
+ case "scorefile":
+ case "sequence":
+ case "annotations":
+ prefName = argName = null;
+ value = resourcePath + value;
+ break;
+
+ // non-loading preferences
+
+ case "defaultcolour":
+ prefName = Preferences.DEFAULT_COLOUR;
+ break;
+ case "defaultcolournuc":
+ prefName = Preferences.DEFAULT_COLOUR_NUC;
+ break;
+ case "defaultcolourprot":
+ prefName = Preferences.DEFAULT_COLOUR_PROT;
+ break;
+ case "annotationcolour_max":
+ prefName = Preferences.ANNOTATIONCOLOUR_MAX;
+ break;
+ case "annotationcolour_min":
+ prefName = Preferences.ANNOTATIONCOLOUR_MIN;
+ break;
+ case "enablesplitframe":
+ prefName = Preferences.ENABLE_SPLIT_FRAME;
+ break;
+ case "centrecolumnlabels":
+ prefName = Preferences.CENTRE_COLUMN_LABELS;
+ break;
+ case "sortby":
+ prefName = Preferences.SORT_ALIGNMENT; // id, etc.
+ break;
+ case "normalisesequencelogo":
+ prefName = Preferences.NORMALISE_CONSENSUS_LOGO;
+ break;
+ case "relaxedidmatch":
+ prefName = Preferences.RELAXEDSEQIDMATCHING;
+ break;
+ case "scaleproteinascdna":
+ prefName = Preferences.SCALE_PROTEIN_TO_CDNA;
+ break;
+ case "userdefinedcolour":
+ argName = "colour";
+ prefName = Preferences.USER_DEFINED_COLOURS;
+ break;
+ case "wrap":
+ prefName = Preferences.WRAP_ALIGNMENT;
+ break;
+ case "sortbytree":
+ argName = prefName;
+ prefName = Preferences.SORT_BY_TREE;
+ value = checkTF(value);
+ break;
+
+ // implemented; not tested:
+
+ case "pdbseq":
+ case "alignpdbfiles":
+ prefName = null;
+ break;
+ case "format":
+ argName = prefName;
+ break;
+ case "separator":
+ argName = prefName;
+ break;
+
+ // TODO: probably not relevant?
+
+ case "rgb":
+ prefName = null; // TODO no background for application?
+ break;
+ case "externalstructureviewer":
+ break;
+ case "application_url":
+ break;
+ case "automaticscrolling":
+ break;
+ case "heightscale":
+ break;
+ case "jalviewhelpurl":
+ break;
+ case "label":
+ break;
+ case "linklabel_":
+ prefName = "linkLabel_";
+ break;
+ case "linklabel_1":
+ prefName = "linkLabel_1";
+ break;
+ case "linkurl_":
+ prefName = "linkURL_";
+ break;
+
+ // unknown:
+
+ case "nojmol":
+ case "normaliselogo":
+ case "resolvetocodebase":
+ case "uppercase":
+ case "widthscale":
+ case "windowheight":
+ case "windowwidth":
+ prefName = null;
+ break;
+
+ // TRUE/FALSE
+
+ case "debug":
+ case "embedded":
+ case "showbutton":
+ value = checkTF(value);
+ break;
+ case "showannotation":
+ prefName = Preferences.SHOW_ANNOTATIONS;
+ value = checkTF(value);
+ break;
+ case "showconsensus":
+ prefName = Preferences.SHOW_CONSENSUS_LOGO;
+ value = checkTF(value);
+ break;
+ case "showconsensushistogram":
+ prefName = Preferences.SHOW_CONSENSUS_HISTOGRAM;
+ value = checkTF(value);
+ break;
+ case "showconservation":
+ prefName = Preferences.SHOW_CONSERVATION;
+ value = checkTF(value);
+ break;
+ case "showgroupconsensus":
+ prefName = Preferences.SHOW_GROUP_CONSENSUS;
+ value = checkTF(value);
+ break;
+ case "showgroupconservation":
+ prefName = Preferences.SHOW_GROUP_CONSERVATION;
+ value = checkTF(value);
+ break;
+ case "showoccupancy":
+ prefName = Preferences.SHOW_OCCUPANCY;
+ value = checkTF(value);
+ break;
+ case "showquality":
+ prefName = Preferences.SHOW_QUALITY;
+ value = checkTF(value);
+ break;
+ case "showsequencelogo":
+ prefName = Preferences.SHOW_CONSENSUS_LOGO;
+ value = checkTF(value);
+ break;
+ case "showunconserved":
+ prefName = Preferences.SHOW_UNCONSERVED;
+ value = checkTF(value);
+ break;
+ case "showfeaturegroups":
+ case "showfeaturesettings":
+ case "showfullid":
+ case "showtreebootstraps":
+ case "showtreedistances":
+ case "showunlinkedtreenodes":
+ value = checkTF(value);
+ break;
+ default:
+ if (appletName.startsWith("pdbfile")
+ || appletName.startsWith("sequence") && Character
+ .isDigit(appletName.charAt(appletName.length() - 1)))
+ {
+ // could be pdbFile2, for example
+ prefName = argName = null;
+ value = resourcePath + value;
+ break;
}
+ // or one of the app preference names
+ break;
+ }
+
+ // CASE I. args[] name and value for ArgsParser
+ //
+ // If given an argument name,
+ // put name and value into application args
+ if (value != null && argName != null)
+ {
+ vargs.add(argName);
+ if (value != "true")
+ {
+ vargs.add(value.toString());
+ }
+ }
+
+ // CASE II. applet parameter for JalviewJSApp
+
+ if (value == null)
+ {
+ value = "false";
+ }
+ System.out.println("AppletParams propName=" + prefName + " argName="
+ + argName + " appletName=" + appletName + " value=" + value);
+ if (appletName != null)
+ {
+ appletParams.put(appletName, value);
+ }
+
+ // CASE III. mapped to a Preference
+
+ if (prefName != null)
+ {
+ Cache.setPropertyNoSave(prefName, value.toString());
}
- return appletParams;
}
/**
@@ -396,9 +428,9 @@ public class AppletParams extends HashMap
* @param value
* @return "true" or null
*/
- private static String checkTF(String value)
+ private static String checkTF(Object value)
{
- return (value.toLowerCase() == "true" ? "true" : null);
+ return (("" + value).toLowerCase() == "true" ? "true" : null);
}
/**
diff --git a/src/jalview/bin/ApplicationSingletonProvider.java b/src/jalview/bin/ApplicationSingletonProvider.java
new file mode 100644
index 0000000..b64f40c
--- /dev/null
+++ b/src/jalview/bin/ApplicationSingletonProvider.java
@@ -0,0 +1,163 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see .
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.bin;
+
+import jalview.util.Platform;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A class to hold singleton objects, whose scope (context) is
+ *
+ * the Java runtime (JVM) when running as Java
+ * one 'applet', when running as JalviewJS
+ *
+ * This allows separation of multiple JS applets running on the same browser
+ * page, each with their own 'singleton' instances.
+ *
+ * Instance objects are held in a separate Map (keyed by Class) for each
+ * context. For Java, this is just a single static Map. For SwingJS, the map is
+ * stored as a field {@code _swingjsSingletons} of
+ * {@code Thread.currentThread.getThreadGroup()}, as a proxy for the applet.
+ *
+ * Note that when an applet is stopped, its ThreadGroup is removed, allowing any
+ * singleton references to be garbage collected.
+ *
+ * @author hansonr
+ */
+public class ApplicationSingletonProvider
+{
+ /**
+ * A tagging interface to mark classes whose singleton instances may be served
+ * by {@code ApplicationSingletonProvider}, giving a distinct instance per JS
+ * 'applet'.
+ *
+ * A class whose singleton should have global scope (be shared across all
+ * applets on a page) should not use this mechanism, but just provide
+ * a single instance (class static member) in the normal way.
+ */
+ public interface ApplicationSingletonI
+ {
+ }
+
+ /*
+ * Map used to hold singletons in JVM context
+ */
+ private static Map, ApplicationSingletonI> singletons = new HashMap<>();
+
+ /**
+ * private constructor for non-instantiable class
+ */
+ private ApplicationSingletonProvider()
+ {
+ }
+
+ /**
+ * Returns the singletons map for the current context (JVM for Java,
+ * ThreadGroup for JS), creating the map on the first request for each JS
+ * ThreadGroup
+ *
+ * @return
+ */
+ private static Map, ApplicationSingletonI> getContextMap()
+ {
+ @SuppressWarnings("unused")
+ ThreadGroup g = (Platform.isJS()
+ ? Thread.currentThread().getThreadGroup()
+ : null);
+ Map, ApplicationSingletonI> map = singletons;
+ /** @j2sNative map = g._swingjsSingletons; */
+ if (map == null)
+ {
+ map = new HashMap<>();
+ /** @j2sNative g._swingjsSingletons = map; */
+ }
+
+ return map;
+ }
+
+ /**
+ * Answers the singleton instance of the given class for the current context
+ * (JVM or SwingJS 'applet'). If no instance yet exists, one is created, by
+ * calling the class's no-argument constructor. Answers null if any error
+ * occurs (or occurred previously for the same class).
+ *
+ * @param c
+ * @return
+ */
+ public static ApplicationSingletonI getInstance(Class extends ApplicationSingletonI> c)
+ {
+ Map, ApplicationSingletonI> map = getContextMap();
+ if (map.containsKey(c))
+ {
+ /*
+ * singleton already created _or_ creation failed (null value stored)
+ */
+ return map.get(c);
+ }
+
+ /*
+ * create and save the singleton
+ */
+ ApplicationSingletonI o = map.get(c);
+ try
+ {
+ Constructor extends ApplicationSingletonI> con = c
+ .getDeclaredConstructor();
+ con.setAccessible(true);
+ o = con.newInstance();
+ } catch (IllegalAccessException | InstantiationException
+ | IllegalArgumentException | InvocationTargetException
+ | NoSuchMethodException | SecurityException e)
+ {
+ Cache.log.error("Failed to create singleton for " + c.toString()
+ + ", error was: " + e.toString());
+ e.printStackTrace();
+ }
+
+ /*
+ * store the new singleton; note that a
+ * null value is saved if construction failed
+ */
+ getContextMap().put(c, o);
+ return o;
+ }
+
+ /**
+ * Removes the current singleton instance of the given class from the current
+ * application context. This has the effect of ensuring that a new instance is
+ * created the next time one is requested.
+ *
+ * @param c
+ */
+ public static void removeInstance(
+ Class extends ApplicationSingletonI> c)
+ {
+ Map, ApplicationSingletonI> map = getContextMap();
+ if (map != null)
+ {
+ map.remove(c);
+ }
+ }
+}
diff --git a/src/jalview/bin/ArgsParser.java b/src/jalview/bin/ArgsParser.java
index 91c8838..c5c08f6 100644
--- a/src/jalview/bin/ArgsParser.java
+++ b/src/jalview/bin/ArgsParser.java
@@ -20,8 +20,11 @@
*/
package jalview.bin;
+import jalview.util.Platform;
+
import java.net.URLDecoder;
-import java.util.Vector;
+import java.util.ArrayList;
+import java.util.List;
/**
* Notes: this argParser does not distinguish between parameter switches,
@@ -96,7 +99,7 @@ public class ArgsParser
public static final String VSESS = "vsess";
- private Vector vargs = null;
+ private List vargs = null;
private boolean isApplet;
@@ -109,7 +112,7 @@ public class ArgsParser
public ArgsParser(String[] args)
{
- vargs = new Vector<>();
+ vargs = new ArrayList<>();
isApplet = (args.length > 0 && args[0].startsWith("= 0 && val.indexOf(" ") == val.lastIndexOf(" ")) {
+ val = val.replace(" ",", ").replace('-',' ');
+ }
+ Date date = date_format.parse(val);
+ return date;
} catch (Exception ex)
{
System.err.println("Invalid or corrupt date in property '"
@@ -1111,11 +1106,11 @@ public class Cache
}
if (value == null || value.trim().length() < 1)
{
- Cache.applicationProperties.remove(propName);
+ getInstance().applicationProperties.remove(propName);
}
else
{
- Cache.applicationProperties.setProperty(propName, value);
+ getInstance().applicationProperties.setProperty(propName, value);
}
}
@@ -1160,17 +1155,12 @@ public class Cache
{
if (coloursFound.toString().length() > 1)
{
- /* for JalviewJS should be
-
- getInstance().
-
- */
setProperty(UserDefinedColours.USER_DEFINED_COLOURS,
coloursFound.toString());
}
else
{
- applicationProperties
+ getInstance().applicationProperties
.remove(UserDefinedColours.USER_DEFINED_COLOURS);
}
}
@@ -1201,16 +1191,20 @@ public class Cache
public static String getVersionDetailsForConsole()
{
StringBuilder sb = new StringBuilder();
- sb.append("Jalview Version: " + jalview.bin.Cache.getDefault("VERSION", "TEST"));
+ sb.append("Jalview Version: "
+ + jalview.bin.Cache.getDefault("VERSION", "TEST"));
sb.append("\n");
sb.append("Jalview Installation: "
+ jalview.bin.Cache.getDefault("INSTALLATION", "unknown"));
sb.append("\n");
- sb.append("Build Date: " + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
+ sb.append("Build Date: "
+ + jalview.bin.Cache.getDefault("BUILD_DATE", "unknown"));
sb.append("\n");
sb.append("Java version: " + System.getProperty("java.version"));
sb.append("\n");
- sb.append(System.getProperty("os.arch") + " " + System.getProperty("os.name") + " " + System.getProperty("os.version"));
+ sb.append(System.getProperty("os.arch") + " "
+ + System.getProperty("os.name") + " "
+ + System.getProperty("os.version"));
sb.append("\n");
appendIfNotNull(sb, "Install4j version: ",
System.getProperty("sys.install4jVersion"), "\n", null);
@@ -1218,7 +1212,9 @@ public class Cache
System.getProperty("installer_template_version"), "\n", null);
appendIfNotNull(sb, "Launcher version: ",
System.getProperty("launcher_version"), "\n", null);
- if (jalview.bin.Cache.getDefault("VERSION", "TEST").equals("DEVELOPMENT")) {
+ if (jalview.bin.Cache.getDefault("VERSION", "TEST")
+ .equals("DEVELOPMENT"))
+ {
appendIfNotNull(sb, "Getdown appdir: ",
System.getProperty("getdownappdir"), "\n", null);
appendIfNotNull(sb, "Java home: ", System.getProperty("java.home"),
@@ -1237,10 +1233,11 @@ public class Cache
// eg 'built from Source' or update channel
return jalview.bin.Cache.getDefault("INSTALLATION", "unknown");
}
-
+
/**
*
- * For AppletParams and Preferences ok_actionPerformed and startupFileTextfield_mouseClicked
+ * For AppletParams and Preferences ok_actionPerformed and
+ * startupFileTextfield_mouseClicked
*
* Sets a property value for the running application, without saving it to the
* properties file
@@ -1250,12 +1247,7 @@ public class Cache
*/
public static void setPropertyNoSave(String key, String obj)
{
- /* for JalviewJS should be
-
- getInstance().
-
- */
- setPropertyImpl(key, obj, false);
+ getInstance().setPropertyImpl(key, obj, false);
}
/**
@@ -1267,7 +1259,8 @@ public class Cache
* @param andSave
* @return
*/
- private /* for JalviewJS should not be static */ static Object setPropertyImpl(String key, String obj, boolean andSave)
+ private Object setPropertyImpl(
+ String key, String obj, boolean andSave)
{
Object oldValue = null;
try
@@ -1287,6 +1280,4 @@ public class Cache
return oldValue;
}
-
-
}
diff --git a/src/jalview/bin/Jalview.java b/src/jalview/bin/Jalview.java
index e98ea63..4a5c733 100755
--- a/src/jalview/bin/Jalview.java
+++ b/src/jalview/bin/Jalview.java
@@ -37,7 +37,6 @@ import java.security.PermissionCollection;
import java.security.Permissions;
import java.security.Policy;
import java.util.HashMap;
-import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;
@@ -49,23 +48,13 @@ import com.threerings.getdown.util.LaunchUtil;
import groovy.lang.Binding;
import groovy.util.GroovyScriptEngine;
import jalview.api.AlignCalcWorkerI;
-import jalview.api.AlignViewportI;
-import jalview.api.JalviewApp;
-import jalview.api.StructureSelectionManagerProvider;
-import jalview.datamodel.ColumnSelection;
-import jalview.datamodel.HiddenColumns;
-import jalview.datamodel.PDBEntry;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.ext.so.SequenceOntology;
import jalview.gui.AlignFrame;
import jalview.gui.AlignViewport;
-import jalview.gui.AlignmentPanel;
-import jalview.gui.CalculationChooser;
import jalview.gui.Desktop;
import jalview.gui.Preferences;
import jalview.gui.PromptUserConfig;
-import jalview.gui.StructureViewer;
import jalview.io.AppletFormatAdapter;
import jalview.io.BioJsHTMLOutput;
import jalview.io.DataSourceType;
@@ -78,17 +67,12 @@ import jalview.io.HtmlSvgOutput;
import jalview.io.IdentifyFile;
import jalview.io.NewickFile;
import jalview.io.gff.SequenceOntologyFactory;
-import jalview.javascript.JSFunctionExec;
-import jalview.javascript.MouseOverStructureListener;
-import jalview.renderer.seqfeatures.FeatureRenderer;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ColourSchemeProperty;
-import jalview.structure.SelectionSource;
-import jalview.structure.VamsasSource;
import jalview.util.MessageManager;
import jalview.util.Platform;
import jalview.ws.jws2.Jws2Discoverer;
-import netscape.javascript.JSObject;
+//import netscape.javascript.JSObject;
/**
* Main class for Jalview Application
@@ -105,30 +89,44 @@ import netscape.javascript.JSObject;
* @author $author$
* @version $Revision$
*/
-public class Jalview implements JalviewJSApi
+public class Jalview implements ApplicationSingletonI
{
- static
+
+ // for testing those nasty messages you cannot ever find.
+ // static
+ // {
+ // System.setOut(new PrintStream(new ByteArrayOutputStream())
+ // {
+ // @Override
+ // public void println(Object o)
+ // {
+ // if (o != null)
+ // {
+ // System.err.println(o);
+ // }
+ // }
+ //
+ // });
+ // }
+ public static Jalview getInstance()
{
- Platform.getURLCommandArguments();
+ return (Jalview) ApplicationSingletonProvider
+ .getInstance(Jalview.class);
}
- private boolean headless;
-
- // singleton instance of this class
+ private Jalview()
+ {
+ }
- private static Jalview instance;
+ private boolean headless;
private Desktop desktop;
- public static AlignFrame currentAlignFrame;
-
- public boolean isJavaAppletTag;
+ public AlignFrame currentAlignFrame;
public String appletResourcePath;
- JalviewAppLoader appLoader;
-
- protected JSFunctionExec jsFunctionExec;
+ public String j2sAppletID;
private boolean noCalculation, noMenuBar, noStatus;
@@ -156,12 +154,9 @@ public class Jalview implements JalviewJSApi
static
{
- if (!Platform.isJS())
- /**
- * Java only
- *
- * @j2sIgnore
- */
+ if (Platform.isJS()) {
+ Platform.getURLCommandArguments();
+ } else /** @j2sIgnore */
{
// grab all the rights we can for the JVM
Policy.setPolicy(new Policy()
@@ -241,12 +236,6 @@ public class Jalview implements JalviewJSApi
}
- public static Jalview getInstance()
- {
- return instance;
- }
-
-
private final static boolean doPlatformLogging = false;
/**
@@ -261,9 +250,7 @@ public class Jalview implements JalviewJSApi
{
Platform.startJavaLogging();
}
-
- instance = new Jalview();
- instance.doMain(args);
+ getInstance().doMain(args);
}
/**
@@ -273,11 +260,7 @@ public class Jalview implements JalviewJSApi
{
boolean isJS = Platform.isJS();
- if (isJS)
- {
- Platform.setAppClass(this);
- }
- else
+ if (!isJS)
{
System.setSecurityManager(null);
}
@@ -305,7 +288,7 @@ public class Jalview implements JalviewJSApi
}
// report Jalview version
- Cache.loadBuildProperties(true);
+ Cache.getInstance().loadBuildProperties(true);
ArgsParser aparser = new ArgsParser(args);
headless = false;
@@ -314,18 +297,16 @@ public class Jalview implements JalviewJSApi
Cache.loadProperties(usrPropsFile); // must do this before
+ boolean allowServices = true;
+
if (isJS)
{
- isJavaAppletTag = aparser.isApplet();
- if (isJavaAppletTag)
- {
- Preferences.setAppletDefaults();
- Cache.loadProperties(usrPropsFile); // again, because we
- // might be changing defaults here?
- }
- System.out.println(
- " found: " + aparser.getValue("Info.j2sAppletID"));
- appletResourcePath = aparser.getValue("Info.resourcePath");
+ j2sAppletID = Platform.getAppID(null);
+ Preferences.setAppletDefaults();
+ Cache.loadProperties(usrPropsFile); // again, because we
+ // might be changing defaults here?
+ appletResourcePath = (String) aparser.getAppletValue("resourcepath",
+ null, true);
}
else
/**
@@ -357,11 +338,12 @@ public class Jalview implements JalviewJSApi
// anything else!
final String jabawsUrl = aparser.getValue(ArgsParser.JABAWS);
- if (jabawsUrl != null)
+ allowServices = !("none".equals(jabawsUrl));
+ if (allowServices && jabawsUrl != null)
{
try
{
- Jws2Discoverer.getDiscoverer().setPreferredUrl(jabawsUrl);
+ Jws2Discoverer.getInstance().setPreferredUrl(jabawsUrl);
System.out.println(
"CMD [-jabaws " + jabawsUrl + "] executed successfully!");
} catch (MalformedURLException e)
@@ -408,8 +390,6 @@ public class Jalview implements JalviewJSApi
System.exit(0);
}
- desktop = null;
-
if (!isJS)
/** @j2sIgnore */
{
@@ -464,17 +444,18 @@ public class Jalview implements JalviewJSApi
* configure 'full' SO model if preferences say to, else use the default (full SO)
* - as JS currently doesn't have OBO parsing, it must use 'Lite' version
*/
- boolean soDefault = !Platform.isJS();
+ boolean soDefault = !isJS;
if (Cache.getDefault("USE_FULL_SO", soDefault))
{
- SequenceOntologyFactory.setInstance(new SequenceOntology());
+ SequenceOntologyFactory.setSequenceOntology(new SequenceOntology());
}
+
+ desktop = null;
if (!headless)
{
- desktop = new Desktop();
+ desktop = Desktop.getInstance();
desktop.setInBatchMode(true); // indicate we are starting up
-
try
{
JalviewTaskbar.setTaskbar(this);
@@ -482,17 +463,17 @@ public class Jalview implements JalviewJSApi
{
System.out.println("Error setting Taskbar: " + t.getMessage());
}
-
desktop.setVisible(true);
- if (!Platform.isJS())
+ if (!isJS)
/**
* Java only
*
* @j2sIgnore
*/
{
- desktop.startServiceDiscovery();
+ if (allowServices)
+ desktop.startServiceDiscovery();
if (!aparser.contains("nousagestats"))
{
startUsageStats(desktop);
@@ -544,37 +525,20 @@ public class Jalview implements JalviewJSApi
BioJsHTMLOutput.updateBioJS();
}
}
-
parseArguments(aparser, true);
}
/**
- * Allow an outside entity to initiate the second half of argument parsing
- * (only).
+ * Parse all command-line String[] arguments as well as all JavaScript-derived
+ * parameters from Info.
*
- * @param args
- * @return null is good
- */
- @Override
- public Object parseArguments(String[] args)
- {
-
- try
- {
- parseArguments(new ArgsParser(args), false);
- return null;
- } catch (Throwable t)
- {
- return t;
- }
- }
-
- /**
+ * We allow for this method to be run from JavaScript. Basically allowing
+ * simple scripting.
*
* @param aparser
* @param isStartup
*/
- private void parseArguments(ArgsParser aparser, boolean isStartup)
+ public void parseArguments(ArgsParser aparser, boolean isStartup)
{
String groovyscript = null; // script to execute after all loading is
@@ -609,18 +573,82 @@ public class Jalview implements JalviewJSApi
String file = aparser.getValue("open", true);
- if (file == null && desktop == null)
+ if (!isJS && file == null && desktop == null)
{
System.out.println("No files to open!");
System.exit(1);
}
+ setDisplayParameters(aparser);
+
+ // time to open a file.
+
long progress = -1;
DataSourceType protocol = null;
FileLoader fileLoader = new FileLoader(!headless);
FileFormatI format = null;
// Finally, deal with the remaining input data.
- if (file != null)
+ AlignFrame af = null;
+
+ JalviewJSApp jsApp = (isJS ? new JalviewJSApp(this, aparser) : null);
+
+ if (file == null)
+ {
+ if (isJS)
+ {
+ // JalviewJS allows sequence1 sequence2 ....
+
+ }
+ else if (!headless && Cache.getDefault("SHOW_STARTUP_FILE", true))
+ /**
+ * Java only
+ *
+ * @j2sIgnore
+ */
+ {
+
+ // We'll only open the default file if the desktop is visible.
+ // And the user
+ // ////////////////////
+
+ file = Cache.getDefault("STARTUP_FILE",
+ Cache.getDefault("www.jalview.org",
+ "http://www.jalview.org")
+ + "/examples/exampleFile_2_7.jar");
+ if (file.equals(
+ "http://www.jalview.org/examples/exampleFile_2_3.jar"))
+ {
+ // hardwire upgrade of the startup file
+ file.replace("_2_3.jar", "_2_7.jar");
+ // and remove the stale setting
+ Cache.removeProperty("STARTUP_FILE");
+ }
+
+ protocol = DataSourceType.FILE;
+
+ if (file.indexOf("http:") > -1)
+ {
+ protocol = DataSourceType.URL;
+ }
+
+ if (file.endsWith(".jar"))
+ {
+ format = FileFormat.Jalview;
+ }
+ else
+ {
+ try
+ {
+ format = new IdentifyFile().identify(file, protocol);
+ } catch (FileFormatException e)
+ {
+ // TODO what?
+ }
+ }
+ af = fileLoader.LoadFileWaitTillLoaded(file, protocol, format);
+ }
+ }
+ else
{
if (!headless)
{
@@ -651,54 +679,30 @@ public class Jalview implements JalviewJSApi
}
}
}
- String fileFormat = (isJavaAppletTag
- ? aparser.getAppletValue("format", null)
+
+ String fileFormat = (isJS
+ ? (String) aparser.getAppletValue("format", null, true)
: null);
protocol = AppletFormatAdapter.checkProtocol(file);
try
{
- format = (isJavaAppletTag && fileFormat != null
+ format = (fileFormat != null
? FileFormats.getInstance().forName(fileFormat)
: null);
if (format == null)
{
format = new IdentifyFile().identify(file, protocol);
}
- format = new IdentifyFile().identify(file, protocol);
} catch (FileFormatException e1)
{
// TODO ?
}
- if (aparser.contains(ArgsParser.NOMENUBAR))
- {
- noMenuBar = true;
- System.out.println("CMD [nomenu] executed successfully!");
- }
-
- if (aparser.contains(ArgsParser.NOSTATUS))
- {
- noStatus = true;
- System.out.println("CMD [nostatus] executed successfully!");
- }
-
- if (aparser.contains(ArgsParser.NOANNOTATION)
- || aparser.contains(ArgsParser.NOANNOTATION2))
- {
- noAnnotation = true;
- System.out.println("CMD no-annotation executed successfully!");
- }
- if (aparser.contains(ArgsParser.NOCALCULATION))
- {
- noCalculation = true;
- System.out.println("CMD [nocalculation] executed successfully!");
- }
-
- AlignFrame af = new FileLoader(!headless).LoadFileWaitTillLoaded(file,
- protocol, format);
+ af = new FileLoader(!headless).LoadFileWaitTillLoaded(file, protocol,
+ format);
if (af == null)
{
- System.out.println("error");
+ System.out.println("jalview error - AlignFrame was not created");
}
else
{
@@ -733,135 +737,13 @@ public class Jalview implements JalviewJSApi
}
setCurrentAlignFrame(af);
- String data = aparser.getValue(ArgsParser.COLOUR, true);
- if (data != null)
- {
- data.replaceAll("%20", " ");
-
- ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
- af.getViewport(), af.getViewport().getAlignment(), data);
-
- if (cs != null)
- {
- System.out.println(
- "CMD [-color " + data + "] executed successfully!");
- }
- af.changeColour(cs);
- }
-
- // Must maintain ability to use the groups flag
- data = aparser.getValue(ArgsParser.GROUPS, true);
- if (data != null)
- {
- af.parseFeaturesFile(data,
- AppletFormatAdapter.checkProtocol(data));
- // System.out.println("Added " + data);
- System.out.println(
- "CMD groups[-" + data + "] executed successfully!");
- }
- data = aparser.getValue(ArgsParser.FEATURES, true);
- if (data != null)
- {
- af.parseFeaturesFile(data,
- AppletFormatAdapter.checkProtocol(data));
- // System.out.println("Added " + data);
- System.out.println(
- "CMD [-features " + data + "] executed successfully!");
- }
- data = aparser.getValue(ArgsParser.ANNOTATIONS, true);
- if (data != null)
- {
- af.loadJalviewDataFile(data, null, null, null);
- // System.out.println("Added " + data);
- System.out.println(
- "CMD [-annotations " + data + "] executed successfully!");
- }
-
- // JavaScript feature
-
- if (aparser.contains(ArgsParser.SHOWOVERVIEW))
- {
- af.overviewMenuItem_actionPerformed(null);
- System.out.println("CMD [showoverview] executed successfully!");
- }
-
- // set or clear the sortbytree flag.
- if (aparser.contains(ArgsParser.SORTBYTREE))
- {
- af.getViewport().setSortByTree(true);
- if (af.getViewport().getSortByTree())
- {
- System.out.println("CMD [-sortbytree] executed successfully!");
- }
- }
-
- boolean doUpdateAnnotation = false;
- /**
- * we do this earlier in JalviewJS because of a complication with
- * SHOWOVERVIEW
- *
- * For now, just fixing this in JalviewJS.
- *
- *
- * @j2sIgnore
- *
- */
- {
- if (aparser.contains(ArgsParser.NOANNOTATION)
- || aparser.contains(ArgsParser.NOANNOTATION2))
- {
- af.getViewport().setShowAnnotation(false);
- if (!af.getViewport().isShowAnnotation())
- {
- doUpdateAnnotation = true;
- System.out
- .println("CMD no-annotation executed successfully!");
- }
- }
- }
+ setFrameDependentProperties(aparser, af);
-
- if (aparser.contains(ArgsParser.NOSORTBYTREE))
- {
- af.getViewport().setSortByTree(false);
- if (!af.getViewport().getSortByTree())
- {
- doUpdateAnnotation = true;
- System.out
- .println("CMD [-nosortbytree] executed successfully!");
- }
- }
- if (doUpdateAnnotation)
- { // BH 2019.07.24
- af.setMenusForViewport();
- af.alignPanel.updateLayout();
- }
-
- data = aparser.getValue(ArgsParser.TREE, true);
- if (data != null)
- {
- try
- {
- System.out.println(
- "CMD [-tree " + data + "] executed successfully!");
- NewickFile nf = new NewickFile(data,
- AppletFormatAdapter.checkProtocol(data));
- af.getViewport()
- .setCurrentTree(af.showNewickTree(nf, data).getTree());
- } catch (IOException ex)
- {
- System.err.println("Couldn't add tree " + data);
- ex.printStackTrace(System.err);
- }
- }
- // TODO - load PDB structure(s) to alignment JAL-629
- // (associate with identical sequence in alignment, or a specified
- // sequence)
- if (isJavaAppletTag)
+ if (isJS)
{
- loadAppletParams(aparser, af);
+ jsApp.initFromParams(af);
}
- else if (!isJS)
+ else
/**
* Java only
*
@@ -880,75 +762,19 @@ public class Jalview implements JalviewJSApi
groovyscript = null;
}
}
- createOutputFiles(aparser, af, format);
- while (aparser.getSize() > 0)
- {
- System.out.println("Unknown arg: " + aparser.nextValue());
- }
- }
- }
-
-
- AlignFrame startUpAlframe = null;
- // We'll only open the default file if the desktop is visible.
- // And the user
- // ////////////////////
-
- if (!isJS && !headless && file == null
- && Cache.getDefault("SHOW_STARTUP_FILE", true))
- /**
- * Java only
- *
- * @j2sIgnore
- */
- {
- file = Cache.getDefault("STARTUP_FILE",
- Cache.getDefault("www.jalview.org", "http://www.jalview.org")
- + "/examples/exampleFile_2_7.jar");
- if (file.equals(
- "http://www.jalview.org/examples/exampleFile_2_3.jar"))
- {
- // hardwire upgrade of the startup file
- file.replace("_2_3.jar", "_2_7.jar");
- // and remove the stale setting
- Cache.removeProperty("STARTUP_FILE");
- }
-
- protocol = DataSourceType.FILE;
-
- if (file.indexOf("http:") > -1)
- {
- protocol = DataSourceType.URL;
- }
-
- if (file.endsWith(".jar"))
- {
- format = FileFormat.Jalview;
- }
- else
- {
- try
- {
- format = new IdentifyFile().identify(file, protocol);
- } catch (FileFormatException e)
- {
- // TODO what?
+ if (!isJS || !isStartup) {
+ createOutputFiles(aparser, format);
}
}
-
- startUpAlframe = fileLoader.LoadFileWaitTillLoaded(file, protocol,
- format);
-
}
-
// extract groovy arguments before anything else.
// Once all other stuff is done, execute any groovy scripts (in order)
- if (groovyscript != null)
+ if (!isJS && groovyscript != null)
{
if (Cache.groovyJarsPresent())
{
System.out.println("Executing script " + groovyscript);
- executeGroovyScript(groovyscript, startUpAlframe);
+ executeGroovyScript(groovyscript, af);
}
else
{
@@ -967,67 +793,220 @@ public class Jalview implements JalviewJSApi
}
desktop.setInBatchMode(false);
}
+
+ if (jsApp != null) {
+ jsApp.callInitCallback();
+ }
}
-
+
/**
- * Writes an output file for each format (if any) specified in the
- * command-line arguments. Supported formats are currently
- *
- * png
- * svg
- * html
- * biojsmsa
- * imgMap
- * eps
- *
- * A format parameter should be followed by a parameter specifying the output
- * file name. {@code imgMap} parameters should follow those for the
- * corresponding alignment image output.
+ * Set general display parameters irrespective of file loading or headlessness.
*
* @param aparser
- * @param af
- * @param format
*/
- private void createOutputFiles(ArgsParser aparser, AlignFrame af,
- FileFormatI format)
+ private void setDisplayParameters(ArgsParser aparser)
{
- String imageName = "unnamed.png";
- while (aparser.getSize() > 1)
+ if (aparser.contains(ArgsParser.NOMENUBAR))
{
- String outputFormat = aparser.nextValue();
- String file = aparser.nextValue();
+ noMenuBar = true;
+ System.out.println("CMD [nomenu] executed successfully!");
+ }
- if (outputFormat.equalsIgnoreCase("png"))
- {
- af.createPNG(new File(file));
- imageName = (new File(file)).getName();
- System.out.println("Creating PNG image: " + file);
- continue;
- }
- else if (outputFormat.equalsIgnoreCase("svg"))
+ if (aparser.contains(ArgsParser.NOSTATUS))
+ {
+ noStatus = true;
+ System.out.println("CMD [nostatus] executed successfully!");
+ }
+
+ if (aparser.contains(ArgsParser.NOANNOTATION)
+ || aparser.contains(ArgsParser.NOANNOTATION2))
+ {
+ noAnnotation = true;
+ System.out.println("CMD no-annotation executed successfully!");
+ }
+ if (aparser.contains(ArgsParser.NOCALCULATION))
+ {
+ noCalculation = true;
+ System.out.println("CMD [nocalculation] executed successfully!");
+ }
+ }
+
+
+ private void setFrameDependentProperties(ArgsParser aparser,
+ AlignFrame af)
+ {
+ String data = aparser.getValue(ArgsParser.COLOUR, true);
+ if (data != null)
+ {
+ data.replaceAll("%20", " ");
+
+ ColourSchemeI cs = ColourSchemeProperty.getColourScheme(
+ af.getViewport(), af.getViewport().getAlignment(), data);
+
+ if (cs != null)
{
- File imageFile = new File(file);
- imageName = imageFile.getName();
- af.createSVG(imageFile);
- System.out.println("Creating SVG image: " + file);
- continue;
+ System.out.println(
+ "CMD [-color " + data + "] executed successfully!");
}
- else if (outputFormat.equalsIgnoreCase("html"))
+ af.changeColour(cs);
+ }
+
+ // Must maintain ability to use the groups flag
+ data = aparser.getValue(ArgsParser.GROUPS, true);
+ if (data != null)
+ {
+ af.parseFeaturesFile(data,
+ AppletFormatAdapter.checkProtocol(data));
+ // System.out.println("Added " + data);
+ System.out.println(
+ "CMD groups[-" + data + "] executed successfully!");
+ }
+ data = aparser.getValue(ArgsParser.FEATURES, true);
+ if (data != null)
+ {
+ af.parseFeaturesFile(data,
+ AppletFormatAdapter.checkProtocol(data));
+ // System.out.println("Added " + data);
+ System.out.println(
+ "CMD [-features " + data + "] executed successfully!");
+ }
+ data = aparser.getValue(ArgsParser.ANNOTATIONS, true);
+ if (data != null)
+ {
+ af.loadJalviewDataFile(data, null, null, null);
+ // System.out.println("Added " + data);
+ System.out.println(
+ "CMD [-annotations " + data + "] executed successfully!");
+ }
+
+ // JavaScript feature
+
+ if (aparser.contains(ArgsParser.SHOWOVERVIEW))
+ {
+ af.overviewMenuItem_actionPerformed(null);
+ System.out.println("CMD [showoverview] executed successfully!");
+ }
+
+ // set or clear the sortbytree flag.
+ if (aparser.contains(ArgsParser.SORTBYTREE))
+ {
+ af.getViewport().setSortByTree(true);
+ if (af.getViewport().getSortByTree())
{
- File imageFile = new File(file);
- imageName = imageFile.getName();
- HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
- htmlSVG.exportHTML(file);
- System.out.println("Creating HTML image: " + file);
- continue;
+ System.out.println("CMD [-sortbytree] executed successfully!");
}
- else if (outputFormat.equalsIgnoreCase("biojsmsa"))
- {
- if (file == null)
- {
- System.err.println("The output html file must not be null");
- return;
- }
+ }
+
+ boolean doUpdateAnnotation = false;
+ /**
+ * we do this earlier in JalviewJS because of a complication with
+ * SHOWOVERVIEW
+ *
+ * For now, just fixing this in JalviewJS.
+ *
+ *
+ * @j2sIgnore
+ *
+ */
+ {
+ if (noAnnotation)
+ {
+ af.getViewport().setShowAnnotation(false);
+ if (!af.getViewport().isShowAnnotation())
+ {
+ doUpdateAnnotation = true;
+ }
+ }
+ }
+
+ if (aparser.contains(ArgsParser.NOSORTBYTREE))
+ {
+ af.getViewport().setSortByTree(false);
+ if (!af.getViewport().getSortByTree())
+ {
+ doUpdateAnnotation = true;
+ System.out
+ .println("CMD [-nosortbytree] executed successfully!");
+ }
+ }
+ if (doUpdateAnnotation)
+ { // BH 2019.07.24
+ af.setMenusForViewport();
+ af.alignPanel.updateLayout();
+ }
+
+ data = aparser.getValue(ArgsParser.TREE, true);
+ if (data != null)
+ {
+ try
+ {
+ NewickFile nf = new NewickFile(data,
+ AppletFormatAdapter.checkProtocol(data));
+ af.getViewport()
+ .setCurrentTree(af.showNewickTree(nf, data).getTree());
+ System.out.println(
+ "CMD [-tree " + data + "] executed successfully!");
+ } catch (IOException ex)
+ {
+ System.err.println("Couldn't add tree " + data);
+ ex.printStackTrace(System.err);
+ }
+ }
+ // TODO - load PDB structure(s) to alignment JAL-629
+ // (associate with identical sequence in alignment, or a specified
+ // sequence)
+
+ }
+
+ /**
+ * Writes an output file for each format (if any) specified in the
+ * command-line arguments. Supported formats are currently
+ *
+ * png
+ * svg
+ * html
+ * biojsmsa
+ * imgMap
+ * eps
+ *
+ * A format parameter should be followed by a parameter specifying the output
+ * file name. {@code imgMap} parameters should follow those for the
+ * corresponding alignment image output.
+ *
+ * @param aparser
+ * @param format
+ */
+ private void createOutputFiles(ArgsParser aparser,
+ FileFormatI format)
+ {
+ AlignFrame af = currentAlignFrame;
+ while (aparser.getSize() >= 2)
+ {
+ String outputFormat = aparser.nextValue();
+ File imageFile;
+ String fname;
+ switch (outputFormat.toLowerCase())
+ {
+ case "png":
+ imageFile = new File(aparser.nextValue());
+ af.createPNG(imageFile);
+ System.out.println(
+ "Creating PNG image: " + imageFile.getAbsolutePath());
+ continue;
+ case "svg":
+ imageFile = new File(aparser.nextValue());
+ af.createSVG(imageFile);
+ System.out.println(
+ "Creating SVG image: " + imageFile.getAbsolutePath());
+ continue;
+ case "eps":
+ imageFile = new File(aparser.nextValue());
+ System.out.println(
+ "Creating EPS file: " + imageFile.getAbsolutePath());
+ af.createEPS(imageFile);
+ continue;
+ case "biojsmsa":
+ fname = new File(aparser.nextValue()).getAbsolutePath();
try
{
BioJsHTMLOutput.refreshVersionInfo(
@@ -1037,39 +1016,45 @@ public class Jalview implements JalviewJSApi
e.printStackTrace();
}
BioJsHTMLOutput bjs = new BioJsHTMLOutput(af.alignPanel);
- bjs.exportHTML(file);
- System.out.println("Creating BioJS MSA Viwer HTML file: " + file);
+ bjs.exportHTML(fname);
+ System.out.println("Creating BioJS MSA Viwer HTML file: " + fname);
continue;
- }
- else if (outputFormat.equalsIgnoreCase("imgMap"))
- {
- af.createImageMap(new File(file), imageName);
- System.out.println("Creating image map: " + file);
+ case "html":
+ fname = new File(aparser.nextValue()).getAbsolutePath();
+ HtmlSvgOutput htmlSVG = new HtmlSvgOutput(af.alignPanel);
+ htmlSVG.exportHTML(fname);
+ System.out.println("Creating HTML image: " + fname);
continue;
- }
- else if (outputFormat.equalsIgnoreCase("eps"))
- {
- File outputFile = new File(file);
+ case "imgmap":
+ imageFile = new File(aparser.nextValue());
+ af.alignPanel.makePNGImageMap(imageFile, "unnamed.png");
System.out.println(
- "Creating EPS file: " + outputFile.getAbsolutePath());
- af.createEPS(outputFile);
+ "Creating image map: " + imageFile.getAbsolutePath());
continue;
}
-
- af.saveAlignment(file, format);
- if (af.isSaveAlignmentSuccessful())
+ if (!Platform.isJS()) /** @j2sIgnore */
{
- System.out.println(
- "Written alignment in " + format + " format to " + file);
- }
- else
- {
- System.out.println("Error writing file " + file + " in " + format
- + " format!!");
+ // skipping outputFormat?
+ System.out.println("Unknown arg: " + outputFormat);
+ fname = new File(aparser.nextValue()).getAbsolutePath();
+ af.saveAlignment(fname, format);
+ if (af.isSaveAlignmentSuccessful())
+ {
+ System.out.println(
+ "Written alignment in " + format + " format to " + fname);
+ }
+ else
+ {
+ System.out.println("Error writing file " + fname + " in " + format
+ + " format!!");
+ }
}
-
+ break;
+ }
+ while (aparser.getSize() > 0)
+ {
+ System.out.println("Unknown arg: " + aparser.nextValue());
}
-
}
private static void showUsage()
@@ -1118,7 +1103,7 @@ public class Jalview implements JalviewJSApi
/**
* start a User Config prompt asking if we can log usage statistics.
*/
- PromptUserConfig prompter = new PromptUserConfig(Desktop.desktop,
+ PromptUserConfig prompter = new PromptUserConfig(Desktop.getDesktopPane(),
"USAGESTATS", "Jalview Usage Statistics",
"Do you want to help make Jalview better by enabling "
+ "the collection of usage statistics with Google Analytics ?"
@@ -1297,813 +1282,32 @@ public class Jalview implements JalviewJSApi
public static AlignFrame getCurrentAlignFrame()
{
- return Jalview.currentAlignFrame;
+ return Jalview.getInstance().currentAlignFrame;
}
public static void setCurrentAlignFrame(AlignFrame currentAlignFrame)
{
- Jalview.currentAlignFrame = currentAlignFrame;
- }
-
- /**
- * Get the SwingJS applet ID and combine that with the frameType
- *
- * @param frameType
- * "alignment", "desktop", etc., or null
- * @return
- */
- public static String getAppID(String frameType)
- {
- String id = Cache.getProperty("Info.j2sAppletID");
- if (id == null)
- {
- id = "jalview";
- }
- return id + (frameType == null ? "" : "-" + frameType);
- }
-
- /**
- * Handle all JalviewLite applet parameters
- *
- * @param aparser
- * @param af
- */
- private void loadAppletParams(ArgsParser aparser, AlignFrame af)
- {
- JalviewApp app = new JalviewApp()
- {
-
- // TODO BH 2019
- //
- // These are methods that are in JalviewLite that various classes call
- // but are not in JalviewLiteJsApi. Or, even if they are, other classes
- // call
- // them to JalviewLite directly. Some may not be necessary, but they have
- // to
- // be at least mentioned here, or the classes calling them should
- // reference
- // JalviewLite itself.
-
- private boolean alignPDBStructures; // From JalviewLite; not implemented
-
- private Hashtable> jsmessages;
-
- private Hashtable jshashes;
-
- @Override
- public String getParameter(String name)
- {
- return aparser.getAppletValue(name, null);
- }
-
- @Override
- public boolean getDefaultParameter(String name, boolean def)
- {
- String stn;
- return ((stn = getParameter(name)) == null ? def
- : "true".equalsIgnoreCase(stn));
- }
-
- /**
- * Get the applet-like document base even though this is an application.
- */
- @Override
- public URL getDocumentBase()
- {
- return Platform.getDocumentBase();
- }
-
- /**
- * Get the applet-like code base even though this is an application.
- */
- @Override
- public URL getCodeBase()
- {
- return Platform.getCodeBase();
- }
-
- @Override
- public AlignViewportI getViewport()
- {
- return af.getViewport();
- }
-
- /**
- * features
- *
- */
- @Override
- public boolean parseFeaturesFile(String filename,
- DataSourceType protocol)
- {
- return af.parseFeaturesFile(filename, protocol);
- }
-
- /**
- * scorefile
- *
- */
- @Override
- public boolean loadScoreFile(String sScoreFile) throws IOException
- {
- af.loadJalviewDataFile(sScoreFile, null, null, null);
- return true;
- }
-
- /**
- * annotations, jpredfile, jnetfile
- *
- */
- @Override
- public void updateForAnnotations()
- {
- af.updateForAnnotations();
- }
-
- @Override
- public void loadTree(NewickFile fin, String treeFile)
- throws IOException
- {
- // n/a -- already done by standard Jalview command line processing
- }
-
- @Override
- public void setAlignPdbStructures(boolean defaultParameter)
- {
- alignPDBStructures = true;
- }
-
- @Override
- public void newStructureView(PDBEntry pdb, SequenceI[] seqs,
- String[] chains, DataSourceType protocol)
- {
- StructureViewer.launchStructureViewer(af.alignPanel, pdb, seqs);
- }
-
- @Override
- public void setFeatureGroupState(String[] groups, boolean state)
- {
- af.setFeatureGroupState(groups, state);
- }
-
- @Override
- public void alignedStructureView(PDBEntry[] pdb, SequenceI[][] seqs,
- String[][] chains, String[] protocols)
- {
- System.err.println(
- "Jalview applet interface alignedStructureView not implemented");
- }
-
- @Override
- public void newFeatureSettings()
- {
- System.err.println(
- "Jalview applet interface newFeatureSettings not implemented");
- }
-
- private Vector jsExecQueue;
-
- @Override
- public Vector getJsExecQueue(JSFunctionExec exec)
- {
- jsFunctionExec = exec;
- return (jsExecQueue == null ? (jsExecQueue = new Vector<>())
- : jsExecQueue);
- }
-
-// AppletContext deprecated
-//
-// @Override
-// public AppletContext getAppletContext()
-// {
-// // TODO Auto-generated method stub
-// return null;
-// }
-//
- @Override
- public boolean isJsfallbackEnabled()
- {
- // TODO Auto-generated method stub
- return false;
- }
-
- @Override
- public JSObject getJSObject()
- {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public StructureSelectionManagerProvider getStructureSelectionManagerProvider()
- {
- // TODO Q: what exactly is this? BH
- return null;
- }
-
- @Override
- public void updateColoursFromMouseOver(Object source,
- MouseOverStructureListener mouseOverStructureListener)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public Object[] getSelectionForListener(SequenceGroup seqsel,
- ColumnSelection colsel, HiddenColumns hidden,
- SelectionSource source, Object alignFrame)
- {
- return appLoader.getSelectionForListener(getCurrentAlignFrame(),
- seqsel, colsel, hidden, source, alignFrame);
- }
-
- @Override
- public String arrayToSeparatorList(String[] array)
- {
- return appLoader.arrayToSeparatorList(array);
- }
-
- @Override
- public Hashtable getJSHashes()
- {
- return (jshashes == null ? (jshashes = new Hashtable<>())
- : jshashes);
- }
-
- @Override
- public Hashtable> getJSMessages()
- {
- return (jsmessages == null ? (jsmessages = new Hashtable<>())
- : jsmessages);
- }
-
- @Override
- public Object getFrameForSource(VamsasSource source)
- {
- if (source != null)
- {
- AlignFrame af;
- if (source instanceof jalview.gui.AlignViewport
- && source == (af = getCurrentAlignFrame()).getViewport())
- {
- // should be valid if it just generated an event!
- return af;
- }
- // TODO: ensure that if '_af' is specified along with a handler
- // function, then only events from that alignFrame are sent to that
- // function
- }
- return null;
- }
-
- @Override
- public FeatureRenderer getNewFeatureRenderer(AlignViewportI vp)
- {
- return new jalview.gui.FeatureRenderer((AlignmentPanel) vp);
- }
-
- };
-
- appLoader = new JalviewAppLoader(true);
- appLoader.load(app);
- }
-
- /**
- *
- * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences()
- */
- @Override
- public String getSelectedSequences()
- {
- return getSelectedSequencesFrom(getCurrentAlignFrame());
- }
-
- /**
- *
- * @see jalview.bin.JalviewLiteJsApi#getSelectedSequences(java.lang.String)
- */
- @Override
- public String getSelectedSequences(String sep)
- {
- return getSelectedSequencesFrom(getCurrentAlignFrame(), sep);
- }
-
- /**
- *
- * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
- * .AlignFrame)
- */
- @Override
- public String getSelectedSequencesFrom(AlignFrame alf)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- return getSelectedSequencesFrom(alf, null);
- }
-
- /**
- *
- * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
- * .AlignFrame, java.lang.String)
- */
- @Override
- public String getSelectedSequencesFrom(AlignFrame alf, String sep)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- return appLoader.getSelectedSequencesFrom(alf, sep);
+ Jalview.getInstance().currentAlignFrame = currentAlignFrame;
}
- /**
- *
- * @see jalview.bin.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
- * .AlignFrame, java.lang.String)
- */
- @Override
- public void highlight(String sequenceId, String position,
- String alignedPosition)
- {
- highlightIn(null, sequenceId, position, alignedPosition);
- }
-
- @Override
- public void highlightIn(AlignFrame alf, String sequenceId,
- String position, String alignedPosition)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- appLoader.highlightIn(alf, sequenceId, position, alignedPosition);
- }
-
- @Override
- public void select(String sequenceIds, String columns)
- {
- selectIn(getCurrentAlignFrame(), sequenceIds, columns, null);
- }
-
- @Override
- public void select(String sequenceIds, String columns, String sep)
- {
- selectIn(null, sequenceIds, columns, sep);
- }
-
- @Override
- public void selectIn(AlignFrame alf, String sequenceIds, String columns)
- {
- selectIn(alf, sequenceIds, columns, null);
- }
-
- @Override
- public void selectIn(AlignFrame alf, String sequenceIds, String columns,
- String sep)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- appLoader.selectIn(alf, sequenceIds, columns, sep);
- }
-
- @Override
- public String getSelectedSequencesAsAlignment(String format,
- String suffix)
- {
- return getSelectedSequencesAsAlignmentFrom(null, format, suffix);
- }
-
- @Override
- public String getSelectedSequencesAsAlignmentFrom(AlignFrame alf,
- String format, String sep)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format, sep);
- }
-
- @Override
- public String getAlignmentOrder()
- {
- return getAlignmentFrom(getCurrentAlignFrame(), null);
- }
-
- @Override
- public String getAlignmentOrderFrom(AlignFrame alf)
- {
- return getAlignmentFrom(alf, null);
- }
-
- @Override
- public String getAlignmentOrderFrom(AlignFrame alf, String sep)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- return appLoader.getAlignmentOrderFrom(alf, sep);
- }
-
- @Override
- public String orderBy(String order, String undoName)
- {
- return orderBy(order, undoName, null);
- }
-
- @Override
- public String orderBy(String order, String undoName, String sep)
- {
- return orderAlignmentBy(getCurrentAlignFrame(), order, undoName, sep);
- }
-
- @Override
- public String orderAlignmentBy(AlignFrame alf, String order,
- String undoName, String sep)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- return appLoader.orderAlignmentBy(alf, order, undoName, sep);
- }
-
- @Override
- public String getAlignment(String format)
- {
- return getAlignmentFrom(null, format, null);
- }
-
- @Override
- public String getAlignmentFrom(AlignFrame alf, String format)
- {
- return getAlignmentFrom(alf, format, null);
- }
-
- @Override
- public String getAlignment(String format, String suffix)
- {
- return getAlignmentFrom(getCurrentAlignFrame(), format, suffix);
- }
-
- @Override
- public String getAlignmentFrom(AlignFrame alf, String format,
- String suffix)
- {
- return appLoader.getAlignmentFrom(alf, format, suffix);
- }
-
- @Override
- public void loadAnnotation(String annotation)
- {
- loadAnnotationFrom(getCurrentAlignFrame(), annotation);
- }
-
- @Override
- public void loadAnnotationFrom(AlignFrame alf, String annotation)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- appLoader.loadAnnotationFrom(alf, annotation);
- }
-
- @Override
- public void loadFeatures(String features, boolean autoenabledisplay)
- {
- loadFeaturesFrom(currentAlignFrame, features, autoenabledisplay);
- }
-
- @Override
- public boolean loadFeaturesFrom(AlignFrame alf, String features,
- boolean autoenabledisplay)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- return appLoader.loadFeaturesFrom(alf, features, autoenabledisplay);
- }
-
- @Override
- public String getFeatures(String format)
- {
- return getFeaturesFrom(null, format);
- }
-
- @Override
- public String getFeaturesFrom(AlignFrame alf, String format)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- return appLoader.getFeaturesFrom(alf, format);
- }
-
- @Override
- public String getAnnotation()
- {
- return getAnnotationFrom(null);
- }
-
- @Override
- public String getAnnotationFrom(AlignFrame alf)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- return appLoader.getAnnotationFrom(alf);
- }
-
- // @Override
- // public AlignFrame newView()
- // {
- // return newViewFrom(null, null);
- // }
- //
- // @Override
- // public AlignFrame newView(String name)
- // {
- // return newViewFrom(null, name);
- // }
- //
- // @Override
- // public AlignFrame newViewFrom(AlignFrame alf)
- // {
- // return newViewFrom(alf, null);
- // }
- //
- // @Override
- // public AlignFrame newViewFrom(AlignFrame alf, String name)
- // {
- // if (alf == null)
- // {
- // alf = getCurrentAlignFrame();
- // }
- // return appLoader.newViewFrom(alf, name);
- // }
-
- @Override
- public AlignFrame loadAlignment(String text, String title)
- {
- return appLoader.loadAlignment(text, AlignFrame.DEFAULT_WIDTH,
- AlignFrame.DEFAULT_HEIGHT, title);
- }
-
- @Override
- public boolean addPdbFile(AlignFrame alFrame, String sequenceId,
- String pdbEntryString, String pdbFile)
- {
- if (alFrame == null)
- {
- alFrame = getCurrentAlignFrame();
- }
- return appLoader.addPdbFile(alFrame, sequenceId, pdbEntryString,
- pdbFile);
- }
-
- @Override
- public void scrollViewToIn(AlignFrame alf, String topRow,
- String leftHandColumn)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- appLoader.scrollViewToIn(alf, topRow, leftHandColumn);
- }
-
- @Override
- public void scrollViewToRowIn(AlignFrame alf, String topRow)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- appLoader.scrollViewToRowIn(alf, topRow);
- }
-
- @Override
- public void scrollViewToColumnIn(AlignFrame alf, String leftHandColumn)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- appLoader.scrollViewToColumnIn(alf, leftHandColumn);
- }
-
- @Override
- public String getFeatureGroups()
- {
- return getFeatureGroupsOn(null);
- }
-
- @Override
- public String getFeatureGroupsOn(AlignFrame alf)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- return appLoader.getFeatureGroupsOn(alf);
- }
-
- @Override
- public String getFeatureGroupsOfState(boolean visible)
- {
- return getFeatureGroupsOfStateOn(null, visible);
- }
-
- @Override
- public String getFeatureGroupsOfStateOn(AlignFrame alf, boolean visible)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- return appLoader.getFeatureGroupsOfStateOn(alf, visible);
- }
-
- @Override
- public void setFeatureGroupState(String groups, boolean state)
- { // JalviewLite API
- setFeatureGroupStateOn(null, groups, state);
- }
-
- @Override
- public void setFeatureGroupStateOn(AlignFrame alf, String groups,
- boolean state)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- appLoader.setFeatureGroupStateOn(alf, groups, state);
- }
-
- @Override
- public String getSeparator()
- {
- return appLoader.getSeparator();
- }
-
- @Override
- public void setSeparator(String separator)
- {
- appLoader.setSeparator(separator);
- }
-
- @Override
- public String getJsMessage(String messageclass, String viewId)
- {
- // see http://www.jalview.org/examples/jalviewLiteJs.html
- return null;
- }
-
- /**
- * Open a new Tree panel on the desktop statically. Params are standard (not
- * set by Groovy). No dialog is opened.
- *
- * @param af
- * @param treeType
- * @param modelName
- * @return null, or the string "label.you_need_at_least_n_sequences" if number
- * of sequences selected is inappropriate
- */
- @Override
- public Object openTreePanel(AlignFrame af, String treeType,
- String modelName)
- { // JalviewJS api
- if (af == null)
- {
- af = getCurrentAlignFrame();
- }
- return CalculationChooser.openTreePanel(af, treeType, modelName, null);
- }
-
- /**
- * public static method for JalviewJS API to open a PCAPanel without
- * necessarily using a dialog.
- *
- * @param af
- * @param modelName
- * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
- * if number of sequences selected is inappropriate
- */
- @Override
- public Object openPcaPanel(AlignFrame af, String modelName)
- {
- if (af == null)
- {
- af = getCurrentAlignFrame();
- }
- return CalculationChooser.openPcaPanel(af, modelName, null);
- }
-
- @Override
- public String getSelectedSequencesAsAlignment(String format,
- boolean suffix)
- {
- return getSelectedSequencesAsAlignmentFrom(null, format, suffix);
- }
-
- @Override
- public String getSelectedSequencesAsAlignmentFrom(AlignFrame alf,
- String format, boolean suffix)
- {
- if (alf == null)
- {
- alf = getCurrentAlignFrame();
- }
- return appLoader.getSelectedSequencesAsAlignmentFrom(alf, format,
- "" + suffix);
- }
-
- @Override
- public String arrayToSeparatorList(String[] array)
- {
- return appLoader.arrayToSeparatorList(array);
- }
-
- @Override
- public String[] separatorListToArray(String list)
- {
- return appLoader.separatorListToArray(list);
- }
-
- //// probably not needed in JalviewJS -- From when Jmol and Jalview did not
- //// have a direct connection?
-
- @Override
- public void setMouseoverListener(String listener)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void setMouseoverListener(AlignFrame af, String listener)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void setSelectionListener(String listener)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void setSelectionListener(AlignFrame af, String listener)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void setStructureListener(String listener, String modelSet)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void removeJavascriptListener(AlignFrame af, String listener)
+
+ public void notifyWorker(AlignCalcWorkerI worker, String status)
{
- // TODO Auto-generated method stub
-
+ // System.out.println("Jalview worker " + worker.getClass().getSimpleName()
+ // + " " + status);
}
- @Override
- public void mouseOverStructure(String pdbResNum, String chain,
- String pdbfile)
- {
- // TODO Auto-generated method stub
- }
+ private static boolean isInteractive = true;
- @Override
- public void showOverview()
+ public static boolean isInteractive()
{
- currentAlignFrame.overviewMenuItem_actionPerformed(null);
+ return isInteractive;
}
- public void notifyWorker(AlignCalcWorkerI worker, String status)
+ public static void setInteractive(boolean tf)
{
- // System.out.println("Jalview worker " + worker.getClass().getSimpleName()
- // + " " + status);
+ isInteractive = tf;
}
}
diff --git a/src/jalview/bin/JalviewAppLoader.java b/src/jalview/bin/JalviewAppLoader.java
deleted file mode 100644
index 1cdeaec..0000000
--- a/src/jalview/bin/JalviewAppLoader.java
+++ /dev/null
@@ -1,1500 +0,0 @@
-package jalview.bin;
-
-import jalview.api.JalviewApp;
-import jalview.api.StructureSelectionManagerProvider;
-import jalview.datamodel.Alignment;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.AlignmentOrder;
-import jalview.datamodel.ColumnSelection;
-import jalview.datamodel.HiddenColumns;
-import jalview.datamodel.PDBEntry;
-import jalview.datamodel.Sequence;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
-import jalview.gui.AlignFrame;
-import jalview.gui.AlignViewport;
-import jalview.gui.Desktop;
-import jalview.io.AnnotationFile;
-import jalview.io.AppletFormatAdapter;
-import jalview.io.DataSourceType;
-import jalview.io.FeaturesFile;
-import jalview.io.FileFormat;
-import jalview.io.FileFormatI;
-import jalview.io.FileFormats;
-import jalview.io.IdentifyFile;
-import jalview.io.JPredFile;
-import jalview.io.JnetAnnotationMaker;
-import jalview.io.NewickFile;
-import jalview.structure.SelectionSource;
-import jalview.structure.StructureSelectionManager;
-import jalview.util.HttpUtils;
-import jalview.util.MessageManager;
-
-import java.awt.EventQueue;
-import java.io.IOException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringTokenizer;
-import java.util.Vector;
-
-/**
- * A class to load parameters for either JalviewLite or Jalview
- *
- * @author hansonr
- *
- */
-public class JalviewAppLoader
-{
-
- private JalviewApp app; // Jalview or JalviewJS or JalviewLite
-
- private boolean debug;
-
- String separator = "\u00AC"; // JalviewLite note: the default used to
- // be '|', but many sequence IDS include
- // pipes.
-
- public String getSeparator()
- {
- return separator;
- }
-
- public void setSeparator(String separator)
- {
- this.separator = separator;
- }
-
- public JalviewAppLoader(boolean debug)
- {
- this.debug = debug;
- }
-
- public void load(JalviewApp app)
- {
-
- this.app = app;
-
- String sep = app.getParameter("separator");
- if (sep != null)
- {
- if (sep.length() > 0)
- {
- separator = sep;
- }
- else
- {
- throw new Error(MessageManager
- .getString("error.invalid_separator_parameter"));
- }
- }
-
- loadTree();
- loadScoreFile();
- loadFeatures();
- loadAnnotations();
- loadJnetFile();
- loadPdbFiles();
- callInitCallback();
- }
-
- /**
- * Load PDBFiles if any specified by parameter(s). Returns true if loaded,
- * else false.
- *
- * @param loaderFrame
- * @return
- */
- protected boolean loadPdbFiles()
- {
- boolean result = false;
- /*
- * Undocumented for 2.6 -
- * related to JAL-434
- */
-
- boolean doAlign = app.getDefaultParameter("alignpdbfiles", false);
- app.setAlignPdbStructures(doAlign);
- /*
- *
- *
- *
- *
- *
- */
-
- // Accumulate pdbs here if they are heading for the same view (if
- // alignPdbStructures is true)
- Vector pdbs = new Vector<>();
- // create a lazy matcher if we're asked to
- jalview.analysis.SequenceIdMatcher matcher = (app
- .getDefaultParameter("relaxedidmatch", false))
- ? new jalview.analysis.SequenceIdMatcher(
- app.getViewport().getAlignment()
- .getSequencesArray())
- : null;
-
- int pdbFileCount = 0;
- String param;
- do
- {
- if (pdbFileCount > 0)
- {
- param = app.getParameter("PDBFILE" + pdbFileCount);
- }
- else
- {
- param = app.getParameter("PDBFILE");
- }
-
- if (param != null)
- {
- PDBEntry pdb = new PDBEntry();
-
- String seqstring;
- SequenceI[] seqs = null;
- String[] chains = null;
-
- StringTokenizer st = new StringTokenizer(param, " ");
-
- if (st.countTokens() < 2)
- {
- String sequence = app.getParameter("PDBSEQ");
- if (sequence != null)
- {
- seqs = new SequenceI[] { matcher == null
- ? (Sequence) app.getViewport().getAlignment()
- .findName(sequence)
- : matcher.findIdMatch(sequence) };
- }
-
- }
- else
- {
- param = st.nextToken();
- List tmp = new ArrayList<>();
- List tmp2 = new ArrayList<>();
-
- while (st.hasMoreTokens())
- {
- seqstring = st.nextToken();
- StringTokenizer st2 = new StringTokenizer(seqstring, "=");
- if (st2.countTokens() > 1)
- {
- // This is the chain
- tmp2.add(st2.nextToken());
- seqstring = st2.nextToken();
- }
- tmp.add(matcher == null
- ? (Sequence) app.getViewport().getAlignment()
- .findName(seqstring)
- : matcher.findIdMatch(seqstring));
- }
-
- seqs = tmp.toArray(new SequenceI[tmp.size()]);
- if (tmp2.size() == tmp.size())
- {
- chains = tmp2.toArray(new String[tmp2.size()]);
- }
- }
- pdb.setId(param);
- ret[0] = param;
- DataSourceType protocol = resolveFileProtocol(app, ret);
- // TODO check JAL-357 for files in a jar (CLASSLOADER)
- pdb.setFile(ret[0]);
-
- if (seqs != null)
- {
- for (int i = 0; i < seqs.length; i++)
- {
- if (seqs[i] != null)
- {
- ((Sequence) seqs[i]).addPDBId(pdb);
- StructureSelectionManager
- .getStructureSelectionManager(
- (StructureSelectionManagerProvider) app)
- .registerPDBEntry(pdb);
- }
- else
- {
- if (debug)
- {
- // this may not really be a problem but we give a warning
- // anyway
- System.err.println(
- "Warning: Possible input parsing error: Null sequence for attachment of PDB (sequence "
- + i + ")");
- }
- }
- }
-
- if (doAlign)
- {
- pdbs.addElement(new Object[] { pdb, seqs, chains, protocol });
- }
- else
- {
- app.newStructureView(pdb, seqs, chains, protocol);
- }
- }
- }
-
- pdbFileCount++;
- } while (param != null || pdbFileCount < 10);
- if (pdbs.size() > 0)
- {
- SequenceI[][] seqs = new SequenceI[pdbs.size()][];
- PDBEntry[] pdb = new PDBEntry[pdbs.size()];
- String[][] chains = new String[pdbs.size()][];
- String[] protocols = new String[pdbs.size()];
- for (int pdbsi = 0, pdbsiSize = pdbs
- .size(); pdbsi < pdbsiSize; pdbsi++)
- {
- Object[] o = pdbs.elementAt(pdbsi);
- pdb[pdbsi] = (PDBEntry) o[0];
- seqs[pdbsi] = (SequenceI[]) o[1];
- chains[pdbsi] = (String[]) o[2];
- protocols[pdbsi] = (String) o[3];
- }
- app.alignedStructureView(pdb, seqs, chains, protocols);
- result = true;
- }
- return result;
- }
-
- /**
- * Load in a Jnetfile if specified by parameter. Returns true if loaded, else
- * false.
- *
- * @param alignFrame
- * @return
- */
- protected boolean loadJnetFile()
- {
- boolean result = false;
- String param = app.getParameter("jnetfile");
- if (param == null)
- {
- // jnet became jpred around 2016
- param = app.getParameter("jpredfile");
- }
- if (param != null)
- {
- try
- {
- ret[0] = param;
- DataSourceType protocol = resolveFileProtocol(app, ret);
- JPredFile predictions = new JPredFile(ret[0], protocol);
- JnetAnnotationMaker.add_annotation(predictions,
- app.getViewport().getAlignment(), 0, false);
- // false == do not add sequence profile from concise output
- app.getViewport().getAlignment().setupJPredAlignment();
- app.updateForAnnotations();
- result = true;
- } catch (Exception ex)
- {
- ex.printStackTrace();
- }
- }
- return result;
- }
-
- /**
- * Load annotations if specified by parameter. Returns true if loaded, else
- * false.
- *
- * @param alignFrame
- * @return
- */
- protected boolean loadAnnotations()
- {
- boolean result = false;
- String param = app.getParameter("annotations");
- if (param != null)
- {
- ret[0] = param;
- DataSourceType protocol = resolveFileProtocol(app, ret);
- param = ret[0];
- if (new AnnotationFile().annotateAlignmentView(app.getViewport(),
- param, protocol))
- {
- app.updateForAnnotations();
- result = true;
- }
- else
- {
- System.err
- .println("Annotations were not added from annotation file '"
- + param + "'");
- }
- }
- return result;
- }
-
- /**
- * Load features file and view settings as specified by parameters. Returns
- * true if features were loaded, else false.
- *
- * @param alignFrame
- * @return
- */
- protected boolean loadFeatures()
- {
- boolean result = false;
- // ///////////////////////////
- // modify display of features
- // we do this before any features have been loaded, ensuring any hidden
- // groups are hidden when features first displayed
- //
- // hide specific groups
- //
- String param = app.getParameter("hidefeaturegroups");
- if (param != null)
- {
- app.setFeatureGroupState(separatorListToArray(param, separator),
- false);
- // app.setFeatureGroupStateOn(newAlignFrame, param, false);
- }
- // show specific groups
- param = app.getParameter("showfeaturegroups");
- if (param != null)
- {
- app.setFeatureGroupState(separatorListToArray(param, separator),
- true);
- // app.setFeatureGroupStateOn(newAlignFrame, param, true);
- }
- // and now load features
- param = app.getParameter("features");
- if (param != null)
- {
- ret[0] = param;
- DataSourceType protocol = resolveFileProtocol(app, ret);
-
- result = app.parseFeaturesFile(ret[0], protocol);
- }
-
- param = app.getParameter("showFeatureSettings");
- if (param != null && param.equalsIgnoreCase("true"))
- {
- app.newFeatureSettings();
- }
- return result;
- }
-
- /**
- * Load a score file if specified by parameter. Returns true if file was
- * loaded, else false.
- *
- * @param loaderFrame
- */
- protected boolean loadScoreFile()
- {
- boolean result = false;
- String sScoreFile = app.getParameter("scoreFile");
- if (sScoreFile != null && !"".equals(sScoreFile))
- {
- try
- {
- if (debug)
- {
- System.err.println(
- "Attempting to load T-COFFEE score file from the scoreFile parameter");
- }
- result = app.loadScoreFile(sScoreFile);
- if (!result)
- {
- System.err.println(
- "Failed to parse T-COFFEE parameter as a valid score file ('"
- + sScoreFile + "')");
- }
- } catch (Exception e)
- {
- System.err.printf("Cannot read score file: '%s'. Cause: %s \n",
- sScoreFile, e.getMessage());
- }
- }
- return result;
- }
-
- String[] ret = new String[1];
-
- /**
- * Load a tree for the alignment if specified by parameter. Returns true if a
- * tree was loaded, else false.
- *
- * @param loaderFrame
- * @return
- */
- protected boolean loadTree()
- {
- boolean result = false;
- String treeFile = app.getParameter("tree");
- if (treeFile == null)
- {
- treeFile = app.getParameter("treeFile");
- }
-
- if (treeFile != null)
- {
- try
- {
- ret[0] = treeFile;
- NewickFile fin = new NewickFile(treeFile,
- resolveFileProtocol(app, ret));
- fin.parse();
-
- if (fin.getTree() != null)
- {
- app.loadTree(fin, ret[0]);
- result = true;
- if (debug)
- {
- System.out.println("Successfully imported tree.");
- }
- }
- else
- {
- if (debug)
- {
- System.out.println(
- "Tree parameter did not resolve to a valid tree.");
- }
- }
- } catch (Exception ex)
- {
- ex.printStackTrace();
- }
- }
- return result;
- }
-
- /**
- * form a complete URL given a path to a resource and a reference location on
- * the same server
- *
- * @param targetPath
- * - an absolute path on the same server as localref or a document
- * located relative to localref
- * @param localref
- * - a URL on the same server as url
- * @return a complete URL for the resource located by url
- */
- public static String resolveUrlForLocalOrAbsolute(String targetPath,
- URL localref)
- {
- String resolvedPath = "";
- if (targetPath.startsWith("/"))
- {
- String codebase = localref.toString();
- String localfile = localref.getFile();
- resolvedPath = codebase.substring(0,
- codebase.length() - localfile.length()) + targetPath;
- return resolvedPath;
- }
-
- /*
- * get URL path and strip off any trailing file e.g.
- * www.jalview.org/examples/index.html#applets?a=b is trimmed to
- * www.jalview.org/examples/
- */
- String urlPath = localref.toString();
- String directoryPath = urlPath;
- int lastSeparator = directoryPath.lastIndexOf("/");
- if (lastSeparator > 0)
- {
- directoryPath = directoryPath.substring(0, lastSeparator + 1);
- }
-
- if (targetPath.startsWith("/"))
- {
- /*
- * construct absolute URL to a file on the server - this is not allowed?
- */
- // String localfile = localref.getFile();
- // resolvedPath = urlPath.substring(0,
- // urlPath.length() - localfile.length())
- // + targetPath;
- resolvedPath = directoryPath + targetPath.substring(1);
- }
- else
- {
- resolvedPath = directoryPath + targetPath;
- }
- // if (debug)
- // {
- // System.err.println(
- // "resolveUrlForLocalOrAbsolute returning " + resolvedPath);
- // }
- return resolvedPath;
- }
-
- /**
- * parse the string into a list
- *
- * @param list
- * @param separator
- * @return elements separated by separator
- */
- public static String[] separatorListToArray(String list, String separator)
- {
- // TODO use StringUtils version (slightly different...)
- int seplen = separator.length();
- if (list == null || list.equals("") || list.equals(separator))
- {
- return null;
- }
- Vector jv = new Vector<>();
- int cp = 0, pos;
- while ((pos = list.indexOf(separator, cp)) > cp)
- {
- jv.addElement(list.substring(cp, pos));
- cp = pos + seplen;
- }
- if (cp < list.length())
- {
- String c = list.substring(cp);
- if (!c.equals(separator))
- {
- jv.addElement(c);
- }
- }
- if (jv.size() > 0)
- {
- String[] v = new String[jv.size()];
- for (int i = 0; i < v.length; i++)
- {
- v[i] = jv.elementAt(i);
- }
- jv.removeAllElements();
- // if (debug)
- // {
- // System.err.println("Array from '" + separator
- // + "' separated List:\n" + v.length);
- // for (int i = 0; i < v.length; i++)
- // {
- // System.err.println("item " + i + " '" + v[i] + "'");
- // }
- // }
- return v;
- }
- // if (debug)
- // {
- // System.err.println(
- // "Empty Array from '" + separator + "' separated List");
- // }
- return null;
- }
-
- public static DataSourceType resolveFileProtocol(JalviewApp app,
- String[] retPath)
- {
- String path = retPath[0];
- /*
- * is it paste data?
- */
- if (path.startsWith("PASTE"))
- {
- retPath[0] = path.substring(5);
- return DataSourceType.PASTE;
- }
-
- /*
- * is it a URL?
- */
- if (path.indexOf("://") >= 0)
- {
- return DataSourceType.URL;
- }
-
- /*
- * try relative to document root
- */
- URL documentBase = app.getDocumentBase();
- String withDocBase = resolveUrlForLocalOrAbsolute(path, documentBase);
- if (HttpUtils.isValidUrl(withDocBase))
- {
- // if (debug)
- // {
- // System.err.println("Prepended document base '" + documentBase
- // + "' to make: '" + withDocBase + "'");
- // }
- retPath[0] = withDocBase;
- return DataSourceType.URL;
- }
-
- /*
- * try relative to codebase (if different to document base)
- */
- URL codeBase = app.getCodeBase();
- String withCodeBase = resolveUrlForLocalOrAbsolute(path, codeBase);
- if (!withCodeBase.equals(withDocBase)
- && HttpUtils.isValidUrl(withCodeBase))
- {
- // if (debug)
- // {
- // System.err.println("Prepended codebase '" + codeBase
- // + "' to make: '" + withCodeBase + "'");
- // }
- retPath[0] = withCodeBase;
- return DataSourceType.URL;
- }
-
- /*
- * try locating by classloader; try this last so files in the directory
- * are resolved using document base
- */
- if (inArchive(app.getClass(), path))
- {
- return DataSourceType.CLASSLOADER;
- }
- return null;
- }
-
- /**
- * Discovers whether the given file is in the Applet Archive
- *
- * @param f
- * String
- * @return boolean
- */
- private static boolean inArchive(Class> c, String f)
- {
- // This might throw a security exception in certain browsers
- // Netscape Communicator for instance.
- try
- {
- boolean rtn = (c.getResourceAsStream("/" + f) != null);
- // if (debug)
- // {
- // System.err.println("Resource '" + f + "' was "
- // + (rtn ? "" : "not ") + "located by classloader.");
- // }
- return rtn;
- } catch (Exception ex)
- {
- System.out.println("Exception checking resources: " + f + " " + ex);
- return false;
- }
- }
-
- public void callInitCallback()
- {
- String initjscallback = app.getParameter("oninit");
- if (initjscallback == null)
- {
- return;
- }
- initjscallback = initjscallback.trim();
- if (initjscallback.length() > 0)
- {
- // TODO
- }
- }
-
- /**
- * read sequence1...sequenceN as a raw alignment
- *
- * @param jalviewApp
- * @return
- */
- public String getPastedSequence(JalviewApp jalviewApp)
- {
- StringBuffer data = new StringBuffer("PASTE");
- int i = 1;
- String file = null;
- while ((file = app.getParameter("sequence" + i)) != null)
- {
- data.append(file.toString() + "\n");
- i++;
- }
- if (data.length() > 5)
- {
- file = data.toString();
- }
- return file;
- }
-
- /**
- * concatenate the list with separator
- *
- * @param list
- * @param separator
- * @return concatenated string
- */
- public static String arrayToSeparatorList(String[] list, String separator)
- {
- // TODO use StringUtils version
- StringBuffer v = new StringBuffer();
- if (list != null && list.length > 0)
- {
- for (int i = 0, iSize = list.length; i < iSize; i++)
- {
- if (list[i] != null)
- {
- if (i > 0)
- {
- v.append(separator);
- }
- v.append(list[i]);
- }
- }
- // if (debug)
- // {
- // System.err
- // .println("Returning '" + separator + "' separated List:\n");
- // System.err.println(v);
- // }
- return v.toString();
- }
- // if (debug)
- // {
- // System.err.println(
- // "Returning empty '" + separator + "' separated List\n");
- // }
- return "" + separator;
- }
-
- public String arrayToSeparatorList(String[] array)
- {
- return arrayToSeparatorList(array, separator);
- }
-
- public String getSelectedSequencesFrom(AlignFrame alf, String sep)
- {
- StringBuffer result = new StringBuffer("");
- if (sep == null || sep.length() == 0)
- {
- sep = separator; // "+0x00AC;
- }
- AlignViewport v = alf.getViewport();
- if (v.getSelectionGroup() != null)
- {
- SequenceI[] seqs = v.getSelectionGroup()
- .getSequencesInOrder(v.getAlignment());
-
- for (int i = 0; i < seqs.length; i++)
- {
- result.append(seqs[i].getName());
- result.append(sep);
- }
- }
-
- return result.toString();
- }
-
- public void setFeatureGroupStateOn(final AlignFrame alf,
- final String groups, boolean state)
- {
- java.awt.EventQueue.invokeLater(new Runnable()
- {
- @Override
- public void run()
- {
- alf.setFeatureGroupState(
- separatorListToArray(groups, separator), state);
- }
- });
- }
-
- public String getFeatureGroupsOfStateOn(AlignFrame alf, boolean visible)
- {
- return arrayToSeparatorList(
- alf.getFeatureGroupsOfState(visible));
- }
-
- public void scrollViewToIn(final AlignFrame alf, final String topRow,
- final String leftHandColumn)
- {
- // TODO test
- java.awt.EventQueue.invokeLater(new Runnable()
- {
- @Override
- public void run()
- {
- try
- {
- alf.scrollTo(Integer.valueOf(topRow).intValue(),
- Integer.valueOf(leftHandColumn).intValue());
-
- } catch (Exception ex)
- {
- System.err.println("Couldn't parse integer arguments (topRow='"
- + topRow + "' and leftHandColumn='" + leftHandColumn
- + "')");
- ex.printStackTrace();
- }
- }
- });
- }
-
- public void scrollViewToRowIn(final AlignFrame alf, final String topRow)
- {
- // TODO test
-
- java.awt.EventQueue.invokeLater(new Runnable()
- {
- @Override
- public void run()
- {
- try
- {
- alf.scrollToRow(Integer.valueOf(topRow).intValue());
-
- } catch (Exception ex)
- {
- System.err.println("Couldn't parse integer arguments (topRow='"
- + topRow + "')");
- ex.printStackTrace();
- }
-
- }
- });
- }
-
- public void scrollViewToColumnIn(final AlignFrame alf,
- final String leftHandColumn)
- {
- // TODO test
- java.awt.EventQueue.invokeLater(new Runnable()
- {
-
- @Override
- public void run()
- {
- try
- {
- alf
- .scrollToColumn(Integer.valueOf(leftHandColumn).intValue());
-
- } catch (Exception ex)
- {
- System.err.println(
- "Couldn't parse integer arguments (leftHandColumn='"
- + leftHandColumn + "')");
- ex.printStackTrace();
- }
- }
- });
-
- }
-
- public boolean addPdbFile(AlignFrame alf, String sequenceId,
- String pdbEntryString, String pdbFile)
- {
- AlignFrame alFrame = alf;
- SequenceI toaddpdb = alFrame.getViewport().getAlignment()
- .findName(sequenceId);
- boolean needtoadd = false;
- if (toaddpdb != null)
- {
- Vector pdbe = toaddpdb.getAllPDBEntries();
- PDBEntry pdbentry = null;
- if (pdbe != null && pdbe.size() > 0)
- {
- for (int pe = 0, peSize = pdbe.size(); pe < peSize; pe++)
- {
- pdbentry = pdbe.elementAt(pe);
- if (!pdbentry.getId().equals(pdbEntryString)
- && !pdbentry.getFile().equals(pdbFile))
- {
- pdbentry = null;
- }
- else
- {
- continue;
- }
- }
- }
- if (pdbentry == null)
- {
- pdbentry = new PDBEntry();
- pdbentry.setId(pdbEntryString);
- pdbentry.setFile(pdbFile);
- needtoadd = true; // add this new entry to sequence.
- }
- // resolve data source
- // TODO: this code should be a refactored to an io package
- DataSourceType protocol = AppletFormatAdapter.resolveProtocol(pdbFile,
- FileFormat.PDB);
- if (protocol == null)
- {
- return false;
- }
- if (needtoadd)
- {
- pdbentry.setProperty("protocol", protocol);
- toaddpdb.addPDBId(pdbentry);
- alFrame.alignPanel.getStructureSelectionManager()
- .registerPDBEntry(pdbentry);
- }
- }
- return true;
- }
-
- public AlignFrame loadAlignment(String text, int width, int height,
- String title)
- {
- AlignmentI al = null;
-
- try
- {
- FileFormatI format = new IdentifyFile().identify(text,
- DataSourceType.PASTE);
- al = new AppletFormatAdapter().readFile(text, DataSourceType.PASTE,
- format);
- if (al.getHeight() > 0)
- {
- return new AlignFrame(al, width, height, title);
- }
- } catch (IOException ex)
- {
- ex.printStackTrace();
- }
- return null;
- }
-
- public String getFeatureGroupsOn(AlignFrame alf)
- {
- return arrayToSeparatorList(
- alf.getFeatureGroups());
- }
-
- public void highlightIn(final AlignFrame alf, final String sequenceId,
- final String position, final String alignedPosition)
- {
- // TODO: could try to highlight in all alignments if alf==null
- jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
- alf.getViewport().getAlignment()
- .getSequencesArray());
- final SequenceI sq = matcher.findIdMatch(sequenceId);
- if (sq != null)
- {
- int apos = -1;
- try
- {
- apos = Integer.valueOf(position).intValue();
- apos--;
- } catch (NumberFormatException ex)
- {
- return;
- }
- final int pos = apos;
- // use vamsas listener to broadcast to all listeners in scope
- if (alignedPosition != null && (alignedPosition.trim().length() == 0
- || alignedPosition.toLowerCase().indexOf("false") > -1))
- {
- java.awt.EventQueue.invokeLater(new Runnable()
- {
- @Override
- public void run()
- {
- StructureSelectionManager
- .getStructureSelectionManager(Desktop.getInstance())
- .mouseOverVamsasSequence(sq, sq.findIndex(pos), null);
- }
- });
- }
- else
- {
- java.awt.EventQueue.invokeLater(new Runnable()
- {
- @Override
- public void run()
- {
- StructureSelectionManager
- .getStructureSelectionManager(Desktop.getInstance())
- .mouseOverVamsasSequence(sq, pos, null);
- }
- });
- }
- }
- }
-
- public void selectIn(final AlignFrame alf, String sequenceIds,
- String columns, String sep)
- {
- if (sep == null || sep.length() == 0)
- {
- sep = separator;
- }
- else
- {
- if (debug)
- {
- System.err.println("Selecting region using separator string '"
- + separator + "'");
- }
- }
- // deparse fields
- String[] ids = JalviewAppLoader.separatorListToArray(sequenceIds, sep);
- String[] cols = JalviewAppLoader.separatorListToArray(columns, sep);
- final SequenceGroup sel = new SequenceGroup();
- final ColumnSelection csel = new ColumnSelection();
- AlignmentI al = alf.getViewport().getAlignment();
- jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
- alf.getViewport().getAlignment()
- .getSequencesArray());
- int start = 0, end = al.getWidth(), alw = al.getWidth();
- boolean seqsfound = true;
- if (ids != null && ids.length > 0)
- {
- seqsfound = false;
- for (int i = 0; i < ids.length; i++)
- {
- if (ids[i].trim().length() == 0)
- {
- continue;
- }
- SequenceI sq = matcher.findIdMatch(ids[i]);
- if (sq != null)
- {
- seqsfound = true;
- sel.addSequence(sq, false);
- }
- }
- }
- boolean inseqpos = false;
- if (cols != null && cols.length > 0)
- {
- boolean seset = false;
- for (int i = 0; i < cols.length; i++)
- {
- String cl = cols[i].trim();
- if (cl.length() == 0)
- {
- continue;
- }
- int p;
- if ((p = cl.indexOf("-")) > -1)
- {
- int from = -1, to = -1;
- try
- {
- from = Integer.valueOf(cl.substring(0, p)).intValue();
- from--;
- } catch (NumberFormatException ex)
- {
- System.err.println(
- "ERROR: Couldn't parse first integer in range element column selection string '"
- + cl + "' - format is 'from-to'");
- return;
- }
- try
- {
- to = Integer.valueOf(cl.substring(p + 1)).intValue();
- to--;
- } catch (NumberFormatException ex)
- {
- System.err.println(
- "ERROR: Couldn't parse second integer in range element column selection string '"
- + cl + "' - format is 'from-to'");
- return;
- }
- if (from >= 0 && to >= 0)
- {
- // valid range
- if (from < to)
- {
- int t = to;
- to = from;
- to = t;
- }
- if (!seset)
- {
- start = from;
- end = to;
- seset = true;
- }
- else
- {
- // comment to prevent range extension
- if (start > from)
- {
- start = from;
- }
- if (end < to)
- {
- end = to;
- }
- }
- for (int r = from; r <= to; r++)
- {
- if (r >= 0 && r < alw)
- {
- csel.addElement(r);
- }
- }
- if (debug)
- {
- System.err.println("Range '" + cl + "' deparsed as [" + from
- + "," + to + "]");
- }
- }
- else
- {
- System.err.println("ERROR: Invalid Range '" + cl
- + "' deparsed as [" + from + "," + to + "]");
- }
- }
- else
- {
- int r = -1;
- try
- {
- r = Integer.valueOf(cl).intValue();
- r--;
- } catch (NumberFormatException ex)
- {
- if (cl.toLowerCase().equals("sequence"))
- {
- // we are in the dataset sequence's coordinate frame.
- inseqpos = true;
- }
- else
- {
- System.err.println(
- "ERROR: Couldn't parse integer from point selection element of column selection string '"
- + cl + "'");
- return;
- }
- }
- if (r >= 0 && r <= alw)
- {
- if (!seset)
- {
- start = r;
- end = r;
- seset = true;
- }
- else
- {
- // comment to prevent range extension
- if (start > r)
- {
- start = r;
- }
- if (end < r)
- {
- end = r;
- }
- }
- csel.addElement(r);
- if (debug)
- {
- System.err.println("Point selection '" + cl
- + "' deparsed as [" + r + "]");
- }
- }
- else
- {
- System.err.println("ERROR: Invalid Point selection '" + cl
- + "' deparsed as [" + r + "]");
- }
- }
- }
- }
- if (seqsfound)
- {
- // we only propagate the selection when it was the null selection, or the
- // given sequences were found in the alignment.
- if (inseqpos && sel.getSize() > 0)
- {
- // assume first sequence provides reference frame ?
- SequenceI rs = sel.getSequenceAt(0);
- start = rs.findIndex(start);
- end = rs.findIndex(end);
- List cs = new ArrayList<>(csel.getSelected());
- csel.clear();
- for (Integer selectedCol : cs)
- {
- csel.addElement(rs.findIndex(selectedCol));
- }
- }
- sel.setStartRes(start);
- sel.setEndRes(end);
- EventQueue.invokeLater(new Runnable()
- {
- @Override
- public void run()
- {
- alf.select(sel, csel, alf
- .getCurrentView().getAlignment().getHiddenColumns());
- }
- });
- }
- }
-
- public String getAlignmentOrderFrom(AlignFrame alf, String sep)
- {
- AlignmentI alorder = alf.getViewport().getAlignment();
- String[] order = new String[alorder.getHeight()];
- for (int i = 0; i < order.length; i++)
- {
- order[i] = alorder.getSequenceAt(i).getName();
- }
- return arrayToSeparatorList(order, sep);
- }
-
- public String getSelectedSequencesAsAlignmentFrom(AlignFrame alf,
- String format, String suffix)
- {
- try
- {
- AlignViewport vp = alf.getViewport();
- FileFormatI theFormat = FileFormats.getInstance().forName(format);
- boolean seqlimits = (suffix == null
- || suffix.equalsIgnoreCase("true"));
- if (vp.getSelectionGroup() != null)
- {
- // JBPNote: getSelectionAsNewSequence behaviour has changed - this
- // method now returns a full copy of sequence data
- // TODO consider using getSequenceSelection instead here
- String reply = new AppletFormatAdapter().formatSequences(theFormat,
- new Alignment(vp.getSelectionAsNewSequence()),
- seqlimits);
- return reply;
- }
- } catch (IllegalArgumentException ex)
- {
- ex.printStackTrace();
- return "Error retrieving alignment, possibly invalid format specifier: "
- + format;
- }
- return "";
- }
-
- public String orderAlignmentBy(AlignFrame alf, String order,
- String undoName, String sep)
- {
- if (sep == null || sep.length() == 0)
- {
- sep = separator;
- }
- String[] ids = JalviewAppLoader.separatorListToArray(order, sep);
- SequenceI[] sqs = null;
- if (ids != null && ids.length > 0)
- {
- jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
- alf.getViewport().getAlignment()
- .getSequencesArray());
- int s = 0;
- sqs = new SequenceI[ids.length];
- for (int i = 0; i < ids.length; i++)
- {
- if (ids[i].trim().length() == 0)
- {
- continue;
- }
- SequenceI sq = matcher.findIdMatch(ids[i]);
- if (sq != null)
- {
- sqs[s++] = sq;
- }
- }
- if (s > 0)
- {
- SequenceI[] sqq = new SequenceI[s];
- System.arraycopy(sqs, 0, sqq, 0, s);
- sqs = sqq;
- }
- else
- {
- sqs = null;
- }
- }
- if (sqs == null)
- {
- return "";
- }
- ;
- final AlignmentOrder aorder = new AlignmentOrder(sqs);
-
- if (undoName != null && undoName.trim().length() == 0)
- {
- undoName = null;
- }
- final String _undoName = undoName;
- // TODO: deal with synchronization here: cannot raise any events until after
- // this has returned.
- return alf.sortBy(aorder, _undoName) ? "true" : "";
- }
-
- public String getAlignmentFrom(AlignFrame alf, String format,
- String suffix)
- {
- try
- {
- boolean seqlimits = (suffix == null
- || suffix.equalsIgnoreCase("true"));
-
- FileFormatI theFormat = FileFormats.getInstance().forName(format);
- String reply = new AppletFormatAdapter().formatSequences(theFormat,
- alf.getViewport().getAlignment(), seqlimits);
- return reply;
- } catch (IllegalArgumentException ex)
- {
- ex.printStackTrace();
- return "Error retrieving alignment, possibly invalid format specifier: "
- + format;
- }
- }
-
- public void loadAnnotationFrom(AlignFrame alf, String annotation)
- {
- if (new AnnotationFile().annotateAlignmentView(
- alf.getViewport(), annotation,
- DataSourceType.PASTE))
- {
- alf.alignPanel.fontChanged();
- alf.alignPanel.setScrollValues(0, 0);
- }
- else
- {
- alf.parseFeaturesFile(annotation,
- DataSourceType.PASTE);
- }
- }
-
- public boolean loadFeaturesFrom(AlignFrame alf, String features,
- boolean autoenabledisplay)
- {
- boolean ret = alf.parseFeaturesFile(features,
- DataSourceType.PASTE);
- if (!ret)
- {
- return false;
- }
- if (autoenabledisplay)
- {
- alf.getViewport().setShowSequenceFeatures(true);
- // this next was for a checkbox in JalviewLite
- // ((AlignFrame) alf).getViewport().sequenceFeatures.setState(true);
- }
- return true;
- }
-
- /**
- * JavaScript interface to print the alignment frame
- *
- * @param alf
- * @param format
- * "jalview" or "gff" with or without ";includeComplement" or
- * ";includeNonpositional"; default with no ";" is
- * ";includeNonpositional"
- * @return
- */
- public String getFeaturesFrom(AlignFrame alf, String format)
- {
- AlignFrame f = (alf);
-
- String features;
- FeaturesFile formatter = new FeaturesFile();
- format = format.toLowerCase();
- if (format.indexOf(";") < 0)
- format += ";includenonpositional";
- boolean nonpos = format.indexOf(";includenonpositional") > 0;
- boolean compl = format.indexOf(";includecomplement") >= 0;
- if (format.startsWith("jalview"))
- {
- features = formatter.printJalviewFormat(
- f.getViewport().getAlignment().getSequencesArray(),
- f.alignPanel.getFeatureRenderer(), nonpos, compl);
- }
- else
- {
- features = formatter.printGffFormat(
- f.getViewport().getAlignment().getSequencesArray(),
- f.alignPanel.getFeatureRenderer(), nonpos, compl);
- }
-
- if (features == null)
- {
- features = "";
- }
- return features;
-
- }
-
- public String getAnnotationFrom(AlignFrame alf)
- {
- AlignFrame f = alf;
- String annotation = new AnnotationFile()
- .printAnnotationsForView(f.getViewport());
- return annotation;
- }
-
- // public AlignFrame newViewFrom(AlignFrame alf, String name)
- // {
- // return (AlignFrame) alf.newView(name, true);
- // }
- //
- public String[] separatorListToArray(String list)
- {
- return separatorListToArray(list, separator);
- }
-
- public Object[] getSelectionForListener(AlignFrame currentFrame,
- SequenceGroup seqsel, ColumnSelection colsel,
- HiddenColumns hidden, SelectionSource source, Object alignFrame)
- {
- // System.err.println("Testing selection event relay to
- // jsfunction:"+_listener);
- String setid = "";
- AlignFrame src = (AlignFrame) alignFrame;
- if (source != null)
- {
- if (source instanceof AlignViewport
- && currentFrame.getViewport() == source)
- {
- // should be valid if it just generated an event!
- src = currentFrame;
-
- }
- }
- String[] seqs = new String[] {};
- String[] cols = new String[] {};
- int strt = 0, end = (src == null) ? -1
- : src.alignPanel.av.getAlignment().getWidth();
- if (seqsel != null && seqsel.getSize() > 0)
- {
- seqs = new String[seqsel.getSize()];
- for (int i = 0; i < seqs.length; i++)
- {
- seqs[i] = seqsel.getSequenceAt(i).getName();
- }
- if (strt < seqsel.getStartRes())
- {
- strt = seqsel.getStartRes();
- }
- if (end == -1 || end > seqsel.getEndRes())
- {
- end = seqsel.getEndRes();
- }
- }
- if (colsel != null && !colsel.isEmpty())
- {
- if (end == -1)
- {
- end = colsel.getMax() + 1;
- }
- cols = new String[colsel.getSelected().size()];
- for (int i = 0; i < cols.length; i++)
- {
- cols[i] = "" + (1 + colsel.getSelected().get(i).intValue());
- }
- }
- else
- {
- if (seqsel != null && seqsel.getSize() > 0)
- {
- // send a valid range, otherwise we send the empty selection
- cols = new String[2];
- cols[0] = "" + (1 + strt) + "-" + (1 + end);
- }
- }
- return new Object[] { src, setid, arrayToSeparatorList(seqs),
- arrayToSeparatorList(cols) };
- }
-
-}
\ No newline at end of file
diff --git a/src/jalview/bin/JalviewJS2.java b/src/jalview/bin/JalviewJS2.java
index 6f69f8a..61b3487 100644
--- a/src/jalview/bin/JalviewJS2.java
+++ b/src/jalview/bin/JalviewJS2.java
@@ -36,11 +36,11 @@ public class JalviewJS2
args = new String[] {
// "headless",
"open", "examples/uniref50.fa",
- "features",
- "examples/exampleFeatures.txt"
- , "noannotation"
- , "showoverview"
- // , "png", "test-bh.png"
+// "features",
+// "examples/exampleFeatures.txt"
+// , "noannotation"
+ //, "showoverview"
+ //, "png", "test-bh.png"
};
}
diff --git a/src/jalview/bin/JalviewJSApi.java b/src/jalview/bin/JalviewJSApi.java
deleted file mode 100644
index a21bebe..0000000
--- a/src/jalview/bin/JalviewJSApi.java
+++ /dev/null
@@ -1,693 +0,0 @@
-package jalview.bin;
-
-import jalview.gui.AlignFrame;
-
-/**
- * JAL-3369 JalviewJS API BH 2019.07.17
- *
- * @author hansonr
- *
- */
-public interface JalviewJSApi
-{
-
- void showOverview();
-
- /**
- * process commandline arguments after the JavaScript application has started
- *
- * @param args
- * @return
- */
- Object parseArguments(String[] args);
-
-
- /**
- * Open a new Tree panel on the desktop statically. Params are standard (not
- * set by Groovy). No dialog is opened.
- *
- * @param af
- * may be null
- * @param treeType
- * @param modelName
- * @return null, or the string "label.you_need_at_least_n_sequences" if number
- * of sequences selected is inappropriate
- */
- public Object openTreePanel(AlignFrame af, String treeType,
- String modelName);
-
- /**
- * public static method for JalviewJS API to open a PCAPanel without
- * necessarily using a dialog.
- *
- * @param af
- * may be null
- * @param modelName
- * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
- * if number of sequences selected is inappropriate
- */
- public Object openPcaPanel(AlignFrame af, String modelName);
-
- /**
- * The following public methods may be called externally, eg via javascript in
- * an HTML page.
- *
- *
- * TODO: introduce abstract interface for
- * jalview.appletgui.AlignFrame
- *
- * Most function arguments are strings, which contain serialised versions of
- * lists. Lists of things are separated by a separator character - either the
- * default or a user supplied one. Ranges and positions on an alignment or
- * sequence can be specified as a list, where an item containing a single
- * number is a single position, and an item like 1-2 specifies columns 1 and 2
- * as a range.
- */
-
- // /**
- // * @author jimp
- // *
- // */
- // public interface JalviewLiteJsApi
- // {
-
- /**
- * @return String list of selected sequence IDs, each terminated by the
- * 'boolean not' character (""+0x00AC); or (¬);
- */
-
- public abstract String getSelectedSequences();
-
- /**
- * @param sep
- * separator string or null for default
- * @return String list of selected sequence IDs, each terminated by given
- * separator string
- */
-
- public abstract String getSelectedSequences(String sep);
-
- /**
- * @param alf
- * AlignFrame containing selection
- * @return String list of selected sequence IDs, each terminated by current
- * default separator sequence
- *
- */
- public abstract String getSelectedSequencesFrom(AlignFrame alf);
-
- /**
- * get list of selected sequence IDs separated by given separator
- *
- * @param alf
- * window containing selection
- * @param sep
- * separator string to use - default is 'boolean not'
- * @return String list of selected sequence IDs, each terminated by the given
- * separator
- */
- public abstract String getSelectedSequencesFrom(AlignFrame alf,
- String sep);
-
- /**
- *
- * @param sequenceId
- * id of sequence to highlight
- * @param position
- * integer position [ tobe implemented or range ] on sequence
- * @param alignedPosition
- * true/false/empty string - indicate if position is an alignment
- * column or unaligned sequence position
- */
-
- public abstract void highlight(String sequenceId, String position,
- String alignedPosition);
-
- /**
- *
- * @param sequenceId
- * id of sequence to highlight
- * @param position
- * integer position [ tobe implemented or range ] on sequence
- * @param alignedPosition
- * false, blank or something else - indicate if position is an
- * alignment column or unaligned sequence position
- */
- public abstract void highlightIn(AlignFrame alf, String sequenceId,
- String position, String alignedPosition);
-
- /**
- * select regions of the currrent alignment frame
- *
- * @param sequenceIds
- * String separated list of sequence ids or empty string
- * @param columns
- * String separated list { column range or column, ..} or empty
- * string
- */
-
- public abstract void select(String sequenceIds, String columns);
-
- /**
- * select regions of the currrent alignment frame
- *
- * @param toselect
- * String separated list { column range, seq1...seqn sequence ids }
- * @param sep
- * separator between toselect fields
- */
-
- public abstract void select(String sequenceIds, String columns,
- String sep);
-
- /**
- * select regions of the given alignment frame
- *
- * @param alf
- * @param toselect
- * String separated list { column range, seq1...seqn sequence ids }
- * @param sep
- * separator between toselect fields
- */
- public abstract void selectIn(AlignFrame alf, String sequenceIds,
- String columns);
-
- /**
- * select regions of the given alignment frame
- *
- * @param alf
- * @param toselect
- * String separated list { column range, seq1...seqn sequence ids }
- * @param sep
- * separator between toselect fields
- */
- public abstract void selectIn(AlignFrame alf, String sequenceIds,
- String columns, String sep);
-
- /**
- * get sequences selected in current AlignFrame and return their alignment in
- * format 'format' either with or without suffix
- *
- * @param alf
- * - where selection is
- * @param format
- * - format of alignment file
- * @param suffix
- * - "true" to append /start-end string to each sequence ID
- * @return selected sequences as flat file or empty string if there was no
- * current selection
- */
-
- public abstract String getSelectedSequencesAsAlignment(String format,
- String suffix);
-
- /**
- * get sequences selected in alf and return their alignment in format 'format'
- * either with or without suffix
- *
- * @param alf
- * - where selection is
- * @param format
- * - format of alignment file
- * @param suffix
- * - "true" to append /start-end string to each sequence ID
- * @return selected sequences as flat file or empty string if there was no
- * current selection
- */
- public abstract String getSelectedSequencesAsAlignmentFrom(
- AlignFrame alf,
- String format, String suffix);
-
- /**
- * get a separator separated list of sequence IDs reflecting the order of the
- * current alignment
- *
- * @return
- */
-
- public abstract String getAlignmentOrder();
-
- /**
- * get a separator separated list of sequence IDs reflecting the order of the
- * alignment in alf
- *
- * @param alf
- * @return
- */
- public abstract String getAlignmentOrderFrom(AlignFrame alf);
-
- /**
- * get a sep separated list of sequence IDs reflecting the order of the
- * alignment in alf
- *
- * @param alf
- * @param sep
- * - separator to use
- * @return
- */
- public abstract String getAlignmentOrderFrom(AlignFrame alf,
- String sep);
-
- /**
- * re-order the current alignment using the given list of sequence IDs
- *
- * @param order
- * - sep separated list
- * @param undoName
- * - string to use when referring to ordering action in undo buffer
- * @return 'true' if alignment was actually reordered. empty string if
- * alignment did not contain sequences.
- */
-
- public abstract String orderBy(String order, String undoName);
-
- /**
- * re-order the current alignment using the given list of sequence IDs
- * separated by sep
- *
- * @param order
- * - sep separated list
- * @param undoName
- * - string to use when referring to ordering action in undo buffer
- * @param sep
- * @return 'true' if alignment was actually reordered. empty string if
- * alignment did not contain sequences.
- */
-
- public abstract String orderBy(String order, String undoName,
- String sep);
-
- /**
- * re-order the given alignment using the given list of sequence IDs separated
- * by sep
- *
- * @param alf
- * @param order
- * - sep separated list
- * @param undoName
- * - string to use when referring to ordering action in undo buffer
- * @param sep
- * @return 'true' if alignment was actually reordered. empty string if
- * alignment did not contain sequences.
- */
- public abstract String orderAlignmentBy(AlignFrame alf, String order,
- String undoName, String sep);
-
- /**
- * get alignment as format (format names FASTA, BLC, CLUSTAL, MSF, PILEUP,
- * PFAM - see jalview.io.AppletFormatAdapter for full list);
- *
- * @param format
- * @return
- */
-
- public abstract String getAlignment(String format);
-
- /**
- * get alignment displayed in alf as format
- *
- * @param alf
- * @param format
- * @return
- */
- public abstract String getAlignmentFrom(AlignFrame alf, String format);
-
- /**
- * get alignment as format with jalview start-end sequence suffix appended
- *
- * @param format
- * @param suffix
- * @return
- */
-
- public abstract String getAlignment(String format, String suffix);
-
- /**
- * get alignment displayed in alf as format with or without the jalview
- * start-end sequence suffix appended
- *
- * @param alf
- * @param format
- * @param suffix
- * @return
- */
- public abstract String getAlignmentFrom(AlignFrame alf, String format,
- String suffix);
-
- /**
- * add the given features or annotation to the current alignment
- *
- * @param annotation
- */
-
- public abstract void loadAnnotation(String annotation);
-
- /**
- * add the given features or annotation to the given alignment view
- *
- * @param alf
- * @param annotation
- */
- public abstract void loadAnnotationFrom(AlignFrame alf,
- String annotation);
-
- /**
- * parse the given string as a jalview feature or GFF annotation file and
- * optionally enable feature display on the current AlignFrame
- *
- * @param features
- * - gff or features file
- * @param autoenabledisplay
- * - when true, feature display will be enabled if any features can
- * be parsed from the string.
- */
-
- public abstract void loadFeatures(String features,
- boolean autoenabledisplay);
-
- /**
- * parse the given string as a jalview feature or GFF annotation file and
- * optionally enable feature display on the given AlignFrame.
- *
- * @param alf
- * @param features
- * - gff or features file
- * @param autoenabledisplay
- * - when true, feature display will be enabled if any features can
- * be parsed from the string.
- * @return true if data parsed as features
- */
- public abstract boolean loadFeaturesFrom(AlignFrame alf, String features,
- boolean autoenabledisplay);
-
- /**
- * get the sequence features in the given format (Jalview or GFF);
- *
- * @param format
- * @return
- */
-
- public abstract String getFeatures(String format);
-
- /**
- * get the sequence features in alf in the given format (Jalview or GFF);
- *
- * @param alf
- * @param format
- * @return
- */
- public abstract String getFeaturesFrom(AlignFrame alf, String format);
-
- /**
- * get current alignment's annotation as an annotation file
- *
- * @return
- */
-
- public abstract String getAnnotation();
-
- /**
- * get alignment view alf's annotation as an annotation file
- *
- * @param alf
- * @return
- */
- public abstract String getAnnotationFrom(AlignFrame alf);
-
- // BH incompatibility here -- JalviewLite created an AlignFrame; Jalview
- // creates an AlignmentPanel
- // /**
- // * create a new view and return the AlignFrame instance
- // *
- // * @return
- // */
- //
- // public abstract AlignFrame newView();
- //
- // /**
- // * create a new view named name and return the AlignFrame instance
- // *
- // * @param name
- // * @return
- // */
- //
- // public abstract AlignFrame newView(String name);
- //
- // /**
- // * create a new view on alf and return the AlignFrame instance
- // *
- // * @param alf
- // * @return
- // */
- // public abstract AlignFrame newViewFrom(AlignFrame alf);
- //
- // /**
- // * create a new view named name on alf
- // *
- // * @param alf
- // * @param name
- // * @return
- // */
- // public abstract AlignFrame newViewFrom(AlignFrame alf, String name);
-
- /**
- *
- * @param text
- * alignment file as a string
- * @param title
- * window title
- * @return null or new alignment frame
- */
-
- public abstract AlignFrame loadAlignment(String text, String title);
-
- /**
- * register a javascript function to handle any alignment mouseover events
- *
- * @param listener
- * name of javascript function (called with arguments
- * [jalview.appletgui.AlignFrame,String(sequence id);,String(column
- * in alignment);, String(position in sequence);]
- */
-
- public abstract void setMouseoverListener(String listener);
-
- /**
- * register a javascript function to handle mouseover events
- *
- * @param af
- * (null or specific AlignFrame for which events are to be listened
- * for);
- * @param listener
- * name of javascript function
- */
- public abstract void setMouseoverListener(AlignFrame af,
- String listener);
-
- /**
- * register a javascript function to handle any alignment selection events.
- * Events are generated when the user completes a selection event, or when the
- * user deselects all selected regions.
- *
- * @param listener
- * name of javascript function (called with arguments
- * [jalview.appletgui.AlignFrame, String(sequence set id);,
- * String(separator separated list of sequences which were
- * selected);, String(separator separated list of column ranges (i.e.
- * single number or hyphenated range); that were selected);]
- */
-
- public abstract void setSelectionListener(String listener);
-
- public abstract void setSelectionListener(AlignFrame af,
- String listener);
-
- /**
- * register a javascript function to handle events normally routed to a Jmol
- * structure viewer.
- *
- * @param listener
- * - javascript function (arguments are variable, see
- * jalview.javascript.MouseOverStructureListener for full details);
- * @param modelSet
- * - separator separated list of PDB file URIs that this viewer is
- * handling. These files must be in the same order they appear in
- * Jmol (e.g. first one is frame 1, second is frame 2, etc);.
- * @see jalview.javascript.MouseOverStructureListener
- */
-
- public abstract void setStructureListener(String listener,
- String modelSet);
-
- /**
- * remove any callback using the given listener function and associated with
- * the given AlignFrame (or null for all callbacks);
- *
- * @param af
- * (may be null);
- * @param listener
- * (may be null);
- */
- public abstract void removeJavascriptListener(AlignFrame af,
- String listener);
-
- /**
- * send a mouseover message to all the alignment windows associated with the
- * given residue in the pdbfile
- *
- * @param pdbResNum
- * @param chain
- * @param pdbfile
- */
-
- public abstract void mouseOverStructure(String pdbResNum, String chain,
- String pdbfile);
-
- /**
- * bind a pdb file to a sequence in the given AlignFrame.
- *
- * @param alFrame
- * - null or specific AlignFrame. This specifies the dataset that
- * will be searched for a seuqence called sequenceId
- * @param sequenceId
- * - sequenceId within the dataset.
- * @param pdbEntryString
- * - the short name for the PDB file
- * @param pdbFile
- * - pdb file - either a URL or a valid PDB file.
- * @return true if binding was as success TODO: consider making an exception
- * structure for indicating when PDB parsing or sequenceId location
- * fails.
- */
- public abstract boolean addPdbFile(AlignFrame alFrame, String sequenceId,
- String pdbEntryString, String pdbFile);
-
- /**
- * adjust horizontal/vertical scroll to make the given location the top left
- * hand corner for the given view
- *
- * @param alf
- * @param topRow
- * @param leftHandColumn
- */
- public abstract void scrollViewToIn(AlignFrame alf, String topRow,
- String leftHandColumn);
-
- /**
- * adjust vertical scroll to make the given row the top one for given view
- *
- * @param alf
- * @param topRow
- */
- public abstract void scrollViewToRowIn(AlignFrame alf, String topRow);
-
- /**
- * adjust horizontal scroll to make the given column the left one in the given
- * view
- *
- * @param alf
- * @param leftHandColumn
- */
- public abstract void scrollViewToColumnIn(AlignFrame alf,
- String leftHandColumn);
-
- /**
- *
- * @return
- * @see jalview.appletgui.AlignFrame#getFeatureGroups();
- */
-
- public abstract String getFeatureGroups();
-
- /**
- * @param alf
- * AlignFrame to get feature groups on
- * @return
- * @see jalview.appletgui.AlignFrame#getFeatureGroups();
- */
- public abstract String getFeatureGroupsOn(AlignFrame alf);
-
- /**
- * @param visible
- * @return
- * @see jalview.appletgui.AlignFrame#getFeatureGroupsOfState(boolean);
- */
-
- public abstract String getFeatureGroupsOfState(boolean visible);
-
- /**
- * @param alf
- * align frame to get groups of state visible
- * @param visible
- * @return
- * @see jalview.appletgui.AlignFrame#getFeatureGroupsOfState(boolean);
- */
- public abstract String getFeatureGroupsOfStateOn(AlignFrame alf,
- boolean visible);
-
- /**
- * @param groups
- * tab separated list of group names
- * @param state
- * true or false
- * @see jalview.appletgui.AlignFrame#setFeatureGroupState(java.lang.String[],
- * boolean);
- */
- public abstract void setFeatureGroupStateOn(AlignFrame alf,
- String groups,
- boolean state);
-
-
- public abstract void setFeatureGroupState(String groups, boolean state);
-
- /**
- * List separator string
- *
- * @return the separator
- */
-
- public abstract String getSeparator();
-
- /**
- * List separator string
- *
- * @param separator
- * the separator to set. empty string will reset separator to default
- */
-
- public abstract void setSeparator(String separator);
-
- /**
- * Retrieve fragments of a large packet of data made available by JalviewLite.
- *
- * @param messageclass
- * @param viewId
- * @return next chunk of message
- */
-
- public abstract String getJsMessage(String messageclass, String viewId);
-
- /// in http://www.jalview.org/examples/jalviewLiteJs.html but missing here
-
- // get selected sequences as alignment as format with or without start-end
- // suffix
-
- public String getSelectedSequencesAsAlignment(String format,
- boolean suffix);
-
- // get selected sequences as alignment from given view as format with or
- // without start-end suffix
- public String getSelectedSequencesAsAlignmentFrom(AlignFrame alf,
- String format, boolean suffix);
-
-
- public String arrayToSeparatorList(String[] array);
-
- // get a string array from a list
-
- public String[] separatorListToArray(String list);
-
- // debug flag - controls output to standard out
- public static boolean debug = false;
-
-}
diff --git a/src/jalview/bin/JalviewJSApp.java b/src/jalview/bin/JalviewJSApp.java
new file mode 100644
index 0000000..feab4ae
--- /dev/null
+++ b/src/jalview/bin/JalviewJSApp.java
@@ -0,0 +1,1691 @@
+package jalview.bin;
+
+import java.awt.EventQueue;
+//import java.applet.AppletContext;
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.Vector;
+
+import javax.swing.SwingUtilities;
+
+import jalview.api.JalviewJSApi;
+import jalview.api.StructureSelectionManagerProvider;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentOrder;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.PDBEntry;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.gui.AlignViewport;
+import jalview.gui.CalculationChooser;
+import jalview.gui.Desktop;
+import jalview.gui.StructureViewer;
+import jalview.io.AnnotationFile;
+import jalview.io.AppletFormatAdapter;
+import jalview.io.DataSourceType;
+import jalview.io.FeaturesFile;
+import jalview.io.FileFormat;
+import jalview.io.FileFormatI;
+import jalview.io.FileFormats;
+import jalview.io.IdentifyFile;
+import jalview.io.JPredFile;
+import jalview.io.JnetAnnotationMaker;
+import jalview.io.NewickFile;
+import jalview.structure.SelectionListener;
+import jalview.structure.SelectionSource;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.HttpUtils;
+import jalview.util.Platform;
+
+/**
+ * Basically the JalviewLite application, but without JalviewLite
+ *
+ * Processing all "applet parameters" and also all "applet interface" methods.
+ *
+ * @author hansonr
+ *
+ */
+public class JalviewJSApp implements JalviewJSApi
+{
+ private ArgsParser aparser;
+
+ private String[] ret = new String[1];
+
+ // private boolean alignPDBStructures; From JalviewLite; not implemented
+
+ private String separator = "\u00AC"; // JalviewLite note: the default used to
+ // be '|', but many sequence IDS include
+ // pipes.
+
+ /**
+ * We maintain a pointer to the jalview instance here, because only with that
+ * do we have a direct connection from the JavaScript "applet" object to the
+ * proper instance of Jalview in case there are multiple applets on a page.
+ */
+ private Jalview jalview;
+
+ public class JsSelectionListener
+ implements jalview.structure.SelectionListener
+ {
+
+ AlignFrame _alf;
+
+ String _listener;
+
+ public JsSelectionListener(AlignFrame alf, String listener)
+ {
+ _alf = alf;
+ _listener = listener;
+ }
+
+ public boolean isFor(AlignFrame alf, String listener)
+ {
+ return (_alf == null || _alf == alf) && _listener.equals(listener);
+ }
+
+ @Override
+ public void selection(SequenceGroup seqsel, ColumnSelection colsel,
+ HiddenColumns hidden, SelectionSource source)
+ {
+ // System.err.println("Testing selection event relay to
+ // jsfunction:"+_listener);
+ String setid = "";
+ AlignFrame srcFrame = (_alf == null ? getCurrentAlignFrame() : _alf);
+ if (source != null)
+ {
+ if (source instanceof AlignViewport
+ && srcFrame.getViewport() != source)
+ {
+ return;
+ }
+ }
+ String[] seqs = new String[] {};
+ String[] cols = new String[] {};
+ int strt = 0, end = (srcFrame == null) ? -1
+ : srcFrame.alignPanel.av.getAlignment().getWidth();
+ if (seqsel != null && seqsel.getSize() > 0)
+ {
+ seqs = new String[seqsel.getSize()];
+ for (int i = 0; i < seqs.length; i++)
+ {
+ seqs[i] = seqsel.getSequenceAt(i).getName();
+ }
+ if (strt < seqsel.getStartRes())
+ {
+ strt = seqsel.getStartRes();
+ }
+ if (end == -1 || end > seqsel.getEndRes())
+ {
+ end = seqsel.getEndRes();
+ }
+ }
+ if (colsel != null && !colsel.isEmpty())
+ {
+ if (end == -1)
+ {
+ end = colsel.getMax() + 1;
+ }
+ cols = new String[colsel.getSelected().size()];
+ for (int i = 0; i < cols.length; i++)
+ {
+ cols[i] = "" + (1 + colsel.getSelected().get(i).intValue());
+ }
+ }
+ else
+ {
+ if (seqsel != null && seqsel.getSize() > 0)
+ {
+ // send a valid range, otherwise we send the empty selection
+ cols = new String[1];
+ cols[0] = "" + (1 + strt) + "-" + (1 + end);
+ }
+ }
+ doSendCallback(_listener,
+ new Object[]
+ { Jalview.getInstance().j2sAppletID, srcFrame, source, setid,
+ seqs, cols });
+ }
+
+ }
+
+ public JalviewJSApp(Jalview jalview, ArgsParser aparser)
+ {
+ Platform.setAppClass(this);
+ this.jalview = jalview;
+ this.aparser = aparser;
+ }
+
+ @Override
+ public boolean addPdbFile(String sequenceId, String pdbId, String pdbFile,
+ AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ SequenceI seq = alf.getViewport().getAlignment().findName(sequenceId);
+ if (seq != null)
+ {
+ Vector pdbe = seq.getAllPDBEntries();
+ PDBEntry pdbentry = null;
+ if (pdbe != null && pdbe.size() > 0)
+ {
+ for (int pe = 0, peSize = pdbe.size(); pe < peSize; pe++)
+ {
+ pdbentry = pdbe.elementAt(pe);
+ if (!pdbentry.getId().equals(pdbId)
+ || pdbFile != null && !pdbentry.getFile().equals(pdbFile))
+ {
+ pdbentry = null;
+ }
+ }
+ }
+ if (pdbentry == null)
+ {
+ pdbentry = new PDBEntry(pdbId, null, pdbFile);
+ if (pdbFile != null)
+ {
+ DataSourceType protocol = AppletFormatAdapter
+ .resolveProtocol(pdbFile, FileFormat.PDB);
+ if (protocol == null)
+ return false;
+ pdbentry.setProperty("protocol", protocol);
+ }
+ seq.addPDBId(pdbentry);
+ alf.alignPanel.getStructureSelectionManager()
+ .registerPDBEntry(pdbentry);
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String getAlignment(String format, boolean addSuffix,
+ AlignFrame alf)
+ {
+ try
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+
+ FileFormatI theFormat = FileFormats.getInstance().forName(format);
+ String reply = new AppletFormatAdapter().formatSequences(theFormat,
+ alf.getViewport().getAlignment(), addSuffix);
+ return reply;
+ } catch (IllegalArgumentException ex)
+ {
+ ex.printStackTrace();
+ return "Error retrieving alignment, possibly invalid format specifier: "
+ + format;
+ }
+ }
+
+ @Override
+ public String[] getAlignmentOrder(AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ AlignmentI alorder = alf.getViewport().getAlignment();
+ String[] order = new String[alorder.getHeight()];
+ for (int i = 0; i < order.length; i++)
+ {
+ order[i] = alorder.getSequenceAt(i).getName();
+ }
+ return order;// arrayToSeparatorList(order, sep);
+ }
+
+ @Override
+ public String getAnnotation(AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ String annotation = new AnnotationFile()
+ .printAnnotationsForView(alf.getViewport());
+ return annotation;
+ }
+
+ /**
+ * Get the applet-like code base even though this is an application.
+ */
+
+ @Override
+ public URL getCodeBase()
+ {
+ return Platform.getCodeBase();
+ }
+
+ @Override
+ public AlignFrame getCurrentAlignFrame()
+ {
+ // if (jalview != Jalview.getInstance() || jalview.currentAlignFrame !=
+ // Jalview.getCurrentAlignFrame()) {
+ // /** @j2sNative debugger */
+ // }
+ return jalview.currentAlignFrame;
+ }
+
+ /**
+ * Get the applet-like document base even though this is an application.
+ */
+
+ @Override
+ public URL getDocumentBase()
+ {
+ return Platform.getDocumentBase();
+ }
+
+ @Override
+ public String[] getFeatureGroups(AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ return alf.getFeatureGroups();
+ }
+
+ @Override
+ public String[] getFeatureGroupsOfState(boolean visible, AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ return alf.getFeatureGroupsOfState(visible);
+ }
+
+ /**
+ * JavaScript interface to print the alignment frame
+ *
+ * @param format
+ * "jalview" or "gff" with or without ";includeComplement" or
+ * ";includeNonpositional"; default with no ";" is
+ * ";includeNonpositional"
+ * @param alf
+ *
+ * @return
+ */
+ @Override
+ public String getFeatures(String format, AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ String features;
+ FeaturesFile formatter = new FeaturesFile();
+ format = format.toLowerCase();
+ if (format.indexOf(";") < 0)
+ format += ";includenonpositional";
+ boolean nonpos = format.indexOf(";includenonpositional") >= 0;
+ boolean compl = format.indexOf(";includecomplement") >= 0;
+ if (format.startsWith("jalview"))
+ {
+ features = formatter.printJalviewFormat(
+ alf.getViewport().getAlignment().getSequencesArray(),
+ alf.alignPanel.getFeatureRenderer(), nonpos, compl);
+ }
+ else
+ {
+ features = formatter.printGffFormat(
+ alf.getViewport().getAlignment().getSequencesArray(),
+ alf.alignPanel.getFeatureRenderer(), nonpos, compl);
+ }
+
+ if (features == null)
+ {
+ features = "";
+ }
+ return features;
+
+ }
+
+ /**
+ * Get an applet parameter as a string.
+ *
+ */
+ @Override
+ public String getParameter(String name)
+ {
+ return (String) aparser.getAppletValue(name, null, true);
+ }
+
+ /**
+ * Get an applet parameter as an Object.
+ */
+
+ @Override
+ public Object getParameterAsObject(String name)
+ {
+ return aparser.getAppletValue(name, null, false);
+ }
+
+ /**
+ * read sequence1...sequenceN as a raw alignment
+ *
+ * @param jalviewApp
+ * @return
+ */
+ public String getPastedSequence(JalviewJSApp jalviewApp)
+ {
+ StringBuffer data = new StringBuffer("PASTE");
+ int i = 1;
+ String file = null;
+ while ((file = getParameter("sequence" + i)) != null)
+ {
+ data.append(file.toString() + "\n");
+ i++;
+ }
+ if (data.length() > 5)
+ {
+ file = data.toString();
+ }
+ return file;
+ }
+
+ /**
+ * @j2sAlias getSelectedSequences
+ *
+ * @see jalview.appletgui.js.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
+ * .AlignFrame)
+ */
+ @Override
+ public SequenceI[] getSelectedSequences(AlignFrame alf)
+ {
+ // return getSelectedSequencesFrom(alf, null);
+ // }
+ //
+ // @Override
+ // public SequenceI[] getSelectedSequencesFrom(AlignFrame alf, String sep)
+ // {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ AlignViewport v = alf.getViewport();
+ if (v.getSelectionGroup() != null)
+ {
+ return v.getSelectionGroup().getSequencesInOrder(v.getAlignment());
+ }
+ return null;
+ }
+ // /**
+ // *
+ // * @see
+ // jalview.appletgui.js.JalviewLiteJsApi#getSelectedSequencesFrom(jalview.appletgui
+ // * .AlignFrame, java.lang.String)
+ // */
+ // @Override
+ // public void highlight(String sequenceId, String position,
+ // String alignedPosition)
+ // {
+ // highlightIn(null, sequenceId, position, alignedPosition);
+ // }
+
+ /**
+ * @j2sAlias getSelectedSequencesAsAlignment
+ */
+ @Override
+ public String getSelectedSequencesAsAlignment(String format,
+ boolean addSuffix, AlignFrame alf)
+ {
+
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ try
+ {
+ AlignViewport vp = alf.getViewport();
+ FileFormatI theFormat = FileFormats.getInstance().forName(format);
+ if (vp.getSelectionGroup() != null)
+ {
+ // JBPNote: getSelectionAsNewSequence behaviour has changed - this
+ // method now returns a full copy of sequence data
+ // TODO consider using getSequenceSelection instead here
+ String reply = new AppletFormatAdapter().formatSequences(theFormat,
+ new Alignment(vp.getSelectionAsNewSequence()), addSuffix);
+ return reply;
+ }
+ } catch (IllegalArgumentException ex)
+ {
+ ex.printStackTrace();
+ return "Error retrieving alignment, possibly invalid format specifier: "
+ + format;
+ }
+ return "";
+ }
+
+ @Override
+ public void highlight(String sequenceId, String position,
+ String alignedPosition, AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ // TODO: could try to highlight in all alignments if alf==null
+ jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
+ alf.getViewport().getAlignment().getSequencesArray());
+ final SequenceI sq = matcher.findIdMatch(sequenceId);
+ if (sq != null)
+ {
+ int apos = -1;
+ try
+ {
+ apos = Integer.valueOf(position).intValue();
+ apos--;
+ } catch (NumberFormatException ex)
+ {
+ return;
+ }
+ final int pos = apos;
+ // use vamsas listener to broadcast to all listeners in scope
+ if (alignedPosition != null && (alignedPosition.trim().length() == 0
+ || alignedPosition.toLowerCase().indexOf("false") > -1))
+ {
+ java.awt.EventQueue.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ StructureSelectionManager
+ .getStructureSelectionManager(Desktop.getInstance())
+ .mouseOverVamsasSequence(sq, sq.findIndex(pos), null);
+ }
+ });
+ }
+ else
+ {
+ java.awt.EventQueue.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ StructureSelectionManager
+ .getStructureSelectionManager(Desktop.getInstance())
+ .mouseOverVamsasSequence(sq, pos, null);
+ }
+ });
+ }
+ }
+ }
+
+ @Override
+ public AlignFrame loadAlignment(String text, String title, int width,
+ int height)
+ {
+ AlignmentI al = null;
+
+ try
+ {
+ FileFormatI format = new IdentifyFile().identify(text,
+ DataSourceType.PASTE);
+ al = new AppletFormatAdapter().readFile(text, DataSourceType.PASTE,
+ format);
+ if (al.getHeight() > 0)
+ {
+ return new AlignFrame(al,
+ width > 0 ? width : AlignFrame.DEFAULT_WIDTH,
+ height > 0 ? height : AlignFrame.DEFAULT_HEIGHT, title);
+ }
+ } catch (IOException ex)
+ {
+ ex.printStackTrace();
+ }
+ return null;
+ }
+
+ @Override
+ public void loadAnnotation(String annotation, AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ if (new AnnotationFile().annotateAlignmentView(alf.getViewport(),
+ annotation, DataSourceType.PASTE))
+ {
+ alf.alignPanel.fontChanged();
+ alf.alignPanel.setScrollValues(0, 0);
+ }
+ else
+ {
+ alf.parseFeaturesFile(annotation, DataSourceType.PASTE);
+ }
+ }
+
+ @Override
+ public boolean loadFeatures(String features, boolean autoenabledisplay,
+ AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ boolean ret = alf.parseFeaturesFile(features, DataSourceType.PASTE);
+ if (!ret)
+ {
+ return false;
+ }
+ if (autoenabledisplay)
+ {
+ alf.getViewport().setShowSequenceFeatures(true);
+ // this next was for a checkbox in JalviewLite
+ // ((AlignFrame) alf).getViewport().sequenceFeatures.setState(true);
+ }
+ return true;
+ }
+
+ @Override
+ public boolean loadScoreFile(String fileName, AlignFrame alf)
+ {
+ try
+ {
+ (alf == null ? getCurrentAlignFrame() : alf)
+ .loadJalviewDataFile(fileName, null, null, null);
+ return true;
+ } catch (Throwable t)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * @j2sAlias openPcaPanel
+ *
+ * public static method for JalviewJS API to open a PCAPanel without
+ * necessarily using a dialog.
+ * @param modelName
+ * @param alf
+ *
+ * @return the PCAPanel, or the string "label.you_need_at_least_n_sequences"
+ * if number of sequences selected is inappropriate
+ */
+ @Override
+ public Object openPcaPanel(String modelName, AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ return CalculationChooser.openPcaPanel(alf, modelName, null);
+ }
+
+ /**
+ * @j2sAlias openTreePanel
+ *
+ * Open a new Tree panel on the desktop statically. Params are
+ * standard (not set by Groovy). No dialog is opened.
+ * @param treeType
+ * @param modelName
+ * @param alf
+ *
+ * @return null, or the string "label.you_need_at_least_n_sequences" if number
+ * of sequences selected is inappropriate
+ */
+ @Override
+ public Object openTreePanel(String treeType, String modelName,
+ AlignFrame alf)
+ {
+ if (alf == null)
+ {
+ alf = getCurrentAlignFrame();
+ }
+ return CalculationChooser.openTreePanel(alf, treeType, modelName, null);
+ }
+
+ @Override
+ public boolean orderAlignment(String[] ids, String undoName,
+ AlignFrame alf)
+ {
+ if (alf == null)
+ alf = getCurrentAlignFrame();
+ SequenceI[] sqs = null;
+ if (ids != null && ids.length > 0)
+ {
+ jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
+ alf.getViewport().getAlignment().getSequencesArray());
+ int s = 0;
+ sqs = new SequenceI[ids.length];
+ for (int i = 0; i < ids.length; i++)
+ {
+ if (ids[i].trim().length() == 0)
+ {
+ continue;
+ }
+ SequenceI sq = matcher.findIdMatch(ids[i]);
+ if (sq != null)
+ {
+ sqs[s++] = sq;
+ }
+ }
+ if (s > 0)
+ {
+ SequenceI[] sqq = new SequenceI[s];
+ System.arraycopy(sqs, 0, sqq, 0, s);
+ sqs = sqq;
+ }
+ else
+ {
+ sqs = null;
+ }
+ }
+ if (sqs == null)
+ {
+ return false;
+ }
+ ;
+ final AlignmentOrder aorder = new AlignmentOrder(sqs);
+
+ if (undoName != null && undoName.trim().length() == 0)
+ {
+ undoName = null;
+ }
+ final String _undoName = undoName;
+ // TODO: deal with synchronization here: cannot raise any events until
+ // alfter
+ // this has returned.
+ return alf.sortBy(aorder, _undoName);
+ }
+
+ /**
+ * Allow an outside entity to initiate the second half of argument parsing
+ * (only).
+ *
+ * @param args
+ * @return null is good
+ */
+ @Override
+ public Object parseArguments(String[] args)
+ {
+
+ try
+ {
+ jalview.parseArguments(new ArgsParser(args), false);
+ return null;
+ } catch (Throwable t)
+ {
+ return t;
+ }
+ }
+
+ /**
+ * @j2sAlias parseFeatureFile
+ *
+ * @param filename
+ * @param alf
+ * @return
+ */
+ @Override
+ public boolean parseFeaturesFile(String filename, AlignFrame alf)
+ {
+ ret[0] = filename;
+ DataSourceType protocol = resolveFileProtocol(ret);
+ if (protocol == null)
+ return false;
+ return (alf == null ? getCurrentAlignFrame() : alf)
+ .parseFeaturesFile(ret[0], protocol);
+ }
+
+ @Override
+ public void removeSelectionListener(String listener, AlignFrame alf)
+ {
+
+ List listeners = Desktop
+ .getStructureSelectionManager().getListeners();
+ for (int i = listeners.size(); --i >= 0;)
+ {
+ SelectionListener l = listeners.get(i);
+ if (l instanceof JsSelectionListener
+ && ((JsSelectionListener) l).isFor(alf, listener))
+ {
+ listeners.remove(i);
+ break;
+ }
+ }
+ }
+
+ private DataSourceType resolveFileProtocol(String[] retPath)
+ {
+ String path = retPath[0];
+ /*
+ * is it paste data?
+ */
+ if (path.startsWith("PASTE"))
+ {
+ retPath[0] = path.substring(5);
+ return DataSourceType.PASTE;
+ }
+
+ /*
+ * is it a URL?
+ */
+ if (path.indexOf("://") >= 0)
+ {
+ return DataSourceType.URL;
+ }
+
+ /*
+ * try relative to document root
+ */
+ URL documentBase = getDocumentBase();
+ String withDocBase = resolveUrlForLocalOrAbsolute(path, documentBase);
+ if (HttpUtils.isValidUrl(withDocBase))
+ {
+ // if (debug)
+ // {
+ // System.err.println("Prepended document base '" + documentBase
+ // + "' to make: '" + withDocBase + "'");
+ // }
+ retPath[0] = withDocBase;
+ return DataSourceType.URL;
+ }
+
+ /*
+ * try relative to codebase (if different to document base)
+ */
+ URL codeBase = getCodeBase();
+ String withCodeBase = resolveUrlForLocalOrAbsolute(path, codeBase);
+ if (!withCodeBase.equals(withDocBase)
+ && HttpUtils.isValidUrl(withCodeBase))
+ {
+ // if (debug)
+ // {
+ // System.err.println("Prepended codebase '" + codeBase
+ // + "' to make: '" + withCodeBase + "'");
+ // }
+ retPath[0] = withCodeBase;
+ return DataSourceType.URL;
+ }
+
+ /*
+ * try locating by classloader; try this last so files in the directory
+ * are resolved using document base
+ */
+ if (inArchive(getClass(), path))
+ {
+ return DataSourceType.CLASSLOADER;
+ }
+ return null;
+ }
+
+ @Override
+ public void scrollViewTo(int topRow, int leftHandColumn, AlignFrame alf)
+ {
+ // TODO test
+ java.awt.EventQueue.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ (alf == null ? getCurrentAlignFrame() : alf).scrollTo(topRow,
+ leftHandColumn);
+ } catch (Exception ex)
+ {
+ System.err.println("Couldn't parse integer arguments (topRow='"
+ + topRow + "' and leftHandColumn='" + leftHandColumn
+ + "')");
+ ex.printStackTrace();
+ }
+ }
+ });
+ }
+
+ @Override
+ public void select(String ids[], String cols[], AlignFrame alf)
+ {
+ if (alf == null)
+ alf = getCurrentAlignFrame();
+ final SequenceGroup sel = new SequenceGroup();
+ final ColumnSelection csel = new ColumnSelection();
+ AlignmentI al = alf.getViewport().getAlignment();
+ jalview.analysis.SequenceIdMatcher matcher = new jalview.analysis.SequenceIdMatcher(
+ alf.getViewport().getAlignment().getSequencesArray());
+ int start = 0, end = al.getWidth(), alw = al.getWidth();
+ boolean seqsfound = true;
+ if (ids != null && ids.length > 0)
+ {
+ seqsfound = false;
+ for (int i = 0; i < ids.length; i++)
+ {
+ if (ids[i].trim().length() == 0)
+ {
+ continue;
+ }
+ SequenceI sq = matcher.findIdMatch(ids[i]);
+ if (sq != null)
+ {
+ seqsfound = true;
+ sel.addSequence(sq, false);
+ }
+ }
+ }
+ boolean inseqpos = false;
+ if (cols != null && cols.length > 0)
+ {
+ boolean seset = false;
+ for (int i = 0; i < cols.length; i++)
+ {
+ String cl = cols[i].trim();
+ if (cl.length() == 0)
+ {
+ continue;
+ }
+ int p;
+ if ((p = cl.indexOf("-")) > -1)
+ {
+ int from = -1, to = -1;
+ try
+ {
+ from = Integer.valueOf(cl.substring(0, p)).intValue();
+ from--;
+ } catch (NumberFormatException ex)
+ {
+ System.err.println(
+ "ERROR: Couldn't parse first integer in range element column selection string '"
+ + cl + "' - format is 'from-to'");
+ return;
+ }
+ try
+ {
+ to = Integer.valueOf(cl.substring(p + 1)).intValue();
+ to--;
+ } catch (NumberFormatException ex)
+ {
+ System.err.println(
+ "ERROR: Couldn't parse second integer in range element column selection string '"
+ + cl + "' - format is 'from-to'");
+ return;
+ }
+ if (from >= 0 && to >= 0)
+ {
+ // valid range
+ if (from < to)
+ {
+ int t = to;
+ to = from;
+ to = t;
+ }
+ if (!seset)
+ {
+ start = from;
+ end = to;
+ seset = true;
+ }
+ else
+ {
+ // comment to prevent range extension
+ if (start > from)
+ {
+ start = from;
+ }
+ if (end < to)
+ {
+ end = to;
+ }
+ }
+ for (int r = from; r <= to; r++)
+ {
+ if (r >= 0 && r < alw)
+ {
+ csel.addElement(r);
+ }
+ }
+ }
+ else
+ {
+ System.err.println("ERROR: Invalid Range '" + cl
+ + "' deparsed as [" + from + "," + to + "]");
+ }
+ }
+ else
+ {
+ int r = -1;
+ try
+ {
+ r = Integer.valueOf(cl).intValue();
+ r--;
+ } catch (NumberFormatException ex)
+ {
+ if (cl.toLowerCase().equals("sequence"))
+ {
+ // we are in the dataset sequence's coordinate frame.
+ inseqpos = true;
+ }
+ else
+ {
+ System.err.println(
+ "ERROR: Couldn't parse integer from point selection element of column selection string '"
+ + cl + "'");
+ return;
+ }
+ }
+ if (r >= 0 && r <= alw)
+ {
+ if (!seset)
+ {
+ start = r;
+ end = r;
+ seset = true;
+ }
+ else
+ {
+ // comment to prevent range extension
+ if (start > r)
+ {
+ start = r;
+ }
+ if (end < r)
+ {
+ end = r;
+ }
+ }
+ csel.addElement(r);
+ }
+ else
+ {
+ System.err.println("ERROR: Invalid Point selection '" + cl
+ + "' deparsed as [" + r + "]");
+ }
+ }
+ }
+ }
+ if (seqsfound)
+ {
+ // we only propagate the selection when it was the null selection, or the
+ // given sequences were found in the alignment.
+ if (inseqpos && sel.getSize() > 0)
+ {
+ // assume first sequence provides reference frame ?
+ SequenceI rs = sel.getSequenceAt(0);
+ start = rs.findIndex(start);
+ end = rs.findIndex(end);
+ List cs = new ArrayList<>(csel.getSelected());
+ csel.clear();
+ for (Integer selectedCol : cs)
+ {
+ csel.addElement(rs.findIndex(selectedCol));
+ }
+ }
+ sel.setStartRes(start);
+ sel.setEndRes(end);
+ AlignFrame af = alf;
+ EventQueue.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ af.select(sel, csel,
+ af.getCurrentView().getAlignment().getHiddenColumns());
+ }
+ });
+ }
+ }
+
+ //
+ // @Override
+ // public void setFeatureGroupState(String[] groups, boolean state)
+ // {
+ // setFeatureGroupState(null, groups, state);
+ // }
+ //
+ // @Override
+ // public void setFeatureGroupState(String[] groups, boolean state)
+ // { // JalviewLite API
+ // setFeatureGroupStateOn(null, groups, state);
+ // }
+ //
+ @Override
+ public void setFeatureGroupState(final String[] groups,
+ boolean state, AlignFrame alf)
+ {
+ // setFeatureGroupState(alf, groups, state);
+ // java.awt.EventQueue.invokeLater(new Runnable()
+ // {
+ // @Override
+ // public void run()
+ // {
+ // (alf == null ? getCurrentAlignFrame() : alf)
+ // .setFeatureGroupState(
+ // separatorListToArray(groups, separator), state);
+ // }
+ // });
+ // }
+ //
+ // public void setFeatureGroupState(AlignFrame alf, String[] groups, boolean
+ // state) {
+ (alf == null ? getCurrentAlignFrame() : alf)
+ .setFeatureGroupState(groups, state);
+ }
+
+ @Override
+ public void setSelectionListener(String listener, AlignFrame alf)
+ {
+ Desktop.getStructureSelectionManager()
+ .addSelectionListener(new JsSelectionListener(alf, listener));
+ }
+
+ @Override
+ public void showOverview()
+ {
+ getCurrentAlignFrame().overviewMenuItem_actionPerformed(null);
+ }
+
+ /**
+ * @j2sAlias showStructure
+ */
+ @Override
+ public void showStructure(String pdbID, String fileType, AlignFrame alf)
+ {
+ if (alf == null)
+ alf = getCurrentAlignFrame();
+ PDBEntry pe = null;
+ SequenceI[] seqs = null;
+ if (pdbID == null)
+ {
+ seqs = alf.getViewport().getSequenceSelection();
+ if (seqs.length == 0)
+ seqs = alf.getViewport().getAlignment().getSequencesArray();
+ for (int i = 0; i < seqs.length; i++)
+ {
+ Vector list = seqs[i].getAllPDBEntries();
+ if (list.size() > 0)
+ {
+ pe = list.get(0);
+ break;
+ }
+ }
+ }
+ if (pe == null)
+ {
+ if (pdbID == null)
+ return;
+ pe = new PDBEntry(pdbID, null, fileType);
+ List list = alf.getViewport().getAlignment()
+ .getSequences();
+ List tmp = new ArrayList();
+ for (int i = 0; i < list.size(); i++)
+ {
+ SequenceI seq = list.get(i);
+ if (seq.getPDBEntry(pdbID) != null)
+ {
+ tmp.add(seq);
+ }
+ }
+ seqs = tmp.toArray(new SequenceI[tmp.size()]);
+ alf.alignPanel.selectSequences(tmp);
+ }
+ StructureViewer.launchStructureViewer(alf.alignPanel, pe, seqs);
+ }
+
+ // private or package-private methods
+
+ /**
+ * form a complete URL given a path to a resource and a reference location on
+ * the same server
+ *
+ * @param targetPath
+ * - an absolute path on the same server as localref or a document
+ * located relative to localref
+ * @param localref
+ * - a URL on the same server as url
+ * @return a complete URL for the resource located by url
+ */
+ private static String resolveUrlForLocalOrAbsolute(String targetPath,
+ URL localref)
+ {
+ String resolvedPath = "";
+ if (targetPath.startsWith("/"))
+ {
+ String codebase = localref.toString();
+ String localfile = localref.getFile();
+ resolvedPath = codebase.substring(0,
+ codebase.length() - localfile.length()) + targetPath;
+ return resolvedPath;
+ }
+
+ /*
+ * get URL path and strip off any trailing file e.g.
+ * www.jalview.org/examples/index.html#applets?a=b is trimmed to
+ * www.jalview.org/examples/
+ */
+ String urlPath = localref.toString();
+ String directoryPath = urlPath;
+ int lastSeparator = directoryPath.lastIndexOf("/");
+ if (lastSeparator > 0)
+ {
+ directoryPath = directoryPath.substring(0, lastSeparator + 1);
+ }
+
+ if (targetPath.startsWith("/"))
+ {
+ /*
+ * construct absolute URL to a file on the server - this is not allowed?
+ */
+ // String localfile = localref.getFile();
+ // resolvedPath = urlPath.substring(0,
+ // urlPath.length() - localfile.length())
+ // + targetPath;
+ resolvedPath = directoryPath + targetPath.substring(1);
+ }
+ else
+ {
+ resolvedPath = directoryPath + targetPath;
+ }
+ // if (debug)
+ // {
+ // System.err.println(
+ // "resolveUrlForLocalOrAbsolute returning " + resolvedPath);
+ // }
+ return resolvedPath;
+ }
+
+ /**
+ * parse the string into a list
+ *
+ * @param list
+ * @param separator
+ * @return elements separated by separator
+ */
+ private static String[] separatorListToArray(String list,
+ String separator)
+ {
+ // TODO use StringUtils version (slightly different...)
+ int seplen = separator.length();
+ if (list == null || list.equals("") || list.equals(separator))
+ {
+ return null;
+ }
+ Vector jv = new Vector<>();
+ int cp = 0, pos;
+ while ((pos = list.indexOf(separator, cp)) > cp)
+ {
+ jv.addElement(list.substring(cp, pos));
+ cp = pos + seplen;
+ }
+ if (cp < list.length())
+ {
+ String c = list.substring(cp);
+ if (!c.equals(separator))
+ {
+ jv.addElement(c);
+ }
+ }
+ if (jv.size() > 0)
+ {
+ String[] v = new String[jv.size()];
+ for (int i = 0; i < v.length; i++)
+ {
+ v[i] = jv.elementAt(i);
+ }
+ jv.removeAllElements();
+ return v;
+ }
+ return null;
+ }
+
+ /**
+ * Discovers whether the given file is in the Applet Archive
+ *
+ * @param f
+ * String
+ * @return boolean
+ */
+ private static boolean inArchive(Class> c, String f)
+ {
+ // This might throw a security exception in certain browsers
+ // Netscape Communicator for instance.
+ try
+ {
+ boolean rtn = (c.getResourceAsStream("/" + f) != null);
+ return rtn;
+ } catch (Exception ex)
+ {
+ System.out.println("Exception checking resources: " + f + " " + ex);
+ return false;
+ }
+ }
+
+ /**
+ * Allowing for a JavaScript function here.
+ */
+ void callInitCallback()
+ {
+ Object initjscallback = getParameterAsObject("oninit");
+ if (initjscallback != null)
+ {
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run()
+ {
+ try
+ {
+ doSendCallback(initjscallback, new Object[] {this});
+ } catch (Exception e)
+ {
+ System.err.println("Exception when executing _oninit callback '"
+ + initjscallback + "'.");
+ e.printStackTrace();
+ }
+ }
+
+ });
+ }
+ }
+
+ /**
+ * Pass the provided array prepended with Jalview.this
+ *
+ * Appropriated from org.jmol.appletjs.Jmol
+ *
+ * @param callback
+ * a window function or "alert"
+ * @param data
+ * @return String return from the callback method.
+ */
+ String doSendCallback(Object callback, Object[] data)
+ {
+ Jalview me = jalview;
+
+ if (me != null && callback != null)
+ {
+ /**
+ * @j2sNative
+ *
+ * try{
+ *
+ * if (callback == "alert") { alert(data[0]); return ""; } var
+ * o; if (typeof callback == "function") { o = callback; } else
+ * { if (!callback)return; var tokens = callback.split("."); o
+ * = window[tokens[0]]; for (var i = 1; i < tokens.length; i++)
+ * o = o[tokens[i]]; } var a = [me]; for (var i = 0; i <
+ * data.length; i++) a.push(data[i] ? data[i].booleanValue &&
+ * (data[i] = data[i].booleanValue()) : data[i]); return
+ * o.apply(null,a) } catch (e) { System.out.println(callback +
+ * " failed " + e); }
+ */
+ }
+ return "";
+ }
+
+ /**
+ * Initialize from Info.key/value pairs that match the old JalviewLite applet
+ * parameters.
+ *
+ * See http://www.jalview.org/old/v2_8/examples/appletParameters.html
+ *
+ * Note that some of these parameters are handled as command-line arguments,
+ * as determined in ArgsParser.
+ *
+ * @param alf
+ */
+ void initFromParams(AlignFrame alf)
+ {
+ String sep = getParameter("separator");
+ if (sep != null && sep.length() > 0)
+ {
+ separator = sep;
+ }
+ initTree(alf);
+ initScoreFile(alf);
+ initFeatures(alf);
+ initAnnotations(alf);
+ initJnetFile(alf);
+ initPdbFiles(alf);
+ }
+
+ /**
+ * Load annotations if specified by parameter. Returns true if loaded, else
+ * false.
+ *
+ *
+ * @param alignFrame
+ * @return
+ */
+ private boolean initAnnotations(AlignFrame alf)
+ {
+
+ String param = getParameter("annotations");
+ if (param == null)
+ return false;
+ ret[0] = param;
+ DataSourceType protocol = resolveFileProtocol(ret);
+ param = ret[0];
+ if (!new AnnotationFile().annotateAlignmentView(alf.getViewport(),
+ param, protocol))
+ {
+ System.err.println("Annotations were not added from annotation file '"
+ + param + "'");
+ return false;
+ }
+ updateForAnnotations();
+ return true;
+ }
+
+ /**
+ * Load features file and view settings as specified by parameters. Returns
+ * true if features were loaded, else false.
+ *
+ * @param
+ *
+ * @param alignFrame
+ * @return
+ */
+ private boolean initFeatures(AlignFrame alf)
+ {
+
+ // ///////////////////////////
+ // modify display of features
+ // we do this before any features have been loaded, ensuring any hidden
+ // groups are hidden when features first displayed
+ //
+ // hide specific groups
+ //
+ String param = getParameter("hidefeaturegroups");
+ if (param != null)
+ {
+ setFeatureGroupState(separatorListToArray(param, separator),
+ false, alf);
+ // setFeatureGroupStateOn(newAlignFrame, param, false);
+ }
+ // show specific groups
+ param = getParameter("showfeaturegroups");
+ if (param != null)
+ {
+ setFeatureGroupState(separatorListToArray(param, separator),
+ true, alf);
+ // setFeatureGroupStateOn(newAlignFrame, param, true);
+ }
+ // and now load features
+ param = getParameter("features");
+ if (param == null)
+ {
+ return false;
+ }
+ if (!parseFeaturesFile(param, alf))
+ return false;
+ param = getParameter("showFeatureSettings");
+ if (param != null && param.equalsIgnoreCase("true"))
+ {
+ alf.showFeatureSettingsUI();
+ }
+ return true;
+ }
+
+ /**
+ * Load in a Jnetfile if specified by parameter. Returns true if loaded, else
+ * false.
+ *
+ * @param alignFrame
+ * @return
+ */
+ private boolean initJnetFile(AlignFrame alf)
+ {
+
+ String param = getParameter("jnetfile");
+ if (param == null)
+ {
+ // jnet became jpred around 2016
+ param = getParameter("jpredfile");
+ }
+ if (param != null)
+ {
+ try
+ {
+ ret[0] = param;
+ DataSourceType protocol = resolveFileProtocol(ret);
+ JPredFile predictions = new JPredFile(ret[0], protocol);
+ JnetAnnotationMaker.add_annotation(predictions,
+ alf.getViewport().getAlignment(), 0, false);
+ // false == do not add sequence profile from concise output
+ alf.getViewport().getAlignment().setupJPredAlignment();
+ updateForAnnotations();
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Load PDBFiles if any specified by parameter(s). Returns true if loaded,
+ * else false.
+ *
+ * @param loaderFrame
+ * @return
+ */
+ private boolean initPdbFiles(AlignFrame alf)
+ {
+
+ /*
+ * Undocumented for 2.6 -
+ * related to JAL-434
+ */
+
+ // not supported (as for JalviewLite)
+ // boolean doAlign = false;//"true".equalsIgnoreCase("" +
+ // getAppletParameter("alignpdbfiles", false));
+ // setAlignPdbStructures(doAlign);
+ /*
+ *
+ *
+ *
+ *
+ *
+ */
+
+ // Accumulate pdbs here if they are heading for the same view (if
+ // alignPdbStructures is true)
+ // ArrayList pdbs = new ArrayList<>();
+ // init a lazy matcher if we're asked to
+ boolean relaxed = "true"
+ .equalsIgnoreCase(getParameter("relaxedidmatch"));
+ jalview.analysis.SequenceIdMatcher matcher = relaxed
+ ? new jalview.analysis.SequenceIdMatcher(
+ alf.getViewport().getAlignment().getSequencesArray())
+ : null;
+
+ String param = getParameter("PDBFILE");
+ int plast = (param == null ? 9 : 1);
+ if (param == null && (param = getParameter("PDBFILE1")) == null)
+ {
+ return false;
+ }
+ for (int p = 1; p <= plast; p++)
+ {
+ if (p > 1)
+ {
+ param = getParameter("PDBFILE" + p);
+ if (param == null)
+ break;
+ }
+ PDBEntry pdb = new PDBEntry();
+
+ String seqstring;
+ SequenceI[] seqs = null;
+ String[] chains = null;
+
+ StringTokenizer st = new StringTokenizer(param, " ");
+
+ if (st.countTokens() < 2)
+ {
+ String sequence = getParameter("PDBSEQ");
+ if (sequence != null)
+ {
+ seqs = new SequenceI[] { matcher == null
+ ? (Sequence) alf.getViewport().getAlignment()
+ .findName(sequence)
+ : matcher.findIdMatch(sequence) };
+ }
+
+ }
+ else
+ {
+ param = st.nextToken();
+ List tmp = new ArrayList<>();
+ List tmp2 = new ArrayList<>();
+
+ while (st.hasMoreTokens())
+ {
+ seqstring = st.nextToken();
+ StringTokenizer st2 = new StringTokenizer(seqstring, "=");
+ if (st2.countTokens() > 1)
+ {
+ // This is the chain
+ tmp2.add(st2.nextToken());
+ seqstring = st2.nextToken();
+ }
+ tmp.add(matcher == null
+ ? (Sequence) alf.getViewport().getAlignment()
+ .findName(seqstring)
+ : matcher.findIdMatch(seqstring));
+ }
+
+ seqs = tmp.toArray(new SequenceI[tmp.size()]);
+ if (tmp2.size() == tmp.size())
+ {
+ chains = tmp2.toArray(new String[tmp2.size()]);
+ }
+ }
+ pdb.setId(param);
+ ret[0] = param;
+ DataSourceType protocol = resolveFileProtocol(ret);
+ // TODO check JAL-357 for files in a jar (CLASSLOADER)
+ pdb.setFile(ret[0]);
+
+ if (seqs != null)
+ {
+ for (int i = 0; i < seqs.length; i++)
+ {
+ if (seqs[i] != null)
+ {
+ ((Sequence) seqs[i]).addPDBId(pdb);
+ StructureSelectionManager
+ .getStructureSelectionManager(
+ (StructureSelectionManagerProvider) this)
+ .registerPDBEntry(pdb);
+ }
+ }
+
+ // if (doAlign)
+ // {
+ // pdbs.add(new Object[] { pdb, seqs, chains, protocol });
+ // }
+ // else
+ {
+ StructureViewer.launchStructureViewer(
+ (alf == null ? getCurrentAlignFrame() : alf).alignPanel,
+ pdb, seqs);
+ }
+ }
+ }
+ //
+ // if (doAlign && pdbs.size() > 0)
+ // {
+ // SequenceI[][] seqs = new SequenceI[pdbs.size()][];
+ // PDBEntry[] pdb = new PDBEntry[pdbs.size()];
+ // String[][] chains = new String[pdbs.size()][];
+ // String[] protocols = new String[pdbs.size()];
+ // for (int pdbsi = 0, pdbsiSize = pdbs
+ // .size(); pdbsi < pdbsiSize; pdbsi++)
+ // {
+ // Object[] o = pdbs.get(pdbsi);
+ // pdb[pdbsi] = (PDBEntry) o[0];
+ // seqs[pdbsi] = (SequenceI[]) o[1];
+ // chains[pdbsi] = (String[]) o[2];
+ // protocols[pdbsi] = (String) o[3];
+ // }
+ //// alignedStructureView(pdb, seqs, chains, protocols);
+ // result = true;
+ // }
+ return true;
+ }
+
+ /**
+ * Load a score file if specified by parameter. Returns true if file was
+ * loaded, else false.
+ *
+ * @param loaderFrame
+ */
+ private boolean initScoreFile(AlignFrame alf)
+ {
+
+ String sScoreFile = getParameter("scoreFile");
+ if (sScoreFile != null && !"".equals(sScoreFile))
+ {
+ try
+ {
+ if (loadScoreFile(sScoreFile, alf))
+ {
+ return true;
+ }
+ System.err.println(
+ "Failed to parse T-COFFEE parameter as a valid score file ('"
+ + sScoreFile + "')");
+ } catch (Exception e)
+ {
+ System.err.printf("Cannot read score file: '%s'. Cause: %s \n",
+ sScoreFile, e.getMessage());
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Load a tree for the alignment if specified by parameter. Returns true if a
+ * tree was loaded, else false.
+ *
+ * @return
+ */
+ private boolean initTree(AlignFrame alf)
+ {
+ String treeFile;
+ if ((treeFile = getParameter("tree")) == null
+ && (treeFile = getParameter("treefile")) == null)
+ return false;
+ if (alf == null)
+ alf = getCurrentAlignFrame();
+ try
+ {
+ ret[0] = treeFile;
+ NewickFile nf = new NewickFile(treeFile, resolveFileProtocol(ret));
+ nf.parse();
+ if (nf.getTree() != null)
+ {
+ treeFile = ret[0];
+ alf.getViewport()
+ .setCurrentTree(alf.showNewickTree(nf, treeFile).getTree());
+ return true;
+ }
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ return false;
+ }
+
+ private void updateForAnnotations()
+ {
+ getCurrentAlignFrame().updateForAnnotations();
+ }
+}
diff --git a/src/jalview/bin/JalviewLite.java b/src/jalview/bin/JalviewLite.java
index e7f2a53..6a8db59 100644
--- a/src/jalview/bin/JalviewLite.java
+++ b/src/jalview/bin/JalviewLite.java
@@ -45,10 +45,12 @@ import jalview.io.IdentifyFile;
import jalview.io.JPredFile;
import jalview.io.JnetAnnotationMaker;
import jalview.io.NewickFile;
-import jalview.javascript.JSFunctionExec;
-import jalview.javascript.JalviewLiteJsApi;
-import jalview.javascript.JsCallBack;
-import jalview.javascript.MouseOverStructureListener;
+import jalview.appletgui.js.JSFunctionExec;
+import jalview.appletgui.js.JalviewLiteJsApi;
+import jalview.appletgui.js.JsCallBack;
+import jalview.appletgui.js.JsSelectionSender;
+import jalview.appletgui.js.MouseOverListener;
+import jalview.appletgui.js.MouseOverStructureListener;
import jalview.structure.SelectionListener;
import jalview.structure.StructureSelectionManager;
import jalview.util.ColorUtils;
@@ -920,7 +922,7 @@ public class JalviewLite extends Applet
setMouseoverListener(currentAlignFrame, listener);
}
- private Vector javascriptListeners = new Vector<>();
+ private Vector javascriptListeners = new Vector<>();
/*
* (non-Javadoc)
@@ -942,7 +944,7 @@ public class JalviewLite extends Applet
return;
}
}
- jalview.javascript.MouseOverListener mol = new jalview.javascript.MouseOverListener(
+ MouseOverListener mol = new MouseOverListener(
this, af, listener);
javascriptListeners.addElement(mol);
StructureSelectionManager.getStructureSelectionManager(this)
@@ -989,7 +991,7 @@ public class JalviewLite extends Applet
return;
}
}
- jalview.javascript.JsSelectionSender mol = new jalview.javascript.JsSelectionSender(
+ JsSelectionSender mol = new JsSelectionSender(
this, af, listener);
javascriptListeners.addElement(mol);
StructureSelectionManager.getStructureSelectionManager(this)
@@ -1128,7 +1130,7 @@ public class JalviewLite extends Applet
{
while (javascriptListeners.size() > 0)
{
- jalview.javascript.JSFunctionExec mol = javascriptListeners
+ JSFunctionExec mol = javascriptListeners
.elementAt(0);
javascriptListeners.removeElement(mol);
if (mol instanceof SelectionListener)
@@ -1155,7 +1157,7 @@ public class JalviewLite extends Applet
StructureSelectionManager.release(this);
}
- private jalview.javascript.JSFunctionExec jsFunctionExec;
+ private JSFunctionExec jsFunctionExec;
/*
* (non-Javadoc)
@@ -1230,7 +1232,7 @@ public class JalviewLite extends Applet
* (non-Javadoc)
*
* @see
- * jalview.javascript.JalviewLiteJsApi#scrollViewToRowIn(jalview.appletgui
+ * JalviewLiteJsApi#scrollViewToRowIn(jalview.appletgui
* .AlignFrame, java.lang.String)
*/
@Override
@@ -1261,7 +1263,7 @@ public class JalviewLite extends Applet
* (non-Javadoc)
*
* @see
- * jalview.javascript.JalviewLiteJsApi#scrollViewToColumnIn(jalview.appletgui
+ * JalviewLiteJsApi#scrollViewToColumnIn(jalview.appletgui
* .AlignFrame, java.lang.String)
*/
@Override
diff --git a/src/jalview/datamodel/Alignment.java b/src/jalview/datamodel/Alignment.java
index c4098e2..8d81a34 100755
--- a/src/jalview/datamodel/Alignment.java
+++ b/src/jalview/datamodel/Alignment.java
@@ -591,7 +591,8 @@ public class Alignment implements AlignmentI, AutoCloseable
@Override
public SequenceI findName(SequenceI startAfter, String token, boolean b)
{
-
+ if (token == null)
+ return null;
int i = 0;
SequenceI sq = null;
String sqname = null;
diff --git a/src/jalview/datamodel/PDBEntry.java b/src/jalview/datamodel/PDBEntry.java
index c1dc77c..d39e9f1 100755
--- a/src/jalview/datamodel/PDBEntry.java
+++ b/src/jalview/datamodel/PDBEntry.java
@@ -21,6 +21,7 @@
package jalview.datamodel;
import jalview.util.CaseInsensitiveString;
+import jalview.ws.params.InvalidArgumentException;
import java.util.Collections;
import java.util.Enumeration;
@@ -152,6 +153,32 @@ public class PDBEntry
{
}
+ /**
+ * Entry point when file is not known and fileType may be string
+ * @param pdbId
+ * @param chain may be null
+ * @param fileType "pdb", "mmcif", or "bcif"; null defaults to mmcif
+ */
+ public PDBEntry(String pdbId, String chain, String fileType) {
+ this.id = pdbId.toLowerCase();
+ setChainCode(chain); // I note that PDB Chains ARE case-sensitive now
+ if (fileType == null)
+ fileType = "mmcif";
+ switch (fileType.toLowerCase()) {
+ case "pdb":
+ this.type = Type.PDB.toString();
+ break;
+ case "mmcif":
+ this.type = Type.MMCIF.toString();
+ break;
+ default:
+ case "bcif":
+ System.out.println("format " + fileType + " has not been implemented; using mmCIF");
+ this.type = Type.MMCIF.toString();
+ break;
+ }
+ }
+
public PDBEntry(String pdbId, String chain, PDBEntry.Type type,
String filePath)
{
@@ -253,6 +280,12 @@ public class PDBEntry
return id;
}
+ /**
+ * TODO
+ *
+ * @param key "protocol"
+ * @param value
+ */
public void setProperty(String key, Object value)
{
if (this.properties == null)
diff --git a/src/jalview/datamodel/features/FeatureAttributes.java b/src/jalview/datamodel/features/FeatureAttributes.java
index bcf404b..a57fd55 100644
--- a/src/jalview/datamodel/features/FeatureAttributes.java
+++ b/src/jalview/datamodel/features/FeatureAttributes.java
@@ -29,17 +29,29 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+
/**
* A singleton class to hold the set of attributes known for each feature type
*/
-public class FeatureAttributes
+public class FeatureAttributes implements ApplicationSingletonI
{
public enum Datatype
{
Character, Number, Mixed
}
- private static FeatureAttributes instance = new FeatureAttributes();
+ public static FeatureAttributes getInstance()
+ {
+ return (FeatureAttributes) ApplicationSingletonProvider
+ .getInstance(FeatureAttributes.class);
+ }
+
+ private FeatureAttributes()
+ {
+ attributes = new HashMap<>();
+ }
/*
* map, by feature type, of a map, by attribute name, of
@@ -120,12 +132,17 @@ public class FeatureAttributes
if (value != null)
{
value = value.trim();
+ if (value.isEmpty())
+ {
+ return;
+ }
/*
* Parse numeric value unless we have previously
* seen text data for this attribute type
*/
- if (type == null || type == Datatype.Number)
+ if ((type == null && couldBeNumber(value))
+ || type == Datatype.Number)
{
try
{
@@ -149,11 +166,23 @@ public class FeatureAttributes
hasValue = false;
}
}
+ else
+ {
+ /*
+ * if not a number, and not seen before...
+ */
+ type = Datatype.Character;
+ min = 0f;
+ max = 0f;
+ hasValue = false;
+ }
}
}
/**
- * Answers the description of the attribute, if recorded and unique, or null if either no, or more than description is recorded
+ * Answers the description of the attribute, if recorded and unique, or null
+ * if either no, or more than description is recorded
+ *
* @return
*/
public String getDescription()
@@ -193,21 +222,6 @@ public class FeatureAttributes
}
/**
- * Answers the singleton instance of this class
- *
- * @return
- */
- public static FeatureAttributes getInstance()
- {
- return instance;
- }
-
- private FeatureAttributes()
- {
- attributes = new HashMap<>();
- }
-
- /**
* Answers the attribute names known for the given feature type, in
* alphabetical order (not case sensitive), or an empty set if no attributes
* are known. An attribute name is typically 'simple' e.g. "AC", but may be
@@ -227,6 +241,34 @@ public class FeatureAttributes
}
/**
+ * A partial check that the string is numeric - only checks the first
+ * character. Returns true if the first character is a digit, or if it is '.',
+ * '+' or '-' and not the only character. Otherwise returns false (including
+ * for an empty string). Note this is not a complete check as it returns true
+ * for (e.g.) "1A".
+ *
+ * @param f
+ * @return
+ */
+ public static boolean couldBeNumber(String f)
+ {
+ int len = f.length();
+ if (len == 0)
+ {
+ return false;
+ }
+ char ch = f.charAt(0);
+ switch (ch)
+ {
+ case '.':
+ case '+':
+ case '-':
+ return len > 1;
+ }
+ return (ch <= '9' && ch >= '0');
+ }
+
+ /**
* Answers true if at least one attribute is known for the given feature type,
* else false
*
@@ -354,7 +396,7 @@ public class FeatureAttributes
{
return;
}
-
+
Map atts = attributes.get(featureType);
if (atts == null)
{
diff --git a/src/jalview/datamodel/features/FeatureSources.java b/src/jalview/datamodel/features/FeatureSources.java
index b316821..4a87349 100644
--- a/src/jalview/datamodel/features/FeatureSources.java
+++ b/src/jalview/datamodel/features/FeatureSources.java
@@ -23,6 +23,9 @@ package jalview.datamodel.features;
import java.util.HashMap;
import java.util.Map;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+
/**
* A singleton to hold metadata about feature attributes, keyed by a unique
* feature source identifier
@@ -30,22 +33,17 @@ import java.util.Map;
* @author gmcarstairs
*
*/
-public class FeatureSources
+public class FeatureSources implements ApplicationSingletonI
{
- private static FeatureSources instance = new FeatureSources();
-
- private Map sources;
- /**
- * Answers the singleton instance of this class
- *
- * @return
- */
public static FeatureSources getInstance()
{
- return instance;
+ return (FeatureSources) ApplicationSingletonProvider
+ .getInstance(FeatureSources.class);
}
+ private Map sources;
+
private FeatureSources()
{
sources = new HashMap<>();
diff --git a/src/jalview/datamodel/features/SequenceFeatures.java b/src/jalview/datamodel/features/SequenceFeatures.java
index 8ac4991..82772bc 100644
--- a/src/jalview/datamodel/features/SequenceFeatures.java
+++ b/src/jalview/datamodel/features/SequenceFeatures.java
@@ -372,7 +372,7 @@ public class SequenceFeatures implements SequenceFeaturesI
{
return true;
}
- SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+ SequenceOntologyI so = SequenceOntologyFactory.getSequenceOntology();
for (String term : soTerm)
{
if (type.equals(term) || so.isA(type, term))
diff --git a/src/jalview/ext/ensembl/EnsemblCds.java b/src/jalview/ext/ensembl/EnsemblCds.java
index 8f13d99..bf37265 100644
--- a/src/jalview/ext/ensembl/EnsemblCds.java
+++ b/src/jalview/ext/ensembl/EnsemblCds.java
@@ -93,7 +93,7 @@ public class EnsemblCds extends EnsemblSeqProxy
@Override
protected boolean retainFeature(SequenceFeature sf, String accessionId)
{
- if (SequenceOntologyFactory.getInstance().isA(sf.getType(),
+ if (SequenceOntologyFactory.getSequenceOntology().isA(sf.getType(),
SequenceOntologyI.CDS))
{
return false;
diff --git a/src/jalview/ext/ensembl/EnsemblGene.java b/src/jalview/ext/ensembl/EnsemblGene.java
index 157b8b9..3d957f0 100644
--- a/src/jalview/ext/ensembl/EnsemblGene.java
+++ b/src/jalview/ext/ensembl/EnsemblGene.java
@@ -578,7 +578,7 @@ public class EnsemblGene extends EnsemblSeqProxy
@Override
protected boolean retainFeature(SequenceFeature sf, String accessionId)
{
- SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+ SequenceOntologyI so = SequenceOntologyFactory.getSequenceOntology();
String type = sf.getType();
if (so.isA(type, SequenceOntologyI.GENE))
{
@@ -625,7 +625,7 @@ public class EnsemblGene extends EnsemblSeqProxy
{
return new FeatureSettingsAdapter()
{
- SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+ SequenceOntologyI so = SequenceOntologyFactory.getSequenceOntology();
@Override
public boolean isFeatureDisplayed(String type)
diff --git a/src/jalview/ext/ensembl/EnsemblSeqProxy.java b/src/jalview/ext/ensembl/EnsemblSeqProxy.java
index fd8800f..11f8b7b 100644
--- a/src/jalview/ext/ensembl/EnsemblSeqProxy.java
+++ b/src/jalview/ext/ensembl/EnsemblSeqProxy.java
@@ -732,7 +732,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
* for sequence_variant on reverse strand, have to convert the allele
* values to their complements
*/
- if (!forwardStrand && SequenceOntologyFactory.getInstance()
+ if (!forwardStrand && SequenceOntologyFactory.getSequenceOntology()
.isA(sf.getType(), SequenceOntologyI.SEQUENCE_VARIANT))
{
reverseComplementAlleles(copy);
@@ -966,7 +966,7 @@ public abstract class EnsemblSeqProxy extends EnsemblRestClient
public static boolean isTranscript(String featureType)
{
return SequenceOntologyI.NMD_TRANSCRIPT_VARIANT.equals(featureType)
- || SequenceOntologyFactory.getInstance().isA(featureType,
+ || SequenceOntologyFactory.getSequenceOntology().isA(featureType,
SequenceOntologyI.TRANSCRIPT);
}
}
diff --git a/src/jalview/ext/jmol/JalviewJmolBinding.java b/src/jalview/ext/jmol/JalviewJmolBinding.java
index 453152e..cfb30b3 100644
--- a/src/jalview/ext/jmol/JalviewJmolBinding.java
+++ b/src/jalview/ext/jmol/JalviewJmolBinding.java
@@ -1368,7 +1368,9 @@ public abstract class JalviewJmolBinding extends AAStructureBindingModel
htmlName + ((Object) this).toString(), documentBase, codeBase,
commandOptions, this);
- viewer.setJmolStatusListener(this); // extends JmolCallbackListener
+ viewer.setJmolStatusListener(this);
+
+ // BH how about extending Jmol's status listener?
try
{
diff --git a/src/jalview/ext/so/SequenceOntology.java b/src/jalview/ext/so/SequenceOntology.java
index 0d631e6..89b2415 100644
--- a/src/jalview/ext/so/SequenceOntology.java
+++ b/src/jalview/ext/so/SequenceOntology.java
@@ -20,8 +20,6 @@
*/
package jalview.ext.so;
-import jalview.io.gff.SequenceOntologyI;
-
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
@@ -44,6 +42,9 @@ import org.biojava.nbio.ontology.Triple;
import org.biojava.nbio.ontology.io.OboParser;
import org.biojava.nbio.ontology.utils.Annotation;
+import jalview.bin.Cache;
+import jalview.io.gff.SequenceOntologyI;
+
/**
* A wrapper class that parses the Sequence Ontology and exposes useful access
* methods. This version uses the BioJava parser.
@@ -183,19 +184,19 @@ public class SequenceOntology implements SequenceOntologyI
boolean oldTermIsObsolete = isObsolete(replaced);
if (newTermIsObsolete && !oldTermIsObsolete)
{
- System.err.println("Ignoring " + term.getName()
+ Cache.log.debug("Ignoring " + term.getName()
+ " as obsolete and duplicated by "
+ replaced.getName());
term = replaced;
}
else if (!newTermIsObsolete && oldTermIsObsolete)
{
- System.err.println("Ignoring " + replaced.getName()
+ Cache.log.debug("Ignoring " + replaced.getName()
+ " as obsolete and duplicated by " + term.getName());
}
else
{
- System.err.println("Warning: " + term.getName()
+ Cache.log.debug("Warning: " + term.getName()
+ " has replaced " + replaced.getName()
+ " for lookup of '" + description + "'");
}
diff --git a/src/jalview/fts/service/pdb/PDBFTSRestClient.java b/src/jalview/fts/service/pdb/PDBFTSRestClient.java
index 22ed591..c6860cc 100644
--- a/src/jalview/fts/service/pdb/PDBFTSRestClient.java
+++ b/src/jalview/fts/service/pdb/PDBFTSRestClient.java
@@ -37,6 +37,8 @@ import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.DefaultClientConfig;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.datamodel.SequenceI;
import jalview.fts.api.FTSData;
import jalview.fts.api.FTSDataColumnI;
@@ -53,13 +55,16 @@ import jalview.util.Platform;
*
* @author tcnofoegbu
*/
-public class PDBFTSRestClient extends FTSRestClient
+public class PDBFTSRestClient extends FTSRestClient implements ApplicationSingletonI
{
-
- private static FTSRestClientI instance = null;
-
public static final String PDB_SEARCH_ENDPOINT = "https://www.ebi.ac.uk/pdbe/search/pdb/select?";
+ public static FTSRestClientI getInstance()
+ {
+ return (FTSRestClientI) ApplicationSingletonProvider
+ .getInstance(PDBFTSRestClient.class);
+ }
+
protected PDBFTSRestClient()
{
}
@@ -458,15 +463,6 @@ public static String parseJsonExceptionString(String jsonErrorResponse)
return "/fts/pdb_data_columns.txt";
}
- public static FTSRestClientI getInstance()
- {
- if (instance == null)
- {
- instance = new PDBFTSRestClient();
- }
- return instance;
- }
-
private Collection allDefaultDisplayedStructureDataColumns;
public Collection getAllDefaultDisplayedStructureDataColumns()
diff --git a/src/jalview/fts/service/uniprot/UniProtFTSRestClient.java b/src/jalview/fts/service/uniprot/UniProtFTSRestClient.java
index 3f0b8a4..0d860c4 100644
--- a/src/jalview/fts/service/uniprot/UniProtFTSRestClient.java
+++ b/src/jalview/fts/service/uniprot/UniProtFTSRestClient.java
@@ -21,6 +21,8 @@
package jalview.fts.service.uniprot;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.bin.Cache;
import jalview.fts.api.FTSData;
import jalview.fts.api.FTSDataColumnI;
@@ -44,7 +46,15 @@ import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.DefaultClientConfig;
public class UniProtFTSRestClient extends FTSRestClient
+implements ApplicationSingletonI
{
+
+public static FTSRestClientI getInstance()
+{
+return (FTSRestClientI) ApplicationSingletonProvider
+ .getInstance(UniProtFTSRestClient.class);
+}
+
private static final String DEFAULT_UNIPROT_DOMAIN = "https://www.uniprot.org";
static
@@ -52,11 +62,9 @@ public class UniProtFTSRestClient extends FTSRestClient
Platform.addJ2SDirectDatabaseCall(DEFAULT_UNIPROT_DOMAIN);
}
- private static FTSRestClientI instance = null;
-
public final String uniprotSearchEndpoint;
- public UniProtFTSRestClient()
+ private UniProtFTSRestClient()
{
super();
uniprotSearchEndpoint = Cache.getDefault("UNIPROT_DOMAIN",
@@ -347,15 +355,6 @@ public class UniProtFTSRestClient extends FTSRestClient
};
}
- public static FTSRestClientI getInstance()
- {
- if (instance == null)
- {
- instance = new UniProtFTSRestClient();
- }
- return instance;
- }
-
@Override
public String getColumnDataConfigFileName()
{
diff --git a/src/jalview/gui/AlignExportOptions.java b/src/jalview/gui/AlignExportOptions.java
index 70601c9..3a8fb7c 100644
--- a/src/jalview/gui/AlignExportOptions.java
+++ b/src/jalview/gui/AlignExportOptions.java
@@ -96,7 +96,7 @@ public class AlignExportOptions extends JPanel
this.settings = defaults;
this.isComplexAlignFile = format.isComplexAlignFile();
init(viewport.hasHiddenRows(), viewport.hasHiddenColumns());
- dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
+ dialog = JvOptionPane.newOptionDialog(Desktop.getDesktopPane());
}
/**
diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java
index 29f6a2e..14e09e7 100644
--- a/src/jalview/gui/AlignFrame.java
+++ b/src/jalview/gui/AlignFrame.java
@@ -20,59 +20,6 @@
*/
package jalview.gui;
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.Rectangle;
-import java.awt.Toolkit;
-import java.awt.datatransfer.Clipboard;
-import java.awt.datatransfer.DataFlavor;
-import java.awt.datatransfer.StringSelection;
-import java.awt.datatransfer.Transferable;
-import java.awt.dnd.DnDConstants;
-import java.awt.dnd.DropTargetDragEvent;
-import java.awt.dnd.DropTargetDropEvent;
-import java.awt.dnd.DropTargetEvent;
-import java.awt.dnd.DropTargetListener;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.FocusAdapter;
-import java.awt.event.FocusEvent;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
-import java.awt.print.PageFormat;
-import java.awt.print.PrinterJob;
-import java.beans.PropertyChangeEvent;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.PrintWriter;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Deque;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Vector;
-
-import javax.swing.ButtonGroup;
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JComponent;
-import javax.swing.JEditorPane;
-import javax.swing.JInternalFrame;
-import javax.swing.JLabel;
-import javax.swing.JLayeredPane;
-import javax.swing.JMenu;
-import javax.swing.JMenuItem;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.SwingUtilities;
-
-import ext.vamsas.ServiceHandle;
import jalview.analysis.AlignmentSorter;
import jalview.analysis.AlignmentUtils;
import jalview.analysis.CrossRef;
@@ -156,6 +103,60 @@ import jalview.ws.jws2.Jws2Discoverer;
import jalview.ws.jws2.jabaws2.Jws2Instance;
import jalview.ws.seqfetcher.DbSourceProxy;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.StringSelection;
+import java.awt.datatransfer.Transferable;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DropTargetDragEvent;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.dnd.DropTargetEvent;
+import java.awt.dnd.DropTargetListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.print.PageFormat;
+import java.awt.print.PrinterJob;
+import java.beans.PropertyChangeEvent;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.PrintWriter;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Vector;
+
+import javax.swing.ButtonGroup;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JComponent;
+import javax.swing.JEditorPane;
+import javax.swing.JInternalFrame;
+import javax.swing.JLabel;
+import javax.swing.JLayeredPane;
+import javax.swing.JMenu;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+
+import ext.vamsas.ServiceHandle;
+
/**
* DOCUMENT ME!
*
@@ -167,6 +168,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
IProgressIndicator, AlignViewControllerGuiI, ColourChangeListener
{
+ public static int frameCount;
+
public static final int DEFAULT_WIDTH = 700;
public static final int DEFAULT_HEIGHT = 500;
@@ -194,6 +197,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
File fileObject;
+ private int id;
+
/**
* Creates a new AlignFrame object with specific width and height.
*
@@ -288,6 +293,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
public AlignFrame(AlignmentI al, HiddenColumns hiddenColumns, int width,
int height, String sequenceSetId, String viewId)
{
+
+ id = (++frameCount);
+
setSize(width, height);
if (al.getDataset() == null)
@@ -297,9 +305,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
viewport = new AlignViewport(al, hiddenColumns, sequenceSetId, viewId);
- alignPanel = new AlignmentPanel(this, viewport);
-
- addAlignmentPanel(alignPanel, true);
+ // JalviewJS needs to distinguish a new panel from an old one in init()
+ // alignPanel = new AlignmentPanel(this, viewport);
+ // addAlignmentPanel(alignPanel, true);
init();
}
@@ -319,8 +327,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
{
viewport.hideSequence(hiddenSeqs);
}
- alignPanel = new AlignmentPanel(this, viewport);
- addAlignmentPanel(alignPanel, true);
+ // alignPanel = new AlignmentPanel(this, viewport);
+ // addAlignmentPanel(alignPanel, true);
init();
}
@@ -336,7 +344,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
{
viewport = ap.av;
alignPanel = ap;
- addAlignmentPanel(ap, false);
+ // addAlignmentPanel(ap, false);
init();
}
@@ -344,13 +352,39 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* initalise the alignframe from the underlying viewport data and the
* configurations
*/
+
void init()
{
-// setBackground(Color.white); // BH 2019
-
+
+ boolean newPanel = (alignPanel == null);
+ viewport.setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
+ if (newPanel)
+ {
+ if (Platform.isJS())
+ {
+ // need to set this up front if NOANNOTATION is
+ // used in conjunction with SHOWOVERVIEW.
+
+ // I have not determined if this is appropriate for
+ // Jalview/Java, as it means we are setting this flag
+ // for all subsequent AlignFrames. For now, at least,
+ // I am setting it to be JalviewJS-only.
+
+ boolean showAnnotation = Jalview.getInstance().getShowAnnotation();
+ viewport.setShowAnnotation(showAnnotation);
+ }
+ alignPanel = new AlignmentPanel(this, viewport);
+ }
+ addAlignmentPanel(alignPanel, newPanel);
+
+ // setBackground(Color.white); // BH 2019
+
if (!Jalview.isHeadlessMode())
{
progressBar = new ProgressBar(this.statusPanel, this.statusBar);
+ // JalviewJS options
+ statusPanel.setVisible(Jalview.getInstance().getShowStatus());
+ alignFrameMenuBar.setVisible(Jalview.getInstance().getAllowMenuBar());
}
avc = new jalview.controller.AlignViewController(this, viewport,
@@ -365,7 +399,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
// modifyPID.setEnabled(false);
}
- String sortby = jalview.bin.Cache.getDefault("SORT_ALIGNMENT",
+ String sortby = jalview.bin.Cache.getDefault(Preferences.SORT_ALIGNMENT,
"No sort");
if (sortby.equals("Id"))
@@ -377,8 +411,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
sortPairwiseMenuItem_actionPerformed(null);
}
- this.alignPanel.av
- .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
+ // BH see above
+ //
+ // this.alignPanel.av
+ // .setShowAutocalculatedAbove(isShowAutoCalculatedAbove());
setMenusFromViewport(viewport);
buildSortByAnnotationScoresMenu();
@@ -393,7 +429,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
});
buildColourMenu();
- if (Desktop.desktop != null)
+ if (Desktop.getDesktopPane() != null)
{
this.setDropTarget(new java.awt.dnd.DropTarget(this, this));
if (!Platform.isJS())
@@ -408,7 +444,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
wrapMenuItem_actionPerformed(null);
}
- if (jalview.bin.Cache.getDefault("SHOW_OVERVIEW", false))
+ if (jalview.bin.Cache.getDefault(Preferences.SHOW_OVERVIEW, false))
{
this.overviewMenuItem_actionPerformed(null);
}
@@ -492,6 +528,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
}
addFocusListener(new FocusAdapter()
{
+
@Override
public void focusGained(FocusEvent e)
{
@@ -510,6 +547,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param format
* format of file
*/
+
public void setFileName(String file, FileFormatI format)
{
fileName = file;
@@ -523,6 +561,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @param file
*/
+
public void setFileObject(File file)
{
this.fileObject = file;
@@ -532,10 +571,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* Add a KeyListener with handlers for various KeyPressed and KeyReleased
* events
*/
+
void addKeyListener()
{
addKeyListener(new KeyAdapter()
{
+
@Override
public void keyPressed(KeyEvent evt)
{
@@ -552,8 +593,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
switch (evt.getKeyCode())
{
- case 27: // escape key
- deselectAllSequenceMenuItem_actionPerformed(null);
+ case KeyEvent.VK_ESCAPE: // escape key
+ // alignPanel.deselectAllSequences();
+ alignPanel.deselectAllSequences();
break;
@@ -736,16 +778,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
case KeyEvent.VK_LEFT:
if (evt.isAltDown() || !viewport.cursorMode)
{
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
}
break;
case KeyEvent.VK_RIGHT:
if (evt.isAltDown() || !viewport.cursorMode)
{
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
}
break;
}
@@ -791,9 +831,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
{
ap.av.getAlignment().padGaps();
}
- ap.av.updateConservation(ap);
- ap.av.updateConsensus(ap);
- ap.av.updateStrucConsensus(ap);
+ if (Jalview.getInstance().getStartCalculations())
+ {
+ ap.av.updateConservation(ap);
+ ap.av.updateConsensus(ap);
+ ap.av.updateStrucConsensus(ap);
+ }
}
}
@@ -816,9 +859,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
private void addServiceListeners()
{
final java.beans.PropertyChangeListener thisListener;
- Desktop.instance.addJalviewPropertyChangeListener("services",
+ Desktop.getInstance().addJalviewPropertyChangeListener("services",
thisListener = new java.beans.PropertyChangeListener()
{
+
@Override
public void propertyChange(PropertyChangeEvent evt)
{
@@ -842,19 +886,21 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
});
addInternalFrameListener(new javax.swing.event.InternalFrameAdapter()
{
+
@Override
public void internalFrameClosed(
javax.swing.event.InternalFrameEvent evt)
{
// System.out.println("deregistering discoverer listener");
- Desktop.instance.removeJalviewPropertyChangeListener("services",
- thisListener);
+ Desktop.getInstance().removeJalviewPropertyChangeListener(
+ "services", thisListener);
closeMenuItem_actionPerformed(true);
}
});
// Finally, build the menu once to get current service state
new Thread(new Runnable()
{
+
@Override
public void run()
{
@@ -867,6 +913,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* Configure menu items that vary according to whether the alignment is
* nucleotide or protein
*/
+
public void setGUINucleotide()
{
AlignmentI al = getViewport().getAlignment();
@@ -891,6 +938,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* operation that affects the data in the current view (selection changed,
* etc) to update the menus to reflect the new state.
*/
+
@Override
public void setMenusForViewport()
{
@@ -904,6 +952,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param av
* AlignViewport
*/
+
public void setMenusFromViewport(AlignViewport av)
{
padGapsMenuitem.setSelected(av.isPadGaps());
@@ -921,13 +970,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
scaleLeft.setVisible(av.getWrapAlignment());
scaleRight.setVisible(av.getWrapAlignment());
annotationPanelMenuItem.setState(av.isShowAnnotation());
- /*
- * Show/hide annotations only enabled if annotation panel is shown
- */
- showAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
- hideAllSeqAnnotations.setEnabled(annotationPanelMenuItem.getState());
- showAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
- hideAllAlAnnotations.setEnabled(annotationPanelMenuItem.getState());
+ // Show/hide annotations only enabled if annotation panel is shown
+ syncAnnotationMenuItems(av.isShowAnnotation());
viewBoxesMenuItem.setSelected(av.getShowBoxes());
viewTextMenuItem.setSelected(av.getShowText());
showNonconservedMenuItem.setSelected(av.getShowUnconserved());
@@ -945,7 +989,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
applyToAllGroups.setState(av.getColourAppliesToAllGroups());
showNpFeatsMenuitem.setSelected(av.isShowNPFeats());
showDbRefsMenuitem.setSelected(av.isShowDBRefs());
- autoCalculate.setSelected(av.autoCalculateConsensus);
+ autoCalculate
+ .setSelected(av.getAutoCalculateConsensusAndConservation());
sortByTree.setSelected(av.sortByTree);
listenToViewSelections.setSelected(av.followSelection);
@@ -960,6 +1005,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @param b
*/
+
public void setGroovyEnabled(boolean b)
{
runGroovy.setEnabled(b);
@@ -972,6 +1018,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @see jalview.gui.IProgressIndicator#setProgressBar(java.lang.String, long)
*/
+
@Override
public void setProgressBar(String message, long id)
{
@@ -989,6 +1036,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @return true if any progress bars are still active
*/
+
@Override
public boolean operationInProgress()
{
@@ -1000,6 +1048,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* will cause the status bar to be hidden, with possibly undesirable flicker
* of the screen layout.
*/
+
@Override
public void setStatus(String text)
{
@@ -1009,6 +1058,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
/*
* Added so Castor Mapping file can obtain Jalview Version
*/
+
public String getVersion()
{
return jalview.bin.Cache.getProperty("VERSION");
@@ -1028,103 +1078,106 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
@Override
public void addFromFile_actionPerformed(ActionEvent e)
{
- Desktop.instance.inputLocalFileMenuItem_actionPerformed(viewport);
+ Desktop.getInstance().inputLocalFileMenuItem_actionPerformed(viewport);
}
@Override
public void reload_actionPerformed(ActionEvent e)
{
- if (fileName != null)
+ if (fileName == null)
{
- // TODO: JAL-1108 - ensure all associated frames are closed regardless of
- // originating file's format
- // TODO: work out how to recover feature settings for correct view(s) when
- // file is reloaded.
- if (FileFormat.Jalview.equals(currentFileFormat))
+ return;
+ }
+ // TODO: JAL-1108 - ensure all associated frames are closed regardless of
+ // originating file's format
+ // TODO: work out how to recover feature settings for correct view(s) when
+ // file is reloaded.
+ if (FileFormat.Jalview.equals(currentFileFormat))
+ {
+ JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames();
+ for (int i = 0; i < frames.length; i++)
{
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
- for (int i = 0; i < frames.length; i++)
+ if (frames[i] instanceof AlignFrame && frames[i] != this
+ && ((AlignFrame) frames[i]).fileName != null
+ && ((AlignFrame) frames[i]).fileName.equals(fileName))
{
- if (frames[i] instanceof AlignFrame && frames[i] != this
- && ((AlignFrame) frames[i]).fileName != null
- && ((AlignFrame) frames[i]).fileName.equals(fileName))
+ try
+ {
+ frames[i].setSelected(true);
+ Desktop.getInstance().closeAssociatedWindows();
+ } catch (java.beans.PropertyVetoException ex)
{
- try
- {
- frames[i].setSelected(true);
- Desktop.instance.closeAssociatedWindows();
- } catch (java.beans.PropertyVetoException ex)
- {
- }
}
-
}
- Desktop.instance.closeAssociatedWindows();
- FileLoader loader = new FileLoader();
- DataSourceType protocol = fileName.startsWith("http:")
- ? DataSourceType.URL
- : DataSourceType.FILE;
- loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
}
- else
- {
- Rectangle bounds = this.getBounds();
+ Desktop.getInstance().closeAssociatedWindows();
- FileLoader loader = new FileLoader();
+ FileLoader loader = new FileLoader();
+ DataSourceType protocol = fileName.startsWith("http:")
+ ? DataSourceType.URL
+ : DataSourceType.FILE;
+ loader.LoadFile(viewport, fileName, protocol, currentFileFormat);
+ }
+ else
+ {
+ Rectangle bounds = this.getBounds();
- AlignFrame newframe = null;
+ FileLoader loader = new FileLoader();
- if (fileObject == null)
- {
+ AlignFrame newframe = null;
- DataSourceType protocol = (fileName.startsWith("http:")
- ? DataSourceType.URL
- : DataSourceType.FILE);
- newframe = loader.LoadFileWaitTillLoaded(fileName, protocol,
- currentFileFormat);
- }
- else
- {
- newframe = loader.LoadFileWaitTillLoaded(fileObject,
- DataSourceType.FILE, currentFileFormat);
- }
+ if (fileObject == null)
+ {
+
+ DataSourceType protocol = (fileName.startsWith("http:")
+ ? DataSourceType.URL
+ : DataSourceType.FILE);
+ newframe = loader.LoadFileWaitTillLoaded(fileName, protocol,
+ currentFileFormat);
+ }
+ else
+ {
+ newframe = loader.LoadFileWaitTillLoaded(fileObject,
+ DataSourceType.FILE, currentFileFormat);
+ }
- newframe.setBounds(bounds);
- if (featureSettings != null && featureSettings.isShowing())
+ newframe.setBounds(bounds);
+ if (featureSettings != null && featureSettings.isShowing())
+ {
+ final Rectangle fspos = featureSettings.frame.getBounds();
+ // TODO: need a 'show feature settings' function that takes bounds -
+ // need to refactor Desktop.addFrame
+ newframe.featureSettings_actionPerformed(null);
+ final FeatureSettings nfs = newframe.featureSettings;
+ SwingUtilities.invokeLater(new Runnable()
{
- final Rectangle fspos = featureSettings.frame.getBounds();
- // TODO: need a 'show feature settings' function that takes bounds -
- // need to refactor Desktop.addFrame
- newframe.featureSettings_actionPerformed(null);
- final FeatureSettings nfs = newframe.featureSettings;
- SwingUtilities.invokeLater(new Runnable()
+
+ @Override
+ public void run()
{
- @Override
- public void run()
- {
- nfs.frame.setBounds(fspos);
- }
- });
- this.featureSettings.close();
- this.featureSettings = null;
- }
- this.closeMenuItem_actionPerformed(true);
+ nfs.frame.setBounds(fspos);
+ }
+ });
+ this.featureSettings.close();
+ this.featureSettings = null;
}
+ this.closeMenuItem_actionPerformed(true);
}
+
}
@Override
public void addFromText_actionPerformed(ActionEvent e)
{
- Desktop.instance
+ Desktop.getInstance()
.inputTextboxMenuItem_actionPerformed(viewport.getAlignPanel());
}
@Override
public void addFromURL_actionPerformed(ActionEvent e)
{
- Desktop.instance.inputURLMenuItem_actionPerformed(viewport);
+ Desktop.getInstance().inputURLMenuItem_actionPerformed(viewport);
}
@Override
@@ -1145,6 +1198,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* Saves the alignment to a file with a name chosen by the user, if necessary
* warning if a file would be overwritten
*/
+
@Override
public void saveAs_actionPerformed()
{
@@ -1168,7 +1222,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
// todo is this (2005) test now obsolete - value is never null?
while (currentFileFormat == null)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager
.getString("label.select_file_format_before_saving"),
MessageManager.getString("label.file_format_not_specified"),
@@ -1199,6 +1253,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @return true if last call to saveAlignment(file, format) was successful.
*/
+
public boolean isSaveAlignmentSuccessful()
{
@@ -1231,6 +1286,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param file
* @param format
*/
+
public void saveAlignment(String file, FileFormatI format)
{
lastSaveSuccessful = true;
@@ -1242,21 +1298,23 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
String shortName = title;
if (shortName.indexOf(File.separatorChar) > -1)
{
- shortName = shortName.substring(
- shortName.lastIndexOf(File.separatorChar) + 1);
+ shortName = shortName
+ .substring(shortName.lastIndexOf(File.separatorChar) + 1);
}
- lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file, shortName);
-
+ lastSaveSuccessful = new Jalview2XML().saveAlignment(this, file,
+ shortName);
+
statusBar.setText(MessageManager.formatMessage(
"label.successfully_saved_to_file_in_format", new Object[]
{ fileName, format }));
-
+
return;
}
AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
Runnable cancelAction = new Runnable()
{
+
@Override
public void run()
{
@@ -1265,6 +1323,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
};
Runnable outputAction = new Runnable()
{
+
@Override
public void run()
{
@@ -1287,16 +1346,17 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
BackupFiles backupfiles = doBackup ? new BackupFiles(file) : null;
try
{
- String tempFilePath = doBackup ? backupfiles.getTempFilePath() : file;
- PrintWriter out = new PrintWriter(
- new FileWriter(tempFilePath));
+ String tempFilePath = doBackup ? backupfiles.getTempFilePath()
+ : file;
+ PrintWriter out = new PrintWriter(new FileWriter(tempFilePath));
out.print(output);
out.close();
AlignFrame.this.setTitle(file);
statusBar.setText(MessageManager.formatMessage(
- "label.successfully_saved_to_file_in_format", new Object[]
- { fileName, format.getName() }));
+ "label.successfully_saved_to_file_in_format",
+ new Object[]
+ { fileName, format.getName() }));
lastSaveSuccessful = true;
} catch (Exception ex)
{
@@ -1338,6 +1398,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @param fileFormatName
*/
+
@Override
protected void outputText_actionPerformed(String fileFormatName)
{
@@ -1346,6 +1407,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
AlignExportSettingsI options = new AlignExportSettingsAdapter(false);
Runnable outputAction = new Runnable()
{
+
@Override
public void run()
{
@@ -1396,6 +1458,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
protected void htmlMenuItem_actionPerformed(ActionEvent e)
{
@@ -1410,6 +1473,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
bjs.exportHTML(null);
}
+ // ??
+
public void createImageMap(File file, String image)
{
alignPanel.makePNGImageMap(file, image);
@@ -1421,6 +1486,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @param f
*/
+
@Override
public void createPNG(File f)
{
@@ -1433,6 +1499,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @param f
*/
+
@Override
public void createEPS(File f)
{
@@ -1445,6 +1512,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @param f
*/
+
@Override
public void createSVG(File f)
{
@@ -1464,6 +1532,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void printMenuItem_actionPerformed(ActionEvent e)
{
@@ -1490,11 +1559,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
final JalviewFileChooser chooser = new JalviewFileChooser(
jalview.bin.Cache.getProperty("LAST_DIRECTORY"));
chooser.setFileView(new JalviewFileView());
- String tooltip = MessageManager.getString("label.load_jalview_annotations");
+ String tooltip = MessageManager
+ .getString("label.load_jalview_annotations");
chooser.setDialogTitle(tooltip);
chooser.setToolTipText(tooltip);
chooser.setResponseHandler(0, new Runnable()
{
+
@Override
public void run()
{
@@ -1513,6 +1584,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @param closeAllTabs
*/
+
@Override
public void closeMenuItem_actionPerformed(boolean closeAllTabs)
{
@@ -1567,6 +1639,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @param panelToClose
*/
+
public void closeView(AlignmentPanel panelToClose)
{
int index = tabbedPane.getSelectedIndex();
@@ -1590,6 +1663,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
/**
* DOCUMENT ME!
*/
+
void updateEditMenuBar()
{
@@ -1643,6 +1717,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @return alignment objects for all views
*/
+
AlignmentI[] getViewAlignments()
{
if (alignPanels != null)
@@ -1668,6 +1743,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
protected void undoMenuItem_actionPerformed(ActionEvent e)
{
@@ -1695,8 +1771,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
// && viewport.getColumnSelection().getHiddenColumns() != null &&
// viewport.getColumnSelection()
// .getHiddenColumns().size() > 0);
- originalSource.firePropertyChange("alignment", null,
- originalSource.getAlignment().getSequences());
+ originalSource.notifyAlignment();
+
}
}
@@ -1706,6 +1782,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
protected void redoMenuItem_actionPerformed(ActionEvent e)
{
@@ -1735,8 +1812,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
// && viewport.getColumnSelection().getHiddenColumns() != null &&
// viewport.getColumnSelection()
// .getHiddenColumns().size() > 0);
- originalSource.firePropertyChange("alignment", null,
- originalSource.getAlignment().getSequences());
+ originalSource.notifyAlignment();
+
}
}
@@ -1788,6 +1865,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param up
* DOCUMENT ME!
*/
+
public void moveSelectedSequences(boolean up)
{
SequenceGroup sg = viewport.getSelectionGroup();
@@ -1912,6 +1990,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
protected void copy_actionPerformed()
{
@@ -1934,16 +2013,17 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
StringSelection ss = new StringSelection(output);
+ Desktop d = Desktop.getInstance();
try
{
- jalview.gui.Desktop.internalCopy = true;
+ d.internalCopy = true;
// Its really worth setting the clipboard contents
// to empty before setting the large StringSelection!!
Toolkit.getDefaultToolkit().getSystemClipboard()
.setContents(new StringSelection(""), null);
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,
- Desktop.instance);
+ Desktop.getInstance());
} catch (OutOfMemoryError er)
{
new OOMWarning("copying region", er);
@@ -1963,7 +2043,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
hiddenCutoff, hiddenOffset);
}
- Desktop.jalviewClipboard = new Object[] { seqs,
+ d.jalviewClipboard = new Object[] { seqs,
viewport.getAlignment().getDataset(), hiddenColumns };
setStatus(MessageManager.formatMessage(
"label.copied_sequences_to_clipboard", new Object[]
@@ -1976,6 +2056,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
protected void pasteNew_actionPerformed(ActionEvent e)
{
@@ -1988,6 +2069,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
protected void pasteThis_actionPerformed(ActionEvent e)
{
@@ -2000,6 +2082,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param newAlignment
* true to paste to a new alignment, otherwise add to this.
*/
+
void paste(boolean newAlignment)
{
boolean externalPaste = true;
@@ -2035,12 +2118,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
boolean annotationAdded = false;
AlignmentI alignment = null;
- if (Desktop.jalviewClipboard != null)
+ Desktop d = Desktop.getInstance();
+
+ if (d.jalviewClipboard != null)
{
// The clipboard was filled from within Jalview, we must use the
// sequences
// And dataset from the copied alignment
- SequenceI[] newseq = (SequenceI[]) Desktop.jalviewClipboard[0];
+ SequenceI[] newseq = (SequenceI[]) d.jalviewClipboard[0];
// be doubly sure that we create *new* sequence objects.
sequences = new SequenceI[newseq.length];
for (int i = 0; i < newseq.length; i++)
@@ -2065,10 +2150,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
if (newAlignment)
{
- if (Desktop.jalviewClipboard != null)
+ if (d.jalviewClipboard != null)
{
// dataset is inherited
- alignment.setDataset((Alignment) Desktop.jalviewClipboard[1]);
+ alignment.setDataset((Alignment) d.jalviewClipboard[1]);
}
else
{
@@ -2084,8 +2169,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
alignment = viewport.getAlignment();
alwidth = alignment.getWidth() + 1;
// decide if we need to import sequences from an existing dataset
- boolean importDs = Desktop.jalviewClipboard != null
- && Desktop.jalviewClipboard[1] != alignment.getDataset();
+ boolean importDs = d.jalviewClipboard != null
+ && d.jalviewClipboard[1] != alignment.getDataset();
// importDs==true instructs us to copy over new dataset sequences from
// an existing alignment
Vector newDs = (importDs) ? new Vector<>() : null; // used to
@@ -2266,8 +2351,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
}
buildSortByAnnotationScoresMenu();
}
- viewport.firePropertyChange("alignment", null,
- alignment.getSequences());
+ viewport.notifyAlignment();
if (alignPanels != null)
{
for (AlignmentPanel ap : alignPanels)
@@ -2287,10 +2371,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
DEFAULT_HEIGHT);
String newtitle = new String("Copied sequences");
- if (Desktop.jalviewClipboard != null
- && Desktop.jalviewClipboard[2] != null)
+ if (d.jalviewClipboard != null && d.jalviewClipboard[2] != null)
{
- HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
+ HiddenColumns hc = (HiddenColumns) d.jalviewClipboard[2];
af.viewport.setHiddenColumns(hc);
}
@@ -2342,11 +2425,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
AlignFrame af = new AlignFrame(alignment, DEFAULT_WIDTH,
DEFAULT_HEIGHT);
String newtitle = new String("Flanking alignment");
-
- if (Desktop.jalviewClipboard != null
- && Desktop.jalviewClipboard[2] != null)
+ Desktop d = Desktop.getInstance();
+ if (d.jalviewClipboard != null && d.jalviewClipboard[2] != null)
{
- HiddenColumns hc = (HiddenColumns) Desktop.jalviewClipboard[2];
+ HiddenColumns hc = (HiddenColumns) d.jalviewClipboard[2];
af.viewport.setHiddenColumns(hc);
}
@@ -2385,6 +2467,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
/**
* Action Cut (delete and copy) the selected region
*/
+
@Override
protected void cut_actionPerformed()
{
@@ -2395,6 +2478,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
/**
* Performs menu option to Delete the currently selected region
*/
+
@Override
protected void delete_actionPerformed()
{
@@ -2405,56 +2489,63 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
return;
}
- Runnable okAction = new Runnable()
- {
- @Override
- public void run()
- {
- SequenceI[] cut = sg.getSequences()
- .toArray(new SequenceI[sg.getSize()]);
-
- addHistoryItem(new EditCommand(
- MessageManager.getString("label.cut_sequences"), Action.CUT,
- cut, sg.getStartRes(), sg.getEndRes() - sg.getStartRes() + 1,
- viewport.getAlignment()));
-
- viewport.setSelectionGroup(null);
- viewport.sendSelection();
- viewport.getAlignment().deleteGroup(sg);
-
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
- if (viewport.getAlignment().getHeight() < 1)
- {
- try
- {
- AlignFrame.this.setClosed(true);
- } catch (Exception ex)
- {
- }
- }
- }};
+ Runnable okAction = new Runnable()
+ {
+
+ @Override
+ public void run()
+ {
+ SequenceI[] cut = sg.getSequences()
+ .toArray(new SequenceI[sg.getSize()]);
+
+ addHistoryItem(new EditCommand(
+ MessageManager.getString("label.cut_sequences"), Action.CUT,
+ cut, sg.getStartRes(),
+ sg.getEndRes() - sg.getStartRes() + 1,
+ viewport.getAlignment()));
+
+ viewport.setSelectionGroup(null);
+ viewport.sendSelection();
+ viewport.getAlignment().deleteGroup(sg);
+
+ viewport.notifyAlignment();
+
+ if (viewport.getAlignment().getHeight() < 1)
+ {
+ try
+ {
+ AlignFrame.this.setClosed(true);
+ } catch (Exception ex)
+ {
+ }
+ }
+ }
+ };
/*
* If the cut affects all sequences, prompt for confirmation
*/
- boolean wholeHeight = sg.getSize() == viewport.getAlignment().getHeight();
+ boolean wholeHeight = sg.getSize() == viewport.getAlignment()
+ .getHeight();
boolean wholeWidth = (((sg.getEndRes() - sg.getStartRes())
+ 1) == viewport.getAlignment().getWidth()) ? true : false;
- if (wholeHeight && wholeWidth)
- {
- JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
- dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
- Object[] options = new Object[] { MessageManager.getString("action.ok"),
- MessageManager.getString("action.cancel") };
- dialog.showDialog(MessageManager.getString("warn.delete_all"),
- MessageManager.getString("label.delete_all"),
- JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
- options, options[0]);
- } else
- {
- okAction.run();
- }
+ if (wholeHeight && wholeWidth)
+ {
+ JvOptionPane dialog = JvOptionPane
+ .newOptionDialog(Desktop.getDesktopPane());
+ dialog.setResponseHandler(0, okAction); // 0 = OK_OPTION
+ Object[] options = new Object[] {
+ MessageManager.getString("action.ok"),
+ MessageManager.getString("action.cancel") };
+ dialog.showDialog(MessageManager.getString("warn.delete_all"),
+ MessageManager.getString("label.delete_all"),
+ JvOptionPane.DEFAULT_OPTION, JvOptionPane.PLAIN_MESSAGE, null,
+ options, options[0]);
+ }
+ else
+ {
+ okAction.run();
+ }
}
/**
@@ -2463,6 +2554,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
protected void deleteGroups_actionPerformed(ActionEvent e)
{
@@ -2480,21 +2572,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void selectAllSequenceMenuItem_actionPerformed(ActionEvent e)
{
- SequenceGroup sg = new SequenceGroup(
- viewport.getAlignment().getSequences());
-
- sg.setEndRes(viewport.getAlignment().getWidth() - 1);
- viewport.setSelectionGroup(sg);
- viewport.isSelectionGroupChanged(true);
- viewport.sendSelection();
- // JAL-2034 - should delegate to
- // alignPanel to decide if overview needs
- // updating.
- alignPanel.paintAlignment(false, false);
- PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
+ alignPanel.selectAllSequences();
}
/**
@@ -2503,24 +2585,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void deselectAllSequenceMenuItem_actionPerformed(ActionEvent e)
{
- if (viewport.cursorMode)
- {
- alignPanel.getSeqPanel().keyboardNo1 = null;
- alignPanel.getSeqPanel().keyboardNo2 = null;
- }
- viewport.setSelectionGroup(null);
- viewport.getColumnSelection().clear();
- viewport.setSelectionGroup(null);
- alignPanel.getIdPanel().getIdCanvas().searchResults = null;
- // JAL-2034 - should delegate to
- // alignPanel to decide if overview needs
- // updating.
- alignPanel.paintAlignment(false, false);
- PaintRefresher.Refresh(alignPanel, viewport.getSequenceSetId());
- viewport.sendSelection();
+ alignPanel.deselectAllSequences();
}
/**
@@ -2529,6 +2598,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void invertSequenceMenuItem_actionPerformed(ActionEvent e)
{
@@ -2536,7 +2606,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
if (sg == null)
{
- selectAllSequenceMenuItem_actionPerformed(null);
+ alignPanel.selectAllSequences();
return;
}
@@ -2568,6 +2638,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void remove2LeftMenuItem_actionPerformed(ActionEvent e)
{
@@ -2580,6 +2651,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void remove2RightMenuItem_actionPerformed(ActionEvent e)
{
@@ -2626,8 +2698,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
column, viewport.getAlignment());
}
- setStatus(MessageManager
- .formatMessage("label.removed_columns", new String[]
+ setStatus(MessageManager.formatMessage("label.removed_columns",
+ new String[]
{ Integer.valueOf(trimRegion.getSize()).toString() }));
addHistoryItem(trimRegion);
@@ -2641,8 +2713,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
}
}
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
+
}
}
@@ -2652,6 +2724,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void removeGappedColumnMenuItem_actionPerformed(ActionEvent e)
{
@@ -2676,8 +2749,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
addHistoryItem(removeGapCols);
- setStatus(MessageManager
- .formatMessage("label.removed_empty_columns", new Object[]
+ setStatus(MessageManager.formatMessage("label.removed_empty_columns",
+ new Object[]
{ Integer.valueOf(removeGapCols.getSize()).toString() }));
// This is to maintain viewport position on first residue
@@ -2691,8 +2764,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
// if (viewport.hasHiddenColumns)
// viewport.getColumnSelection().compensateForEdits(shifts);
ranges.setStartRes(seq.findIndex(startRes) - 1);
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
+
}
@@ -2702,6 +2775,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void removeAllGapsMenuItem_actionPerformed(ActionEvent e)
{
@@ -2729,9 +2803,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
viewport.getAlignment()));
viewport.getRanges().setStartRes(seq.findIndex(startRes) - 1);
-
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
}
@@ -2741,12 +2813,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void padGapsMenuitem_actionPerformed(ActionEvent e)
{
viewport.setPadGaps(padGapsMenuitem.isSelected());
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
+
}
/**
@@ -2755,6 +2828,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void findMenuItem_actionPerformed(ActionEvent e)
{
@@ -2764,6 +2838,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
/**
* Create a new view of the current alignment.
*/
+
@Override
public void newView_actionPerformed(ActionEvent e)
{
@@ -2779,6 +2854,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* if true then duplicate all annnotation, groups and settings
* @return new alignment panel, already displayed.
*/
+
public AlignmentPanel newView(String viewTitle, boolean copyAnnotation)
{
/*
@@ -2799,8 +2875,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
if (viewport.getViewName() == null)
{
- viewport.setViewName(MessageManager
- .getString("label.view_name_original"));
+ viewport.setViewName(
+ MessageManager.getString("label.view_name_original"));
}
/*
@@ -2851,6 +2927,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param viewTitle
* @return
*/
+
protected String getNewViewName(String viewTitle)
{
int index = Desktop.getViewCount(viewport.getSequenceSetId());
@@ -2885,6 +2962,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param comps
* @return
*/
+
protected List getExistingViewNames(List comps)
{
List existingNames = new ArrayList<>();
@@ -2905,6 +2983,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
/**
* Explode tabbed views into separate windows.
*/
+
@Override
public void expandViews_actionPerformed(ActionEvent e)
{
@@ -2914,10 +2993,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
/**
* Gather views in separate windows back into a tabbed presentation.
*/
+
@Override
public void gatherViews_actionPerformed(ActionEvent e)
{
- Desktop.instance.gatherViews(this);
+ Desktop.getInstance().gatherViews(this);
}
/**
@@ -2926,6 +3006,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void font_actionPerformed(ActionEvent e)
{
@@ -2938,6 +3019,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
protected void seqLimit_actionPerformed(ActionEvent e)
{
@@ -2967,6 +3049,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @see jalview.jbgui.GAlignFrame#followHighlight_actionPerformed()
*/
+
@Override
protected void followHighlight_actionPerformed()
{
@@ -2988,6 +3071,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
protected void colourTextMenuItem_actionPerformed(ActionEvent e)
{
@@ -3001,6 +3085,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void wrapMenuItem_actionPerformed(ActionEvent e)
{
@@ -3037,6 +3122,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param toggleSeqs
* @param toggleCols
*/
+
protected void toggleHiddenRegions(boolean toggleSeqs, boolean toggleCols)
{
@@ -3104,6 +3190,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* jalview.jbgui.GAlignFrame#hideAllButSelection_actionPerformed(java.awt.
* event.ActionEvent)
*/
+
@Override
public void hideAllButSelection_actionPerformed(ActionEvent e)
{
@@ -3118,6 +3205,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* jalview.jbgui.GAlignFrame#hideAllSelection_actionPerformed(java.awt.event
* .ActionEvent)
*/
+
@Override
public void hideAllSelection_actionPerformed(ActionEvent e)
{
@@ -3137,6 +3225,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* jalview.jbgui.GAlignFrame#showAllhidden_actionPerformed(java.awt.event.
* ActionEvent)
*/
+
@Override
public void showAllhidden_actionPerformed(ActionEvent e)
{
@@ -3168,6 +3257,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
protected void scaleAbove_actionPerformed(ActionEvent e)
{
@@ -3182,6 +3272,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
protected void scaleLeft_actionPerformed(ActionEvent e)
{
@@ -3196,6 +3287,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
protected void scaleRight_actionPerformed(ActionEvent e)
{
@@ -3210,6 +3302,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void viewBoxesMenuItem_actionPerformed(ActionEvent e)
{
@@ -3223,6 +3316,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void viewTextMenuItem_actionPerformed(ActionEvent e)
{
@@ -3236,6 +3330,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
protected void renderGapsMenuItem_actionPerformed(ActionEvent e)
{
@@ -3281,6 +3376,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param evt
* DOCUMENT ME!
*/
+
@Override
public void showSeqFeatures_actionPerformed(ActionEvent evt)
{
@@ -3297,16 +3393,32 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @param e
*/
+
@Override
public void annotationPanelMenuItem_actionPerformed(ActionEvent e)
{
final boolean setVisible = annotationPanelMenuItem.isSelected();
viewport.setShowAnnotation(setVisible);
- this.showAllSeqAnnotations.setEnabled(setVisible);
- this.hideAllSeqAnnotations.setEnabled(setVisible);
- this.showAllAlAnnotations.setEnabled(setVisible);
- this.hideAllAlAnnotations.setEnabled(setVisible);
+ syncAnnotationMenuItems(setVisible);
alignPanel.updateLayout();
+ repaint();
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run()
+ {
+ alignPanel.updateScrollBarsFromRanges();
+ }
+
+ });
+ }
+
+ private void syncAnnotationMenuItems(boolean setVisible)
+ {
+ showAllSeqAnnotations.setEnabled(setVisible);
+ hideAllSeqAnnotations.setEnabled(setVisible);
+ showAllAlAnnotations.setEnabled(setVisible);
+ hideAllAlAnnotations.setEnabled(setVisible);
}
@Override
@@ -3326,7 +3438,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
JLabel textLabel = new JLabel();
textLabel.setText(content);
textLabel.setBackground(Color.WHITE);
-
+
pane = new JPanel(new BorderLayout());
((JPanel) pane).setOpaque(true);
pane.setBackground(Color.WHITE);
@@ -3360,6 +3472,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void overviewMenuItem_actionPerformed(ActionEvent e)
{
@@ -3369,12 +3482,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
}
JInternalFrame frame = new JInternalFrame();
-
-
// BH 2019.07.26 we allow for an embedded
// undecorated overview with defined size
- frame.setName(Jalview.getAppID("overview"));
+ frame.setName(Platform.getAppID("overview"));
//
Dimension dim = Platform.getDimIfEmbedded(frame, -1, -1);
if (dim != null && dim.width == 0)
@@ -3399,13 +3510,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
"resize") != "none");
Desktop.addInternalFrame(frame, MessageManager
.formatMessage("label.overview_params", new Object[]
- { this.getTitle() }), true, dim.width, dim.height, resizable,
- true);
+ { this.getTitle() }), Desktop.FRAME_MAKE_VISIBLE, dim.width,
+ dim.height, resizable, Desktop.FRAME_ALLOW_ANY_SIZE);
frame.pack();
frame.setLayer(JLayeredPane.PALETTE_LAYER);
frame.addInternalFrameListener(
new javax.swing.event.InternalFrameAdapter()
{
+
@Override
public void internalFrameClosed(
javax.swing.event.InternalFrameEvent evt)
@@ -3434,6 +3546,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* CovariationColourScheme(viewport.getAlignment().getAlignmentAnnotation
* ()[0])); }
*/
+
@Override
public void annotationColour_actionPerformed()
{
@@ -3453,6 +3566,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @param selected
*/
+
@Override
public void applyToAllGroups_actionPerformed(boolean selected)
{
@@ -3465,6 +3579,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param name
* the name (not the menu item label!) of the colour scheme
*/
+
@Override
public void changeColour_actionPerformed(String name)
{
@@ -3482,8 +3597,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* otherwise set the chosen colour scheme (or null for 'None')
*/
ColourSchemeI cs = ColourSchemes.getInstance().getColourScheme(name,
- viewport,
- viewport.getAlignment(), viewport.getHiddenRepSequences());
+ viewport, viewport.getAlignment(),
+ viewport.getHiddenRepSequences());
changeColour(cs);
}
@@ -3492,6 +3607,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @param cs
*/
+
@Override
public void changeColour(ColourSchemeI cs)
{
@@ -3506,6 +3622,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
/**
* Show the PID threshold slider panel
*/
+
@Override
protected void modifyPID_actionPerformed()
{
@@ -3517,6 +3634,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
/**
* Show the Conservation slider panel
*/
+
@Override
protected void modifyConservation_actionPerformed()
{
@@ -3528,6 +3646,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
/**
* Action on selecting or deselecting (Colour) By Conservation
*/
+
@Override
public void conservationMenuItem_actionPerformed(boolean selected)
{
@@ -3549,6 +3668,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
/**
* Action on selecting or deselecting (Colour) Above PID Threshold
*/
+
@Override
public void abovePIDThreshold_actionPerformed(boolean selected)
{
@@ -3577,6 +3697,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void sortPairwiseMenuItem_actionPerformed(ActionEvent e)
{
@@ -3594,6 +3715,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void sortIDMenuItem_actionPerformed(ActionEvent e)
{
@@ -3610,6 +3732,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void sortLengthMenuItem_actionPerformed(ActionEvent e)
{
@@ -3626,6 +3749,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void sortGroupMenuItem_actionPerformed(ActionEvent e)
{
@@ -3643,6 +3767,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void removeRedundancyMenuItem_actionPerformed(ActionEvent e)
{
@@ -3655,6 +3780,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
public void pairwiseAlignmentMenuItem_actionPerformed(ActionEvent e)
{
@@ -3680,11 +3806,14 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
@Override
public void autoCalculate_actionPerformed(ActionEvent e)
{
- viewport.autoCalculateConsensus = autoCalculate.isSelected();
- if (viewport.autoCalculateConsensus)
+ viewport.setAutoCalculateConsensusAndConservation(
+ autoCalculate.isSelected());
+ if (viewport.getAutoCalculateConsensusAndConservation())
+ // ??
+ // viewport.autoCalculateConsensus = autoCalculate.isSelected();
+ // if (viewport.autoCalculateConsensus)
{
- viewport.firePropertyChange("alignment", null,
- viewport.getAlignment().getSequences());
+ viewport.notifyAlignment();
}
}
@@ -3710,6 +3839,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param options
* parameters for the distance or similarity calculation
*/
+
void newTreePanel(String type, String modelName,
SimilarityParamsI options)
{
@@ -3727,7 +3857,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
{
if (_s.getLength() < sg.getEndRes())
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString(
"label.selected_region_to_tree_may_only_contain_residues_or_gaps"),
MessageManager.getString(
@@ -3771,6 +3901,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param order
* DOCUMENT ME!
*/
+
public void addSortByOrderMenuItem(String title,
final AlignmentOrder order)
{
@@ -3780,6 +3911,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
sort.add(item);
item.addActionListener(new java.awt.event.ActionListener()
{
+
@Override
public void actionPerformed(ActionEvent e)
{
@@ -3806,6 +3938,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* the label used to retrieve scores for each sequence on the
* alignment
*/
+
public void addSortByAnnotScoreMenuItem(JMenu sort,
final String scoreLabel)
{
@@ -3813,6 +3946,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
sort.add(item);
item.addActionListener(new java.awt.event.ActionListener()
{
+
@Override
public void actionPerformed(ActionEvent e)
{
@@ -3838,6 +3972,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* rebuilding in subsequence calls.
*
*/
+
@Override
public void buildSortByAnnotationScoresMenu()
{
@@ -3867,8 +4002,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
Enumeration labels = scoreSorts.keys();
while (labels.hasMoreElements())
{
- addSortByAnnotScoreMenuItem(sortByAnnotScore,
- labels.nextElement());
+ addSortByAnnotScoreMenuItem(sortByAnnotScore, labels.nextElement());
}
sortByAnnotScore.setVisible(scoreSorts.size() > 0);
scoreSorts.clear();
@@ -3879,41 +4013,38 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
}
/**
+ * Enable (or, if desired, make visible) the By Tree
+ * submenu only if it has at least one element (or will have).
+ *
+ */
+ @Override
+ protected void enableSortMenuOptions()
+ {
+ List treePanels = getTreePanels();
+ sortByTreeMenu.setEnabled(!treePanels.isEmpty());
+ }
+
+ /**
* Maintain the Order by->Displayed Tree menu. Creates a new menu item for a
* TreePanel with an appropriate jalview.analysis.AlignmentSorter
* call. Listeners are added to remove the menu item when the treePanel is
* closed, and adjust the tree leaf to sequence mapping when the alignment is
* modified.
*/
+
@Override
public void buildTreeSortMenu()
{
sortByTreeMenu.removeAll();
- List comps = PaintRefresher.components
- .get(viewport.getSequenceSetId());
- List treePanels = new ArrayList<>();
- for (Component comp : comps)
- {
- if (comp instanceof TreePanel)
- {
- treePanels.add((TreePanel) comp);
- }
- }
-
- if (treePanels.size() < 1)
- {
- sortByTreeMenu.setVisible(false);
- return;
- }
-
- sortByTreeMenu.setVisible(true);
+ List treePanels = getTreePanels();
for (final TreePanel tp : treePanels)
{
final JMenuItem item = new JMenuItem(tp.getTitle());
item.addActionListener(new java.awt.event.ActionListener()
{
+
@Override
public void actionPerformed(ActionEvent e)
{
@@ -3927,6 +4058,21 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
}
}
+ private List getTreePanels()
+ {
+ List comps = PaintRefresher.components
+ .get(viewport.getSequenceSetId());
+ List treePanels = new ArrayList<>();
+ for (Component comp : comps)
+ {
+ if (comp instanceof TreePanel)
+ {
+ treePanels.add((TreePanel) comp);
+ }
+ }
+ return treePanels;
+ }
+
public boolean sortBy(AlignmentOrder alorder, String undoname)
{
SequenceI[] oldOrder = viewport.getAlignment().getSequencesArray();
@@ -3945,6 +4091,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* be submitted for multiple alignment.
*
*/
+
public jalview.datamodel.AlignmentView gatherSequencesForAlignment()
{
// Now, check we have enough sequences
@@ -3990,6 +4137,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* region or the whole alignment. (where the first sequence in the set is the
* one that the prediction will be for).
*/
+
public AlignmentView gatherSeqOrMsaForSecStrPrediction()
{
AlignmentView seqs = null;
@@ -4023,6 +4171,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param e
* DOCUMENT ME!
*/
+
@Override
protected void loadTreeMenuItem_actionPerformed(ActionEvent e)
{
@@ -4035,8 +4184,9 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
chooser.setToolTipText(
MessageManager.getString("label.load_tree_file"));
- chooser.setResponseHandler(0,new Runnable()
+ chooser.setResponseHandler(0, new Runnable()
{
+
@Override
public void run()
{
@@ -4050,7 +4200,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
viewport.setCurrentTree(showNewickTree(fin, filePath).getTree());
} catch (Exception ex)
{
- JvOptionPane.showMessageDialog(Desktop.desktop, ex.getMessage(),
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
+ ex.getMessage(),
MessageManager
.getString("label.problem_reading_tree_file"),
JvOptionPane.WARNING_MESSAGE);
@@ -4058,7 +4209,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
}
if (fin != null && fin.hasWarningMessage())
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
fin.getWarningMessage(),
MessageManager.getString(
"label.possible_problem_with_tree_file"),
@@ -4100,6 +4251,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* position
* @return TreePanel handle
*/
+
public TreePanel showNewickTree(NewickFile nf, String treeTitle,
AlignmentView input, int w, int h, int x, int y)
{
@@ -4145,6 +4297,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* Generates menu items and listener event actions for web service clients
*
*/
+
public void BuildWebServiceMenu()
{
while (buildingMenu)
@@ -4161,6 +4314,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
buildingMenu = true;
new Thread(new Runnable()
{
+
@Override
public void run()
{
@@ -4195,9 +4349,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
final JMenu dismenu = new JMenu("Protein Disorder");
// JAL-940 - only show secondary structure prediction services from
// the legacy server
+ Hashtable> ds = Discoverer
+ .getInstance().getServices();
if (// Cache.getDefault("SHOW_JWS1_SERVICES", true)
// &&
- Discoverer.services != null && (Discoverer.services.size() > 0))
+ ds != null && (ds.size() > 0))
{
// TODO: refactor to allow list of AbstractName/Handler bindings to
// be
@@ -4205,15 +4361,13 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
// No MSAWS used any more:
// Vector msaws = null; // (Vector)
// Discoverer.services.get("MsaWS");
- Vector secstrpr = Discoverer.services
- .get("SecStrPred");
+ Vector secstrpr = ds.get("SecStrPred");
if (secstrpr != null)
{
// Add any secondary structure prediction services
for (int i = 0, j = secstrpr.size(); i < j; i++)
{
- final ext.vamsas.ServiceHandle sh = secstrpr
- .get(i);
+ final ext.vamsas.ServiceHandle sh = secstrpr.get(i);
jalview.ws.WSMenuEntryProviderI impl = jalview.ws.jws1.Discoverer
.getServiceClient(sh);
int p = secstrmenu.getItemCount();
@@ -4238,6 +4392,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
+
@Override
public void run()
{
@@ -4257,10 +4412,10 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
webService.add(me.webServiceNoServices);
}
// TODO: move into separate menu builder class.
- boolean new_sspred = false;
+ // boolean new_sspred = false;
if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
{
- Jws2Discoverer jws2servs = Jws2Discoverer.getDiscoverer();
+ Jws2Discoverer jws2servs = Jws2Discoverer.getInstance();
if (jws2servs != null)
{
if (jws2servs.hasServices())
@@ -4322,6 +4477,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @param webService
*/
+
protected void build_urlServiceMenu(JMenu webService)
{
// TODO: remove this code when 2.7 is released
@@ -4330,7 +4486,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* JMenuItem testAlView = new JMenuItem("Test AlignmentView"); final
* AlignFrame af = this; testAlView.addActionListener(new ActionListener() {
*
- * @Override public void actionPerformed(ActionEvent e) {
+ * public void actionPerformed(ActionEvent e) {
* jalview.datamodel.AlignmentView
* .testSelectionViews(af.viewport.getAlignment(),
* af.viewport.getColumnSelection(), af.viewport.selectionGroup); }
@@ -4359,6 +4515,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @return true if Show Cross-references menu should be enabled
*/
+
public boolean canShowProducts()
{
SequenceI[] seqs = viewport.getAlignment().getSequencesArray();
@@ -4386,6 +4543,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
JMenuItem xtype = new JMenuItem(source);
xtype.addActionListener(new ActionListener()
{
+
@Override
public void actionPerformed(ActionEvent e)
{
@@ -4418,6 +4576,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param source
* the database to show cross-references for
*/
+
protected void showProductsFor(final SequenceI[] sel, final boolean _odna,
final String source)
{
@@ -4429,6 +4588,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* Construct and display a new frame containing the translation of this
* frame's DNA sequences to their aligned protein (amino acid) equivalents.
*/
+
@Override
public void showTranslation_actionPerformed(GeneticCodeI codeTable)
{
@@ -4447,8 +4607,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
final String errorTitle = MessageManager
.getString("label.implementation_error")
+ MessageManager.getString("label.translation_failed");
- JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
- JvOptionPane.ERROR_MESSAGE);
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(), msg,
+ errorTitle, JvOptionPane.ERROR_MESSAGE);
return;
}
if (al == null || al.getHeight() == 0)
@@ -4457,8 +4617,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
"label.select_at_least_three_bases_in_at_least_one_sequence_to_cDNA_translation");
final String errorTitle = MessageManager
.getString("label.translation_failed");
- JvOptionPane.showMessageDialog(Desktop.desktop, msg, errorTitle,
- JvOptionPane.WARNING_MESSAGE);
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(), msg,
+ errorTitle, JvOptionPane.WARNING_MESSAGE);
}
else
{
@@ -4486,6 +4646,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @param format
*/
+
public void setFileFormat(FileFormatI format)
{
this.currentFileFormat = format;
@@ -4500,11 +4661,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* access mode of file (see jalview.io.AlignFile)
* @return true if features file was parsed correctly.
*/
+
public boolean parseFeaturesFile(Object file, DataSourceType sourceType)
{
// BH 2018
return avc.parseFeaturesFile(file, sourceType,
- Cache.getDefault("RELAXEDSEQIDMATCHING", false));
+ Cache.getDefault(Preferences.RELAXEDSEQIDMATCHING, false));
}
@@ -4550,184 +4712,190 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
evt.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
Transferable t = evt.getTransferable();
- final AlignFrame thisaf = this;
final List files = new ArrayList<>();
List protocols = new ArrayList<>();
try
{
Desktop.transferFromDropTarget(files, protocols, evt, t);
+ if (files.size() > 0)
+ {
+ new Thread(new Runnable()
+ {
+
+ @Override
+ public void run()
+ {
+ loadDroppedFiles(files, protocols, evt, t);
+ }
+ }).start();
+ }
} catch (Exception e)
{
e.printStackTrace();
}
- if (files != null)
+ }
+
+ protected void loadDroppedFiles(List files,
+ List protocols, DropTargetDropEvent evt,
+ Transferable t)
+ {
+ try
{
- new Thread(new Runnable()
+ // check to see if any of these files have names matching sequences
+ // in
+ // the alignment
+ SequenceIdMatcher idm = new SequenceIdMatcher(
+ viewport.getAlignment().getSequencesArray());
+ /**
+ * Object[] { String,SequenceI}
+ */
+ ArrayList filesmatched = new ArrayList<>();
+ ArrayList filesnotmatched = new ArrayList<>();
+ for (int i = 0; i < files.size(); i++)
{
- @Override
- public void run()
+ // BH 2018
+ Object file = files.get(i);
+ String fileName = file.toString();
+ String pdbfn = "";
+ DataSourceType protocol = (file instanceof File
+ ? DataSourceType.FILE
+ : FormatAdapter.checkProtocol(fileName));
+ if (protocol == DataSourceType.FILE)
{
- try
+ File fl;
+ if (file instanceof File)
+ {
+ fl = (File) file;
+ Platform.cacheFileData(fl);
+ }
+ else
+ {
+ fl = new File(fileName);
+ }
+ pdbfn = fl.getName();
+ }
+ else if (protocol == DataSourceType.URL)
+ {
+ URL url = new URL(fileName);
+ pdbfn = url.getFile();
+ }
+ if (pdbfn.length() > 0)
+ {
+ // attempt to find a match in the alignment
+ SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
+ int l = 0, c = pdbfn.indexOf(".");
+ while (mtch == null && c != -1)
{
- // check to see if any of these files have names matching sequences
- // in
- // the alignment
- SequenceIdMatcher idm = new SequenceIdMatcher(
- viewport.getAlignment().getSequencesArray());
- /**
- * Object[] { String,SequenceI}
- */
- ArrayList filesmatched = new ArrayList<>();
- ArrayList filesnotmatched = new ArrayList<>();
- for (int i = 0; i < files.size(); i++)
+ do
{
- // BH 2018
- Object file = files.get(i);
- String fileName = file.toString();
- String pdbfn = "";
- DataSourceType protocol = (file instanceof File
- ? DataSourceType.FILE
- : FormatAdapter.checkProtocol(fileName));
- if (protocol == DataSourceType.FILE)
- {
- File fl;
- if (file instanceof File) {
- fl = (File) file;
- Platform.cacheFileData(fl);
- } else {
- fl = new File(fileName);
- }
- pdbfn = fl.getName();
- }
- else if (protocol == DataSourceType.URL)
- {
- URL url = new URL(fileName);
- pdbfn = url.getFile();
- }
- if (pdbfn.length() > 0)
- {
- // attempt to find a match in the alignment
- SequenceI[] mtch = idm.findAllIdMatches(pdbfn);
- int l = 0, c = pdbfn.indexOf(".");
- while (mtch == null && c != -1)
- {
- do
- {
- l = c;
- } while ((c = pdbfn.indexOf(".", l)) > l);
- if (l > -1)
- {
- pdbfn = pdbfn.substring(0, l);
- }
- mtch = idm.findAllIdMatches(pdbfn);
- }
- if (mtch != null)
- {
- FileFormatI type;
- try
- {
- type = new IdentifyFile().identify(file, protocol);
- } catch (Exception ex)
- {
- type = null;
- }
- if (type != null && type.isStructureFile())
- {
- filesmatched.add(new Object[] { file, protocol, mtch });
- continue;
- }
- }
- // File wasn't named like one of the sequences or wasn't a PDB
- // file.
- filesnotmatched.add(file);
- }
+ l = c;
+ } while ((c = pdbfn.indexOf(".", l)) > l);
+ if (l > -1)
+ {
+ pdbfn = pdbfn.substring(0, l);
}
- int assocfiles = 0;
- if (filesmatched.size() > 0)
+ mtch = idm.findAllIdMatches(pdbfn);
+ }
+ if (mtch != null)
+ {
+ FileFormatI type;
+ try
{
- boolean autoAssociate = Cache
- .getDefault("AUTOASSOCIATE_PDBANDSEQS", false);
- if (!autoAssociate)
- {
- String msg = MessageManager.formatMessage(
- "label.automatically_associate_structure_files_with_sequences_same_name",
- new Object[]
- { Integer.valueOf(filesmatched.size())
- .toString() });
- String ttl = MessageManager.getString(
- "label.automatically_associate_structure_files_by_name");
- int choice = JvOptionPane.showConfirmDialog(thisaf, msg,
- ttl, JvOptionPane.YES_NO_OPTION);
- autoAssociate = choice == JvOptionPane.YES_OPTION;
- }
- if (autoAssociate)
- {
- for (Object[] fm : filesmatched)
- {
- // try and associate
- // TODO: may want to set a standard ID naming formalism for
- // associating PDB files which have no IDs.
- for (SequenceI toassoc : (SequenceI[]) fm[2])
- {
- PDBEntry pe = new AssociatePdbFileWithSeq()
- .associatePdbWithSeq(fm[0].toString(),
- (DataSourceType) fm[1], toassoc, false,
- Desktop.instance);
- if (pe != null)
- {
- System.err.println("Associated file : "
- + (fm[0].toString()) + " with "
- + toassoc.getDisplayId(true));
- assocfiles++;
- }
- }
- // TODO: do we need to update overview ? only if features are
- // shown I guess
- alignPanel.paintAlignment(true, false);
- }
- }
- else
- {
- /*
- * add declined structures as sequences
- */
- for (Object[] o : filesmatched)
- {
- filesnotmatched.add(o[0]);
- }
- }
+ type = new IdentifyFile().identify(file, protocol);
+ } catch (Exception ex)
+ {
+ type = null;
}
- if (filesnotmatched.size() > 0)
+ if (type != null && type.isStructureFile())
{
- if (assocfiles > 0 && (Cache.getDefault(
- "AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
- || JvOptionPane.showConfirmDialog(thisaf,
- "" + MessageManager.formatMessage(
- "label.ignore_unmatched_dropped_files_info",
- new Object[]
- { Integer.valueOf(
- filesnotmatched.size())
- .toString() })
- + "",
- MessageManager.getString(
- "label.ignore_unmatched_dropped_files"),
- JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
- {
- return;
- }
- for (Object fn : filesnotmatched)
+ filesmatched.add(new Object[] { file, protocol, mtch });
+ continue;
+ }
+ }
+ // File wasn't named like one of the sequences or wasn't a PDB
+ // file.
+ filesnotmatched.add(file);
+ }
+ }
+ int assocfiles = 0;
+ if (filesmatched.size() > 0)
+ {
+ boolean autoAssociate = Cache
+ .getDefault(Preferences.AUTOASSOCIATE_PDBANDSEQS, false);
+ if (!autoAssociate)
+ {
+ String msg = MessageManager.formatMessage(
+ "label.automatically_associate_structure_files_with_sequences_same_name",
+ new Object[]
+ { Integer.valueOf(filesmatched.size()).toString() });
+ String ttl = MessageManager.getString(
+ "label.automatically_associate_structure_files_by_name");
+ int choice = JvOptionPane.showConfirmDialog(this, msg, ttl,
+ JvOptionPane.YES_NO_OPTION);
+ autoAssociate = choice == JvOptionPane.YES_OPTION;
+ }
+ if (autoAssociate)
+ {
+ for (Object[] fm : filesmatched)
+ {
+ // try and associate
+ // TODO: may want to set a standard ID naming formalism for
+ // associating PDB files which have no IDs.
+ for (SequenceI toassoc : (SequenceI[]) fm[2])
+ {
+ PDBEntry pe = AssociatePdbFileWithSeq.associatePdbWithSeq(
+ fm[0].toString(), (DataSourceType) fm[1], toassoc,
+ false);
+ if (pe != null)
{
- loadJalviewDataFile(fn, null, null, null);
+ System.err.println("Associated file : " + (fm[0].toString())
+ + " with " + toassoc.getDisplayId(true));
+ assocfiles++;
}
-
}
- } catch (Exception ex)
+ // TODO: do we need to update overview ? only if features are
+ // shown I guess
+ alignPanel.paintAlignment(true, false);
+ }
+ }
+ else
+ {
+ /*
+ * add declined structures as sequences
+ */
+ for (Object[] o : filesmatched)
{
- ex.printStackTrace();
+ filesnotmatched.add(o[0]);
}
}
- }).start();
+ }
+ if (filesnotmatched.size() > 0)
+ {
+ if (assocfiles > 0 && (Cache
+ .getDefault("AUTOASSOCIATE_PDBANDSEQS_IGNOREOTHERS", false)
+ || JvOptionPane.showConfirmDialog(this,
+ "" + MessageManager.formatMessage(
+ "label.ignore_unmatched_dropped_files_info",
+ new Object[]
+ { Integer.valueOf(filesnotmatched.size())
+ .toString() })
+ + "",
+ MessageManager.getString(
+ "label.ignore_unmatched_dropped_files"),
+ JvOptionPane.YES_NO_OPTION) == JvOptionPane.YES_OPTION))
+ {
+ return;
+ }
+ for (Object fn : filesnotmatched)
+ {
+ loadJalviewDataFile(fn, null, null, null);
+ }
+
+ }
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
}
}
@@ -4743,6 +4911,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param file
* either a filename or a URL string.
*/
+
public void loadJalviewDataFile(Object file, DataSourceType sourceType,
FileFormatI format, SequenceI assocSeq)
{
@@ -4784,7 +4953,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
{
// some problem - if no warning its probable that the ID matching
// process didn't work
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
tcf.getWarningMessage() == null
? MessageManager.getString(
"label.check_file_matches_sequence_ids_alignment")
@@ -4881,7 +5050,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
+ (format != null
? "(parsing as '" + format + "' file)"
: ""),
- oom, Desktop.desktop);
+ oom, Desktop.getDesktopPane());
}
}
@@ -4907,6 +5076,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param state
* visible or invisible
*/
+
public void setFeatureGroupState(String[] groups, boolean state)
{
jalview.api.FeatureRenderer fr = null;
@@ -4924,11 +5094,11 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
}
}
-
/**
* Method invoked by the ChangeListener on the tabbed pane, in other words
* when a different tabbed pane is selected by the user or programmatically.
*/
+
@Override
public void tabSelectionChanged(int index)
{
@@ -4999,6 +5169,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
/**
* On right mouse click on view tab, prompt for and set new view name.
*/
+
@Override
public void tabbedPane_mousePressed(MouseEvent e)
{
@@ -5025,6 +5196,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
/**
* Open the dialog for regex description parsing.
*/
+
@Override
protected void extractScores_actionPerformed(ActionEvent e)
{
@@ -5048,6 +5220,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* jalview.jbgui.GAlignFrame#showDbRefs_actionPerformed(java.awt.event.ActionEvent
* )
*/
+
@Override
protected void showDbRefs_actionPerformed(ActionEvent e)
{
@@ -5060,6 +5233,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @seejalview.jbgui.GAlignFrame#showNpFeats_actionPerformed(java.awt.event.
* ActionEvent)
*/
+
@Override
protected void showNpFeats_actionPerformed(ActionEvent e)
{
@@ -5072,6 +5246,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @param av
*/
+
public boolean closeView(AlignViewportI av)
{
if (viewport == av)
@@ -5115,6 +5290,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
Cache.getDefault(DBRefFetcher.TRIM_RETRIEVED_SEQUENCES, true));
trimrs.addActionListener(new ActionListener()
{
+
@Override
public void actionPerformed(ActionEvent e)
{
@@ -5136,6 +5312,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
{
new Thread(new Runnable()
{
+
@Override
public void run()
{
@@ -5147,6 +5324,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
alignPanel.alignFrame.featureSettings, isNucleotide);
dbRefFetcher.addListener(new FetchFinishedListenerI()
{
+
@Override
public void finished()
{
@@ -5170,16 +5348,21 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
rfetch.add(fetchr);
new Thread(new Runnable()
{
+
@Override
public void run()
{
- final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
- .getSequenceFetcherSingleton();
+ // ??
+ // final jalview.ws.SequenceFetcher sf = jalview.gui.SequenceFetcher
+ // .getSequenceFetcherSingleton();
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
+
@Override
public void run()
{
+ jalview.ws.SequenceFetcher sf = jalview.ws.SequenceFetcher
+ .getInstance();
String[] dbclasses = sf.getNonAlignmentSources();
List otherdb;
JMenu dfetch = new JMenu();
@@ -5203,9 +5386,8 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
}
if (otherdb.size() == 1)
{
- final DbSourceProxy[] dassource = otherdb
- .toArray(new DbSourceProxy[0]);
DbSourceProxy src = otherdb.get(0);
+ DbSourceProxy[] dassource = new DbSourceProxy[] { src };
fetchr = new JMenuItem(src.getDbSource());
fetchr.addActionListener(new ActionListener()
{
@@ -5230,6 +5412,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
dbRefFetcher
.addListener(new FetchFinishedListenerI()
{
+
@Override
public void finished()
{
@@ -5264,6 +5447,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
{ src.getDbSource() }));
fetchr.addActionListener(new ActionListener()
{
+
@Override
public void actionPerformed(ActionEvent e)
{
@@ -5284,6 +5468,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
dbRefFetcher
.addListener(new FetchFinishedListenerI()
{
+
@Override
public void finished()
{
@@ -5352,6 +5537,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
dbRefFetcher
.addListener(new FetchFinishedListenerI()
{
+
@Override
public void finished()
{
@@ -5403,23 +5589,23 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
/**
* Left justify the whole alignment.
*/
+
@Override
protected void justifyLeftMenuItem_actionPerformed(ActionEvent e)
{
- AlignmentI al = viewport.getAlignment();
- al.justify(false);
- viewport.firePropertyChange("alignment", null, al);
+ viewport.getAlignment().justify(false);
+ viewport.notifyAlignment();
}
/**
* Right justify the whole alignment.
*/
+
@Override
protected void justifyRightMenuItem_actionPerformed(ActionEvent e)
{
- AlignmentI al = viewport.getAlignment();
- al.justify(true);
- viewport.firePropertyChange("alignment", null, al);
+ viewport.getAlignment().justify(true);
+ viewport.notifyAlignment();
}
@Override
@@ -5436,6 +5622,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* jalview.jbgui.GAlignFrame#showUnconservedMenuItem_actionPerformed(java.
* awt.event.ActionEvent)
*/
+
@Override
protected void showUnconservedMenuItem_actionPerformed(ActionEvent e)
{
@@ -5450,6 +5637,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* jalview.jbgui.GAlignFrame#showGroupConsensus_actionPerformed(java.awt.event
* .ActionEvent)
*/
+
@Override
protected void showGroupConsensus_actionPerformed(ActionEvent e)
{
@@ -5465,6 +5653,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* jalview.jbgui.GAlignFrame#showGroupConservation_actionPerformed(java.awt
* .event.ActionEvent)
*/
+
@Override
protected void showGroupConservation_actionPerformed(ActionEvent e)
{
@@ -5479,6 +5668,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* jalview.jbgui.GAlignFrame#showConsensusHistogram_actionPerformed(java.awt
* .event.ActionEvent)
*/
+
@Override
protected void showConsensusHistogram_actionPerformed(ActionEvent e)
{
@@ -5493,6 +5683,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* jalview.jbgui.GAlignFrame#showConsensusProfile_actionPerformed(java.awt
* .event.ActionEvent)
*/
+
@Override
protected void showSequenceLogo_actionPerformed(ActionEvent e)
{
@@ -5522,6 +5713,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* jalview.jbgui.GAlignFrame#makeGrpsFromSelection_actionPerformed(java.awt
* .event.ActionEvent)
*/
+
@Override
protected void makeGrpsFromSelection_actionPerformed(ActionEvent e)
{
@@ -5573,6 +5765,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @param alignmentPanel
*/
+
public void setDisplayedView(AlignmentPanel alignmentPanel)
{
if (!viewport.getSequenceSetId()
@@ -5597,6 +5790,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param forAlignment
* update non-sequence-related annotations
*/
+
@Override
protected void setAnnotationsVisibility(boolean visible,
boolean forSequences, boolean forAlignment)
@@ -5630,6 +5824,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
/**
* Store selected annotation sort order for the view and repaint.
*/
+
@Override
protected void sortAnnotations_actionPerformed()
{
@@ -5643,6 +5838,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @return alignment panels in this alignment frame
*/
+
public List extends AlignmentViewPanel> getAlignPanels()
{
// alignPanels is never null
@@ -5654,6 +5850,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* Open a new alignment window, with the cDNA associated with this (protein)
* alignment, aligned as is the protein.
*/
+
protected void viewAsCdna_actionPerformed()
{
// TODO no longer a menu action - refactor as required
@@ -5704,6 +5901,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @param show
*/
+
@Override
protected void showComplement_actionPerformed(boolean show)
{
@@ -5718,6 +5916,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* Generate the reverse (optionally complemented) of the selected sequences,
* and add them to the alignment
*/
+
@Override
protected void showReverse_actionPerformed(boolean complement)
{
@@ -5743,6 +5942,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* AlignFrame is set as currentAlignFrame in Desktop, to allow the script to
* be targeted at this alignment.
*/
+
@Override
protected void runGroovy_actionPerformed()
{
@@ -5756,7 +5956,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
} catch (Exception ex)
{
System.err.println((ex.toString()));
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString("label.couldnt_run_groovy_script"),
MessageManager.getString("label.groovy_support_failed"),
JvOptionPane.ERROR_MESSAGE);
@@ -5776,6 +5976,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* @param columnsContaining
* @return
*/
+
public boolean hideFeatureColumns(String featureType,
boolean columnsContaining)
{
@@ -5808,6 +6009,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* Rebuilds the Colour menu, including any user-defined colours which have
* been loaded either on startup or during the session
*/
+
public void buildColourMenu()
{
colourMenu.removeAll();
@@ -5835,6 +6037,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* Open a dialog (if not already open) that allows the user to select and
* calculate PCA or Tree analysis
*/
+
protected void openTreePcaDialog()
{
if (alignPanel.getCalculationDialog() == null)
@@ -5854,6 +6057,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
final AlignFrame us = this;
chooser.setResponseHandler(0, new Runnable()
{
+
@Override
public void run()
{
@@ -5868,6 +6072,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
}
private Rectangle lastFeatureSettingsBounds = null;
+
@Override
public void setFeatureSettingsGeometry(Rectangle bounds)
{
@@ -5904,12 +6109,12 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
* true is visible
* @return list
*/
+
public String[] getFeatureGroupsOfState(boolean visible)
{
jalview.api.FeatureRenderer fr = null;
if (alignPanel != null
- && (fr = alignPanel
- .getFeatureRenderer()) != null)
+ && (fr = alignPanel.getFeatureRenderer()) != null)
{
List gps = fr.getGroups(visible);
String[] _gps = gps.toArray(new String[gps.size()]);
@@ -5922,6 +6127,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
*
* @return list of feature groups on the view
*/
+
public String[] getFeatureGroups()
{
jalview.api.FeatureRenderer fr = null;
@@ -5941,43 +6147,47 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
alignPanel.getSeqPanel().selection(sel, csel, hidden, null);
}
-
-}
-
-class PrintThread extends Thread
-{
- AlignmentPanel ap;
-
- public PrintThread(AlignmentPanel ap)
+ public int getID()
{
- this.ap = ap;
+ return id;
}
- static PageFormat pf;
-
- @Override
- public void run()
+ static class PrintThread extends Thread
{
- PrinterJob printJob = PrinterJob.getPrinterJob();
+ AlignmentPanel ap;
- if (pf != null)
+ public PrintThread(AlignmentPanel ap)
{
- printJob.setPrintable(ap, pf);
- }
- else
- {
- printJob.setPrintable(ap);
+ this.ap = ap;
}
- if (printJob.printDialog())
+ static PageFormat pf;
+
+ @Override
+ public void run()
{
- try
+ PrinterJob printJob = PrinterJob.getPrinterJob();
+
+ if (pf != null)
+ {
+ printJob.setPrintable(ap, pf);
+ }
+ else
{
- printJob.print();
- } catch (Exception PrintException)
+ printJob.setPrintable(ap);
+ }
+
+ if (printJob.printDialog())
{
- PrintException.printStackTrace();
+ try
+ {
+ printJob.print();
+ } catch (Exception PrintException)
+ {
+ PrintException.printStackTrace();
+ }
}
}
}
}
+
diff --git a/src/jalview/gui/AlignViewport.java b/src/jalview/gui/AlignViewport.java
index 1849447..7ab84ad 100644
--- a/src/jalview/gui/AlignViewport.java
+++ b/src/jalview/gui/AlignViewport.java
@@ -223,7 +223,7 @@ f */
setRightAlignIds(Cache.getDefault("RIGHT_ALIGN_IDS", false));
setCentreColumnLabels(Cache.getDefault("CENTRE_COLUMN_LABELS", false));
- autoCalculateConsensus = Cache.getDefault("AUTO_CALC_CONSENSUS", true);
+ autoCalculateConsensusAndConservation = Cache.getDefault("AUTO_CALC_CONSENSUS", true);
setPadGaps(Cache.getDefault("PAD_GAPS", true));
setShowNPFeats(Cache.getDefault("SHOW_NPFEATS_TOOLTIP", true));
@@ -394,7 +394,7 @@ f */
if (align != null)
{
StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
ssm.registerMappings(align.getCodonFrames());
}
@@ -416,7 +416,7 @@ f */
if (mappings != null)
{
StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
for (AlignedCodonFrame acf : mappings)
{
if (noReferencesTo(acf))
@@ -542,7 +542,7 @@ f */
public void sendSelection()
{
jalview.structure.StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance)
+ .getStructureSelectionManager(Desktop.getInstance())
.sendSelection(new SequenceGroup(getSelectionGroup()),
new ColumnSelection(getColumnSelection()),
new HiddenColumns(getAlignment().getHiddenColumns()),
@@ -588,7 +588,7 @@ f */
public StructureSelectionManager getStructureSelectionManager()
{
return StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
}
@Override
@@ -754,7 +754,8 @@ f */
}
ranges.setEndSeq(getAlignment().getHeight() - 1); // BH 2019.04.18
- firePropertyChange("alignment", null, getAlignment().getSequences());
+ notifyAlignment();
+
}
/**
@@ -780,7 +781,7 @@ f */
* dialog responses 0, 1, 2 (even though JOptionPane shows them
* in reverse order)
*/
- JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop)
+ JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.getDesktopPane())
.setResponseHandler(NO_SPLIT, new Runnable()
{
@Override
@@ -1147,4 +1148,5 @@ f */
{
this.viewName = viewName;
}
+
}
diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java
index eb612c8..b57bc08 100644
--- a/src/jalview/gui/AlignmentPanel.java
+++ b/src/jalview/gui/AlignmentPanel.java
@@ -20,29 +20,6 @@
*/
package jalview.gui;
-import jalview.analysis.AnnotationSorter;
-import jalview.api.AlignViewportI;
-import jalview.api.AlignmentViewPanel;
-import jalview.bin.Cache;
-import jalview.bin.Jalview;
-import jalview.datamodel.AlignmentI;
-import jalview.datamodel.HiddenColumns;
-import jalview.datamodel.SearchResultsI;
-import jalview.datamodel.SequenceFeature;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
-import jalview.gui.ImageExporter.ImageWriterI;
-import jalview.io.HTMLOutput;
-import jalview.jbgui.GAlignmentPanel;
-import jalview.math.AlignmentDimension;
-import jalview.schemes.ResidueProperties;
-import jalview.structure.StructureSelectionManager;
-import jalview.util.Comparison;
-import jalview.util.ImageMaker;
-import jalview.util.MessageManager;
-import jalview.viewmodel.ViewportListenerI;
-import jalview.viewmodel.ViewportRanges;
-
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
@@ -67,6 +44,30 @@ import java.util.List;
import javax.swing.SwingUtilities;
+import jalview.analysis.AnnotationSorter;
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+import jalview.bin.Cache;
+import jalview.bin.Jalview;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.SearchResultsI;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.gui.ImageExporter.ImageWriterI;
+import jalview.io.HTMLOutput;
+import jalview.jbgui.GAlignmentPanel;
+import jalview.math.AlignmentDimension;
+import jalview.schemes.ResidueProperties;
+import jalview.structure.StructureSelectionManager;
+import jalview.util.Comparison;
+import jalview.util.ImageMaker;
+import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
+import jalview.viewmodel.ViewportListenerI;
+import jalview.viewmodel.ViewportRanges;
+
/**
* DOCUMENT ME!
*
@@ -122,7 +123,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
*/
public AlignmentPanel(AlignFrame af, final AlignViewport av)
{
-// setBackground(Color.white); // BH 2019
+ // setBackground(Color.white); // BH 2019
alignFrame = af;
this.av = av;
setSeqPanel(new SeqPanel(av, this));
@@ -173,6 +174,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
ranges.setViewportWidth(widthInRes);
ranges.setViewportHeight(heightInSeq);
}
+ repaint();
}
});
@@ -183,10 +185,17 @@ public class AlignmentPanel extends GAlignmentPanel implements
@Override
public void propertyChange(PropertyChangeEvent evt)
{
- if (evt.getPropertyName().equals("alignment"))
- {
+ switch (evt.getPropertyName()) {
+ case AlignmentViewport.PROPERTY_SEQUENCE:
+ updateScrollBarsFromRanges();
+ if (annotationPanel != null)
+ annotationPanel.paintImmediately(0, 0, getWidth(), getHeight());
+ break;
+ case AlignmentViewport.PROPERTY_ALIGNMENT:
+ updateScrollBarsFromRanges();
PaintRefresher.Refresh(ap, av.getSequenceSetId(), true, true);
alignmentChanged();
+ break;
}
}
};
@@ -259,32 +268,37 @@ public class AlignmentPanel extends GAlignmentPanel implements
int oldWidth = av.getIdWidth();
// calculate sensible default width when no preference is available
- Dimension r = null;
+ Dimension d = null;
if (av.getIdWidth() < 0)
{
- int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300);
- int idWidth = Math.min(afwidth - 200, 2 * afwidth / 3);
- int maxwidth = Math.max(IdwidthAdjuster.MIN_ID_WIDTH, idWidth);
- r = calculateIdWidth(maxwidth);
- av.setIdWidth(r.width);
+ int maxWidth = getMaxWidth();
+ d = calculateIdWidth(maxWidth);
+ av.setIdWidth(d.width);
}
else
{
- r = new Dimension();
- r.width = av.getIdWidth();
- r.height = 0;
+ d = new Dimension();
+ d.width = av.getIdWidth();
+ d.height = 0;
}
/*
* fudge: if desired width has changed, update layout
* (see also paintComponent - updates layout on a repaint)
*/
- if (r.width != oldWidth)
+ if (d.width != oldWidth)
{
- idPanelHolder.setPreferredSize(r);
+ idPanelHolder.setPreferredSize(d);
validate();
}
- return r;
+ return d;
+ }
+
+ public int getMaxWidth()
+ {
+ int afwidth = (alignFrame != null ? alignFrame.getWidth() : 300);
+ int idWidth = Math.min(afwidth - 200, 2 * afwidth / 3);
+ return Math.max(IdwidthAdjuster.MIN_ID_WIDTH, idWidth);
}
/**
@@ -296,10 +310,9 @@ public class AlignmentPanel extends GAlignmentPanel implements
* @return Dimension giving the maximum width of the alignment label panel
* that should be used.
*/
- protected Dimension calculateIdWidth(int maxwidth)
+ public Dimension calculateIdWidth(int maxwidth)
{
- Container c = new Container();
-
+ Container c = this;// new Container();
FontMetrics fm = c.getFontMetrics(
new Font(av.font.getName(), Font.ITALIC, av.font.getSize()));
@@ -307,10 +320,12 @@ public class AlignmentPanel extends GAlignmentPanel implements
int i = 0;
int idWidth = 0;
+ boolean withSuffix = av.getShowJVSuffix();
+
while ((i < al.getHeight()) && (al.getSequenceAt(i) != null))
{
SequenceI s = al.getSequenceAt(i);
- String id = s.getDisplayId(av.getShowJVSuffix());
+ String id = s.getDisplayId(withSuffix);
int stringWidth = fm.stringWidth(id);
idWidth = Math.max(idWidth, stringWidth);
i++;
@@ -471,8 +486,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
/*
* Scroll down to make end of search results visible
*/
- setScrollValues(ranges.getStartRes(), starts + seqIndex - ends
- + 1);
+ setScrollValues(ranges.getStartRes(), starts + seqIndex - ends + 1);
}
/*
* Else results are already visible - no need to scroll
@@ -554,17 +568,24 @@ public class AlignmentPanel extends GAlignmentPanel implements
{
// BH 2018.04.18 comment: addNotify() is not appropriate here. We
// are not changing ancestors, and keyboard action listeners do
- // not need to be reset. addNotify() is a very expensive operation,
+ // not need to be reset, and most importantly, we can't be sure we are actually
+ // connected to resources.
+
+ // addNotify() is a very expensive operation,
// requiring a full re-layout of all parents and children.
+
// Note in JComponent:
+
// This method is called by the toolkit internally and should
// not be called directly by programs.
+
// I note that addNotify() is called in several areas of Jalview.
int annotationHeight = getAnnotationPanel().adjustPanelHeight();
annotationHeight = getAnnotationPanel()
.adjustForAlignFrame(adjustPanelHeight, annotationHeight);
+ // BH no!!
hscroll.addNotify();
annotationScroller.setPreferredSize(
new Dimension(annotationScroller.getWidth(), annotationHeight));
@@ -572,7 +593,6 @@ public class AlignmentPanel extends GAlignmentPanel implements
Dimension e = idPanel.getSize();
alabels.setSize(new Dimension(e.width, annotationHeight));
-
annotationSpaceFillerHolder.setPreferredSize(new Dimension(
annotationSpaceFillerHolder.getWidth(), annotationHeight));
annotationScroller.validate();
@@ -587,10 +607,17 @@ public class AlignmentPanel extends GAlignmentPanel implements
*/
public void updateLayout()
{
+ // BH 2020.06.09 avoiding negative values for SequencePanel and SeqCanvas
+ // dimensions.
+
+ if (getTopLevelAncestor() == null)
+ return;
+
+
+ ViewportRanges ranges = av.getRanges();
fontChanged();
setAnnotationVisible(av.isShowAnnotation());
boolean wrap = av.getWrapAlignment();
- ViewportRanges ranges = av.getRanges();
ranges.setStartSeq(0);
scalePanelHolder.setVisible(!wrap);
hscroll.setVisible(!wrap);
@@ -630,7 +657,14 @@ public class AlignmentPanel extends GAlignmentPanel implements
idSpaceFillerPanel1.setVisible(!wrap);
- repaint();
+ // System.out.println("ap dim = " + getSize());
+
+ // these values will go negative if getSize() returns (0,0):
+
+ // System.out.println("seqpan dim = " + getSeqPanel().getSize());
+ // System.out.println("seqcan dim = " + getSeqPanel().seqCanvas.getSize());
+
+ // BH not added to anything yet! repaint();
}
/**
@@ -642,10 +676,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
* visible row to scroll to
*
*/
- public void setScrollValues(int xpos, int ypos)
+ public void setScrollValues(int x, int y)
{
- int x = xpos;
- int y = ypos;
if (av == null || av.getAlignment() == null)
{
@@ -660,46 +692,24 @@ public class AlignmentPanel extends GAlignmentPanel implements
{
int width = av.getAlignment().getVisibleWidth();
int height = av.getAlignment().getHeight();
-
- hextent = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
- vextent = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight();
-
- if (hextent > width)
- {
- hextent = width;
- }
-
- if (vextent > height)
- {
- vextent = height;
- }
-
- if ((hextent + x) > width)
- {
- x = width - hextent;
- }
-
- if ((vextent + y) > height)
- {
- y = height - vextent;
- }
-
- if (y < 0)
- {
- y = 0;
- }
-
- if (x < 0)
- {
- x = 0;
- }
-
- // update the scroll values
- hscroll.setValues(x, hextent, 0, width);
- vscroll.setValues(y, vextent, 0, height);
+
+ hextent = Math.min(getSeqPanel().seqCanvas.getWidth() / av.getCharWidth(), width);
+ vextent = Math.min(getSeqPanel().seqCanvas.getHeight() / av.getCharHeight(), height);
+
+ x = Math.max(0, Math.min(x, width - hextent));
+ y = Math.max(0, Math.min(y, height - vextent));
+
+ updateRanges(x, y);
+ updateScrollBars(x, y, width, height);
}
}
+ private void updateScrollBars(int x, int y, int width, int height)
+ {
+ hscroll.setValues(x, hextent, 0, width);
+ vscroll.setValues(y, vextent, 0, height);
+ }
+
/**
* Respond to adjustment event when horizontal or vertical scrollbar is
* changed
@@ -716,41 +726,54 @@ public class AlignmentPanel extends GAlignmentPanel implements
return;
}
- ViewportRanges ranges = av.getRanges();
-
if (evt.getSource() == hscroll)
{
+ if (!updateRanges(hscroll.getValue(), Integer.MIN_VALUE))
+ return;
+ }
+ else if (evt.getSource() == vscroll)
+ {
+ if (!updateRanges(Integer.MIN_VALUE, vscroll.getValue()))
+ return;
+ }
+ repaint();
+ }
+
+ private boolean updateRanges(int x, int y)
+ {
+ ViewportRanges ranges = av.getRanges();
+ boolean isChanged = false;
+ if (x != Integer.MIN_VALUE)
+ {
int oldX = ranges.getStartRes();
int oldwidth = ranges.getViewportWidth();
- int x = hscroll.getValue();
int width = getSeqPanel().seqCanvas.getWidth() / av.getCharWidth();
// if we're scrolling to the position we're already at, stop
// this prevents infinite recursion of events when the scroll/viewport
// ranges values are the same
- if ((x == oldX) && (width == oldwidth))
+ if (width > 0 && (x != oldX || width != oldwidth))
{
- return;
+ ranges.setViewportStartAndWidth(x, width);
+ isChanged = true;
}
- ranges.setViewportStartAndWidth(x, width);
}
- else if (evt.getSource() == vscroll)
+ if (y != Integer.MIN_VALUE)
{
int oldY = ranges.getStartSeq();
int oldheight = ranges.getViewportHeight();
- int y = vscroll.getValue();
int height = getSeqPanel().seqCanvas.getHeight() / av.getCharHeight();
// if we're scrolling to the position we're already at, stop
// this prevents infinite recursion of events when the scroll/viewport
// ranges values are the same
- if ((y == oldY) && (height == oldheight))
+ if (height > 0 && (y != oldY || height != oldheight))
{
- return;
+ ranges.setViewportStartAndHeight(y, height);
+ isChanged = true;
}
- ranges.setViewportStartAndHeight(y, height);
}
- repaint();
+ return isChanged;
}
/**
@@ -829,7 +852,6 @@ public class AlignmentPanel extends GAlignmentPanel implements
av.isShowAutocalculatedAbove());
sorter.sort(getAlignment().getAlignmentAnnotation(),
av.getSortAnnotationsBy());
- repaint();
if (updateStructures)
{
@@ -837,11 +859,14 @@ public class AlignmentPanel extends GAlignmentPanel implements
}
if (updateOverview)
{
+ alignFrame.repaint();
if (overviewPanel != null)
{
overviewPanel.updateOverviewImage();
}
+ } else {
+ repaint();
}
}
@@ -861,7 +886,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
* though I still think this call should be elsewhere.
*/
ViewportRanges ranges = av.getRanges();
- setScrollValues(ranges.getStartRes(), ranges.getStartSeq());
+ // setScrollValues(ranges.getStartRes(), ranges.getStartSeq());
super.paintComponent(g);
}
@@ -1020,8 +1045,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
* single graphics context), then reset to (0, scale height)
*/
alignmentGraphics.translate(alignmentGraphicsOffset, scaleHeight);
- getSeqPanel().seqCanvas.drawPanelForPrinting(alignmentGraphics, startRes,
- endRes, startSeq, endSeq - 1);
+ getSeqPanel().seqCanvas.drawPanelForPrinting(alignmentGraphics,
+ startRes, endRes, startSeq, endSeq - 1);
alignmentGraphics.translate(-alignmentGraphicsOffset, 0);
if (av.isShowAnnotation() && (endSeq == alignmentHeight))
@@ -1065,11 +1090,10 @@ public class AlignmentPanel extends GAlignmentPanel implements
*
* @throws PrinterException
*/
- public int printWrappedAlignment(int pageWidth, int pageHeight, int pageNumber,
- Graphics g) throws PrinterException
+ public int printWrappedAlignment(int pageWidth, int pageHeight,
+ int pageNumber, Graphics g) throws PrinterException
{
- getSeqPanel().seqCanvas.calculateWrappedGeometry(getWidth(),
- getHeight());
+ getSeqPanel().seqCanvas.calculateWrappedGeometry();
int annotationHeight = 0;
if (av.isShowAnnotation())
{
@@ -1118,8 +1142,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
g.translate(idWidth, 0);
- getSeqPanel().seqCanvas.drawWrappedPanelForPrinting(g, pageWidth - idWidth,
- totalHeight, 0);
+ getSeqPanel().seqCanvas.drawWrappedPanelForPrinting(g,
+ pageWidth - idWidth, totalHeight, 0);
if ((pageNumber * pageHeight) < totalHeight)
{
@@ -1284,13 +1308,13 @@ public class AlignmentPanel extends GAlignmentPanel implements
String triplet = null;
if (av.getAlignment().isNucleotide())
{
- triplet = ResidueProperties.nucleotideName.get(seq
- .getCharAt(column) + "");
+ triplet = ResidueProperties.nucleotideName
+ .get(seq.getCharAt(column) + "");
}
else
{
- triplet = ResidueProperties.aa2Triplet.get(seq.getCharAt(column)
- + "");
+ triplet = ResidueProperties.aa2Triplet
+ .get(seq.getCharAt(column) + "");
}
if (triplet == null)
@@ -1307,7 +1331,8 @@ public class AlignmentPanel extends GAlignmentPanel implements
text.append(" features = seq.findFeatures(column, column);
+ List features = seq.findFeatures(column,
+ column);
for (SequenceFeature sf : features)
{
if (sf.isContactFeature())
@@ -1702,10 +1728,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
public void propertyChange(PropertyChangeEvent evt)
{
// update this panel's scroll values based on the new viewport ranges values
- ViewportRanges ranges = av.getRanges();
- int x = ranges.getStartRes();
- int y = ranges.getStartSeq();
- setScrollValues(x, y);
+ updateScrollBarsFromRanges();
// now update any complementary alignment (its viewport ranges object
// is different so does not get automatically updated)
@@ -1717,6 +1740,12 @@ public class AlignmentPanel extends GAlignmentPanel implements
}
}
+ void updateScrollBarsFromRanges()
+ {
+ ViewportRanges ranges = av.getRanges();
+ setScrollValues(ranges.getStartRes(), ranges.getStartSeq());
+ }
+
/**
* Set the reference to the PCA/Tree chooser dialog for this panel. This
* reference should be nulled when the dialog is closed.
@@ -1854,4 +1883,84 @@ public class AlignmentPanel extends GAlignmentPanel implements
return true;
}
+ private boolean holdRepaint = false;
+
+ /**
+ * Called by IdCanvas and SeqPanel to defer painting until after JVP loading.
+ *
+ * @return true if holding
+ */
+ public boolean getHoldRepaint()
+ {
+ return holdRepaint;
+ }
+
+ /**
+ * Called by Jalview2xml while loading
+ *
+ * @param tf
+ */
+ public void setHoldRepaint(boolean tf)
+ {
+ if (holdRepaint == tf)
+ {
+ return;
+ }
+ holdRepaint = tf;
+ if (!tf)
+ {
+ repaint();
+ }
+ }
+
+ @Override
+ public void repaint()
+ {
+ if (holdRepaint)
+ {
+ // System.out.println("AP repaint holding");
+ // Platform.stackTrace();
+ return;
+ }
+ super.repaint();
+ }
+
+ public void selectAllSequences()
+ {
+ selectSequences(av.getAlignment().getSequences());
+ }
+
+ public void deselectAllSequences()
+ {
+ if (av.cursorMode)
+ {
+ getSeqPanel().keyboardNo1 = null;
+ getSeqPanel().keyboardNo2 = null;
+ }
+ av.setSelectionGroup(null);
+ av.getColumnSelection().clear();
+ av.setSelectionGroup(null);
+ getIdPanel().getIdCanvas().searchResults = null;
+ av.sendSelection();
+ // JAL-2034 - should delegate to
+ // alignPanel to decide if overview needs
+ // updating.
+ paintAlignment(false, false);
+ PaintRefresher.Refresh(this, av.getSequenceSetId());
+ }
+
+ public void selectSequences(List seqs)
+ {
+ SequenceGroup sg = new SequenceGroup(seqs);
+ sg.setEndRes(av.getAlignment().getWidth() - 1);
+ av.setSelectionGroup(sg);
+ av.isSelectionGroupChanged(true);
+ av.sendSelection();
+ // JAL-2034 - should delegate to
+ // alignPanel to decide if overview needs
+ // updating.
+ paintAlignment(false, false);
+ PaintRefresher.Refresh(this, av.getSequenceSetId());
+ }
+
}
diff --git a/src/jalview/gui/AnnotationChooser.java b/src/jalview/gui/AnnotationChooser.java
index 791421d..233f280 100644
--- a/src/jalview/gui/AnnotationChooser.java
+++ b/src/jalview/gui/AnnotationChooser.java
@@ -605,8 +605,8 @@ public class AnnotationChooser extends JPanel
frame.setContentPane(this);
frame.setLayer(JLayeredPane.PALETTE_LAYER);
Desktop.addInternalFrame(frame,
- MessageManager.getString("label.choose_annotations"),
- MY_FRAME_WIDTH, MY_FRAME_HEIGHT, true);
+ MessageManager.getString("label.choose_annotations"), Desktop.FRAME_MAKE_VISIBLE,
+ MY_FRAME_WIDTH, MY_FRAME_HEIGHT, Desktop.FRAME_ALLOW_RESIZE, Desktop.FRAME_SET_MIN_SIZE_300);
}
protected void setShowSelected(boolean showSelected)
diff --git a/src/jalview/gui/AnnotationColourChooser.java b/src/jalview/gui/AnnotationColourChooser.java
index e89c1c2..bd05be1 100644
--- a/src/jalview/gui/AnnotationColourChooser.java
+++ b/src/jalview/gui/AnnotationColourChooser.java
@@ -301,7 +301,7 @@ public class AnnotationColourChooser extends AnnotationRowFilter
updateView();
}
};
- JalviewColourChooser.showColourChooser(Desktop.getDesktop(), ttl,
+ JalviewColourChooser.showColourChooser(Desktop.getDesktopPane(), ttl,
colourPanel.getBackground(), listener);
}
diff --git a/src/jalview/gui/AnnotationExporter.java b/src/jalview/gui/AnnotationExporter.java
index d84287f..541c63a 100644
--- a/src/jalview/gui/AnnotationExporter.java
+++ b/src/jalview/gui/AnnotationExporter.java
@@ -109,8 +109,8 @@ public class AnnotationExporter extends JPanel
frame.setContentPane(this);
frame.setLayer(JLayeredPane.PALETTE_LAYER);
Dimension preferredSize = frame.getPreferredSize();
- Desktop.addInternalFrame(frame, "", true, preferredSize.width,
- preferredSize.height, true, true);
+ Desktop.addInternalFrame(frame, "", Desktop.FRAME_MAKE_VISIBLE, preferredSize.width,
+ preferredSize.height, Desktop.FRAME_ALLOW_RESIZE, Desktop.FRAME_ALLOW_ANY_SIZE);
}
/**
diff --git a/src/jalview/gui/AnnotationLabels.java b/src/jalview/gui/AnnotationLabels.java
index 5a681f1..c843f37 100755
--- a/src/jalview/gui/AnnotationLabels.java
+++ b/src/jalview/gui/AnnotationLabels.java
@@ -20,21 +20,6 @@
*/
package jalview.gui;
-import jalview.analysis.AlignSeq;
-import jalview.analysis.AlignmentUtils;
-import jalview.datamodel.Alignment;
-import jalview.datamodel.AlignmentAnnotation;
-import jalview.datamodel.Annotation;
-import jalview.datamodel.HiddenColumns;
-import jalview.datamodel.Sequence;
-import jalview.datamodel.SequenceGroup;
-import jalview.datamodel.SequenceI;
-import jalview.io.FileFormat;
-import jalview.io.FormatAdapter;
-import jalview.util.Comparison;
-import jalview.util.MessageManager;
-import jalview.util.Platform;
-
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
@@ -62,6 +47,21 @@ import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
+import jalview.analysis.AlignSeq;
+import jalview.analysis.AlignmentUtils;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.HiddenColumns;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
+import jalview.io.FileFormat;
+import jalview.io.FormatAdapter;
+import jalview.util.Comparison;
+import jalview.util.MessageManager;
+import jalview.util.Platform;
+
/**
* The panel that holds the labels for alignment annotations, providing
* tooltips, context menus, drag to reorder rows, and drag to adjust panel
@@ -971,7 +971,7 @@ public class AnnotationLabels extends JPanel
seqs, omitHidden, alignmentStartEnd);
Toolkit.getDefaultToolkit().getSystemClipboard()
- .setContents(new StringSelection(output), Desktop.instance);
+ .setContents(new StringSelection(output), Desktop.getInstance());
HiddenColumns hiddenColumns = null;
@@ -981,20 +981,12 @@ public class AnnotationLabels extends JPanel
av.getAlignment().getHiddenColumns());
}
- Desktop.jalviewClipboard = new Object[] { seqs, ds, // what is the dataset
- // of a consensus
- // sequence ? need to
- // flag
- // sequence as special.
+ // what is the dataset of a consensus sequence?
+ // need to flag sequence as special.
+ Desktop.getInstance().jalviewClipboard = new Object[] { seqs, ds,
hiddenColumns };
}
- /**
- * DOCUMENT ME!
- *
- * @param g1
- * DOCUMENT ME!
- */
@Override
public void paintComponent(Graphics g)
{
diff --git a/src/jalview/gui/AnnotationPanel.java b/src/jalview/gui/AnnotationPanel.java
index 35ae242..01be3b5 100755
--- a/src/jalview/gui/AnnotationPanel.java
+++ b/src/jalview/gui/AnnotationPanel.java
@@ -1009,23 +1009,28 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
g.setColor(Color.white);
g.fillRect(0, 0, visibleRect.width, visibleRect.height);
+ ViewportRanges ranges = av.getRanges();
+
+
+
if (image != null)
{
// BH 2018 optimizing generation of new Rectangle().
if (fastPaint || (visibleRect.width != (clipBounds = g.getClipBounds(clipBounds)).width)
|| (visibleRect.height != clipBounds.height))
{
-
-
g.drawImage(image, 0, 0, this);
fastPaint = false;
return;
}
}
- imgWidth = (av.getRanges().getEndRes() - av.getRanges().getStartRes()
+
+ imgWidth = (ranges.getEndRes() - ranges.getStartRes()
+ 1) * av.getCharWidth();
+
if (imgWidth < 1)
{
+ fastPaint = false;
return;
}
Graphics2D gg;
@@ -1068,8 +1073,8 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
gg = (Graphics2D) image.getGraphics();
}
-
- drawComponent(gg, av.getRanges().getStartRes(),
+
+ drawComponent(gg, ranges.getStartRes(),
av.getRanges().getEndRes() + 1);
gg.dispose();
imageFresh = false;
@@ -1077,11 +1082,6 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
}
/**
- * set true to enable redraw timing debug output on stderr
- */
- private final boolean debugRedraw = false;
-
- /**
* non-Thread safe repaint
*
* @param horizontal
@@ -1101,6 +1101,11 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
int sr = av.getRanges().getStartRes();
int er = av.getRanges().getEndRes() + 1;
int transX = 0;
+
+ if (er == sr + 1) {
+ fastPaint = false;
+ return;
+ }
Graphics2D gg = (Graphics2D) image.getGraphics();
diff --git a/src/jalview/gui/AppJmol.java b/src/jalview/gui/AppJmol.java
index e13df4a..afb727f 100644
--- a/src/jalview/gui/AppJmol.java
+++ b/src/jalview/gui/AppJmol.java
@@ -546,7 +546,7 @@ public class AppJmol extends StructureViewerBase
}
if (errormsgs.length() > 0)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.pdb_entries_couldnt_be_retrieved", new String[]
{ errormsgs.toString() }),
diff --git a/src/jalview/gui/AssociatePdbFileWithSeq.java b/src/jalview/gui/AssociatePdbFileWithSeq.java
index fe0aedf..5b5bd18 100644
--- a/src/jalview/gui/AssociatePdbFileWithSeq.java
+++ b/src/jalview/gui/AssociatePdbFileWithSeq.java
@@ -20,18 +20,15 @@
*/
package jalview.gui;
-import jalview.api.StructureSelectionManagerProvider;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
import jalview.io.DataSourceType;
import jalview.io.StructureFile;
-import jalview.structure.StructureSelectionManager;
import jalview.util.MessageManager;
-import javax.swing.JOptionPane;
-
/**
- * GUI related routines for associating PDB files with sequences
+ * GUI related routines for associating PDB files with sequences. A single
+ * static method.
*
* @author JimP
*
@@ -39,58 +36,56 @@ import javax.swing.JOptionPane;
public class AssociatePdbFileWithSeq
{
+ private AssociatePdbFileWithSeq()
+ {
+ // inaccessible
+ }
+
/**
- * assocate the given PDB file with
+ * Associate the given PDB file name or URL with a sequence. Do not map
+ * mouse-over events.
*
- * @param choice
+ * @param fileName
+ * or URL
+ * @param type
+ * will be DataType.FILE or DataType.URL
* @param sequence
+ * to associate
+ * @param prompt
+ * true if the user should be asked what to do if the specified file
+ * does not seem to contain PDB information (StructureChooser only)
+ * @return null if file is not found
*/
- public PDBEntry associatePdbWithSeq(String choice, DataSourceType file,
- SequenceI sequence, boolean prompt,
- StructureSelectionManagerProvider ssmp)
+ public static PDBEntry associatePdbWithSeq(String fileName,
+ DataSourceType type, SequenceI sequence, boolean prompt)
{
PDBEntry entry = new PDBEntry();
StructureFile pdbfile = null;
- pdbfile = StructureSelectionManager.getStructureSelectionManager(ssmp)
+ pdbfile = Desktop.getStructureSelectionManager()
.setMapping(false, new SequenceI[]
- { sequence }, null, choice, file);
+ { sequence }, null, fileName, type);
if (pdbfile == null)
{
// stacktrace already thrown so just return
return null;
}
- if (pdbfile.getId() == null)
- {
- String reply = null;
-
- if (prompt)
- {
- reply = JvOptionPane.showInternalInputDialog(Desktop.desktop,
- MessageManager
- .getString("label.couldnt_find_pdb_id_in_file"),
- MessageManager.getString("label.no_pdb_id_in_file"),
- JvOptionPane.QUESTION_MESSAGE);
- }
- if (reply == null)
- {
- return null;
- }
-
- entry.setId(reply);
- }
- else
+ String id = pdbfile.getId();
+ if (id == null && (id = (prompt
+ ? JvOptionPane.showInternalInputDialog(Desktop.getDesktopPane(),
+ MessageManager
+ .getString("label.couldnt_find_pdb_id_in_file"),
+ MessageManager.getString("label.no_pdb_id_in_file"),
+ JvOptionPane.QUESTION_MESSAGE)
+ : null)) == null)
{
- entry.setId(pdbfile.getId());
+ return null;
}
+ entry.setId(id);
entry.setType(PDBEntry.Type.FILE);
-
- if (pdbfile != null)
- {
- entry.setFile(choice);
- sequence.getDatasetSequence().addPDBId(entry);
- StructureSelectionManager.getStructureSelectionManager(ssmp)
- .registerPDBEntry(entry);
- }
+ entry.setFile(fileName);
+ sequence.getDatasetSequence().addPDBId(entry);
+ Desktop.getStructureSelectionManager()
+ .registerPDBEntry(entry);
return entry;
}
}
diff --git a/src/jalview/gui/CalculationChooser.java b/src/jalview/gui/CalculationChooser.java
index 5248306..c69d0a8 100644
--- a/src/jalview/gui/CalculationChooser.java
+++ b/src/jalview/gui/CalculationChooser.java
@@ -319,7 +319,7 @@ public class CalculationChooser extends JPanel
title = title + " (" + af.getViewport().getViewName() + ")";
}
- Desktop.addInternalFrame(frame, title, width, height, false);
+ Desktop.addInternalFrame(frame, title, Desktop.FRAME_MAKE_VISIBLE, width, height, Desktop.FRAME_NOT_RESIZABLE, Desktop.FRAME_SET_MIN_SIZE_300);
calcChoicePanel.doLayout();
revalidate();
/*
diff --git a/src/jalview/gui/ChimeraViewFrame.java b/src/jalview/gui/ChimeraViewFrame.java
index c6d6e97..317eff5 100644
--- a/src/jalview/gui/ChimeraViewFrame.java
+++ b/src/jalview/gui/ChimeraViewFrame.java
@@ -336,7 +336,7 @@ public class ChimeraViewFrame extends StructureViewerBase
if (!jmb.launchChimera())
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString("label.chimera_failed"),
MessageManager.getString("label.error_loading_file"),
JvOptionPane.ERROR_MESSAGE);
@@ -497,7 +497,7 @@ public class ChimeraViewFrame extends StructureViewerBase
if (errormsgs.length() > 0)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.pdb_entries_couldnt_be_retrieved", new Object[]
{ errormsgs.toString() }),
diff --git a/src/jalview/gui/ColourMenuHelper.java b/src/jalview/gui/ColourMenuHelper.java
index 43d7015..e38b55b 100644
--- a/src/jalview/gui/ColourMenuHelper.java
+++ b/src/jalview/gui/ColourMenuHelper.java
@@ -158,7 +158,7 @@ public class ColourMenuHelper
ActionListener al = radioItem.getActionListeners()[0];
radioItem.removeActionListener(al);
int option = JvOptionPane.showInternalConfirmDialog(
- Desktop.desktop,
+ Desktop.getDesktopPane(),
MessageManager
.getString("label.remove_from_default_list"),
MessageManager
diff --git a/src/jalview/gui/CrossRefAction.java b/src/jalview/gui/CrossRefAction.java
index 2ada4d2..cc25696 100644
--- a/src/jalview/gui/CrossRefAction.java
+++ b/src/jalview/gui/CrossRefAction.java
@@ -454,7 +454,7 @@ public class CrossRefAction implements Runnable
.setGapCharacter(alignFrame.viewport.getGapCharacter());
StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
/*
* register any new mappings for sequence mouseover etc
diff --git a/src/jalview/gui/CutAndPasteTransfer.java b/src/jalview/gui/CutAndPasteTransfer.java
index d328a0d..4badcba 100644
--- a/src/jalview/gui/CutAndPasteTransfer.java
+++ b/src/jalview/gui/CutAndPasteTransfer.java
@@ -234,7 +234,7 @@ public class CutAndPasteTransfer extends GCutAndPasteTransfer
.println(MessageManager.getString("label.couldnt_read_data"));
if (!Jalview.isHeadlessMode())
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
AppletFormatAdapter.getSupportedFormats(),
MessageManager.getString("label.couldnt_read_data"),
JvOptionPane.WARNING_MESSAGE);
@@ -253,7 +253,7 @@ public class CutAndPasteTransfer extends GCutAndPasteTransfer
} catch (IOException ex)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop, MessageManager
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(), MessageManager
.formatMessage("label.couldnt_read_pasted_text", new String[]
{ ex.toString() }),
MessageManager.getString("label.error_parsing_text"),
@@ -342,7 +342,7 @@ public class CutAndPasteTransfer extends GCutAndPasteTransfer
.println(MessageManager.getString("label.couldnt_read_data"));
if (!Jalview.isHeadlessMode())
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
AppletFormatAdapter.getSupportedFormats(),
MessageManager.getString("label.couldnt_read_data"),
JvOptionPane.WARNING_MESSAGE);
diff --git a/src/jalview/gui/Desktop.java b/src/jalview/gui/Desktop.java
index 0e2fcf0..3d91e47 100644
--- a/src/jalview/gui/Desktop.java
+++ b/src/jalview/gui/Desktop.java
@@ -94,6 +94,9 @@ import org.stackoverflowusers.file.WindowsShortcut;
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
+import jalview.api.StructureSelectionManagerProvider;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.bin.Cache;
import jalview.bin.Jalview;
import jalview.gui.ImageExporter.ImageWriterI;
@@ -108,6 +111,7 @@ import jalview.io.FormatAdapter;
import jalview.io.IdentifyFile;
import jalview.io.JalviewFileChooser;
import jalview.io.JalviewFileView;
+import jalview.jbgui.GDesktop;
import jalview.jbgui.GSplitFrame;
import jalview.jbgui.GStructureViewer;
import jalview.project.Jalview2XML;
@@ -130,9 +134,11 @@ import jalview.ws.utils.UrlDownloadClient;
* @author $author$
* @version $Revision: 1.155 $
*/
-public class Desktop extends jalview.jbgui.GDesktop
+@SuppressWarnings("serial")
+public class Desktop extends GDesktop
implements DropTargetListener, ClipboardOwner, IProgressIndicator,
- jalview.api.StructureSelectionManagerProvider
+ StructureSelectionManagerProvider, ApplicationSingletonI
+
{
private static final String CITATION = " Development managed by The Barton Group, University of Dundee, Scotland, UK. "
+ " For help, see the FAQ at www.jalview.org/faq and/or join the jalview-discuss@jalview.org mailing list"
@@ -201,41 +207,47 @@ public class Desktop extends jalview.jbgui.GDesktop
listener);
}
- /** Singleton Desktop instance */
- public static Desktop instance;
+ private MyDesktopPane desktopPane;
+
+ public static MyDesktopPane getDesktopPane()
+ {
+ Desktop desktop = getInstance();
+ return desktop == null ? null : desktop.desktopPane;
+ }
/**
- * BH TEMPORARY ONLY -- should use ApplicationSingleton
+ * Answers an 'application scope' singleton instance of this class. Separate
+ * SwingJS 'applets' running in the same browser page will each have a
+ * distinct instance of Desktop.
*
* @return
*/
public static Desktop getInstance()
{
- return instance;
+ return Jalview.isHeadlessMode() ? null
+ : (Desktop) ApplicationSingletonProvider
+ .getInstance(Desktop.class);
}
- public static MyDesktopPane desktop;
-
- public static MyDesktopPane getDesktop()
+ public static StructureSelectionManager getStructureSelectionManager()
{
- // BH 2018 could use currentThread() here as a reference to a
- // Hashtable in JavaScript
- return desktop;
+ return StructureSelectionManager
+ .getStructureSelectionManager(getInstance());
}
- static int openFrameCount = 0;
+ int openFrameCount = 0;
- static final int xOffset = 30;
+ final int xOffset = 30;
- static final int yOffset = 30;
+ final int yOffset = 30;
- public static jalview.ws.jws1.Discoverer discoverer;
+ public jalview.ws.jws1.Discoverer discoverer;
- public static Object[] jalviewClipboard;
+ public Object[] jalviewClipboard;
- public static boolean internalCopy = false;
+ public boolean internalCopy = false;
- static int fileLoadingCount = 0;
+ int fileLoadingCount = 0;
class MyDesktopManager implements DesktopManager
{
@@ -256,7 +268,7 @@ public class Desktop extends jalview.jbgui.GDesktop
} catch (NullPointerException npe)
{
Point p = getMousePosition();
- instance.showPasteMenu(p.x, p.y);
+ showPasteMenu(p.x, p.y);
}
}
@@ -304,14 +316,14 @@ public class Desktop extends jalview.jbgui.GDesktop
public void endDraggingFrame(JComponent f)
{
delegate.endDraggingFrame(f);
- desktop.repaint();
+ desktopPane.repaint();
}
@Override
public void endResizingFrame(JComponent f)
{
delegate.endResizingFrame(f);
- desktop.repaint();
+ desktopPane.repaint();
}
@Override
@@ -361,190 +373,202 @@ public class Desktop extends jalview.jbgui.GDesktop
}
/**
- * Creates a new Desktop object.
+ * Private constructor enforces singleton pattern. It is called by reflection
+ * from ApplicationSingletonProvider.getInstance().
*/
- public Desktop()
+ private Desktop()
{
- super();
- /**
- * A note to implementors. It is ESSENTIAL that any activities that might
- * block are spawned off as threads rather than waited for during this
- * constructor.
- */
- instance = this;
-
- doConfigureStructurePrefs();
- setTitle("Jalview " + Cache.getProperty("VERSION"));
- /*
- if (!Platform.isAMac())
- {
- // this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
- }
- else
- {
- this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
- }
- */
-
+ Cache.initLogger();
try
{
- APQHandlers.setAPQHandlers(this);
- } catch (Throwable t)
- {
- System.out.println("Error setting APQHandlers: " + t.toString());
- // t.printStackTrace();
- }
-
- addWindowListener(new WindowAdapter()
- {
+ /**
+ * A note to implementors. It is ESSENTIAL that any activities that might
+ * block are spawned off as threads rather than waited for during this
+ * constructor.
+ */
- @Override
- public void windowClosing(WindowEvent ev)
+ doConfigureStructurePrefs();
+ setTitle("Jalview " + Cache.getProperty("VERSION"));
+ /*
+ if (!Platform.isAMac())
{
- quit();
+ // this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
- });
+ else
+ {
+ this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+ }
+ */
- boolean selmemusage = Cache.getDefault("SHOW_MEMUSAGE",
- false);
+ try
+ {
+ APQHandlers.setAPQHandlers(this);
+ } catch (Throwable t)
+ {
+ System.out.println("Error setting APQHandlers: " + t.toString());
+ // t.printStackTrace();
+ }
- boolean showjconsole = Cache.getDefault("SHOW_JAVA_CONSOLE",
- false);
- desktop = new MyDesktopPane(selmemusage);
+ addWindowListener(new WindowAdapter()
+ {
- showMemusage.setSelected(selmemusage);
- desktop.setBackground(Color.white);
+ @Override
+ public void windowClosing(WindowEvent ev)
+ {
+ quit();
+ }
+ });
- getContentPane().setLayout(new BorderLayout());
- // alternate config - have scrollbars - see notes in JAL-153
- // JScrollPane sp = new JScrollPane();
- // sp.getViewport().setView(desktop);
- // getContentPane().add(sp, BorderLayout.CENTER);
+ boolean selmemusage = Cache.getDefault("SHOW_MEMUSAGE", false);
- // BH 2018 - just an experiment to try unclipped JInternalFrames.
- if (Platform.isJS())
- {
- getRootPane().putClientProperty("swingjs.overflow.hidden", "false");
- }
+ boolean showjconsole = Cache.getDefault("SHOW_JAVA_CONSOLE", false);
+ desktopPane = new MyDesktopPane(selmemusage);
- getContentPane().add(desktop, BorderLayout.CENTER);
- desktop.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
+ showMemusage.setSelected(selmemusage);
+ desktopPane.setBackground(Color.white);
- // This line prevents Windows Look&Feel resizing all new windows to maximum
- // if previous window was maximised
- desktop.setDesktopManager(new MyDesktopManager(
- (Platform.isWindowsAndNotJS() ? new DefaultDesktopManager()
- : Platform.isAMacAndNotJS()
- ? new AquaInternalFrameManager(
- desktop.getDesktopManager())
- : desktop.getDesktopManager())));
+ getContentPane().setLayout(new BorderLayout());
+ // alternate config - have scrollbars - see notes in JAL-153
+ // JScrollPane sp = new JScrollPane();
+ // sp.getViewport().setView(desktop);
+ // getContentPane().add(sp, BorderLayout.CENTER);
- Rectangle dims = getLastKnownDimensions("");
- if (dims != null)
- {
- setBounds(dims);
- }
- else
- {
- Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
- int xPos = Math.max(5, (screenSize.width - 900) / 2);
- int yPos = Math.max(5, (screenSize.height - 650) / 2);
- setBounds(xPos, yPos, 900, 650);
- }
+ // BH 2018 - just an experiment to try unclipped JInternalFrames.
+ if (Platform.isJS())
+ {
+ getRootPane().putClientProperty("swingjs.overflow.hidden", "false");
+ }
- if (!Platform.isJS())
- /**
- * Java only
- *
- * @j2sIgnore
- */
- {
- jconsole = new Console(this, showjconsole);
- jconsole.setHeader(Cache.getVersionDetailsForConsole());
- showConsole(showjconsole);
+ getContentPane().add(desktopPane, BorderLayout.CENTER);
+ desktopPane.setDragMode(JDesktopPane.OUTLINE_DRAG_MODE);
- showNews.setVisible(false);
+ // This line prevents Windows Look&Feel resizing all new windows to
+ // maximum
+ // if previous window was maximised
+ desktopPane.setDesktopManager(new MyDesktopManager(
+ (Platform.isWindowsAndNotJS() ? new DefaultDesktopManager()
+ : Platform.isAMacAndNotJS()
+ ? new AquaInternalFrameManager(
+ desktopPane.getDesktopManager())
+ : desktopPane.getDesktopManager())));
- experimentalFeatures.setSelected(showExperimental());
+ Rectangle dims = getLastKnownDimensions("");
+ if (dims != null)
+ {
+ setBounds(dims);
+ }
+ else
+ {
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+ int xPos = Math.max(5, (screenSize.width - 900) / 2);
+ int yPos = Math.max(5, (screenSize.height - 650) / 2);
+ setBounds(xPos, yPos, 900, 650);
+ }
getIdentifiersOrgData();
- checkURLLinks();
+ if (!Platform.isJS())
+ /**
+ * Java only
+ *
+ * @j2sIgnore
+ */
+ {
+ jconsole = new Console(this, showjconsole);
+ jconsole.setHeader(Cache.getVersionDetailsForConsole());
+ showConsole(showjconsole);
- // Spawn a thread that shows the splashscreen
+ showNews.setVisible(false);
- SwingUtilities.invokeLater(new Runnable()
- {
- @Override
- public void run()
- {
- new SplashScreen(true);
- }
- });
+ experimentalFeatures.setSelected(showExperimental());
- // Thread off a new instance of the file chooser - this reduces the time
- // it
- // takes to open it later on.
- new Thread(new Runnable()
- {
- @Override
- public void run()
+ if (Jalview.isInteractive())
{
- Cache.log.debug("Filechooser init thread started.");
- String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
- JalviewFileChooser.forRead(Cache.getProperty("LAST_DIRECTORY"),
- fileFormat);
- Cache.log.debug("Filechooser init thread finished.");
- }
- }).start();
- // Add the service change listener
- changeSupport.addJalviewPropertyChangeListener("services",
- new PropertyChangeListener()
- {
+ // disabled for SeqCanvasTest
+ checkURLLinks();
- @Override
- public void propertyChange(PropertyChangeEvent evt)
- {
- Cache.log.debug("Firing service changed event for "
- + evt.getNewValue());
- JalviewServicesChanged(evt);
- }
- });
- }
+ checkURLLinks();
- this.setDropTarget(new java.awt.dnd.DropTarget(desktop, this));
+ // Spawn a thread that shows the splashscreen
- this.addWindowListener(new WindowAdapter()
- {
- @Override
- public void windowClosing(WindowEvent evt)
- {
- quit();
- }
- });
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ new SplashScreen(true);
+ }
+ });
- MouseAdapter ma;
- this.addMouseListener(ma = new MouseAdapter()
- {
- @Override
- public void mousePressed(MouseEvent evt)
- {
- if (evt.isPopupTrigger()) // Mac
- {
- showPasteMenu(evt.getX(), evt.getY());
+ // Thread off a new instance of the file chooser - this reduces the
+ // time
+ // it
+ // takes to open it later on.
+ new Thread(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ Cache.log.debug("Filechooser init thread started.");
+ String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
+ JalviewFileChooser.forRead(
+ Cache.getProperty("LAST_DIRECTORY"), fileFormat);
+ Cache.log.debug("Filechooser init thread finished.");
+ }
+ }).start();
+ // Add the service change listener
+ changeSupport.addJalviewPropertyChangeListener("services",
+ new PropertyChangeListener()
+ {
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ Cache.log.debug("Firing service changed event for "
+ + evt.getNewValue());
+ JalviewServicesChanged(evt);
+ }
+ });
}
- }
- @Override
- public void mouseReleased(MouseEvent evt)
- {
- if (evt.isPopupTrigger()) // Windows
+ this.setDropTarget(new java.awt.dnd.DropTarget(desktopPane, this));
+
+ this.addWindowListener(new WindowAdapter()
{
- showPasteMenu(evt.getX(), evt.getY());
- }
+ @Override
+ public void windowClosing(WindowEvent evt)
+ {
+ quit();
+ }
+ });
+
+ MouseAdapter ma;
+ this.addMouseListener(ma = new MouseAdapter()
+ {
+ @Override
+ public void mousePressed(MouseEvent evt)
+ {
+ if (evt.isPopupTrigger()) // Mac
+ {
+ showPasteMenu(evt.getX(), evt.getY());
+ }
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent evt)
+ {
+ if (evt.isPopupTrigger()) // Windows
+ {
+ showPasteMenu(evt.getX(), evt.getY());
+ }
+ }
+ });
+ desktopPane.addMouseListener(ma);
}
- });
- desktop.addMouseListener(ma);
+ } catch (Throwable t)
+ {
+ t.printStackTrace();
+ }
}
@@ -568,10 +592,10 @@ public class Desktop extends jalview.jbgui.GDesktop
.getStructureSelectionManager(this);
if (Cache.getDefault(Preferences.ADD_SS_ANN, true))
{
- ssm.setAddTempFacAnnot(Cache
- .getDefault(Preferences.ADD_TEMPFACT_ANN, true));
- ssm.setProcessSecondaryStructure(Cache
- .getDefault(Preferences.STRUCT_FROM_PDB, true));
+ ssm.setAddTempFacAnnot(
+ Cache.getDefault(Preferences.ADD_TEMPFACT_ANN, true));
+ ssm.setProcessSecondaryStructure(
+ Cache.getDefault(Preferences.STRUCT_FROM_PDB, true));
ssm.setSecStructServices(
Cache.getDefault(Preferences.USE_RNAVIEW, true));
}
@@ -620,7 +644,7 @@ public class Desktop extends jalview.jbgui.GDesktop
}
}
}).start();
-
+
}
@Override
@@ -641,10 +665,10 @@ public class Desktop extends jalview.jbgui.GDesktop
public void run()
{
long now = System.currentTimeMillis();
- Desktop.instance.setProgressBar(
- MessageManager.getString("status.refreshing_news"), now);
+ setProgressBar(MessageManager.getString("status.refreshing_news"),
+ now);
jvnews.refreshNews();
- Desktop.instance.setProgressBar(null, now);
+ setProgressBar(null, now);
jvnews.showNews();
}
}).start();
@@ -665,10 +689,8 @@ public class Desktop extends jalview.jbgui.GDesktop
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
String x = Cache.getProperty(windowName + "SCREEN_X");
String y = Cache.getProperty(windowName + "SCREEN_Y");
- String width = Cache
- .getProperty(windowName + "SCREEN_WIDTH");
- String height = Cache
- .getProperty(windowName + "SCREEN_HEIGHT");
+ String width = Cache.getProperty(windowName + "SCREEN_WIDTH");
+ String height = Cache.getProperty(windowName + "SCREEN_HEIGHT");
if ((x != null) && (y != null) && (width != null) && (height != null))
{
int ix = Integer.parseInt(x), iy = Integer.parseInt(y),
@@ -678,10 +700,10 @@ public class Desktop extends jalview.jbgui.GDesktop
// attempt #1 - try to cope with change in screen geometry - this
// version doesn't preserve original jv aspect ratio.
// take ratio of current screen size vs original screen size.
- double sw = ((1f * screenSize.width) / (1f * Integer.parseInt(
- Cache.getProperty("SCREENGEOMETRY_WIDTH"))));
- double sh = ((1f * screenSize.height) / (1f * Integer.parseInt(
- Cache.getProperty("SCREENGEOMETRY_HEIGHT"))));
+ double sw = ((1f * screenSize.width) / (1f * Integer
+ .parseInt(Cache.getProperty("SCREENGEOMETRY_WIDTH"))));
+ double sh = ((1f * screenSize.height) / (1f * Integer
+ .parseInt(Cache.getProperty("SCREENGEOMETRY_HEIGHT"))));
// rescale the bounds depending upon the current screen geometry.
ix = (int) (ix * sw);
iw = (int) (iw * sw);
@@ -752,69 +774,81 @@ public class Desktop extends jalview.jbgui.GDesktop
}
}
- /**
- * Adds and opens the given frame to the desktop
- *
- * @param frame
- * Frame to show
- * @param title
- * Visible Title
- * @param w
- * width
- * @param h
- * height
- */
- public static synchronized void addInternalFrame(
- final JInternalFrame frame, String title, int w, int h)
- {
- addInternalFrame(frame, title, true, w, h, true, false);
- }
+// /**
+// * Add an internal frame to the Jalview desktop that is allowed to be resized,
+// * has a minimum size of 300px and might or might not be visible
+// *
+// * @param frame
+// * Frame to show
+// * @param title
+// * Visible Title
+// * @param makeVisible
+// * When true, display frame immediately, otherwise, caller must call
+// * setVisible themselves.
+// * @param w
+// * width
+// * @param h
+// * height
+// */
+// @Deprecated
+// public static synchronized void addInternalFrame(
+// final JInternalFrame frame, String title, boolean makeVisible,
+// int w, int h)
+// {
+// // textbox, web services, sequenceFetcher, featureSettings
+// getInstance().addFrame(frame, title, makeVisible, w, h,
+// FRAME_ALLOW_RESIZE, FRAME_SET_MIN_SIZE_300);
+// }
+//
+// /**
+// * Add an internal frame to the Jalview desktop that is visible, has a minimum
+// * size of 300px, and may or may not be resizable
+// *
+// * @param frame
+// * Frame to show
+// * @param title
+// * Visible Title
+// * @param w
+// * width
+// * @param h
+// * height
+// * @param resizable
+// * Allow resize
+// */
+// @Deprecated
+// public static synchronized void addInternalFrame(
+// final JInternalFrame frame, String title, int w, int h,
+// boolean resizable)
+// {
+// // annotation, font, calculation, user-defined colors
+// getInstance().addFrame(frame, title, FRAME_MAKE_VISIBLE, w, h,
+// resizable, FRAME_SET_MIN_SIZE_300);
+// }
/**
- * Add an internal frame to the Jalview desktop
+ * Adds and opens the given frame to the desktop that is visible, allowed to
+ * resize, and has a 300px minimum width.
*
* @param frame
* Frame to show
* @param title
* Visible Title
- * @param makeVisible
- * When true, display frame immediately, otherwise, caller must call
- * setVisible themselves.
* @param w
* width
* @param h
* height
*/
public static synchronized void addInternalFrame(
- final JInternalFrame frame, String title, boolean makeVisible,
- int w, int h)
- {
- addInternalFrame(frame, title, makeVisible, w, h, true, false);
- }
-
- /**
- * Add an internal frame to the Jalview desktop and make it visible
- *
- * @param frame
- * Frame to show
- * @param title
- * Visible Title
- * @param w
- * width
- * @param h
- * height
- * @param resizable
- * Allow resize
- */
- public static synchronized void addInternalFrame(
- final JInternalFrame frame, String title, int w, int h,
- boolean resizable)
+ final JInternalFrame frame, String title, int w, int h)
{
- addInternalFrame(frame, title, true, w, h, resizable, false);
+ // 58 classes
+ getInstance().addFrame(frame, title, Desktop.FRAME_MAKE_VISIBLE, w, h,
+ FRAME_ALLOW_RESIZE, FRAME_SET_MIN_SIZE_300);
}
/**
- * Add an internal frame to the Jalview desktop
+ * Add an internal frame to the Jalview desktop that may optionally be
+ * visible, resizable, and allowed to be any size
*
* @param frame
* Frame to show
@@ -836,7 +870,29 @@ public class Desktop extends jalview.jbgui.GDesktop
final JInternalFrame frame, String title, boolean makeVisible,
int w, int h, boolean resizable, boolean ignoreMinSize)
{
+ // 15 classes
+ getInstance().addFrame(frame, title, makeVisible, w, h, resizable,
+ ignoreMinSize);
+ }
+
+ // These can now by put into a single int flag, if desired:
+
+ public final static boolean FRAME_MAKE_VISIBLE = true;
+
+ public final static boolean FRAME_NOT_VISIBLE = false;
+
+ public final static boolean FRAME_ALLOW_RESIZE = true;
+ public final static boolean FRAME_NOT_RESIZABLE = false;
+
+ public final static boolean FRAME_ALLOW_ANY_SIZE = true;
+
+ public final static boolean FRAME_SET_MIN_SIZE_300 = false;
+
+ private void addFrame(JInternalFrame frame, String title,
+ boolean makeVisible, int w, int h, boolean resizable,
+ boolean ignoreMinSize)
+ {
// TODO: allow callers to determine X and Y position of frame (eg. via
// bounds object).
// TODO: consider fixing method to update entries in the window submenu with
@@ -851,19 +907,20 @@ public class Desktop extends jalview.jbgui.GDesktop
// A HEADLESS STATE WHEN NO DESKTOP EXISTS. MUST RETURN
// IF JALVIEW IS RUNNING HEADLESS
// ///////////////////////////////////////////////
- if (instance == null || (System.getProperty("java.awt.headless") != null
- && System.getProperty("java.awt.headless").equals("true")))
+ if (Jalview.isHeadlessMode())
{
return;
}
openFrameCount++;
-
+
+ boolean isEmbedded = (Platform.getEmbeddedAttribute(frame, "id") != null);
+ boolean hasEmbeddedSize = (Platform.getDimIfEmbedded(frame, -1, -1) != null);
+ // Web page embedding allows us to ignore minimum size
+ ignoreMinSize |= hasEmbeddedSize;
+
if (!ignoreMinSize)
{
- frame.setMinimumSize(
- new Dimension(DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT));
-
// Set default dimension for Alignment Frame window.
// The Alignment Frame window could be added from a number of places,
// hence,
@@ -872,6 +929,10 @@ public class Desktop extends jalview.jbgui.GDesktop
{
frame.setMinimumSize(new Dimension(ALIGN_FRAME_DEFAULT_MIN_WIDTH,
ALIGN_FRAME_DEFAULT_MIN_HEIGHT));
+ } else {
+ frame.setMinimumSize(
+ new Dimension(DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT));
+
}
}
@@ -881,7 +942,6 @@ public class Desktop extends jalview.jbgui.GDesktop
frame.setMaximizable(resizable);
frame.setIconifiable(resizable);
frame.setOpaque(Platform.isJS());
- boolean isEmbedded = (Platform.getDimIfEmbedded(frame, -1, -1) != null);
if (!isEmbedded && frame.getX() < 1 && frame.getY() < 1)
{
frame.setLocation(xOffset * openFrameCount,
@@ -898,7 +958,7 @@ public class Desktop extends jalview.jbgui.GDesktop
@Override
public void internalFrameActivated(InternalFrameEvent evt)
{
- JInternalFrame itf = desktop.getSelectedFrame();
+ JInternalFrame itf = getDesktopPane().getSelectedFrame();
if (itf != null)
{
if (itf instanceof AlignFrame)
@@ -930,7 +990,7 @@ public class Desktop extends jalview.jbgui.GDesktop
{
menuItem.removeActionListener(menuItem.getActionListeners()[0]);
}
- windowMenu.remove(menuItem);
+ getInstance().windowMenu.remove(menuItem);
}
});
@@ -952,9 +1012,9 @@ public class Desktop extends jalview.jbgui.GDesktop
setKeyBindings(frame);
- desktop.add(frame);
+ getDesktopPane().add(frame);
- windowMenu.add(menuItem);
+ getInstance().windowMenu.add(menuItem);
frame.toFront();
try
@@ -972,14 +1032,13 @@ public class Desktop extends jalview.jbgui.GDesktop
}
/**
- * Add key bindings to a JInternalFrame so that Ctrl-W and Cmd-W will close the
- * window
+ * Add key bindings to a JInternalFrame so that Ctrl-W and Cmd-W will close
+ * the window
*
* @param frame
*/
private static void setKeyBindings(JInternalFrame frame)
{
- @SuppressWarnings("serial")
final Action closeAction = new AbstractAction()
{
@Override
@@ -1012,7 +1071,7 @@ public class Desktop extends jalview.jbgui.GDesktop
{
if (!internalCopy)
{
- Desktop.jalviewClipboard = null;
+ jalviewClipboard = null;
}
internalCopy = false;
@@ -1057,7 +1116,7 @@ public class Desktop extends jalview.jbgui.GDesktop
try
{
- Desktop.transferFromDropTarget(files, protocols, evt, t);
+ transferFromDropTarget(files, protocols, evt, t);
} catch (Exception e)
{
e.printStackTrace();
@@ -1113,8 +1172,9 @@ public class Desktop extends jalview.jbgui.GDesktop
public void inputLocalFileMenuItem_actionPerformed(AlignViewport viewport)
{
String fileFormat = Cache.getProperty("DEFAULT_FILE_FORMAT");
- JalviewFileChooser chooser = JalviewFileChooser
- .forRead(Cache.getProperty("LAST_DIRECTORY"), fileFormat, BackupFiles.getEnabled());
+ JalviewFileChooser chooser = JalviewFileChooser.forRead(
+ Cache.getProperty("LAST_DIRECTORY"), fileFormat,
+ BackupFiles.getEnabled());
chooser.setFileView(new JalviewFileView());
chooser.setDialogTitle(
@@ -1247,7 +1307,7 @@ public class Desktop extends jalview.jbgui.GDesktop
{
String msg = MessageManager
.formatMessage("label.couldnt_locate", url);
- JvOptionPane.showInternalMessageDialog(Desktop.desktop, msg,
+ JvOptionPane.showInternalMessageDialog(getDesktopPane(), msg,
MessageManager.getString("label.url_not_found"),
JvOptionPane.WARNING_MESSAGE);
@@ -1268,7 +1328,7 @@ public class Desktop extends jalview.jbgui.GDesktop
};
String dialogOption = MessageManager
.getString("label.input_alignment_from_url");
- JvOptionPane.newOptionDialog(desktop).setResponseHandler(0, action)
+ JvOptionPane.newOptionDialog(desktopPane).setResponseHandler(0, action)
.showInternalDialog(panel, dialogOption,
JvOptionPane.YES_NO_CANCEL_OPTION,
JvOptionPane.PLAIN_MESSAGE, null, options,
@@ -1288,9 +1348,10 @@ public class Desktop extends jalview.jbgui.GDesktop
{
CutAndPasteTransfer cap = new CutAndPasteTransfer();
cap.setForInput(viewPanel);
- Desktop.addInternalFrame(cap,
- MessageManager.getString("label.cut_paste_alignmen_file"), true,
- 600, 500);
+ addInternalFrame(cap,
+ MessageManager.getString("label.cut_paste_alignmen_file"),
+ FRAME_MAKE_VISIBLE, 600, 500, FRAME_ALLOW_RESIZE,
+ FRAME_SET_MIN_SIZE_300);
}
/*
@@ -1300,10 +1361,8 @@ public class Desktop extends jalview.jbgui.GDesktop
public void quit()
{
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
- Cache.setProperty("SCREENGEOMETRY_WIDTH",
- screen.width + "");
- Cache.setProperty("SCREENGEOMETRY_HEIGHT",
- screen.height + "");
+ Cache.setProperty("SCREENGEOMETRY_WIDTH", screen.width + "");
+ Cache.setProperty("SCREENGEOMETRY_HEIGHT", screen.height + "");
storeLastKnownDimensions("", new Rectangle(getBounds().x, getBounds().y,
getWidth(), getHeight()));
@@ -1334,9 +1393,9 @@ public class Desktop extends jalview.jbgui.GDesktop
private void storeLastKnownDimensions(String string, Rectangle jc)
{
- Cache.log.debug("Storing last known dimensions for "
- + string + ": x:" + jc.x + " y:" + jc.y + " width:" + jc.width
- + " height:" + jc.height);
+ Cache.log.debug("Storing last known dimensions for " + string + ": x:"
+ + jc.x + " y:" + jc.y + " width:" + jc.width + " height:"
+ + jc.height);
Cache.setProperty(string + "SCREEN_X", jc.x + "");
Cache.setProperty(string + "SCREEN_Y", jc.y + "");
@@ -1447,7 +1506,7 @@ public class Desktop extends jalview.jbgui.GDesktop
public void closeAll_actionPerformed(ActionEvent e)
{
// TODO show a progress bar while closing?
- JInternalFrame[] frames = desktop.getAllFrames();
+ JInternalFrame[] frames = desktopPane.getAllFrames();
for (int i = 0; i < frames.length; i++)
{
try
@@ -1514,7 +1573,7 @@ public class Desktop extends jalview.jbgui.GDesktop
@Override
protected void showMemusage_actionPerformed(ActionEvent e)
{
- desktop.showMemoryUsage(showMemusage.isSelected());
+ desktopPane.showMemoryUsage(showMemusage.isSelected());
}
/*
@@ -1551,7 +1610,7 @@ public class Desktop extends jalview.jbgui.GDesktop
void reorderAssociatedWindows(boolean minimize, boolean close)
{
- JInternalFrame[] frames = desktop.getAllFrames();
+ JInternalFrame[] frames = desktopPane.getAllFrames();
if (frames == null || frames.length < 1)
{
return;
@@ -1691,16 +1750,17 @@ public class Desktop extends jalview.jbgui.GDesktop
setProgressBar(MessageManager.formatMessage(
"label.saving_jalview_project", new Object[]
{ chosenFile.getName() }), chosenFile.hashCode());
- Cache.setProperty("LAST_DIRECTORY",
- chosenFile.getParent());
+ Cache.setProperty("LAST_DIRECTORY", chosenFile.getParent());
// TODO catch and handle errors for savestate
// TODO prevent user from messing with the Desktop whilst we're saving
try
{
- boolean doBackup = BackupFiles.getEnabled();
- BackupFiles backupfiles = doBackup ? new BackupFiles(chosenFile) : null;
+ boolean doBackup = BackupFiles.getEnabled();
+ BackupFiles backupfiles = doBackup ? new BackupFiles(chosenFile)
+ : null;
- new Jalview2XML().saveState(doBackup ? backupfiles.getTempFile() : chosenFile);
+ new Jalview2XML().saveState(
+ doBackup ? backupfiles.getTempFile() : chosenFile);
if (doBackup)
{
@@ -1726,7 +1786,7 @@ public class Desktop extends jalview.jbgui.GDesktop
setProgressBar(null, chosenFile.hashCode());
}
}).start();
- }
+ }
}
@Override
@@ -1757,8 +1817,10 @@ public class Desktop extends jalview.jbgui.GDesktop
"Jalview Project (old)" };
JalviewFileChooser chooser = new JalviewFileChooser(
Cache.getProperty("LAST_DIRECTORY"), suffix, desc,
- "Jalview Project", true, BackupFiles.getEnabled()); // last two booleans: allFiles,
- // allowBackupFiles
+ "Jalview Project", true, BackupFiles.getEnabled()); // last two
+ // booleans:
+ // allFiles,
+ // allowBackupFiles
chooser.setFileView(new JalviewFileView());
chooser.setDialogTitle(MessageManager.getString("label.restore_state"));
chooser.setResponseHandler(0, new Runnable()
@@ -1775,29 +1837,30 @@ public class Desktop extends jalview.jbgui.GDesktop
@Override
public void run()
{
- try
+ try
{
new Jalview2XML().loadJalviewAlign(selectedFile);
} catch (OutOfMemoryError oom)
- {
- new OOMWarning("Whilst loading project from " + choice, oom);
- } catch (Exception ex)
- {
- Cache.log.error(
- "Problems whilst loading project from " + choice, ex);
- JvOptionPane.showMessageDialog(Desktop.desktop,
- MessageManager.formatMessage(
- "label.error_whilst_loading_project_from",
- new Object[]
- { choice }),
- MessageManager.getString("label.couldnt_load_project"),
- JvOptionPane.WARNING_MESSAGE);
- }
+ {
+ new OOMWarning("Whilst loading project from " + choice, oom);
+ } catch (Exception ex)
+ {
+ Cache.log.error(
+ "Problems whilst loading project from " + choice, ex);
+ JvOptionPane.showMessageDialog(getDesktopPane(),
+ MessageManager.formatMessage(
+ "label.error_whilst_loading_project_from",
+ new Object[]
+ { choice }),
+ MessageManager
+ .getString("label.couldnt_load_project"),
+ JvOptionPane.WARNING_MESSAGE);
+ }
}
}).start();
}
});
-
+
chooser.showOpenDialog(this);
}
@@ -1828,7 +1891,7 @@ public class Desktop extends jalview.jbgui.GDesktop
{
progressPanel = new JPanel(new GridLayout(1, 1));
totalProgressCount = 0;
- instance.getContentPane().add(progressPanel, BorderLayout.SOUTH);
+ getContentPane().add(progressPanel, BorderLayout.SOUTH);
}
JPanel thisprogress = new JPanel(new BorderLayout(10, 5));
JProgressBar progressBar = new JProgressBar();
@@ -1841,7 +1904,7 @@ public class Desktop extends jalview.jbgui.GDesktop
((GridLayout) progressPanel.getLayout()).setRows(
((GridLayout) progressPanel.getLayout()).getRows() + 1);
++totalProgressCount;
- instance.validate();
+ validate();
return thisprogress;
}
@@ -1895,7 +1958,7 @@ public class Desktop extends jalview.jbgui.GDesktop
*/
public static AlignmentPanel[] getAlignmentPanels(String alignmentId)
{
- if (Desktop.desktop == null)
+ if (getDesktopPane() == null)
{
// no frames created and in headless mode
// TODO: verify that frames are recoverable when in headless mode
@@ -1937,9 +2000,9 @@ public class Desktop extends jalview.jbgui.GDesktop
public static AlignmentViewport[] getViewports(String sequenceSetId)
{
List viewp = new ArrayList<>();
- if (desktop != null)
+ if (getDesktopPane() != null)
{
- AlignFrame[] frames = Desktop.getAlignFrames();
+ AlignFrame[] frames = getAlignFrames();
for (AlignFrame afr : frames)
{
@@ -1986,9 +2049,7 @@ public class Desktop extends jalview.jbgui.GDesktop
// FIXME: ideally should use UI interface API
FeatureSettings viewFeatureSettings = (af.featureSettings != null
- && af.featureSettings.isOpen())
- ? af.featureSettings
- : null;
+ && af.featureSettings.isOpen()) ? af.featureSettings : null;
Rectangle fsBounds = af.getFeatureSettingsGeometry();
for (int i = 0; i < size; i++)
{
@@ -2021,7 +2082,8 @@ public class Desktop extends jalview.jbgui.GDesktop
addInternalFrame(newaf, af.getTitle(), AlignFrame.DEFAULT_WIDTH,
AlignFrame.DEFAULT_HEIGHT);
- // and materialise a new feature settings dialog instance for the new alignframe
+ // and materialise a new feature settings dialog instance for the new
+ // alignframe
// (closes the old as if 'OK' was pressed)
if (ap == af.alignPanel && newaf.featureSettings != null
&& newaf.featureSettings.isOpen()
@@ -2039,9 +2101,9 @@ public class Desktop extends jalview.jbgui.GDesktop
/**
* Gather expanded views (separate AlignFrame's) with the same sequence set
- * identifier back in to this frame as additional views, and close the expanded
- * views. Note the expanded frames may themselves have multiple views. We take
- * the lot.
+ * identifier back in to this frame as additional views, and close the
+ * expanded views. Note the expanded frames may themselves have multiple
+ * views. We take the lot.
*
* @param source
*/
@@ -2049,7 +2111,7 @@ public class Desktop extends jalview.jbgui.GDesktop
{
source.viewport.setGatherViewsHere(true);
source.viewport.setExplodedGeometry(source.getBounds());
- JInternalFrame[] frames = desktop.getAllFrames();
+ JInternalFrame[] frames = desktopPane.getAllFrames();
String viewId = source.viewport.getSequenceSetId();
for (int t = 0; t < frames.length; t++)
{
@@ -2093,8 +2155,7 @@ public class Desktop extends jalview.jbgui.GDesktop
}
// refresh the feature setting UI for the source frame if it exists
- if (source.featureSettings != null
- && source.featureSettings.isOpen())
+ if (source.featureSettings != null && source.featureSettings.isOpen())
{
source.showFeatureSettingsUI();
}
@@ -2102,7 +2163,7 @@ public class Desktop extends jalview.jbgui.GDesktop
public JInternalFrame[] getAllFrames()
{
- return desktop.getAllFrames();
+ return desktopPane.getAllFrames();
}
/**
@@ -2188,7 +2249,7 @@ public class Desktop extends jalview.jbgui.GDesktop
});
msgPanel.add(jcb);
- JvOptionPane.showMessageDialog(Desktop.desktop, msgPanel,
+ JvOptionPane.showMessageDialog(desktopPane, msgPanel,
MessageManager
.getString("label.SEQUENCE_ID_no_longer_used"),
JvOptionPane.WARNING_MESSAGE);
@@ -2199,12 +2260,12 @@ public class Desktop extends jalview.jbgui.GDesktop
/**
* Proxy class for JDesktopPane which optionally displays the current memory
- * usage and highlights the desktop area with a red bar if free memory runs low.
+ * usage and highlights the desktop area with a red bar if free memory runs
+ * low.
*
* @author AMW
*/
- public class MyDesktopPane extends JDesktopPane
- implements Runnable
+ public class MyDesktopPane extends JDesktopPane implements Runnable
{
private static final float ONE_MB = 1048576f;
@@ -2303,11 +2364,10 @@ public class Desktop extends jalview.jbgui.GDesktop
{
if (Jalview.isHeadlessMode())
{
- // Desktop.desktop is null in headless mode
- return new AlignFrame[] { Jalview.currentAlignFrame };
+ return new AlignFrame[] { Jalview.getInstance().currentAlignFrame };
}
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ JInternalFrame[] frames = getDesktopPane().getAllFrames();
if (frames == null)
{
@@ -2352,7 +2412,7 @@ public class Desktop extends jalview.jbgui.GDesktop
*/
public GStructureViewer[] getJmols()
{
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ JInternalFrame[] frames = desktopPane.getAllFrames();
if (frames == null)
{
@@ -2388,7 +2448,7 @@ public class Desktop extends jalview.jbgui.GDesktop
} catch (Exception ex)
{
Cache.log.error("Groovy Shell Creation failed.", ex);
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(desktopPane,
MessageManager.getString("label.couldnt_create_groovy_shell"),
MessageManager.getString("label.groovy_support_failed"),
@@ -2441,14 +2501,23 @@ public class Desktop extends jalview.jbgui.GDesktop
}
/**
- * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this binding
- * when opened
+ * Bind Ctrl/Cmd-Q to Quit - for reset as Groovy Console takes over this
+ * binding when opened
*/
protected void addQuitHandler()
{
+<<<<<<< HEAD
+ getRootPane()
+ .getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
+ KeyStroke
+ .getKeyStroke(KeyEvent.VK_Q,
+ jalview.util.ShortcutKeyMaskExWrapper
+ .getMenuShortcutKeyMaskEx()),
+=======
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
.put(KeyStroke.getKeyStroke(KeyEvent.VK_Q,
Platform.SHORTCUT_KEY_MASK),
+>>>>>>> refs/heads/Jalview-JS/develop.JAL-3446.ctrlDown
"Quit");
getRootPane().getActionMap().put("Quit", new AbstractAction()
{
@@ -2577,15 +2646,16 @@ public class Desktop extends jalview.jbgui.GDesktop
}
/**
- * This will return the first AlignFrame holding the given viewport instance. It
- * will break if there are more than one AlignFrames viewing a particular av.
+ * This will return the first AlignFrame holding the given viewport instance.
+ * It will break if there are more than one AlignFrames viewing a particular
+ * av.
*
* @param viewport
* @return alignFrame for viewport
*/
public static AlignFrame getAlignFrameFor(AlignViewportI viewport)
{
- if (desktop != null)
+ if (getDesktopPane() != null)
{
AlignmentPanel[] aps = getAlignmentPanels(
viewport.getSequenceSetId());
@@ -2647,7 +2717,7 @@ public class Desktop extends jalview.jbgui.GDesktop
// todo: changesupport handlers need to be transferred
if (discoverer == null)
{
- discoverer = new jalview.ws.jws1.Discoverer();
+ discoverer = jalview.ws.jws1.Discoverer.getInstance();
// register PCS handler for desktop.
discoverer.addPropertyChangeListener(changeSupport);
}
@@ -2658,7 +2728,7 @@ public class Desktop extends jalview.jbgui.GDesktop
if (Cache.getDefault("SHOW_JWS2_SERVICES", true))
{
- t2 = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
+ t2 = jalview.ws.jws2.Jws2Discoverer.getInstance()
.startDiscoverer(changeSupport);
}
Thread t3 = null;
@@ -2691,7 +2761,7 @@ public class Desktop extends jalview.jbgui.GDesktop
{
if (evt.getNewValue() == null || evt.getNewValue() instanceof Vector)
{
- final String ermsg = jalview.ws.jws2.Jws2Discoverer.getDiscoverer()
+ final String ermsg = jalview.ws.jws2.Jws2Discoverer.getInstance()
.getErrorMessages();
if (ermsg != null)
{
@@ -2730,7 +2800,7 @@ public class Desktop extends jalview.jbgui.GDesktop
*
* jd.waitForInput();
*/
- JvOptionPane.showConfirmDialog(Desktop.desktop,
+ JvOptionPane.showConfirmDialog(desktopPane,
new JLabel(""
+ "It may be that you have invalid JABA URLs in your web service preferences,"
@@ -2767,7 +2837,7 @@ public class Desktop extends jalview.jbgui.GDesktop
*/
public static void showUrl(final String url)
{
- showUrl(url, Desktop.instance);
+ showUrl(url, getInstance());
}
/**
@@ -2796,7 +2866,7 @@ public class Desktop extends jalview.jbgui.GDesktop
jalview.util.BrowserLauncher.openURL(url);
} catch (Exception ex)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(getDesktopPane(),
MessageManager
.getString("label.web_browser_not_found_unix"),
MessageManager.getString("label.web_browser_not_found"),
@@ -2836,7 +2906,7 @@ public class Desktop extends jalview.jbgui.GDesktop
try
{
url = e.getURL().toString();
- Desktop.showUrl(url);
+ showUrl(url);
} catch (Exception x)
{
if (url != null)
@@ -2895,7 +2965,7 @@ public class Desktop extends jalview.jbgui.GDesktop
{
}
}
- if (instance == null)
+ if (Jalview.isHeadlessMode())
{
return;
}
@@ -2955,8 +3025,8 @@ public class Desktop extends jalview.jbgui.GDesktop
/**
* Explode the views in the given SplitFrame into separate SplitFrame windows.
- * This respects (remembers) any previous 'exploded geometry' i.e. the size and
- * location last time the view was expanded (if any). However it does not
+ * This respects (remembers) any previous 'exploded geometry' i.e. the size
+ * and location last time the view was expanded (if any). However it does not
* remember the split pane divider location - this is set to match the
* 'exploding' frame.
*
@@ -3021,7 +3091,7 @@ public class Desktop extends jalview.jbgui.GDesktop
{
splitFrame.setLocation(geometry.getLocation());
}
- Desktop.addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
+ addInternalFrame(splitFrame, sf.getTitle(), -1, -1);
}
/*
@@ -3059,7 +3129,7 @@ public class Desktop extends jalview.jbgui.GDesktop
String topViewId = myTopFrame.viewport.getSequenceSetId();
String bottomViewId = myBottomFrame.viewport.getSequenceSetId();
- JInternalFrame[] frames = desktop.getAllFrames();
+ JInternalFrame[] frames = desktopPane.getAllFrames();
for (JInternalFrame frame : frames)
{
if (frame instanceof SplitFrame && frame != source)
@@ -3122,12 +3192,14 @@ public class Desktop extends jalview.jbgui.GDesktop
* - the payload from the drop event
* @throws Exception
*/
+ @SuppressWarnings("unchecked")
public static void transferFromDropTarget(List files,
List protocols, DropTargetDropEvent evt,
Transferable t) throws Exception
{
- // BH 2018 changed List to List to allow for File from SwingJS
+ // BH 2018 changed List to List to allow for File from
+ // SwingJS
// DataFlavor[] flavors = t.getTransferDataFlavors();
// for (int i = 0; i < flavors.length; i++) {
@@ -3139,7 +3211,8 @@ public class Desktop extends jalview.jbgui.GDesktop
// byte[] data = getDroppedFileBytes(file);
// fileName.setText(file.getName() + " - " + data.length + " " +
// evt.getLocation());
- // JTextArea target = (JTextArea) ((DropTarget) evt.getSource()).getComponent();
+ // JTextArea target = (JTextArea) ((DropTarget)
+ // evt.getSource()).getComponent();
// target.setText(new String(data));
// }
// dtde.dropComplete(true);
@@ -3191,7 +3264,7 @@ public class Desktop extends jalview.jbgui.GDesktop
{
// Works on Windows and MacOSX
Cache.log.debug("Drop handled as javaFileListFlavor");
- for (Object file : (List) t
+ for (File file : (List) t
.getTransferData(DataFlavor.javaFileListFlavor))
{
files.add(file);
@@ -3339,10 +3412,10 @@ public class Desktop extends jalview.jbgui.GDesktop
}
/**
- * Answers a (possibly empty) list of any structure viewer frames (currently for
- * either Jmol or Chimera) which are currently open. This may optionally be
- * restricted to viewers of a specified class, or viewers linked to a specified
- * alignment panel.
+ * Answers a (possibly empty) list of any structure viewer frames (currently
+ * for either Jmol or Chimera) which are currently open. This may optionally
+ * be restricted to viewers of a specified class, or viewers linked to a
+ * specified alignment panel.
*
* @param apanel
* if not null, only return viewers linked to this panel
@@ -3355,7 +3428,7 @@ public class Desktop extends jalview.jbgui.GDesktop
Class extends StructureViewerBase> structureViewerClass)
{
List result = new ArrayList<>();
- JInternalFrame[] frames = Desktop.instance.getAllFrames();
+ JInternalFrame[] frames = getAllFrames();
for (JInternalFrame frame : frames)
{
diff --git a/src/jalview/gui/FeatureEditor.java b/src/jalview/gui/FeatureEditor.java
index d547c58..a02ec36 100644
--- a/src/jalview/gui/FeatureEditor.java
+++ b/src/jalview/gui/FeatureEditor.java
@@ -222,7 +222,7 @@ public class FeatureEditor
updateColourButton(mainPanel, colour, featureColour);
};
};
- JalviewColourChooser.showColourChooser(Desktop.getDesktop(),
+ JalviewColourChooser.showColourChooser(Desktop.getDesktopPane(),
title, featureColour.getColour(), listener);
}
else
@@ -412,7 +412,7 @@ public class FeatureEditor
* set dialog action handlers for OK (create/Amend) and Cancel options
* also for Delete if applicable (when amending features)
*/
- JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.desktop)
+ JvOptionPane dialog = JvOptionPane.newOptionDialog(Desktop.getDesktopPane())
.setResponseHandler(0, okAction).setResponseHandler(2, cancelAction);
if (!forCreate)
{
diff --git a/src/jalview/gui/FeatureSettings.java b/src/jalview/gui/FeatureSettings.java
index b49593a..8c4b355 100644
--- a/src/jalview/gui/FeatureSettings.java
+++ b/src/jalview/gui/FeatureSettings.java
@@ -436,8 +436,8 @@ public class FeatureSettings extends JPanel
}
else
{
- Desktop.addInternalFrame(frame, title, false, bounds.width,
- bounds.height);
+ Desktop.addInternalFrame(frame, title, Desktop.FRAME_NOT_VISIBLE, bounds.width,
+ bounds.height, Desktop.FRAME_ALLOW_RESIZE, Desktop.FRAME_SET_MIN_SIZE_300);
frame.setBounds(bounds);
frame.setVisible(true);
}
diff --git a/src/jalview/gui/Finder.java b/src/jalview/gui/Finder.java
index a1693f7..01c8a16 100755
--- a/src/jalview/gui/Finder.java
+++ b/src/jalview/gui/Finder.java
@@ -121,8 +121,8 @@ public class Finder extends GFinder
}
});
addEscapeHandler();
- Desktop.addInternalFrame(frame, MessageManager.getString("label.find"),
- true, MY_WIDTH, MY_HEIGHT, true, true);
+ Desktop.addInternalFrame(frame, MessageManager.getString("label.find"),
+ Desktop.FRAME_MAKE_VISIBLE, MY_WIDTH, MY_HEIGHT, Desktop.FRAME_ALLOW_RESIZE, Desktop.FRAME_ALLOW_ANY_SIZE);
searchBox.getComponent().requestFocus();
}
@@ -176,7 +176,7 @@ public class Finder extends GFinder
*/
boolean getFocusedViewport()
{
- if (focusfixed || Desktop.desktop == null)
+ if (focusfixed || Desktop.getDesktopPane() == null)
{
if (ap != null && av != null)
{
@@ -187,7 +187,7 @@ public class Finder extends GFinder
}
// now checks further down the window stack to fix bug
// https://mantis.lifesci.dundee.ac.uk/view.php?id=36008
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames();
for (int f = 0; f < frames.length; f++)
{
JInternalFrame alignFrame = frames[f];
diff --git a/src/jalview/gui/FontChooser.java b/src/jalview/gui/FontChooser.java
index 92cc4c6..2d9682b 100755
--- a/src/jalview/gui/FontChooser.java
+++ b/src/jalview/gui/FontChooser.java
@@ -137,14 +137,14 @@ public class FontChooser extends GFontChooser
if (isTreeFont())
{
Desktop.addInternalFrame(frame,
- MessageManager.getString("action.change_font_tree_panel"),
- 400, 200, false);
+ MessageManager.getString("action.change_font_tree_panel"), Desktop.FRAME_MAKE_VISIBLE,
+ 400, 200, Desktop.FRAME_NOT_RESIZABLE, Desktop.FRAME_SET_MIN_SIZE_300);
}
else
{
Desktop.addInternalFrame(frame,
- MessageManager.getString("action.change_font"), 380, 220,
- false);
+ MessageManager.getString("action.change_font"), Desktop.FRAME_MAKE_VISIBLE, 380, 220,
+ Desktop.FRAME_NOT_RESIZABLE, Desktop.FRAME_SET_MIN_SIZE_300);
}
frame.setLayer(JLayeredPane.PALETTE_LAYER);
diff --git a/src/jalview/gui/IdCanvas.java b/src/jalview/gui/IdCanvas.java
index 10c0787..14ae033 100755
--- a/src/jalview/gui/IdCanvas.java
+++ b/src/jalview/gui/IdCanvas.java
@@ -20,6 +20,10 @@
*/
package jalview.gui;
+import jalview.datamodel.SequenceI;
+import jalview.viewmodel.ViewportListenerI;
+import jalview.viewmodel.ViewportRanges;
+
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
@@ -33,10 +37,6 @@ import java.util.List;
import javax.swing.JPanel;
-import jalview.datamodel.SequenceI;
-import jalview.viewmodel.ViewportListenerI;
-import jalview.viewmodel.ViewportRanges;
-
/**
* DOCUMENT ME!
*
@@ -59,7 +59,7 @@ public class IdCanvas extends JPanel implements ViewportListenerI
int imgHeight = 0;
- boolean fastPaint = false;
+ private boolean fastPaint = false;
List searchResults;
@@ -137,6 +137,7 @@ public class IdCanvas extends JPanel implements ViewportListenerI
g.drawString(s.getDisplayId(av.getShowJVSuffix()), xPos,
(((i - starty + 1) * charHeight) + ypos) - (charHeight / 5));
+ // JAL-3253-applet was just hiddenRows here. ccfc48e (gmungoc) added getShowHiddenMarkers test
if (hiddenRows && av.getShowHiddenMarkers())
{
drawMarker(g, av, i, starty, ypos);
@@ -221,6 +222,11 @@ public class IdCanvas extends JPanel implements ViewportListenerI
@Override
public void paintComponent(Graphics g)
{
+ if (av.getAlignPanel().getHoldRepaint())
+ {
+ return;
+ }
+
g.setColor(Color.white);
g.fillRect(0, 0, getWidth(), getHeight());
@@ -244,7 +250,7 @@ public class IdCanvas extends JPanel implements ViewportListenerI
if (oldHeight != imgHeight || image.getWidth(this) != getWidth())
{
- image = new BufferedImage(getWidth(), imgHeight,
+ image = new BufferedImage(getWidth(), imgHeight,
BufferedImage.TYPE_INT_RGB);
}
@@ -384,20 +390,49 @@ public class IdCanvas extends JPanel implements ViewportListenerI
int alignmentWidth = alignViewport.getAlignment().getWidth();
final int alheight = alignViewport.getAlignment().getHeight();
- /*
+
+// int annotationHeight = 0;
+
+ /* (former)
* assumption: SeqCanvas.calculateWrappedGeometry has been called
+ *
+ * was based on the fact that SeqCanvas was added as a child prior to IdCanvas,
+ * and children are processed in order of addition.
+ *
+ * It's probably fine. But...
+ *
*/
SeqCanvas seqCanvas = alignViewport.getAlignPanel()
.getSeqPanel().seqCanvas;
+ // ...better: let's call it now
+ seqCanvas.calculateWrappedGeometry();
final int charHeight = alignViewport.getCharHeight();
AnnotationLabels labels = null;
if (alignViewport.isShowAnnotation())
{
+ // BH when was ap == null?
+ if (ap == null)
+ {
+ ap = new AnnotationPanel(alignViewport);
+ }
+// annotationHeight = ap.adjustPanelHeight();
labels = new AnnotationLabels(alignViewport);
}
+// int hgap = charHeight;
+// if (alignViewport.getScaleAboveWrapped())
+// {
+// hgap += charHeight;
+// }
+//
+// /*
+// * height of alignment + gap + annotations (if shown)
+// */
+// int cHeight = alheight * charHeight + hgap
+// + annotationHeight;
+//
ViewportRanges ranges = alignViewport.getRanges();
int rowSize = ranges.getViewportWidth();
@@ -568,20 +603,34 @@ public class IdCanvas extends JPanel implements ViewportListenerI
public void propertyChange(PropertyChangeEvent evt)
{
String propertyName = evt.getPropertyName();
- if (propertyName.equals(ViewportRanges.STARTSEQ)
- || (av.getWrapAlignment()
- && propertyName.equals(ViewportRanges.STARTRES)))
+ switch (propertyName)
{
+ case ViewportRanges.STARTSEQ:
fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
- }
- else if (propertyName.equals(ViewportRanges.STARTRESANDSEQ))
- {
+ break;
+ case ViewportRanges.STARTRES:
+ if (av.getWrapAlignment())
+ {
+ fastPaint((int) evt.getNewValue() - (int) evt.getOldValue());
+ }
+ break;
+ case ViewportRanges.STARTRESANDSEQ:
fastPaint(((int[]) evt.getNewValue())[1]
- ((int[]) evt.getOldValue())[1]);
- }
- else if (propertyName.equals(ViewportRanges.MOVE_VIEWPORT))
- {
+ break;
+ case ViewportRanges.MOVE_VIEWPORT:
repaint();
+ break;
+ default:
}
}
+
+ /**
+ * Clears the flag that allows a 'fast paint' on the next repaint, so
+ * requiring a full repaint
+ */
+ public void setNoFastPaint()
+ {
+ fastPaint = false;
+ }
}
diff --git a/src/jalview/gui/IdPanel.java b/src/jalview/gui/IdPanel.java
index 4b5e9d4..2734b8d 100755
--- a/src/jalview/gui/IdPanel.java
+++ b/src/jalview/gui/IdPanel.java
@@ -242,7 +242,7 @@ public class IdPanel extends JPanel
jalview.util.BrowserLauncher.openURL(url);
} catch (Exception ex)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString("label.web_browser_not_found_unix"),
MessageManager.getString("label.web_browser_not_found"),
JvOptionPane.WARNING_MESSAGE);
diff --git a/src/jalview/gui/JalviewDialog.java b/src/jalview/gui/JalviewDialog.java
index 1d7bf3d..0ff5606 100644
--- a/src/jalview/gui/JalviewDialog.java
+++ b/src/jalview/gui/JalviewDialog.java
@@ -78,11 +78,11 @@ public abstract class JalviewDialog extends JPanel
boolean block, String title, int width, int height)
{
- frame = new JDialog(Desktop.instance, modal);
+ frame = new JDialog(Desktop.getInstance(), modal);
frame.setTitle(title);
- if (Desktop.instance != null)
+ if (Desktop.getInstance() != null)
{
- Rectangle deskr = Desktop.instance.getBounds();
+ Rectangle deskr = Desktop.getInstance().getBounds();
frame.setBounds(new Rectangle((int) (deskr.getCenterX() - width / 2),
(int) (deskr.getCenterY() - height / 2), width, height));
}
diff --git a/src/jalview/gui/JvSwingUtils.java b/src/jalview/gui/JvSwingUtils.java
index 2f4a0fe..f23dcf8 100644
--- a/src/jalview/gui/JvSwingUtils.java
+++ b/src/jalview/gui/JvSwingUtils.java
@@ -47,6 +47,7 @@ import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import jalview.util.MessageManager;
+import jalview.util.Platform;
/**
* useful functions for building Swing GUIs
@@ -56,12 +57,18 @@ import jalview.util.MessageManager;
*/
public final class JvSwingUtils
{
+ static final String HTML_PREFIX = (Platform.isJS() ?
+ ""
+ : "
"
+ );
+
/**
* wrap a bare html safe string to around 60 characters per line using a CSS
* style class specifying word-wrap and break-word
*
* @param enclose
- * if true, add <html> wrapper tags
+ * if true, add <html> wrapper tags (currently false for only
+ * two references -- both in Jws2Discoverer --
* @param ttext
*
* @return
@@ -70,40 +77,40 @@ public final class JvSwingUtils
{
Objects.requireNonNull(ttext,
"Tootip text to format must not be null!");
- ttext = ttext.trim();
- boolean maxLengthExceeded = false;
+ ttext = ttext.trim().replaceAll("
", "
");
- if (ttext.contains("
"))
+ boolean maxLengthExceeded = false;
+ boolean isHTML = ttext.startsWith("");
+ if (isHTML)
{
- String[] htmllines = ttext.split("
");
- for (String line : htmllines)
- {
- maxLengthExceeded = line.length() > 60;
- if (maxLengthExceeded)
- {
+ ttext = ttext.substring(6);
+ }
+ if (ttext.endsWith(""))
+ {
+ isHTML = true;
+ ttext = ttext.substring(0, ttext.length() - 7);
+ }
+ boolean hasBR = ttext.contains("
");
+ enclose |= isHTML || hasBR;
+ if (hasBR)
+ {
+ int pt = -1, ptlast = -4;
+ while ((pt = ttext.indexOf("
", pt + 1)) >= 0) {
+ if (pt - ptlast - 4 > 60) {
+ maxLengthExceeded = true;
break;
}
}
}
- else
+ else
{
maxLengthExceeded = ttext.length() > 60;
}
- if (!maxLengthExceeded)
- {
- return enclose ? "" + ttext + "" : ttext;
- }
-
- return (enclose ? "" : "")
- // BH 2018
- + "
"
-// + "
"
- + ttext
- + "
"
-// + ""
- + ((enclose ? "" : ""));
+ String ret = (!enclose ? ttext : maxLengthExceeded ? HTML_PREFIX + ttext + "
" :
+ "" + ttext + "");
+ //System.out.println("JvSwUtil " + enclose + " " + maxLengthExceeded + " " + ret);
+ return ret;
}
public static JButton makeButton(String label, String tooltip,
diff --git a/src/jalview/gui/LineartOptions.java b/src/jalview/gui/LineartOptions.java
index 9704b39..62bdd35 100644
--- a/src/jalview/gui/LineartOptions.java
+++ b/src/jalview/gui/LineartOptions.java
@@ -86,7 +86,7 @@ public class LineartOptions extends JPanel
ex.printStackTrace();
}
- dialog = JvOptionPane.newOptionDialog(Desktop.desktop);
+ dialog = JvOptionPane.newOptionDialog(Desktop.getDesktopPane());
}
/**
diff --git a/src/jalview/gui/OOMWarning.java b/src/jalview/gui/OOMWarning.java
index 02c8fe1..dc5d0f5 100644
--- a/src/jalview/gui/OOMWarning.java
+++ b/src/jalview/gui/OOMWarning.java
@@ -72,7 +72,7 @@ public class OOMWarning implements Runnable
public OOMWarning(String string, OutOfMemoryError oomerror)
{
- this(string, oomerror, Desktop.desktop);
+ this(string, oomerror, Desktop.getDesktopPane());
}
@Override
diff --git a/src/jalview/gui/PaintRefresher.java b/src/jalview/gui/PaintRefresher.java
index 953fdc5..326bac0 100755
--- a/src/jalview/gui/PaintRefresher.java
+++ b/src/jalview/gui/PaintRefresher.java
@@ -128,13 +128,13 @@ public class PaintRefresher
{
// BH 2019.04.22 fixes JS problem of repaint() consolidation
// that occurs in JavaScript but not Java [JAL-3226]
- ((IdCanvas) comp).fastPaint = false;
+ ((IdCanvas) comp).setNoFastPaint();
}
else if (comp instanceof SeqCanvas)
{
// BH 2019.04.22 fixes JS problem of repaint() consolidation
// that occurs in JavaScript but not Java [JAL-3226]
- ((SeqCanvas) comp).fastPaint = false;
+ ((SeqCanvas) comp).setNoFastPaint();
}
comp.repaint();
}
diff --git a/src/jalview/gui/PopupMenu.java b/src/jalview/gui/PopupMenu.java
index 2a7fb9f..4469b43 100644
--- a/src/jalview/gui/PopupMenu.java
+++ b/src/jalview/gui/PopupMenu.java
@@ -301,7 +301,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
jalview.util.BrowserLauncher.openURL(url);
} catch (Exception ex)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString("label.web_browser_not_found_unix"),
MessageManager.getString("label.web_browser_not_found"),
JvOptionPane.WARNING_MESSAGE);
@@ -1699,7 +1699,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
menuItem.setEnabled(true);
for (String calcId : tipEntries.keySet())
{
- tooltip.append("
" + calcId + "/" + tipEntries.get(calcId));
+ tooltip.append("
" + calcId + "/" + tipEntries.get(calcId));
}
String tooltipText = JvSwingUtils.wrapTooltip(true,
tooltip.toString());
@@ -2040,8 +2040,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
ap.paintAlignment(false, false);
}
sequence.setDescription(dialog.getDescription());
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
}
});
}
@@ -2083,7 +2082,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
refresh();
}
};
- JalviewColourChooser.showColourChooser(Desktop.getDesktop(),
+ JalviewColourChooser.showColourChooser(Desktop.getDesktopPane(),
title, Color.BLUE, listener);
}
@@ -2172,9 +2171,8 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
startEnd, caseChange);
ap.alignFrame.addHistoryItem(caseCommand);
+ ap.av.notifyAlignment();
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
}
}
@@ -2281,8 +2279,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener
sg.getStartRes(), sg.getEndRes() + 1,
ap.av.getAlignment());
ap.alignFrame.addHistoryItem(editCommand);
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
}
});
}
diff --git a/src/jalview/gui/Preferences.java b/src/jalview/gui/Preferences.java
index 55345e0..4030afa 100755
--- a/src/jalview/gui/Preferences.java
+++ b/src/jalview/gui/Preferences.java
@@ -781,16 +781,16 @@ public class Preferences extends GPreferences
protColour.getSelectedItem().toString());
Cache.setPropertyNoSave(DEFAULT_COLOUR_NUC,
nucColour.getSelectedItem().toString());
- Cache.setColourProperty("ANNOTATIONCOLOUR_MIN",
+ Cache.setColourPropertyNoSave("ANNOTATIONCOLOUR_MIN",
minColour.getBackground());
- Cache.setColourProperty("ANNOTATIONCOLOUR_MAX",
+ Cache.setColourPropertyNoSave("ANNOTATIONCOLOUR_MAX",
maxColour.getBackground());
/*
* Save Overview settings
*/
- Cache.setColourProperty(GAP_COLOUR, gapColour.getBackground());
- Cache.setColourProperty(HIDDEN_COLOUR, hiddenColour.getBackground());
+ Cache.setColourPropertyNoSave(GAP_COLOUR, gapColour.getBackground());
+ Cache.setColourPropertyNoSave(HIDDEN_COLOUR, hiddenColour.getBackground());
Cache.setPropertyNoSave(USE_LEGACY_GAP,
Boolean.toString(useLegacyGap.isSelected()));
Cache.setPropertyNoSave(SHOW_OV_HIDDEN_AT_START,
@@ -807,8 +807,11 @@ public class Preferences extends GPreferences
Boolean.toString(useRnaView.isSelected()));
Cache.setPropertyNoSave(STRUCT_FROM_PDB,
Boolean.toString(structFromPdb.isSelected()));
- Cache.setPropertyNoSave(STRUCTURE_DISPLAY,
- structViewer.getSelectedItem().toString());
+ if (!Platform.isJS())
+ {
+ Cache.setPropertyNoSave(STRUCTURE_DISPLAY,
+ structViewer.getSelectedItem().toString());
+ }
Cache.setOrRemove(CHIMERA_PATH, chimeraPath.getText());
Cache.setPropertyNoSave("MAP_WITH_SIFTS",
Boolean.toString(siftsMapping.isSelected()));
@@ -960,7 +963,7 @@ public class Preferences extends GPreferences
BackupFilesPresetEntry.SAVEDCONFIG, savedBFPE.toString());
Cache.saveProperties();
- Desktop.instance.doConfigureStructurePrefs();
+ Desktop.getInstance().doConfigureStructurePrefs();
try
{
frame.setClosed(true);
@@ -1107,7 +1110,7 @@ public class Preferences extends GPreferences
boolean valid = false;
while (!valid)
{
- if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
+ if (JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(), link,
MessageManager.getString("label.new_sequence_url_link"),
JvOptionPane.OK_CANCEL_OPTION, -1,
null) == JvOptionPane.OK_OPTION)
@@ -1159,7 +1162,7 @@ public class Preferences extends GPreferences
boolean valid = false;
while (!valid)
{
- if (JvOptionPane.showInternalConfirmDialog(Desktop.desktop, link,
+ if (JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(), link,
MessageManager.getString("label.edit_sequence_url_link"),
JvOptionPane.OK_CANCEL_OPTION, -1,
null) == JvOptionPane.OK_OPTION)
@@ -1332,7 +1335,7 @@ public class Preferences extends GPreferences
} catch (NumberFormatException x)
{
userIdWidth.setText("");
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager
.getString("warn.user_defined_width_requirements"),
MessageManager.getString("label.invalid_id_column_width"),
@@ -1358,7 +1361,7 @@ public class Preferences extends GPreferences
File f = new File(chimeraPath.getText());
if (!f.canExecute())
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString("label.invalid_chimera_path"),
MessageManager.getString("label.invalid_name"),
JvOptionPane.ERROR_MESSAGE);
@@ -1397,7 +1400,7 @@ public class Preferences extends GPreferences
if (!found)
{
String[] options = { "OK", "Help" };
- int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
+ int showHelp = JvOptionPane.showInternalOptionDialog(Desktop.getDesktopPane(),
JvSwingUtils.wrapTooltip(true,
MessageManager.getString("label.chimera_missing")),
"", JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
diff --git a/src/jalview/gui/PromptUserConfig.java b/src/jalview/gui/PromptUserConfig.java
index cb59452..77d83a8 100644
--- a/src/jalview/gui/PromptUserConfig.java
+++ b/src/jalview/gui/PromptUserConfig.java
@@ -200,7 +200,7 @@ public class PromptUserConfig implements Runnable
}
try
{
- int reply = JvOptionPane.showConfirmDialog(Desktop.desktop, // component,
+ int reply = JvOptionPane.showConfirmDialog(Desktop.getDesktopPane(), // component,
dialogText, dialogTitle,
(allowCancel) ? JvOptionPane.YES_NO_CANCEL_OPTION
: JvOptionPane.YES_NO_OPTION,
diff --git a/src/jalview/gui/RedundancyPanel.java b/src/jalview/gui/RedundancyPanel.java
index 6ed3248..c7e2b8e 100755
--- a/src/jalview/gui/RedundancyPanel.java
+++ b/src/jalview/gui/RedundancyPanel.java
@@ -103,8 +103,8 @@ public class RedundancyPanel extends GSliderPanel implements Runnable
frame.setContentPane(this);
Desktop.addInternalFrame(frame,
MessageManager
- .getString("label.redundancy_threshold_selection"),
- true, FRAME_WIDTH, FRAME_HEIGHT, false, true);
+ .getString("label.redundancy_threshold_selection"), Desktop.FRAME_MAKE_VISIBLE,
+ FRAME_WIDTH, FRAME_HEIGHT, Desktop.FRAME_NOT_RESIZABLE, Desktop.FRAME_ALLOW_ANY_SIZE);
frame.addInternalFrameListener(new InternalFrameAdapter()
{
@Override
@@ -263,8 +263,7 @@ public class RedundancyPanel extends GSliderPanel implements Runnable
ap.alignFrame.addHistoryItem(cut);
PaintRefresher.Refresh(this, ap.av.getSequenceSetId(), true, true);
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
}
}
@@ -289,8 +288,7 @@ public class RedundancyPanel extends GSliderPanel implements Runnable
{
command.undoCommand(af.getViewAlignments());
ap.av.getHistoryList().remove(command);
- ap.av.firePropertyChange("alignment", null,
- ap.av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
af.updateEditMenuBar();
}
diff --git a/src/jalview/gui/ScalePanel.java b/src/jalview/gui/ScalePanel.java
index a6b4b49..fda1e03 100755
--- a/src/jalview/gui/ScalePanel.java
+++ b/src/jalview/gui/ScalePanel.java
@@ -180,9 +180,7 @@ public class ScalePanel extends JPanel
{
av.showColumn(hiddenRange[0]);
reveal = null;
- ap.updateLayout();
- ap.paintAlignment(true, true);
- av.sendSelection();
+ updatePanel();
}
});
pop.add(item);
@@ -197,9 +195,7 @@ public class ScalePanel extends JPanel
{
av.showAllHiddenColumns();
reveal = null;
- ap.updateLayout();
- ap.paintAlignment(true, true);
- av.sendSelection();
+ updatePanel();
}
});
pop.add(item);
@@ -221,10 +217,7 @@ public class ScalePanel extends JPanel
{
av.setSelectionGroup(null);
}
-
- ap.updateLayout();
- ap.paintAlignment(true, true);
- av.sendSelection();
+ updatePanel();
}
});
pop.add(item);
@@ -232,6 +225,14 @@ public class ScalePanel extends JPanel
return pop;
}
+ protected void updatePanel()
+ {
+ ap.updateLayout();
+ ap.paintAlignment(true, true);
+ ap.updateScrollBarsFromRanges();
+ av.sendSelection();
+ }
+
/**
* Handles left mouse button press
*
diff --git a/src/jalview/gui/SeqCanvas.java b/src/jalview/gui/SeqCanvas.java
index b27208a..f62507a 100755
--- a/src/jalview/gui/SeqCanvas.java
+++ b/src/jalview/gui/SeqCanvas.java
@@ -57,7 +57,8 @@ import javax.swing.JPanel;
public class SeqCanvas extends JPanel implements ViewportListenerI
{
/**
- * vertical gap in pixels between sequences and annotations when in wrapped mode
+ * vertical gap in pixels between sequences and annotations when in wrapped
+ * mode
*/
static final int SEQS_ANNOTATION_GAP = 3;
@@ -75,7 +76,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
private final SequenceRenderer seqRdr;
- boolean fastPaint = false;
+ private boolean fastPaint = false;
private boolean fastpainting = false;
@@ -94,8 +95,12 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
private int wrappedVisibleWidths; // number of wrapped widths displayed
+ private int availWidth;
+
+ private int availHeight;
+
// Don't do this! Graphics handles are supposed to be transient
- //private Graphics2D gg;
+ // private Graphics2D gg;
/**
* Creates a new SeqCanvas object.
@@ -116,7 +121,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
public SequenceRenderer getSequenceRenderer()
{
- return seqRdr;
+ return seqRdr;
}
public FeatureRenderer getFeatureRenderer()
@@ -202,7 +207,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
int yPos = ypos + charHeight;
int startX = startx;
int endX = endx;
-
+
if (av.hasHiddenColumns())
{
HiddenColumns hiddenColumns = av.getAlignment().getHiddenColumns();
@@ -238,7 +243,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
}
}
-
/*
* white fill the space for the scale
*/
@@ -343,7 +347,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
}
}
-
// System.err.println(">>> FastPaint to " + transX + " " + transY + " "
// + horizontal + " " + vertical + " " + startRes + " " + endRes
// + " " + startSeq + " " + endSeq);
@@ -352,9 +355,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
gg.copyArea(horizontal * charWidth, vertical * charHeight,
img.getWidth(), img.getHeight(), -horizontal * charWidth,
-vertical * charHeight);
-
- /** @j2sNative xxi = this.img */
-
gg.translate(transX, transY);
drawPanel(gg, startRes, endRes, startSeq, endSeq, 0);
gg.translate(-transX, -transY);
@@ -374,19 +374,14 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
@Override
public void paintComponent(Graphics g)
{
+ if (av.getAlignPanel().getHoldRepaint())
+ {
+ return;
+ }
- int charHeight = av.getCharHeight();
- int charWidth = av.getCharWidth();
-
- int width = getWidth();
- int height = getHeight();
-
- width -= (width % charWidth);
- height -= (height % charHeight);
-
- // BH 2019 can't possibly fastPaint if either width or height is 0
+ getAvailSizes();
- if (width == 0 || height == 0)
+ if (availWidth == 0 || availHeight == 0)
{
return;
}
@@ -436,10 +431,11 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
// img is a cached version of the last view we drew.
// If we have no img or the size has changed, make a new one.
//
- if (img == null || width != img.getWidth()
- || height != img.getHeight())
+ if (img == null || availWidth != img.getWidth()
+ || availHeight != img.getHeight())
{
- img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ img = new BufferedImage(availWidth, availHeight,
+ BufferedImage.TYPE_INT_RGB);
}
Graphics2D gg = (Graphics2D) img.getGraphics();
@@ -452,11 +448,11 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
}
gg.setColor(Color.white);
- gg.fillRect(0, 0, img.getWidth(), img.getHeight());
+ gg.fillRect(0, 0, availWidth, availHeight);
if (av.getWrapAlignment())
{
- drawWrappedPanel(gg, width, height, ranges.getStartRes());
+ drawWrappedPanel(gg, availWidth, availHeight, ranges.getStartRes());
}
else
{
@@ -474,7 +470,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
drawCursor(g, startRes, endRes, startSeq, endSeq);
}
}
-
+
/**
* Draw an alignment panel for printing
*
@@ -494,8 +490,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
{
drawPanel(g1, startRes, endRes, startSeq, endSeq, 0);
- drawSelectionGroup((Graphics2D) g1, startRes, endRes,
- startSeq, endSeq);
+ drawSelectionGroup((Graphics2D) g1, startRes, endRes, startSeq, endSeq);
}
/**
@@ -519,37 +514,36 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
if (group != null)
{
drawWrappedSelection((Graphics2D) g, group, canvasWidth, canvasHeight,
- startRes);
+ startRes);
}
}
/**
- * Returns the visible width of the canvas in residues, after allowing for
- * East or West scales (if shown)
+ * Using the current font, determine fields labelWidthEast and labelWidthWest,
+ * and return the number of residues that can fill the remaining width
*
- * @param canvasWidth
+ * @param w
* the width in pixels (possibly including scales)
*
- * @return
+ * @return the visible width in residues, after allowing for East or West
+ * scales (if shown)
+ *
*/
- public int getWrappedCanvasWidth(int canvasWidth)
+ public int getWrappedCanvasWidth(int w)
{
int charWidth = av.getCharWidth();
FontMetrics fm = getFontMetrics(av.getFont());
- int labelWidth = 0;
-
- if (av.getScaleRightWrapped() || av.getScaleLeftWrapped())
- {
- labelWidth = getLabelWidth(fm);
- }
+ int labelWidth = (av.getScaleRightWrapped() || av.getScaleLeftWrapped()
+ ? getLabelWidth(fm)
+ : 0);
labelWidthEast = av.getScaleRightWrapped() ? labelWidth : 0;
labelWidthWest = av.getScaleLeftWrapped() ? labelWidth : 0;
- return (canvasWidth - labelWidthEast - labelWidthWest) / charWidth;
+ return (w - labelWidthEast - labelWidthWest) / charWidth;
}
/**
@@ -575,6 +569,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
maxWidth = Math.max(maxWidth, alignment.getSequenceAt(i).getEnd());
}
+ // quick int log10
int length = 0;
for (int i = maxWidth; i > 0; i /= 10)
{
@@ -589,28 +584,25 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
* window
*
* @param g
- * @param canvasWidth
+ * @param availWidth
* available width in pixels
- * @param canvasHeight
+ * @param availHeight
* available height in pixels
* @param startColumn
* the first column (0...) of the alignment to draw
*/
- public void drawWrappedPanel(Graphics g, int canvasWidth,
- int canvasHeight, final int startColumn)
+ public void drawWrappedPanel(Graphics g, int availWidth, int availHeight,
+ final int startColumn)
{
- int wrappedWidthInResidues = calculateWrappedGeometry(canvasWidth,
- canvasHeight);
-
+ int wrappedWidthInResidues = calculateWrappedGeometry();
av.setWrappedWidth(wrappedWidthInResidues);
-
ViewportRanges ranges = av.getRanges();
ranges.setViewportStartAndWidth(startColumn, wrappedWidthInResidues);
// we need to call this again to make sure the startColumn +
// wrappedWidthInResidues values are used to calculate wrappedVisibleWidths
// correctly.
- calculateWrappedGeometry(canvasWidth, canvasHeight);
+ calculateWrappedGeometry();
/*
* draw one width at a time (excluding any scales shown),
@@ -623,9 +615,9 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
int currentWidth = 0;
while ((currentWidth < wrappedVisibleWidths) && (start < maxWidth))
{
- int endColumn = Math
- .min(maxWidth, start + wrappedWidthInResidues - 1);
- drawWrappedWidth(g, ypos, start, endColumn, canvasHeight);
+ int endColumn = Math.min(maxWidth,
+ start + wrappedWidthInResidues - 1);
+ drawWrappedWidth(g, ypos, start, endColumn, availHeight);
ypos += wrappedRepeatHeightPx;
start += wrappedWidthInResidues;
currentWidth++;
@@ -634,6 +626,16 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
drawWrappedDecorators(g, startColumn);
}
+ private void getAvailSizes()
+ {
+ int charHeight = av.getCharHeight();
+ int charWidth = av.getCharWidth();
+ availWidth = getWidth();
+ availHeight = getHeight();
+ availWidth -= (availWidth % charWidth);
+ availHeight -= (availHeight % charHeight);
+ }
+
/**
* Calculates and saves values needed when rendering a wrapped alignment.
* These depend on many factors, including
@@ -644,12 +646,26 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
*
whether scales are shown left, right or above the alignment
*
*
+ * @param availWidth
+ * @param availHeight
+ * @return the number of residue columns in each width
+ */
+ protected int calculateWrappedGeometry()
+ {
+ getAvailSizes();
+ return calculateWrappedGeometry(availWidth, availHeight);
+
+ }
+
+ /**
+ * for test only
* @param canvasWidth
* @param canvasHeight
- * @return the number of residue columns in each width
+ * @return
*/
- protected int calculateWrappedGeometry(int canvasWidth, int canvasHeight)
+ public int calculateWrappedGeometry(int canvasWidth, int canvasHeight)
{
+
int charHeight = av.getCharHeight();
/*
@@ -663,9 +679,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
* compute height in pixels of the wrapped widths
* - start with space above plus sequences
*/
- wrappedRepeatHeightPx = wrappedSpaceAboveAlignment;
- wrappedRepeatHeightPx += av.getAlignment().getHeight()
- * charHeight;
+ wrappedRepeatHeightPx = wrappedSpaceAboveAlignment
+ + av.getAlignment().getHeight() * charHeight;
/*
* add annotations panel height if shown
@@ -736,7 +751,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
int charWidth = av.getCharWidth();
int xOffset = labelWidthWest
+ ((startColumn - ranges.getStartRes()) % viewportWidth)
- * charWidth;
+ * charWidth;
g.translate(xOffset, 0);
@@ -803,7 +818,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
if (av.getScaleRightWrapped())
{
int x = labelWidthWest + viewportWidth * charWidth;
-
+
g.translate(x, 0);
drawVerticalScale(g, startCol, endColumn, ypos, false);
g.translate(-x, 0);
@@ -815,8 +830,9 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
*/
g.translate(labelWidthWest, 0);
g.setColor(Color.white);
- g.fillRect(0, ypos - wrappedSpaceAboveAlignment, viewportWidth
- * charWidth + labelWidthWest, wrappedSpaceAboveAlignment);
+ g.fillRect(0, ypos - wrappedSpaceAboveAlignment,
+ viewportWidth * charWidth + labelWidthWest,
+ wrappedSpaceAboveAlignment);
g.setColor(Color.black);
g.translate(-labelWidthWest, 0);
@@ -883,18 +899,21 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
}
}
+ private final static BasicStroke dottedStroke = new BasicStroke(1,
+ BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 3f, new float[]
+ { 5f, 3f }, 0f);
+
+ private final static BasicStroke basicStroke = new BasicStroke();
+
/*
* Draw a selection group over a wrapped alignment
*/
private void drawWrappedSelection(Graphics2D g, SequenceGroup group,
- int canvasWidth,
- int canvasHeight, int startRes)
+ int canvasWidth, int canvasHeight, int startRes)
{
// chop the wrapped alignment extent up into panel-sized blocks and treat
// each block as if it were a block from an unwrapped alignment
- g.setStroke(new BasicStroke(1, BasicStroke.CAP_BUTT,
- BasicStroke.JOIN_ROUND, 3f, new float[]
- { 5f, 3f }, 0f));
+ g.setStroke(dottedStroke);
g.setColor(Color.RED);
int charWidth = av.getCharWidth();
@@ -902,6 +921,21 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
/ charWidth;
int startx = startRes;
int maxwidth = av.getAlignment().getVisibleWidth();
+
+ // JAL-3253-applet had this:
+ // // height gap above each panel
+ // int charHeight = av.getCharHeight();
+ // int hgap = charHeight;
+ // if (av.getScaleAboveWrapped())
+ // {
+ // hgap += charHeight;
+ // }
+ // int dy = getAnnotationHeight() + hgap
+ // + av.getAlignment().getHeight() * charHeight;
+ // int ypos = hgap; // vertical offset
+
+ // this is from 0b573ed (gmungoc)
+ int dy = wrappedRepeatHeightPx;
int ypos = wrappedSpaceAboveAlignment;
while ((ypos <= canvasHeight) && (startx < maxwidth))
@@ -915,21 +949,24 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
}
g.translate(labelWidthWest, 0);
+
drawUnwrappedSelection(g, group, startx, endx, 0,
- av.getAlignment().getHeight() - 1,
- ypos);
+ av.getAlignment().getHeight() - 1, ypos);
+
g.translate(-labelWidthWest, 0);
- ypos += wrappedRepeatHeightPx;
+ // update vertical offset
+ ypos += dy;
+ // update horizontal offset
startx += cWidth;
}
- g.setStroke(new BasicStroke());
+ g.setStroke(basicStroke);
}
/**
- * Answers zero if annotations are not shown, otherwise recalculates and answers
- * the total height of all annotation rows in pixels
+ * Answers zero if annotations are not shown, otherwise recalculates and
+ * answers the total height of all annotation rows in pixels
*
* @return
*/
@@ -1190,8 +1227,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
* the cursor drawn on it, if any
*/
private void drawCursor(Graphics g, int startRes, int endRes,
- int startSeq,
- int endSeq)
+ int startSeq, int endSeq)
{
// convert the cursorY into a position on the visible alignment
int cursor_ypos = cursorY;
@@ -1262,7 +1298,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
}
}
-
/**
* Draw a selection group over an unwrapped alignment
*
@@ -1285,7 +1320,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
int startRes, int endRes, int startSeq, int endSeq, int offset)
{
int charWidth = av.getCharWidth();
-
+
if (!av.hasHiddenColumns())
{
drawPartialGroupOutline(g, group, startRes, endRes, startSeq, endSeq,
@@ -1308,8 +1343,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
blockStart = region[0];
g.translate(screenY * charWidth, 0);
- drawPartialGroupOutline(g, group,
- blockStart, blockEnd, startSeq, endSeq, offset);
+ drawPartialGroupOutline(g, group, blockStart, blockEnd, startSeq,
+ endSeq, offset);
g.translate(-screenY * charWidth, 0);
screenY += blockEnd - blockStart + 1;
@@ -1478,7 +1513,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
g.drawLine(sx + xwidth, oldY, sx + xwidth, sy);
}
}
-
+
/**
* Highlights search results in the visible region by rendering as white text
* on a black background. Any previous highlighting is removed. Answers true
@@ -1494,7 +1529,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
return highlightSearchResults(results, false);
}
-
+
/**
* Highlights search results in the visible region by rendering as white text
* on a black background. Any previous highlighting is removed. Answers true
@@ -1652,7 +1687,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
{
firstCol = alignment.getHiddenColumns()
.absoluteToVisibleColumn(firstCol);
- lastCol = alignment.getHiddenColumns().absoluteToVisibleColumn(lastCol);
+ lastCol = alignment.getHiddenColumns()
+ .absoluteToVisibleColumn(lastCol);
}
int transX = (firstCol - ranges.getStartRes()) * av.getCharWidth();
int transY = (firstSeq - ranges.getStartSeq()) * av.getCharHeight();
@@ -1670,92 +1706,161 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
public void propertyChange(PropertyChangeEvent evt)
{
String eventName = evt.getPropertyName();
- // System.err.println(">>SeqCanvas propertyChange " + eventName);
- if (eventName.equals(SequenceGroup.SEQ_GROUP_CHANGED))
- {
- fastPaint = true;
- repaint();
- return;
- }
- else if (eventName.equals(ViewportRanges.MOVE_VIEWPORT))
- {
- fastPaint = false;
- // System.err.println("!!!! fastPaint false from MOVE_VIEWPORT");
- repaint();
- return;
- }
- int scrollX = 0;
- if (eventName.equals(ViewportRanges.STARTRES)
- || eventName.equals(ViewportRanges.STARTRESANDSEQ))
- {
- // Make sure we're not trying to draw a panel
- // larger than the visible window
- if (eventName.equals(ViewportRanges.STARTRES))
- {
- scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
- }
- else
- {
- scrollX = ((int[]) evt.getNewValue())[0]
- - ((int[]) evt.getOldValue())[0];
- }
- ViewportRanges vpRanges = av.getRanges();
+ // BH 2019.07.27 removes dead code introduced in aad3650 and simplifies
+ // logic, emphasizing no check for ENDRES or ENDSEQ
- int range = vpRanges.getEndRes() - vpRanges.getStartRes() + 1;
- if (scrollX > range)
- {
- scrollX = range;
- }
- else if (scrollX < -range)
- {
- scrollX = -range;
- }
- }
// Both scrolling and resizing change viewport ranges: scrolling changes
// both start and end points, but resize only changes end values.
// Here we only want to fastpaint on a scroll, with resize using a normal
// paint, so scroll events are identified as changes to the horizontal or
// vertical start value.
- if (eventName.equals(ViewportRanges.STARTRES))
- {
- if (av.getWrapAlignment())
- {
- fastPaintWrapped(scrollX);
- }
- else
- {
- fastPaint(scrollX, 0);
- }
- }
- else if (eventName.equals(ViewportRanges.STARTSEQ))
+
+ // Make sure we're not trying to draw a panel
+ // larger than the visible window
+ int scrollX = 0;
+ int scrollY = 0;
+ switch (eventName)
{
- // scroll
+ case SequenceGroup.SEQ_GROUP_CHANGED:
+ fastPaint = true;
+ repaint();
+ return;
+ case ViewportRanges.MOVE_VIEWPORT:
+ fastPaint = false;
+ repaint();
+ return;
+ case ViewportRanges.STARTSEQ:
+ // meaning STARTOREND
+ // typically scroll, but possibly just the end changed
fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
- }
- else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
- {
- if (av.getWrapAlignment())
- {
- fastPaintWrapped(scrollX);
- }
- else
+ return;
+ case ViewportRanges.STARTRES:
+ // meaning STARTOREND
+ scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+ break;
+ case ViewportRanges.STARTRESANDSEQ:
+ scrollX = ((int[]) evt.getNewValue())[0]
+ - ((int[]) evt.getOldValue())[0];
+ scrollY = ((int[]) evt.getNewValue())[1]
+ - ((int[]) evt.getOldValue())[1];
+
+ // System.out.println("SC dx dy " + scrollX + " " + scrollY);
+
+ if (scrollX != 0 && scrollY != 0)
{
- fastPaint(scrollX, 0);
+ // all sorts of problems in JavaScript if this is commented out.
+ repaint();
+ return;
+
}
+ break;
+ default:
+ return;
}
- else if (eventName.equals(ViewportRanges.STARTSEQ))
+
+ ViewportRanges vpRanges = av.getRanges();
+ int range = vpRanges.getEndRes() - vpRanges.getStartRes() + 1;
+ scrollX = Math.max(Math.min(scrollX, range), -range);
+ // only STARTRES or STARTRESANDSEQ:
+ if (av.getWrapAlignment())
{
- // scroll
- fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ fastPaintWrapped(scrollX);
}
- else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
+ else
{
- if (av.getWrapAlignment())
- {
- fastPaintWrapped(scrollX);
- }
+ fastPaint(scrollX, scrollY);
}
+
+ // BH 2019.07.27 was:
+ // if (eventName.equals(SequenceGroup.SEQ_GROUP_CHANGED))
+ // {
+ // fastPaint = true;
+ // repaint();
+ // return;
+ // }
+ // else if (eventName.equals(ViewportRanges.MOVE_VIEWPORT))
+ // {
+ // fastPaint = false;
+ // // System.err.println("!!!! fastPaint false from MOVE_VIEWPORT");
+ // repaint();
+ // return;
+ // }
+ //
+ // if (eventName.equals(ViewportRanges.STARTRES)
+ // || eventName.equals(ViewportRanges.STARTRESANDSEQ))
+ // {
+ // // Make sure we're not trying to draw a panel
+ // // larger than the visible window
+ // if (eventName.equals(ViewportRanges.STARTRES))
+ // {
+ // scrollX = (int) evt.getNewValue() - (int) evt.getOldValue();
+ // }
+ // else
+ // {
+ // scrollX = ((int[]) evt.getNewValue())[0]
+ // - ((int[]) evt.getOldValue())[0];
+ // }
+ // ViewportRanges vpRanges = av.getRanges();
+ //
+ // int range = vpRanges.getEndRes() - vpRanges.getStartRes() + 1;
+ // if (scrollX > range)
+ // {
+ // scrollX = range;
+ // }
+ // else if (scrollX < -range)
+ // {
+ // scrollX = -range;
+ // }
+ // }
+ // Both scrolling and resizing change viewport ranges: scrolling changes
+ // both start and end points, but resize only changes end values.
+ // Here we only want to fastpaint on a scroll, with resize using a normal
+ // paint, so scroll events are identified as changes to the horizontal or
+ // vertical start value.
+ // BH 2019.07.27 was:
+ // if (eventName.equals(ViewportRanges.STARTRES))
+ // {
+ // if (av.getWrapAlignment())
+ // {
+ // fastPaintWrapped(scrollX);
+ // }
+ // else
+ // {
+ // fastPaint(scrollX, 0);
+ // }
+ // }
+ // else if (eventName.equals(ViewportRanges.STARTSEQ))
+ // {
+ // // scroll
+ // fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ // }
+ // else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
+ // {
+ // if (av.getWrapAlignment())
+ // {
+ // fastPaintWrapped(scrollX);
+ // }
+ // else
+ // {
+ // fastPaint(scrollX, 0);
+ // }
+ // }
+ //
+ // BH oops!
+ //
+ // else if (eventName.equals(ViewportRanges.STARTSEQ))
+ // {
+ // // scroll
+ // fastPaint(0, (int) evt.getNewValue() - (int) evt.getOldValue());
+ // }
+ // else if (eventName.equals(ViewportRanges.STARTRESANDSEQ))
+ // {
+ // if (av.getWrapAlignment())
+ // {
+ // fastPaintWrapped(scrollX);
+ // }
+ // }
}
/**
@@ -1792,10 +1897,10 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
try
{
-
+
Graphics gg = img.getGraphics();
-
- calculateWrappedGeometry(getWidth(), getHeight());
+
+ calculateWrappedGeometry();
/*
* relocate the regions of the alignment that are still visible
@@ -1810,8 +1915,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
if (scrollX < 0)
{
int startRes = ranges.getStartRes();
- drawWrappedWidth(gg, wrappedSpaceAboveAlignment, startRes, startRes
- - scrollX - 1, getHeight());
+ drawWrappedWidth(gg, wrappedSpaceAboveAlignment, startRes,
+ startRes - scrollX - 1, getHeight());
}
else
{
@@ -1824,7 +1929,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
drawWrappedDecorators(gg, ranges.getStartRes());
gg.dispose();
-
+
repaint();
} finally
{
@@ -1849,7 +1954,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
}
Graphics gg = img.getGraphics();
-
+
ViewportRanges ranges = av.getRanges();
int viewportWidth = ranges.getViewportWidth();
int charWidth = av.getCharWidth();
@@ -1860,7 +1965,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
*/
int visibleWidths = wrappedVisibleWidths;
int canvasHeight = getHeight();
- boolean lastWidthPartHeight = (wrappedVisibleWidths * wrappedRepeatHeightPx) > canvasHeight;
+ boolean lastWidthPartHeight = (wrappedVisibleWidths
+ * wrappedRepeatHeightPx) > canvasHeight;
if (lastWidthPartHeight)
{
@@ -1876,16 +1982,15 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
/*
* white fill first to erase annotations
*/
-
-
+
gg.translate(xOffset, 0);
gg.setColor(Color.white);
- gg.fillRect(labelWidthWest, ypos,
- (endRes - startRes + 1) * charWidth, wrappedRepeatHeightPx);
+ gg.fillRect(labelWidthWest, ypos, (endRes - startRes + 1) * charWidth,
+ wrappedRepeatHeightPx);
gg.translate(-xOffset, 0);
drawWrappedWidth(gg, ypos, startRes, endRes, canvasHeight);
-
+
}
/*
@@ -1930,7 +2035,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
gg.fillRect(0, canvasHeight - heightBelow, getWidth(), heightBelow);
}
gg.dispose();
- }
+ }
/**
* Shifts the visible alignment by the specified number of columns - left if
@@ -2018,8 +2123,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
if (y + wrappedRepeatHeightPx < canvasHeight - wrappedRepeatHeightPx
&& (xpos + viewportWidth <= xMax))
{
- gg.copyArea(labelWidthWest, y + wrappedRepeatHeightPx, -positions
- * charWidth, heightToCopy, widthToCopy,
+ gg.copyArea(labelWidthWest, y + wrappedRepeatHeightPx,
+ -positions * charWidth, heightToCopy, widthToCopy,
-wrappedRepeatHeightPx);
}
y += wrappedRepeatHeightPx;
@@ -2029,7 +2134,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
gg.dispose();
}
-
/**
* Redraws any positions in the search results in the visible region of a
* wrapped alignment. Any highlights are drawn depending on the search results
@@ -2050,7 +2154,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
boolean matchFound = false;
- calculateWrappedGeometry(getWidth(), getHeight());
+ calculateWrappedGeometry();
int wrappedWidth = av.getWrappedWidth();
int wrappedHeight = wrappedRepeatHeightPx;
@@ -2063,8 +2167,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
}
int firstVisibleColumn = ranges.getStartRes();
- int lastVisibleColumn = ranges.getStartRes() + repeats
- * ranges.getViewportWidth() - 1;
+ int lastVisibleColumn = ranges.getStartRes()
+ + repeats * ranges.getViewportWidth() - 1;
AlignmentI alignment = av.getAlignment();
if (av.hasHiddenColumns())
@@ -2077,7 +2181,6 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
int gapHeight = charHeight * (av.getScaleAboveWrapped() ? 2 : 1);
-
Graphics gg = img.getGraphics();
for (int seqNo = ranges.getStartSeq(); seqNo <= ranges
@@ -2121,8 +2224,8 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
* transX: offset from left edge of canvas to residue position
*/
int transX = labelWidthWest
- + ((displayColumn - ranges.getStartRes()) % wrappedWidth)
- * av.getCharWidth();
+ + ((displayColumn - ranges.getStartRes())
+ % wrappedWidth) * av.getCharWidth();
/*
* transY: offset from top edge of canvas to residue position
@@ -2149,7 +2252,7 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
}
}
}
-
+
gg.dispose();
return matchFound;
@@ -2165,4 +2268,13 @@ public class SeqCanvas extends JPanel implements ViewportListenerI
return labelWidthWest;
}
+ /**
+ * Clears the flag that allows a 'fast paint' on the next repaint, so
+ * requiring a full repaint
+ */
+ public void setNoFastPaint()
+ {
+ fastPaint = false;
+ }
+
}
diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java
index b2149df..3de631f 100644
--- a/src/jalview/gui/SeqPanel.java
+++ b/src/jalview/gui/SeqPanel.java
@@ -291,8 +291,7 @@ public class SeqPanel extends JPanel
int alignmentHeight = av.getAlignment().getHeight();
if (av.getWrapAlignment())
{
- seqCanvas.calculateWrappedGeometry(seqCanvas.getWidth(),
- seqCanvas.getHeight());
+ seqCanvas.calculateWrappedGeometry();
/*
* yPos modulo height of repeating width
@@ -424,8 +423,7 @@ public class SeqPanel extends JPanel
if (editCommand != null && editCommand.getSize() > 0)
{
ap.alignFrame.addHistoryItem(editCommand);
- av.firePropertyChange("alignment", null,
- av.getAlignment().getSequences());
+ ap.av.notifyAlignment();
}
} finally
{
diff --git a/src/jalview/gui/SequenceFetcher.java b/src/jalview/gui/SequenceFetcher.java
index 8b5d3b7..3d09f99 100755
--- a/src/jalview/gui/SequenceFetcher.java
+++ b/src/jalview/gui/SequenceFetcher.java
@@ -145,8 +145,8 @@ public class SequenceFetcher extends JPanel implements Runnable
frame = new JInternalFrame();
frame.setContentPane(this);
- Desktop.addInternalFrame(frame, getFrameTitle(), true, 400,
- Platform.isAMacAndNotJS() ? 240 : 180);
+ Desktop.addInternalFrame(frame, getFrameTitle(), Desktop.FRAME_MAKE_VISIBLE, 400,
+ Platform.isAMacAndNotJS() ? 240 : 180, Desktop.FRAME_ALLOW_RESIZE, Desktop.FRAME_SET_MIN_SIZE_300);
}
private String getFrameTitle()
@@ -868,7 +868,7 @@ public class SequenceFetcher extends JPanel implements Runnable
@Override
public void run()
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop, error,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(), error,
MessageManager.getString("label.error_retrieving_data"),
JvOptionPane.WARNING_MESSAGE);
}
diff --git a/src/jalview/gui/SliderPanel.java b/src/jalview/gui/SliderPanel.java
index 46b47a2..7effb0f 100755
--- a/src/jalview/gui/SliderPanel.java
+++ b/src/jalview/gui/SliderPanel.java
@@ -231,8 +231,8 @@ public class SliderPanel extends GSliderPanel
if (!conservationSlider.isVisible())
{
Desktop.addInternalFrame(conservationSlider,
- conservationSlider.getTitle(), true, FRAME_WIDTH,
- FRAME_HEIGHT, false, true);
+ conservationSlider.getTitle(), Desktop.FRAME_MAKE_VISIBLE, FRAME_WIDTH,
+ FRAME_HEIGHT, Desktop.FRAME_NOT_RESIZABLE, Desktop.FRAME_ALLOW_ANY_SIZE);
conservationSlider.addInternalFrameListener(new InternalFrameAdapter()
{
@Override
@@ -307,8 +307,8 @@ public class SliderPanel extends GSliderPanel
if (!PIDSlider.isVisible())
{
- Desktop.addInternalFrame(PIDSlider, PIDSlider.getTitle(), true,
- FRAME_WIDTH, FRAME_HEIGHT, false, true);
+ Desktop.addInternalFrame(PIDSlider, PIDSlider.getTitle(), Desktop.FRAME_MAKE_VISIBLE,
+ FRAME_WIDTH, FRAME_HEIGHT, Desktop.FRAME_NOT_RESIZABLE, Desktop.FRAME_ALLOW_ANY_SIZE);
PIDSlider.setLayer(JLayeredPane.PALETTE_LAYER);
PIDSlider.addInternalFrameListener(new InternalFrameAdapter()
{
diff --git a/src/jalview/gui/SplashScreen.java b/src/jalview/gui/SplashScreen.java
index f4b275d..0edede4 100755
--- a/src/jalview/gui/SplashScreen.java
+++ b/src/jalview/gui/SplashScreen.java
@@ -160,7 +160,7 @@ public class SplashScreen extends JPanel
System.err.println("Error when loading images!");
}
} while (!mt.checkAll());
- Desktop.instance.setIconImage(logo);
+ Desktop.getInstance().setIconImage(logo);
}
} catch (Exception ex)
{
@@ -191,7 +191,7 @@ public class SplashScreen extends JPanel
}
add(splashText, BorderLayout.CENTER);
splashText.addMouseListener(closer);
- Desktop.desktop.add(iframe);
+ Desktop.getDesktopPane().add(iframe);
refreshText();
}
@@ -200,7 +200,7 @@ public class SplashScreen extends JPanel
*/
protected boolean refreshText()
{
- String newtext = Desktop.instance.getAboutMessage();
+ String newtext = Desktop.getInstance().getAboutMessage();
// System.err.println("Text found: \n"+newtext+"\nEnd of newtext.");
if (oldTextLength != newtext.length())
{
@@ -239,8 +239,8 @@ public class SplashScreen extends JPanel
splashText.setSize(new Dimension(750, 375));
add(splashText, BorderLayout.CENTER);
revalidate();
- iframe.setBounds((Desktop.instance.getWidth() - 750) / 2,
- (Desktop.instance.getHeight() - 375) / 2, 750,
+ iframe.setBounds((Desktop.getInstance().getWidth() - 750) / 2,
+ (Desktop.getInstance().getHeight() - 375) / 2, 750,
splashText.getHeight() + iconimg.getHeight());
iframe.validate();
iframe.setVisible(true);
@@ -286,7 +286,7 @@ public class SplashScreen extends JPanel
}
closeSplash();
- Desktop.instance.startDialogQueue();
+ Desktop.getInstance().startDialogQueue();
}
/**
diff --git a/src/jalview/gui/SplitFrame.java b/src/jalview/gui/SplitFrame.java
index f57279e..953755f 100644
--- a/src/jalview/gui/SplitFrame.java
+++ b/src/jalview/gui/SplitFrame.java
@@ -152,7 +152,7 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
// allow about 65 pixels for Desktop decorators on Windows
int newHeight = Math.min(height,
- Desktop.instance.getHeight() - DESKTOP_DECORATORS_HEIGHT);
+ Desktop.getInstance().getHeight() - DESKTOP_DECORATORS_HEIGHT);
if (newHeight != height)
{
int oldDividerLocation = getDividerLocation();
@@ -170,7 +170,7 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
// TODO if CommandListener is only ever 1:1 for complementary views,
// may change broadcast pattern to direct messaging (more efficient)
final StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
ssm.addCommandListener(((AlignFrame) getTopFrame()).getViewport());
ssm.addCommandListener(((AlignFrame) getBottomFrame()).getViewport());
}
@@ -571,7 +571,7 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
adjustLayout();
final StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
ssm.addCommandListener(newTopPanel.av);
ssm.addCommandListener(newBottomPanel.av);
}
@@ -698,7 +698,7 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
*/
protected void expandViews_actionPerformed()
{
- Desktop.instance.explodeViews(this);
+ Desktop.getInstance().explodeViews(this);
}
/**
@@ -707,7 +707,7 @@ public class SplitFrame extends GSplitFrame implements SplitContainerI
*/
protected void gatherViews_actionPerformed()
{
- Desktop.instance.gatherViews(this);
+ Desktop.getInstance().gatherViews(this);
}
/**
diff --git a/src/jalview/gui/StructureChooser.java b/src/jalview/gui/StructureChooser.java
index 4a8a7d8..c30d8c7 100644
--- a/src/jalview/gui/StructureChooser.java
+++ b/src/jalview/gui/StructureChooser.java
@@ -145,7 +145,7 @@ public class StructureChooser extends GStructureChooser
*/
private void discoverStructureViews()
{
- if (Desktop.instance != null)
+ if (Desktop.getInstance() != null)
{
targetView.removeAllItems();
if (lastTargetedView != null && !lastTargetedView.isVisible())
@@ -153,7 +153,7 @@ public class StructureChooser extends GStructureChooser
lastTargetedView = null;
}
int linkedViewsAt = 0;
- for (StructureViewerBase view : Desktop.instance
+ for (StructureViewerBase view : Desktop.getInstance()
.getStructureViewers(null, null))
{
StructureViewer viewHandler = (lastTargetedView != null
@@ -886,11 +886,9 @@ public class StructureChooser extends GStructureChooser
public void showStructures(boolean waitUntilFinished)
{
- final StructureSelectionManager ssm = ap.getStructureSelectionManager();
-
final int preferredHeight = pnl_filter.getHeight();
- final StructureViewer theViewer = getTargetedStructureViewer(ssm);
+ final StructureViewer theViewer = getTargetedStructureViewer();
boolean superimpose = chk_superpose.isSelected();
Runnable viewStruc = new Runnable()
@@ -929,9 +927,7 @@ public class StructureChooser extends GStructureChooser
if (pdbEntry == null)
{
- pdbEntry = new PDBEntry();
- pdbEntry.setId(pdbIdStr);
- pdbEntry.setType(PDBEntry.Type.PDB);
+ pdbEntry = new PDBEntry(pdbIdStr, null, "pdb");
selectedSeq.getDatasetSequence().addPDBId(pdbEntry);
}
pdbEntriesToView[count++] = pdbEntry;
@@ -1005,10 +1001,8 @@ public class StructureChooser extends GStructureChooser
{
selectedSequence = userSelectedSeq;
}
- PDBEntry fileEntry = new AssociatePdbFileWithSeq()
- .associatePdbWithSeq(selectedPdbFileName,
- DataSourceType.FILE, selectedSequence, true,
- Desktop.instance);
+ PDBEntry fileEntry = AssociatePdbFileWithSeq.associatePdbWithSeq(selectedPdbFileName,
+ DataSourceType.FILE, selectedSequence, true);
sViewer = StructureViewer.launchStructureViewer(ap, new PDBEntry[] { fileEntry },
new SequenceI[]
{ selectedSequence }, superimpose, theViewer,
@@ -1066,11 +1060,9 @@ public class StructureChooser extends GStructureChooser
* @param ssm
* @return
*/
- StructureViewer getTargetedStructureViewer(StructureSelectionManager ssm)
+ StructureViewer getTargetedStructureViewer()
{
- Object sv = targetView.getSelectedItem();
-
- return sv == null ? new StructureViewer(ssm) : (StructureViewer) sv;
+ return (StructureViewer) targetView.getSelectedItem();
}
/**
diff --git a/src/jalview/gui/StructureViewer.java b/src/jalview/gui/StructureViewer.java
index e0c33e5..e7a30f9 100644
--- a/src/jalview/gui/StructureViewer.java
+++ b/src/jalview/gui/StructureViewer.java
@@ -433,6 +433,8 @@ public class StructureViewer
StructureViewer theViewer, IProgressIndicator pb)
{
final StructureSelectionManager ssm = ap.getStructureSelectionManager();
+ if (theViewer == null)
+ theViewer = new StructureViewer(ssm);
long progressId = sequences.hashCode();
if (pb != null)
pb.setProgressBar(MessageManager.getString(
diff --git a/src/jalview/gui/StructureViewerBase.java b/src/jalview/gui/StructureViewerBase.java
index 418a84d..af48093 100644
--- a/src/jalview/gui/StructureViewerBase.java
+++ b/src/jalview/gui/StructureViewerBase.java
@@ -407,7 +407,7 @@ public abstract class StructureViewerBase extends GStructureViewer
*/
protected List
getViewersFor(AlignmentPanel alp)
{
- return Desktop.instance.getStructureViewers(alp, this.getClass());
+ return Desktop.getInstance().getStructureViewers(alp, this.getClass());
}
@Override
diff --git a/src/jalview/gui/TreeCanvas.java b/src/jalview/gui/TreeCanvas.java
index 29ba52b..e59dfcc 100755
--- a/src/jalview/gui/TreeCanvas.java
+++ b/src/jalview/gui/TreeCanvas.java
@@ -761,7 +761,9 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
*/
if (e.isPopupTrigger())
{
- chooseSubtreeColour();
+ if (highlightNode != null) {
+ chooseSubtreeColour();
+ }
e.consume(); // prevent mouseClicked happening
}
}
diff --git a/src/jalview/gui/TreePanel.java b/src/jalview/gui/TreePanel.java
index 37b4dac..d242892 100755
--- a/src/jalview/gui/TreePanel.java
+++ b/src/jalview/gui/TreePanel.java
@@ -174,11 +174,12 @@ public class TreePanel extends GTreePanel
{
final PropertyChangeListener listener = new PropertyChangeListener()
{
+ @SuppressWarnings("unchecked")
@Override
public void propertyChange(PropertyChangeEvent evt)
{
- if (evt.getPropertyName().equals("alignment"))
- {
+ switch (evt.getPropertyName()) {
+ case AlignmentViewport.PROPERTY_ALIGNMENT:
if (tree == null)
{
System.out.println("tree is null");
@@ -191,12 +192,14 @@ public class TreePanel extends GTreePanel
{
System.out.println(
"new alignment sequences vector value is null");
+ return;
}
tree.updatePlaceHolders((List) evt.getNewValue());
treeCanvas.nameHash.clear(); // reset the mapping between canvas
// rectangles and leafnodes
repaint();
+ break;
}
}
};
diff --git a/src/jalview/gui/UserDefinedColours.java b/src/jalview/gui/UserDefinedColours.java
index 4846049..1139ae0 100755
--- a/src/jalview/gui/UserDefinedColours.java
+++ b/src/jalview/gui/UserDefinedColours.java
@@ -149,8 +149,8 @@ public class UserDefinedColours extends GUserDefinedColours
frame = new JInternalFrame();
frame.setContentPane(this);
Desktop.addInternalFrame(frame,
- MessageManager.getString("label.user_defined_colours"),
- MY_FRAME_WIDTH, MY_FRAME_HEIGHT, true);
+ MessageManager.getString("label.user_defined_colours"), Desktop.FRAME_MAKE_VISIBLE,
+ MY_FRAME_WIDTH, MY_FRAME_HEIGHT, Desktop.FRAME_ALLOW_RESIZE, Desktop.FRAME_SET_MIN_SIZE_300);
}
/**
@@ -448,7 +448,7 @@ public class UserDefinedColours extends GUserDefinedColours
{
if (isNoSelectionMade())
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager
.getString("label.no_colour_selection_in_scheme"),
MessageManager.getString("label.no_colour_selection_warn"),
@@ -503,7 +503,7 @@ public class UserDefinedColours extends GUserDefinedColours
String[] options = new String[] { title,
MessageManager.getString("label.dont_save_changes"), };
final String question = JvSwingUtils.wrapTooltip(true, message);
- int response = JvOptionPane.showOptionDialog(Desktop.desktop,
+ int response = JvOptionPane.showOptionDialog(Desktop.getDesktopPane(),
question, title, JvOptionPane.DEFAULT_OPTION,
JvOptionPane.PLAIN_MESSAGE, null, options, options[0]);
@@ -557,7 +557,7 @@ public class UserDefinedColours extends GUserDefinedColours
{
if (isNoSelectionMade())
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager
.getString("label.no_colour_selection_in_scheme"),
MessageManager.getString("label.no_colour_selection_warn"),
@@ -741,7 +741,7 @@ public class UserDefinedColours extends GUserDefinedColours
String name = schemeName.getText().trim();
if (name.length() < 1)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager
.getString("label.user_colour_scheme_must_have_name"),
MessageManager.getString("label.no_name_colour_scheme"),
@@ -756,7 +756,7 @@ public class UserDefinedColours extends GUserDefinedColours
* @j2sIgnore
*/
{
- int reply = JvOptionPane.showInternalConfirmDialog(Desktop.desktop,
+ int reply = JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.colour_scheme_exists_overwrite", new Object[]
{ name, name }),
diff --git a/src/jalview/gui/UserQuestionnaireCheck.java b/src/jalview/gui/UserQuestionnaireCheck.java
index ef86756..e12586a 100644
--- a/src/jalview/gui/UserQuestionnaireCheck.java
+++ b/src/jalview/gui/UserQuestionnaireCheck.java
@@ -141,7 +141,7 @@ public class UserQuestionnaireCheck implements Runnable
+ qid + "&rid=" + rid;
jalview.bin.Cache.log
.info("Prompting user for questionnaire at " + qurl);
- int reply = JvOptionPane.showInternalConfirmDialog(Desktop.desktop,
+ int reply = JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(),
MessageManager.getString("label.jalview_new_questionnaire"),
MessageManager.getString("label.jalview_user_survey"),
JvOptionPane.YES_NO_OPTION, JvOptionPane.QUESTION_MESSAGE);
diff --git a/src/jalview/gui/VamsasApplication.java b/src/jalview/gui/VamsasApplication.java
index 0848a4d..2ee3e06 100644
--- a/src/jalview/gui/VamsasApplication.java
+++ b/src/jalview/gui/VamsasApplication.java
@@ -173,7 +173,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
}
} catch (InvalidSessionDocumentException e)
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString(
"label.vamsas_doc_couldnt_be_opened_as_new_session"),
@@ -455,7 +455,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
VamsasAppDatastore vds = new VamsasAppDatastore(doc, vobj2jv, jv2vobj,
baseProvEntry(), alRedoState);
// wander through frames
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames();
if (frames == null)
{
@@ -660,7 +660,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
Cache.log.debug(
"Asking user if the vamsas session should be stored.");
int reply = JvOptionPane.showInternalConfirmDialog(
- Desktop.desktop,
+ Desktop.getDesktopPane(),
"The current VAMSAS session has unsaved data - do you want to save it ?",
"VAMSAS Session Shutdown",
JvOptionPane.YES_NO_OPTION,
@@ -669,7 +669,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
if (reply == JvOptionPane.YES_OPTION)
{
Cache.log.debug("Prompting for vamsas store filename.");
- Desktop.instance.vamsasSave_actionPerformed(null);
+ Desktop.getInstance().vamsasSave_actionPerformed(null);
Cache.log
.debug("Finished attempt at storing document.");
}
@@ -689,7 +689,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
public void disableGui(boolean b)
{
// JAL-3311 TODO: remove this class!
- // Desktop.instance.setVamsasUpdate(b);
+ // Desktop.getInstance().setVamsasUpdate(b);
}
Hashtable _backup_vobj2jv;
@@ -764,7 +764,7 @@ public class VamsasApplication implements SelectionSource, VamsasSource
{
final IPickManager pm = vclient.getPickManager();
final StructureSelectionManager ssm = StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance);
+ .getStructureSelectionManager(Desktop.getInstance());
final VamsasApplication me = this;
pm.registerMessageHandler(new IMessageHandler()
{
diff --git a/src/jalview/gui/WebserviceInfo.java b/src/jalview/gui/WebserviceInfo.java
index 25ade21..ab9444e 100644
--- a/src/jalview/gui/WebserviceInfo.java
+++ b/src/jalview/gui/WebserviceInfo.java
@@ -259,6 +259,7 @@ public class WebserviceInfo extends GWebserviceInfo
public WebserviceInfo(String title, String info, int width, int height,
boolean makeVisible)
{
+ // no references
init(title, info, width, height, makeVisible);
}
@@ -322,7 +323,7 @@ public class WebserviceInfo extends GWebserviceInfo
{
frame = new JInternalFrame();
frame.setContentPane(this);
- Desktop.addInternalFrame(frame, title, makeVisible, width, height);
+ Desktop.addInternalFrame(frame, title, makeVisible, width, height, Desktop.FRAME_ALLOW_RESIZE, Desktop.FRAME_SET_MIN_SIZE_300);
frame.setClosable(false);
progressBar = new ProgressBar(statusPanel, statusBar);
@@ -746,7 +747,7 @@ public class WebserviceInfo extends GWebserviceInfo
@Override
public void run()
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop, message,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(), message,
title, JvOptionPane.WARNING_MESSAGE);
}
diff --git a/src/jalview/gui/WsJobParameters.java b/src/jalview/gui/WsJobParameters.java
index 976e551..45822a3 100644
--- a/src/jalview/gui/WsJobParameters.java
+++ b/src/jalview/gui/WsJobParameters.java
@@ -215,12 +215,12 @@ public class WsJobParameters extends JPanel implements ItemListener,
public boolean showRunDialog()
{
- frame = new JDialog(Desktop.instance, true);
+ frame = new JDialog(Desktop.getInstance(), true);
frame.setTitle(MessageManager.formatMessage("label.edit_params_for",
new String[]
{ service.getActionText() }));
- Rectangle deskr = Desktop.instance.getBounds();
+ Rectangle deskr = Desktop.getInstance().getBounds();
Dimension pref = this.getPreferredSize();
frame.setBounds(
new Rectangle((int) (deskr.getCenterX() - pref.width / 2),
@@ -436,8 +436,8 @@ public class WsJobParameters extends JPanel implements ItemListener,
dialogpanel.add(canceljob);
// JAL-1580: setMaximumSize() doesn't work, so just size for the worst case:
// check for null is for JUnit usage
- final int windowHeight = Desktop.instance == null ? 540
- : Desktop.instance.getHeight();
+ final int windowHeight = Desktop.getInstance() == null ? 540
+ : Desktop.getInstance().getHeight();
setPreferredSize(new Dimension(540, windowHeight));
add(dialogpanel, BorderLayout.SOUTH);
validate();
@@ -963,13 +963,13 @@ public class WsJobParameters extends JPanel implements ItemListener,
public static void main(String[] args)
{
jalview.ws.jws2.Jws2Discoverer disc = jalview.ws.jws2.Jws2Discoverer
- .getDiscoverer();
+ .getInstance();
int p = 0;
if (args.length > 0)
{
Vector services = new Vector<>();
services.addElement(args[p++]);
- Jws2Discoverer.getDiscoverer().setServiceUrls(services);
+ Jws2Discoverer.getInstance().setServiceUrls(services);
}
try
{
diff --git a/src/jalview/gui/WsParamSetManager.java b/src/jalview/gui/WsParamSetManager.java
index bb5d996..0f315eb 100644
--- a/src/jalview/gui/WsParamSetManager.java
+++ b/src/jalview/gui/WsParamSetManager.java
@@ -203,7 +203,7 @@ public class WsParamSetManager implements ParamManager
chooser.setDialogTitle(MessageManager
.getString("label.choose_filename_for_param_file"));
chooser.setToolTipText(MessageManager.getString("action.save"));
- int value = chooser.showSaveDialog(Desktop.instance);
+ int value = chooser.showSaveDialog(Desktop.getInstance());
if (value == JalviewFileChooser.APPROVE_OPTION)
{
outfile = chooser.getSelectedFile();
@@ -311,7 +311,7 @@ public class WsParamSetManager implements ParamManager
File pfile = new File(filename);
if (pfile.exists() && pfile.canWrite())
{
- if (JvOptionPane.showConfirmDialog(Desktop.instance,
+ if (JvOptionPane.showConfirmDialog(Desktop.getInstance(),
"Delete the preset's file, too ?", "Delete User Preset ?",
JvOptionPane.OK_CANCEL_OPTION) == JvOptionPane.OK_OPTION)
{
diff --git a/src/jalview/gui/WsPreferences.java b/src/jalview/gui/WsPreferences.java
index 5186a26..b97a25e 100644
--- a/src/jalview/gui/WsPreferences.java
+++ b/src/jalview/gui/WsPreferences.java
@@ -65,7 +65,7 @@ public class WsPreferences extends GWsPreferences
private void initFromPreferences()
{
- wsUrls = Jws2Discoverer.getDiscoverer().getServiceUrls();
+ wsUrls = Jws2Discoverer.getInstance().getServiceUrls();
if (!wsUrls.isEmpty())
{
oldUrls = new Vector(wsUrls);
@@ -122,7 +122,7 @@ public class WsPreferences extends GWsPreferences
int r = 0;
for (String url : wsUrls)
{
- int status = Jws2Discoverer.getDiscoverer().getServerStatusFor(url);
+ int status = Jws2Discoverer.getInstance().getServerStatusFor(url);
tdat[r][1] = Integer.valueOf(status);
tdat[r++][0] = url;
}
@@ -241,7 +241,7 @@ public class WsPreferences extends GWsPreferences
private void updateServiceList()
{
- Jws2Discoverer.getDiscoverer().setServiceUrls(wsUrls);
+ Jws2Discoverer.getInstance().setServiceUrls(wsUrls);
}
private void updateRsbsServiceList()
@@ -454,7 +454,7 @@ public class WsPreferences extends GWsPreferences
boolean valid = false;
int resp = JvOptionPane.CANCEL_OPTION;
while (!valid && (resp = JvOptionPane.showInternalConfirmDialog(
- Desktop.desktop, panel, title,
+ Desktop.getDesktopPane(), panel, title,
JvOptionPane.OK_CANCEL_OPTION)) == JvOptionPane.OK_OPTION)
{
try
@@ -472,13 +472,13 @@ public class WsPreferences extends GWsPreferences
} catch (Exception e)
{
valid = false;
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString("label.invalid_url"));
}
}
if (valid && resp == JvOptionPane.OK_OPTION)
{
- int validate = JvOptionPane.showInternalConfirmDialog(Desktop.desktop,
+ int validate = JvOptionPane.showInternalConfirmDialog(Desktop.getDesktopPane(),
MessageManager.getString("info.validate_jabaws_server"),
MessageManager.getString("label.test_server"),
JvOptionPane.YES_NO_OPTION);
@@ -491,7 +491,7 @@ public class WsPreferences extends GWsPreferences
}
else
{
- int opt = JvOptionPane.showInternalOptionDialog(Desktop.desktop,
+ int opt = JvOptionPane.showInternalOptionDialog(Desktop.getDesktopPane(),
"The Server '" + foo.toString()
+ "' failed validation,\ndo you want to add it anyway? ",
"Server Validation Failed", JvOptionPane.YES_NO_OPTION,
@@ -502,7 +502,7 @@ public class WsPreferences extends GWsPreferences
}
else
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString(
"warn.server_didnt_pass_validation"));
}
@@ -595,7 +595,7 @@ public class WsPreferences extends GWsPreferences
if (lastrefresh != update)
{
lastrefresh = update;
- Desktop.instance.startServiceDiscovery(true); // wait around for all
+ Desktop.getInstance().startServiceDiscovery(true); // wait around for all
// threads to complete
updateList();
@@ -616,15 +616,15 @@ public class WsPreferences extends GWsPreferences
public void run()
{
long ct = System.currentTimeMillis();
- Desktop.instance.setProgressBar(MessageManager
+ Desktop.getInstance().setProgressBar(MessageManager
.getString("status.refreshing_web_service_menus"), ct);
if (lastrefresh != update)
{
lastrefresh = update;
- Desktop.instance.startServiceDiscovery(true);
+ Desktop.getInstance().startServiceDiscovery(true);
updateList();
}
- Desktop.instance.setProgressBar(null, ct);
+ Desktop.getInstance().setProgressBar(null, ct);
}
}).start();
@@ -646,8 +646,8 @@ public class WsPreferences extends GWsPreferences
@Override
protected void resetWs_actionPerformed(ActionEvent e)
{
- Jws2Discoverer.getDiscoverer().setServiceUrls(null);
- List nwsUrls = Jws2Discoverer.getDiscoverer().getServiceUrls();
+ Jws2Discoverer.getInstance().setServiceUrls(null);
+ List nwsUrls = Jws2Discoverer.getInstance().getServiceUrls();
if (!wsUrls.equals(nwsUrls))
{
update++;
diff --git a/src/jalview/httpserver/HttpServer.java b/src/jalview/httpserver/HttpServer.java
index a18d38d..7021fae 100644
--- a/src/jalview/httpserver/HttpServer.java
+++ b/src/jalview/httpserver/HttpServer.java
@@ -20,6 +20,8 @@
*/
package jalview.httpserver;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.rest.RestHandler;
import java.net.BindException;
@@ -49,39 +51,8 @@ import org.eclipse.jetty.util.thread.QueuedThreadPool;
* @author gmcarstairs
* @see http://eclipse.org/jetty/documentation/current/embedding-jetty.html
*/
-public class HttpServer
+public class HttpServer implements ApplicationSingletonI
{
- /*
- * 'context root' - actually just prefixed to the path for each handler for
- * now - see registerHandler
- */
- private static final String JALVIEW_PATH = "jalview";
-
- /*
- * Singleton instance of this server
- */
- private static HttpServer instance;
-
- /*
- * The Http server
- */
- private Server server;
-
- /*
- * Registered handlers for context paths
- */
- private HandlerCollection contextHandlers;
-
- /*
- * Lookup of ContextHandler by its wrapped handler
- */
- Map myHandlers = new HashMap();
-
- /*
- * The context root for the server
- */
- private URI contextRoot;
-
/**
* Returns the singleton instance of this class.
*
@@ -92,14 +63,10 @@ public class HttpServer
{
synchronized (HttpServer.class)
{
- if (instance == null)
- {
- instance = new HttpServer();
- }
- return instance;
+ return (HttpServer) ApplicationSingletonProvider.getInstance(HttpServer.class);
}
}
-
+
/**
* Private constructor to enforce use of singleton
*
@@ -116,6 +83,34 @@ public class HttpServer
registerHandler(RestHandler.getInstance());
}
+
+ /*
+ * 'context root' - actually just prefixed to the path for each handler for
+ * now - see registerHandler
+ */
+ private static final String JALVIEW_PATH = "jalview";
+
+ /*
+ * The Http server
+ */
+ private Server server;
+
+ /*
+ * Registered handlers for context paths
+ */
+ private HandlerCollection contextHandlers;
+
+ /*
+ * Lookup of ContextHandler by its wrapped handler
+ */
+ Map myHandlers = new HashMap();
+
+ /*
+ * The context root for the server
+ */
+ private URI contextRoot;
+
+
/**
* Start the http server
*
diff --git a/src/jalview/io/AppletFormatAdapter.java b/src/jalview/io/AppletFormatAdapter.java
index 4916bb3..f01bfdc 100755
--- a/src/jalview/io/AppletFormatAdapter.java
+++ b/src/jalview/io/AppletFormatAdapter.java
@@ -158,11 +158,7 @@ public class AppletFormatAdapter
{
this.selectedFile = selectedFile;
- if (selectedFile != null)
- {
- this.inFile = selectedFile.getPath();
- }
- this.inFile = file;
+ inFile = (selectedFile == null ? file : selectedFile.getPath());
try
{
if (fileFormat.isStructureFile())
diff --git a/src/jalview/io/BSMLFile.java b/src/jalview/io/BSMLFile.java
new file mode 100644
index 0000000..69e29f8
--- /dev/null
+++ b/src/jalview/io/BSMLFile.java
@@ -0,0 +1,225 @@
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
+ * Copyright (C) $$Year-Rel$$ The Jalview Authors
+ *
+ * This file is part of Jalview.
+ *
+ * Jalview is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * Jalview is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Jalview. If not, see .
+ * The Jalview Authors are detailed in the 'AUTHORS' file.
+ */
+package jalview.io;
+
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.util.MessageManager;
+
+import java.io.BufferedReader;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import fr.orsay.lri.varna.exceptions.ExceptionFileFormatOrSyntax;
+import fr.orsay.lri.varna.exceptions.ExceptionLoadingFailed;
+import fr.orsay.lri.varna.exceptions.ExceptionPermissionDenied;
+
+/**
+ * Preliminary reader for Bioinformatics Sequence Markup Language
+ * http://www.bsml.org
+ *
+ * @author hansonr
+ *
+ */
+public class BSMLFile extends AlignFile
+{
+
+ public BSMLFile()
+ {
+ super();
+
+ }
+
+ public BSMLFile(String inFile, DataSourceType type) throws IOException
+ {
+ super(inFile, type);
+
+ }
+
+ public BSMLFile(FileParse source) throws IOException
+ {
+ super(source);
+
+ }
+
+ public BufferedReader CreateReader() throws FileNotFoundException
+ {
+ FileReader fr = null;
+ fr = new FileReader(inFile);
+
+ BufferedReader r = new BufferedReader(fr);
+ return r;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see jalview.io.AlignFile#parse()
+ */
+ @Override
+ public void parse() throws IOException
+ {
+ try
+ {
+ _parse();
+ } catch (ExceptionPermissionDenied pdx)
+ {
+ errormessage = MessageManager.formatMessage(
+ "exception.BSML_couldnt_access_datasource", new String[]
+ { pdx.getMessage() });
+ throw new IOException(pdx);
+ } catch (ExceptionLoadingFailed lf)
+ {
+ errormessage = MessageManager.formatMessage(
+ "exception.BSML_couldnt_process_data", new String[]
+ { lf.getMessage() });
+ throw new IOException(lf);
+ } catch (ExceptionFileFormatOrSyntax iff)
+ {
+ errormessage = MessageManager
+ .formatMessage("exception.BSML_invalid_file", new String[]
+ { iff.getMessage() });
+ throw new IOException(iff);
+ } catch (Exception x)
+ {
+ error = true;
+ errormessage = MessageManager.formatMessage(
+ "exception.BSML_problem_parsing_data", new String[]
+ { x.getMessage() });
+ throw new IOException(errormessage, x);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public void _parse()
+ throws ExceptionPermissionDenied, ExceptionLoadingFailed,
+ ExceptionFileFormatOrSyntax, ParserConfigurationException,
+ SAXException, IOException
+ {
+
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+
+ dbf.setIgnoringElementContentWhitespace(true);
+ dbf.setIgnoringComments(true);
+ dbf.setValidating(true);
+ dbf.setCoalescing(true);
+ dbf.setNamespaceAware(true);
+ dbf.setFeature("http://xml.org/sax/features/namespaces", false);
+ dbf.setFeature("http://xml.org/sax/features/validation", false);
+ dbf.setFeature(
+ "http://apache.org/xml/features/nonvalidating/load-dtd-grammar",
+ false);
+ dbf.setFeature(
+ "http://apache.org/xml/features/nonvalidating/load-external-dtd",
+ false);
+
+ DocumentBuilder db = dbf.newDocumentBuilder();
+
+ Map htSeq = new Hashtable<>();
+ InputSource is = new InputSource(getReader());
+ Document d = db.parse(is);
+ NodeList sequences = d.getElementsByTagName("Sequence-data");
+ int n = sequences.getLength();
+ SequenceI[] sqs = new SequenceI[n];
+ for (int i = 0; i < n; i++)
+ {
+ Element e = (Element) sequences.item(i);
+ String s = e.getTextContent();
+ String id = e.getAttribute("seq-name");
+ SequenceI seq = sqs[i] = new Sequence(id, s, 1, s.length());
+ htSeq.put(id, seq);
+ // ?? sqs[i].setEnd(sqs[i].findPosition(sqs[i].getLength()));
+ }
+
+ sequences = d.getElementsByTagName("Sequence");
+ n = sequences.getLength();
+ for (int i = 0; i < n; i++)
+ {
+ Element e = (Element) sequences.item(i);
+ String mol = e.getAttribute("molecule"); // dna or rna
+ if (!"dna".equals(mol))
+ {
+ System.err.println("BSML molecule=rna not implemented");
+ continue;
+ }
+ String title = e.getAttribute("title");
+ SequenceI seq = htSeq.get(title);
+ if (seq == null)
+ {
+ continue;
+ }
+ NodeList features = e.getElementsByTagName("Feature");
+ int featureCount = features.getLength();
+ for (int f = 0; f < featureCount; f++)
+ {
+ Element feature = (Element) features.item(f);
+ //
+ //
+ //
+ //
+ Element iloc = (Element) feature
+ .getElementsByTagName("Interval-loc").item(0);
+ String complement = iloc.getAttribute("complement");
+ if (!"0".equals(complement))
+ {
+ // Jalview cannot handle complement genes (running backward on the
+ // complementary strand);
+ continue;
+ }
+ String fclass = feature.getAttribute("class");
+ if (!"GENE".equals(fclass))
+ {
+ // just processing GENE features for now;
+ continue;
+ }
+ String ftitle = feature.getAttribute("title");
+ int start = Integer.parseInt(iloc.getAttribute("startpos"));
+ int end = Integer.parseInt(iloc.getAttribute("endpos"));
+ SequenceFeature sf = new SequenceFeature("GENE", ftitle, start, end,
+ null);
+ seq.addSequenceFeature(sf);
+ }
+ setSeqs(sqs);
+ }
+
+ }
+
+ @Override
+ public String print(SequenceI[] s, boolean jvSuffix)
+ {
+ return "not yet implemented";
+ }
+
+}
diff --git a/src/jalview/io/BackupFiles.java b/src/jalview/io/BackupFiles.java
index 0d5f92b..9537442 100644
--- a/src/jalview/io/BackupFiles.java
+++ b/src/jalview/io/BackupFiles.java
@@ -538,7 +538,7 @@ public class BackupFiles
MessageManager.getString("label.delete"),
MessageManager.getString("label.rename") };
- confirmButton = JvOptionPane.showOptionDialog(Desktop.desktop,
+ confirmButton = JvOptionPane.showOptionDialog(Desktop.getDesktopPane(),
messageSB.toString(),
MessageManager.getString("label.backupfiles_confirm_delete"),
JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
@@ -558,7 +558,7 @@ public class BackupFiles
MessageManager.getString("label.delete"),
MessageManager.getString("label.keep") };
- confirmButton = JvOptionPane.showOptionDialog(Desktop.desktop,
+ confirmButton = JvOptionPane.showOptionDialog(Desktop.getDesktopPane(),
messageSB.toString(),
MessageManager.getString("label.backupfiles_confirm_delete"),
JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE,
@@ -593,7 +593,7 @@ public class BackupFiles
Long.toString(df.length()) }));
}
- int confirmButton = JvOptionPane.showConfirmDialog(Desktop.desktop,
+ int confirmButton = JvOptionPane.showConfirmDialog(Desktop.getDesktopPane(),
messageSB.toString(),
MessageManager
.getString("label.backupfiles_confirm_delete"),
@@ -682,7 +682,7 @@ public class BackupFiles
"label.backupfiles_confirm_save_new_saved_file_not_ok"));
}
- int confirmButton = JvOptionPane.showConfirmDialog(Desktop.desktop,
+ int confirmButton = JvOptionPane.showConfirmDialog(Desktop.getDesktopPane(),
messageSB.toString(),
MessageManager
.getString("label.backupfiles_confirm_save_file"),
diff --git a/src/jalview/io/BioJsHTMLOutput.java b/src/jalview/io/BioJsHTMLOutput.java
index 9db3df2..5573e0d 100644
--- a/src/jalview/io/BioJsHTMLOutput.java
+++ b/src/jalview/io/BioJsHTMLOutput.java
@@ -25,6 +25,7 @@ import jalview.gui.OOMWarning;
import jalview.json.binding.biojs.BioJSReleasePojo;
import jalview.json.binding.biojs.BioJSRepositoryPojo;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
@@ -44,8 +45,7 @@ public class BioJsHTMLOutput extends HTMLOutput
private static TreeMap bioJsMSAVersions;
- public static final String DEFAULT_DIR = System.getProperty("user.home")
- + File.separatorChar + ".biojs_templates" + File.separatorChar;
+ public static final String DEFAULT_DIR = Platform.getUserPath(".biojs_templates/");
public static final String BJS_TEMPLATES_LOCAL_DIRECTORY = jalview.bin.Cache
.getDefault("biojs_template_directory", DEFAULT_DIR);
diff --git a/src/jalview/io/FileFormats.java b/src/jalview/io/FileFormats.java
index aadcdb9..fca29bd 100644
--- a/src/jalview/io/FileFormats.java
+++ b/src/jalview/io/FileFormats.java
@@ -27,6 +27,9 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+
/**
* A singleton registry of alignment file formats known to Jalview. On startup,
* the 'built-in' formats are added (from the FileFormat enum). Additional
@@ -36,23 +39,11 @@ import java.util.Set;
* @author gmcarstairs
*
*/
-public class FileFormats
+public class FileFormats implements ApplicationSingletonI
{
- private static FileFormats instance = new FileFormats();
-
- /*
- * A lookup map of file formats by upper-cased name
- */
- private static Map formats;
-
- /*
- * Formats in this set are capable of being identified by IdentifyFile
- */
- private static Set identifiable;
-
public static FileFormats getInstance()
{
- return instance;
+ return (FileFormats) ApplicationSingletonProvider.getInstance(FileFormats.class);
}
/**
@@ -63,6 +54,17 @@ public class FileFormats
reset();
}
+ /*
+ * A lookup map of file formats by upper-cased name
+ */
+ private Map formats;
+
+ /*
+ * Formats in this set are capable of being identified by IdentifyFile
+ */
+ private Set identifiable;
+
+
/**
* Reset to just the built-in file formats packaged with Jalview. These are
* added (and will be shown in menus) in the order of their declaration in the
diff --git a/src/jalview/io/FileLoader.java b/src/jalview/io/FileLoader.java
index ac55911..7eda110 100755
--- a/src/jalview/io/FileLoader.java
+++ b/src/jalview/io/FileLoader.java
@@ -275,9 +275,9 @@ public class FileLoader implements Runnable
Runtime rt = Runtime.getRuntime();
try
{
- if (Desktop.instance != null)
+ if (Desktop.getInstance() != null)
{
- Desktop.instance.startLoading(file);
+ Desktop.getInstance().startLoading(file);
}
if (format == null)
{
@@ -299,12 +299,12 @@ public class FileLoader implements Runnable
if (format == null)
{
- Desktop.instance.stopLoading();
+ Desktop.getInstance().stopLoading();
System.err.println("The input file \"" + file
+ "\" has null or unidentifiable data content!");
if (!Jalview.isHeadlessMode())
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.getString("label.couldnt_read_data")
+ " in " + file + "\n"
+ AppletFormatAdapter.getSupportedFormats(),
@@ -315,7 +315,7 @@ public class FileLoader implements Runnable
}
// TODO: cache any stream datasources as a temporary file (eg. PDBs
// retrieved via URL)
- if (Desktop.desktop != null && Desktop.desktop.isShowMemoryUsage())
+ if (Desktop.getDesktopPane() != null && Desktop.getDesktopPane().isShowMemoryUsage())
{
System.gc();
memused = (rt.maxMemory() - rt.totalMemory() + rt.freeMemory()); // free
@@ -408,7 +408,7 @@ public class FileLoader implements Runnable
// register PDB entries with desktop's structure selection
// manager
StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance)
+ .getStructureSelectionManager(Desktop.getInstance())
.registerPDBEntry(pdbe);
}
}
@@ -501,23 +501,23 @@ public class FileLoader implements Runnable
}
else
{
- if (Desktop.instance != null)
+ if (Desktop.getInstance() != null)
{
- Desktop.instance.stopLoading();
+ Desktop.getInstance().stopLoading();
}
final String errorMessage = MessageManager.getString(
"label.couldnt_load_file") + " " + title + "\n" + error;
// TODO: refactor FileLoader to be independent of Desktop / Applet GUI
// bits ?
- if (raiseGUI && Desktop.desktop != null)
+ if (raiseGUI && Desktop.getDesktopPane() != null)
{
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
errorMessage,
MessageManager
.getString("label.error_loading_file"),
@@ -545,7 +545,7 @@ public class FileLoader implements Runnable
@Override
public void run()
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.problems_opening_file", new String[]
{ file }),
@@ -567,7 +567,7 @@ public class FileLoader implements Runnable
@Override
public void run()
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"warn.out_of_memory_loading_file", new String[]
{ file }),
@@ -589,7 +589,7 @@ public class FileLoader implements Runnable
// memory
// after
// load
- if (Desktop.desktop != null && Desktop.desktop.isShowMemoryUsage())
+ if (Desktop.getDesktopPane() != null && Desktop.getDesktopPane().isShowMemoryUsage())
{
if (alignFrame != null)
{
@@ -611,9 +611,9 @@ public class FileLoader implements Runnable
}
}
// remove the visual delay indicator
- if (Desktop.instance != null)
+ if (Desktop.getInstance() != null)
{
- Desktop.instance.stopLoading();
+ Desktop.getInstance().stopLoading();
}
}
diff --git a/src/jalview/io/SequenceAnnotationReport.java b/src/jalview/io/SequenceAnnotationReport.java
index 8e4e783..4d0bec7 100644
--- a/src/jalview/io/SequenceAnnotationReport.java
+++ b/src/jalview/io/SequenceAnnotationReport.java
@@ -237,7 +237,7 @@ public class SequenceAnnotationReport
{
if (sb0.length() > 6)
{
- sb.append(" ");
+ sb.append(" ");
}
sb.append(feature.getType()).append(" ").append(begin).append(":")
.append(end);
@@ -247,7 +247,7 @@ public class SequenceAnnotationReport
if (sb0.length() > 6)
{
- sb.append(" ");
+ sb.append(" ");
}
// TODO: remove this hack to display link only features
boolean linkOnly = feature.getValue("linkonly") != null;
@@ -276,7 +276,9 @@ public class SequenceAnnotationReport
int linkindex = description.toLowerCase().indexOf(" -1
&& linkindex < MAX_DESCRIPTION_LENGTH;
- if (description.length() > MAX_DESCRIPTION_LENGTH && !hasLink)
+ if (
+ // BH suggestion maxlength == 0 &&
+ description.length() > MAX_DESCRIPTION_LENGTH && !hasLink)
{
description = description.substring(0, MAX_DESCRIPTION_LENGTH)
+ ELLIPSIS;
@@ -395,7 +397,7 @@ public class SequenceAnnotationReport
{
for (List urllink : createLinksFrom(null, urlstring))
{
- sb.append(" ");
+ + " ");
}
} catch (Exception x)
{
@@ -561,7 +563,7 @@ public class SequenceAnnotationReport
countForSource++;
if (countForSource == 1 || !summary)
{
- sb.append(" ");
+ sb.append(" ");
}
if (countForSource <= MAX_REFS_PER_SOURCE || !summary)
{
@@ -587,11 +589,11 @@ public class SequenceAnnotationReport
}
if (moreSources)
{
- sb.append(" ").append(source).append(COMMA).append(ELLIPSIS);
+ sb.append(" ").append(source).append(COMMA).append(ELLIPSIS);
}
if (ellipsis)
{
- sb.append(" (");
+ sb.append(" (");
sb.append(MessageManager.getString("label.output_seq_details"));
sb.append(")");
}
diff --git a/src/jalview/io/VamsasAppDatastore.java b/src/jalview/io/VamsasAppDatastore.java
index 387dbfa..c60fd88 100644
--- a/src/jalview/io/VamsasAppDatastore.java
+++ b/src/jalview/io/VamsasAppDatastore.java
@@ -720,9 +720,9 @@ public class VamsasAppDatastore
// /SAVE THE TREES
// /////////////////////////////////
// FIND ANY ASSOCIATED TREES
- if (Desktop.desktop != null)
+ if (Desktop.getDesktopPane() != null)
{
- javax.swing.JInternalFrame[] frames = Desktop.instance
+ javax.swing.JInternalFrame[] frames = Desktop.getInstance()
.getAllFrames();
for (int t = 0; t < frames.length; t++)
@@ -1479,7 +1479,7 @@ public class VamsasAppDatastore
if (mappings != null)
{
jalview.structure.StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance)
+ .getStructureSelectionManager(Desktop.getInstance())
.registerMappings(mappings);
}
}
diff --git a/src/jalview/io/WSWUBlastClient.java b/src/jalview/io/WSWUBlastClient.java
index 63b78b2..e24c2f3 100755
--- a/src/jalview/io/WSWUBlastClient.java
+++ b/src/jalview/io/WSWUBlastClient.java
@@ -150,7 +150,7 @@ public class WSWUBlastClient
{
// This must be outside the run() body as java 1.5
// will not return any value from the OptionPane to the expired thread.
- int reply = JvOptionPane.showConfirmDialog(Desktop.desktop,
+ int reply = JvOptionPane.showConfirmDialog(Desktop.getDesktopPane(),
"Automatically update suggested ids?",
"Auto replace sequence ids", JvOptionPane.YES_NO_OPTION);
diff --git a/src/jalview/io/cache/AppCache.java b/src/jalview/io/cache/AppCache.java
index eaf6ecd..fdcad08 100644
--- a/src/jalview/io/cache/AppCache.java
+++ b/src/jalview/io/cache/AppCache.java
@@ -20,6 +20,8 @@
*/
package jalview.io.cache;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.bin.Cache;
import java.util.Hashtable;
@@ -31,22 +33,27 @@ import java.util.LinkedHashSet;
* @author tcnofoegbu
*
*/
-public class AppCache
+public class AppCache implements ApplicationSingletonI
{
+
+ public static AppCache getInstance()
+ {
+ return (AppCache) ApplicationSingletonProvider.getInstance(AppCache.class);
+ }
+
+ private AppCache()
+ {
+ cacheItems = new Hashtable>();
+ }
+
public static final String DEFAULT_LIMIT = "99";
public static final String CACHE_DELIMITER = ";";
- private static AppCache instance = null;
-
private static final String DEFAULT_LIMIT_KEY = ".DEFAULT_LIMIT";
private Hashtable> cacheItems;
- private AppCache()
- {
- cacheItems = new Hashtable>();
- }
/**
* Method to obtain all the cache items for a given cache key
@@ -66,20 +73,6 @@ public class AppCache
}
/**
- * Returns a singleton instance of AppCache
- *
- * @return
- */
- public static AppCache getInstance()
- {
- if (instance == null)
- {
- instance = new AppCache();
- }
- return instance;
- }
-
- /**
* Method for persisting cache items for a given cache key
*
* @param cacheKey
diff --git a/src/jalview/io/gff/Gff3Helper.java b/src/jalview/io/gff/Gff3Helper.java
index 1ef8848..e422ed4 100644
--- a/src/jalview/io/gff/Gff3Helper.java
+++ b/src/jalview/io/gff/Gff3Helper.java
@@ -91,7 +91,7 @@ public class Gff3Helper extends GffHelperBase
String atts = gff[ATTRIBUTES_COL];
Map> attributes = parseNameValuePairs(atts);
- SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+ SequenceOntologyI so = SequenceOntologyFactory.getSequenceOntology();
if (so.isA(soTerm, SequenceOntologyI.PROTEIN_MATCH))
{
sf = processProteinMatch(attributes, seq, gff, align, newseqs,
@@ -385,7 +385,7 @@ public class Gff3Helper extends GffHelperBase
desc = target.split(" ")[0];
}
- SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+ SequenceOntologyI so = SequenceOntologyFactory.getSequenceOntology();
String type = sf.getType();
if (so.isA(type, SequenceOntologyI.SEQUENCE_VARIANT))
{
diff --git a/src/jalview/io/gff/InterProScanHelper.java b/src/jalview/io/gff/InterProScanHelper.java
index 948cdd2..141b677 100644
--- a/src/jalview/io/gff/InterProScanHelper.java
+++ b/src/jalview/io/gff/InterProScanHelper.java
@@ -108,7 +108,7 @@ public class InterProScanHelper extends Gff3Helper
*/
public static boolean recognises(String[] columns)
{
- SequenceOntologyI so = SequenceOntologyFactory.getInstance();
+ SequenceOntologyI so = SequenceOntologyFactory.getSequenceOntology();
String type = columns[TYPE_COL];
if (so.isA(type, SequenceOntologyI.PROTEIN_MATCH)
|| (".".equals(columns[SOURCE_COL])
diff --git a/src/jalview/io/gff/SequenceOntologyFactory.java b/src/jalview/io/gff/SequenceOntologyFactory.java
index 90cae7a..08a2c6a 100644
--- a/src/jalview/io/gff/SequenceOntologyFactory.java
+++ b/src/jalview/io/gff/SequenceOntologyFactory.java
@@ -20,6 +20,9 @@
*/
package jalview.io.gff;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+
/**
* A factory class that returns a model of the Sequence Ontology. By default a
* hard-coded subset is used (for the applet, or testing), or setInstance() can
@@ -28,21 +31,53 @@ package jalview.io.gff;
* @author gmcarstairs
*
*/
-public class SequenceOntologyFactory
+public class SequenceOntologyFactory implements ApplicationSingletonI
{
- private static SequenceOntologyI instance;
+ /**
+ * Answers an instance of this class for the current application context. Note
+ * that this supports running two JS 'applets' on the same page, one with the
+ * full Sequence Ontology (USE_FULL_SO = true) and one with a hard-coded
+ * subset (USE_FULL_SO = false). If this is overkill, could change this method
+ * to just return a common static instance.
+ *
+ * @return
+ */
+ private static synchronized SequenceOntologyFactory getInstance()
+ {
+ return (SequenceOntologyFactory) ApplicationSingletonProvider
+ .getInstance(SequenceOntologyFactory.class);
+ }
+
+ private SequenceOntologyFactory()
+ {
+ // private singleton
+ }
+
- public static synchronized SequenceOntologyI getInstance()
+ /**
+ * Answers the configured model of the Sequence Ontology.
+ *
+ * @return
+ */
+ public static synchronized SequenceOntologyI getSequenceOntology()
{
- if (instance == null)
- {
- instance = new SequenceOntologyLite();
- }
- return instance;
+ SequenceOntologyFactory f = getInstance();
+ return (f.sequenceOntology == null
+ ? f.sequenceOntology = new SequenceOntologyLite()
+ : f.sequenceOntology);
}
- public static void setInstance(SequenceOntologyI so)
+ /**
+ * For testng only
+ *
+ * @param so
+ */
+ public static void setSequenceOntology(SequenceOntologyI so)
{
- instance = so;
+ getInstance().sequenceOntology = so;
}
+
+
+ private SequenceOntologyI sequenceOntology;
+
}
diff --git a/src/jalview/io/vamsas/Sequencemapping.java b/src/jalview/io/vamsas/Sequencemapping.java
index 0a582e5..402ffdf 100644
--- a/src/jalview/io/vamsas/Sequencemapping.java
+++ b/src/jalview/io/vamsas/Sequencemapping.java
@@ -365,7 +365,7 @@ public class Sequencemapping extends Rangetype
}
bindjvvobj(mapping, sequenceMapping);
jalview.structure.StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance)
+ .getStructureSelectionManager(Desktop.getInstance())
.registerMapping(acf);
// Try to link up any conjugate database references in the two sequences
// matchConjugateDBRefs(from, to, mapping);
diff --git a/src/jalview/jbgui/GAlignFrame.java b/src/jalview/jbgui/GAlignFrame.java
index edaabf1..38ad437 100755
--- a/src/jalview/jbgui/GAlignFrame.java
+++ b/src/jalview/jbgui/GAlignFrame.java
@@ -25,9 +25,10 @@ import jalview.analysis.GeneticCodeI;
import jalview.analysis.GeneticCodes;
import jalview.api.SplitContainerI;
import jalview.bin.Cache;
-import jalview.bin.Jalview;
import jalview.gui.JvSwingUtils;
+import jalview.gui.PaintRefresher;
import jalview.gui.Preferences;
+import jalview.gui.TreePanel;
import jalview.io.FileFormats;
import jalview.schemes.ResidueColourScheme;
import jalview.util.MessageManager;
@@ -35,6 +36,7 @@ import jalview.util.Platform;
import java.awt.BorderLayout;
import java.awt.Color;
+import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
@@ -44,7 +46,9 @@ import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import javax.swing.BorderFactory;
@@ -222,7 +226,7 @@ public class GAlignFrame extends JInternalFrame
{
// for Web-page embedding using id=align-frame-div
- setName(Jalview.getAppID("alignment"));
+ setName(Platform.getAppID("alignment"));
jbInit();
@@ -1172,6 +1176,24 @@ public class GAlignFrame extends JInternalFrame
@Override
public void menuSelected(MenuEvent e)
{
+ enableSortMenuOptions();
+ }
+
+ @Override
+ public void menuDeselected(MenuEvent e)
+ {
+ }
+
+ @Override
+ public void menuCanceled(MenuEvent e)
+ {
+ }
+ });
+ sortByTreeMenu.addMenuListener(new MenuListener()
+ {
+ @Override
+ public void menuSelected(MenuEvent e)
+ {
buildTreeSortMenu();
}
@@ -1712,8 +1734,8 @@ public class GAlignFrame extends JInternalFrame
});
JMenuItem selectHighlighted = new JMenuItem(
MessageManager.getString("action.select_highlighted_columns"));
- selectHighlighted.setToolTipText(
- MessageManager.getString("tooltip.select_highlighted_columns"));
+ selectHighlighted.setToolTipText(JvSwingUtils.wrapTooltip(true,
+ MessageManager.getString("tooltip.select_highlighted_columns")));
al = new ActionListener()
{
@Override
@@ -1918,6 +1940,10 @@ public class GAlignFrame extends JInternalFrame
// selectMenu.add(listenToViewSelections);
}
+ protected void enableSortMenuOptions()
+ {
+ }
+
protected void loadVcf_actionPerformed()
{
}
@@ -2716,4 +2742,6 @@ public class GAlignFrame extends JInternalFrame
protected void showComplement_actionPerformed(boolean complement)
{
}
+
+
}
diff --git a/src/jalview/jbgui/GDesktop.java b/src/jalview/jbgui/GDesktop.java
index 8e30f5a..0c179e8 100755
--- a/src/jalview/jbgui/GDesktop.java
+++ b/src/jalview/jbgui/GDesktop.java
@@ -21,7 +21,6 @@
package jalview.jbgui;
import jalview.api.AlignmentViewPanel;
-import jalview.bin.Jalview;
import jalview.io.FileFormatException;
import jalview.util.MessageManager;
import jalview.util.Platform;
@@ -46,7 +45,7 @@ import javax.swing.JMenuItem;
public class GDesktop extends JFrame
{
- protected static JMenu windowMenu = new JMenu();
+ protected JMenu windowMenu = new JMenu();
JMenuBar desktopMenubar = new JMenuBar();
@@ -141,7 +140,7 @@ public class GDesktop extends JFrame
private void jbInit() throws Exception
{
- setName(Jalview.getAppID("desktop"));
+ setName(Platform.getAppID("desktop"));
FileMenu.setText(MessageManager.getString("action.file"));
HelpMenu.setText(MessageManager.getString("action.help"));
inputLocalFileMenuItem
diff --git a/src/jalview/jbgui/GPCAPanel.java b/src/jalview/jbgui/GPCAPanel.java
index 74b5afd..aa2f549 100755
--- a/src/jalview/jbgui/GPCAPanel.java
+++ b/src/jalview/jbgui/GPCAPanel.java
@@ -20,9 +20,9 @@
*/
package jalview.jbgui;
-import jalview.bin.Jalview;
import jalview.util.ImageMaker.TYPE;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import java.awt.BorderLayout;
import java.awt.Color;
@@ -89,7 +89,7 @@ public class GPCAPanel extends JInternalFrame
private void jbInit() throws Exception
{
- setName(Jalview.getAppID("pca"));
+ setName(Platform.getAppID("pca"));
this.getContentPane().setLayout(new BorderLayout());
JPanel jPanel2 = new JPanel();
jPanel2.setLayout(new FlowLayout());
diff --git a/src/jalview/jbgui/GPreferences.java b/src/jalview/jbgui/GPreferences.java
index 60f17ab..08fbea3 100755
--- a/src/jalview/jbgui/GPreferences.java
+++ b/src/jalview/jbgui/GPreferences.java
@@ -2259,7 +2259,7 @@ public class GPreferences extends JPanel
boolean ret = false;
String warningMessage = MessageManager
.getString("label.warning_confirm_change_reverse");
- int confirm = JvOptionPane.showConfirmDialog(Desktop.desktop,
+ int confirm = JvOptionPane.showConfirmDialog(Desktop.getDesktopPane(),
warningMessage,
MessageManager.getString("label.change_increment_decrement"),
JvOptionPane.YES_NO_OPTION, JvOptionPane.WARNING_MESSAGE);
diff --git a/src/jalview/jbgui/GSequenceLink.java b/src/jalview/jbgui/GSequenceLink.java
index a43e504..2ec7051 100755
--- a/src/jalview/jbgui/GSequenceLink.java
+++ b/src/jalview/jbgui/GSequenceLink.java
@@ -219,7 +219,7 @@ public class GSequenceLink extends JPanel
return true;
}
- JvOptionPane.showInternalMessageDialog(jalview.gui.Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(jalview.gui.Desktop.getDesktopPane(),
MessageManager.getString("warn.url_must_contain"),
MessageManager.getString("label.invalid_url"),
JvOptionPane.WARNING_MESSAGE);
@@ -228,7 +228,7 @@ public class GSequenceLink extends JPanel
public void notifyDuplicate()
{
- JvOptionPane.showInternalMessageDialog(jalview.gui.Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(jalview.gui.Desktop.getDesktopPane(),
MessageManager.getString("warn.name_cannot_be_duplicate"),
MessageManager.getString("label.invalid_name"),
JvOptionPane.WARNING_MESSAGE);
diff --git a/src/jalview/jbgui/GStructureViewer.java b/src/jalview/jbgui/GStructureViewer.java
index e16d63a..1e7cf37 100644
--- a/src/jalview/jbgui/GStructureViewer.java
+++ b/src/jalview/jbgui/GStructureViewer.java
@@ -21,10 +21,10 @@
package jalview.jbgui;
import jalview.api.structures.JalviewStructureDisplayI;
-import jalview.bin.Jalview;
import jalview.gui.ColourMenuHelper.ColourChangeListener;
import jalview.util.ImageMaker.TYPE;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import java.awt.BorderLayout;
import java.awt.GridLayout;
@@ -90,7 +90,7 @@ public abstract class GStructureViewer extends JInternalFrame
private void jbInit() throws Exception
{
- setName(Jalview.getAppID("structureviewer"));
+ setName(Platform.getAppID("structureviewer"));
JMenuBar menuBar = new JMenuBar();
this.setJMenuBar(menuBar);
diff --git a/src/jalview/jbgui/GTreePanel.java b/src/jalview/jbgui/GTreePanel.java
index 0f9c2a2..3aff0e0 100755
--- a/src/jalview/jbgui/GTreePanel.java
+++ b/src/jalview/jbgui/GTreePanel.java
@@ -20,9 +20,9 @@
*/
package jalview.jbgui;
-import jalview.bin.Jalview;
import jalview.util.ImageMaker.TYPE;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import java.awt.BorderLayout;
import java.awt.Color;
@@ -93,7 +93,7 @@ public class GTreePanel extends JInternalFrame
private void jbInit() throws Exception
{
- setName(Jalview.getAppID("tree"));
+ setName(Platform.getAppID("tree"));
this.getContentPane().setLayout(borderLayout1);
this.setBackground(Color.white);
this.setFont(new java.awt.Font("Verdana", 0, 12));
diff --git a/src/jalview/project/Jalview2XML.java b/src/jalview/project/Jalview2XML.java
index 751b297..9303aed 100644
--- a/src/jalview/project/Jalview2XML.java
+++ b/src/jalview/project/Jalview2XML.java
@@ -28,6 +28,7 @@ import jalview.analysis.Conservation;
import jalview.analysis.PCA;
import jalview.analysis.scoremodels.ScoreModels;
import jalview.analysis.scoremodels.SimilarityParams;
+import jalview.api.AlignmentViewPanel;
import jalview.api.FeatureColourI;
import jalview.api.ViewStyleI;
import jalview.api.analysis.ScoreModelI;
@@ -60,6 +61,7 @@ import jalview.gui.AlignmentPanel;
import jalview.gui.AppVarna;
import jalview.gui.ChimeraViewFrame;
import jalview.gui.Desktop;
+import jalview.gui.FeatureRenderer;
import jalview.gui.JvOptionPane;
import jalview.gui.OOMWarning;
import jalview.gui.PCAPanel;
@@ -82,7 +84,6 @@ import jalview.schemes.ColourSchemeProperty;
import jalview.schemes.FeatureColour;
import jalview.schemes.ResidueProperties;
import jalview.schemes.UserColourScheme;
-import jalview.structure.StructureSelectionManager;
import jalview.structures.models.AAStructureBindingModel;
import jalview.util.Format;
import jalview.util.MessageManager;
@@ -162,10 +163,10 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
-import java.lang.reflect.InvocationTargetException;
import java.math.BigInteger;
import java.net.MalformedURLException;
import java.net.URL;
@@ -268,6 +269,25 @@ public class Jalview2XML
private Map rnaSessions = new HashMap<>();
/**
+ * contains last error message (if any) encountered by XML loader.
+ */
+ String errorMessage = null;
+
+ /**
+ * flag to control whether the Jalview2XML_V1 parser should be deferred to if
+ * exceptions are raised during project XML parsing
+ */
+ public boolean attemptversion1parse = false;
+
+ /*
+ * JalviewJS only -- to allow read file bytes to be saved in the
+ * created AlignFrame, allowing File | Reload of a project file to work
+ *
+ * BH 2019 JAL-3436
+ */
+ private File jarFile;
+
+ /**
* A helper method for safely using the value of an optional attribute that
* may be null if not present in the XML. Answers the boolean value, or false
* if null.
@@ -427,7 +447,7 @@ public class Jalview2XML
* @param _jmap
* @return
*/
- public SeqFref newMappingRef(final String sref,
+ protected SeqFref newMappingRef(final String sref,
final jalview.datamodel.Mapping _jmap)
{
SeqFref fref = new SeqFref(sref, "Mapping")
@@ -449,7 +469,7 @@ public class Jalview2XML
return fref;
}
- public SeqFref newAlcodMapRef(final String sref,
+ protected SeqFref newAlcodMapRef(final String sref,
final AlignedCodonFrame _cf,
final jalview.datamodel.Mapping _jmap)
{
@@ -481,7 +501,7 @@ public class Jalview2XML
return fref;
}
- public void resolveFrefedSequences()
+ protected void resolveFrefedSequences()
{
Iterator nextFref = frefedSequence.iterator();
int toresolve = frefedSequence.size();
@@ -626,13 +646,14 @@ public class Jalview2XML
* core method for storing state for a set of AlignFrames.
*
* @param frames
- * - frames involving all data to be exported (including containing
- * splitframes)
+ * - frames involving all data to be exported (including those
+ * contained in splitframes, though not the split frames themselves)
* @param jout
* - project output stream
*/
private void saveAllFrames(List frames, JarOutputStream jout)
{
+
Hashtable dsses = new Hashtable<>();
/*
@@ -655,21 +676,22 @@ public class Jalview2XML
for (int i = frames.size() - 1; i > -1; i--)
{
AlignFrame af = frames.get(i);
+ AlignViewport vp = af.getViewport();
// skip ?
if (skipList != null && skipList
- .containsKey(af.getViewport().getSequenceSetId()))
+ .containsKey(vp.getSequenceSetId()))
{
continue;
}
String shortName = makeFilename(af, shortNames);
- int apSize = af.getAlignPanels().size();
-
+ AlignmentI alignment = vp.getAlignment();
+ List extends AlignmentViewPanel> panels = af.getAlignPanels();
+ int apSize = panels.size();
for (int ap = 0; ap < apSize; ap++)
- {
- AlignmentPanel apanel = (AlignmentPanel) af.getAlignPanels()
- .get(ap);
+ {
+ AlignmentPanel apanel = (AlignmentPanel) panels.get(ap);
String fileName = apSize == 1 ? shortName : ap + shortName;
if (!fileName.endsWith(".xml"))
{
@@ -677,11 +699,17 @@ public class Jalview2XML
}
saveState(apanel, fileName, jout, viewIds);
-
- String dssid = getDatasetIdRef(
- af.getViewport().getAlignment().getDataset());
+ }
+ if (apSize > 0)
+ {
+ // BH moved next bit out of inner loop, not that it really matters.
+ // so we are testing to make sure we actually have an alignment,
+ // apparently.
+ String dssid = getDatasetIdRef(alignment.getDataset());
if (!dsses.containsKey(dssid))
{
+ // We have not already covered this data by reference from another
+ // frame.
dsses.put(dssid, af);
}
}
@@ -799,10 +827,22 @@ public class Jalview2XML
}
}
+ /**
+ * Each AlignFrame has a single data set associated with it. Note that none of
+ * these frames are split frames, because Desktop.getAlignFrames() collects
+ * top and bottom separately here.
+ *
+ * @param dsses
+ * @param fileName
+ * @param jout
+ */
private void writeDatasetFor(Hashtable dsses,
String fileName, JarOutputStream jout)
{
+ // Note that in saveAllFrames we have associated each specific dataset to
+ // ONE of its associated frames.
+
for (String dssids : dsses.keySet())
{
AlignFrame _af = dsses.get(dssids);
@@ -829,7 +869,7 @@ public class Jalview2XML
* @param out
* jar entry name
*/
- public JalviewModel saveState(AlignmentPanel ap, String fileName,
+ protected JalviewModel saveState(AlignmentPanel ap, String fileName,
JarOutputStream jout, List viewIds)
{
return saveState(ap, fileName, false, jout, viewIds);
@@ -851,7 +891,7 @@ public class Jalview2XML
* @param out
* jar entry name
*/
- public JalviewModel saveState(AlignmentPanel ap, String fileName,
+ protected JalviewModel saveState(AlignmentPanel ap, String fileName,
boolean storeDS, JarOutputStream jout, List viewIds)
{
if (viewIds == null)
@@ -1083,7 +1123,7 @@ public class Jalview2XML
* only view *should* be coped with sensibly.
*/
// This must have been loaded, is it still visible?
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames();
String matchedFile = null;
for (int f = frames.length - 1; f > -1; f--)
{
@@ -1235,9 +1275,9 @@ public class Jalview2XML
{
// FIND ANY ASSOCIATED TREES
// NOT IMPLEMENTED FOR HEADLESS STATE AT PRESENT
- if (Desktop.desktop != null)
+ if (Desktop.getDesktopPane() != null)
{
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames();
for (int t = 0; t < frames.length; t++)
{
@@ -1281,9 +1321,9 @@ public class Jalview2XML
/*
* save PCA viewers
*/
- if (!storeDS && Desktop.desktop != null)
+ if (!storeDS && Desktop.getDesktopPane() != null)
{
- for (JInternalFrame frame : Desktop.desktop.getAllFrames())
+ for (JInternalFrame frame : Desktop.getDesktopPane().getAllFrames())
{
if (frame instanceof PCAPanel)
{
@@ -1924,11 +1964,11 @@ public class Jalview2XML
final SequenceI jds, List viewIds, AlignmentPanel ap,
boolean storeDataset)
{
- if (Desktop.desktop == null)
+ if (Desktop.getDesktopPane() == null)
{
return;
}
- JInternalFrame[] frames = Desktop.desktop.getAllFrames();
+ JInternalFrame[] frames = Desktop.getDesktopPane().getAllFrames();
for (int f = frames.length - 1; f > -1; f--)
{
if (frames[f] instanceof AppVarna)
@@ -2384,7 +2424,7 @@ public class Jalview2XML
if (calcIdParam.getVersion().equals("1.0"))
{
final String[] calcIds = calcIdParam.getServiceURL().toArray(new String[0]);
- Jws2Instance service = Jws2Discoverer.getDiscoverer()
+ Jws2Instance service = Jws2Discoverer.getInstance()
.getPreferredServiceFor(calcIds);
if (service != null)
{
@@ -2723,17 +2763,6 @@ public class Jalview2XML
}
/**
- * contains last error message (if any) encountered by XML loader.
- */
- String errorMessage = null;
-
- /**
- * flag to control whether the Jalview2XML_V1 parser should be deferred to if
- * exceptions are raised during project XML parsing
- */
- public boolean attemptversion1parse = false;
-
- /**
* Load a jalview project archive from a jar file
*
* @param file
@@ -2767,7 +2796,10 @@ public class Jalview2XML
{
try
{
- SwingUtilities.invokeAndWait(new Runnable()
+// was invokeAndWait
+
+ // BH 2019 -- can't wait
+ SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
@@ -2780,55 +2812,55 @@ public class Jalview2XML
System.err.println("Error loading alignment: " + x.getMessage());
}
}
+ this.jarFile = null;
return af;
}
@SuppressWarnings("unused")
- private jarInputStreamProvider createjarInputStreamProvider(final Object ofile) throws MalformedURLException {
-
- // BH 2018 allow for bytes already attached to File object
- try {
- String file = (ofile instanceof File ? ((File) ofile).getCanonicalPath() : ofile.toString());
+ private jarInputStreamProvider createjarInputStreamProvider(
+ final Object ofile) throws MalformedURLException
+ {
+ try
+ {
+ String file = (ofile instanceof File
+ ? ((File) ofile).getCanonicalPath()
+ : ofile.toString());
byte[] bytes = Platform.isJS() ? Platform.getFileBytes((File) ofile)
: null;
- URL url = null;
- errorMessage = null;
- uniqueSetSuffix = null;
- seqRefIds = null;
- viewportsAdded.clear();
- frefedSequence = null;
-
- if (file.startsWith("http://")) {
- url = new URL(file);
- }
- final URL _url = url;
- return new jarInputStreamProvider() {
-
- @Override
- public JarInputStream getJarInputStream() throws IOException {
- if (bytes != null) {
-// System.out.println("Jalview2XML: opening byte jarInputStream for bytes.length=" + bytes.length);
- return new JarInputStream(new ByteArrayInputStream(bytes));
- }
- if (_url != null) {
-// System.out.println("Jalview2XML: opening url jarInputStream for " + _url);
- return new JarInputStream(_url.openStream());
- } else {
-// System.out.println("Jalview2XML: opening file jarInputStream for " + file);
- return new JarInputStream(new FileInputStream(file));
- }
- }
-
- @Override
- public String getFilename() {
- return file;
- }
- };
- } catch (IOException e) {
- e.printStackTrace();
- return null;
- }
- }
+ if (bytes != null)
+ {
+ this.jarFile = (File) ofile;
+ }
+ errorMessage = null;
+ uniqueSetSuffix = null;
+ seqRefIds = null;
+ viewportsAdded.clear();
+ frefedSequence = null;
+
+ URL url = file.startsWith("http://") ? new URL(file) : null;
+ return new jarInputStreamProvider()
+ {
+ @Override
+ public JarInputStream getJarInputStream() throws IOException
+ {
+ InputStream is = bytes != null ? new ByteArrayInputStream(bytes)
+ : (url != null ? url.openStream()
+ : new FileInputStream(file));
+ return new JarInputStream(is);
+ }
+
+ @Override
+ public String getFilename()
+ {
+ return file;
+ }
+ };
+ } catch (IOException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
/**
* Recover jalview session from a jalview project archive. Caller may
@@ -2854,12 +2886,19 @@ public class Jalview2XML
IdentityHashMap importedDatasets = new IdentityHashMap<>();
Map gatherToThisFrame = new HashMap<>();
final String file = jprovider.getFilename();
+
+ List alignFrames = new ArrayList<>();
+
try
{
JarInputStream jin = null;
JarEntry jarentry = null;
int entryCount = 1;
+
+ // Look for all the entry names ending with ".xml"
+ // This includes all panels and at least one frame.
+// Platform.timeCheck(null, Platform.TIME_MARK);
do
{
jin = jprovider.getJarInputStream();
@@ -2867,9 +2906,27 @@ public class Jalview2XML
{
jarentry = jin.getNextJarEntry();
}
+ String name = (jarentry == null ? null : jarentry.getName());
- if (jarentry != null && jarentry.getName().endsWith(".xml"))
+// System.out.println("Jalview2XML opening " + name);
+ if (name != null && name.endsWith(".xml"))
{
+
+ // DataSet for.... is read last.
+
+
+ // The question here is what to do with the two
+ // .xml files in the jvp file.
+ // Some number of them, "...Dataset for...", will be the
+ // Only AlignPanels and will have Viewport.
+ // One or more will be the source data, with the DBRefs.
+ //
+ // JVP file writing (above) ensures tha the AlignPanels are written
+ // first, then all relevant datasets (which are
+ // Jalview.datamodel.Alignment).
+ //
+
+// Platform.timeCheck("Jalview2XML JAXB " + name, Platform.TIME_MARK);
JAXBContext jc = JAXBContext
.newInstance("jalview.xml.binding.jalview");
XMLStreamReader streamReader = XMLInputFactory.newInstance()
@@ -2877,14 +2934,25 @@ public class Jalview2XML
javax.xml.bind.Unmarshaller um = jc.createUnmarshaller();
JAXBElement jbe = um
.unmarshal(streamReader, JalviewModel.class);
- JalviewModel object = jbe.getValue();
+ JalviewModel model = jbe.getValue();
if (true) // !skipViewport(object))
{
- _af = loadFromObject(object, file, true, jprovider);
- if (_af != null && object.getViewport().size() > 0)
- // getJalviewModelSequence().getViewportCount() > 0)
+ // Q: Do we have to load from the model, even if it
+ // does not have a viewport, could we discover that early on?
+ // Q: Do we need to load this object?
+ _af = loadFromObject(model, file, true, jprovider);
+// Platform.timeCheck("Jalview2XML.loadFromObject",
+ // Platform.TIME_MARK);
+
+ if (_af != null)
{
+ alignFrames.add(_af);
+ }
+ if (_af != null && model.getViewport().size() > 0)
+ {
+
+ // That is, this is one of the AlignmentPanel models
if (af == null)
{
// store a reference to the first view
@@ -2927,9 +2995,9 @@ public class Jalview2XML
{
// used to attempt to parse as V1 castor-generated xml
}
- if (Desktop.instance != null)
+ if (Desktop.getInstance() != null)
{
- Desktop.instance.stopLoading();
+ Desktop.getInstance().stopLoading();
}
if (af != null)
{
@@ -2946,6 +3014,13 @@ public class Jalview2XML
errorMessage = "Out of memory loading jalview XML file";
System.err.println("Out of memory whilst loading jalview XML file");
e.printStackTrace();
+ } finally
+ {
+ for (AlignFrame alf : alignFrames)
+ {
+ alf.alignPanel.setHoldRepaint(false);
+ }
+
}
/*
@@ -2957,7 +3032,7 @@ public class Jalview2XML
*/
for (AlignFrame fr : gatherToThisFrame.values())
{
- Desktop.instance.gatherViews(fr);
+ Desktop.getInstance().gatherViews(fr);
}
restoreSplitFrames();
@@ -2965,8 +3040,7 @@ public class Jalview2XML
{
if (ds.getCodonFrames() != null)
{
- StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance)
+ Desktop.getStructureSelectionManager()
.registerMappings(ds.getCodonFrames());
}
}
@@ -2975,9 +3049,9 @@ public class Jalview2XML
reportErrors();
}
- if (Desktop.instance != null)
+ if (Desktop.getInstance() != null)
{
- Desktop.instance.stopLoading();
+ Desktop.getInstance().stopLoading();
}
return af;
@@ -3058,7 +3132,7 @@ public class Jalview2XML
*/
for (SplitFrame sf : gatherTo)
{
- Desktop.instance.gatherViews(sf);
+ Desktop.getInstance().gatherViews(sf);
}
splitFrameCandidates.clear();
@@ -3117,7 +3191,7 @@ public class Jalview2XML
@Override
public void run()
{
- JvOptionPane.showInternalMessageDialog(Desktop.desktop,
+ JvOptionPane.showInternalMessageDialog(Desktop.getDesktopPane(),
finalErrorMessage,
"Error " + (saving ? "saving" : "loading")
+ " Jalview file",
@@ -3178,25 +3252,25 @@ public class Jalview2XML
* @param prefix
* a prefix for the temporary file name, must be at least three
* characters long
- * @param suffixModel
+ * @param origFile
* null or original file - so new file can be given the same suffix
* as the old one
* @return
*/
protected String copyJarEntry(jarInputStreamProvider jprovider,
- String jarEntryName, String prefix, String suffixModel)
+ String jarEntryName, String prefix, String origFile)
{
BufferedReader in = null;
PrintWriter out = null;
String suffix = ".tmp";
- if (suffixModel == null)
+ if (origFile == null)
{
- suffixModel = jarEntryName;
+ origFile = jarEntryName;
}
- int sfpos = suffixModel.lastIndexOf(".");
- if (sfpos > -1 && sfpos < (suffixModel.length() - 1))
+ int sfpos = origFile.lastIndexOf(".");
+ if (sfpos > -1 && sfpos < (origFile.length() - 3))
{
- suffix = "." + suffixModel.substring(sfpos + 1);
+ suffix = "." + origFile.substring(sfpos + 1);
}
try
{
@@ -3276,7 +3350,9 @@ public class Jalview2XML
}
/**
- * Load alignment frame from jalview XML DOM object
+ * Load alignment frame from jalview XML DOM object. For a DOM object that
+ * includes one or more Viewport elements (one with a title that does NOT
+ * contain "Dataset for"), create the frame.
*
* @param jalviewModel
* DOM
@@ -3294,6 +3370,7 @@ public class Jalview2XML
SequenceSet vamsasSet = jalviewModel.getVamsasModel().getSequenceSet().get(0);
List vamsasSeqs = vamsasSet.getSequence();
+
// JalviewModelSequence jms = object.getJalviewModelSequence();
// Viewport view = (jms.getViewportCount() > 0) ? jms.getViewport(0)
@@ -3589,8 +3666,7 @@ public class Jalview2XML
{
entry.setProperty(prop.getName(), prop.getValue());
}
- StructureSelectionManager
- .getStructureSelectionManager(Desktop.instance)
+ Desktop.getStructureSelectionManager()
.registerPDBEntry(entry);
// adds PDBEntry to datasequence's set (since Jalview 2.10)
if (al.getSequenceAt(i).getDatasetSequence() != null)
@@ -3603,6 +3679,7 @@ public class Jalview2XML
}
}
}
+
}
} // end !multipleview
@@ -3740,6 +3817,7 @@ public class Jalview2XML
}
}
}
+ // create the new AlignmentAnnotation
jalview.datamodel.AlignmentAnnotation jaa = null;
if (annotation.isGraph())
@@ -3776,6 +3854,7 @@ public class Jalview2XML
jaa._linecolour = firstColour;
}
// register new annotation
+ // Annotation graphs such as Conservation will not have id.
if (annotation.getId() != null)
{
annotationIds.put(annotation.getId(), jaa);
@@ -3987,8 +4066,6 @@ public class Jalview2XML
// ///////////////////////////////
// LOAD VIEWPORT
- AlignFrame af = null;
- AlignViewport av = null;
// now check to see if we really need to create a new viewport.
if (multipleView && viewportsAdded.size() == 0)
{
@@ -4027,8 +4104,9 @@ public class Jalview2XML
boolean doGroupAnnColour = Jalview2XML.isVersionStringLaterThan("2.8.1",
jalviewModel.getVersion());
+ AlignFrame af = null;
AlignmentPanel ap = null;
- boolean isnewview = true;
+ AlignViewport av = null;
if (viewId != null)
{
// Check to see if this alignment already has a view id == viewId
@@ -4038,25 +4116,27 @@ public class Jalview2XML
{
for (int v = 0; v < views.length; v++)
{
- if (views[v].av.getViewId().equalsIgnoreCase(viewId))
+ ap = views[v];
+ av = ap.av;
+ if (av.getViewId().equalsIgnoreCase(viewId))
{
// recover the existing alignpanel, alignframe, viewport
- af = views[v].alignFrame;
- av = views[v].av;
- ap = views[v];
+ af = ap.alignFrame;
+ break;
// TODO: could even skip resetting view settings if we don't want to
// change the local settings from other jalview processes
- isnewview = false;
}
}
}
}
- if (isnewview)
+ if (af == null)
{
af = loadViewport(file, jseqs, hiddenSeqs, al, jalviewModel, view,
uniqueSeqSetId, viewId, autoAlan);
av = af.getViewport();
+ // note that this only retrieves the most recently accessed
+ // tab of an AlignFrame.
ap = af.alignPanel;
}
@@ -4065,14 +4145,61 @@ public class Jalview2XML
*
* Not done if flag is false (when this method is used for New View)
*/
+ final AlignFrame af0 = af;
+ final AlignViewport av0 = av;
+ final AlignmentPanel ap0 = ap;
+// Platform.timeCheck("Jalview2XML.loadFromObject-beforetree",
+// Platform.TIME_MARK);
if (loadTreesAndStructures)
{
- loadTrees(jalviewModel, view, af, av, ap);
- loadPCAViewers(jalviewModel, ap);
- loadPDBStructures(jprovider, jseqs, af, ap);
- loadRnaViewers(jprovider, jseqs, ap);
+ if (!jalviewModel.getTree().isEmpty())
+ {
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+// Platform.timeCheck(null, Platform.TIME_MARK);
+ loadTrees(jalviewModel, view, af0, av0, ap0);
+// Platform.timeCheck("Jalview2XML.loadTrees", Platform.TIME_MARK);
+ }
+ });
+ }
+ if (!jalviewModel.getPcaViewer().isEmpty())
+ {
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+// Platform.timeCheck(null, Platform.TIME_MARK);
+ loadPCAViewers(jalviewModel, ap0);
+// Platform.timeCheck("Jalview2XML.loadPCA", Platform.TIME_MARK);
+ }
+ });
+ }
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+// Platform.timeCheck(null, Platform.TIME_MARK);
+ loadPDBStructures(jprovider, jseqs, af0, ap0);
+// Platform.timeCheck("Jalview2XML.loadPDB", Platform.TIME_MARK);
+ }
+ });
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ loadRnaViewers(jprovider, jseqs, ap0);
+ }
+ });
}
// and finally return.
+ // but do not set holdRepaint true just yet, because this could be the
+ // initial frame with just its dataset.
return af;
}
@@ -4089,7 +4216,7 @@ public class Jalview2XML
* @param jseqs
* @param ap
*/
- private void loadRnaViewers(jarInputStreamProvider jprovider,
+ protected void loadRnaViewers(jarInputStreamProvider jprovider,
List jseqs, AlignmentPanel ap)
{
/*
@@ -4199,6 +4326,12 @@ public class Jalview2XML
tree.getTitle(), safeInt(tree.getWidth()),
safeInt(tree.getHeight()), safeInt(tree.getXpos()),
safeInt(tree.getYpos()));
+ if (tp == null)
+ {
+ warn("There was a problem recovering stored Newick tree: \n"
+ + tree.getNewick());
+ continue;
+ }
if (tree.getId() != null)
{
// perhaps bind the tree id to something ?
@@ -4219,13 +4352,6 @@ public class Jalview2XML
tp.getTreeCanvas().setAssociatedPanel(ap); // af.alignPanel;
}
tp.getTreeCanvas().setApplyToAllViews(tree.isLinkToAllViews());
- if (tp == null)
- {
- warn("There was a problem recovering stored Newick tree: \n"
- + tree.getNewick());
- continue;
- }
-
tp.fitToWindow.setState(safeBoolean(tree.isFitToWindow()));
tp.fitToWindow_actionPerformed(null);
@@ -4308,7 +4434,7 @@ public class Jalview2XML
int height = safeInt(structureState.getHeight());
// Probably don't need to do this anymore...
- // Desktop.desktop.getComponentAt(x, y);
+ // Desktop.getDesktop().getComponentAt(x, y);
// TODO: NOW: check that this recovers the PDB file correctly.
String pdbFile = loadPDBFile(jprovider, pdbid.getId(),
pdbid.getFile());
@@ -4550,7 +4676,8 @@ public class Jalview2XML
String reformatedOldFilename = oldfilenam.replaceAll("/", "\\\\");
filedat = oldFiles.get(new File(reformatedOldFilename));
}
- newFileLoc.append(Platform.escapeBackslashes(filedat.getFilePath()));
+ newFileLoc
+ .append(Platform.escapeBackslashes(filedat.getFilePath()));
pdbfilenames.add(filedat.getFilePath());
pdbids.add(filedat.getPdbId());
seqmaps.add(filedat.getSeqList().toArray(new SequenceI[0]));
@@ -4627,9 +4754,11 @@ public class Jalview2XML
final AlignFrame alf = af;
final Rectangle rect = new Rectangle(svattrib.getX(), svattrib.getY(),
svattrib.getWidth(), svattrib.getHeight());
- try
- {
- javax.swing.SwingUtilities.invokeAndWait(new Runnable()
+
+ // BH again was invokeAndWait
+ // try
+ // {
+ javax.swing.SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
@@ -4656,14 +4785,14 @@ public class Jalview2XML
}
}
});
- } catch (InvocationTargetException ex)
- {
- warn("Unexpected error when opening Jmol view.", ex);
-
- } catch (InterruptedException e)
- {
- // e.printStackTrace();
- }
+ // } catch (InvocationTargetException ex)
+ // {
+ // warn("Unexpected error when opening Jmol view.", ex);
+ //
+ // } catch (InterruptedException e)
+ // {
+ // // e.printStackTrace();
+ // }
}
@@ -4792,7 +4921,7 @@ public class Jalview2XML
{
try
{
- frames = Desktop.desktop.getAllFrames();
+ frames = Desktop.getDesktopPane().getAllFrames();
} catch (ArrayIndexOutOfBoundsException e)
{
// occasional No such child exceptions are thrown here...
@@ -4862,27 +4991,28 @@ public class Jalview2XML
}
}
- AlignFrame loadViewport(String file, List JSEQ,
- List hiddenSeqs, AlignmentI al,
- JalviewModel jm, Viewport view, String uniqueSeqSetId,
- String viewId, List autoAlan)
+ AlignFrame loadViewport(String fileName, List JSEQ,
+ List hiddenSeqs, AlignmentI al, JalviewModel jm,
+ Viewport view, String uniqueSeqSetId, String viewId,
+ List autoAlan)
{
AlignFrame af = null;
af = new AlignFrame(al, safeInt(view.getWidth()),
- safeInt(view.getHeight()), uniqueSeqSetId, viewId)
-// {
-//
-// @Override
-// protected void processKeyEvent(java.awt.event.KeyEvent e) {
-// System.out.println("Jalview2XML AF " + e);
-// super.processKeyEvent(e);
-//
-// }
-//
-// }
+ safeInt(view.getHeight()), uniqueSeqSetId, viewId)
+ // {
+ //
+ // @Override
+ // protected void processKeyEvent(java.awt.event.KeyEvent e) {
+ // System.out.println("Jalview2XML AF " + e);
+ // super.processKeyEvent(e);
+ //
+ // }
+ //
+ // }
;
-
- af.setFileName(file, FileFormat.Jalview);
+ af.alignPanel.setHoldRepaint(true);
+ af.setFileName(fileName, FileFormat.Jalview);
+ af.setFileObject(jarFile); // BH 2019 JAL-3436
final AlignViewport viewport = af.getViewport();
for (int i = 0; i < JSEQ.size(); i++)
@@ -4957,9 +5087,8 @@ public class Jalview2XML
viewport.setColourText(safeBoolean(view.isShowColourText()));
- viewport
- .setConservationSelected(
- safeBoolean(view.isConservationSelected()));
+ viewport.setConservationSelected(
+ safeBoolean(view.isConservationSelected()));
viewport.setIncrement(safeInt(view.getConsThreshold()));
viewport.setShowJVSuffix(safeBoolean(view.isShowFullId()));
viewport.setRightAlignIds(safeBoolean(view.isRightAlignIds()));
@@ -4990,8 +5119,18 @@ public class Jalview2XML
viewport.setViewName(view.getViewName());
af.setInitialTabVisible();
}
- af.setBounds(safeInt(view.getXpos()), safeInt(view.getYpos()),
- safeInt(view.getWidth()), safeInt(view.getHeight()));
+ int x = safeInt(view.getXpos());
+ int y = safeInt(view.getYpos());
+ int w = safeInt(view.getWidth());
+ int h = safeInt(view.getHeight());
+ // // BH we cannot let the title bar go off the top
+ // if (Platform.isJS())
+ // {
+ // x = Math.max(50 - w, x);
+ // y = Math.max(0, y);
+ // }
+
+ af.setBounds(x, y, w, h);
// startSeq set in af.alignPanel.updateLayout below
af.alignPanel.updateLayout();
ColourSchemeI cs = null;
@@ -5035,9 +5174,8 @@ public class Jalview2XML
af.changeColour(cs);
viewport.setColourAppliesToAllGroups(true);
- viewport
- .setShowSequenceFeatures(
- safeBoolean(view.isShowSequenceFeatures()));
+ viewport.setShowSequenceFeatures(
+ safeBoolean(view.isShowSequenceFeatures()));
viewport.setCentreColumnLabels(view.isCentreColumnLabels());
viewport.setIgnoreGapsConsensus(view.isIgnoreGapsinConsensus(), null);
@@ -5057,17 +5195,17 @@ public class Jalview2XML
// recover feature settings
if (jm.getFeatureSettings() != null)
{
- FeatureRendererModel fr = af.alignPanel.getSeqPanel().seqCanvas
+ FeatureRenderer fr = af.alignPanel.getSeqPanel().seqCanvas
.getFeatureRenderer();
FeaturesDisplayed fdi;
viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
- String[] renderOrder = new String[jm.getFeatureSettings()
- .getSetting().size()];
+ String[] renderOrder = new String[jm.getFeatureSettings().getSetting()
+ .size()];
Map featureColours = new Hashtable<>();
Map featureOrder = new Hashtable<>();
- for (int fs = 0; fs < jm.getFeatureSettings()
- .getSetting().size(); fs++)
+ for (int fs = 0; fs < jm.getFeatureSettings().getSetting()
+ .size(); fs++)
{
Setting setting = jm.getFeatureSettings().getSetting().get(fs);
String featureType = setting.getType();
@@ -5079,8 +5217,8 @@ public class Jalview2XML
.getMatcherSet();
if (filters != null)
{
- FeatureMatcherSetI filter = Jalview2XML
- .parseFilter(featureType, filters);
+ FeatureMatcherSetI filter = Jalview2XML.parseFilter(featureType,
+ filters);
if (!filter.isEmpty())
{
fr.setFeatureFilter(featureType, filter);
@@ -5112,8 +5250,7 @@ public class Jalview2XML
float max = setting.getMax() == null ? 1f
: setting.getMax().floatValue();
FeatureColourI gc = new FeatureColour(maxColour, minColour,
- maxColour,
- noValueColour, min, max);
+ maxColour, noValueColour, min, max);
if (setting.getAttributeName().size() > 0)
{
gc.setAttributeName(setting.getAttributeName().toArray(
@@ -5147,8 +5284,7 @@ public class Jalview2XML
}
else
{
- featureColours.put(featureType,
- new FeatureColour(maxColour));
+ featureColours.put(featureType, new FeatureColour(maxColour));
}
renderOrder[fs] = featureType;
if (setting.getOrder() != null)
@@ -5485,7 +5621,7 @@ public class Jalview2XML
return false;
}
- public void addToSkipList(AlignFrame af)
+ protected void addToSkipList(AlignFrame af)
{
if (skipList == null)
{
@@ -5494,7 +5630,7 @@ public class Jalview2XML
skipList.put(af.getViewport().getSequenceSetId(), af);
}
- public void clearSkipList()
+ protected void clearSkipList()
{
if (skipList != null)
{
@@ -5563,8 +5699,8 @@ public class Jalview2XML
SequenceI[] dsseqs = new SequenceI[dseqs.size()];
dseqs.copyInto(dsseqs);
ds = new jalview.datamodel.Alignment(dsseqs);
- debug("Created new dataset " + vamsasSet.getDatasetId()
- + " for alignment " + System.identityHashCode(al));
+// debug("Jalview2XML Created new dataset " + vamsasSet.getDatasetId()
+// + " for alignment " + System.identityHashCode(al));
addDatasetRef(vamsasSet.getDatasetId(), ds);
}
// set the dataset for the newly imported alignment.
@@ -5994,6 +6130,8 @@ public class Jalview2XML
AlignFrame af = loadFromObject(jm, null, false, null);
af.getAlignPanels().clear();
af.closeMenuItem_actionPerformed(true);
+ af.alignPanel.setHoldRepaint(false);
+ this.jarFile = null;
/*
* if(ap.av.getAlignment().getAlignmentAnnotation()!=null) { for(int i=0;
@@ -6351,7 +6489,11 @@ public class Jalview2XML
panel.getRotatableCanvas().getAxisEndPoints()[i] = new Point(
axis.getXPos(), axis.getYPos(), axis.getZPos());
}
- PCAPanel.addToDesktop(panel, modelName);
+
+ Dimension dim = Platform.getDimIfEmbedded(panel, 475, 450);
+ Desktop.addInternalFrame(panel, MessageManager.formatMessage(
+ "label.calc_title", "PCA", modelName), dim.width,
+ dim.height);
}
} catch (Exception ex)
{
diff --git a/src/jalview/rest/RestHandler.java b/src/jalview/rest/RestHandler.java
index a37882f..7c8c9a6 100644
--- a/src/jalview/rest/RestHandler.java
+++ b/src/jalview/rest/RestHandler.java
@@ -20,6 +20,8 @@
*/
package jalview.rest;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.httpserver.AbstractRequestHandler;
import java.io.IOException;
@@ -30,20 +32,16 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
- * A simple handler to process (or delegate) HTTP requests on /jalview/rest
+ * A simple handler to process (or delegate) HTTP requests on /jalview/rest.
*/
public class RestHandler extends AbstractRequestHandler
+ implements ApplicationSingletonI
{
private static final String MY_PATH = "rest";
private static final String MY_NAME = "Rest";
/**
- * Singleton instance of this class
- */
- private static RestHandler instance = null;
-
- /**
* Returns the singleton instance of this class
*
* @return
@@ -53,12 +51,8 @@ public class RestHandler extends AbstractRequestHandler
{
synchronized (RestHandler.class)
{
- if (instance == null)
- {
- instance = new RestHandler();
- }
+ return (RestHandler) ApplicationSingletonProvider.getInstance(RestHandler.class);
}
- return instance;
}
/**
diff --git a/src/jalview/schemes/ColourSchemes.java b/src/jalview/schemes/ColourSchemes.java
index d31fbba..0ff7c6e 100644
--- a/src/jalview/schemes/ColourSchemes.java
+++ b/src/jalview/schemes/ColourSchemes.java
@@ -21,24 +21,19 @@
package jalview.schemes;
import jalview.api.AlignViewportI;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.datamodel.AnnotatedCollectionI;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
+import jalview.util.ColorUtils;
+import java.awt.Color;
import java.util.LinkedHashMap;
import java.util.Map;
-public class ColourSchemes
+public class ColourSchemes implements ApplicationSingletonI
{
- /*
- * singleton instance of this class
- */
- private static ColourSchemes instance = new ColourSchemes();
-
- /*
- * a map from scheme name (lower-cased) to an instance of it
- */
- private Map schemes;
/**
* Returns the singleton instance of this class
@@ -47,7 +42,8 @@ public class ColourSchemes
*/
public static ColourSchemes getInstance()
{
- return instance;
+ return (ColourSchemes) ApplicationSingletonProvider
+ .getInstance(ColourSchemes.class);
}
private ColourSchemes()
@@ -56,6 +52,51 @@ public class ColourSchemes
}
/**
+ * ColourSchemeProperty "static"
+ */
+ public Color[] rnaHelices = null;
+
+ /**
+ * delete the existing cached RNA helices colours
+ */
+ public static void resetRnaHelicesShading()
+ {
+ getInstance().rnaHelices = null;
+ }
+
+ public static void initRnaHelicesShading(int n)
+ {
+ int i = 0;
+ ColourSchemes j = getInstance();
+
+ if (j.rnaHelices == null)
+ {
+ j.rnaHelices = new Color[n + 1];
+ }
+ else if (j.rnaHelices != null && j.rnaHelices.length <= n)
+ {
+ Color[] t = new Color[n + 1];
+ System.arraycopy(j.rnaHelices, 0, t, 0, j.rnaHelices.length);
+ i = j.rnaHelices.length;
+ j.rnaHelices = t;
+ }
+ else
+ {
+ return;
+ }
+ // Generate random colors and store
+ for (; i <= n; i++)
+ {
+ j.rnaHelices[i] = ColorUtils.generateRandomColor(Color.white);
+ }
+ }
+
+ /**
+ * a map from scheme name (lower-cased) to an instance of it
+ */
+ private Map schemes;
+
+ /**
* Loads an instance of each standard or user-defined colour scheme
*
* @return
diff --git a/src/jalview/structure/StructureImportSettings.java b/src/jalview/structure/StructureImportSettings.java
index 9662fee..b5672ab 100644
--- a/src/jalview/structure/StructureImportSettings.java
+++ b/src/jalview/structure/StructureImportSettings.java
@@ -20,6 +20,8 @@
*/
package jalview.structure;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.PDBEntry.Type;
@@ -30,27 +32,39 @@ import jalview.datamodel.PDBEntry.Type;
* @author tcofoegbu
*
*/
-public class StructureImportSettings
+public class StructureImportSettings implements ApplicationSingletonI
{
+
+ private StructureImportSettings()
+ {
+ // private singleton
+ }
+
+ private static StructureImportSettings getInstance()
+ {
+ return (StructureImportSettings) ApplicationSingletonProvider
+ .getInstance(StructureImportSettings.class);
+ }
+
/**
* set to true to add derived sequence annotations (temp factor read from
* file, or computed secondary structure) to the alignment
*/
- private static boolean visibleChainAnnotation = false;
+ private boolean visibleChainAnnotation = false;
/**
* Set true to predict secondary structure (using JMol for protein, Annotate3D
* for RNA)
*/
- private static boolean processSecStr = false;
+ private boolean processSecStr = false;
/**
* Set true (with predictSecondaryStructure=true) to predict secondary
* structure using an external service (currently Annotate3D for RNA only)
*/
- private static boolean externalSecondaryStructure = false;
+ private boolean externalSecondaryStructure = false;
- private static boolean showSeqFeatures = true;
+ private boolean showSeqFeatures = true;
public enum StructureParser
{
@@ -61,92 +75,93 @@ public class StructureImportSettings
* Determines the default file format for structure files to be downloaded
* from the PDB sequence fetcher. Possible options include: PDB|mmCIF
*/
- private static PDBEntry.Type defaultStructureFileFormat = Type.PDB;
+ private PDBEntry.Type defaultStructureFileFormat = Type.PDB;
/**
* Determines the parser used for parsing PDB format file. Possible options
* are : JMolParser|JalveiwParser
*/
- private static StructureParser defaultPDBFileParser = StructureParser.JMOL_PARSER;
+ private StructureParser defaultPDBFileParser = StructureParser.JMOL_PARSER;
public static void addSettings(boolean addAlignmentAnnotations,
boolean processSecStr, boolean externalSecStr)
{
- StructureImportSettings.visibleChainAnnotation = addAlignmentAnnotations;
- StructureImportSettings.processSecStr = processSecStr;
- StructureImportSettings.externalSecondaryStructure = externalSecStr;
- StructureImportSettings.showSeqFeatures = true;
+ StructureImportSettings s = getInstance();
+ s.visibleChainAnnotation = addAlignmentAnnotations;
+ s.processSecStr = processSecStr;
+ s.externalSecondaryStructure = externalSecStr;
+ s.showSeqFeatures = true;
}
public static boolean isVisibleChainAnnotation()
{
- return visibleChainAnnotation;
+ return getInstance().visibleChainAnnotation;
}
public static void setVisibleChainAnnotation(
boolean visibleChainAnnotation)
{
- StructureImportSettings.visibleChainAnnotation = visibleChainAnnotation;
+ getInstance().visibleChainAnnotation = visibleChainAnnotation;
}
public static boolean isProcessSecondaryStructure()
{
- return processSecStr;
+ return getInstance().processSecStr;
}
public static void setProcessSecondaryStructure(
boolean processSecondaryStructure)
{
- StructureImportSettings.processSecStr = processSecondaryStructure;
+ getInstance().processSecStr = processSecondaryStructure;
}
public static boolean isExternalSecondaryStructure()
{
- return externalSecondaryStructure;
+ return getInstance().externalSecondaryStructure;
}
public static void setExternalSecondaryStructure(
boolean externalSecondaryStructure)
{
- StructureImportSettings.externalSecondaryStructure = externalSecondaryStructure;
+ getInstance().externalSecondaryStructure = externalSecondaryStructure;
}
public static boolean isShowSeqFeatures()
{
- return showSeqFeatures;
+ return getInstance().showSeqFeatures;
}
public static void setShowSeqFeatures(boolean showSeqFeatures)
{
- StructureImportSettings.showSeqFeatures = showSeqFeatures;
+ getInstance().showSeqFeatures = showSeqFeatures;
}
public static PDBEntry.Type getDefaultStructureFileFormat()
{
- return defaultStructureFileFormat;
+ return getInstance().defaultStructureFileFormat;
}
public static void setDefaultStructureFileFormat(
String defaultStructureFileFormat)
{
- StructureImportSettings.defaultStructureFileFormat = PDBEntry.Type
+ getInstance().defaultStructureFileFormat = PDBEntry.Type
.valueOf(defaultStructureFileFormat.toUpperCase());
}
public static String getDefaultPDBFileParser()
{
- return defaultPDBFileParser.toString();
+ return getInstance().defaultPDBFileParser.toString();
}
public static void setDefaultPDBFileParser(
StructureParser defaultPDBFileParser)
{
- StructureImportSettings.defaultPDBFileParser = defaultPDBFileParser;
+ getInstance().defaultPDBFileParser = defaultPDBFileParser;
}
public static void setDefaultPDBFileParser(String defaultPDBFileParser)
{
- StructureImportSettings.defaultPDBFileParser = StructureParser
+ getInstance().defaultPDBFileParser = StructureParser
.valueOf(defaultPDBFileParser.toUpperCase());
}
diff --git a/src/jalview/structure/StructureSelectionManager.java b/src/jalview/structure/StructureSelectionManager.java
index 8c3816e..f8048cd 100644
--- a/src/jalview/structure/StructureSelectionManager.java
+++ b/src/jalview/structure/StructureSelectionManager.java
@@ -20,19 +20,10 @@
*/
package jalview.structure;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.IdentityHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Vector;
-
import jalview.analysis.AlignSeq;
import jalview.api.StructureSelectionManagerProvider;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.bin.Cache;
import jalview.commands.CommandI;
import jalview.commands.EditCommand;
@@ -57,16 +48,26 @@ import jalview.util.Platform;
import jalview.ws.sifts.SiftsClient;
import jalview.ws.sifts.SiftsException;
import jalview.ws.sifts.SiftsSettings;
+
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+
import mc_view.Atom;
import mc_view.PDBChain;
import mc_view.PDBfile;
-public class StructureSelectionManager
+public class StructureSelectionManager implements ApplicationSingletonI
{
public final static String NEWLINE = System.lineSeparator();
- static IdentityHashMap instances;
-
private List mappings = new ArrayList<>();
private boolean processSecondaryStructure = false;
@@ -84,6 +85,67 @@ public class StructureSelectionManager
private List sel_listeners = new ArrayList<>();
+ /*
+ * instances of this class scoped by some context class
+ */
+ private IdentityHashMap selectionManagers;
+
+ /**
+ * Answers an instance of this class for the current application (Java or JS
+ * 'applet') scope
+ *
+ * @return
+ */
+ private static StructureSelectionManager getInstance()
+ {
+ return (StructureSelectionManager) ApplicationSingletonProvider
+ .getInstance(StructureSelectionManager.class);
+ }
+
+ /**
+ * Private constructor as all 'singleton' instances are managed here or by
+ * ApplicationSingletonProvider
+ */
+ private StructureSelectionManager()
+ {
+ selectionManagers = new IdentityHashMap<>();
+ }
+
+ /**
+ * Answers an instance of this class for the current application (Java or JS
+ * 'applet') scope, and scoped to the specified context
+ *
+ * @param context
+ * @return
+ */
+ public static StructureSelectionManager getStructureSelectionManager(
+ StructureSelectionManagerProvider context)
+ {
+ return getInstance().getInstanceForContext(context);
+ }
+
+ /**
+ * Answers an instance of this class scoped to the given context. The instance
+ * is created on the first request for the context, thereafter the same
+ * instance is returned. Note that the context may be null (this is the case
+ * when running headless without a Desktop).
+ *
+ * @param context
+ * @return
+ */
+ StructureSelectionManager getInstanceForContext(
+ StructureSelectionManagerProvider context)
+ {
+ StructureSelectionManager instance = selectionManagers.get(context);
+ if (instance == null)
+ {
+ instance = new StructureSelectionManager();
+ selectionManagers.put(context, instance);
+ }
+ return instance;
+ }
+
+
/**
* @return true if will try to use external services for processing secondary
* structure
@@ -198,49 +260,6 @@ public class StructureSelectionManager
|| pdbIdFileName.containsKey(idOrFile);
}
- private static StructureSelectionManager nullProvider = null;
-
- public static StructureSelectionManager getStructureSelectionManager(
- StructureSelectionManagerProvider context)
- {
- if (context == null)
- {
- if (nullProvider == null)
- {
- if (instances != null)
- {
- throw new Error(MessageManager.getString(
- "error.implementation_error_structure_selection_manager_null"),
- new NullPointerException(MessageManager
- .getString("exception.ssm_context_is_null")));
- }
- else
- {
- nullProvider = new StructureSelectionManager();
- }
- return nullProvider;
- }
- }
- if (instances == null)
- {
- instances = new java.util.IdentityHashMap<>();
- }
- StructureSelectionManager instance = instances.get(context);
- if (instance == null)
- {
- if (nullProvider != null)
- {
- instance = nullProvider;
- }
- else
- {
- instance = new StructureSelectionManager();
- }
- instances.put(context, instance);
- }
- return instance;
- }
-
/**
* flag controlling whether SeqMappings are relayed from received sequence
* mouse over events to other sequences
@@ -270,7 +289,7 @@ public class StructureSelectionManager
return relaySeqMappings;
}
- Vector listeners = new Vector();
+ Vector listeners = new Vector<>();
/**
* register a listener for alignment sequence mouseover events
@@ -308,6 +327,8 @@ public class StructureSelectionManager
* Import structure data and register a structure mapping for broadcasting
* colouring, mouseovers and selection events (convenience wrapper).
*
+ * This is the standard entry point.
+ *
* @param sequence
* - one or more sequences to be mapped to pdbFile
* @param targetChains
@@ -332,8 +353,11 @@ public class StructureSelectionManager
* broadcasting colouring, mouseovers and selection events (convenience
* wrapper).
*
+ *
+ *
* @param forStructureView
- * when true, record the mapping for use in mouseOvers
+ * when true (testng only), record the mapping for use in mouseOvers
+ * (testng only)
* @param sequence
* - one or more sequences to be mapped to pdbFile
* @param targetChains
@@ -377,7 +401,7 @@ public class StructureSelectionManager
* mapping operation
* @return null or the structure data parsed as a pdb file
*/
- synchronized public StructureFile computeMapping(
+ synchronized private StructureFile computeMapping(
boolean forStructureView, SequenceI[] sequenceArray,
String[] targetChainIds, String pdbFile, DataSourceType sourceType,
IProgressIndicator progress)
@@ -652,7 +676,6 @@ public class StructureSelectionManager
{
ds = ds.getDatasetSequence();
}
- ;
if (ds.getAnnotation() != null)
{
for (AlignmentAnnotation ala : ds.getAnnotation())
@@ -906,9 +929,9 @@ public class StructureSelectionManager
if (s != null)
{
result = s;
- }
}
}
+ }
return result;
}
@@ -1242,8 +1265,11 @@ public class StructureSelectionManager
}
/**
- * Resets this object to its initial state by removing all registered
- * listeners, codon mappings, PDB file mappings
+ * Reset this object to its initial state by removing all registered
+ * listeners, codon mappings, PDB file mappings.
+ *
+ * Called only by Desktop and testng.
+ *
*/
public void resetAll()
{
@@ -1281,7 +1307,11 @@ public class StructureSelectionManager
}
}
- public void addSelectionListener(SelectionListener selecter)
+ public List getListeners() {
+ return sel_listeners;
+ }
+
+ public void addSelectionListener(SelectionListener selecter)
{
if (!sel_listeners.contains(selecter))
{
@@ -1329,41 +1359,23 @@ public class StructureSelectionManager
{
slis.viewPosition(startRes, endRes, startSeq, endSeq, source);
}
- ;
+
}
}
}
+
/**
- * release all references associated with this manager provider
+ * Removes the instance associated with this provider
*
- * @param jalviewLite
+ * @param provider
*/
- public static void release(StructureSelectionManagerProvider jalviewLite)
+
+ public static void release(StructureSelectionManagerProvider provider)
{
- // synchronized (instances)
- {
- if (instances == null)
- {
- return;
- }
- StructureSelectionManager mnger = (instances.get(jalviewLite));
- if (mnger != null)
- {
- instances.remove(jalviewLite);
- try
- {
- /* bsoares 2019-03-20 finalize deprecated, no apparent external
- * resources to close
- */
- // mnger.finalize();
- } catch (Throwable x)
- {
- }
- }
- }
+ getInstance().selectionManagers.remove(provider);
}
-
+
public void registerPDBEntry(PDBEntry pdbentry)
{
if (pdbentry.getFile() != null
diff --git a/src/jalview/urls/IdOrgSettings.java b/src/jalview/urls/IdOrgSettings.java
index 7dd1a19..7c38ab6 100644
--- a/src/jalview/urls/IdOrgSettings.java
+++ b/src/jalview/urls/IdOrgSettings.java
@@ -21,35 +21,46 @@
package jalview.urls;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+
/**
* Holds settings for identifiers.org e.g. url, download location
- *
- * @author $author$
- * @version $Revision$
*/
-public class IdOrgSettings
+public class IdOrgSettings implements ApplicationSingletonI
{
- private static String url;
+ private String url;
+
+ private String location;
+
+ private static IdOrgSettings getInstance()
+ {
+ return (IdOrgSettings) ApplicationSingletonProvider
+ .getInstance(IdOrgSettings.class);
+ }
- private static String location;
+ private IdOrgSettings()
+ {
+ // private singleton
+ }
public static void setUrl(String seturl)
{
- url = seturl;
+ getInstance().url = seturl;
}
public static void setDownloadLocation(String setloc)
{
- location = setloc;
+ getInstance().location = setloc;
}
public static String getUrl()
{
- return url;
+ return getInstance().url;
}
public static String getDownloadLocation()
{
- return location;
+ return getInstance().location;
}
}
diff --git a/src/jalview/urls/IdentifiersUrlProvider.java b/src/jalview/urls/IdentifiersUrlProvider.java
index 07eb23e..e898438 100644
--- a/src/jalview/urls/IdentifiersUrlProvider.java
+++ b/src/jalview/urls/IdentifiersUrlProvider.java
@@ -118,11 +118,6 @@ private HashMap readIdentifiers(String idFileName)
}
} catch (IOException | ParseException e)
{
- // unnecessary e.printStackTrace();
- // Note how in JavaScript we can grab the first bytes from any file reader.
- // Typical report here is "NetworkError" because the file does not exist.
- // "https://." is coming from System.getProperty("user.home"), but this could
- // be set by the page developer to anything, of course.
errorMessage = e.toString();
idData.clear();
}
diff --git a/src/jalview/util/MessageManager.java b/src/jalview/util/MessageManager.java
index bb94566..2a07616 100644
--- a/src/jalview/util/MessageManager.java
+++ b/src/jalview/util/MessageManager.java
@@ -57,8 +57,7 @@ public class MessageManager
// Locale.setDefault(loc);
/* Getting messages for GV */
log.info("Getting messages for lang: " + loc);
- Control control = Control.getControl(Control.FORMAT_PROPERTIES);
- rb = ResourceBundle.getBundle("lang.Messages", loc, control);
+ rb = ResourceBundle.getBundle("lang.Messages", Platform.getLocaleOrNone(loc), Control.getControl(Control.FORMAT_PROPERTIES));
// if (log.isLoggable(Level.FINEST))
// {
// // this might take a while, so we only do it if it will be shown
@@ -94,7 +93,7 @@ public class MessageManager
} catch (Exception e)
{
String msg = "I18N missing: " + loc + "\t" + key;
- logWarning(key, msg);
+ logWarning(key, msg);
}
return value;
}
@@ -169,8 +168,8 @@ public class MessageManager
} catch (Exception x)
{
String msg = "I18N missing key with root " + keyroot + ": " + loc + "\t"
- + smkey;
- logWarning(smkey, msg);
+ + smkey;
+ logWarning(smkey, msg);
}
return name;
}
@@ -183,10 +182,10 @@ public class MessageManager
*/
private static void logWarning(String key, String msg)
{
- if (!reportedMissing.contains(key))
- {
+ if (!reportedMissing.contains(key))
+ {
reportedMissing.add(key);
- log.info(msg);
- }
+ log.info(msg);
+ }
}
}
diff --git a/src/jalview/util/Platform.java b/src/jalview/util/Platform.java
index 6dbe549..371cd32 100644
--- a/src/jalview/util/Platform.java
+++ b/src/jalview/util/Platform.java
@@ -22,9 +22,7 @@ package jalview.util;
import java.awt.Component;
import java.awt.Dimension;
-import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
-import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.File;
@@ -34,8 +32,17 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
-import java.lang.reflect.Method;
import java.net.URL;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Date;
+import java.util.Locale;
+import java.util.Map;
import java.util.Properties;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
@@ -48,6 +55,7 @@ import org.json.simple.parser.ParseException;
import com.stevesoft.pat.Regex;
+import jalview.bin.Jalview;
import jalview.javascript.json.JSON;
import swingjs.api.JSUtilI;
@@ -56,7 +64,6 @@ import swingjs.api.JSUtilI;
*
* @author Jim Procter
*/
-
public class Platform
{
@@ -69,7 +76,6 @@ public class Platform
private static Boolean isHeadless = null;
private static swingjs.api.JSUtilI jsutil;
-
static
{
@@ -77,6 +83,9 @@ public class Platform
{
try
{
+ // this is ok - it's a highly embedded method in Java; the deprecation
+ // is
+ // really a recommended best practice.
jsutil = ((JSUtilI) Class.forName("swingjs.JSUtil").newInstance());
} catch (InstantiationException | IllegalAccessException
| ClassNotFoundException e)
@@ -230,14 +239,14 @@ public class Platform
*/
protected static boolean isControlDown(MouseEvent e, boolean aMac)
{
-
+
System.out.println(e.isPopupTrigger()
+ " " + ((SHORTCUT_KEY_MASK & e.getModifiersEx()) != 0)
+ " " + e.isControlDown());
return (aMac ? !e.isPopupTrigger()
&& (SHORTCUT_KEY_MASK & e.getModifiersEx()) != 0
: e.isControlDown());
- }
+ }
// BH: I don't know about that previous method. Here is what SwingJS uses.
// Notice the distinction in mouse events. (BUTTON3_MASK == META)
@@ -638,9 +647,14 @@ public class Platform
}
+ /**
+ * Allow for URL-line command arguments. Untested.
+ *
+ */
public static void getURLCommandArguments()
{
+ try {
/**
* Retrieve the first query field as command arguments to Jalview. Include
* only if prior to "?j2s" or "&j2s" or "#". Assign the applet's __Info.args
@@ -650,8 +664,11 @@ public class Platform
* decodeURI((document.location.href.replace("&","?").split("?j2s")[0]
* + "?").split("?")[1].split("#")[0]); a &&
* (J2S.thisApplet.__Info.args = a.split(" "));
+ *
+ * System.out.println("URL arguments: " + a);
*/
-
+ } catch (Throwable t) {
+ }
}
/**
@@ -804,17 +821,17 @@ public class Platform
{
if (isJS)
{
- jsutil.setAppletAttribute("app", j);
+ jsutil.setAppClass(j);
}
}
/**
*
- * If this frame ia embedded in a web page, return a known type.
+ * If this frame is embedded in a web page, return a known type.
*
* @param frame
* a JFrame or JInternalFrame
- * @param type
+ * @param type "name", "node", "init", "dim", or any DOM attribute, such as "id"
* @return null if frame is not embedded.
*/
public static Object getEmbeddedAttribute(Component frame, String type)
@@ -844,4 +861,160 @@ public class Platform
return (isJS ? jsutil.getCodeBase() : null);
}
+ public static String getUserPath(String subpath)
+ {
+ char sep = File.separatorChar;
+ return System.getProperty("user.home") + sep
+ + subpath.replace('/', sep);
+ }
+
+ /**
+ * This method enables checking if a cached file has exceeded a certain
+ * threshold(in days)
+ *
+ * @param file
+ * the cached file
+ * @param noOfDays
+ * the threshold in days
+ * @return
+ */
+ public static boolean isFileOlderThanThreshold(File file, int noOfDays)
+ {
+ if (isJS())
+ {
+ // not meaningful in SwingJS -- this is a session-specific temp file. It
+ // doesn't have a timestamp.
+ return false;
+ }
+ Path filePath = file.toPath();
+ BasicFileAttributes attr;
+ int diffInDays = 0;
+ try
+ {
+ attr = Files.readAttributes(filePath, BasicFileAttributes.class);
+ diffInDays = (int) ((new Date().getTime()
+ - attr.lastModifiedTime().toMillis())
+ / (1000 * 60 * 60 * 24));
+ // System.out.println("Diff in days : " + diffInDays);
+ } catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ return noOfDays <= diffInDays;
+ }
+
+ /**
+ * Get the leading integer part of a string that begins with an integer.
+ *
+ * @param input
+ * - the string input to process
+ * @param failValue
+ * - value returned if unsuccessful
+ * @return
+ */
+ public static int getLeadingIntegerValue(String input, int failValue)
+ {
+ if (input == null)
+ {
+ return failValue;
+ }
+ if (isJS)
+ {
+ int val = /** @j2sNative 1 ? parseInt(input) : */
+ 0;
+ return (val == val + 0 ? val : failValue);
+ }
+ // JavaScript does not support Regex ? lookahead
+ String[] parts = input.split("(?=\\D)(?<=\\d)");
+ if (parts != null && parts.length > 0 && parts[0].matches("[0-9]+"))
+ {
+ return Integer.valueOf(parts[0]);
+ }
+ return failValue;
+ }
+
+ public static Map getAppletInfoAsMap()
+ {
+ return (isJS ? jsutil.getAppletInfoAsMap() : null);
+ }
+
+ /**
+ * Get the SwingJS applet ID and combine that with the frameType
+ *
+ * @param frameType
+ * "alignment", "desktop", etc., or null
+ * @return
+ */
+ public static String getAppID(String frameType)
+ {
+
+ String id = Jalview.getInstance().j2sAppletID;
+ if (id == null)
+ {
+ Jalview.getInstance().j2sAppletID = id = (isJS ? (String) jsutil
+ .getAppletAttribute("_id") : "jalview");
+ }
+ return id + (frameType == null ? "" : "-" + frameType);
+ }
+
+
+ /**
+ * Option to avoid unnecessary seeking of nonexistent resources in JavaScript.
+ * Works in Java as well.
+ *
+ * @param loc
+ * @return
+ */
+ public static Locale getLocaleOrNone(Locale loc)
+ {
+ return (isJS && loc.getLanguage() == "en" ? new Locale("") : loc);
+ }
+
+ /**
+ * From UrlDownloadClient; trivial in JavaScript; painful in Java.
+ *
+ * @param urlstring
+ * @param outfile
+ * @throws IOException
+ */
+ public static void download(String urlstring, String outfile)
+ throws IOException
+ {
+ Path temp = null;
+ try (InputStream is = new URL(urlstring).openStream())
+ {
+ if (isJS)
+ { // so much easier!
+ streamToFile(is, new File(outfile));
+ return;
+ }
+ temp = Files.createTempFile(".jalview_", ".tmp");
+ try (FileOutputStream fos = new FileOutputStream(temp.toString());
+ ReadableByteChannel rbc = Channels.newChannel(is))
+ {
+ fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
+ // copy tempfile to outfile once our download completes
+ // incase something goes wrong
+ Files.copy(temp, Paths.get(outfile),
+ StandardCopyOption.REPLACE_EXISTING);
+ }
+ } catch (IOException e)
+ {
+ throw e;
+ } finally
+ {
+ try
+ {
+ if (temp != null)
+ {
+ Files.deleteIfExists(temp);
+ }
+ } catch (IOException e)
+ {
+ System.out.println("Exception while deleting download temp file: "
+ + e.getMessage());
+ }
+ }
+ }
+
}
diff --git a/src/jalview/viewmodel/AlignmentViewport.java b/src/jalview/viewmodel/AlignmentViewport.java
index 4f399f0..4148c72 100644
--- a/src/jalview/viewmodel/AlignmentViewport.java
+++ b/src/jalview/viewmodel/AlignmentViewport.java
@@ -83,6 +83,9 @@ import java.util.Map;
public abstract class AlignmentViewport
implements AlignViewportI, CommandListener, VamsasSource
{
+ public static final String PROPERTY_ALIGNMENT = "alignment";
+ public static final String PROPERTY_SEQUENCE = "sequence";
+
protected ViewportRanges ranges;
protected ViewStyleI viewStyle = new ViewStyle();
@@ -605,10 +608,31 @@ public abstract class AlignmentViewport
protected ColumnSelection colSel = new ColumnSelection();
- public boolean autoCalculateConsensus = true;
+ protected boolean autoCalculateConsensusAndConservation = true;
+
+ public boolean getAutoCalculateConsensusAndConservation()
+ { // BH 2019.07.24
+ return autoCalculateConsensusAndConservation;
+ }
+
+ public void setAutoCalculateConsensusAndConservation(boolean b)
+ {
+ autoCalculateConsensusAndConservation = b;
+ }
protected boolean autoCalculateStrucConsensus = true;
+ public boolean getAutoCalculateStrucConsensus()
+ { // BH 2019.07.24
+ return autoCalculateStrucConsensus;
+ }
+
+ public void setAutoCalculateStrucConsensus(boolean b)
+ {
+ autoCalculateStrucConsensus = b;
+ }
+
+
protected boolean ignoreGapsInConsensusCalculation = false;
protected ResidueShaderI residueShading = new ResidueShader();
@@ -824,7 +848,7 @@ public abstract class AlignmentViewport
// see note in mantis : issue number 8585
if (alignment.isNucleotide()
|| (conservation == null && quality == null)
- || !autoCalculateConsensus)
+ || !autoCalculateConsensusAndConservation)
{
return;
}
@@ -842,7 +866,7 @@ public abstract class AlignmentViewport
public void updateConsensus(final AlignmentViewPanel ap)
{
// see note in mantis : issue number 8585
- if (consensus == null || !autoCalculateConsensus)
+ if (consensus == null || !autoCalculateConsensusAndConservation)
{
return;
}
@@ -1275,21 +1299,22 @@ public abstract class AlignmentViewport
* checks current colsel against record of last hash value, and optionally
* updates record.
*
- * @param b
+ * @param updateHash
* update the record of last hash value
* @return true if colsel changed since last call (when b is true)
*/
- public boolean isColSelChanged(boolean b)
+ public boolean isColSelChanged(boolean updateHash)
{
int hc = (colSel == null || colSel.isEmpty()) ? -1 : colSel.hashCode();
if (hc != -1 && hc != colselhash)
{
- if (b)
+ if (updateHash)
{
colselhash = hc;
}
return true;
}
+ notifySequence();
return false;
}
@@ -1350,22 +1375,6 @@ public abstract class AlignmentViewport
}
}
- /**
- * Property change listener for changes in alignment
- *
- * @param prop
- * DOCUMENT ME!
- * @param oldvalue
- * DOCUMENT ME!
- * @param newvalue
- * DOCUMENT ME!
- */
- public void firePropertyChange(String prop, Object oldvalue,
- Object newvalue)
- {
- changeSupport.firePropertyChange(prop, oldvalue, newvalue);
- }
-
// common hide/show column stuff
public void hideSelectedColumns()
@@ -1430,13 +1439,14 @@ public abstract class AlignmentViewport
ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
- firePropertyChange("alignment", null, alignment.getSequences());
// used to set hasHiddenRows/hiddenRepSequences here, after the property
// changed event
+ notifySequence();
sendSelection();
}
}
+
public void showSequence(int index)
{
int startSeq = ranges.getStartSeq();
@@ -1459,8 +1469,7 @@ public abstract class AlignmentViewport
}
ranges.setStartEndSeq(startSeq, endSeq + tmp.size());
-
- firePropertyChange("alignment", null, alignment.getSequences());
+ notifyAlignment();
sendSelection();
}
}
@@ -1494,7 +1503,7 @@ public abstract class AlignmentViewport
setSequenceAnnotationsVisible(seq[i], false);
}
ranges.setStartSeq(startSeq);
- firePropertyChange("alignment", null, alignment.getSequences());
+ notifyAlignment();
}
}
@@ -1859,11 +1868,11 @@ public abstract class AlignmentViewport
{
alignment.padGaps();
}
- if (autoCalculateConsensus)
+ if (autoCalculateConsensusAndConservation)
{
updateConsensus(ap);
}
- if (hconsensus != null && autoCalculateConsensus)
+ if (hconsensus != null && autoCalculateConsensusAndConservation)
{
updateConservation(ap);
}
@@ -3078,4 +3087,22 @@ public abstract class AlignmentViewport
codingComplement.setUpdateStructures(needToUpdateStructureViews);
}
}
+
+
+ /**
+ * Notify TreePanel and AlignmentPanel of some sort of alignment change.
+ */
+ public void notifyAlignment()
+ {
+ changeSupport.firePropertyChange(PROPERTY_ALIGNMENT, null, alignment.getSequences());
+ }
+
+ /**
+ * Notify AlignmentPanel of a sequence column selection or visibility changes.
+ */
+ public void notifySequence()
+ {
+ changeSupport.firePropertyChange(PROPERTY_SEQUENCE, null, null);
+ }
+
}
diff --git a/src/jalview/viewmodel/ViewportRanges.java b/src/jalview/viewmodel/ViewportRanges.java
index 4f671da..b96ac28 100644
--- a/src/jalview/viewmodel/ViewportRanges.java
+++ b/src/jalview/viewmodel/ViewportRanges.java
@@ -112,7 +112,7 @@ public class ViewportRanges extends ViewportProperties
* Set first residue visible in the viewport, and retain the current width.
* Fires a property change event.
*
- * @param res
+ * @param res
* residue position
*/
public void setStartRes(int res)
@@ -136,13 +136,25 @@ public class ViewportRanges extends ViewportProperties
int[] oldvalues = updateStartEndRes(start, end);
int oldstartres = oldvalues[0];
int oldendres = oldvalues[1];
+
+ if (oldstartres == startRes && oldendres == endRes)
+ {
+ return; // BH 2019.07.27 standard check for no changes
+ }
+ // "STARTRES" is a misnomer here -- really "STARTORENDRES"
+ // note that this could be "no change" if the range is just being expanded
changeSupport.firePropertyChange(STARTRES, oldstartres, startRes);
if (oldstartres == startRes)
{
+ // only caught in ViewportRangesTest
+ // No listener cares about this
+ // "ENDRES" is a misnomer here -- really "ENDONLYRES"
+ // BH 2019.07.27 adds end change check
+ // fire only if only the end is changed
// event won't be fired if start positions are same
// fire an event for the end positions in case they changed
- changeSupport.firePropertyChange(ENDRES, oldendres, endRes);
+ changeSupport.firePropertyChange(ENDRES, oldendres, endRes);
}
}
@@ -224,7 +236,6 @@ public class ViewportRanges extends ViewportProperties
*/
public void setStartEndSeq(int start, int end)
{
- // System.out.println("ViewportRange setStartEndSeq " + start + " " + end);
int[] oldvalues = updateStartEndSeq(start, end);
int oldstartseq = oldvalues[0];
int oldendseq = oldvalues[1];
@@ -250,34 +261,16 @@ public class ViewportRanges extends ViewportProperties
*/
private int[] updateStartEndSeq(int start, int end)
{
- int oldstartseq = this.startSeq;
- int visibleHeight = getVisibleAlignmentHeight();
- if (start > visibleHeight - 1)
- {
- startSeq = Math.max(visibleHeight - 1, 0);
- }
- else if (start < 0)
- {
- startSeq = 0;
- }
- else
- {
- startSeq = start;
- }
+// if (end == 3 && this.endSeq == 14 || end == 13 && this.endSeq == 3) {
+// new NullPointerException().printStackTrace(System.out);
+// System.out.println("ViewportRange updateStartEndSeq " + start + " " + end + " " + Thread.currentThread());
+// }
+ int oldstartseq = this.startSeq;
int oldendseq = this.endSeq;
- if (end >= visibleHeight)
- {
- endSeq = Math.max(visibleHeight - 1, 0);
- }
- else if (end < 0)
- {
- endSeq = 0;
- }
- else
- {
- endSeq = end;
- }
+ int max = getVisibleAlignmentHeight() - 1;
+ startSeq = Math.max(0, Math.min(start, max));
+ endSeq = Math.max(0, Math.min(end, max));
return new int[] { oldstartseq, oldendseq };
}
@@ -392,21 +385,15 @@ public class ViewportRanges extends ViewportProperties
*/
public void setViewportStartAndWidth(int start, int w)
{
- int vpstart = start;
- if (vpstart < 0)
- {
- vpstart = 0;
- }
-
- /*
- * if not wrapped, don't leave white space at the right margin
- */
+ int vpstart = Math.max(0, start);
+
if (!wrappedMode)
{
- if ((w <= getVisibleAlignmentWidth())
- && (vpstart + w - 1 > getVisibleAlignmentWidth() - 1))
+ // if not wrapped, don't leave white space at the right margin
+ int maxStart = getVisibleAlignmentWidth() - w;
+ if (maxStart >= 0)
{
- vpstart = getVisibleAlignmentWidth() - w;
+ vpstart = Math.min(vpstart, maxStart);
}
}
@@ -425,22 +412,15 @@ public class ViewportRanges extends ViewportProperties
*/
public void setViewportStartAndHeight(int start, int h)
{
- int vpstart = start;
-
- int visHeight = getVisibleAlignmentHeight();
- if (vpstart < 0)
- {
- vpstart = 0;
- }
- else if (h <= visHeight && vpstart + h > visHeight)
- // viewport height is less than the full alignment and we are running off
- // the bottom
+ int vpstart = Math.max(0, start);
+ int maxStart = getVisibleAlignmentHeight() - h;
+ if (maxStart > 0)
{
- vpstart = visHeight - h;
+ // can't start higher than vertical extent will allow
+ // (viewport height is less than the full alignment
+ // and we are running off the bottom)
+ vpstart = Math.min(vpstart, maxStart);
}
- // System.out.println("ViewportRanges setviewportStartAndHeight " + vpstart
- // + " " + start + " " + h + " " + getVisibleAlignmentHeight());
-
setStartEndSeq(vpstart, vpstart + h - 1);
}
@@ -797,4 +777,10 @@ public class ViewportRanges extends ViewportProperties
return maxScroll;
}
+
+
+ @Override
+ public String toString() {
+ return "[ViewportRange " + startSeq + "-" + endSeq + ", "+ startRes + "-" + endRes + "]";
+ }
}
diff --git a/src/jalview/workers/AlignCalcManager.java b/src/jalview/workers/AlignCalcManager.java
index 08ef3a2..c596f05 100644
--- a/src/jalview/workers/AlignCalcManager.java
+++ b/src/jalview/workers/AlignCalcManager.java
@@ -207,6 +207,10 @@ public class AlignCalcManager implements AlignCalcManagerI
}
}
+ public int getQueueLength() {
+ return inProgress.size();
+ }
+
@Override
public void registerWorker(AlignCalcWorkerI worker)
{
diff --git a/src/jalview/ws/SequenceFetcher.java b/src/jalview/ws/SequenceFetcher.java
index a480176..5c94faf 100644
--- a/src/jalview/ws/SequenceFetcher.java
+++ b/src/jalview/ws/SequenceFetcher.java
@@ -20,6 +20,8 @@
*/
package jalview.ws;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.ext.ensembl.EnsemblGene;
import jalview.ws.dbsources.EmblCdsSource;
import jalview.ws.dbsources.EmblSource;
@@ -39,8 +41,39 @@ import java.util.List;
* This implements the run-time discovery of sequence database clients.
*
*/
-public class SequenceFetcher extends ASequenceFetcher
+public class SequenceFetcher extends ASequenceFetcher implements ApplicationSingletonI
{
+ /*
+ * set a mock fetcher here for testing only - reset to null afterwards
+ */
+ private static SequenceFetcher mockFetcher;
+
+ /**
+ * Set the instance object to use (intended for unit testing with mock
+ * objects).
+ *
+ * Be sure to reset to null in the tearDown method of any tests!
+ *
+ * @param sf
+ */
+ public static void setMockFetcher(SequenceFetcher sf)
+ {
+ mockFetcher = sf;
+ }
+
+ /**
+ * Returns a new SequenceFetcher singleton, or a mock object if one has been
+ * set.
+ *
+ * @return
+ */
+ public static SequenceFetcher getInstance()
+ {
+ return mockFetcher != null ? mockFetcher
+ : (SequenceFetcher) ApplicationSingletonProvider
+ .getInstance(SequenceFetcher.class);
+ }
+
/**
* Thread safe construction of database proxies TODO: extend to a configurable
* database plugin mechanism where classes are instantiated by reflection and
diff --git a/src/jalview/ws/SequenceFetcherFactory.java b/src/jalview/ws/SequenceFetcherFactory.java
index 9cc4960..25144fc 100644
--- a/src/jalview/ws/SequenceFetcherFactory.java
+++ b/src/jalview/ws/SequenceFetcherFactory.java
@@ -24,29 +24,33 @@ import jalview.ws.seqfetcher.ASequenceFetcher;
public class SequenceFetcherFactory
{
-
- private static SequenceFetcher instance;
-
- /**
- * Returns a new SequenceFetcher object, or a mock object if one has been set
- *
- * @return
- */
- public static ASequenceFetcher getSequenceFetcher()
- {
- return instance == null ? new SequenceFetcher() : instance;
- }
-
- /**
- * Set the instance object to use (intended for unit testing with mock
- * objects).
- *
- * Be sure to reset to null in the tearDown method of any tests!
- *
- * @param sf
- */
- public static void setSequenceFetcher(SequenceFetcher sf)
- {
- instance = sf;
- }
+ // BH the two methods in this class merged into SequenceFetcher
}
+//public class SequenceFetcherFactory
+//{
+//
+// private static SequenceFetcher instance;
+//
+// /**
+// * Returns a new SequenceFetcher object, or a mock object if one has been set
+// *
+// * @return
+// */
+// public static ASequenceFetcher getSequenceFetcher()
+// {
+// return instance == null ? new SequenceFetcher() : instance;
+// }
+//
+// /**
+// * Set the instance object to use (intended for unit testing with mock
+// * objects).
+// *
+// * Be sure to reset to null in the tearDown method of any tests!
+// *
+// * @param sf
+// */
+// public static void setSequenceFetcher(SequenceFetcher sf)
+// {
+// instance = sf;
+// }
+//}
diff --git a/src/jalview/ws/jws1/Discoverer.java b/src/jalview/ws/jws1/Discoverer.java
index bee9fad..6aa3f48 100644
--- a/src/jalview/ws/jws1/Discoverer.java
+++ b/src/jalview/ws/jws1/Discoverer.java
@@ -20,11 +20,15 @@
*/
package jalview.ws.jws1;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+import jalview.gui.AlignmentPanel;
import jalview.gui.JvOptionPane;
import jalview.util.MessageManager;
import java.net.URL;
import java.util.Hashtable;
+import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;
@@ -34,8 +38,19 @@ import ext.vamsas.RegistryServiceSoapBindingStub;
import ext.vamsas.ServiceHandle;
import ext.vamsas.ServiceHandles;
-public class Discoverer implements Runnable
+public class Discoverer implements Runnable, ApplicationSingletonI
{
+
+ public static Discoverer getInstance()
+ {
+ return (Discoverer) ApplicationSingletonProvider.getInstance(Discoverer.class);
+ }
+
+ private Discoverer()
+ {
+ // use getInstance()
+ }
+
ext.vamsas.IRegistry registry; // the root registry service.
private java.beans.PropertyChangeSupport changeSupport = new java.beans.PropertyChangeSupport(
@@ -110,20 +125,24 @@ public class Discoverer implements Runnable
return server;
}
- static private java.net.URL RootServiceURL = null;
+ private java.net.URL RootServiceURL = null;
- static public Vector ServiceURLList = null;
+ private Vector ServiceURLList = null;
- static private boolean reallyDiscoverServices = true;
+ public Vector getServiceURLList() {
+ return ServiceURLList;
+ }
+
+ private boolean reallyDiscoverServices = true;
- public static java.util.Hashtable> services = null;
+ private java.util.Hashtable> services = null;
// stored by
// abstractServiceType
// string
- public static java.util.Vector serviceList = null;
+ public java.util.Vector serviceList = null;
- static private Vector getDiscoveryURLS()
+ private Vector getDiscoveryURLS()
{
Vector urls = new Vector<>();
String RootServiceURLs = jalview.bin.Cache.getDefault("DISCOVERY_URLS",
@@ -176,10 +195,16 @@ public class Discoverer implements Runnable
*/
static public void doDiscovery()
{
+ getInstance().discovery();
+ }
+
+ private void discovery()
+ {
jalview.bin.Cache.log
.debug("(Re)-Initialising the discovery URL list.");
try
{
+ Discoverer d = getInstance();
reallyDiscoverServices = jalview.bin.Cache
.getDefault("DISCOVERY_START", false);
if (reallyDiscoverServices)
@@ -246,9 +271,9 @@ public class Discoverer implements Runnable
// JBPNote - should do this a better way!
if (f.getFaultReason().indexOf("(407)") > -1)
{
- if (jalview.gui.Desktop.desktop != null)
+ if (jalview.gui.Desktop.getDesktopPane() != null)
{
- JvOptionPane.showMessageDialog(jalview.gui.Desktop.desktop,
+ JvOptionPane.showMessageDialog(jalview.gui.Desktop.getDesktopPane(),
MessageManager.getString("label.set_proxy_settings"),
MessageManager
.getString("label.proxy_authorization_failed"),
@@ -284,7 +309,7 @@ public class Discoverer implements Runnable
* Hashtable
* @return boolean
*/
- static private boolean buildServiceLists(ServiceHandle[] sh,
+ private boolean buildServiceLists(ServiceHandle[] sh,
Vector cat,
Hashtable> sscat)
{
@@ -395,10 +420,32 @@ public class Discoverer implements Runnable
/**
* binding service abstract name to handler class
*/
- private static Hashtable serviceClientBindings;
+ private Hashtable serviceClientBindings;
public static WS1Client getServiceClient(ServiceHandle sh)
{
+ return getInstance().getClient(sh);
+ }
+
+ /**
+ * notes on discovery service 1. need to allow multiple discovery source urls.
+ * 2. user interface to add/control list of urls in preferences notes on
+ * wsclient discovery 1. need a classpath property with list of additional
+ * plugin directories 2. optional config to cite specific bindings between
+ * class name and Abstract service name. 3. precedence for automatic discovery
+ * by using getAbstractName for WSClient - user added plugins override default
+ * plugins ? notes on wsclient gui code for gui attachment now moved to
+ * wsclient implementation. Needs more abstraction but approach seems to work.
+ * is it possible to 'generalise' the data retrieval calls further ? current
+ * methods are very specific (gatherForMSA or gatherForSeqOrMsaSecStrPred),
+ * new methods for conservation (group or alignment), treecalc (aligned
+ * profile), seqannot (sequences selected from dataset, annotation back to
+ * dataset).
+ *
+ */
+
+ private WS1Client getClient(ServiceHandle sh)
+ {
if (serviceClientBindings == null)
{
// get a list from Config or create below
@@ -421,20 +468,9 @@ public class Discoverer implements Runnable
}
return instance;
}
- /**
- * notes on discovery service 1. need to allow multiple discovery source urls.
- * 2. user interface to add/control list of urls in preferences notes on
- * wsclient discovery 1. need a classpath property with list of additional
- * plugin directories 2. optional config to cite specific bindings between
- * class name and Abstract service name. 3. precedence for automatic discovery
- * by using getAbstractName for WSClient - user added plugins override default
- * plugins ? notes on wsclient gui code for gui attachment now moved to
- * wsclient implementation. Needs more abstraction but approach seems to work.
- * is it possible to 'generalise' the data retrieval calls further ? current
- * methods are very specific (gatherForMSA or gatherForSeqOrMsaSecStrPred),
- * new methods for conservation (group or alignment), treecalc (aligned
- * profile), seqannot (sequences selected from dataset, annotation back to
- * dataset).
- *
- */
+
+ public static Hashtable> getServices()
+ {
+ return getInstance().services;
+ }
}
diff --git a/src/jalview/ws/jws1/JPredClient.java b/src/jalview/ws/jws1/JPredClient.java
index 3b7bdb6..1c625fa 100644
--- a/src/jalview/ws/jws1/JPredClient.java
+++ b/src/jalview/ws/jws1/JPredClient.java
@@ -304,7 +304,7 @@ public class JPredClient extends WS1Client
WsURL = "http://www.compbio.dundee.ac.uk/JalviewWS/services/jpred";
WebserviceInfo wsInfo = new WebserviceInfo(WebServiceJobTitle,
- WebServiceReference, true);
+ WebServiceReference, Desktop.FRAME_MAKE_VISIBLE);
return wsInfo;
}
@@ -323,7 +323,7 @@ public class JPredClient extends WS1Client
} catch (Exception ex)
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.secondary_structure_prediction_service_couldnt_be_located",
new String[]
diff --git a/src/jalview/ws/jws1/MsaWSClient.java b/src/jalview/ws/jws1/MsaWSClient.java
index 4a09625..e97d309 100644
--- a/src/jalview/ws/jws1/MsaWSClient.java
+++ b/src/jalview/ws/jws1/MsaWSClient.java
@@ -78,7 +78,7 @@ public class MsaWSClient extends WS1Client
alignFrame = _alignFrame;
if (!sh.getAbstractName().equals("MsaWS"))
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.service_called_is_not_msa_service",
new String[]
@@ -91,7 +91,7 @@ public class MsaWSClient extends WS1Client
if ((wsInfo = setWebService(sh)) == null)
{
- JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(), MessageManager
.formatMessage("label.msa_service_is_unknown", new String[]
{ sh.getName() }),
MessageManager.getString("label.internal_jalview_error"),
diff --git a/src/jalview/ws/jws1/SeqSearchWSClient.java b/src/jalview/ws/jws1/SeqSearchWSClient.java
index 53338d3..cb965f0 100644
--- a/src/jalview/ws/jws1/SeqSearchWSClient.java
+++ b/src/jalview/ws/jws1/SeqSearchWSClient.java
@@ -84,7 +84,7 @@ public class SeqSearchWSClient extends WS1Client
// name to service client name
if (!sh.getAbstractName().equals(this.getServiceActionKey()))
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.service_called_is_not_seq_search_service",
new String[]
@@ -97,7 +97,7 @@ public class SeqSearchWSClient extends WS1Client
if ((wsInfo = setWebService(sh)) == null)
{
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.seq_search_service_is_unknown", new String[]
{ sh.getName() }),
diff --git a/src/jalview/ws/jws1/WS1Client.java b/src/jalview/ws/jws1/WS1Client.java
index 6fa41fc..7bffe43 100644
--- a/src/jalview/ws/jws1/WS1Client.java
+++ b/src/jalview/ws/jws1/WS1Client.java
@@ -21,6 +21,7 @@
package jalview.ws.jws1;
import jalview.gui.AlignFrame;
+import jalview.gui.Desktop;
import jalview.gui.WebserviceInfo;
import jalview.util.MessageManager;
import jalview.ws.WSClient;
@@ -92,8 +93,8 @@ public abstract class WS1Client extends WSClient
WebserviceInfo wsInfo = null;
if (!headless)
{
- wsInfo = new WebserviceInfo(WebServiceJobTitle, WebServiceReference,
- true);
+ wsInfo = new WebserviceInfo(WebServiceJobTitle, WebServiceReference,
+ Desktop.FRAME_MAKE_VISIBLE);
}
return wsInfo;
}
diff --git a/src/jalview/ws/jws2/Jws2Client.java b/src/jalview/ws/jws2/Jws2Client.java
index 0f1a25e..004a845 100644
--- a/src/jalview/ws/jws2/Jws2Client.java
+++ b/src/jalview/ws/jws2/Jws2Client.java
@@ -154,8 +154,8 @@ public abstract class Jws2Client extends jalview.ws.WSClient
return new WebserviceInfo(WebServiceJobTitle,
WebServiceJobTitle + " using service hosted at "
+ serv.hosturl + "\n"
- + (serv.description != null ? serv.description : ""),
- false);
+ + (serv.description != null ? serv.description : ""),
+ Desktop.FRAME_NOT_VISIBLE);
}
return null;
}
@@ -398,7 +398,7 @@ public abstract class Jws2Client extends jalview.ws.WSClient
{
// check service is actually in the list of currently avaialable
// services
- if (!Jws2Discoverer.getDiscoverer().getServices().contains(service))
+ if (!Jws2Discoverer.getInstance().getServices().contains(service))
{
// it isn't ..
service = null;
@@ -408,7 +408,7 @@ public abstract class Jws2Client extends jalview.ws.WSClient
if (service == null)
{
// get the default service for AACon
- service = Jws2Discoverer.getDiscoverer().getPreferredServiceFor(null,
+ service = Jws2Discoverer.getInstance().getPreferredServiceFor(null,
aaui.getServiceType());
}
if (service == null)
diff --git a/src/jalview/ws/jws2/Jws2Discoverer.java b/src/jalview/ws/jws2/Jws2Discoverer.java
index 516a719..255ef8f 100644
--- a/src/jalview/ws/jws2/Jws2Discoverer.java
+++ b/src/jalview/ws/jws2/Jws2Discoverer.java
@@ -21,6 +21,8 @@
package jalview.ws.jws2;
import jalview.bin.Cache;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.gui.AlignFrame;
import jalview.gui.Desktop;
import jalview.gui.JvSwingUtils;
@@ -60,8 +62,29 @@ import compbio.ws.client.Services;
* @author JimP
*
*/
-public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
+public class Jws2Discoverer
+ implements Runnable, WSMenuEntryProviderI, ApplicationSingletonI
{
+
+ /**
+ * Returns the singleton instance of this class.
+ *
+ * @return
+ */
+ public static Jws2Discoverer getInstance()
+ {
+ return (Jws2Discoverer) ApplicationSingletonProvider
+ .getInstance(Jws2Discoverer.class);
+ }
+
+ /**
+ * Private constructor enforces use of singleton via getDiscoverer()
+ */
+ private Jws2Discoverer()
+ {
+ // use getInstance();
+ }
+
public static final String COMPBIO_JABAWS = "http://www.compbio.dundee.ac.uk/jabaws";
/*
@@ -70,19 +93,14 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
private final static String JWS2HOSTURLS = "JWS2HOSTURLS";
/*
- * Singleton instance
- */
- private static Jws2Discoverer discoverer;
-
- /*
* Override for testing only
*/
- private static List testUrls = null;
+ private List testUrls = null;
// preferred url has precedence over others
private String preferredUrl;
- private PropertyChangeSupport changeSupport = new PropertyChangeSupport(
+ protected PropertyChangeSupport changeSupport = new PropertyChangeSupport(
this);
private Vector invalidServiceUrls = null;
@@ -103,13 +121,6 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
protected Vector services;
/**
- * Private constructor enforces use of singleton via getDiscoverer()
- */
- private Jws2Discoverer()
- {
- }
-
- /**
* change listeners are notified of "services" property changes
*
* @param listener
@@ -190,7 +201,7 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
oldthread = Thread.currentThread();
try
{
- Class foo = getClass().getClassLoader()
+ getClass().getClassLoader()
.loadClass("compbio.ws.client.Jws2Client");
} catch (ClassNotFoundException e)
{
@@ -583,36 +594,36 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
*/
public static void main(String[] args)
{
+ Jws2Discoverer instance = getInstance();
if (args.length > 0)
{
- testUrls = new ArrayList<>();
+ instance.testUrls = new ArrayList<>();
for (String url : args)
{
- testUrls.add(url);
+ instance.testUrls.add(url);
}
}
- Thread runner = getDiscoverer()
- .startDiscoverer(new PropertyChangeListener()
- {
+ Thread runner = instance.startDiscoverer(new PropertyChangeListener()
+ {
- @Override
- public void propertyChange(PropertyChangeEvent evt)
- {
- if (getDiscoverer().services != null)
- {
- System.out.println("Changesupport: There are now "
- + getDiscoverer().services.size() + " services");
- int i = 1;
- for (Jws2Instance instance : getDiscoverer().services)
- {
- System.out.println("Service " + i++ + " "
- + instance.getClass() + "@" + instance.getHost()
- + ": " + instance.getActionText());
- }
+ @Override
+ public void propertyChange(PropertyChangeEvent evt)
+ {
+ if (getInstance().services != null)
+ {
+ System.out.println("Changesupport: There are now "
+ + getInstance().services.size() + " services");
+ int i = 1;
+ for (Jws2Instance instance : getInstance().services)
+ {
+ System.out.println("Service " + i++ + " " + instance.getClass()
+ + "@" + instance.getHost() + ": "
+ + instance.getActionText());
+ }
- }
- }
- });
+ }
+ }
+ });
while (runner.isAlive())
{
try
@@ -630,20 +641,6 @@ public class Jws2Discoverer implements Runnable, WSMenuEntryProviderI
}
}
- /**
- * Returns the singleton instance of this class.
- *
- * @return
- */
- public static Jws2Discoverer getDiscoverer()
- {
- if (discoverer == null)
- {
- discoverer = new Jws2Discoverer();
- }
- return discoverer;
- }
-
public boolean hasServices()
{
return !running && services != null && services.size() > 0;
diff --git a/src/jalview/ws/jws2/MsaWSClient.java b/src/jalview/ws/jws2/MsaWSClient.java
index 23c6949..319252a 100644
--- a/src/jalview/ws/jws2/MsaWSClient.java
+++ b/src/jalview/ws/jws2/MsaWSClient.java
@@ -107,7 +107,7 @@ public class MsaWSClient extends Jws2Client
if (!(sh.service instanceof MsaWS))
{
// redundant at mo - but may change
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
MessageManager.formatMessage(
"label.service_called_is_not_msa_service",
new String[]
@@ -120,7 +120,7 @@ public class MsaWSClient extends Jws2Client
server = (MsaWS) sh.service;
if ((wsInfo = setWebService(sh, false)) == null)
{
- JvOptionPane.showMessageDialog(Desktop.desktop, MessageManager
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(), MessageManager
.formatMessage("label.msa_service_is_unknown", new String[]
{ sh.serviceType }),
MessageManager.getString("label.internal_jalview_error"),
diff --git a/src/jalview/ws/jws2/SequenceAnnotationWSClient.java b/src/jalview/ws/jws2/SequenceAnnotationWSClient.java
index 45bddac..67e3338 100644
--- a/src/jalview/ws/jws2/SequenceAnnotationWSClient.java
+++ b/src/jalview/ws/jws2/SequenceAnnotationWSClient.java
@@ -242,7 +242,7 @@ public class SequenceAnnotationWSClient extends Jws2Client
@Override
public void actionPerformed(ActionEvent arg0)
{
- Desktop.instance.showUrl(service.docUrl);
+ Desktop.getInstance().showUrl(service.docUrl);
}
});
annotservice.setToolTipText(
diff --git a/src/jalview/ws/jws2/jabaws2/Jws2Instance.java b/src/jalview/ws/jws2/jabaws2/Jws2Instance.java
index e092192..7954db0 100644
--- a/src/jalview/ws/jws2/jabaws2/Jws2Instance.java
+++ b/src/jalview/ws/jws2/jabaws2/Jws2Instance.java
@@ -186,7 +186,7 @@ public class Jws2Instance implements AutoCloseable
try
{
paramStore = new JabaParamStore(this,
- (Desktop.instance != null ? Desktop.getUserParameterStore()
+ (Desktop.getInstance() != null ? Desktop.getUserParameterStore()
: null));
} catch (Exception ex)
{
diff --git a/src/jalview/ws/jws2/jabaws2/Jws2InstanceFactory.java b/src/jalview/ws/jws2/jabaws2/Jws2InstanceFactory.java
index 623b8de..1983ff5 100644
--- a/src/jalview/ws/jws2/jabaws2/Jws2InstanceFactory.java
+++ b/src/jalview/ws/jws2/jabaws2/Jws2InstanceFactory.java
@@ -20,6 +20,8 @@
*/
package jalview.ws.jws2.jabaws2;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.ws.jws2.AAConClient;
import jalview.ws.jws2.RNAalifoldClient;
import jalview.ws.uimodel.AlignAnalysisUIText;
@@ -29,11 +31,23 @@ import java.util.HashSet;
import compbio.data.msa.JABAService;
-public class Jws2InstanceFactory
+public class Jws2InstanceFactory implements ApplicationSingletonI
{
- private static HashMap aaConGUI;
- private static HashSet ignoreGUI;
+ private Jws2InstanceFactory()
+ {
+ // private singleton
+ }
+
+ private static Jws2InstanceFactory getInstance()
+ {
+ return (Jws2InstanceFactory) ApplicationSingletonProvider
+ .getInstance(Jws2InstanceFactory.class);
+ }
+
+ private HashMap aaConGUI;
+
+ private HashSet ignoreGUI;
private static String category_rewrite(String cat_name)
{
@@ -42,17 +56,17 @@ public class Jws2InstanceFactory
: cat_name;
}
- private static void init()
+ private void init()
{
if (aaConGUI == null)
{
- aaConGUI = new HashMap();
+ aaConGUI = new HashMap<>();
aaConGUI.put(compbio.ws.client.Services.AAConWS.toString(),
AAConClient.getAlignAnalysisUITest());
aaConGUI.put(compbio.ws.client.Services.RNAalifoldWS.toString(),
RNAalifoldClient.getAlignAnalysisUITest());
// ignore list for JABAWS services not supported in jalview ...
- ignoreGUI = new HashSet();
+ ignoreGUI = new HashSet<>();
}
}
@@ -65,8 +79,8 @@ public class Jws2InstanceFactory
*/
public static boolean ignoreService(String serviceType)
{
- init();
- return (ignoreGUI.contains(serviceType.toString()));
+ getInstance().init();
+ return (getInstance().ignoreGUI.contains(serviceType.toString()));
}
/**
@@ -84,10 +98,10 @@ public class Jws2InstanceFactory
String serviceType, String name, String description,
JABAService service)
{
- init();
+ getInstance().init();
Jws2Instance svc = new Jws2Instance(jwsservers, serviceType,
category_rewrite(name), description, service);
- svc.aaui = aaConGUI.get(serviceType.toString());
+ svc.aaui = getInstance().aaConGUI.get(serviceType.toString());
return svc;
}
diff --git a/src/jalview/ws/rest/RestClient.java b/src/jalview/ws/rest/RestClient.java
index a71b70d..5d1a288 100644
--- a/src/jalview/ws/rest/RestClient.java
+++ b/src/jalview/ws/rest/RestClient.java
@@ -20,6 +20,8 @@
*/
package jalview.ws.rest;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
import jalview.bin.Cache;
import jalview.datamodel.AlignmentView;
import jalview.gui.AlignFrame;
@@ -49,8 +51,27 @@ import javax.swing.event.MenuListener;
*
*/
public class RestClient extends WSClient
- implements WSClientI, WSMenuEntryProviderI
+implements WSClientI, WSMenuEntryProviderI, ApplicationSingletonI
{
+
+ @SuppressWarnings("unused")
+ private RestClient()
+ {
+ // accessed by ApplicationSingletonProvider
+ }
+
+
+private static RestClient getInstance()
+{
+return (RestClient) ApplicationSingletonProvider.getInstance(RestClient.class);
+}
+
+public static final String RSBS_SERVICES = "RSBS_SERVICES";
+
+
+ protected Vector services = null;
+
+
RestServiceDescription service;
public RestClient(RestServiceDescription rsd)
@@ -109,7 +130,7 @@ public class RestClient extends WSClient
if (!headless)
{
wsInfo = new WebserviceInfo(WebServiceJobTitle,
- WebServiceName + "\n" + WebServiceReference, true);
+ WebServiceName + "\n" + WebServiceReference, Desktop.FRAME_MAKE_VISIBLE);
wsInfo.setRenderAsHtml(true);
}
@@ -329,7 +350,7 @@ public class RestClient extends WSClient
else
{
// TODO: try to tell the user why the job couldn't be started.
- JvOptionPane.showMessageDialog(Desktop.desktop,
+ JvOptionPane.showMessageDialog(Desktop.getDesktopPane(),
(jobsthread.hasWarnings() ? jobsthread.getWarnings()
: MessageManager.getString(
"label.job_couldnt_be_started_check_input")),
@@ -399,12 +420,13 @@ public class RestClient extends WSClient
return true;
}
- protected static Vector services = null;
-
- public static final String RSBS_SERVICES = "RSBS_SERVICES";
-
public static RestClient[] getRestClients()
{
+ return getInstance().getClients();
+ }
+
+ private RestClient[] getClients()
+ {
if (services == null)
{
services = new Vector();
@@ -458,10 +480,11 @@ public class RestClient extends WSClient
{
if (rsbsUrls != null)
{
+
// TODO: consider validating services ?
- services = new Vector(rsbsUrls);
+ getInstance().services = new Vector(rsbsUrls);
StringBuffer sprop = new StringBuffer();
- for (String s : services)
+ for (String s : getInstance().services)
{
sprop.append(s);
}
diff --git a/src/jalview/ws/sifts/SiftsClient.java b/src/jalview/ws/sifts/SiftsClient.java
index 4fb9ca9..3ec6320 100644
--- a/src/jalview/ws/sifts/SiftsClient.java
+++ b/src/jalview/ws/sifts/SiftsClient.java
@@ -22,20 +22,15 @@ package jalview.ws.sifts;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.URL;
import java.net.URLConnection;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
-import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -101,8 +96,6 @@ public class SiftsClient implements SiftsClientI
*/
private jalview.datamodel.Mapping seqFromPdbMapping;
- private static final int BUFFER_SIZE = 4096;
-
public static final int UNASSIGNED = Integer.MIN_VALUE;
private static final int PDB_RES_POS = 0;
@@ -117,10 +110,15 @@ public class SiftsClient implements SiftsClientI
private final static String NEWLINE = System.lineSeparator();
+ private static final boolean GET_STREAM = false;
+ private static final boolean CACHE_FILE = true;
+
private String curSourceDBRef;
private HashSet curDBRefAccessionIdsString;
+ private boolean doCache = false;
+
private enum CoordinateSys
{
UNIPROT("UniProt"), PDB("PDBresnum"), PDBe("PDBe");
@@ -165,8 +163,31 @@ public class SiftsClient implements SiftsClientI
{
this.pdb = pdb;
this.pdbId = pdb.getId();
- File siftsFile = getSiftsFile(pdbId);
- siftsEntry = parseSIFTs(siftsFile);
+ if (doCache) {
+ File siftsFile = getSiftsFile(pdbId);
+ siftsEntry = parseSIFTs(siftsFile);
+ } else {
+ siftsEntry = parseSIFTSStreamFor(pdbId);
+ }
+ }
+
+ /**
+ * A more streamlined version of SIFT reading that allows for streaming of the data.
+ *
+ * @param pdbId
+ * @return
+ * @throws SiftsException
+ */
+ private static Entry parseSIFTSStreamFor(String pdbId) throws SiftsException
+ {
+ try
+ {
+ InputStream is = (InputStream) downloadSifts(pdbId, GET_STREAM);
+ return parseSIFTs(is);
+ } catch (Exception e)
+ {
+ throw new SiftsException(e.getMessage());
+ }
}
/**
@@ -180,8 +201,17 @@ public class SiftsClient implements SiftsClientI
*/
private Entry parseSIFTs(File siftFile) throws SiftsException
{
- try (InputStream in = new FileInputStream(siftFile);
- GZIPInputStream gzis = new GZIPInputStream(in);)
+ try (InputStream in = new FileInputStream(siftFile)) {
+ return parseSIFTs(in);
+ } catch (Exception e)
+ {
+ e.printStackTrace();
+ throw new SiftsException(e.getMessage());
+ }
+ }
+
+ private static Entry parseSIFTs(InputStream in) throws Exception {
+ try (GZIPInputStream gzis = new GZIPInputStream(in);)
{
// System.out.println("File : " + siftFile.getAbsolutePath());
JAXBContext jc = JAXBContext.newInstance("jalview.xml.binding.sifts");
@@ -190,10 +220,6 @@ public class SiftsClient implements SiftsClientI
Unmarshaller um = jc.createUnmarshaller();
JAXBElement jbe = um.unmarshal(streamReader, Entry.class);
return jbe.getValue();
- } catch (Exception e)
- {
- e.printStackTrace();
- throw new SiftsException(e.getMessage());
}
}
@@ -223,14 +249,14 @@ public class SiftsClient implements SiftsClientI
// The line below is required for unit testing... don't comment it out!!!
System.out.println(">>> SIFTS File already downloaded for " + pdbId);
- if (isFileOlderThanThreshold(siftsFile,
+ if (Platform.isFileOlderThanThreshold(siftsFile,
SiftsSettings.getCacheThresholdInDays()))
{
File oldSiftsFile = new File(siftsFileName + "_old");
siftsFile.renameTo(oldSiftsFile);
try
{
- siftsFile = downloadSiftsFile(pdbId.toLowerCase());
+ siftsFile = downloadSiftsFile(pdbId);
oldSiftsFile.delete();
return siftsFile;
} catch (IOException e)
@@ -247,7 +273,7 @@ public class SiftsClient implements SiftsClientI
}
try
{
- siftsFile = downloadSiftsFile(pdbId.toLowerCase());
+ siftsFile = downloadSiftsFile(pdbId);
} catch (IOException e)
{
throw new SiftsException(e.getMessage());
@@ -256,35 +282,6 @@ public class SiftsClient implements SiftsClientI
}
/**
- * This method enables checking if a cached file has exceeded a certain
- * threshold(in days)
- *
- * @param file
- * the cached file
- * @param noOfDays
- * the threshold in days
- * @return
- */
- public static boolean isFileOlderThanThreshold(File file, int noOfDays)
- {
- Path filePath = file.toPath();
- BasicFileAttributes attr;
- int diffInDays = 0;
- try
- {
- attr = Files.readAttributes(filePath, BasicFileAttributes.class);
- diffInDays = (int) ((new Date().getTime()
- - attr.lastModifiedTime().toMillis())
- / (1000 * 60 * 60 * 24));
- // System.out.println("Diff in days : " + diffInDays);
- } catch (IOException e)
- {
- e.printStackTrace();
- }
- return noOfDays <= diffInDays;
- }
-
- /**
* Download a SIFTs XML file for a given PDB Id from an FTP repository
*
* @param pdbId
@@ -294,53 +291,47 @@ public class SiftsClient implements SiftsClientI
*/
public static File downloadSiftsFile(String pdbId)
throws SiftsException, IOException
+ {
+ return (File) downloadSifts(pdbId, CACHE_FILE);
+ }
+
+ /**
+ * Download SIFTs XML with the option to cache a file or to get a stream.
+ *
+ * @param pdbId
+ * @param asFile
+ * @return
+ * @throws IOException
+ */
+ private static Object downloadSifts(String pdbId, boolean asFile) throws IOException
{
+ pdbId = pdbId.toLowerCase();
if (pdbId.contains(".cif"))
{
pdbId = pdbId.replace(".cif", "");
}
String siftFile = pdbId + ".xml.gz";
- String siftsFileFTPURL = SIFTS_FTP_BASE_URL + siftFile;
-
- /*
- * Download the file from URL to either
- * Java: directory of cached downloaded SIFTS files
- * Javascript: temporary 'file' (in-memory cache)
- */
+
File downloadTo = null;
- if (Platform.isJS())
- {
- downloadTo = File.createTempFile(siftFile, ".xml.gz");
- }
- else
+ if (asFile)
{
downloadTo = new File(
SiftsSettings.getSiftDownloadDirectory() + siftFile);
- File siftsDownloadDir = new File(
- SiftsSettings.getSiftDownloadDirectory());
+ File siftsDownloadDir = new File(SiftsSettings.getSiftDownloadDirectory());
if (!siftsDownloadDir.exists())
{
siftsDownloadDir.mkdirs();
}
}
-
- // System.out.println(">> Download ftp url : " + siftsFileFTPURL);
- // long now = System.currentTimeMillis();
+ String siftsFileFTPURL = SIFTS_FTP_BASE_URL + siftFile;
URL url = new URL(siftsFileFTPURL);
URLConnection conn = url.openConnection();
- InputStream inputStream = conn.getInputStream();
- FileOutputStream outputStream = new FileOutputStream(
- downloadTo);
- byte[] buffer = new byte[BUFFER_SIZE];
- int bytesRead = -1;
- while ((bytesRead = inputStream.read(buffer)) != -1)
- {
- outputStream.write(buffer, 0, bytesRead);
- }
- outputStream.close();
- inputStream.close();
- // System.out.println(">>> File downloaded : " + downloadedSiftsFile
- // + " took " + (System.currentTimeMillis() - now) + "ms");
+ InputStream is = conn.getInputStream();
+ if (!asFile)
+ return is;
+ // This is MUCH more efficent in JavaScript, as we already have the bytes
+ Platform.streamToFile(is, downloadTo);
+ is.close();
return downloadTo;
}
@@ -648,7 +639,7 @@ public class SiftsClient implements SiftsClientI
for (Residue residue : residues)
{
boolean isObserved = isResidueObserved(residue);
- int pdbeIndex = getLeadingIntegerValue(residue.getDbResNum(),
+ int pdbeIndex = Platform.getLeadingIntegerValue(residue.getDbResNum(),
UNASSIGNED);
int currSeqIndex = UNASSIGNED;
List cRefDbs = residue.getCrossRefDb();
@@ -660,7 +651,7 @@ public class SiftsClient implements SiftsClientI
pdbRefDb = cRefDb;
if (firstPDBResNum == UNASSIGNED)
{
- firstPDBResNum = getLeadingIntegerValue(cRefDb.getDbResNum(),
+ firstPDBResNum = Platform.getLeadingIntegerValue(cRefDb.getDbResNum(),
UNASSIGNED);
}
else
@@ -675,7 +666,7 @@ public class SiftsClient implements SiftsClientI
if (cRefDb.getDbCoordSys().equalsIgnoreCase(seqCoordSys.getName())
&& isAccessionMatched(cRefDb.getDbAccessionId()))
{
- currSeqIndex = getLeadingIntegerValue(cRefDb.getDbResNum(),
+ currSeqIndex = Platform.getLeadingIntegerValue(cRefDb.getDbResNum(),
UNASSIGNED);
if (pdbRefDb != null)
{
@@ -725,9 +716,9 @@ public class SiftsClient implements SiftsClientI
{
int resNum = (pdbRefDb == null)
- ? getLeadingIntegerValue(residue.getDbResNum(),
+ ? Platform.getLeadingIntegerValue(residue.getDbResNum(),
UNASSIGNED)
- : getLeadingIntegerValue(pdbRefDb.getDbResNum(),
+ : Platform.getLeadingIntegerValue(pdbRefDb.getDbResNum(),
UNASSIGNED);
if (isObserved)
@@ -748,29 +739,6 @@ public class SiftsClient implements SiftsClientI
}
/**
- * Get the leading integer part of a string that begins with an integer.
- *
- * @param input
- * - the string input to process
- * @param failValue
- * - value returned if unsuccessful
- * @return
- */
- static int getLeadingIntegerValue(String input, int failValue)
- {
- if (input == null)
- {
- return failValue;
- }
- String[] parts = input.split("(?=\\D)(?<=\\d)");
- if (parts != null && parts.length > 0 && parts[0].matches("[0-9]+"))
- {
- return Integer.valueOf(parts[0]);
- }
- return failValue;
- }
-
- /**
*
* @param chainId
* Target chain to populate mapping of its atom positions.
diff --git a/src/jalview/ws/sifts/SiftsSettings.java b/src/jalview/ws/sifts/SiftsSettings.java
index 5e2c526..029f48d 100644
--- a/src/jalview/ws/sifts/SiftsSettings.java
+++ b/src/jalview/ws/sifts/SiftsSettings.java
@@ -20,59 +20,79 @@
*/
package jalview.ws.sifts;
+import jalview.bin.ApplicationSingletonProvider;
+import jalview.bin.ApplicationSingletonProvider.ApplicationSingletonI;
+import jalview.util.Platform;
+
import java.util.Objects;
-public class SiftsSettings
+public class SiftsSettings implements ApplicationSingletonI
{
- private static boolean mapWithSifts = false;
+ /**
+ * Constructor
+ *
+ * @return
+ */
+ private static SiftsSettings getInstance()
+ {
+ return (SiftsSettings) ApplicationSingletonProvider
+ .getInstance(SiftsSettings.class);
+ }
+
+ private SiftsSettings()
+ {
+ // singleton; use getInstance()
+ }
+
+ private boolean mapWithSifts = false;
- private static String siftDownloadDirectory;
+ private String siftDownloadDirectory;
- private static int cacheThresholdInDays;
+ private int cacheThresholdInDays;
- private static int failSafePIDThreshold;
+ private int failSafePIDThreshold;
public static boolean isMapWithSifts()
{
- return mapWithSifts;
+ return getInstance().mapWithSifts;
}
public static void setMapWithSifts(boolean mapWithSifts)
{
- SiftsSettings.mapWithSifts = mapWithSifts;
+ getInstance().mapWithSifts = mapWithSifts;
}
public static String getSiftDownloadDirectory()
{
- return siftDownloadDirectory;
+ return getInstance().siftDownloadDirectory;
}
public static void setSiftDownloadDirectory(String siftDownloadDirectory)
{
- SiftsSettings.siftDownloadDirectory = siftDownloadDirectory;
+ getInstance().siftDownloadDirectory = siftDownloadDirectory;
}
public static int getCacheThresholdInDays()
{
- return cacheThresholdInDays;
+ return getInstance().cacheThresholdInDays;
}
public static void setCacheThresholdInDays(String cacheThresholdInDays)
{
Objects.requireNonNull(cacheThresholdInDays);
- SiftsSettings.cacheThresholdInDays = Integer
+ getInstance().cacheThresholdInDays = Integer
.valueOf(cacheThresholdInDays);
}
public static int getFailSafePIDThreshold()
{
- return failSafePIDThreshold;
+ return getInstance().failSafePIDThreshold;
}
public static void setFailSafePIDThreshold(String failSafePIDThreshold)
{
Objects.requireNonNull(failSafePIDThreshold);
- SiftsSettings.failSafePIDThreshold = Integer
+ getInstance().failSafePIDThreshold = Integer
.valueOf(failSafePIDThreshold);
}
}
diff --git a/src/jalview/ws/utils/UrlDownloadClient.java b/src/jalview/ws/utils/UrlDownloadClient.java
index 58632f2..227fe23 100644
--- a/src/jalview/ws/utils/UrlDownloadClient.java
+++ b/src/jalview/ws/utils/UrlDownloadClient.java
@@ -53,64 +53,7 @@ public class UrlDownloadClient
public static void download(String urlstring, String outfile)
throws IOException
{
-
- FileOutputStream fos = null;
- ReadableByteChannel rbc = null;
- Path temp = null;
- try
- {
- temp = Files.createTempFile(".jalview_", ".tmp");
-
- URL url = new URL(urlstring);
- rbc = Channels.newChannel(url.openStream());
- fos = new FileOutputStream(temp.toString());
- fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
-
- // copy tempfile to outfile once our download completes
- // incase something goes wrong
- Files.copy(temp, Paths.get(outfile),
- StandardCopyOption.REPLACE_EXISTING);
- } catch (IOException e)
- {
- throw e;
- } finally
- {
- try
- {
- if (fos != null)
- {
- fos.close();
- }
- } catch (IOException e)
- {
- System.out.println(
- "Exception while closing download file output stream: "
- + e.getMessage());
- }
- try
- {
- if (rbc != null)
- {
- rbc.close();
- }
- } catch (IOException e)
- {
- System.out.println("Exception while closing download channel: "
- + e.getMessage());
- }
- try
- {
- if (temp != null)
- {
- Files.deleteIfExists(temp);
- }
- } catch (IOException e)
- {
- System.out.println("Exception while deleting download temp file: "
- + e.getMessage());
- }
- }
-
+ Platform.download(urlstring, outfile);
}
public static void download(String urlstring, File tempFile) throws IOException
diff --git a/src/javajs/async/Assets.java b/src/javajs/async/Assets.java
index b57528b..3650544 100644
--- a/src/javajs/async/Assets.java
+++ b/src/javajs/async/Assets.java
@@ -1,5 +1,6 @@
package javajs.async;
+import java.awt.Toolkit;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@@ -361,7 +362,7 @@ public class Assets {
try {
URL url = getInstance()._getURLFromPath(path, true);
if (url == null && !zipOnly) {
- url = Assets.class.getResource(path);
+ url = Assets.class.getClassLoader().getResource(path);
}
if (url != null)
return url.openStream();
diff --git a/src/javajs/async/AsyncSwingWorker.java b/src/javajs/async/AsyncSwingWorker.java
index df103cd..703f7f5 100644
--- a/src/javajs/async/AsyncSwingWorker.java
+++ b/src/javajs/async/AsyncSwingWorker.java
@@ -10,6 +10,8 @@ import javajs.async.SwingJSUtils.StateHelper;
import javajs.async.SwingJSUtils.StateMachine;
/**
+ * v. 2020.06.03
+ *
* Executes synchronous or asynchronous tasks using a SwingWorker in Java or
* JavaScript, equivalently.
*
@@ -38,18 +40,56 @@ import javajs.async.SwingJSUtils.StateMachine;
* the subclass to update the progress field in both the SwingWorker and the
* ProgressMonitor.
*
- * If it is desired to run the AsyncSwingWorker synchonously, call the
+ * If it is desired to run the AsyncSwingWorker synchronously, call the
* executeSynchronously() method rather than execute(). Never call
* SwingWorker.run().
*
+ * Note that doInBackgroundAsync runs on the Java AWT event queue. This means
+ * that, unlike a true SwingWorker, it will run in event-queue sequence, after
+ * anything that that method itself adds to the queue. This is what SwingWorker itself
+ * does with its done() signal.
+ *
+ * If doInBackgroundAsync has tasks that are time intensive, the thing to do is to
+ *
+ * (a) pause this worker by setting the value of progress for the NEXT step:
+ *
+ * setProgressAsync(n);
+ *
+ * (b) pause the timer so that when doInBackgroundAsync returns, the timer is not fired:
+ *
+ * setPaused(true);
+ *
+ * (c) start your process as new Thread, which bypasses the AWT EventQueue:
+ *
+ * new Thread(Runnable).start();
+ *
+ * (d) have your thread, when it is done, return control to this worker:
+ *
+ * setPaused(false);
+ *
+ * This final call restarts the worker with the currently specified progress value.
*
* @author hansonr
*
*/
public abstract class AsyncSwingWorker extends SwingWorker implements StateMachine {
+
+ // PropertyChangeEvent getPropertyName()
+
+ private static final String PROPERTY_STATE = "state";
+ private static final String PROPERTY_PAUSE = "pause";
+
+ // PropertyChangeEvent getNewValue()
+
+ public static final String STARTED_ASYNC = "STARTED_ASYNC";
+ public static final String STARTED_SYNC = "STARTED_SYNC";
+
public static final String DONE_ASYNC = "DONE_ASYNC";
public static final String CANCELED_ASYNC = "CANCELED_ASYNC";
+
+ public static final String PAUSED = "PAUSED";
+ public static final String RESUMED = "RESUMED";
protected int progressAsync;
@@ -119,10 +159,12 @@ public abstract class AsyncSwingWorker extends SwingWorker implement
}
public void executeAsync() {
+ firePropertyChange(PROPERTY_STATE, null, STARTED_ASYNC);
super.execute();
}
public void executeSynchronously() {
+ firePropertyChange(PROPERTY_STATE, null, STARTED_SYNC);
isAsync = false;
delayMillis = 0;
try {
@@ -244,7 +286,7 @@ public abstract class AsyncSwingWorker extends SwingWorker implement
private final static int STATE_LOOP = 1;
private final static int STATE_WAIT = 2;
private final static int STATE_DONE = 99;
-
+
private StateHelper helper;
protected StateHelper getHelper() {
@@ -255,6 +297,9 @@ public abstract class AsyncSwingWorker extends SwingWorker implement
protected void setPaused(boolean tf) {
isPaused = tf;
+ firePropertyChange(PROPERTY_PAUSE, null, (tf ? PAUSED : RESUMED));
+ if (!tf)
+ stateLoop();
}
protected boolean isPaused() {
@@ -292,7 +337,7 @@ public abstract class AsyncSwingWorker extends SwingWorker implement
case STATE_LOOP:
if (checkCanceled()) {
helper.setState(STATE_DONE);
- firePropertyChange("state", null, CANCELED_ASYNC);
+ firePropertyChange(PROPERTY_STATE, null, CANCELED_ASYNC);
} else {
int ret = doInBackgroundAsync(progressAsync);
if (!helper.isAlive() || isPaused) {
@@ -309,6 +354,7 @@ public abstract class AsyncSwingWorker extends SwingWorker implement
}
continue;
case STATE_WAIT:
+ // meaning "sleep" and then "loop"
helper.setState(STATE_LOOP);
helper.sleep(delayMillis);
return true;
@@ -343,7 +389,7 @@ public abstract class AsyncSwingWorker extends SwingWorker implement
@Override
public void run() {
doneAsync();
- firePropertyChange("state", null, DONE_ASYNC);
+ firePropertyChange(PROPERTY_STATE, null, DONE_ASYNC);
}
};
diff --git a/src/swingjs/api/JSUtilI.java b/src/swingjs/api/JSUtilI.java
index 1b6ff9b..322ec83 100644
--- a/src/swingjs/api/JSUtilI.java
+++ b/src/swingjs/api/JSUtilI.java
@@ -7,6 +7,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.HashMap;
+import java.util.Map;
import java.util.Properties;
import java.util.function.Function;
import java.util.zip.ZipEntry;
@@ -91,10 +92,10 @@ public interface JSUtilI {
/**
- * Get an attribute of applet's Info map for the applet found using
- * getApplet(null). That is, applet.__Info[InfoKey].
+ * Get the applet's __Info map or an attribute of that map for the applet found using
+ * getApplet(null). That is, applet.__Info or applet.__Info[InfoKey].
*
- * @param infoKey
+ * @param infoKey if null, return the full __Info map
*/
Object getAppletInfo(String infoKey);
@@ -329,4 +330,25 @@ public interface JSUtilI {
*/
void setUIEnabled(JComponent jc, boolean enabled);
+
+ /**
+ * Play an audio
+ * @param buffer
+ * @param format a javax.sound.sampled.AudioFormat
+ * @throws Exception
+ */
+ void playAudio(byte[] buffer, Object format) throws Exception;
+
+ /**
+ * For either an applet or an application, get the ORIGINAL __Info as a Map that
+ * has a full set up lower-case keys along with whatever non-all-lower-case keys
+ * provided at start-up.
+ *
+ * @return
+ */
+ Map getAppletInfoAsMap();
+
+
+ void setAppClass(Object j);
+
}
diff --git a/swingjs/SwingJS-site.zip b/swingjs/SwingJS-site.zip
index d5e28c1..5e9828e 100644
Binary files a/swingjs/SwingJS-site.zip and b/swingjs/SwingJS-site.zip differ
diff --git a/swingjs/differences.txt b/swingjs/differences.txt
new file mode 100644
index 0000000..70eabbc
--- /dev/null
+++ b/swingjs/differences.txt
@@ -0,0 +1,1480 @@
+Notes
+=====
+
+---IMPORTANT CHARACTER SET NOTE---
+
+It is critical that all development work in Java2Script
+be done in UTF-8. This means:
+
+- making sure your Eclipse project is set up for UTF-8 (not the Eclipse default?)
+- making sure your server can serve up UTF-8 by default for any browser-loaded files
+- making sure you don't edit a Java2Script class file or one of the site .js files
+ using a non-UTF-8 editor. It may replace non-Latin characters with "?" or garbage.
+- making sure that your web pages are delivered with proper headings indicating HTML5 and UTF-8
+
+
+
+
+
+
+Note that the DOCTYPE tag is critical for some browsers to switch into HTML5 mode. (MSIE?)
+
+
+
+
+In particular, the Mandarin character 秘 (mi; "secret") is used extensively throughout
+the SwingJS class files to distinguish j2s-specific fields and methods that must not
+ever be shadowed or overridden by subclasses. For example, we see in java.lang.Thread.java:
+
+ public static JSThread 秘thisThread;
+
+----------------------------------
+
+
+updated 3/21/2020 -- adds note about HashMap, Hashtable, and HashSet iterator ordering
+updated 3/20/2020 -- adds note about interning, new String("xxx"), and "xxx"
+updated 2/26/2020 -- adds Graphics.setClip issue
+updated 12/22/19 -- additional issues
+updated 11/03/19 -- adds information about File.exists() and points to src/javajs/async
+updated 10/26/19 -- adds information about File.createTempFile()
+updated 8/16/19 -- minor typos and added summary paragraph
+updated 7/19/19 -- clarification that AWT and Swing classes are supported directly
+updated 5/13/19 -- Mandarin U+79D8 reserved character; Missing Math methods; int and long
+updated 5/10/19 -- adds a section on static issues in multi-(duplicate)-applet pages
+updated 1/4/19 -- nio
+updated 9/15/18 -- adds integer 1/0 == Infinity
+updated 7/24/18 -- most classes replaced with https://github.com/frohoff/jdk8u-jdk
+updated 6/5/17 -- reserved package name "window"
+updated 3/11/17 -- myClass.getField
+updated 3/7/17 -- overloading of JSplitPane.setDividerLocation
+updated 3/2/17 -- more indication of classes not implemented (KeyListener)
+
+=============================================================================
+SwingJS and OpenJDK 8+
+=============================================================================
+
+SwingJS implements a wide range of the Java language in JavaScript. The base
+version for this implementation is OpenJDK8. some classes are implemented using
+older source code, and there are some missing methods. For the most part, this is
+no real problem. You can add or modify any java class just be adding it as source
+in your project. Or (preferably) you can contact me, and I can get it into the
+distribution. Or (even more preferably) you can do that via a patch submission.
+
+=================
+DESIGN PHILOSOPHY
+=================
+
+The java2script/SwingJS design goal is to recreate a recognizable, easily debuggable
+equivalent in JavaScript for as much of Java as practical. This means, for example,
+that one can call in JavaScript
+
+ new java.util.Hashtable()
+
+and for all practical purposes it will appear that Java is running.
+
+
+Method and Field Disambiguation
+-------------------------------
+
+SwingJS has no problem with the overloading of methods, for example:
+
+ public void print(int b);
+ public void print(float b);
+
+JavaScript does not allow overloading of methods, and the common practice in
+Java of naming a field the same as a method -- isAllowed and isAllowed() -- is
+not possible in JavaScript. As a result, SwingJS implements "fully-qualified"
+method names using "$" parameter type separation. Thus, these methods in SwingJS
+will be referred to as print$I and print$F. The rules for this encoding are
+relatively simple:
+
+1. The seven primitive types in Java are encoded $I (int), $L (long), $F (float),
+$D (double), $B (byte) $Z (boolean), and $H (short).
+
+2. String and Object are encoded as $S and $O, respectively.
+
+3. "java_lang_" is dropped for all other classes in the java.lang package (as in Java).
+ For example: $StringBuffer, not $java_lang_StringBuffer
+
+4. All other classes are encoded as
+
+ "$" + Class.getName().replace(".","_")
+
+For example, in Java we see:
+
+ public void equals(Object o) {...}
+
+Whereas in SwingJS we have:
+
+ Clazz.newMeth(C$, 'equals$O', function (o) {...}
+
+And
+
+ this.getContentPane().add(bar, "North");
+
+becomes
+
+ this.getContentPane$().add$java_awt_Component$O(bar, "North");
+
+5. Arrays are indicated with appended "A" for each level. So
+
+ setDataVector(Object[][] dataVector, Object[] columnIdentifiers)
+
+becomes
+
+ setDataVector$OAA$OA(dataVector, columnIdentifiers)
+
+(It is recognized that this design does introduce a bit of ambiguity, in that
+ in principal there could be user class named XA and X in the same package,
+ and methods a(X[]) and a(XA) in the same class that cannot be distinguished.
+ The benefit of this simple system, however, triumphed over the unlikelyhood
+ of that scenario.) The transpiler could be set to flag this possibility.
+
+6. Constructors are prepended with "c$". So
+
+ public JLabel(String text) {...}
+
+becomes:
+
+ Clazz.newMeth(C$, 'c$$S', function (text) {...});
+
+Field disambiguation involves prepending. In Java, a class and its subclass
+can both have the same field name, such as
+
+ boolean visible;
+
+When this happens, it is called "shadowing", and though not recommended, Java allows
+it. The Java2Script transpiler will prepend such shadowing fields with "$" so that the
+subclass instance has both "visible" (for use in its methods inherited from its
+superclass) and "$visible" (for its own methods). Thus, we might see in Java:
+
+ this.visible = super.visible;
+
+while in SwingJS we will see:
+
+ this.$visible=this.visible;
+
+since JavaScript does not have the "super" keyword.
+
+
+
+Parameterless methods such as toString() are appended with "$" to become toString$().
+The one exception to this rule is private methods, which are saved in (truly) private
+array in the class (and are not accessible by reflection). Private parameterless
+methods retain their simple Java name, since they cannot conflict with field names.
+
+This renaming of methods has a few consequences, which are discussed more fully below.
+See particularly the section on "qualified field and method names", where it is described
+how you can use packages or classes or interfaces with ".api.js" in them to represent JavaScript
+objects for which all method names are to be left unqualified. Note that it is not
+possible to cherry-pick methods to be unqualified; only full packages, classes or
+interfaces can hold this status.
+
+The swingjs.api.js package in particular contains a number of useful interfaces that
+you can import into your project for JavaScript-specific capabilities.
+
+
+Applet vs. Application
+----------------------
+
+One of the very cool aspects of SwingJS is that it doesn't particularly matter if a browser-based
+Java app is an "applet" or an "application". We don't need JNLP (Java Network Launch Protocol)
+because now we can just start up any Java application in a browser just as easily as any applet.
+The associative array that passes information to the SwingJS applet (information that formerly
+might have been part of the APPLET tag, such as width, height, and codebase, always referred to
+in our writing as "the Info array") allows the option to specify the JApplet/Applet "code"
+class or the application "main" class. Either one will run just fine.
+
+
+Performance
+-----------
+
+Obviously, there are limitations. One is performance, but we have seen reproducible
+performance at 1/6 - 1/3 the speed of Java. Achieving this performance may require
+some refactoring of the Java to make it more efficient in both Java and JavaScript.
+"for" loops need to be more carefully crafted; use of "new" and "instanceof" need to be
+minimized in critical areas. Note that method overloading -- that is, the same method name
+with different parameters, such as read(int) and read(byte) -- is no longer any problem.
+
+
+Threads
+-------
+
+Although there is only a single thread in JavaScript, meaning Thread.wait(), Thread.sleep(int) and
+Thread.notify() cannot be reproduced, we have found that this is not a serious limitation.
+For example, javax.swing.Timer() works perfectly in JavaScript. All it means is that threads
+that use sleep(int) or notify() must be refactored to allow Timer-like callbacks. That is,
+they must allow full exit and re-entry of Thread.run(), not the typical while/sleep motif.
+
+The key is to create a state-based run() that can be exited and re-entered in JavaScript.
+
+
+Static fields
+-------------
+
+Final static primitive "constant" fields (String, boolean, int, etc.) such as
+
+static final int TEST = 3;
+static final String MY_STRING = "my " + "string";
+
+are converted to their primitive form automatically by the Eclipse Java compiler
+and do not appear in the JavaScript by their names.
+
+Other static fields are properties of their class and can be used as expected.
+
+Note, however, that SwingJS runs all "Java" code on a page in a common "jvm"
+(like older versions of Java). So, like the older Java schema, the JavaScript
+equivalents of both applets and applications will share all of their static
+fields and methods. This includes java.lang.System.
+
+Basically, SwingJS implementations of Java run in a browser page-based sandbox
+instead of an applet-specific one.
+
+In general, this is no problem. But if we are to implement pages with
+multiple applets present, we must be sure to only have static references
+that are "final" or specifically meant to be shared in a JavaScript
+environment only (since they will not be shared in Java).
+
+A simple solution, if static non-constant references are needed, is to attach the
+field to Thread.currentThread.threadGroup(), which is an applet-specific reference.
+Be sure, if you do this, that you use explicit setters and getters:
+
+For example,
+
+private static String myvar;
+
+...
+
+public void setMyVar(String x) {
+ ThreadGroup g = Thread.currentThread().threadGroup();
+ /**
+ * @j2sNative g._myvar = x;
+ *
+ */
+ {
+ myvar = x;
+ }
+}
+
+public String getMyVar() {
+ ThreadGroup g = Thread.currentThread().threadGroup();
+ /**
+ * @j2sNative return g._myvar || null;
+ *
+ */
+ {
+ return myvar;
+ }
+}
+
+ in Java will get and set x the same in JavaScript and in Java.
+
+
+A convenient way to do this in general is to supply a singleton class with
+explicitly private-only constructors and then refer to it in Java and in JavaScript
+instead of using static field, referring to myclass.getIntance().xxx instead of
+myclass.xxx in Java (and JavaScript).
+
+This was done extensively in the Jalview project. See jalview.bin.Instance.
+
+
+Helper Packages -- swingjs/ and javajs/
+---------------------------------------
+
+The SwingJS library is the swingjs/ package. There are interfaces that may be of assistance
+in swingjs/api, but other than that, it is not recommended that developers access classes in
+this package. The "public" nature of their methods is really an internal necessity.
+
+In addition to swingjs/, though, there are several useful classes in the javajs/ package
+that could be very useful. This package is a stand-alone package that can be
+cloned in any Java project that also would be great to have in any JavaScript project
+-- SwingJS-related or not. Functionality ranges from reading and writing various file
+formats, including PDF, BMP, PNG, GIF, JPG, JSON, ZIP, and CompoundDocument formats.
+
+A variety of highly efficient three- and four-dimensional point, vector, matrix, and
+quaternion classes are included, as they were developed for JSmol and inherited from that
+project.
+
+Of particular interest should be javajs/async/, which includes
+
+javajs.async.Async
+javajs.async.AsyncColorChooser
+javajs.async.AsyncDialog
+javajs.async.AsyncFileChooser
+
+See javajs.async.Async JavaDoc comments for a full description of
+these useful classes.
+
+
+Modal Dialogs
+-------------
+
+Although true modal dialogs are not possible with only one thread, a functional equivalent --
+asynchronous modal dialogs -- is relatively easy to set up. All the JOptionPane dialogs will
+return PropertyChangeEvents to signal that they have been disposed of and containing the results.
+See below and classes in the javajs.async package.
+
+
+Native calls
+------------
+
+Native calls in Java are calls to operating system methods that are not in Java. JavaScript
+has no access to these, of course, and they must all be replaced by JavaScript equivalents.
+Fortunately, they are not common, and those that are present in Java (for example, in calculating
+checksums in ZIP file creation) are at a low enough level that most developers do not utilize them
+or do not even have access to them. All native calls in Java classes have been replaced by
+Java equivalents.
+
+
+Swing GUI Peers and UIClasses
+-----------------------------
+
+One of the biggest adaptations introduced in SwingJS is in the area of the graphical
+user interface. The issue here is complex but workable. In Java there are two background
+concepts -- the Component "peer" (one per "heavy-weight" component, such as a Frame) and the
+component "uiClass" (one per component, such as JButton or JTextField).
+
+Peers are native objects of the operating system. These are the virtual buttons and text areas
+that the user is interacting with at a very base level. Their events are being passed on to
+Java or the browser by the operating system. UI classes provide a consistent "look and feel"
+for these native objects, rendering them onto the native window canvas and handling all
+user-generated events. They paint the borders, the backgrounds, the highlights, of every
+control you see in Java. There is one-to-one correspondence of Swing classes and UI classes.
+Setting the Look and Feel for a project amounts to selecting the directory from which to draw
+these UI classes. The UI classes can be found in the javax.swing.plaf ("platform look and feel")
+package.
+
+Early on in the development of SwingJS, we decided not to fully reproduce the painfully detailed
+bit-by-bit painting of controls as is done in Java. Instead, we felt it was wiser to utilize the standard
+HTML5 UI capabilities as much as possible, using DIV, and INPUT especially, with extensive use
+of CSS and sometimes jQuery (menus, and sliders, for example). Thus, we have created a new
+set of UIs -- the "HTML5 Look and Feel". These classes can be found in swingjs.plaf. Besides being
+more adaptable, this approach allows far more versatility to SwingJS developers, allowing them
+to modify the GUI to suit their needs if desired.
+
+In SwingJS, since we have no access to native peers except through the browser DOM,
+it seemed logical to merge the peer and UI idea. So instead of having one peer per heavy-weight control and
+one UI class instance for each control type, we just have one UI class instance per control, and
+that UI class instance is what is being referred to when a "peer" is notified.
+
+In some ways this is a throw back to when all of Swing's components were subclasses of
+specific AWT components such as Button and List. These "heavy-weight components" all had their
+own individual native peers and thus automatically took on the look and feel provided by the OS.
+Later Swing versions implemented full look and feel for all peers, leaving only JDialog, JFrame,
+and a few other classes to have native peers. But in SwingJS we have again a 1:1 map of component
+and UI class/peer instance.
+
+The origin of most issues (read "bugs") in relation to the GUI will probably be found in the
+swingjs.plaf JSxxxxUI.java code.
+
+
+Swing-only Components -- no longer an issue
+-------------------------------------------
+
+Swing was introduced into Java well after the Java Abstract Window Toolkit (AWT) was well
+established. As such, its designers chose to allow AWT controls such as Button and List to be used
+alongside their Swing counterparts JButton and JList. Reading the code, it is clear that this
+design choice posed a huge headache for Swing class developers.
+
+For SwingJS, we decided from the beginning NOT to allow this mixed-mode programming and
+instead to require that all components be Swing components.
+
+However, this is no longer an issue. All AWT components in SwingJS are now subclasses of
+javax.swing.JComponent. So far, we have found no problem with this.
+
+
+The a2s Adapter Package
+-----------------------
+
+Originally, we thought that we would restrict ourselves to JApplets only. That is, only
+Swing-based applets. But as we worked, we discovered that there are a lot of great
+applets out there that are pre-Swing pure-AWT java.applet.Applet applets. Our problem was
+that we also wanted it to be possible to quickly adapt these applets to JavaScript as well.
+
+The solution turned out to be simple: Write a package (a2s) that recreates the interface for
+non-Swing components as subclasses of Swing components. Thus, a2s.Button subclasses javax.swing.JButton
+but also accepts all of the methods of java.awt.Button. This works amazingly well, with a few
+special adaptations to the core javax.swing to be "AWT-aware." All AWT components now subclass
+a2s components, which in turn subclass JComponents. So no changes in code are necessary. We have
+successfully transpiled over 500 applets using this strategy. (Kind of surprising, actually, that
+the original Java developers did not see that option. But we have a hindsight advantage here.)
+
+
+Working with Files
+==================
+
+Simple String file names are not optimal for passing information about
+read files within SwingJS applications.
+
+All work with files should either use Path or File objects exclusively.
+These objects, after a file is read or checked for existence, will already
+contain the file byte[] data. Doing something like this:
+
+File f = File("./test.dat");
+boolean isOK = f.exists();
+
+will load f with its byte[] data, if the file exists.
+
+But if after that, we use:
+
+File f2 = new File(f.getAbsolutePath());
+
+f2 will not contain that data. Such copying should be done as:
+
+File f2 = new File(f);
+
+in which case, the byte[] data will be transferred.
+
+
+SwingJS uses the following criteria to determine if File.exists() returns true:
+
+(1) if this File object has been used directly to read data, or
+(2) if reading data using this File object is successful.
+
+Note that you cannot check to see if a file exists before input or if it
+was actually written or if it already exists prior to writing in SwingJS.
+
+Thus, you should check each use of file.exists() carefully, and if necessary, provide a J2sNative
+block that gives an appropriate "OK" message, for example:
+
+(/** @j2sNative 1 ? false : */ outputfile.exits())
+
+or
+
+(/** @j2sNative 1 ? true : */ inputfile.exits())
+
+Temporary files can be created in SwingJS. SwingJS will maintain a pseudo-filesystem for files
+created with File.createTempFile(). This is useful in that closure of writing to a temporary file
+does not generate a pseudo-download to the user's machine.
+
+
+UNIMPLEMENTED CLASSES BY DESIGN
+===============================
+
+The SwingJS implementation of the following classes are present
+in a way that gracefully bypasses their functionality:
+
+accessibility
+security
+serialization
+
+
+
+TODO LIST FOR UNIMPLEMENTED CLASSES
+===================================
+
+JEditorPane (minimal implementation) - DONE 12/2018; some issues still
+JSplitPane - DONE 8/2018
+JTabbedPane - DONE 10/2018
+JTree - done 12/2019
+
+
+MINOR ISSUES--required some rewriting/refactoring by Bob and Udo
+================================================================
+
+Thread.currentThread() == dispatchThread
+
+
+MINOR ISSUES--requiring some rewriting/refactoring outside of SwingJS
+=====================================================================
+
+See below for a full discussion.
+
+HashMap, Hashtable, and HashSet iterator ordering
+interning, new String("xxx") vs "xxx"
+Names with "$" and "_"
+positive integers do not add to give negative numbers
+ArrayIndexOutOfBounds
+java.awt.Color
+native methods
+javax.swing.JFileDialog
+key focus
+LookAndFeel and UI Classes
+System.exit(0) does not stop all processes
+list cell renderers must be JComponents
+myClass.getField not implemented
+"window" and other reserved JavaScript names
+reserved field and method names
+qualified field and method names
+missing Math methods
+Component.getGraphics(), Graphics.dispose()
+Graphics.setClip()
+
+MAJOR ISSUES--for Bob and Udo within SwingJS
+============================================
+
+fonts
+OS-dependent classes
+AWT component peers
+some aspects of reflection
+
+MAJOR ISSUES--to be resolved by implementers
+============================================
+
+fonts
+threads
+modal dialogs
+image loading
+BigDecimal not fully implemented
+no format internationalization
+no winding rules
+text-related field implementation
+Formatter/Regex limitations
+integer 1/0 == Infinity
+
+========================================================================
+
+DISCUSS
+=======
+
+Table row/col sorter needs checking after removal of java.text.Collator references
+
+I had to move all of SunHints class to RenderingHints, or the
+two classes could not be loaded. Shouldn't be a problem, I think. The sun classes are
+not accessible to developers in Java anyway, since they are generally package private.
+
+==========================================================================
+
+//////////////////////////////////////////////////////////////////////////////
+
+UNIMPLEMENTED CLASSES
+=====================
+
+accessibility
+-------------
+
+All Accessibility handling has been commented out to save the download footprint.
+This removes the need for sun.misc.SharedSecrets as well.
+Nothing says we could not implement accessibility. We just didn't.
+
+
+security
+--------
+
+All JavaScript security is handled by the browser natively.
+Thus, Java security checking is no longer necessary, and
+java.security.AccessController has been simplified to work without
+native security checking.
+
+Note that private methods in a class are REALLY private.
+
+
+serialization
+-------------
+
+All serialization has been removed. It was never very useful for Swing anyway,
+because one needs exactly the same Java version to save and restore serialized objects.
+
+
+keyboard accelerators and mnemonics
+-----------------------------------
+
+This work was completed in the spring of 2019. Note that in a browser, some
+key strokes, particularly CTRL-keys, are not available. Bummer.
+
+
+MINOR ISSUES--required some rewriting/refactoring by Bob and Udo
+================================================================
+
+
+Thread.currentThread() == dispatchThread
+----------------------------------------
+
+changed to JSToolkit.isDispatchThread()
+
+
+MINOR ISSUES--requiring some rewriting/refactoring outside of SwingJS
+=====================================================================
+
+HashMap, Hashtable, and HashSet iterator ordering
+-------------------------------------------------
+
+In Java, iterators for HashMap, Hashtable, and HashSet do not guarantee any particular order.
+From the HashMap documentation for Java 8:
+
+ This class makes no guarantees as to the order of the map; in particular, it does not
+ guarantee that the order will remain constant over time.
+
+Likewise, for HashSet (because it is simply a convenience method for HashMap:
+
+ [HashSet] makes no guarantees as to the iteration order of the set.
+
+JavaScript's Map object is different. It is basically a LinkedHashMap, so it guarantees iteration
+in order of object addition.
+
+Starting with java2script 3.2.9.v1, these classes use the JavaScript Map object rather than hash codes
+whenever all keys are strictly of JavaScript typeof "string". If any key is introduced that is not a string, the
+implementation falls back to using hash codes, the same as Java.
+
+Note strings created using new String("xxxx") are NOT typeof "string"; they are typeof "object".
+
+The result is significantly faster performance (3-12 x faster) than originally, and up to 3 x faster
+performance in JavaScript than in Java itself. Right. Faster than Java.
+
+The JavaScript Map implementation is implemented UNLESS the constructor used is the one that
+specifies both initial capacity and load factor in their constructor. Thus,
+
+new Hashtable()
+new HashMap()
+new HashMap(16)
+new HashSet()
+
+all use the JavaScript Map. But
+
+new Hashtable(11, 0.75f)
+new HashMap(16, 0.75f)
+new HashSet(16, 0.75f)
+
+do not.
+
+This design allows for opting out of the JavaScript Map use in order to retain the exact behavior of
+iterators in JavaScript as in Java.
+
+
+interning, new String("xxx") vs "xxx"
+-------------------------------------
+
+Note that the following are true in JavaScript:
+
+typeof new String("xxxx") == "object"
+typeof "xxxx" == "string"
+var s = "x";typeof ("xxx" + s) == "string"
+
+There is no equivalence to this behavior in Java, where a String is a String is a String.
+
+Be aware that SwingJS does not always create a JavaScript String object using JavaScript's
+new String(...) constructor. It only does this for Java new String("xxxx") or new String(new String()).
+
+In all other cases, new String(...) (in Java) results in a simple "xxxx" string in JavaScript.
+That is, it will be JavaScript typeof "string", not typeof "object".
+
+The reason for this design is that several classes in the Java core use toString()
+methods that return new String(), and those classes that do that would cause a JavaScript error
+if implicitly stringified if new String() returned a JavaScript String object.
+
+This is fine in JavaScript
+
+test1 = function() { return { toString:function(){ return "OK" } } }
+"testing" + new test1()
+>> "testingOK"
+
+But for whatever reason in JavaScript:
+
+test2 = function() { return { toString:function(){ return new String("OK") } } }
+"testing" + new test2()
+>> Uncaught TypeError: Cannot convert object to primitive value
+
+The lesson here is never to use
+
+ return new String("...");
+
+in a Java toString() method. In Java it will be fine; in JavaScript it will also be fine as long as
+that method is never called in JavaScript implicitly in the context of string concatenation.
+
+A note about interning. Consider the following six Java constructions, where we have a == "x";
+
+"xxx"
+"xx" + "x"
+new String("xxx").intern()
+
+new String("xxx")
+"xx" + a.toString()
+"xx" + a
+
+All six of these will return java.lang.String for .getClass().getName().
+However, the first three are String literals, while the last three are String objects.
+Thus:
+ "xxx" == "xxx"
+ "xxx" == "xx" + "x"
+ "xxx" == new String("xxx").intern()
+
+but none of the other three are equivalent to "xxx" or each other:
+
+ "xxx" != new String("xxx")
+ "xxx" != "xx" + a.toString()
+ "xxx" != "xx" + a
+ new String("xxx") != new String("xxx")
+ "xx" + a != new String("xxx")
+
+etc.
+
+As in Java, in SwingJS, all of the following Java assertions pass as true:
+
+ assert("xxx" == "xx" + "x");
+ assert("xxx" == ("xx" + a).intern());
+ assert("xxx" === new String("xxx").intern());
+
+and both of these do as well:
+
+ assert(new String("xxx") != "xxx");
+ assert(new String("xxx") != new String("xxx"));
+
+But the following two fail to assert true:
+
+ assert("xxx" != "xx" + a);
+ assert("xxx" != "xx" + a.toString());
+
+because in JavaScript, both of these right-side expressions evaluate to a simple "interned" string.
+
+In Java, however, these assertions are true because Java implicitly "boxes" String
+concatentaion as a String object, not a literal.
+
+Most of us know not to generally use == with Strings unless they are explicitly interned.
+Where this problem may arise, though, is in IdentityHashMap, which compares objects using
+System.identityHashCode(), which is not the same for different objects or their string literal equivalents.
+
+My recommendation, if you need to use IdentityHashMap with strings is to always use an explicit String.intern()
+for any keys -- unless you really want to keep every string as separate keys even if they are the same sequence,
+in which case, use new String(). This will work in Java and in JavaScript.
+
+Be aware when working with strings that come from SwingJS and are being used by other JavaScript modules
+that those that are String objects will return "object" for the JavaScript typeof operator, not "string".
+
+The easy way to ensure this is no problem is to concatenate strings with "" to force immediate interning:
+
+ var x = aJavaObject.getString() + "";
+
+unless you are certain that the string is being returned is a raw JavaScript string.
+
+Names with "$" and "_"
+----------------------
+
+For the most part, this should be no problem.
+
+Note that the use of $ and _ in Java field names has always been discouraged:
+[https://docs.oracle.com/javase/tutorial/java/nutsandbolts/variables.html]
+
+ You may find some situations where auto-generated names will contain the dollar sign,
+ but your variable names should always avoid using it. A similar convention
+ exists for the underscore character; while it's technically legal to begin your
+ variable's name with "_", this practice is discouraged.
+
+Some impacts of transpiling method names with full qualification:
+
+1) SwingJS will introduce fields that start with $ or _. These will not conflict
+ if the above convention is followed.
+
+2) Fields that have the same Java name as a method are not an issue.
+
+3) Fields that have a Java name with $ that matches a transpiled method name,
+ such as toString$, will need to be refactored in Java to not have that name collision.
+
+4) Fields in a subclass that have the same name as private fields in a superclass
+ represent a name collision, because the superclass method needs to call its private
+ field even if invoked from a subclass. The solution was to modify the subclass field
+ name using one or more prepended $.
+
+5) Use of Class.getDeclaredMethods() reflection will return Method objects having the transpiled
+ name, not the Java name. This could require some j2sNative adjustment
+ to strip the $... parameters from the name if that is needed.
+
+6) Use of Method.getParameterTypes() should work fine, provided class names
+ do not contain "_". This is because the transpiler converts "." to "_" when
+ creating the fully qualified JavaScript name.
+
+
+positive integers do not add to give negative numbers
+-----------------------------------------------------
+
+In Java, the following is true:
+
+ 2000000000 + 2000000000 == -294967296
+
+But in SwingJS, that will be 4000000000. So, for example, the following
+strategy will fail in SwingJS:
+
+ int newLength = lineBuf.length * 2;
+ if (newLength < 0) {
+ newLength = Integer.MAX_VALUE;
+ }
+
+"-1" in JavaScript is not 0xFFFFFFFF.
+
+And one must take care to not compare a negative number with a 32-bit mask. So
+
+(b & 0xFF000000) == 0xFF000000
+
+is true in Java for (int) b = -1, but is false in JavaScript, because 0xFF000000 is 4278190080,
+while (-1 & 0xFF000000) is, strangely enough, -16777216, and, in fact,
+
+(0xFF000000 & 0xFF000000) != 0xFF000000
+
+because -16777216 is not 4278190080.
+
+The fix is that one must compare similar operations:
+
+if ((b & 0xFF000000) == (0xFF000000 & 0xFF000000)) .....
+
+Importantly, the JavaScript Int32Array does behave properly. From
+the Firefox developer console:
+
+>> x = new Int32Array(1)
+<- Int32Array(1) [ 0 ]
+>> x[0] = 4000000000
+<- 4000000000
+>> x[0]
+<- -294967296
+
+Notice that, perhaps unexpectedly, the following two constructs produce
+different results in JavaScript:
+
+x = new Int32Array(1);
+b = x[0] = 4000000000;
+
+(b will be 4000000000)
+
+and
+
+x = new Int32Array(1);
+x[0] = 4000000000;
+b = x[0];
+
+(b will be -294967296)
+
+
+SwingJS leverages array typing to handle all byte and short arithmetic so as
+to ensure that any byte or short operation in JavaScript does give the same
+result in Java. The design decision to not also do this with integer math was
+a trade-off between performance and handling edge cases.
+
+
+ArrayIndexOutOfBounds
+---------------------
+
+You cannot implicitly throw an ArrayIndexOutOfBoundsException in JavaScript.
+JavaScript will simply return "undefined", not throw an Exception. So:
+
+boolean notAGoodIdeaIsOutOfBounds(String[] sa, int i) {
+ try {
+ return (sa[i] == sa[i]);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ return false;
+ }
+}
+
+will work in Java but not in JavaScript. Code should not depend upon this sort
+of trap anyway, if you ask me.
+
+Throwable vs Error vs Exception
+-------------------------------
+
+True JavaScript errors are trapped as Throwable, whereas you can still trap
+Error and Exception as well. So if you want to be sure to catch any JavaScript
+error, use try{}catch (Throwable t){}, not try{}catch (Exception e){}.
+
+j
+ava.awt.Color
+--------------
+
+ColorSpace: only "support" CS_sRGB.
+
+ TODO -- any volunteers??
+
+
+javax.swing.JFileDialog
+-----------------------
+
+HTML5 cannot expose a file reading directory structure. But you certainly
+can still do file reading and writing. It just works a little differently.
+It's a simple modification:
+
+ b = new JButton("FileOpenDialog");
+ b.addActionListener(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JFileChooser fc = new JFileChooser();
+ Test_Dialog.this.onDialogReturn(fc.showOpenDialog(Test_Dialog.this));
+ // Java will wait until the dialog is closed, then enter the onDialogReturn method.
+ // JavaScript will exit with NaN immediately, and then call back with its actual value
+ // asynchronously.
+ }
+
+ });
+
+ public void onDialogReturn(int value) {
+ if (value != Math.floor(value))
+ return; // in JavaScript, this will be NaN, indicating the dialog has been opened
+ // If we are here, the dialog has closed, in both Java and JavaScript.
+ System.out.println("int value is " + value);
+ }
+
+
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ Object val = event.getNewValue();
+ String name = event.getPropertyName();
+ System.out.println(name);
+ switch (event.getSource().getClass().getName()) {
+ case "javax.swing.JOptionPane":
+ switch (name) {
+ case "inputValue":
+ onDialogReturn(val);
+ return;
+ case "value":
+ if (val instanceof Integer)
+ onDialogReturn(((Integer) val).intValue());
+ else
+ onDialogReturn(val);
+ return;
+ }
+ break;
+ case "javax.swing.ColorChooserDialog":
+ switch (name) {
+ case "SelectedColor":
+ onDialogReturn(val);
+ return;
+ }
+ break;
+ case "javax.swing.JFileChooser":
+ switch (name) {
+ case "SelectedFile":
+ File file = (File) val;
+ byte[] array = (val == null ? null : /** @j2sNative file.秘bytes || */
+ null);
+ onDialogReturn("fileName is '" + file.getName() + "'\n\n" + new String(array));
+ return;
+ }
+ break;
+ }
+ System.out.println(
+ event.getSource().getClass().getName() + " " + event.getPropertyName() + ": " + event.getNewValue());
+ }
+
+
+Developers are encouraged to create a separate class that handles general calls to JFileDialog.
+An example class can be found in the SwingJS distribution as
+
+/sources/net.sf.j2s.java.core/src/javajs/async/AsyncFileChooser.java.
+
+
+javax.swing.JOptionPane dialogs
+-------------------------------
+
+For this action to work, the parentComponent must implement
+propertyChangeListener, and any call to JOptionPanel should allow for
+an asynchronous response, meaning that there is no actionable code following the
+call to the dialog opening.
+
+In addition, for compatibility with the Java version, implementation should
+wrap the call to getConfirmDialog or getOptionDialog in a method call to
+handle the Java:
+
+onDialogReturn(JOptionPane.showConfirmDialog(parentFrame,
+messageOrMessagePanel, "title", JOptionPane.OK_CANCEL_OPTION));
+
+Then parentFrame.propertyChange(event) should also call onDialogReturn.
+
+This will then work in both Java and JavaScript.
+
+Note that there is an int and an Object version of onDialogReturn().
+
+
+In JavaScript:
+
+The initial return from JOptionPane.showConfirmDialog and showMessageDialog
+will be (SwingJS) JDialog.ASYNCHRONOUS_INTEGER (NaN), testable as an impossible
+Java int value using ret != -(-ret) if the parent implements PropertyChangeListener, or -1
+(CLOSE_OPTION) if not.
+
+For showOptionDialog (which returns Object) or showInputDialog (which returns
+String), the initial return will be (SwingJS) JDialog.ASYNCHRONOUS_OBJECT, testable as
+((Object) ret) instanceof javax.swing.plaf.UIResource if the parent implements
+PropertyChangeListeneer, or null if not.
+
+The second return will be the desired return.
+
+In Java:
+
+The initial return will be the one and only modal final return.
+
+
+
+For full compatibility, The calling method must not continue beyond this
+call.
+
+All of the standard Java events associated with Components are also
+available.
+
+Certain fall back mechanisms are possible, where onReturn does not exist, but
+only for the following cases:
+
+
+For showMessageDialog, for WARNING_MESSAGE and ERROR_MESSAGE, a simple
+JavaScript alert() is used, returning 0 (OK_OPTION) or -1 (CLOSED_OPTION).
+
+For showInputDialog, if the message is a string, a simple JavaScript prompt()
+with input box is used, returning the entered string or null.
+
+For showConfirmDialog, a simple JavaScript confirm() is used, in which case:
+
+for YES_NO_OPTION: YES_OPTION or NO_OPTION
+
+for YES_NO_CANCEL_OPTION: YES_OPTION or CANCEL_OPTION
+
+for OK_CANCEL_OPTION or any other: OK_OPTION or CANCEL_OPTION
+
+Note that you should implement a response for CLOSED_OPTION for
+showConfirmDialog. For other dialogs, a null return indicates the dialog was
+closed, just as for Java.
+
+Developers are encouraged to create a separate class that handles general calls.
+An example class can be found in the SwingJS distribution as src/javajs/async/AsyncDialog.java.
+Very simple modifications to the Java allows asynchronous operation using AsyncDialog. Here
+is a simple "do you want to close this frame" example, where you can see that what we have
+done is to set the reply into an ActionListener that is defined in the constructor of
+the AsyncDisplay object:
+
+// Original:
+//
+// private void promptQuit() {
+// int sel = JOptionPane.showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION);
+// switch (sel) {
+// case JOptionPane.YES_OPTION:
+// resultsTab.clean();
+// seqs.dispose();
+// if (fromMain) {
+// System.exit(0);
+// }
+// break;
+// }
+// }
+
+ private void promptQuitAsync() {
+ new AsyncDialog(new ActionListener() {
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ int sel = ((AsyncDialog)e.getSource()).getOption();
+ switch (sel) {
+ case JOptionPane.YES_OPTION:
+ resultsTab.clean();
+ seqs.dispose();
+ if (fromMain) {
+ System.exit(0);
+ }
+ break;
+ }
+ }}).showConfirmDialog(null, PROMPT_EXIT, NAME, JOptionPane.YES_NO_OPTION);
+ }
+
+Very simple!
+
+
+native methods
+--------------
+
+The J2S compiler ignores all static native method declarations.
+Anything of this nature needs to be implemented in JavaScript if it is needed,
+using j2sNative blocks:
+
+/**
+ * @j2sNative
+ *
+ * var putYourJavaScriptCodeHere
+ *
+ */
+
+ Note that if you follow that directly with a {...} block, then
+ the javadoc code will run in JavaScript, and the {...} code will run in Java.
+
+
+key Focus
+---------
+
+As of June, 2019, the keyboard focus manager is fully implemented.
+The one catch is that JTextPane and JTextArea, which already consume
+VK_TAB in Java, cannot use CTRL-TAB to continue a tabbing cycle around
+the components in a window. Instead, CTRL-TAB is absorbed by the browser.
+
+
+LookAndFeel and UI Classes
+--------------------------
+
+SwingJS implements the native browser look and feel as swingjs.plaf.HTML5LookAndFeel.
+There are small differences between all look and feels -- MacOS, Windows, SwingJS.
+
+Expert developers know how to coerce changes in the UI by subclassing the UI for a
+component. This probably will not work in SwingJS.
+
+Note that LookAndFeel in Java usually determines canvas size in a Frame because
+different operating systems (Mac OS vs Windows vs HTML5) will have
+different edge sizes on their frames. If you want to ensure a component size,
+use getContentPane().setPreferredSize().
+
+
+System.exit(0) does not stop all processes
+------------------------------------------
+
+Although System.ext(int) has been implemented in JavaScript, it just closes the
+frames, stops all pending javax.swing.Timer objects in the queue, and runs any
+threads added using Runtime.getRuntime().addShutdownHook(Thread).
+It may not stop all "threads." So don't rely on that.
+Applications are responsible for shutting down prior to executing System.exit(0).
+
+
+myClass.getField not implemented
+--------------------------------
+
+java.lang.reflect.Field is implemented minimally. It is not
+certain that Field.getDeclaringClass() will work. If you just want a
+value of a field, you can do this:
+
+/**
+ *@j2sNative
+ *
+ * return myClass[name]
+ */
+
+But that is not a java.lang.reflection.Field object.
+
+
+"window" and other reserved JavaScript names
+--------------------------------------------
+
+No reserved top-level JavaScript name is allowed for a package name. So, for example,
+one must rename packages such as "window" or "document" to names such as "win" or "doc".
+
+reserved field and method names
+-------------------------------
+
+In order to minimize the chance of added SwingJS field and method names colliding with ones
+developers might use in subclassing Java classes, we have added U+79D8 (first character of Mandarin
+"secret") to the characters already disrecommended by Java documentation ("$" and "_"). The only problem
+would be if you use that character followed by certain English words in certain classes. For example
+\u79D8canvas for JComponents (in java.awt.JSComponent) and \u79D8byte (in java.io.File).
+
+qualified field and method names
+--------------------------------
+
+Method names in SwingJS are fully qualified, meaning two methods with the same Java name but different
+parameters, such as write(int) and write(double), must not have the same name in JavaScript. (In this
+case, we will have write$I and write$D.) However, in certain cases it may be desirable to leave the
+method names unqualified. In particular, when an interface actually represents a JavaScript object,
+the transpiler can leave a method name unqualified. The default situation for this is a class name
+includes ".api.js" (case-sensitive). This means that any method in any class in a package js within
+a package api, or any private interface js that has an outer interface api, will have all-unqualified
+methods. An example of this is swingjs.plaf.JSComboPopupList, which needs to communicate with a jQuery
+object directly using the following interface:
+
+ private interface api {
+
+ interface js extends JQueryObject {
+
+ abstract js j2sCB(Object options);
+
+ abstract Object[] j2sCB(String method);
+
+ abstract Object[] j2sCB(String method, Object o);
+
+ abstract Object[] j2sCB(String method, int i);
+
+ abstract int j2sCB(String OPTION, String name);
+
+ }
+ }
+
+Notice that all these variants of j2sCB() will call the same method in JavaScript by design.
+
+
+missing Math methods
+--------------------
+
+java.lang.Math is worked out, but some methods are missing, either because they
+involve long integer value that are inaccessible in JavaScript, or because I just
+didn't implement them. This is a result of continued Java development.
+It is easy enough to add these methods if you have the source. They go into j2sClazz.js,
+which is combined with other initial libraries into swingjs2.js by build_site.xml
+
+
+Component.getGraphics(), Graphics.dispose()
+-------------------------------------------
+
+Use of component.getGraphics() is discouraged in Java and in SwingJS.
+Specifically in SwingJS, any call to component.getGraphics() or
+BufferedImage.createGraphics() or Graphics.create(...) should be matched with graphics.dispose(),
+particularly when it is called outside the context of a paint(Graphics)
+call from the system.
+
+If you see your graphics scrolling down the page with each repaint,
+look for where you have used Component.getGraphics() and not Graphics.dispose().
+For example, this will definitely NOT work in SwingJS:
+
+ this.paint(getGraphics())
+
+and really should not work in Java, either, as it is technically a resource memory leak.
+
+Instead, if you really do not want to use repaint(), use this:
+
+ Graphics g = getGraphics();
+ paint(g);
+ g.dispose();
+
+
+
+Graphics.setClip()
+------------------
+
+The HTML5 canvas.clip() method is permanent. You can only reset the clip using
+save/restore. This is different from Java, where you can temporarily change it using
+
+ Shape oldClip = Graphics.getClip();
+ Graphics.setClip(newClip);
+ ...
+ Graphics.setClip(oldClip);
+
+If you need to do something like this, you must schedule the paints
+to not have overlapping clip needs.
+
+
+MAJOR ISSUES--for Bob and Udo within SwingJS
+============================================
+
+fonts
+-----
+
+Fonts and FontMetrics will all be handled in JavaScript. Font matching will
+not be exact, and composite (drawn) fonts will not be supported.
+
+SwingJS handles calls such as font.getFontMetrics(g).stringWidth("xxx") by
+creating a containing that text, placing it in an obscure location on
+the page, and reading div.getBoundingClientRect(). This is a VERY precise
+value, but can be a pixel or two off from what Java reports for the same font.
+
+
+OS-dependent classes
+--------------------
+
+Static classes such as:
+
+ java.awt.Toolkit
+ java.awt.GraphicsEnvironment
+
+
+which are created using Class.forName are implemented using classes in the swingjs package.
+
+AWTAccessor is not implemented.
+
+
+AWT component peers and component "ui" user interfaces
+------------------------------------------------------
+
+ComponentPeer is a class that represents a native AWT component.
+Components with such peers are called "heavy-weight" components.
+They are expected to do the dirty work of graphics drawing.
+
+Java Swing implements peers only for JApplet, JDialog, JFrame, and JWindow.
+References to such objects have been removed, but clearly there must be
+some connection to similar DOM objects, even for "light-weight" components.
+
+
+
+MAJOR ISSUES--to be resolved by implementers
+============================================
+
+fonts
+-----
+
+Glyph/composite/outline fonts are not supported.
+
+
+
+threads
+-------
+
+Thread locking and synchronization are not relevant to JavaScript.
+Thus, anything requiring "notify.." or "waitFor.." could be a serious issue.
+
+All threading must be "faked" in JavaScript. Specifically not available is:
+
+ Thread.sleep()
+
+javax.swing.AbstractButton#doClick(pressTime) will not work, as it requires Thread.sleep();
+
+However, java.lang.Thread itself is implemented and used extensively.
+
+Methods thread.start() and thread.run() both work fine.
+
+For simple applications that use Thread.sleep() just to have a delay, as in a frame rate, for
+example, one can use javax.swing.Timer instead. That is fully implemented.
+
+Likewise, java.util.Timer can be replaced with no loss of performance with javax.Swing.Timer.
+Note that java.util.TimerTask is implemented, but it can also be replaced by an implementation of Runnable.
+
+task = new TimerTask(){....};
+t = new java.util.Timer();
+t.schedule(task, 0, 1);
+
+becomes
+
+task = new TimerTask(){....}; // or task = new Runnable() {...}
+t = new javax.swing.Timer(1, new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ task.run();
+ }
+};
+t.setInitialDelay(0); // not particularly necessary
+t.start();
+
+In addition, SwingJS provides swingjs.JSThread, which can be subclassed
+if desired. This class allows simple
+
+ while(!interrupted()){
+ wait()
+ ...
+ }
+
+action through an asynchronous function run1(mode). For example:
+
+ protected void run1(int mode) {
+ try {
+ while (true)
+ switch (mode) {
+ case INIT:
+ // once-through stuff here
+ mode = LOOP;
+ break;
+ case LOOP:
+ if (!doDispatch || isInterrupted()) {
+ mode = DONE;
+ } else {
+ Runnable r = new Runnable() {
+ public void run() {
+ // put the loop code here
+ }
+ };
+ dispatchAndReturn(r);
+ if (isJS)
+ return;
+ }
+ break;
+ // add more cases as needed
+ case DONE:
+ // finish up here
+ if (isInterrupted())
+ return;
+ // or here
+ break;
+ }
+ } finally {
+ // stuff here to be executed after each loop in JS or at the end in Java
+ }
+ }
+
+image loading
+-------------
+- All image loading in SwingJS is synchronous. A MediaTracker call will immediately return "complete".
+ However, it still may take one system clock tick to fully load images. Thus, it is recommended that
+ images be preloaded in the static block of the applet if it is necessary that they be available in init().
+ This is only an issue if you are trying to access the pixel buffer of the image in JavaScript.
+
+- Applet.getImage(path, name) will return null if the image does not exist.
+
+- BufferedImage: only "support" imageType RGB and ARGB
+
+ -BH: This is a temporary edit, just to get us started. Certainly GRAY will be needed
+
+
+BigInteger and BigDecimal
+-------------------------
+
+java.math.BigInteger is fully supported; java.math.BigDecimal is roughed
+in and not fully tested (07/2019).
+
+Both classes present significant issues for JavaScript, as they are based in
+Java's 64-bit long for all their operations. Here is the JavaDoc note I added
+to BigInteger:
+
+ * SwingJS note: Because of the limitations of JavaScript with regard
+ * to long-integer bit storage as a double, this implementation drops
+ * the integer storage bit length to 24, giving 48 for long and leaving
+ * the last 16 bits clear for the exponent of the double number. This should
+ * not affect performance significantly. It does increase the storage
+ * size by about 33%. By bringing an "int" to 3 bytes, we can easily construct
+ * and use byte[] data intended for the original BitSet.
+
+"Easily" may be a bit strong there. This was a serious challenge.
+
+BigDecimal seems to run normally, but in order to do that, my hack involves
+reducing the size of an integer that is allowed to be stored as such and not
+in byte[] as a BigInteger. I'm sure there is a performance hit, but it does work.
+
+no format internationalization
+------------------------------
+
+For now, just en for number and date formatters
+
+no winding rules
+----------------
+
+ When filling a graphic, only nonzero winding rule is implemented in HTML5 Canvas2D.
+
+
+
+text-related field implementation
+---------------------------------
+
+Text fields are:
+
+JTextField (JavaScript
)
+JTextArea (JavaScript