Merge branch 'develop' into bug/JAL-1803_JAL-2157
authorJim Procter <jprocter@issues.jalview.org>
Wed, 7 Sep 2016 11:46:28 +0000 (12:46 +0100)
committerJim Procter <jprocter@issues.jalview.org>
Wed, 7 Sep 2016 11:46:28 +0000 (12:46 +0100)
48 files changed:
examples/exampleFeatures.txt
help/helpTOC.xml
help/html/features/chimera.html
help/html/features/dasfeatures.html
help/html/features/jmol.html
help/html/features/mmcif.html
help/html/features/pdbviewer.html
help/html/features/seqfeatures.html
help/html/features/seqfetch.html
help/html/features/seqmappings.html
help/html/features/siftsmapping.html
help/html/features/structurechooser.html
help/html/features/uniprotsequencefetcher.html
help/html/features/viewingpdbs.html
help/html/menus/alignmentMenu.html
help/html/menus/alwfile.html
help/html/menus/desktopMenu.html
help/html/releases.html
help/html/webServices/dbreffetcher.html
help/html/whatsNew.html
src/MCview/PDBViewer.java
src/jalview/analysis/NJTree.java
src/jalview/api/AlignViewportI.java
src/jalview/appletgui/SeqPanel.java
src/jalview/appletgui/TreeCanvas.java
src/jalview/datamodel/SequenceGroup.java
src/jalview/ext/jmol/JmolParser.java
src/jalview/gui/AlignFrame.java
src/jalview/gui/AnnotationLabels.java
src/jalview/gui/AnnotationPanel.java
src/jalview/gui/CutAndPasteHtmlTransfer.java
src/jalview/gui/CutAndPasteTransfer.java
src/jalview/gui/Desktop.java
src/jalview/gui/FeatureSettings.java
src/jalview/gui/IdPanel.java
src/jalview/gui/OptsAndParamsPage.java
src/jalview/gui/ScalePanel.java
src/jalview/gui/SeqPanel.java
src/jalview/gui/TreeCanvas.java
src/jalview/io/vamsas/Tree.java
src/jalview/jbgui/GAlignFrame.java
src/jalview/jbgui/GCutAndPasteHtmlTransfer.java
src/jalview/jbgui/GCutAndPasteTransfer.java
src/jalview/util/Platform.java
src/jalview/viewmodel/AlignmentViewport.java
test/jalview/gui/MouseEventDemo.java [new file with mode: 0644]
test/jalview/io/NewickFileTests.java
utils/checkstyle/import-control.xml

index c0098a9..689cd43 100755 (executable)
@@ -26,11 +26,11 @@ BETA-TURN-IIL       8b5b50
 ST-MOTIF       ac25a1
 
 STARTGROUP     uniprot
-<html><a href="http://pfam.xfam.org/family/PF00111">Pfam family</a></html>     FER_CAPAA       -1      0       0       Pfam
 Iron-sulfur (2Fe-2S)   FER_CAPAA       -1      39      39      METAL
 Iron-sulfur (2Fe-2S)   FER_CAPAA       -1      44      44      METAL
 Iron-sulfur (2Fe-2S)   FER_CAPAA       -1      47      47      METAL
 Iron-sulfur (2Fe-2S)   FER_CAPAA       -1      77      77      METAL
+<html><a href="http://pfam.xfam.org/family/PF00111">Pfam family</a></html>     FER_CAPAA       -1      0       0       Pfam
 <html>Fer2 Status: True Positive <a href="http://pfam.xfam.org/family/PF00111">Pfam 8_8</a></html>     FER_CAPAA       -1      8       83      Pfam
 Ferredoxin_fold Status: True Positive  FER_CAPAA       -1      3       93      Cath
 Iron-sulfur (2Fe-2S)   FER_CAPAN       -1      86      86      METAL
index fe8e1a9..f5b28f7 100755 (executable)
                        <tocitem text="PDB Sequence Fetcher" target="pdbfetcher" />
                        <tocitem text="PDB Structure Chooser" target="pdbchooser" />
                        <tocitem text="Jmol Viewer" target="pdbjmol" />
-                       <tocitem text="Chimera Viewer" target="chimera" />
-                       <tocitem text="Simple PDB Viewer" target="pdbmcviewer" />
+                       <tocitem text="Chimera Viewer" target="chimera" />                      
                </tocitem>
                <tocitem text="Viewing RNA structures" target="varna" expand="false"/>
                <tocitem text="VAMSAS Data Exchange" target="vamsas">
index 39dff75..0569513 100644 (file)
         </strong><em> Colours each residue in the structure with the colour
             of its corresponding residue in the associated sequence as
             rendered in the associated alignment views, including any
-            Uniprot sequence features or region colourings.<br />Pick
+            UniProt sequence features or region colourings.<br />Pick
             which of the associated alignment views are used to colour
             the structures using the <strong>View&#8594;Colour
               by ..</strong> sub menu.
index 90958ae..32408ee 100644 (file)
     </li>
   </ol>
   <p>
-    If your DAS source selection contains sources which use Uniprot
-    accession ids, you will be asked whether Jalview should find Uniprot
+    If your DAS source selection contains sources which use UniProt
+    accession ids, you will be asked whether Jalview should find UniProt
     Accession ids for the given sequence names. It is important to
-    realise that many DAS sources only use Uniprot accession ids, rather
-    than Swissprot/Uniprot sequence names.<br> The <a
+    realise that many DAS sources only use UniProt accession ids, rather
+    than Swissprot/UniProt sequence names.<br> The <a
       href="../webServices/dbreffetcher.html"
     >database reference fetcher</a> documentation describes how Jalview
     discovers what database references are appropriate for the sequences
index 3fa1563..3141aae 100644 (file)
         </strong><em> Colours each residue in the structure with the colour
             of its corresponding residue in the associated sequence as
             rendered in the associated alignment views, including any
-            Uniprot sequence features or region colourings.<br />Pick
+            UniProt sequence features or region colourings.<br />Pick
             which of the associated alignment views are used to colour
             the structures using the <strong>View&#8594;Colour
               by ..</strong> sub menu.
index 6df0fd4..e67f5cd 100644 (file)
@@ -5,24 +5,30 @@
 <title>mmCIF File Format</title>
 </head>
 <body>
-       <strong>mmCIF File Format</strong>
-       <p>The mmCIF file format (macromolecular Crystallographic
-               Information) was developed under the auspices of the International Union of Crystallography (IUCr) to extend the Crystallographic Information
-               File (CIF) data representation used for describing small molecule
-               structures and associated diffraction experiments.</p>
-       <strong>Merits of mmCIF file format</strong>
-       <ul>
-               <li>Large structures (containing >62 chains and/or 99999 ATOM
-                       records) that cannot be fully represented in the PDB file format are
-                       available in the PDB archive as single PDBx/mmCIF files.</li>
-               <li>PDBx/mmCIF file format provides richer data annotation</li>         
-               <li>PDBx/mmCIF became the standard PDB archive format in 2014.
-                       Since 2016 the PDB File Format is no longer being modified or
-                       extended to support new content.
-               </li>
-       </ul>
+  <strong>What is mmCIF ?</strong>
+  <br />mmCIF stands for 'macro-molecular Crystallographic Information
+  File'. This format was developed by the PDB consortium and the
+  International Union of Crystallography (IUCr), based on
+  Crystallographic Information File (CIF), a format used for describing
+  the structures of small molecules.<br/>mmCIF became the recommended format
+  for the exchange of biomacromolecular structures in 2014.
+  <p>
+    <strong>mmCIF and Jalview</strong> <br />Since Jalview 2.10, mmCIF
+    is used for structures downloaded from the PDB. This means:
+  </p>
+  <ol>
+    <li>Jalview can use the mmCIF to read structures that are too
+      large to be represented by a single PDB file. (ie, with more than
+      >62 chains and/or 99999 ATOM records).</li>
+    <li>Jalview users will have access to the richer annotation
+      provided by PDBx/mmCIF files.</li>
+    <li>There may be slight differences between sequences
+      containing modified residues for structures downloaded in mmCIF
+      format. This is because mmCIF differs from the PDB format in the
+      way it describes non-standard sequence data.</li>
+  </ol>
 
-       <em>mmCIF file format support for importing 3D structure data from
-               flat file and EMBL-PDBe via mmCIF was added in Jalview 2.9.1</em>
+  <em>Support for importing 3D structure data from flat file and
+    EMBL-PDBe as mmCIF was added in Jalview 2.10</em>
 </body>
 </html>
\ No newline at end of file
index fd13f57..eca218a 100755 (executable)
         </strong><em> Colours each residue in the structure with the colour
             of its corresponding residue in the associated sequence as
             rendered in the associated alignment view, including any
-            Uniprot sequence features or region colourings.<br>
+            UniProt sequence features or region colourings.<br>
             Residues which only exist in the PDB structure are coloured
             white if they are insertions (relative to the associated
             sequence in the alignment) and grey if they are N or C
index 0ec5f3b..cf79858 100755 (executable)
@@ -29,7 +29,7 @@
   <p>
     Jalview can colour parts of a sequence based on the presence of
     sequence features - which may be retrieved from database records
-    (such as Uniprot), the result of <a href="search.html">sequence
+    (such as UniProt), the result of <a href="search.html">sequence
       motif searches</a> or simply read from a <a href="featuresFormat.html">sequence
       features file</a>. You can also <a href="creatinFeatures.html">create
       features</a> from the results of searches or the current selection,
@@ -54,7 +54,7 @@
   <p>
     Since Jalview 2.08, sequence features assigned to a sequence can be
     organised into groups, which may indicate that the features were all
-    retrieved from the same database (such as Uniprot features), or
+    retrieved from the same database (such as UniProt features), or
     generated by the same analysis process (as might be specified in a <a
       href="featuresFormat.html"
     >sequence features file</a>).
index 4aa7234..ff5c1b0 100755 (executable)
@@ -87,7 +87,7 @@
   </p>
 
   <p>If you use the WSDBFetch sequence fetcher services (EMBL,
-    Uniprot, PFAM, and RFAM) in work for publication, please cite:</p>
+    UniProt, PFAM, and RFAM) in work for publication, please cite:</p>
   <p>
     Pillai S., Silventoinen V., Kallio K., Senger M., Sobhany S., Tate
     J., Velankar S., Golovin A., Henrick K., Rice P., Stoehr P., Lopez
index 60ac6ab..b88aefc 100644 (file)
@@ -25,7 +25,7 @@
 <body>
   <p>
     <strong>Mapping Between Different Sequences</strong>
-  </p>
+  </p><!--  TODO: review and check if this page is really needed -->
   <p>A new feature in Jalview 2.3 is the ability to map between
     sequences in different domains, based on alignment, or by the use of
     explicit mappings provided by databases.</p>
     correspondence between DNA and protein sequences. This mapping can
     be imported directly from EMBL and EMBLCDS database records
     retrieved by the <a href="seqfetch.html">Sequence Fetcher</a>, and
-    allows sequence features to be mapped directly from Uniprot das
+    allows sequence features to be mapped directly from UniProt das
     sources to their coding region on EMBL sequence records.
   </p>
-   <p>In Jalview 2.9.1 <a href="siftsmapping.html">SIFTS Mapping</a> was added as a better means for explicitly identifying the coordinates corresponding to a displayed sequence when viewing a PDB structure associated with a sequence </p>
+  <em><a href="siftsmapping.html">SIFTS Mapping</a> between PDB and
+    UniProt data was introduced in Jalview 2.10</em>
 </body>
 </html>
index 08089ad..80c0294 100644 (file)
@@ -2,65 +2,69 @@
 <html>
 <head>
 <meta charset="UTF-8">
-<title>SIFTS Mapping</title>
+<title>SIFTS Mapping from UniProt for PDB Structures</title>
 </head>
 <body>
-  <p><strong>SIFTS Mapping</strong></p>
-  
+
   <p>
-       SIFTS (Structure Integration with Function, Taxonomy
-       and Sequences) provides an up-to-date resource for residue-level
-       mapping between Uniprot and PDB entries. The information is updated and
-       released weekly simultaneously with the release of new PDB entries.
-       SIFTS Entries are published as XML files and made publicly available via an FTP
-       site hosted at the European Bioinformatics Institute. 
+    <strong>SIFTS Mapping for UniProt sequences and PDB
+      Structures</strong><br /> SIFTS (Structure Integration with Function,
+    Taxonomy and Sequences) is a database of residue-level mappings
+    between UniProt protein sequences, and protein structures found in
+    the PDB. The database is updated for each PDB release, and is
+    provided by the <a href="https://www.ebi.ac.uk/pdbe/docs/sifts/">PDBe
+      at EMBL-EBI</a>.
   </p>
-       
+  <p>When Jalview imports PDB data for a protein sequence found in
+    UniProt, either via the 'View 3D Structure...' option, or the 'Fetch
+    DB Refs' web services menu, Jalview will also download its SIFTS
+    record and use that information to construct a mapping between the
+    sequence and downloaded structure.</p>
+  <p>If, for some reason, no SIFTS mapping data exists, then Jalview
+    will generate a mapping using its built-in Needleman and Wunsch
+    global alignment algorithm. This method of mapping was used for all
+    structures prior to version 2.10.
   <p>
-    At the point of viewing a PDB structure, if the default mapping method is set as 'SIFTS', 
-    Jalview will download a SIFTS file 
-       for the target entry and uses it to accurately map the sequence residues with the 
-       structure residue. Prior to SIFTS integration, Jalview uses Needleman and Wunsch 
-       Alignment algorithm to  map sequence residues to structure residues, and that may not 
-       always result to a correct mapping since it is computational determined.        
+    <strong>Controlling and troubleshooting SIFTS mappings</strong> <br />
+    Configuration options controlling whether SIFTS mappings are used
+    can be found in the <strong>Tools &rarr; Preferences &rarr;
+      Structure tab</strong>, under 'Sequence &harr; Structure method'.<br /> <em>Note:</em>
+    Changing the configuration will only affect how new mappings are
+    created. In order to recompute mappings for structures already
+    loaded, please reload the sequence & structural data.
   </p>
-  
+
   <p>
-  <strong>Configuration</strong><br/>
-       The default mapping method can be configured via <strong>Tools &rarr; Preferences &rarr; 
-       Structure tab</strong> Then scroll to the 'Sequence &harr; Structure method' section of 
-       the dialog box and change the default method. When 'SIFTS' is enabled as the default, all 
-       mappings between 'Sequence &harr; Structure' is performed via SIFTS provided that there 
-       is a valid SIFTS resource for the PDB entry. If no valid SIFTS resource is available, then 
-       the 'Sequence &harr; Structure' mapping falls back to Needleman and Wunsch Alignment algorithm.
-  </p>
-       
-  <p><strong>Multi-Chain Mappings</strong>
-  <br/>One of the main merits of SIFTS is the ability to accurately achieve multi-chain mapping 
-  (one-to-many) between a single Uniprot sequence and its corresponding multiple chains in 
-  PDB. Consequently, mousing over the uniprot sequence in the alignment window results 
-  to highlighting multiple corresponding positions in the structure viewer for the mapped chains. 
+    <strong>Multi-Chain Mappings</strong> <br />SIFTS gives Jalview the
+    ability to display multi-chain mappings between UniProt sequences
+    and PDB structure data. This is important when working with
+    multimeric proteins, since the biological unit will contain several
+    structures for the same protein sequence. Multi-chain mapping allows
+    all residues in a structure to be located in the alignment, and
+    also, when shading the structure by sequence colours, enables
+    conservation patterns between oligomer interfaces to be explored.
   </p>
+  <p>To see this in action, load uniprot sequence for FER1_MAIZE
+    then veiw PDB structure for 3B2F, you will notice that mousing over
+    the sequence results to two positions being highlighted in the
+    structure, also colouring the sequence transfers the color to all
+    the mapped chains in the structure.</p>
+
   <p>
-  To see this in action, load uniprot sequence for FER1_MAIZE then veiw PDB structure for 3B2F, you
-  will notice that mousing over the sequence results to two positions being highlighted in the 
-  structure, also colouring the sequence transfers the color to all the mapped chains in the structure.
-  </p>
-  
+    <Strong>Viewing Mapping Output</Strong> <br /> The mapping provided
+    by the SIFTS record is accessible via <strong>File &rarr;
+      View mapping</strong> menu of the structure viewers. The screenshot below
+    is the mapping output for the <Strong>{FER1_MAIZE &harr;
+      3B2F}</Strong> example described above, and confirms that all two chains
+    were mapped. The mapping method used can be seen within the area
+    highlighted with red boarder.
   <p>
-  <Strong>Viewing Mapping Output</Strong> <br/>
-  The mapping output is accessible via <strong>File &rarr; View mapping</strong> menu of the structure 
-  viewers. The screenshot below is the mapping output for the <Strong>{FER1_MAIZE &harr; 3B2F}</Strong> 
-  example described above. Observe that all the two chains were mapped. The mapping method used can be 
-  seen within the area highlighted with red boarder. This is useful for visually ascertaining the 
-  mapping method when in doubt.    
+
+    &emsp;<img src="sifts_mapping_output.png" align="left"
+      alt="SIFTS mapping output" />
   <p>
-       
-       &emsp;<img src="sifts_mapping_output.png" align="left" alt="SIFTS mapping output" />
-       
-  <p><em>SIFTS Mapping integration was added in Jalview 2.9.1</em></p>
-       
+    <em>SIFTS Mapping integration was added in Jalview 2.10</em>
+  </p>
+
 </body>
 </html>
\ No newline at end of file
index 296a751..f5f5916 100644 (file)
@@ -75,7 +75,7 @@
   structures using various metric categories avaialble from the
   meta-data of the structures. To perform this simply select any of the
   following options from the drop-down menu in the Structure Chooser
-  interface: Best Uniprot coverage, Higest Resolution, Best Quality,
+  interface: Best UniProt coverage, Higest Resolution, Best Quality,
   Highest Protein Chain etc. When the 'Invert' option is selected,
   Jalview returns an inverse result for the current selected option in
   the drop-down menu.
index 9b2e3fa..77f7b60 100644 (file)
  * The Jalview Authors are detailed in the 'AUTHORS' file.
  -->
 <head>
-<title>The Uniprot Free Text Search Interface</title>
+<title>The UniProt Free Text Search Interface</title>
 </head>
 <body>
 
-  <strong>The Uniprot Free Text Search Interface</strong>
+  <strong>The UniProt Free Text Search Interface</strong>
+  <br /> Since version 2.10 (September 2016), the Jalview Desktop
+  provides a search interface for interactive discovery and retrieval of
+  sequence data from UniProt. This dialog enables UniProt sequence
+  metadata to be searched with free text and structured queries, which
+  allows sequences to be located via gene name, keywords, or even
+  <em>via</em> manual cross-referencing from UniProt or other
+  bioinformatics websites.
   <p>
-    Jalview provides a specialised interface that allows fast and
-    efficient discovery and retrieval of data from the Uniprot database.
-    It allows
-    interactive querying of Uniprot metadata with free text and structured
-    queries, so sequences can be located without prior knowledge of
-    their database accessions, or <em>via</em> manual cross-referencing
-    from Uniprot or other bioinformatics websites.
+    To open the UniProt Sequence Fetcher, select UniProt as the database
+    from any <a href="seqfetch.html">Sequence Fetcher</a> dialog (opened
+    <em>via</em> <strong>&quot;File &#8594;Fetch
+      Sequences&quot;</strong>).
   </p>
   <p>
-    To open the UniProt Sequence Fetcher, select UniProt as the database from
-    any <a href="seqfetch.html">Sequence Fetcher</a> dialog (opened <em>via</em>
-    <strong>&quot;File &#8594;Fetch Sequences&quot;</strong>).
-  </p>
-  <p>
-  <img src="uniprotseqfetcher.png" align="left"
-    alt="Uniprot sequence fetcher (introduced in Jalview 2.9.1)"
-  />
+    <img src="uniprotseqfetcher.png" align="left"
+      alt="UniProt sequence fetcher (introduced in Jalview 2.10)" />
   </p>
 
   <p>
-    <strong>Searching the Uniprot Database</strong>
+    <strong>Searching the UniProt Database</strong>
   </p>
   <p>
-    To search the Uniprot, begin typing in the text box. The results of your
-    query are shown in the search results tab, which queries Uniprot after 1.5secs every time
-    you type in the search text box. You can sort results according to
-    the displayed columns, and select entries with the mouse or
-    keyboard. Once you have selected one or more entries, hit the <strong>OK</strong>
-    button to retrieve and visualise the sequences in Jalview Alignment interface.
+    To search UniProt, simply begin typing in the text box. After a
+    short delay (uabout 1.5 seconds), results will be shown in the table
+    below. You can sort results by clicking on the displayed columns,
+    and select entries with the mouse or keyboard. Once you have
+    selected one or more entries, hit the <strong>OK</strong> button to
+    retrieve the sequences.
   </p>
   <ul>
-    <li><strong>Searching a specific Uniprot field </strong> If you
-      want to find sequences based on a specific Uniprot metadata field,
-      you can select it from the drop-down menu.</li>
-      
+    <li><strong>Searching a specific UniProt field </strong> To
+      find sequences with particular UniProt metadata, you can select a
+      field to search from the drop-down menu.</li>
+
+
+    <li><strong>Bulk UniProt record retrieval</strong><br> To
+      retrieve several uniprot accessions at once, first select <strong>UniProt
+        ID</strong> from the dropdown menu, then paste in the accession IDs as a
+      semi-colon separated list. (e.g. fila_human; mnt_human;
+      mnt_mouse).<br />Hitting Return or OK will automatically fetch
+      those IDs, like the default Sequence Fetcher interface.</li>
 
-               <li><strong>Bulk Uniprot retrieval</strong><br>
-      Firstly, switch the search target to Uniprot Id, then enter multiple IDs by separating them with a semi-colon.
-      e.g. fila_human; mnt_human; mnt_mouse.<br />Hitting Return or OK will automatically
-      fetch those IDs, like the default Sequence Fetcher interface.</li>
-      
-            <li><strong>Advanced / Custom querying</strong>  
-      The table below provides a brief overview of the supported Uniprot query syntax (see <a href="uniprotqueryfields.html">query fields for UniProtKB</a>):
-               <table border="1" width="95%">
-                               <tr>
-                                       <td><code>human antigen</code></td>
-                                       <td rowspan="3">All entries containing both terms.</td>
-                               </tr>
-                               <tr>
-                                       <td><code>human AND antigen</code></td>
-                               </tr>
-                               <tr>
-                                       <td><code>human &amp;&amp; antigen</code></td>
-                               </tr>
-                               <tr>
-                                       <td><code>"human antigen"</code></td>
-                                       <td>All entries containing both terms in the exact order.</td>
-                               </tr>
-                               <tr>
-                                       <td><code>human -antigen</code></td>
-                                       <td rowspan="3">All entries containing the term <code>human</code>
-                                               but not <code>antigen</code>.
-                                       </td>
-                               </tr>
-                               <tr>
-                                       <td><code>human NOT antigen</code></td>
-                               </tr>
-                               <tr>
-                                       <td><code>human ! antigen</code></td>
-                               </tr>
-                               <tr>
-                                       <td><code>human OR mouse</code></td>
-                                       <td rowspan="2">All entries containing either term.</td>
-                               </tr>
-                               <tr>
-                                       <td><code>human || mouse</code></td>
-                               </tr>
-                               <tr>
-                                       <td><code>antigen AND (human OR mouse)</code></td>
-                                       <td>Using parentheses to override boolean precedence rules.</td>
-                               </tr>
-                               <tr>
-                                       <td><code>anti*</code></td>
-                                       <td>All entries containing terms starting with <code>anti</code>.
-                                               Asterisks can also be used at the beginning and within terms. <strong>Note:</strong>
-                                               Terms starting with an asterisk or a single letter followed by an
-                                               asterisk can slow down queries considerably.
-                                       </td>
-                               </tr>
-                               <tr>
-                                       <td><code> author:Tiger*</code></td>
-                                       <td>Citations that have an author whose name starts with <code>Tiger</code>.
-                                               To search in a specific field of a dataset, you must prefix your
-                                               search term with the field name and a colon. To discover what
-                                               fields can be queried explicitly, observe the query hints that are
-                                               shown after submitting a query or use the query builder (see
-                                               below).
-                                       </td>
-                               </tr>
-                               <tr>
-                                       <td><code>length:[100 TO *]</code></td>
-                                       <td>All entries with a sequence of at least 100 amino acids.</td>
-                               </tr>
-                               <tr>
-                                       <td><code>citation:(author:Arai author:Chung)</code></td>
-                                       <td>All entries with a publication that was coauthored by two
-                                               specific authors.</td>
-                               </tr>
-                       </table>
-               </li>
-</ul>
+    <li><strong>Complex queries with the UniProt query
+        Syntax</strong> The text box also allows complex queries to be entered.
+      The table below provides a brief overview of the supported syntax
+      (see <a href="uniprotqueryfields.html">query fields for
+        UniProtKB</a>):
+      <table border="1" width="95%">
+        <tr>
+          <td><code>human antigen</code></td>
+          <td rowspan="3">All entries containing both terms.</td>
+        </tr>
+        <tr>
+          <td><code>human AND antigen</code></td>
+        </tr>
+        <tr>
+          <td><code>human &amp;&amp; antigen</code></td>
+        </tr>
+        <tr>
+          <td><code>"human antigen"</code></td>
+          <td>All entries containing both terms in the exact order.</td>
+        </tr>
+        <tr>
+          <td><code>human -antigen</code></td>
+          <td rowspan="3">All entries containing the term <code>human</code>
+            but not <code>antigen</code>.
+          </td>
+        </tr>
+        <tr>
+          <td><code>human NOT antigen</code></td>
+        </tr>
+        <tr>
+          <td><code>human ! antigen</code></td>
+        </tr>
+        <tr>
+          <td><code>human OR mouse</code></td>
+          <td rowspan="2">All entries containing either term.</td>
+        </tr>
+        <tr>
+          <td><code>human || mouse</code></td>
+        </tr>
+        <tr>
+          <td><code>antigen AND (human OR mouse)</code></td>
+          <td>Using parentheses to override boolean precedence
+            rules.</td>
+        </tr>
+        <tr>
+          <td><code>anti*</code></td>
+          <td>All entries containing terms starting with <code>anti</code>.
+            Asterisks can also be used at the beginning and within
+            terms. <strong>Note:</strong> Terms starting with an
+            asterisk or a single letter followed by an asterisk can slow
+            down queries considerably.
+          </td>
+        </tr>
+        <tr>
+          <td><code> author:Tiger*</code></td>
+          <td>Citations that have an author whose name starts with
+            <code>Tiger</code>. To search in a specific field of a
+            dataset, you must prefix your search term with the field
+            name and a colon. To discover what fields can be queried
+            explicitly, observe the query hints that are shown after
+            submitting a query or use the query builder (see below).
+          </td>
+        </tr>
+        <tr>
+          <td><code>length:[100 TO *]</code></td>
+          <td>All entries with a sequence of at least 100 amino
+            acids.</td>
+        </tr>
+        <tr>
+          <td><code>citation:(author:Arai author:Chung)</code></td>
+          <td>All entries with a publication that was coauthored by
+            two specific authors.</td>
+        </tr>
+      </table></li>
+  </ul>
   <p>
     <strong>Result pagination</strong>
   </p>
-  The query results returned from the Uniprot server are paginated for performance optimisation. 
-  The button labelled <strong>'&nbsp;&lt;&lt;&nbsp;'</strong> and <strong>'&nbsp;&gt;&gt;&nbsp;'</strong> can be used to navigate to the next or previous result page respectively. 
-  The page range is shown on the title bar of the Free Text Search interface. Jalview's pagination implementation supports multiple selection of entries across multiple pages. 
-  
-  
- <p>
-    <strong>Customising The Uniprot Sequence Fetcher</strong>
-  </p>
+  The query results returned from the UniProt server are paginated for
+  performance optimisation. The button labelled
+  <strong>'&nbsp;&lt;&lt;&nbsp;'</strong> and
+  <strong>'&nbsp;&gt;&gt;&nbsp;'</strong> can be used to navigate to the
+  next or previous result page respectively. The page range is shown on
+  the title bar of the Free Text Search interface. Jalview's pagination
+  implementation supports multiple selection of entries across multiple
+  pages.
+
+
   <p>
-    To change the displayed meta-data in the search result, click the
-    'Customise Displayed Options' tab, and select the fields you'd like
-    to displayed or remove. 
+    <strong>Customising The UniProt Sequence Fetcher</strong>
   </p>
+  <p>To change the displayed meta-data in the search result, click
+    the 'Customise Displayed Options' tab, and select the fields you'd
+    like to displayed or remove.</p>
   <p>
-    <em>The Uniprot Free Test Search Interface was introduced in
-      Jalview 2.9.1</em>
+    <em>The UniProt Free Test Search Interface was introduced in
+      Jalview 2.10.0</em>
   </p>
 </body>
 </html>
\ No newline at end of file
index d4819f1..e62b2a7 100755 (executable)
 </head>
 <body>
   <p>
-    <strong>Viewing PDB Structures</strong>
+    <strong>Discovering and Viewing PDB Structures</strong>
   </p>
-  Jalview can be used to view protein structures by following the steps
-  below:
+  Jalview can be used to explore the 3D structures of sequences in an
+  alignment by following the steps below:
   <ol>
     <li>Select the <strong>"3D Structure Data..."</strong> option
       from a sequence's <a href="../menus/popupMenu.html">pop-up
           pane.
         </li>
         <li>However, if no structure was found, the <a
-          href="structurechooser.html"
-        >Structure Chooser</a> interface will present options for manual
-          association of PDB structures.
+          href="structurechooser.html">Structure Chooser</a> interface
+          will present options for manual association of PDB structures.
         </li>
       </ul>
     </li>
-    <li><strong>Selecting Structures</strong><br /> If structures
-      have been discovered, then some will already be selected according
-      to predefined selection criteria, such as structures with the
-      highest resolution. Use the drop down menu to select structures
-      according to different criteria, or, alternatively, choose
-      structures manually by selecting with the keyboard and mouse.
+    <li><strong>Selecting Structures</strong><br />You can select
+      the structures to you want to open and view by selecting them with
+      the mouse and keyboard.<br />By default, if structures were
+      discovered, then some will already be selected according to the
+      criteria shown in the drop-down menu. The default criteria is
+      'highest resolution', simply choose another to pick structures in
+      a different way.<br />
       <ul>
         <li><strong>Viewing Cached Structures</strong><br />If you
           have previously downloaded structures for your sequences, they
@@ -89,9 +89,8 @@
 
     <li>If another structure is already shown for the current
       alignment, then you will be asked if you want to add and <a
-      href="jmol.html#align"
-    >align this structure</a> to the structure in the existing view. (<em>new
-        feature in Jalview 2.6</em>).
+      href="jmol.html#align">align this structure</a> to the structure
+      in the existing view. (<em>new feature in Jalview 2.6</em>).
     </li>
 
     <li>If the structure is already shown, then you will be
 
 
   <p>
-    <strong>Importing PDB Entries or files in PDB format</strong><br>
-    You can retrieve sequences from the PDB using the <a
-      href="pdbsequencefetcher.html"
-    >Sequence Fetcher</a>. Any sequences retrieved with this service are
-    automatically associated with their source database entry. For PDB
-    sequences, simply select PDB as the database and enter your known
-    PDB id (appended with ':' and a chain code, if desired).<br>
-    Jalview will also read PDB files directly. Simply load in the file
-    as you would an alignment file. The sequences of any protein or
-    nucleotide chains will be extracted from the file and viewed in the
-    alignment window.
+    <strong>Retrieving sequences from the PDB</strong><br>You can
+    retrieve sequences from the PDB using the <a
+      href="pdbsequencefetcher.html">Sequence Fetcher</a>. The sequences
+    retrieved with this service are derived directly from the PDB 3D
+    structure data, which can be viewed in the same way above. Secondary
+    structure and temperature factor annotation can also be added. <br />
   </p>
-
   <p>
-    <strong>Importing PDB Entries or files in mmCIF format</strong><br>
-    <a href="mmcif.html">mmCIF file format</a> provides an alternative means for 
-    importing 3D structure data from flat file and EMBL-PDBe 
-    web-service. To enable mmCIF as the default format for 
-    importing PBD sequences from the PDB sequence fetcher, add or modify the 
-    property  
-    <code>DEFAULT_STRUCTURE_FORMAT=mmCIF</code> in Jalview properties file. 
-    Once this is done, the steps followed in retrieving PDB format files above can 
-    be followed to obtain the same data with mmCIF. <em>mmCIF format file support was added in Jalview 2.9.1.</em></p>
-    
-   
+    <strong>Retrieving sequences from the PDB</strong><br>Jalview
+    will also read PDB files directly - either in PDB format, or <a
+      href="mmcif.html">mmCIF</a>. Simply load in the file as you would
+    an alignment file. The sequences of any protein or nucleotide chains
+    will be extracted from the file and viewed in the alignment window.
+  </p>
 
   <p>
     <strong>Associating a large number of PDB files to
     desktop, Jalview will give you the option of associating PDB files
     with sequences that have the same filename. This means, for example,
     you can automatically associate PDB files with names like '1gaq.pdb'
-    with sequences that have an ID like '1gaq'. <br />
-    <em>Note: This feature was added in Jalview 2.7</em>
+    with sequences that have an ID like '1gaq'. <br /> <em>Note:
+      This feature was added in Jalview 2.7</em>
   </p>
   <p>
     <em>Note for Jalview applet users:<br> Due to the applet
       Features"</strong> menu item and the <a href="featuresettings.html">Feature
       Settings dialog box</a>.
   </p>
+  <br/>
+  <hr>
+  <p>
+    <strong>Switching between mmCIF and PDB format for
+      downloading files from the PDB</strong><br /> Jalview now employs the <a
+      href="mmcif.html">mmCIF format</a> for importing 3D structure data
+    from flat file and EMBL-PDBe web-service, as recommended by the
+    wwwPDB. If you prefer (for any reason) to download data as PDB files
+    instead, then first close Jalview, and add the following line to
+    your .jalview_properties file:<br />
+    <code> DEFAULT_STRUCTURE_FORMAT=PDB </code>
+    <br /> When this setting is configured, Jalview will only request
+    PDB format files from EMBL-EBI's PDBe.<br /> <em>mmCIF format
+      file support was added in Jalview 2.10.</em>
+  </p>
 
   <p>
     <em><strong>Outstanding problem with cut'n'pasted
-        files in Jalview 2.6 and Jalview 2.7</strong><br> Structures
-      imported via the cut'n'paste dialog box will not be correctly
-      highlighted or coloured when they are displayed in structure
-      views, especially if they contain more than one PDB structure. See
-      the bug report at http://issues.jalview.org/browse/JAL-623 for
-      news on this problem.</em>
+        files in Jalview 2.6 and Jalview 2.7</strong><br>Structures imported
+      via the cut'n'paste dialog box will not be correctly highlighted
+      or coloured when they are displayed in structure views, especially
+      if they contain more than one PDB structure. See the bug report at
+      http://issues.jalview.org/browse/JAL-623 for news on this problem.</em>
   </p>
+
 </body>
 </html>
 
index ce339cc..5739797 100755 (executable)
@@ -33,7 +33,7 @@
       <ul>
         <li><strong>Fetch Sequence</strong><br> <em>Shows
             a dialog window in which you can retrieve known ids from
-            Uniprot, EMBL, EMBLCDS, PFAM, Rfam, or PDB database using
+            UniProt, EMBL, EMBLCDS, PFAM, Rfam, or PDB database using
             Web Services provided by the European Bioinformatics
             Institute. See <a href="../features/seqfetch.html">Sequence
               Fetcher</a>
index 10d510d..bf1ba90 100755 (executable)
@@ -29,7 +29,7 @@
   </p>
   <ul>
     <li><strong>Fetch Sequence</strong><br> <em>Shows a
-        dialog window in which you can select known ids from Uniprot,
+        dialog window in which you can select known ids from UniProt,
         EMBL, EMBLCDS, PDB, PFAM, or RFAM databases using Web Services
         provided by the European Bioinformatics Institute. See <a
         href="../features/seqfetch.html"
index edbd1e9..1ccbbcf 100755 (executable)
@@ -43,7 +43,7 @@
           </ul></li>
         <li><strong>Fetch Sequence<br>
         </strong><em>Shows a dialog window in which you can select known ids
-            from Uniprot, EMBL, EMBLCDS or PDB database using Web
+            from UniProt, EMBL, EMBLCDS or PDB database using Web
             Services provided by the European Bioinformatics Institute.</em></li>
         <li><strong>Save Project</strong><br> <em>Saves
             all currently open alignment windows with their current view
index 5a5020a..c4a8bab 100755 (executable)
@@ -47,7 +47,7 @@
     <tr>
       <td width="60" nowrap>
         <div align="center">
-          <strong><a name="Jalview.2.9.1">2.9.1</a><br /> <em>21/6/2016</em></strong>
+          <strong><a name="Jalview.2.10.0">2.10.0</a><br /> <em>13/9/2016</em></strong>
         </div>
       </td>
       <td><em>General</em>
         </ul> <em>Application</em>
         <ul>
             <li><!-- JAL---></li>
+            <li><!-- JAL---></li>
+            <li><!-- JAL---></li>
+            <li><!-- JAL---></li>
+            <li><!-- JAL---></li>
+            <li><!-- JAL---></li>
+            <li><!-- JAL-2123 -->Show residue labels in Chimera when mousing over sequences in Jalview</li>
             <li><!-- JAL-2027-->Support for reverse-complement coding regions in ENA and EMBL</li>
             <li><!-- JAL-1855, JAL-2113, JAL-2114-->Upgrade to EMBL XML 1.2 for ENA record retrieval</li>
             <li><!--  JAL 1812 -->New 'execute Groovy script' option in an alignment window's Calculate menu</li>
             <a href="https://www.certum.eu">Certum</a> to the Jalview
             open source project).
           </li>
-          <li>Jalview SRS links replaced by Uniprot and EBI-search
+          <li>Jalview SRS links replaced by UniProt and EBI-search
           </li>
           <li>Output in Stockholm format</li>
           <li>Allow import of data from gzipped files</li>
             current built in colourscheme is saved as new scheme</li>
           <li>AlignFrame-&gt;Save in application pops up save
             dialog for valid filename/format</li>
-          <li>Cannot view associated structure for Uniprot sequence</li>
-          <li>PDB file association breaks for Uniprot sequence
+          <li>Cannot view associated structure for UniProt sequence</li>
+          <li>PDB file association breaks for UniProt sequence
             P37173</li>
           <li>Associate PDB from file dialog does not tell you
             which sequence is to be associated with the file</li>
           <li>Save works when Jalview project is default format</li>
           <li>Save as dialog opened if current alignment format is
             not a valid output format</li>
-          <li>Uniprot canonical names introduced for both das and
+          <li>UniProt canonical names introduced for both das and
             vamsas</li>
           <li>Histidine should be midblue (not pink!) in Zappo</li>
           <li>error messages passed up and output when data read
             due to null pointer exceptions</li>
           <li>Secondary structure lines are drawn starting from
             first column of alignment</li>
-          <li>Uniprot XML import updated for new schema release in
+          <li>UniProt XML import updated for new schema release in
             July 2008</li>
           <li>Sequence feature to sequence ID match for Features
             file is case-insensitive</li>
           <li>Re-instated Zoom function for PCA
           <li>Sequence descriptions conserved in web service
             analysis results
-          <li>Uniprot ID discoverer uses any word separated by
+          <li>UniProt ID discoverer uses any word separated by
             &#8739;
           <li>WsDbFetch query/result association resolved
           <li>Tree leaf to sequence mapping improved
index e919f3f..632e993 100644 (file)
@@ -64,8 +64,8 @@
 <p>
   <strong>The Sequence Identification Process</strong><br> The
   method of accession id discovery is derived from the method which
-  earlier Jalview versions used for Uniprot sequence feature retrieval,
-  and was originally restricted to the identification of valid Uniprot
+  earlier Jalview versions used for UniProt sequence feature retrieval,
+  and was originally restricted to the identification of valid UniProt
   accessions.<br> Essentially, Jalview will try to retrieve records
   from a subset of the databases accessible by the <a
     href="../features/seqfetch.html"
index d7a93c6..a74e5b7 100755 (executable)
     <strong>What's new ?</strong>
   </p>
   <p>
-    Jalview 2.9.1 is the next major release in the Jalview 2.9 series. Full details are in the
-    <a href="releases.html#Jalview.2.9.1">Jalview 2.9.1 Release Notes</a>.
+    Jalview 2.10 is the next major release in the Jalview 2 series. Full details are in the
+    <a href="releases.html#Jalview.2.10">Jalview 2.10 Release Notes</a>, but the highlights are below.
   </p>
   <p>
-    <strong>Highlights in Jalview 2.9.1</strong>
+    <strong>Highlights in Jalview 2.10</strong>
   <ul>
+    <li><strong>Ensembl sequence fetcher.</strong> Annotated Genes, transcripts and
+      proteins can be retrieved via Jalview's new Ensembl REST client.</li>
+    <li><strong>Improved sequence/structure mappings.</strong>
+      Jalview now utilises the PDBe's SIFTS database (at EMBL-EBI) to
+      match PDB data positions in UniProt sequences.</li>
   </ul>
 
 </body>
index d5f0d0b..66ce147 100755 (executable)
@@ -415,34 +415,51 @@ public class PDBViewer extends JInternalFrame implements Runnable
           @Override
           public void mousePressed(MouseEvent evt)
           {
-            if (evt.isPopupTrigger())
+            if (evt.isPopupTrigger()) // Mac
             {
-              radioItem.removeActionListener(radioItem.getActionListeners()[0]);
-
-              int option = JOptionPane.showInternalConfirmDialog(
-                      jalview.gui.Desktop.desktop,
-                      MessageManager
-                              .getString("label.remove_from_default_list"),
-                      MessageManager
-                              .getString("label.remove_user_defined_colour"),
-                      JOptionPane.YES_NO_OPTION);
-              if (option == JOptionPane.YES_OPTION)
-              {
-                jalview.gui.UserDefinedColours
-                        .removeColourFromDefaults(radioItem.getText());
-                coloursMenu.remove(radioItem);
-              }
-              else
+              offerRemoval(radioItem);
+            }
+          }
+
+          @Override
+          public void mouseReleased(MouseEvent evt)
+          {
+            if (evt.isPopupTrigger()) // Windows
+            {
+              offerRemoval(radioItem);
+            }
+          }
+
+          /**
+           * @param radioItem
+           */
+          void offerRemoval(final JRadioButtonMenuItem radioItem)
+          {
+            radioItem.removeActionListener(radioItem.getActionListeners()[0]);
+
+            int option = JOptionPane.showInternalConfirmDialog(
+                    jalview.gui.Desktop.desktop,
+                    MessageManager
+                            .getString("label.remove_from_default_list"),
+                    MessageManager
+                            .getString("label.remove_user_defined_colour"),
+                    JOptionPane.YES_NO_OPTION);
+            if (option == JOptionPane.YES_OPTION)
+            {
+              jalview.gui.UserDefinedColours
+                      .removeColourFromDefaults(radioItem.getText());
+              coloursMenu.remove(radioItem);
+            }
+            else
+            {
+              radioItem.addActionListener(new ActionListener()
               {
-                radioItem.addActionListener(new ActionListener()
+                @Override
+                public void actionPerformed(ActionEvent evt)
                 {
-                  @Override
-                  public void actionPerformed(ActionEvent evt)
-                  {
-                    user_actionPerformed(evt);
-                  }
-                });
-              }
+                  user_actionPerformed(evt);
+                }
+              });
             }
           }
         });
index 4489783..96b45c1 100644 (file)
@@ -44,7 +44,7 @@ import java.util.Vector;
  */
 public class NJTree
 {
-  Vector cluster;
+  Vector<Cluster> cluster;
 
   SequenceI[] sequence;
 
@@ -68,7 +68,7 @@ public class NJTree
 
   float rj;
 
-  Vector groups = new Vector();
+  Vector<SequenceNode> groups = new Vector<SequenceNode>();
 
   SequenceNode maxdist;
 
@@ -80,7 +80,7 @@ public class NJTree
 
   int ycount;
 
-  Vector node;
+  Vector<SequenceNode> node;
 
   String type;
 
@@ -88,8 +88,6 @@ public class NJTree
 
   Object found = null;
 
-  Object leaves = null;
-
   boolean hasDistances = true; // normal case for jalview trees
 
   boolean hasBootstrap = false; // normal case for jalview trees
@@ -151,8 +149,7 @@ public class NJTree
 
     SequenceIdMatcher algnIds = new SequenceIdMatcher(seqs);
 
-    Vector leaves = new Vector();
-    findLeaves(top, leaves);
+    Vector<SequenceNode> leaves = findLeaves(top);
 
     int i = 0;
     int namesleft = seqs.length;
@@ -160,11 +157,11 @@ public class NJTree
     SequenceNode j;
     SequenceI nam;
     String realnam;
-    Vector one2many = new Vector();
+    Vector<SequenceI> one2many = new Vector<SequenceI>();
     int countOne2Many = 0;
     while (i < leaves.size())
     {
-      j = (SequenceNode) leaves.elementAt(i++);
+      j = leaves.elementAt(i++);
       realnam = j.getName();
       nam = null;
 
@@ -221,7 +218,7 @@ public class NJTree
           String pwtype, ScoreModelI sm, int start, int end)
   {
     this.sequence = sequence;
-    this.node = new Vector();
+    this.node = new Vector<SequenceNode>();
     this.type = type;
     this.pwtype = pwtype;
     if (seqData != null)
@@ -282,6 +279,7 @@ public class NJTree
    * 
    * @return Newick File with all tree data available
    */
+  @Override
   public String toString()
   {
     jalview.io.NewickFile fout = new jalview.io.NewickFile(getTopNode());
@@ -299,8 +297,7 @@ public class NJTree
    */
   public void UpdatePlaceHolders(List<SequenceI> list)
   {
-    Vector leaves = new Vector();
-    findLeaves(top, leaves);
+    Vector<SequenceNode> leaves = findLeaves(top);
 
     int sz = leaves.size();
     SequenceIdMatcher seqmatcher = null;
@@ -308,7 +305,7 @@ public class NJTree
 
     while (i < sz)
     {
-      SequenceNode leaf = (SequenceNode) leaves.elementAt(i++);
+      SequenceNode leaf = leaves.elementAt(i++);
 
       if (list.contains(leaf.element()))
       {
@@ -369,12 +366,12 @@ public class NJTree
     {
 
       @Override
-      public void transform(BinaryNode node)
+      public void transform(BinaryNode nd)
       {
-        Object el = node.element();
+        Object el = nd.element();
         if (el != null && el instanceof SequenceI)
         {
-          node.setName(((SequenceI) el).getName());
+          nd.setName(((SequenceI) el).getName());
         }
       }
     });
@@ -428,7 +425,7 @@ public class NJTree
     }
 
     joinClusters(one, two);
-    top = (SequenceNode) (node.elementAt(one));
+    top = (node.elementAt(one));
 
     reCount(top);
     findHeight(top);
@@ -449,19 +446,19 @@ public class NJTree
   {
     float dist = distance[i][j];
 
-    int noi = ((Cluster) cluster.elementAt(i)).value.length;
-    int noj = ((Cluster) cluster.elementAt(j)).value.length;
+    int noi = cluster.elementAt(i).value.length;
+    int noj = cluster.elementAt(j).value.length;
 
     int[] value = new int[noi + noj];
 
     for (int ii = 0; ii < noi; ii++)
     {
-      value[ii] = ((Cluster) cluster.elementAt(i)).value[ii];
+      value[ii] = cluster.elementAt(i).value[ii];
     }
 
     for (int ii = noi; ii < (noi + noj); ii++)
     {
-      value[ii] = ((Cluster) cluster.elementAt(j)).value[ii - noi];
+      value[ii] = cluster.elementAt(j).value[ii - noi];
     }
 
     Cluster c = new Cluster(value);
@@ -480,11 +477,11 @@ public class NJTree
 
     SequenceNode sn = new SequenceNode();
 
-    sn.setLeft((SequenceNode) (node.elementAt(i)));
-    sn.setRight((SequenceNode) (node.elementAt(j)));
+    sn.setLeft((node.elementAt(i)));
+    sn.setRight((node.elementAt(j)));
 
-    SequenceNode tmpi = (SequenceNode) (node.elementAt(i));
-    SequenceNode tmpj = (SequenceNode) (node.elementAt(j));
+    SequenceNode tmpi = (node.elementAt(i));
+    SequenceNode tmpj = (node.elementAt(j));
 
     if (type.equals("NJ"))
     {
@@ -576,8 +573,8 @@ public class NJTree
    */
   public void findClusterDistance(int i, int j)
   {
-    int noi = ((Cluster) cluster.elementAt(i)).value.length;
-    int noj = ((Cluster) cluster.elementAt(j)).value.length;
+    int noi = cluster.elementAt(i).value.length;
+    int noj = cluster.elementAt(j).value.length;
 
     // New distances from cluster to others
     float[] newdist = new float[noseqs];
@@ -733,7 +730,7 @@ public class NJTree
   public float[][] findDistances(ScoreModelI _pwmatrix)
   {
 
-    float[][] distance = new float[noseqs][noseqs];
+    float[][] dist = new float[noseqs][noseqs];
     if (_pwmatrix == null)
     {
       // Resolve substitution model
@@ -743,8 +740,8 @@ public class NJTree
         _pwmatrix = ResidueProperties.getScoreMatrix("BLOSUM62");
       }
     }
-    distance = _pwmatrix.findDistances(seqData);
-    return distance;
+    dist = _pwmatrix.findDistances(seqData);
+    return dist;
 
   }
 
@@ -753,7 +750,7 @@ public class NJTree
    */
   public void makeLeaves()
   {
-    cluster = new Vector();
+    cluster = new Vector<Cluster>();
 
     for (int i = 0; i < noseqs; i++)
     {
@@ -772,26 +769,42 @@ public class NJTree
   }
 
   /**
+   * Search for leaf nodes below (or at) the given node
+   * 
+   * @param nd
+   *          root node to search from
+   * 
+   * @return
+   */
+  public Vector<SequenceNode> findLeaves(SequenceNode nd)
+  {
+    Vector<SequenceNode> leaves = new Vector<SequenceNode>();
+    findLeaves(nd, leaves);
+    return leaves;
+  }
+
+  /**
    * Search for leaf nodes.
    * 
-   * @param node
+   * @param nd
    *          root node to search from
    * @param leaves
    *          Vector of leaves to add leaf node objects too.
    * 
    * @return Vector of leaf nodes on binary tree
    */
-  public Vector findLeaves(SequenceNode node, Vector leaves)
+  Vector<SequenceNode> findLeaves(SequenceNode nd,
+          Vector<SequenceNode> leaves)
   {
-    if (node == null)
+    if (nd == null)
     {
       return leaves;
     }
 
-    if ((node.left() == null) && (node.right() == null)) // Interior node
+    if ((nd.left() == null) && (nd.right() == null)) // Interior node
     // detection
     {
-      leaves.addElement(node);
+      leaves.addElement(nd);
 
       return leaves;
     }
@@ -801,8 +814,8 @@ public class NJTree
        * TODO: Identify internal nodes... if (node.isSequenceLabel()) {
        * leaves.addElement(node); }
        */
-      findLeaves((SequenceNode) node.left(), leaves);
-      findLeaves((SequenceNode) node.right(), leaves);
+      findLeaves((SequenceNode) nd.left(), leaves);
+      findLeaves((SequenceNode) nd.right(), leaves);
     }
 
     return leaves;
@@ -811,16 +824,16 @@ public class NJTree
   /**
    * Find the leaf node with a particular ycount
    * 
-   * @param node
+   * @param nd
    *          initial point on tree to search from
    * @param count
    *          value to search for
    * 
    * @return null or the node with ycound=count
    */
-  public Object findLeaf(SequenceNode node, int count)
+  public Object findLeaf(SequenceNode nd, int count)
   {
-    found = _findLeaf(node, count);
+    found = _findLeaf(nd, count);
 
     return found;
   }
@@ -828,23 +841,23 @@ public class NJTree
   /*
    * #see findLeaf(SequenceNode node, count)
    */
-  public Object _findLeaf(SequenceNode node, int count)
+  public Object _findLeaf(SequenceNode nd, int count)
   {
-    if (node == null)
+    if (nd == null)
     {
       return null;
     }
 
-    if (node.ycount == count)
+    if (nd.ycount == count)
     {
-      found = node.element();
+      found = nd.element();
 
       return found;
     }
     else
     {
-      _findLeaf((SequenceNode) node.left(), count);
-      _findLeaf((SequenceNode) node.right(), count);
+      _findLeaf((SequenceNode) nd.left(), count);
+      _findLeaf((SequenceNode) nd.right(), count);
     }
 
     return found;
@@ -853,58 +866,58 @@ public class NJTree
   /**
    * printNode is mainly for debugging purposes.
    * 
-   * @param node
+   * @param nd
    *          SequenceNode
    */
-  public void printNode(SequenceNode node)
+  public void printNode(SequenceNode nd)
   {
-    if (node == null)
+    if (nd == null)
     {
       return;
     }
 
-    if ((node.left() == null) && (node.right() == null))
+    if ((nd.left() == null) && (nd.right() == null))
     {
       System.out
-              .println("Leaf = " + ((SequenceI) node.element()).getName());
-      System.out.println("Dist " + node.dist);
-      System.out.println("Boot " + node.getBootstrap());
+              .println("Leaf = " + ((SequenceI) nd.element()).getName());
+      System.out.println("Dist " + nd.dist);
+      System.out.println("Boot " + nd.getBootstrap());
     }
     else
     {
-      System.out.println("Dist " + node.dist);
-      printNode((SequenceNode) node.left());
-      printNode((SequenceNode) node.right());
+      System.out.println("Dist " + nd.dist);
+      printNode((SequenceNode) nd.left());
+      printNode((SequenceNode) nd.right());
     }
   }
 
   /**
    * DOCUMENT ME!
    * 
-   * @param node
+   * @param nd
    *          DOCUMENT ME!
    */
-  public void findMaxDist(SequenceNode node)
+  public void findMaxDist(SequenceNode nd)
   {
-    if (node == null)
+    if (nd == null)
     {
       return;
     }
 
-    if ((node.left() == null) && (node.right() == null))
+    if ((nd.left() == null) && (nd.right() == null))
     {
-      float dist = node.dist;
+      float dist = nd.dist;
 
       if (dist > maxDistValue)
       {
-        maxdist = node;
+        maxdist = nd;
         maxDistValue = dist;
       }
     }
     else
     {
-      findMaxDist((SequenceNode) node.left());
-      findMaxDist((SequenceNode) node.right());
+      findMaxDist((SequenceNode) nd.left());
+      findMaxDist((SequenceNode) nd.right());
     }
   }
 
@@ -913,7 +926,7 @@ public class NJTree
    * 
    * @return DOCUMENT ME!
    */
-  public Vector getGroups()
+  public Vector<SequenceNode> getGroups()
   {
     return groups;
   }
@@ -931,51 +944,51 @@ public class NJTree
   /**
    * DOCUMENT ME!
    * 
-   * @param node
+   * @param nd
    *          DOCUMENT ME!
    * @param threshold
    *          DOCUMENT ME!
    */
-  public void groupNodes(SequenceNode node, float threshold)
+  public void groupNodes(SequenceNode nd, float threshold)
   {
-    if (node == null)
+    if (nd == null)
     {
       return;
     }
 
-    if ((node.height / maxheight) > threshold)
+    if ((nd.height / maxheight) > threshold)
     {
-      groups.addElement(node);
+      groups.addElement(nd);
     }
     else
     {
-      groupNodes((SequenceNode) node.left(), threshold);
-      groupNodes((SequenceNode) node.right(), threshold);
+      groupNodes((SequenceNode) nd.left(), threshold);
+      groupNodes((SequenceNode) nd.right(), threshold);
     }
   }
 
   /**
    * DOCUMENT ME!
    * 
-   * @param node
+   * @param nd
    *          DOCUMENT ME!
    * 
    * @return DOCUMENT ME!
    */
-  public float findHeight(SequenceNode node)
+  public float findHeight(SequenceNode nd)
   {
-    if (node == null)
+    if (nd == null)
     {
       return maxheight;
     }
 
-    if ((node.left() == null) && (node.right() == null))
+    if ((nd.left() == null) && (nd.right() == null))
     {
-      node.height = ((SequenceNode) node.parent()).height + node.dist;
+      nd.height = ((SequenceNode) nd.parent()).height + nd.dist;
 
-      if (node.height > maxheight)
+      if (nd.height > maxheight)
       {
-        return node.height;
+        return nd.height;
       }
       else
       {
@@ -984,18 +997,18 @@ public class NJTree
     }
     else
     {
-      if (node.parent() != null)
+      if (nd.parent() != null)
       {
-        node.height = ((SequenceNode) node.parent()).height + node.dist;
+        nd.height = ((SequenceNode) nd.parent()).height + nd.dist;
       }
       else
       {
         maxheight = 0;
-        node.height = (float) 0.0;
+        nd.height = (float) 0.0;
       }
 
-      maxheight = findHeight((SequenceNode) (node.left()));
-      maxheight = findHeight((SequenceNode) (node.right()));
+      maxheight = findHeight((SequenceNode) (nd.left()));
+      maxheight = findHeight((SequenceNode) (nd.right()));
     }
 
     return maxheight;
@@ -1078,43 +1091,43 @@ public class NJTree
   /**
    * DOCUMENT ME!
    * 
-   * @param node
+   * @param nd
    *          DOCUMENT ME!
    */
-  public void printN(SequenceNode node)
+  public void printN(SequenceNode nd)
   {
-    if (node == null)
+    if (nd == null)
     {
       return;
     }
 
-    if ((node.left() != null) && (node.right() != null))
+    if ((nd.left() != null) && (nd.right() != null))
     {
-      printN((SequenceNode) node.left());
-      printN((SequenceNode) node.right());
+      printN((SequenceNode) nd.left());
+      printN((SequenceNode) nd.right());
     }
     else
     {
       System.out.println(" name = "
-              + ((SequenceI) node.element()).getName());
+              + ((SequenceI) nd.element()).getName());
     }
 
-    System.out.println(" dist = " + node.dist + " " + node.count + " "
-            + node.height);
+    System.out.println(" dist = " + nd.dist + " " + nd.count + " "
+            + nd.height);
   }
 
   /**
    * DOCUMENT ME!
    * 
-   * @param node
+   * @param nd
    *          DOCUMENT ME!
    */
-  public void reCount(SequenceNode node)
+  public void reCount(SequenceNode nd)
   {
     ycount = 0;
     _lycount = 0;
     // _lylimit = this.node.size();
-    _reCount(node);
+    _reCount(nd);
   }
 
   private long _lycount = 0, _lylimit = 0;
@@ -1122,37 +1135,37 @@ public class NJTree
   /**
    * DOCUMENT ME!
    * 
-   * @param node
+   * @param nd
    *          DOCUMENT ME!
    */
-  public void _reCount(SequenceNode node)
+  public void _reCount(SequenceNode nd)
   {
     // if (_lycount<_lylimit)
     // {
     // System.err.println("Warning: depth of _recount greater than number of nodes.");
     // }
-    if (node == null)
+    if (nd == null)
     {
       return;
     }
     _lycount++;
 
-    if ((node.left() != null) && (node.right() != null))
+    if ((nd.left() != null) && (nd.right() != null))
     {
 
-      _reCount((SequenceNode) node.left());
-      _reCount((SequenceNode) node.right());
+      _reCount((SequenceNode) nd.left());
+      _reCount((SequenceNode) nd.right());
 
-      SequenceNode l = (SequenceNode) node.left();
-      SequenceNode r = (SequenceNode) node.right();
+      SequenceNode l = (SequenceNode) nd.left();
+      SequenceNode r = (SequenceNode) nd.right();
 
-      node.count = l.count + r.count;
-      node.ycount = (l.ycount + r.ycount) / 2;
+      nd.count = l.count + r.count;
+      nd.ycount = (l.ycount + r.ycount) / 2;
     }
     else
     {
-      node.count = 1;
-      node.ycount = ycount++;
+      nd.count = 1;
+      nd.ycount = ycount++;
     }
     _lycount--;
   }
@@ -1160,80 +1173,80 @@ public class NJTree
   /**
    * DOCUMENT ME!
    * 
-   * @param node
+   * @param nd
    *          DOCUMENT ME!
    */
-  public void swapNodes(SequenceNode node)
+  public void swapNodes(SequenceNode nd)
   {
-    if (node == null)
+    if (nd == null)
     {
       return;
     }
 
-    SequenceNode tmp = (SequenceNode) node.left();
+    SequenceNode tmp = (SequenceNode) nd.left();
 
-    node.setLeft(node.right());
-    node.setRight(tmp);
+    nd.setLeft(nd.right());
+    nd.setRight(tmp);
   }
 
   /**
    * DOCUMENT ME!
    * 
-   * @param node
+   * @param nd
    *          DOCUMENT ME!
    * @param dir
    *          DOCUMENT ME!
    */
-  public void changeDirection(SequenceNode node, SequenceNode dir)
+  public void changeDirection(SequenceNode nd, SequenceNode dir)
   {
-    if (node == null)
+    if (nd == null)
     {
       return;
     }
 
-    if (node.parent() != top)
+    if (nd.parent() != top)
     {
-      changeDirection((SequenceNode) node.parent(), node);
+      changeDirection((SequenceNode) nd.parent(), nd);
 
-      SequenceNode tmp = (SequenceNode) node.parent();
+      SequenceNode tmp = (SequenceNode) nd.parent();
 
-      if (dir == node.left())
+      if (dir == nd.left())
       {
-        node.setParent(dir);
-        node.setLeft(tmp);
+        nd.setParent(dir);
+        nd.setLeft(tmp);
       }
-      else if (dir == node.right())
+      else if (dir == nd.right())
       {
-        node.setParent(dir);
-        node.setRight(tmp);
+        nd.setParent(dir);
+        nd.setRight(tmp);
       }
     }
     else
     {
-      if (dir == node.left())
+      if (dir == nd.left())
       {
-        node.setParent(node.left());
+        nd.setParent(nd.left());
 
-        if (top.left() == node)
+        if (top.left() == nd)
         {
-          node.setRight(top.right());
+          nd.setRight(top.right());
         }
         else
         {
-          node.setRight(top.left());
+          nd.setRight(top.left());
         }
       }
       else
       {
-        node.setParent(node.right());
+        nd.setParent(nd.right());
 
-        if (top.left() == node)
+        if (top.left() == nd)
         {
-          node.setLeft(top.right());
+          nd.setLeft(top.right());
         }
         else
         {
-          node.setLeft(top.left());
+          nd.setLeft(top.left());
         }
       }
     }
@@ -1289,8 +1302,9 @@ public class NJTree
    */
   public void applyToNodes(NodeTransformI nodeTransformI)
   {
-    for (Enumeration nodes = node.elements(); nodes.hasMoreElements(); nodeTransformI
-            .transform((BinaryNode) nodes.nextElement()))
+    for (Enumeration<SequenceNode> nodes = node.elements(); nodes
+            .hasMoreElements(); nodeTransformI
+            .transform(nodes.nextElement()))
     {
       ;
     }
index 8343f0b..df57cc0 100644 (file)
@@ -397,4 +397,12 @@ public interface AlignViewportI extends ViewStyleI
 
 
   public void applyFeaturesStyle(FeatureSettingsModelI featureSettings);
+
+  /**
+   * check if current selection group is defined on the view, or is simply a
+   * temporary group.
+   * 
+   * @return true if group is defined on the alignment
+   */
+  boolean isSelectionDefinedGroup();
 }
index 02172d6..a437960 100644 (file)
@@ -927,13 +927,6 @@ public class SeqPanel extends Panel implements MouseMotionListener,
    */
   private boolean needOverviewUpdate; // TODO: refactor to avcontroller
 
-  /**
-   * set if av.getSelectionGroup() refers to a group that is defined on the
-   * alignment view, rather than a transient selection
-   */
-  private boolean editingDefinedGroup = false; // TODO: refactor to avcontroller
-                                               // or viewModel
-
   @Override
   public void mouseDragged(MouseEvent evt)
   {
@@ -1436,12 +1429,10 @@ public class SeqPanel extends Panel implements MouseMotionListener,
               && res < stretchGroup.getEndRes())
       {
         av.setSelectionGroup(stretchGroup);
-        editingDefinedGroup = true;
       }
       else
       {
         stretchGroup = null;
-        editingDefinedGroup = false;
       }
     }
 
@@ -1461,7 +1452,6 @@ public class SeqPanel extends Panel implements MouseMotionListener,
                   && allGroups[i].getEndRes() >= res)
           {
             stretchGroup = allGroups[i];
-            editingDefinedGroup = true;
             break;
           }
         }
@@ -1517,7 +1507,6 @@ public class SeqPanel extends Panel implements MouseMotionListener,
       sg.setEndRes(res);
       sg.addSequence(sequence, false);
       av.setSelectionGroup(sg);
-      editingDefinedGroup = false;
       stretchGroup = sg;
 
       if (av.getConservationSelected())
@@ -1543,7 +1532,8 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     // always do this - annotation has own state
     // but defer colourscheme update until hidden sequences are passed in
     boolean vischange = stretchGroup.recalcConservation(true);
-    needOverviewUpdate |= vischange && editingDefinedGroup;
+    // here we rely on stretchGroup == av.getSelection()
+    needOverviewUpdate |= vischange && av.isSelectionDefinedGroup();
     if (stretchGroup.cs != null)
     {
       stretchGroup.cs.alignmentChanged(stretchGroup,
@@ -1563,7 +1553,6 @@ public class SeqPanel extends Panel implements MouseMotionListener,
     PaintRefresher.Refresh(ap, av.getSequenceSetId());
     ap.paintAlignment(needOverviewUpdate);
     needOverviewUpdate =false;
-    editingDefinedGroup = false;
     changeEndRes = false;
     changeStartRes = false;
     stretchGroup = null;
@@ -1618,7 +1607,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
       if (res > (stretchGroup.getStartRes() - 1))
       {
         stretchGroup.setEndRes(res);
-        needOverviewUpdate |= editingDefinedGroup;
+        needOverviewUpdate |= av.isSelectionDefinedGroup();
       }
     }
     else if (changeStartRes)
@@ -1626,7 +1615,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
       if (res < (stretchGroup.getEndRes() + 1))
       {
         stretchGroup.setStartRes(res);
-        needOverviewUpdate |= editingDefinedGroup;
+        needOverviewUpdate |= av.isSelectionDefinedGroup();
       }
     }
 
@@ -1660,7 +1649,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
       if (stretchGroup.getSequences(null).contains(nextSeq))
       {
         stretchGroup.deleteSequence(seq, false);
-        needOverviewUpdate |= editingDefinedGroup;
+        needOverviewUpdate |= av.isSelectionDefinedGroup();
       }
       else
       {
@@ -1670,7 +1659,7 @@ public class SeqPanel extends Panel implements MouseMotionListener,
         }
 
         stretchGroup.addSequence(nextSeq, false);
-        needOverviewUpdate |= editingDefinedGroup;
+        needOverviewUpdate |= av.isSelectionDefinedGroup();
       }
     }
 
index edcd961..c8f526c 100755 (executable)
@@ -122,13 +122,13 @@ public class TreeCanvas extends Panel implements MouseListener,
     tree.findHeight(tree.getTopNode());
 
     // Now have to calculate longest name based on the leaves
-    Vector leaves = tree.findLeaves(tree.getTopNode(), new Vector());
+    Vector<SequenceNode> leaves = tree.findLeaves(tree.getTopNode());
     boolean has_placeholders = false;
     longestName = "";
 
     for (int i = 0; i < leaves.size(); i++)
     {
-      SequenceNode lf = (SequenceNode) leaves.elementAt(i);
+      SequenceNode lf = leaves.elementAt(i);
 
       if (lf.isPlaceholder())
       {
@@ -525,12 +525,11 @@ public class TreeCanvas extends Panel implements MouseListener,
       }
       else
       {
-        Vector leaves = new Vector();
-        tree.findLeaves(highlightNode, leaves);
+        Vector<SequenceNode> leaves = tree.findLeaves(highlightNode);
 
         for (int i = 0; i < leaves.size(); i++)
         {
-          SequenceI seq = (SequenceI) ((SequenceNode) leaves.elementAt(i))
+          SequenceI seq = (SequenceI) leaves.elementAt(i)
                   .element();
           treeSelectionChanged(seq);
         }
@@ -630,13 +629,13 @@ public class TreeCanvas extends Panel implements MouseListener,
               (int) (Math.random() * 255), (int) (Math.random() * 255));
       setColor((SequenceNode) tree.getGroups().elementAt(i), col.brighter());
 
-      Vector l = tree.findLeaves(
-              (SequenceNode) tree.getGroups().elementAt(i), new Vector());
+      Vector<SequenceNode> l = tree.findLeaves((SequenceNode) tree
+              .getGroups().elementAt(i));
 
-      Vector sequences = new Vector();
+      Vector<SequenceI> sequences = new Vector<SequenceI>();
       for (int j = 0; j < l.size(); j++)
       {
-        SequenceI s1 = (SequenceI) ((SequenceNode) l.elementAt(j))
+        SequenceI s1 = (SequenceI) l.elementAt(j)
                 .element();
         if (!sequences.contains(s1))
         {
index 22c537a..046f1e6 100755 (executable)
@@ -529,6 +529,7 @@ public class SequenceGroup implements AnnotatedCollectionI
     }
     // TODO: try harder to detect changes in state in order to minimise
     // recalculation effort
+    boolean upd = false;
     try
     {
       Hashtable cnsns[] = AAFrequency.calculate(sequences, startRes,
@@ -536,10 +537,12 @@ public class SequenceGroup implements AnnotatedCollectionI
       if (consensus != null)
       {
         _updateConsensusRow(cnsns, sequences.size());
+        upd = true;
       }
       if (cs != null)
       {
         cs.setConsensus(cnsns);
+        upd = true;
       }
 
       if ((conservation != null)
@@ -561,6 +564,8 @@ public class SequenceGroup implements AnnotatedCollectionI
             cs.setConservation(c);
           }
         }
+        // eager update - will cause a refresh of overview regardless
+        upd = true;
       }
       if (cs != null && !defer)
       {
@@ -570,14 +575,14 @@ public class SequenceGroup implements AnnotatedCollectionI
       }
       else
       {
-        return false;
+        return upd;
       }
     } catch (java.lang.OutOfMemoryError err)
     {
       // TODO: catch OOM
       System.out.println("Out of memory loading groups: " + err);
     }
-    return false;
+    return upd;
   }
 
   private void _updateConservationRow(Conservation c)
index 2cb7559..7836d24 100644 (file)
@@ -270,6 +270,10 @@ public class JmolParser extends StructureFile implements JmolStatusListener
       // diff < 5 then mark as valid and update termination Atom
       if (chainTerMap.containsKey(curAtomChId))
       {
+        if (curAtom.getResno() < chainTerMap.get(curAtomChId).getResno())
+        {
+          return false;
+        }
         if ((curAtom.getResno() - chainTerMap.get(curAtomChId).getResno()) < 5)
         {
           chainTerMap.put(curAtomChId, curAtom);
@@ -281,6 +285,10 @@ public class JmolParser extends StructureFile implements JmolStatusListener
     // atom with previously terminated chain encountered
     else if (chainTerMap.containsKey(curAtomChId))
     {
+      if (curAtom.getResno() < chainTerMap.get(curAtomChId).getResno())
+      {
+        return false;
+      }
       if ((curAtom.getResno() - chainTerMap.get(curAtomChId).getResno()) < 5)
       {
         chainTerMap.put(curAtomChId, curAtom);
index edfa928..1848595 100644 (file)
@@ -3620,34 +3620,51 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
           @Override
           public void mousePressed(MouseEvent evt)
           {
-            if (evt.isPopupTrigger())
+            if (evt.isPopupTrigger()) // Mac
             {
-              radioItem.removeActionListener(radioItem.getActionListeners()[0]);
+              offerRemoval(radioItem);
+            }
+          }
 
-              int option = JOptionPane.showInternalConfirmDialog(
-                      jalview.gui.Desktop.desktop,
-                      MessageManager
-                              .getString("label.remove_from_default_list"),
-                      MessageManager
-                              .getString("label.remove_user_defined_colour"),
-                      JOptionPane.YES_NO_OPTION);
-              if (option == JOptionPane.YES_OPTION)
-              {
-                jalview.gui.UserDefinedColours
-                        .removeColourFromDefaults(radioItem.getText());
-                colourMenu.remove(radioItem);
-              }
-              else
+          @Override
+          public void mouseReleased(MouseEvent evt)
+          {
+            if (evt.isPopupTrigger()) // Windows
+            {
+              offerRemoval(radioItem);
+            }
+          }
+
+          /**
+           * @param radioItem
+           */
+          void offerRemoval(final JRadioButtonMenuItem radioItem)
+          {
+            radioItem.removeActionListener(radioItem.getActionListeners()[0]);
+
+            int option = JOptionPane.showInternalConfirmDialog(
+                    jalview.gui.Desktop.desktop,
+                    MessageManager
+                            .getString("label.remove_from_default_list"),
+                    MessageManager
+                            .getString("label.remove_user_defined_colour"),
+                    JOptionPane.YES_NO_OPTION);
+            if (option == JOptionPane.YES_OPTION)
+            {
+              jalview.gui.UserDefinedColours
+                      .removeColourFromDefaults(radioItem.getText());
+              colourMenu.remove(radioItem);
+            }
+            else
+            {
+              radioItem.addActionListener(new ActionListener()
               {
-                radioItem.addActionListener(new ActionListener()
+                @Override
+                public void actionPerformed(ActionEvent evt)
                 {
-                  @Override
-                  public void actionPerformed(ActionEvent evt)
-                  {
-                    userDefinedColour_actionPerformed(evt);
-                  }
-                });
-              }
+                  userDefinedColour_actionPerformed(evt);
+                }
+              });
             }
           }
         });
index 5b01b9b..92c6dc6 100755 (executable)
@@ -332,12 +332,20 @@ public class AnnotationLabels extends JPanel implements MouseListener,
   {
     getSelectedRow(evt.getY() - getScrollOffset());
     oldY = evt.getY();
-    if (!evt.isPopupTrigger())
+    if (evt.isPopupTrigger())
     {
-      return;
+      showPopupMenu(evt);
     }
+  }
+
+  /**
+   * Build and show the Pop-up menu at the right-click mouse position
+   * 
+   * @param evt
+   */
+  void showPopupMenu(MouseEvent evt)
+  {
     evt.consume();
-    // handle popup menu event
     final AlignmentAnnotation[] aa = ap.av.getAlignment()
             .getAlignmentAnnotation();
 
@@ -595,7 +603,6 @@ public class AnnotationLabels extends JPanel implements MouseListener,
       }
     }
     pop.show(this, evt.getX(), evt.getY());
-
   }
 
   /**
@@ -607,6 +614,12 @@ public class AnnotationLabels extends JPanel implements MouseListener,
   @Override
   public void mouseReleased(MouseEvent evt)
   {
+    if (evt.isPopupTrigger())
+    {
+      showPopupMenu(evt);
+      return;
+    }
+
     int start = selectedRow;
     getSelectedRow(evt.getY() - getScrollOffset());
     int end = selectedRow;
index 6a621ff..bd903b3 100755 (executable)
@@ -507,6 +507,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     int height = 0;
     activeRow = -1;
 
+    final int y = evt.getY();
     for (int i = 0; i < aa.length; i++)
     {
       if (aa[i].visible)
@@ -514,7 +515,7 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         height += aa[i].height;
       }
 
-      if (evt.getY() < height)
+      if (y < height)
       {
         if (aa[i].editable)
         {
@@ -524,58 +525,71 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
         {
           // Stretch Graph
           graphStretch = i;
-          graphStretchY = evt.getY();
+          graphStretchY = y;
         }
 
         break;
       }
     }
 
+    /*
+     * isPopupTrigger fires in mousePressed on Mac,
+     * not until mouseRelease on Windows
+     */
     if (evt.isPopupTrigger() && activeRow != -1)
     {
-      if (av.getColumnSelection() == null
-              || av.getColumnSelection().isEmpty())
-      {
-        return;
-      }
+      showPopupMenu(y, evt.getX());
+      return;
+    }
 
-      JPopupMenu pop = new JPopupMenu(
-              MessageManager.getString("label.structure_type"));
-      JMenuItem item;
-      /*
-       * Just display the needed structure options
-       */
-      if (av.getAlignment().isNucleotide())
-      {
-        item = new JMenuItem(STEM);
-        item.addActionListener(this);
-        pop.add(item);
-      }
-      else
-      {
-        item = new JMenuItem(HELIX);
-        item.addActionListener(this);
-        pop.add(item);
-        item = new JMenuItem(SHEET);
-        item.addActionListener(this);
-        pop.add(item);
-      }
-      item = new JMenuItem(LABEL);
+    ap.getScalePanel().mousePressed(evt);
+  }
+
+  /**
+   * Construct and display a context menu at the right-click position
+   * 
+   * @param y
+   * @param x
+   */
+  void showPopupMenu(final int y, int x)
+  {
+    if (av.getColumnSelection() == null
+            || av.getColumnSelection().isEmpty())
+    {
+      return;
+    }
+
+    JPopupMenu pop = new JPopupMenu(
+            MessageManager.getString("label.structure_type"));
+    JMenuItem item;
+    /*
+     * Just display the needed structure options
+     */
+    if (av.getAlignment().isNucleotide())
+    {
+      item = new JMenuItem(STEM);
       item.addActionListener(this);
       pop.add(item);
-      item = new JMenuItem(COLOUR);
+    }
+    else
+    {
+      item = new JMenuItem(HELIX);
       item.addActionListener(this);
       pop.add(item);
-      item = new JMenuItem(REMOVE);
+      item = new JMenuItem(SHEET);
       item.addActionListener(this);
       pop.add(item);
-      pop.show(this, evt.getX(), evt.getY());
-
-      return;
     }
-
-    ap.getScalePanel().mousePressed(evt);
-
+    item = new JMenuItem(LABEL);
+    item.addActionListener(this);
+    pop.add(item);
+    item = new JMenuItem(COLOUR);
+    item.addActionListener(this);
+    pop.add(item);
+    item = new JMenuItem(REMOVE);
+    item.addActionListener(this);
+    pop.add(item);
+    pop.show(this, x, y);
   }
 
   /**
@@ -591,6 +605,16 @@ public class AnnotationPanel extends JPanel implements AwtRenderPanelI,
     graphStretchY = -1;
     mouseDragging = false;
     ap.getScalePanel().mouseReleased(evt);
+
+    /*
+     * isPopupTrigger is set in mouseReleased on Windows
+     * (in mousePressed on Mac)
+     */
+    if (evt.isPopupTrigger() && activeRow != -1)
+    {
+      showPopupMenu(evt.getY(), evt.getX());
+    }
+
   }
 
   /**
index 65d8670..dae83d1 100644 (file)
@@ -228,6 +228,7 @@ public class CutAndPasteHtmlTransfer extends GCutAndPasteHtmlTransfer
   @Override
   public void textarea_mousePressed(MouseEvent e)
   {
+    // isPopupTrigger is on mousePressed (Mac) or mouseReleased (Windows)
     if (e.isPopupTrigger())
     {
       JPopupMenu popup = new JPopupMenu(
index 1161340..ed2b9bf 100644 (file)
@@ -358,6 +358,10 @@ public class CutAndPasteTransfer extends GCutAndPasteTransfer
   @Override
   public void textarea_mousePressed(MouseEvent e)
   {
+    /*
+     * isPopupTrigger is checked in mousePressed on Mac,
+     * in mouseReleased on Windows
+     */
     if (e.isPopupTrigger())
     {
       JPopupMenu popup = new JPopupMenu(
index 3cc2c14..387a2a9 100644 (file)
@@ -397,7 +397,16 @@ public class Desktop extends jalview.jbgui.GDesktop implements
       @Override
       public void mousePressed(MouseEvent evt)
       {
-        if (evt.isPopupTrigger())
+        if (evt.isPopupTrigger()) // Mac
+        {
+          showPasteMenu(evt.getX(), evt.getY());
+        }
+      }
+
+      @Override
+      public void mouseReleased(MouseEvent evt)
+      {
+        if (evt.isPopupTrigger()) // Windows
         {
           showPasteMenu(evt.getX(), evt.getY());
         }
index 3b8ce37..874ce16 100644 (file)
@@ -174,8 +174,7 @@ public class FeatureSettings extends JPanel implements
       public void mousePressed(MouseEvent evt)
       {
         selectedRow = table.rowAtPoint(evt.getPoint());
-        boolean ctrlDown = Platform.isControlDown(evt);
-        if (SwingUtilities.isRightMouseButton(evt) && !ctrlDown)
+        if (evt.isPopupTrigger())
         {
           popupSort(selectedRow, (String) table.getValueAt(selectedRow, 0),
                   table.getValueAt(selectedRow, 1), fr.getMinMax(),
@@ -184,7 +183,7 @@ public class FeatureSettings extends JPanel implements
         else if (evt.getClickCount() == 2)
         {
           boolean invertSelection = evt.isAltDown();
-          boolean toggleSelection = ctrlDown;
+          boolean toggleSelection = Platform.isControlDown(evt);
           boolean extendSelection = evt.isShiftDown();
           fr.ap.alignFrame.avc.markColumnsContainingFeatures(
                   invertSelection, extendSelection, toggleSelection,
@@ -192,7 +191,7 @@ public class FeatureSettings extends JPanel implements
         }
       }
 
-      // isPopupTrigger fires on mouseReleased on Mac
+      // isPopupTrigger fires on mouseReleased on Windows
       @Override
       public void mouseReleased(MouseEvent evt)
       {
index 61ddafb..05166ad 100755 (executable)
@@ -26,6 +26,7 @@ import jalview.datamodel.SequenceGroup;
 import jalview.datamodel.SequenceI;
 import jalview.io.SequenceAnnotationReport;
 import jalview.util.MessageManager;
+import jalview.util.Platform;
 import jalview.util.UrlLink;
 import jalview.viewmodel.AlignmentViewport;
 
@@ -316,39 +317,22 @@ public class IdPanel extends JPanel implements MouseListener,
       return;
     }
 
-    int seq = alignPanel.getSeqPanel().findSeq(e);
-
-    if (e.isPopupTrigger())
+    if (e.isPopupTrigger()) // Mac reports this in mousePressed
     {
-      Sequence sq = (Sequence) av.getAlignment().getSequenceAt(seq);
-      // build a new links menu based on the current links + any non-positional
-      // features
-      Vector<String> nlinks = new Vector<String>(
-              Preferences.sequenceURLLinks);
-      SequenceFeature sfs[] = sq == null ? null : sq.getSequenceFeatures();
-      if (sfs != null)
-      {
-        for (SequenceFeature sf : sfs)
-        {
-          if (sf.begin == sf.end && sf.begin == 0)
-          {
-            if (sf.links != null && sf.links.size() > 0)
-            {
-              for (int l = 0, lSize = sf.links.size(); l < lSize; l++)
-              {
-                nlinks.addElement(sf.links.elementAt(l));
-              }
-            }
-          }
-        }
-      }
-
-      PopupMenu pop = new PopupMenu(alignPanel, sq, nlinks,
-              Preferences.getGroupURLLinks());
-      pop.show(this, e.getX(), e.getY());
+      showPopupMenu(e);
+      return;
+    }
 
+    /*
+     * defer right-mouse click handling to mouseReleased on Windows
+     * (where isPopupTrigger() will answer true)
+     * NB isRightMouseButton is also true for Cmd-click on Mac
+     */
+    if (SwingUtilities.isRightMouseButton(e) && !Platform.isAMac())
+    {
       return;
     }
+
     if ((av.getSelectionGroup() == null)
             || (!jalview.util.Platform.isControlDown(e)
                     && !e.isShiftDown() && av.getSelectionGroup() != null))
@@ -358,6 +342,7 @@ public class IdPanel extends JPanel implements MouseListener,
       av.getSelectionGroup().setEndRes(av.getAlignment().getWidth() - 1);
     }
 
+    int seq = alignPanel.getSeqPanel().findSeq(e);
     if (e.isShiftDown() && (lastid != -1))
     {
       selectSeqs(lastid, seq);
@@ -366,13 +351,49 @@ public class IdPanel extends JPanel implements MouseListener,
     {
       selectSeq(seq);
     }
-    // TODO is this addition ok here?
+
     av.isSelectionGroupChanged(true);
 
     alignPanel.paintAlignment(true);
   }
 
   /**
+   * Build and show the popup-menu at the right-click mouse position
+   * 
+   * @param e
+   */
+  void showPopupMenu(MouseEvent e)
+  {
+    int seq2 = alignPanel.getSeqPanel().findSeq(e);
+    Sequence sq = (Sequence) av.getAlignment().getSequenceAt(seq2);
+    // build a new links menu based on the current links + any non-positional
+    // features
+    Vector<String> nlinks = new Vector<String>(
+            Preferences.sequenceURLLinks);
+    SequenceFeature sfs[] = sq == null ? null : sq.getSequenceFeatures();
+    if (sfs != null)
+    {
+      for (SequenceFeature sf : sfs)
+      {
+        if (sf.begin == sf.end && sf.begin == 0)
+        {
+          if (sf.links != null && sf.links.size() > 0)
+          {
+            for (int l = 0, lSize = sf.links.size(); l < lSize; l++)
+            {
+              nlinks.addElement(sf.links.elementAt(l));
+            }
+          }
+        }
+      }
+    }
+
+    PopupMenu pop = new PopupMenu(alignPanel, sq, nlinks,
+            Preferences.getGroupURLLinks());
+    pop.show(this, e.getX(), e.getY());
+  }
+
+  /**
    * Toggle whether the sequence is part of the current selection group.
    * 
    * @param seq
@@ -439,6 +460,11 @@ public class IdPanel extends JPanel implements MouseListener,
     PaintRefresher.Refresh(this, av.getSequenceSetId());
     // always send selection message when mouse is released
     av.sendSelection();
+
+    if (e.isPopupTrigger()) // Windows reports this in mouseReleased
+    {
+      showPopupMenu(e);
+    }
   }
 
   /**
index 7f1b305..040a1e5 100644 (file)
@@ -210,7 +210,7 @@ public class OptsAndParamsPage
     @Override
     public void mouseClicked(MouseEvent e)
     {
-      if (e.isPopupTrigger())
+      if (e.isPopupTrigger()) // for Windows
       {
         showUrlPopUp(this, finfo.toString(), e.getX(), e.getY());
       }
@@ -233,15 +233,15 @@ public class OptsAndParamsPage
     @Override
     public void mousePressed(MouseEvent e)
     {
-      // TODO Auto-generated method stub
-
+      if (e.isPopupTrigger()) // Mac
+      {
+        showUrlPopUp(this, finfo.toString(), e.getX(), e.getY());
+      }
     }
 
     @Override
     public void mouseReleased(MouseEvent e)
     {
-      // TODO Auto-generated method stub
-
     }
 
     public void resetToDefault(boolean setDefaultParams)
@@ -537,7 +537,7 @@ public class OptsAndParamsPage
     @Override
     public void mouseClicked(MouseEvent e)
     {
-      if (e.isPopupTrigger())
+      if (e.isPopupTrigger()) // for Windows
       {
         showUrlPopUp(this, finfo.toString(), e.getX(), e.getY());
       }
@@ -560,8 +560,10 @@ public class OptsAndParamsPage
     @Override
     public void mousePressed(MouseEvent e)
     {
-      // TODO Auto-generated method stub
-
+      if (e.isPopupTrigger()) // for Mac
+      {
+        showUrlPopUp(this, finfo.toString(), e.getX(), e.getY());
+      }
     }
 
     @Override
index 316b6be..0aa2459 100755 (executable)
@@ -43,6 +43,7 @@ import java.util.List;
 import javax.swing.JMenuItem;
 import javax.swing.JPanel;
 import javax.swing.JPopupMenu;
+import javax.swing.SwingUtilities;
 import javax.swing.ToolTipManager;
 
 /**
@@ -120,10 +121,19 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
     min = res;
     max = res;
 
-    if (evt.isPopupTrigger())
+    if (evt.isPopupTrigger()) // Mac: mousePressed
     {
       rightMouseButtonPressed(evt, res);
     }
+    else if (SwingUtilities.isRightMouseButton(evt) && !Platform.isAMac())
+    {
+      /*
+       * defer right-mouse click handling to mouse up on Windows
+       * (where isPopupTrigger() will answer true)
+       * but accept Cmd-click on Mac which passes isRightMouseButton
+       */
+      return;
+    }
     else
     {
       leftMouseButtonPressed(evt, res);
@@ -222,6 +232,11 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
    */
   protected void leftMouseButtonPressed(MouseEvent evt, final int res)
   {
+    /*
+     * Ctrl-click/Cmd-click adds to the selection
+     * Shift-click extends the selection
+     */
+    // TODO Problem: right-click on Windows not reported until mouseReleased?!?
     if (!Platform.isControlDown(evt) && !evt.isShiftDown())
     {
       av.getColumnSelection().clear();
@@ -281,8 +296,14 @@ public class ScalePanel extends JPanel implements MouseMotionListener,
 
     if (!stretchingGroup)
     {
-      ap.paintAlignment(false);
-
+      if (evt.isPopupTrigger()) // Windows: mouseReleased
+      {
+        rightMouseButtonPressed(evt, res);
+      }
+      else
+      {
+        ap.paintAlignment(false);
+      }
       return;
     }
 
index f476d41..136d222 100644 (file)
@@ -43,6 +43,7 @@ import jalview.structure.VamsasSource;
 import jalview.util.Comparison;
 import jalview.util.MappingUtils;
 import jalview.util.MessageManager;
+import jalview.util.Platform;
 import jalview.viewmodel.AlignmentViewport;
 
 import java.awt.BorderLayout;
@@ -582,6 +583,13 @@ public class SeqPanel extends JPanel implements MouseListener,
     mouseDragging = false;
     mouseWheelPressed = false;
 
+    if (evt.isPopupTrigger()) // Windows: mouseReleased
+    {
+      showPopupMenu(evt);
+      evt.consume();
+      return;
+    }
+
     if (!editingSeqs)
     {
       doMouseReleasedDefineMode(evt);
@@ -836,7 +844,8 @@ public class SeqPanel extends JPanel implements MouseListener,
    * set if av.getSelectionGroup() refers to a group that is defined on the
    * alignment view, rather than a transient selection
    */
-  private boolean editingDefinedGroup = false;  // TODO: refactor to avcontroller or viewModel
+  // private boolean editingDefinedGroup = false; // TODO: refactor to
+  // avcontroller or viewModel
 
   /**
    * Set status message in alignment panel
@@ -1546,9 +1555,10 @@ public class SeqPanel extends JPanel implements MouseListener,
    */
   public void doMousePressedDefineMode(MouseEvent evt)
   {
-    int res = findRes(evt);
-    int seq = findSeq(evt);
+    final int res = findRes(evt);
+    final int seq = findSeq(evt);
     oldSeq = seq;
+    needOverviewUpdate = false;
 
     startWrapBlock = wrappedBlock;
 
@@ -1583,12 +1593,10 @@ public class SeqPanel extends JPanel implements MouseListener,
               && (res < stretchGroup.getEndRes()))
       {
         av.setSelectionGroup(stretchGroup);
-        editingDefinedGroup = true;
       }
       else
       {
         stretchGroup = null;
-        editingDefinedGroup = false;
       }
     }
     else if (!stretchGroup.getSequences(null).contains(sequence)
@@ -1607,35 +1615,27 @@ public class SeqPanel extends JPanel implements MouseListener,
                   && (allGroups[i].getEndRes() >= res))
           {
             stretchGroup = allGroups[i];
-            editingDefinedGroup = true;
             break;
           }
         }
       }
 
       av.setSelectionGroup(stretchGroup);
-
     }
 
-    if (evt.isPopupTrigger())
+    if (evt.isPopupTrigger()) // Mac: mousePressed
     {
-      List<SequenceFeature> allFeatures = ap.getFeatureRenderer()
-              .findFeaturesAtRes(sequence.getDatasetSequence(),
-                      sequence.findPosition(res));
-      List<String> links = new ArrayList<String>();
-      for (SequenceFeature sf : allFeatures)
-      {
-        if (sf.links != null)
-        {
-          for (String link : sf.links)
-          {
-            links.add(link);
-          }
-        }
-      }
+      showPopupMenu(evt);
+      return;
+    }
 
-      PopupMenu pop = new PopupMenu(ap, null, links);
-      pop.show(this, evt.getX(), evt.getY());
+    /*
+     * defer right-mouse click handling to mouseReleased on Windows
+     * (where isPopupTrigger() will answer true)
+     * NB isRightMouseButton is also true for Cmd-click on Mac
+     */
+    if (SwingUtilities.isRightMouseButton(evt) && !Platform.isAMac())
+    {
       return;
     }
 
@@ -1657,7 +1657,6 @@ public class SeqPanel extends JPanel implements MouseListener,
       sg.setEndRes(res);
       sg.addSequence(sequence, false);
       av.setSelectionGroup(sg);
-      editingDefinedGroup = false;
       stretchGroup = sg;
 
       if (av.getConservationSelected())
@@ -1689,6 +1688,37 @@ public class SeqPanel extends JPanel implements MouseListener,
   }
 
   /**
+   * Build and show a pop-up menu at the right-click mouse position
+   * 
+   * @param evt
+   * @param res
+   * @param sequence
+   */
+  void showPopupMenu(MouseEvent evt)
+  {
+    final int res = findRes(evt);
+    final int seq = findSeq(evt);
+    SequenceI sequence = av.getAlignment().getSequenceAt(seq);
+    List<SequenceFeature> allFeatures = ap.getFeatureRenderer()
+            .findFeaturesAtRes(sequence.getDatasetSequence(),
+                    sequence.findPosition(res));
+    List<String> links = new ArrayList<String>();
+    for (SequenceFeature sf : allFeatures)
+    {
+      if (sf.links != null)
+      {
+        for (String link : sf.links)
+        {
+          links.add(link);
+        }
+      }
+    }
+
+    PopupMenu pop = new PopupMenu(ap, null, links);
+    pop.show(this, evt.getX(), evt.getY());
+  }
+
+  /**
    * DOCUMENT ME!
    * 
    * @param evt
@@ -1703,7 +1733,7 @@ public class SeqPanel extends JPanel implements MouseListener,
     // always do this - annotation has own state
     // but defer colourscheme update until hidden sequences are passed in
     boolean vischange = stretchGroup.recalcConservation(true);
-    needOverviewUpdate |= vischange && editingDefinedGroup;
+    needOverviewUpdate |= vischange && av.isSelectionDefinedGroup();
     if (stretchGroup.cs != null)
     {
       stretchGroup.cs.alignmentChanged(stretchGroup,
@@ -1723,7 +1753,6 @@ public class SeqPanel extends JPanel implements MouseListener,
     PaintRefresher.Refresh(this, av.getSequenceSetId());
     ap.paintAlignment(needOverviewUpdate);
     needOverviewUpdate =false;
-    editingDefinedGroup = false;
     changeEndRes = false;
     changeStartRes = false;
     stretchGroup = null;
@@ -1777,7 +1806,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       if (res > (stretchGroup.getStartRes() - 1))
       {
         stretchGroup.setEndRes(res);
-        needOverviewUpdate |= editingDefinedGroup;
+        needOverviewUpdate |= av.isSelectionDefinedGroup();
       }
     }
     else if (changeStartRes)
@@ -1785,7 +1814,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       if (res < (stretchGroup.getEndRes() + 1))
       {
         stretchGroup.setStartRes(res);
-        needOverviewUpdate |= editingDefinedGroup;
+        needOverviewUpdate |= av.isSelectionDefinedGroup();
       }
     }
 
@@ -1819,7 +1848,7 @@ public class SeqPanel extends JPanel implements MouseListener,
       if (stretchGroup.getSequences(null).contains(nextSeq))
       {
         stretchGroup.deleteSequence(seq, false);
-        needOverviewUpdate |= editingDefinedGroup;
+        needOverviewUpdate |= av.isSelectionDefinedGroup();
       }
       else
       {
@@ -1829,7 +1858,7 @@ public class SeqPanel extends JPanel implements MouseListener,
         }
 
         stretchGroup.addSequence(nextSeq, false);
-        needOverviewUpdate |= editingDefinedGroup;
+        needOverviewUpdate |= av.isSelectionDefinedGroup();
       }
     }
 
index f21c5e7..6bfea9e 100755 (executable)
@@ -59,6 +59,7 @@ import java.util.Vector;
 import javax.swing.JColorChooser;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
 import javax.swing.ToolTipManager;
 
 /**
@@ -174,13 +175,13 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
     tree.findHeight(tree.getTopNode());
 
     // Now have to calculate longest name based on the leaves
-    Vector leaves = tree.findLeaves(tree.getTopNode(), new Vector());
+    Vector<SequenceNode> leaves = tree.findLeaves(tree.getTopNode());
     boolean has_placeholders = false;
     longestName = "";
 
     for (int i = 0; i < leaves.size(); i++)
     {
-      SequenceNode lf = (SequenceNode) leaves.elementAt(i);
+      SequenceNode lf = leaves.elementAt(i);
 
       if (lf.isPlaceholder())
       {
@@ -747,21 +748,27 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
   }
 
   /**
-   * DOCUMENT ME!
+   * Empty method to satisfy the MouseListener interface
    * 
    * @param e
-   *          DOCUMENT ME!
    */
   @Override
   public void mouseReleased(MouseEvent e)
   {
+    /*
+     * isPopupTrigger is set on mouseReleased on Windows
+     */
+    if (e.isPopupTrigger())
+    {
+      chooseSubtreeColour();
+      e.consume(); // prevent mouseClicked happening
+    }
   }
 
   /**
-   * DOCUMENT ME!
+   * Empty method to satisfy the MouseListener interface
    * 
    * @param e
-   *          DOCUMENT ME!
    */
   @Override
   public void mouseEntered(MouseEvent e)
@@ -769,10 +776,9 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
   }
 
   /**
-   * DOCUMENT ME!
+   * Empty method to satisfy the MouseListener interface
    * 
    * @param e
-   *          DOCUMENT ME!
    */
   @Override
   public void mouseExited(MouseEvent e)
@@ -780,47 +786,57 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
   }
 
   /**
-   * DOCUMENT ME!
+   * Handles a mouse click on a tree node (clicks elsewhere are handled in
+   * mousePressed). Click selects the sub-tree, double-click swaps leaf nodes
+   * order, right-click opens a dialogue to choose colour for the sub-tree.
    * 
    * @param e
-   *          DOCUMENT ME!
    */
   @Override
   public void mouseClicked(MouseEvent evt)
   {
-    if (highlightNode != null)
+    if (highlightNode == null)
     {
-      if (evt.isPopupTrigger())
-      {
-        Color col = JColorChooser.showDialog(this,
-                MessageManager.getString("label.select_subtree_colour"),
-                highlightNode.color);
-        if (col != null)
-        {
-          setColor(highlightNode, col);
-        }
-      }
-      else if (evt.getClickCount() > 1)
+      return;
+    }
+
+    if (evt.getClickCount() > 1)
+    {
+      tree.swapNodes(highlightNode);
+      tree.reCount(tree.getTopNode());
+      tree.findHeight(tree.getTopNode());
+    }
+    else
+    {
+      Vector<SequenceNode> leaves = tree.findLeaves(highlightNode);
+
+      for (int i = 0; i < leaves.size(); i++)
       {
-        tree.swapNodes(highlightNode);
-        tree.reCount(tree.getTopNode());
-        tree.findHeight(tree.getTopNode());
+        SequenceI seq = (SequenceI) leaves.elementAt(i)
+                .element();
+        treeSelectionChanged(seq);
       }
-      else
-      {
-        Vector leaves = new Vector();
-        tree.findLeaves(highlightNode, leaves);
+      av.sendSelection();
+    }
 
-        for (int i = 0; i < leaves.size(); i++)
-        {
-          SequenceI seq = (SequenceI) ((SequenceNode) leaves.elementAt(i))
-                  .element();
-          treeSelectionChanged(seq);
-        }
-        av.sendSelection();
-      }
+    PaintRefresher.Refresh(tp, av.getSequenceSetId());
+    repaint();
+  }
 
-      PaintRefresher.Refresh(tp, av.getSequenceSetId());
+  /**
+   * Offer the user the option to choose a colour for the highlighted node and
+   * its children; this colour is also applied to the corresponding sequence ids
+   * in the alignment
+   */
+  void chooseSubtreeColour()
+  {
+    Color col = JColorChooser.showDialog(this,
+            MessageManager.getString("label.select_subtree_colour"),
+            highlightNode.color);
+    if (col != null)
+    {
+      setColor(highlightNode, col);
+      PaintRefresher.Refresh(tp, ap.av.getSequenceSetId());
       repaint();
     }
   }
@@ -857,16 +873,42 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
   }
 
   /**
-   * DOCUMENT ME!
+   * Handles a mouse press on a sequence name or the tree background canvas
+   * (click on a node is handled in mouseClicked). The action is to create
+   * groups by partitioning the tree at the mouse position. Colours for the
+   * groups (and sequence names) are generated randomly.
    * 
    * @param e
-   *          DOCUMENT ME!
    */
   @Override
   public void mousePressed(MouseEvent e)
   {
     av.setCurrentTree(tree);
 
+    /*
+     * isPopupTrigger is set for mousePressed (Mac)
+     * or mouseReleased (Windows)
+     */
+    if (e.isPopupTrigger())
+    {
+      if (highlightNode != null)
+      {
+        chooseSubtreeColour();
+      }
+      return;
+    }
+
+    /*
+     * defer right-click handling on Windows to
+     * mouseClicked; note isRightMouseButton
+     * also matches Cmd-click on Mac which should do
+     * nothing here
+     */
+    if (SwingUtilities.isRightMouseButton(e))
+    {
+      return;
+    }
+
     int x = e.getX();
     int y = e.getY();
 
@@ -925,16 +967,16 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
     {
       Color col = new Color((int) (Math.random() * 255),
               (int) (Math.random() * 255), (int) (Math.random() * 255));
-      setColor((SequenceNode) tree.getGroups().elementAt(i), col.brighter());
+      setColor(tree.getGroups().elementAt(i), col.brighter());
 
-      Vector l = tree.findLeaves(
-              (SequenceNode) tree.getGroups().elementAt(i), new Vector());
+      Vector<SequenceNode> l = tree.findLeaves(tree
+              .getGroups().elementAt(i));
 
-      Vector sequences = new Vector();
+      Vector<SequenceI> sequences = new Vector<SequenceI>();
 
       for (int j = 0; j < l.size(); j++)
       {
-        SequenceI s1 = (SequenceI) ((SequenceNode) l.elementAt(j))
+        SequenceI s1 = (SequenceI) l.elementAt(j)
                 .element();
 
         if (!sequences.contains(s1))
@@ -993,17 +1035,14 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
                 .getCodingComplement();
         if (codingComplement != null)
         {
-          if (codingComplement != null)
+          SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg, av,
+                  codingComplement);
+          if (mappedGroup.getSequences().size() > 0)
           {
-            SequenceGroup mappedGroup = MappingUtils.mapSequenceGroup(sg,
-                    av, codingComplement);
-            if (mappedGroup.getSequences().size() > 0)
+            codingComplement.getAlignment().addGroup(mappedGroup);
+            for (SequenceI seq : mappedGroup.getSequences())
             {
-              codingComplement.getAlignment().addGroup(mappedGroup);
-              for (SequenceI seq : mappedGroup.getSequences())
-              {
-                codingComplement.setSequenceColour(seq, col.brighter());
-              }
+              codingComplement.setSequenceColour(seq, col.brighter());
             }
           }
         }
@@ -1022,11 +1061,8 @@ public class TreeCanvas extends JPanel implements MouseListener, Runnable,
       {
         ((AlignViewport) codingComplement).getAlignPanel()
                 .updateAnnotation();
-
       }
-
     }
-
   }
 
   /**
index 0bf4096..a3781a7 100644 (file)
@@ -291,8 +291,10 @@ public class Tree extends DatastoreItem
       }
     }
     if (alsq.size() < sequences.length)
+    {
       Cache.log
               .warn("Not recovered all alignment sequences for given set of input sequence CIGARS");
+    }
     return alsq;
   }
 
@@ -306,15 +308,18 @@ public class Tree extends DatastoreItem
   public void UpdateSequenceTreeMap(TreePanel tp)
   {
     if (tp == null || tree == null)
+    {
       return;
-    Vector leaves = new Vector();
+    }
+
     if (tp.getTree() == null)
     {
       Cache.log.warn("Not updating SequenceTreeMap for "
               + tree.getVorbaId());
       return;
     }
-    tp.getTree().findLeaves(tp.getTree().getTopNode(), leaves);
+    Vector<SequenceNode> leaves = tp.getTree().findLeaves(
+            tp.getTree().getTopNode());
     Treenode[] tn = tree.getTreenode(); // todo: select nodes for this
     // particular tree
     int sz = tn.length;
@@ -371,8 +376,7 @@ public class Tree extends DatastoreItem
    */
   public Treenode[] makeTreeNodes(NJTree ntree, Newick newick)
   {
-    Vector leaves = new Vector();
-    ntree.findLeaves(ntree.getTopNode(), leaves);
+    Vector<SequenceNode> leaves = ntree.findLeaves(ntree.getTopNode());
     Vector tnv = new Vector();
     Enumeration l = leaves.elements();
     Hashtable nodespecs = new Hashtable();
@@ -473,7 +477,9 @@ public class Tree extends DatastoreItem
         --occurence;
       }
       else
+      {
         bn = null;
+      }
     }
     return bn;
   }
index d7def6b..70333f4 100755 (executable)
@@ -292,34 +292,51 @@ public class GAlignFrame extends JInternalFrame
           @Override
           public void mousePressed(MouseEvent evt)
           {
-            if (evt.isPopupTrigger())
+            if (evt.isPopupTrigger()) // Mac
             {
-              radioItem.removeActionListener(radioItem.getActionListeners()[0]);
-
-              int option = JOptionPane.showInternalConfirmDialog(
-                      jalview.gui.Desktop.desktop,
-                      MessageManager
-                              .getString("label.remove_from_default_list"),
-                      MessageManager
-                              .getString("label.remove_user_defined_colour"),
-                      JOptionPane.YES_NO_OPTION);
-              if (option == JOptionPane.YES_OPTION)
-              {
-                jalview.gui.UserDefinedColours
-                        .removeColourFromDefaults(radioItem.getText());
-                colourMenu.remove(radioItem);
-              }
-              else
+              offerRemoval(radioItem);
+            }
+          }
+
+          @Override
+          public void mouseReleased(MouseEvent evt)
+          {
+            if (evt.isPopupTrigger()) // Windows
+            {
+              offerRemoval(radioItem);
+            }
+          }
+
+          /**
+           * @param radioItem
+           */
+          void offerRemoval(final JRadioButtonMenuItem radioItem)
+          {
+            radioItem.removeActionListener(radioItem.getActionListeners()[0]);
+
+            int option = JOptionPane.showInternalConfirmDialog(
+                    jalview.gui.Desktop.desktop,
+                    MessageManager
+                            .getString("label.remove_from_default_list"),
+                    MessageManager
+                            .getString("label.remove_user_defined_colour"),
+                    JOptionPane.YES_NO_OPTION);
+            if (option == JOptionPane.YES_OPTION)
+            {
+              jalview.gui.UserDefinedColours
+                      .removeColourFromDefaults(radioItem.getText());
+              colourMenu.remove(radioItem);
+            }
+            else
+            {
+              radioItem.addActionListener(new ActionListener()
               {
-                radioItem.addActionListener(new ActionListener()
+                @Override
+                public void actionPerformed(ActionEvent evt)
                 {
-                  @Override
-                  public void actionPerformed(ActionEvent evt)
-                  {
-                    userDefinedColour_actionPerformed(evt);
-                  }
-                });
-              }
+                  userDefinedColour_actionPerformed(evt);
+                }
+              });
             }
           }
         });
@@ -2030,7 +2047,19 @@ public class GAlignFrame extends JInternalFrame
       @Override
       public void mousePressed(MouseEvent e)
       {
-        tabbedPane_mousePressed(e);
+        if (e.isPopupTrigger()) // Mac
+        {
+          tabbedPane_mousePressed(e);
+        }
+      }
+
+      @Override
+      public void mouseReleased(MouseEvent e)
+      {
+        if (e.isPopupTrigger()) // Windows
+        {
+          tabbedPane_mousePressed(e);
+        }
       }
     });
     tabbedPane.addFocusListener(new FocusAdapter()
index a9e3112..157dddd 100644 (file)
@@ -106,6 +106,7 @@ public class GCutAndPasteHtmlTransfer extends JInternalFrame
     ok.setText(MessageManager.getString("label.new_window"));
     ok.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         ok_actionPerformed(e);
@@ -114,6 +115,7 @@ public class GCutAndPasteHtmlTransfer extends JInternalFrame
     cancel.setText(MessageManager.getString("action.close"));
     cancel.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         cancel_actionPerformed(e);
@@ -123,6 +125,7 @@ public class GCutAndPasteHtmlTransfer extends JInternalFrame
     close.setText(MessageManager.getString("action.close"));
     close.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         cancel_actionPerformed(e);
@@ -137,6 +140,7 @@ public class GCutAndPasteHtmlTransfer extends JInternalFrame
                     .getMenuShortcutKeyMask(), false));
     selectAll.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         selectAll_actionPerformed(e);
@@ -149,6 +153,7 @@ public class GCutAndPasteHtmlTransfer extends JInternalFrame
                     .getMenuShortcutKeyMask(), false));
     save.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         save_actionPerformed(e);
@@ -163,15 +168,23 @@ public class GCutAndPasteHtmlTransfer extends JInternalFrame
     textarea.setFont(new java.awt.Font("Monospaced", Font.PLAIN, 12));
     textarea.addMouseListener(new java.awt.event.MouseAdapter()
     {
+      @Override
       public void mousePressed(MouseEvent e)
       {
         textarea_mousePressed(e);
       }
+
+      @Override
+      public void mouseReleased(MouseEvent e)
+      {
+        textarea_mousePressed(e);
+      }
     });
     editMenu.setText(MessageManager.getString("action.edit"));
     copyItem.setText(MessageManager.getString("action.copy"));
     copyItem.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         copyItem_actionPerformed(e);
index acf1581..21705f0 100755 (executable)
@@ -103,6 +103,7 @@ public class GCutAndPasteTransfer extends JInternalFrame
     ok.setText(MessageManager.getString("label.new_window"));
     ok.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         ok_actionPerformed(e);
@@ -111,6 +112,7 @@ public class GCutAndPasteTransfer extends JInternalFrame
     cancel.setText(MessageManager.getString("action.close"));
     cancel.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         cancel_actionPerformed(e);
@@ -124,6 +126,7 @@ public class GCutAndPasteTransfer extends JInternalFrame
                     .getMenuShortcutKeyMask(), false));
     selectAll.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         selectAll_actionPerformed(e);
@@ -136,6 +139,7 @@ public class GCutAndPasteTransfer extends JInternalFrame
                     .getMenuShortcutKeyMask(), false));
     save.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         save_actionPerformed(e);
@@ -152,15 +156,23 @@ public class GCutAndPasteTransfer extends JInternalFrame
     textarea.setFont(new java.awt.Font("Monospaced", Font.PLAIN, 12));
     textarea.addMouseListener(new java.awt.event.MouseAdapter()
     {
+      @Override
       public void mousePressed(MouseEvent e)
       {
-        textarea_mousePressed(e);
+        textarea_mousePressed(e); // on Mac
+      }
+
+      @Override
+      public void mouseReleased(MouseEvent e)
+      {
+        textarea_mousePressed(e); // on Windows
       }
     });
     editMenu.setText(MessageManager.getString("action.edit"));
     pasteMenu.setText(MessageManager.getString("action.paste"));
     pasteMenu.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         pasteMenu_actionPerformed(e);
@@ -169,6 +181,7 @@ public class GCutAndPasteTransfer extends JInternalFrame
     copyItem.setText(MessageManager.getString("action.copy"));
     copyItem.addActionListener(new ActionListener()
     {
+      @Override
       public void actionPerformed(ActionEvent e)
       {
         copyItem_actionPerformed(e);
index 85a27f6..3fb384f 100644 (file)
@@ -79,8 +79,10 @@ public class Platform
   }
 
   /**
-   * Answers true if the mouse event has Meta-down (on Mac) or Ctrl-down (on
-   * other o/s)
+   * Answers true if the mouse event has Meta-down (Command key on Mac) or
+   * Ctrl-down (on other o/s). Note this answers _false_ if the Ctrl key is
+   * pressed instead of the Meta/Cmd key on Mac. To test for Ctrl-click on Mac,
+   * you can use e.isPopupTrigger().
    * 
    * @param e
    * @return
index a954a83..97f2e1c 100644 (file)
@@ -2782,5 +2782,32 @@ public abstract class AlignmentViewport implements AlignViewportI,
     }
   }
 
+  /**
+   * hold status of current selection group - defined on alignment or not.
+   */
+  private boolean selectionIsDefinedGroup = false;
 
+  @Override
+  public boolean isSelectionDefinedGroup()
+  {
+    if (selectionGroup == null)
+    {
+      return false;
+    }
+    if (isSelectionGroupChanged(true))
+    {
+      selectionIsDefinedGroup = false;
+      List<SequenceGroup> gps = alignment.getGroups();
+      if (gps == null || gps.size() == 0)
+      {
+        selectionIsDefinedGroup = false;
+      }
+      else
+      {
+        selectionIsDefinedGroup = gps.contains(selectionGroup);
+      }
+    }
+    return selectionGroup.getContext() == alignment
+            || selectionIsDefinedGroup;
+  }
 }
diff --git a/test/jalview/gui/MouseEventDemo.java b/test/jalview/gui/MouseEventDemo.java
new file mode 100644 (file)
index 0000000..3667b52
--- /dev/null
@@ -0,0 +1,236 @@
+package jalview.gui;
+
+/*
+ * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Oracle or the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+* MouseEventDemo.java
+*/
+
+import jalview.util.Platform;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.InputMap;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTextArea;
+import javax.swing.KeyStroke;
+import javax.swing.SwingUtilities;
+
+/**
+ * Sourced from Oracle and adapted
+ * 
+ * @see https
+ *      ://docs.oracle.com/javase/tutorial/uiswing/events/mouselistener.html
+ */
+public class MouseEventDemo extends JPanel implements MouseListener
+{
+  private class BlankArea extends JLabel
+  {
+    Dimension minSize = new Dimension(200, 100);
+
+    public BlankArea(Color color)
+    {
+      setBackground(color);
+      setOpaque(true);
+      setBorder(BorderFactory.createLineBorder(Color.black));
+    }
+
+    @Override
+    public Dimension getMinimumSize()
+    {
+      return minSize;
+    }
+
+    @Override
+    public Dimension getPreferredSize()
+    {
+      return minSize;
+    }
+  }
+
+  static int counter = 0;
+
+  BlankArea blankArea;
+
+  JTextArea textArea;
+
+  static final String NEWLINE = System.getProperty("line.separator");
+
+  public static void main(String[] args)
+  {
+    // Schedule a job for the event dispatch thread:
+    // creating and showing this application's GUI.
+    javax.swing.SwingUtilities.invokeLater(new Runnable()
+    {
+      @Override
+      public void run()
+      {
+        createAndShowGUI();
+      }
+    });
+  }
+
+  /**
+   * Create the GUI and show it. For thread safety, this method should be
+   * invoked from the event dispatch thread.
+   */
+  private static void createAndShowGUI()
+  {
+    // Create and set up the window.
+    JFrame frame = new JFrame("MouseEventDemo (C to clear)");
+    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+
+    // Create and set up the content pane.
+    JComponent newContentPane = new MouseEventDemo();
+    newContentPane.setOpaque(true); // content panes must be opaque
+    frame.setContentPane(newContentPane);
+
+    // Display the window.
+    frame.pack();
+    frame.setVisible(true);
+  }
+
+  public MouseEventDemo()
+  {
+    super(new GridLayout(0, 1));
+
+    textArea = new JTextArea();
+    textArea.setEditable(false);
+    JScrollPane scrollPane = new JScrollPane(textArea);
+    scrollPane
+            .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
+    scrollPane.setPreferredSize(new Dimension(400, 75));
+
+    blankArea = new BlankArea(Color.YELLOW);
+    JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
+            blankArea, scrollPane);
+    splitPane.setVisible(true);
+    splitPane.setDividerLocation(0.2d);
+    splitPane.setResizeWeight(0.5d);
+    add(splitPane);
+
+    addKeyBinding();
+
+    blankArea.addMouseListener(this);
+    addMouseListener(this);
+    setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
+  }
+
+  private void addKeyBinding()
+  {
+    addKeyBinding(KeyStroke.getKeyStroke('C'));
+    addKeyBinding(KeyStroke.getKeyStroke('c'));
+  }
+
+  /**
+   * @param ks
+   */
+  void addKeyBinding(final KeyStroke ks)
+  {
+    InputMap inputMap = this.getInputMap(JComponent.WHEN_FOCUSED);
+    inputMap.put(ks, ks);
+    this.getActionMap().put(ks, new AbstractAction()
+    {
+      @Override
+      public void actionPerformed(ActionEvent e)
+      {
+        textArea.setText("");
+        log("");
+      }
+    });
+  }
+
+  void logEvent(String eventDescription, MouseEvent e)
+  {
+    log("------- " + counter++ + ": " + eventDescription);
+    log("e.isPopupTrigger: " + e.isPopupTrigger());
+    log("SwingUtilities.isRightMouseButton: "
+            + SwingUtilities.isRightMouseButton(e));
+    log("SwingUtilities.isLeftMouseButton: "
+            + SwingUtilities.isLeftMouseButton(e));
+    log("Platform.isControlDown: " + Platform.isControlDown(e));
+    log("e.isControlDown: " + e.isControlDown());
+    log("e.isAltDown: " + e.isAltDown());
+    log("e.isMetaDown: " + e.isMetaDown());
+    log("e.isShiftDown: " + e.isShiftDown());
+    log("e.getClickCount: " + e.getClickCount());
+  }
+
+  /**
+   * @param msg
+   */
+  void log(String msg)
+  {
+    textArea.append(msg + NEWLINE);
+    textArea.setCaretPosition(textArea.getDocument().getLength());
+  }
+
+  @Override
+  public void mousePressed(MouseEvent e)
+  {
+    logEvent("Mouse pressed", e);
+  }
+
+  @Override
+  public void mouseReleased(MouseEvent e)
+  {
+    logEvent("Mouse released", e);
+  }
+
+  @Override
+  public void mouseEntered(MouseEvent e)
+  {
+  }
+
+  @Override
+  public void mouseExited(MouseEvent e)
+  {
+  }
+
+  @Override
+  public void mouseClicked(MouseEvent e)
+  {
+    logEvent("Mouse clicked", e);
+  }
+}
\ No newline at end of file
index f89f58b..4de36f2 100644 (file)
@@ -116,24 +116,23 @@ public class NewickFileTests
       AssertJUnit.assertTrue(stage + "Null Tree", tree_regen != null);
       stage = "Compare original and generated tree" + treename;
 
-      Vector oseqs, nseqs;
-      oseqs = new NJTree(new SequenceI[0], nf).findLeaves(nf.getTree(),
-              new Vector());
+      Vector<SequenceNode> oseqs, nseqs;
+      oseqs = new NJTree(new SequenceI[0], nf).findLeaves(nf.getTree());
       AssertJUnit.assertTrue(stage + "No nodes in original tree.",
               oseqs.size() > 0);
       SequenceI[] olsqs = new SequenceI[oseqs.size()];
       for (int i = 0, iSize = oseqs.size(); i < iSize; i++)
       {
-        olsqs[i] = (SequenceI) ((SequenceNode) oseqs.get(i)).element();
+        olsqs[i] = (SequenceI) oseqs.get(i).element();
       }
-      nseqs = new NJTree(new SequenceI[0], nf_regen).findLeaves(
-              nf_regen.getTree(), new Vector());
+      nseqs = new NJTree(new SequenceI[0], nf_regen).findLeaves(nf_regen
+              .getTree());
       AssertJUnit.assertTrue(stage + "No nodes in regerated tree.",
               nseqs.size() > 0);
       SequenceI[] nsqs = new SequenceI[nseqs.size()];
       for (int i = 0, iSize = nseqs.size(); i < iSize; i++)
       {
-        nsqs[i] = (SequenceI) ((SequenceNode) nseqs.get(i)).element();
+        nsqs[i] = (SequenceI) nseqs.get(i).element();
       }
       AssertJUnit.assertTrue(stage
               + " Different number of leaves (original " + olsqs.length
index b11b567..b41aab3 100644 (file)
@@ -20,6 +20,7 @@
                <allow pkg="com.stevesoft.pat"/>
                
                <subpackage name="appletgui">
+               <disallow pkg="javax.swing"/>
                <disallow pkg="jalview.gui"/>
                <disallow pkg="jalview.ws"/>
                <allow pkg="org.jmol"/>