Formatting
[jalview.git] / src / jalview / gui / FeatureSettings.java
index b720008..955684c 100755 (executable)
@@ -1,6 +1,6 @@
 /*\r
  * Jalview - A Sequence Alignment Editor and Viewer\r
- * Copyright (C) 2005 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
+ * Copyright (C) 2007 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle\r
  *\r
  * This program is free software; you can redistribute it and/or\r
  * modify it under the terms of the GNU General Public License\r
  */\r
 package jalview.gui;\r
 \r
-import jalview.datamodel.*;\r
-import javax.swing.*;\r
-import javax.swing.event.*;\r
-import java.awt.*;\r
+import java.io.*;\r
 import java.util.*;\r
-import javax.swing.BorderFactory;\r
+\r
+import java.awt.*;\r
 import java.awt.event.*;\r
+import javax.swing.*;\r
+import javax.swing.event.*;\r
 import javax.swing.table.*;\r
-import java.io.*;\r
-import jalview.io.JalviewFileChooser;\r
-import java.awt.BorderLayout;\r
-import java.awt.Font;\r
-import java.awt.Color;\r
-import org.biojava.dasobert.dasregistry.DasSource;\r
-import org.biojava.dasobert.dasregistry.DasCoordinateSystem;\r
-\r
-public class FeatureSettings extends JPanel\r
+\r
+import jalview.datamodel.*;\r
+import jalview.io.*;\r
+\r
+public class FeatureSettings\r
+    extends JPanel\r
 {\r
   DasSourceBrowser dassourceBrowser;\r
+  jalview.io.DasSequenceFeatureFetcher dasFeatureFetcher;\r
   JPanel settingsPane = new JPanel();\r
   JPanel dasSettingsPane = new JPanel();\r
 \r
   final FeatureRenderer fr;\r
-  final AlignFrame af;\r
-  Object [][] originalData;\r
+  public final AlignFrame af;\r
+  Object[][] originalData;\r
   final JInternalFrame frame;\r
   JScrollPane scrollPane = new JScrollPane();\r
   JTable table;\r
@@ -50,32 +48,78 @@ public class FeatureSettings extends JPanel
   JSlider transparency = new JSlider();\r
 \r
   JPanel transPanel = new JPanel(new FlowLayout());\r
-  boolean alignmentHasFeatures = false;\r
 \r
   public FeatureSettings(AlignFrame af)\r
   {\r
     this.af = af;\r
     fr = af.getFeatureRenderer();\r
 \r
-    transparency.setMaximum( 100 - (int)(fr.transparency*100) ) ;\r
+    transparency.setMaximum(100 - (int) (fr.transparency * 100));\r
 \r
-   try\r
-   {\r
-     jbInit();\r
-   }\r
-   catch (Exception ex)\r
-   {\r
-     ex.printStackTrace();\r
-   }\r
+    try\r
+    {\r
+      jbInit();\r
+    }\r
+    catch (Exception ex)\r
+    {\r
+      ex.printStackTrace();\r
+    }\r
 \r
-    dassourceBrowser = new DasSourceBrowser();\r
-    dasSettingsPane.add(dassourceBrowser, BorderLayout.CENTER);\r
+    table = new JTable();\r
+    table.getTableHeader().setFont(new Font("Verdana", Font.PLAIN, 12));\r
+    table.setFont(new Font("Verdana", Font.PLAIN, 12));\r
+    table.setDefaultRenderer(Color.class,\r
+                             new ColorRenderer());\r
+\r
+    table.setDefaultEditor(Color.class,\r
+                           new ColorEditor());\r
+\r
+    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\r
+\r
+    table.addMouseListener(new MouseAdapter()\r
+    {\r
+      public void mousePressed(MouseEvent evt)\r
+      {\r
+        selectedRow = table.rowAtPoint(evt.getPoint());\r
+      }\r
+    });\r
+\r
+    table.addMouseMotionListener(new MouseMotionAdapter()\r
+    {\r
+      public void mouseDragged(MouseEvent evt)\r
+      {\r
+        int newRow = table.rowAtPoint(evt.getPoint());\r
+        if (newRow != selectedRow\r
+            && selectedRow != -1\r
+            && newRow != -1)\r
+        {\r
+          Object[] temp = new Object[3];\r
+          temp[0] = table.getValueAt(selectedRow, 0);\r
+          temp[1] = table.getValueAt(selectedRow, 1);\r
+          temp[2] = table.getValueAt(selectedRow, 2);\r
+\r
+          table.setValueAt(table.getValueAt(newRow, 0), selectedRow, 0);\r
+          table.setValueAt(table.getValueAt(newRow, 1), selectedRow, 1);\r
+          table.setValueAt(table.getValueAt(newRow, 2), selectedRow, 2);\r
 \r
+          table.setValueAt(temp[0], newRow, 0);\r
+          table.setValueAt(temp[1], newRow, 1);\r
+          table.setValueAt(temp[2], newRow, 2);\r
 \r
+          selectedRow = newRow;\r
+        }\r
+      }\r
+    });\r
 \r
-    if (af.getViewport().featuresDisplayed == null || fr.renderOrder==null)\r
-       fr.findAllFeatures();\r
+    scrollPane.setViewportView(table);\r
 \r
+    dassourceBrowser = new DasSourceBrowser();\r
+    dasSettingsPane.add(dassourceBrowser, BorderLayout.CENTER);\r
+\r
+    if (af.getViewport().featuresDisplayed == null || fr.renderOrder == null)\r
+    {\r
+      fr.findAllFeatures();\r
+    }\r
 \r
     setTableData();\r
 \r
@@ -85,12 +129,12 @@ public class FeatureSettings extends JPanel
     frame.setLayer(JLayeredPane.PALETTE_LAYER);\r
   }\r
 \r
-  public void setTableData()\r
+  synchronized public void setTableData()\r
   {\r
-    alignmentHasFeatures = false;\r
-\r
     if (fr.featureGroups == null)\r
+    {\r
       fr.featureGroups = new Hashtable();\r
+    }\r
 \r
     Vector allFeatures = new Vector();\r
     Vector allGroups = new Vector();\r
@@ -99,152 +143,164 @@ public class FeatureSettings extends JPanel
 \r
     for (int i = 0; i < af.getViewport().alignment.getHeight(); i++)\r
     {\r
-      if (af.getViewport().alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures() == null)\r
+      if (af.getViewport().alignment.getSequenceAt(i).getDatasetSequence().\r
+          getSequenceFeatures() == null)\r
+      {\r
         continue;\r
+      }\r
 \r
-      alignmentHasFeatures = true;\r
-\r
-      tmpfeatures = af.getViewport().alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures();\r
+      tmpfeatures = af.getViewport().alignment.getSequenceAt(i).\r
+          getDatasetSequence().getSequenceFeatures();\r
 \r
       int index = 0;\r
       while (index < tmpfeatures.length)\r
       {\r
-        if(tmpfeatures[index].begin == 0 && tmpfeatures[index].end ==0)\r
+        if (tmpfeatures[index].begin == 0 && tmpfeatures[index].end == 0)\r
         {\r
           index++;\r
           continue;\r
         }\r
 \r
-        if(tmpfeatures[index].getFeatureGroup()!=null)\r
+        if (tmpfeatures[index].getFeatureGroup() != null)\r
         {\r
           group = tmpfeatures[index].featureGroup;\r
-          if(!allGroups.contains(group))\r
-           {\r
-             allGroups.addElement(group);\r
-\r
-             boolean visible = true;\r
-             if (fr.featureGroups.containsKey(group))\r
-             {\r
-               visible = ( (Boolean) fr.featureGroups.get(group)).booleanValue();\r
-             }\r
-             else\r
-             {\r
-               fr.featureGroups.put(group, new Boolean(visible));\r
-               if (groupPanel == null)\r
-               {\r
-                 groupPanel = new JPanel();\r
-               }\r
-\r
-               final JCheckBox check = new JCheckBox(group, visible);\r
-               check.setFont(new Font("Serif", Font.BOLD, 12));\r
-               check.addItemListener(new ItemListener()\r
-               {\r
-                 public void itemStateChanged(ItemEvent evt)\r
-                 {\r
-                   fr.featureGroups.put(check.getText(),\r
-                                        new Boolean(check.isSelected()));\r
-                   af.alignPanel.seqPanel.seqCanvas.repaint();\r
-                   if (af.alignPanel.overviewPanel != null)\r
-                     af.alignPanel.overviewPanel.updateOverviewImage();\r
-\r
-                   resetTable(true);\r
-                 }\r
-               });\r
-               groupPanel.add(check);\r
-             }\r
-           }\r
-\r
-       }\r
-\r
-       if (!allFeatures.contains(tmpfeatures[index].getType()))\r
-       {\r
-           allFeatures.addElement(tmpfeatures[index].getType());\r
-       }\r
-       index ++;\r
-    }\r
-  }\r
+          if (!allGroups.contains(group))\r
+          {\r
+            allGroups.addElement(group);\r
+\r
+            boolean visible = true;\r
+            if (fr.featureGroups.containsKey(group))\r
+            {\r
+              visible = ( (Boolean) fr.featureGroups.get(group)).booleanValue();\r
+            }\r
+\r
+            if (groupPanel == null)\r
+            {\r
+              groupPanel = new JPanel();\r
+            }\r
 \r
+            boolean alreadyAdded = false;\r
+            for (int g = 0; g < groupPanel.getComponentCount(); g++)\r
+            {\r
+              if ( ( (JCheckBox) groupPanel.getComponent(g))\r
+                  .getText().equals(group))\r
+              {\r
+                alreadyAdded = true;\r
+                break;\r
+              }\r
+            }\r
 \r
-    if(!alignmentHasFeatures)\r
-     {\r
-    //   try\r
-     //  { frame.setClosed(true);  }\r
-    //   catch (Exception ex){}\r
+            if (alreadyAdded)\r
+            {\r
+              continue;\r
+            }\r
 \r
-    //   JOptionPane.showInternalMessageDialog(\r
-    ///       Desktop.desktop, "No features have been added to this alignment!",\r
-    //\r
-   //    return;\r
-     }\r
+            fr.featureGroups.put(group, new Boolean(visible));\r
 \r
-     resetTable(false);\r
-  }\r
+            final JCheckBox check = new JCheckBox(group, visible);\r
+            check.setFont(new Font("Serif", Font.BOLD, 12));\r
+            check.addItemListener(new ItemListener()\r
+            {\r
+              public void itemStateChanged(ItemEvent evt)\r
+              {\r
+                fr.featureGroups.put(check.getText(),\r
+                                     new Boolean(check.isSelected()));\r
+                af.alignPanel.seqPanel.seqCanvas.repaint();\r
+                if (af.alignPanel.overviewPanel != null)\r
+                {\r
+                  af.alignPanel.overviewPanel.updateOverviewImage();\r
+                }\r
+\r
+                resetTable(true);\r
+              }\r
+            });\r
+            groupPanel.add(check);\r
+          }\r
+        }\r
+\r
+        if (!allFeatures.contains(tmpfeatures[index].getType()))\r
+        {\r
+          allFeatures.addElement(tmpfeatures[index].getType());\r
+        }\r
+        index++;\r
+      }\r
+    }\r
 \r
+    resetTable(false);\r
+\r
+    validate();\r
+  }\r
 \r
   void resetTable(boolean groupsChanged)\r
   {\r
-   SequenceFeature [] tmpfeatures;\r
-   String group=null, type;\r
-   Vector visibleChecks = new Vector();\r
+    SequenceFeature[] tmpfeatures;\r
+    String group = null, type;\r
+    Vector visibleChecks = new Vector();\r
 \r
-   //Find out which features should be visible depending on which groups\r
-   //are selected / deselected\r
+    //Find out which features should be visible depending on which groups\r
+    //are selected / deselected\r
     for (int i = 0; i < af.getViewport().alignment.getHeight(); i++)\r
     {\r
 \r
-        tmpfeatures = af.getViewport().alignment.getSequenceAt(i).getDatasetSequence().getSequenceFeatures();\r
-        if (tmpfeatures == null)\r
-          continue;\r
+      tmpfeatures = af.getViewport().alignment.getSequenceAt(i).\r
+          getDatasetSequence().getSequenceFeatures();\r
+      if (tmpfeatures == null)\r
+      {\r
+        continue;\r
+      }\r
 \r
-        int index = 0;\r
-        while (index < tmpfeatures.length)\r
-        {\r
-          group = tmpfeatures[index].featureGroup;\r
+      int index = 0;\r
+      while (index < tmpfeatures.length)\r
+      {\r
+        group = tmpfeatures[index].featureGroup;\r
 \r
-          if(tmpfeatures[index].begin==0 && tmpfeatures[index].end==0)\r
-          {\r
-            index ++;\r
-            continue;\r
-          }\r
+        if (tmpfeatures[index].begin == 0 && tmpfeatures[index].end == 0)\r
+        {\r
+          index++;\r
+          continue;\r
+        }\r
 \r
-          if (group==null || fr.featureGroups.get(group)==null ||\r
-              ((Boolean) fr.featureGroups.get(group)).booleanValue())\r
+        if (group == null || fr.featureGroups.get(group) == null ||\r
+            ( (Boolean) fr.featureGroups.get(group)).booleanValue())\r
+        {\r
+          type = tmpfeatures[index].getType();\r
+          if (!visibleChecks.contains(type))\r
           {\r
-            type = tmpfeatures[index].getType();\r
-            if(!visibleChecks.contains(type) )\r
-            {\r
-              visibleChecks.addElement(type);\r
-            }\r
+            visibleChecks.addElement(type);\r
           }\r
-          index++;\r
         }\r
+        index++;\r
+      }\r
     }\r
 \r
     int fSize = visibleChecks.size();\r
-    Object [][] data = new Object[fSize][3];\r
+    Object[][] data = new Object[fSize][3];\r
     int dataIndex = 0;\r
 \r
-    if(fr.renderOrder!=null)\r
+    if (fr.renderOrder != null)\r
     {\r
       //First add the checks in the previous render order,\r
       //in case the window has been closed and reopened\r
-      for(int ro=fr.renderOrder.length-1; ro>-1; ro--)\r
+      for (int ro = fr.renderOrder.length - 1; ro > -1; ro--)\r
       {\r
-           type = fr.renderOrder[ro];\r
+        type = fr.renderOrder[ro];\r
 \r
-           if(!visibleChecks.contains(type))\r
-             continue;\r
+        if (!visibleChecks.contains(type))\r
+        {\r
+          continue;\r
+        }\r
 \r
-           data[dataIndex][0] = type;\r
-           data[dataIndex][1] = fr.getColour(type);\r
-           data[dataIndex][2] = new Boolean(af.getViewport().featuresDisplayed.containsKey(type));\r
-           dataIndex++;\r
-           visibleChecks.removeElement(type);\r
+        data[dataIndex][0] = type;\r
+        data[dataIndex][1] = fr.getColour(type);\r
+        data[dataIndex][2] = new Boolean(af.getViewport().featuresDisplayed.\r
+                                         containsKey(type));\r
+        dataIndex++;\r
+        visibleChecks.removeElement(type);\r
       }\r
     }\r
 \r
     fSize = visibleChecks.size();\r
-    for(int i=0; i<fSize; i++)\r
+    for (int i = 0; i < fSize; i++)\r
     {\r
       //These must be extra features belonging to the group\r
       //which was just selected\r
@@ -252,65 +308,26 @@ public class FeatureSettings extends JPanel
       data[dataIndex][0] = type;\r
 \r
       data[dataIndex][1] = fr.getColour(type);\r
+      if (data[dataIndex][1] == null)\r
+      {\r
+        //"Colour has been updated in another view!!"\r
+        fr.renderOrder = null;\r
+        return;\r
+      }\r
+\r
       data[dataIndex][2] = new Boolean(true);\r
       dataIndex++;\r
     }\r
 \r
-    if(originalData==null)\r
+    if (originalData == null)\r
     {\r
       originalData = new Object[data.length][3];\r
-      System.arraycopy(data,0,originalData,0,data.length);\r
+      System.arraycopy(data, 0, originalData, 0, data.length);\r
     }\r
 \r
-    table = new JTable(new FeatureTableModel(data));\r
-    scrollPane.setViewportView(table);\r
-    table.getTableHeader().setFont(new Font("Verdana", Font.PLAIN, 12));\r
-    table.setFont(new Font("Verdana", Font.PLAIN, 12));\r
-    table.setDefaultRenderer(Color.class,\r
-                         new ColorRenderer());\r
-\r
-    table.setDefaultEditor(Color.class,\r
-                      new ColorEditor());\r
-\r
+    table.setModel(new FeatureTableModel(data));\r
     table.getColumnModel().getColumn(0).setPreferredWidth(200);\r
 \r
-    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);\r
-\r
-    table.addMouseListener(new MouseAdapter()\r
-        {\r
-          public void mousePressed(MouseEvent evt)\r
-          {\r
-            selectedRow = table.rowAtPoint(evt.getPoint());\r
-          }\r
-        });\r
-\r
-    table.addMouseMotionListener(new MouseMotionAdapter()\r
-        {\r
-          public void mouseDragged(MouseEvent evt)\r
-          {\r
-            int newRow = table.rowAtPoint(evt.getPoint());\r
-            if(newRow!=selectedRow\r
-               && selectedRow!=-1\r
-               && newRow!=-1)\r
-            {\r
-              Object[] temp = new Object[3];\r
-              temp[0] = table.getValueAt(selectedRow, 0);\r
-              temp[1] = table.getValueAt(selectedRow, 1);\r
-              temp[2] = table.getValueAt(selectedRow, 2);\r
-\r
-              table.setValueAt(table.getValueAt(newRow, 0), selectedRow, 0);\r
-              table.setValueAt(table.getValueAt(newRow, 1), selectedRow, 1);\r
-              table.setValueAt(table.getValueAt(newRow, 2), selectedRow, 2);\r
-\r
-              table.setValueAt(temp[0], newRow, 0);\r
-              table.setValueAt(temp[1], newRow, 1);\r
-              table.setValueAt(temp[2], newRow, 2);\r
-\r
-              selectedRow = newRow;\r
-            }\r
-          }\r
-    });\r
-\r
     if (groupPanel != null)\r
     {\r
       groupPanel.setLayout(\r
@@ -326,50 +343,56 @@ public class FeatureSettings extends JPanel
 \r
   void load()\r
   {\r
-    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
-                 "LAST_DIRECTORY"), new String[] { "fc" },\r
-             new String[] { "Sequence Feature Colours" }, "Sequence Feature Colours");\r
-     chooser.setFileView(new jalview.io.JalviewFileView());\r
-     chooser.setDialogTitle("Load Feature Colours");\r
-     chooser.setToolTipText("Load");\r
-\r
-     int value = chooser.showOpenDialog(this);\r
-\r
-     if (value == JalviewFileChooser.APPROVE_OPTION)\r
-     {\r
-       File file = chooser.getSelectedFile();\r
-\r
-       try\r
-       {\r
-         InputStreamReader in = new InputStreamReader(new FileInputStream(\r
-             file), "UTF-8");\r
-\r
-         jalview.binding.JalviewUserColours jucs = new jalview.binding.\r
-             JalviewUserColours();\r
-         jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);\r
-\r
-\r
-         for (int i = 0; i < jucs.getColourCount(); i++)\r
-         {\r
-           fr.setColour( jucs.getColour(i).getName(),\r
-                          new Color(Integer.parseInt( jucs.getColour(i).getRGB(), 16)));\r
-         }\r
-\r
-         setTableData();\r
-         af.alignPanel.repaint();\r
-       }\r
-       catch (Exception ex)\r
-       {\r
-         System.out.println("Error loading User Colour File\n" + ex);\r
-       }\r
-     }\r
+    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
+        getProperty(\r
+            "LAST_DIRECTORY"), new String[]\r
+        {"fc"},\r
+        new String[]\r
+        {"Sequence Feature Colours"}, "Sequence Feature Colours");\r
+    chooser.setFileView(new jalview.io.JalviewFileView());\r
+    chooser.setDialogTitle("Load Feature Colours");\r
+    chooser.setToolTipText("Load");\r
+\r
+    int value = chooser.showOpenDialog(this);\r
+\r
+    if (value == JalviewFileChooser.APPROVE_OPTION)\r
+    {\r
+      File file = chooser.getSelectedFile();\r
+\r
+      try\r
+      {\r
+        InputStreamReader in = new InputStreamReader(new FileInputStream(\r
+            file), "UTF-8");\r
+\r
+        jalview.binding.JalviewUserColours jucs = new jalview.binding.\r
+            JalviewUserColours();\r
+        jucs = (jalview.binding.JalviewUserColours) jucs.unmarshal(in);\r
+\r
+        for (int i = 0; i < jucs.getColourCount(); i++)\r
+        {\r
+          fr.setColour(jucs.getColour(i).getName(),\r
+                       new Color(Integer.parseInt(jucs.getColour(i).getRGB(),\r
+                                                  16)));\r
+        }\r
+\r
+        setTableData();\r
+        af.alignPanel.repaint();\r
+      }\r
+      catch (Exception ex)\r
+      {\r
+        System.out.println("Error loading User Colour File\n" + ex);\r
+      }\r
+    }\r
   }\r
 \r
   void save()\r
   {\r
-    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.getProperty(\r
-                "LAST_DIRECTORY"), new String[] { "fc" },\r
-            new String[] { "Sequence Feature Colours" }, "Sequence Feature Colours");\r
+    JalviewFileChooser chooser = new JalviewFileChooser(jalview.bin.Cache.\r
+        getProperty(\r
+            "LAST_DIRECTORY"), new String[]\r
+        {"fc"},\r
+        new String[]\r
+        {"Sequence Feature Colours"}, "Sequence Feature Colours");\r
     chooser.setFileView(new jalview.io.JalviewFileView());\r
     chooser.setDialogTitle("Save Feature Colour Scheme");\r
     chooser.setToolTipText("Save");\r
@@ -378,43 +401,44 @@ public class FeatureSettings extends JPanel
 \r
     if (value == JalviewFileChooser.APPROVE_OPTION)\r
     {\r
-        String choice = chooser.getSelectedFile().getPath();\r
-        jalview.binding.JalviewUserColours ucs = new jalview.binding.JalviewUserColours();\r
-        ucs.setSchemeName("Sequence Features");\r
-        try\r
-        {\r
-            PrintWriter out = new PrintWriter(new OutputStreamWriter(\r
-                        new FileOutputStream(choice), "UTF-8"));\r
-\r
-            Enumeration e = fr.featureColours.keys();\r
-           while(e.hasMoreElements())\r
-           {\r
-                jalview.binding.Colour col = new jalview.binding.Colour();\r
-                col.setName(e.nextElement().toString());\r
-                col.setRGB(jalview.util.Format.getHexString(\r
-                        fr.getColour(col.getName())));\r
-                ucs.addColour(col);\r
-            }\r
+      String choice = chooser.getSelectedFile().getPath();\r
+      jalview.binding.JalviewUserColours ucs = new jalview.binding.\r
+          JalviewUserColours();\r
+      ucs.setSchemeName("Sequence Features");\r
+      try\r
+      {\r
+        PrintWriter out = new PrintWriter(new OutputStreamWriter(\r
+            new FileOutputStream(choice), "UTF-8"));\r
 \r
-            ucs.marshal(out);\r
-            out.close();\r
-        }\r
-        catch (Exception ex)\r
+        Enumeration e = fr.featureColours.keys();\r
+        while (e.hasMoreElements())\r
         {\r
-            ex.printStackTrace();\r
+          jalview.binding.Colour col = new jalview.binding.Colour();\r
+          col.setName(e.nextElement().toString());\r
+          col.setRGB(jalview.util.Format.getHexString(\r
+              fr.getColour(col.getName())));\r
+          ucs.addColour(col);\r
         }\r
+\r
+        ucs.marshal(out);\r
+        out.close();\r
+      }\r
+      catch (Exception ex)\r
+      {\r
+        ex.printStackTrace();\r
+      }\r
     }\r
   }\r
 \r
   public void invertSelection()\r
   {\r
-    for(int i=0; i<table.getRowCount(); i++)\r
+    for (int i = 0; i < table.getRowCount(); i++)\r
     {\r
-      Boolean value = (Boolean)table.getValueAt(i,2);\r
+      Boolean value = (Boolean) table.getValueAt(i, 2);\r
 \r
       table.setValueAt(\r
           new Boolean(!value.booleanValue()),\r
-                       i,2);\r
+          i, 2);\r
     }\r
   }\r
 \r
@@ -429,16 +453,18 @@ public class FeatureSettings extends JPanel
 \r
   }\r
 \r
-  public void updateFeatureRenderer(Object [][] data)\r
+  public void updateFeatureRenderer(Object[][] data)\r
   {\r
-    fr.setFeaturePriority( data );\r
+    fr.setFeaturePriority(data);\r
     af.alignPanel.repaint();\r
 \r
-    if(af.alignPanel.overviewPanel!=null)\r
+    if (af.alignPanel.overviewPanel != null)\r
+    {\r
       af.alignPanel.overviewPanel.updateOverviewImage();\r
+    }\r
   }\r
 \r
-  int selectedRow =-1;\r
+  int selectedRow = -1;\r
   JTabbedPane tabbedPane = new JTabbedPane();\r
   BorderLayout borderLayout1 = new BorderLayout();\r
   BorderLayout borderLayout2 = new BorderLayout();\r
@@ -454,6 +480,7 @@ public class FeatureSettings extends JPanel
   JPanel dasButtonPanel = new JPanel();\r
   JButton fetchDAS = new JButton();\r
   JButton saveDAS = new JButton();\r
+  JButton cancelDAS = new JButton();\r
   private void jbInit()\r
       throws Exception\r
   {\r
@@ -476,8 +503,8 @@ public class FeatureSettings extends JPanel
     {\r
       public void actionPerformed(ActionEvent e)\r
       {\r
-          updateFeatureRenderer(originalData);\r
-          close();\r
+        updateFeatureRenderer(originalData);\r
+        close();\r
       }\r
     });\r
     ok.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));\r
@@ -516,7 +543,6 @@ public class FeatureSettings extends JPanel
       }\r
     });\r
 \r
-\r
     transparency.setMaximum(70);\r
     fetchDAS.setText("Fetch DAS Features");\r
     fetchDAS.addActionListener(new ActionListener()\r
@@ -536,8 +562,17 @@ public class FeatureSettings extends JPanel
     });\r
     dasButtonPanel.setBorder(BorderFactory.createEtchedBorder());\r
     dasSettingsPane.setBorder(null);\r
+    cancelDAS.setEnabled(false);\r
+    cancelDAS.setText("Cancel Fetch");\r
+    cancelDAS.addActionListener(new ActionListener()\r
+    {\r
+      public void actionPerformed(ActionEvent e)\r
+      {\r
+        cancelDAS_actionPerformed(e);\r
+      }\r
+    });\r
     this.add(tabbedPane, java.awt.BorderLayout.CENTER);\r
-    tabbedPane.addTab("Display Settings", settingsPane );\r
+    tabbedPane.addTab("Feature Settings", settingsPane);\r
     tabbedPane.addTab("DAS Settings", dasSettingsPane);\r
     bigPanel.add(transPanel, java.awt.BorderLayout.SOUTH);\r
     transPanel.add(transparency);\r
@@ -549,6 +584,7 @@ public class FeatureSettings extends JPanel
     bigPanel.add(scrollPane, java.awt.BorderLayout.CENTER);\r
     dasSettingsPane.add(dasButtonPanel, java.awt.BorderLayout.SOUTH);\r
     dasButtonPanel.add(fetchDAS);\r
+    dasButtonPanel.add(cancelDAS);\r
     dasButtonPanel.add(saveDAS);\r
     settingsPane.add(bigPanel, java.awt.BorderLayout.CENTER);\r
     settingsPane.add(buttonPanel, java.awt.BorderLayout.SOUTH);\r
@@ -556,30 +592,39 @@ public class FeatureSettings extends JPanel
 \r
   public void fetchDAS_actionPerformed(ActionEvent e)\r
   {\r
+    fetchDAS.setEnabled(false);\r
+    cancelDAS.setEnabled(true);\r
     Vector selectedSources = dassourceBrowser.getSelectedSources();\r
 \r
-    int uniprotCount = 0;\r
-    for(int i=0; i<selectedSources.size(); i++)\r
+    SequenceI[] dataset, seqs;\r
+    int iSize;\r
+\r
+    if (af.getViewport().getSelectionGroup() != null\r
+        && af.getViewport().getSelectionGroup().getSize() > 0)\r
+    {\r
+      iSize = af.getViewport().getSelectionGroup().getSize();\r
+      dataset = new SequenceI[iSize];\r
+      seqs = af.getViewport().getSelectionGroup().\r
+          getSequencesInOrder(\r
+              af.getViewport().getAlignment());\r
+    }\r
+    else\r
     {\r
-     DasSource source = (DasSource)selectedSources.elementAt(i);\r
-     DasCoordinateSystem [] coords = source.getCoordinateSystem();\r
-     for(int c=0; c<coords.length; c++)\r
-     {\r
-       if (coords[c].getName().equalsIgnoreCase("UniProt"))\r
-       {\r
-         uniprotCount++;\r
-         break;\r
-       }\r
-     }\r
+      iSize = af.getViewport().getAlignment().getHeight();\r
+      seqs = af.getViewport().getAlignment().getSequencesArray();\r
     }\r
 \r
-    System.out.println("User selection is "\r
-                       + (((float)uniprotCount/(float)selectedSources.size())*100)\r
-                       +" % Uniprot");\r
+    dataset = new SequenceI[iSize];\r
+    for (int i = 0; i < iSize; i++)\r
+    {\r
+      dataset[i] = seqs[i].getDatasetSequence();\r
+    }\r
 \r
-   new jalview.io.DasSequenceFeatureFetcher(af.getViewport().getAlignment(),\r
-                                             af,\r
-                                            selectedSources);\r
+    dasFeatureFetcher =\r
+        new jalview.io.DasSequenceFeatureFetcher(\r
+            dataset,\r
+            this,\r
+            selectedSources);\r
 \r
     af.getViewport().setShowSequenceFeatures(true);\r
     af.showSeqFeatures.setSelected(true);\r
@@ -590,6 +635,19 @@ public class FeatureSettings extends JPanel
     dassourceBrowser.saveProperties(jalview.bin.Cache.applicationProperties);\r
   }\r
 \r
+  public void complete()\r
+  {\r
+    fetchDAS.setEnabled(true);\r
+    cancelDAS.setEnabled(false);\r
+  }\r
+\r
+  public void cancelDAS_actionPerformed(ActionEvent e)\r
+  {\r
+    dasFeatureFetcher.cancel();\r
+    fetchDAS.setEnabled(true);\r
+    cancelDAS.setEnabled(false);\r
+  }\r
+\r
   /////////////////////////////////////////////////////////////////////////\r
   // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html\r
   /////////////////////////////////////////////////////////////////////////\r
@@ -601,153 +659,179 @@ public class FeatureSettings extends JPanel
       this.data = data;\r
     }\r
 \r
-    private String[] columnNames = {"Feature Type", "Colour","Display"};\r
-          private Object[][] data;\r
+    private String[] columnNames =\r
+        {\r
+        "Feature Type", "Colour", "Display"};\r
+    private Object[][] data;\r
 \r
-          public Object[][] getData()\r
-          {\r
-            return data;\r
-          }\r
+    public Object[][] getData()\r
+    {\r
+      return data;\r
+    }\r
 \r
-          public void setData(Object[][] data)\r
-          {\r
-            this.data = data;\r
-          }\r
+    public void setData(Object[][] data)\r
+    {\r
+      this.data = data;\r
+    }\r
 \r
-          public int getColumnCount() {\r
-              return columnNames.length;\r
-          }\r
+    public int getColumnCount()\r
+    {\r
+      return columnNames.length;\r
+    }\r
 \r
-          public Object[] getRow(int row)\r
-          {\r
-            return data[row];\r
-          }\r
+    public Object[] getRow(int row)\r
+    {\r
+      return data[row];\r
+    }\r
 \r
-          public int getRowCount() {\r
-              return data.length;\r
-          }\r
+    public int getRowCount()\r
+    {\r
+      return data.length;\r
+    }\r
 \r
-          public String getColumnName(int col) {\r
-              return columnNames[col];\r
-          }\r
+    public String getColumnName(int col)\r
+    {\r
+      return columnNames[col];\r
+    }\r
 \r
-          public Object getValueAt(int row, int col) {\r
-              return data[row][col];\r
-          }\r
+    public Object getValueAt(int row, int col)\r
+    {\r
+      return data[row][col];\r
+    }\r
 \r
-          public Class getColumnClass(int c) {\r
-              return getValueAt(0, c).getClass();\r
-          }\r
+    public Class getColumnClass(int c)\r
+    {\r
+      return getValueAt(0, c).getClass();\r
+    }\r
 \r
-          public boolean isCellEditable(int row, int col) {\r
-              return col==0 ? false:true;\r
-          }\r
+    public boolean isCellEditable(int row, int col)\r
+    {\r
+      return col == 0 ? false : true;\r
+    }\r
 \r
-          public void setValueAt(Object value, int row, int col) {\r
-              data[row][col] = value;\r
-              fireTableCellUpdated(row, col);\r
-              updateFeatureRenderer(data);\r
-          }\r
+    public void setValueAt(Object value, int row, int col)\r
+    {\r
+      data[row][col] = value;\r
+      fireTableCellUpdated(row, col);\r
+      updateFeatureRenderer(data);\r
+    }\r
 \r
+  }\r
+\r
+  class ColorRenderer\r
+      extends JLabel implements TableCellRenderer\r
+  {\r
+    javax.swing.border.Border unselectedBorder = null;\r
+    javax.swing.border.Border selectedBorder = null;\r
+\r
+    public ColorRenderer()\r
+    {\r
+      setOpaque(true); //MUST do this for background to show up.\r
     }\r
-    class ColorRenderer extends JLabel\r
-                              implements TableCellRenderer {\r
-       javax.swing.border.Border unselectedBorder = null;\r
-       javax.swing.border.Border selectedBorder = null;\r
-\r
-       public ColorRenderer() {\r
-           setOpaque(true); //MUST do this for background to show up.\r
-       }\r
-\r
-       public Component getTableCellRendererComponent(\r
-                               JTable table, Object color,\r
-                               boolean isSelected, boolean hasFocus,\r
-                               int row, int column) {\r
-           Color newColor = (Color)color;\r
-           setBackground(newColor);\r
-               if (isSelected) {\r
-                   if (selectedBorder == null) {\r
-                       selectedBorder = BorderFactory.createMatteBorder(2,5,2,5,\r
-                                                 table.getSelectionBackground());\r
-                   }\r
-                   setBorder(selectedBorder);\r
-               } else {\r
-                   if (unselectedBorder == null) {\r
-                       unselectedBorder = BorderFactory.createMatteBorder(2,5,2,5,\r
-                                                 table.getBackground());\r
-                   }\r
-                   setBorder(unselectedBorder);\r
-               }\r
-\r
-           setToolTipText("RGB value: " + newColor.getRed() + ", "\r
-                                        + newColor.getGreen() + ", "\r
-                                        + newColor.getBlue());\r
-           return this;\r
-       }\r
-   }\r
+\r
+    public Component getTableCellRendererComponent(\r
+        JTable table, Object color,\r
+        boolean isSelected, boolean hasFocus,\r
+        int row, int column)\r
+    {\r
+      Color newColor = (Color) color;\r
+      setBackground(newColor);\r
+      if (isSelected)\r
+      {\r
+        if (selectedBorder == null)\r
+        {\r
+          selectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5,\r
+              table.getSelectionBackground());\r
+        }\r
+        setBorder(selectedBorder);\r
+      }\r
+      else\r
+      {\r
+        if (unselectedBorder == null)\r
+        {\r
+          unselectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5,\r
+              table.getBackground());\r
+        }\r
+        setBorder(unselectedBorder);\r
+      }\r
+\r
+      setToolTipText("RGB value: " + newColor.getRed() + ", "\r
+                     + newColor.getGreen() + ", "\r
+                     + newColor.getBlue());\r
+      return this;\r
+    }\r
+  }\r
 }\r
 \r
- class ColorEditor extends AbstractCellEditor\r
-                          implements TableCellEditor,\r
-                                     ActionListener {\r
-     Color currentColor;\r
-     JButton button;\r
-     JColorChooser colorChooser;\r
-     JDialog dialog;\r
-     protected static final String EDIT = "edit";\r
-\r
-     public ColorEditor() {\r
-         //Set up the editor (from the table's point of view),\r
-         //which is a button.\r
-         //This button brings up the color chooser dialog,\r
-         //which is the editor from the user's point of view.\r
-         button = new JButton();\r
-         button.setActionCommand(EDIT);\r
-         button.addActionListener(this);\r
-         button.setBorderPainted(false);\r
-         //Set up the dialog that the button brings up.\r
-         colorChooser = new JColorChooser();\r
-         dialog = JColorChooser.createDialog(button,\r
-                                         "Select new Colour",\r
-                                         true,  //modal\r
-                                         colorChooser,\r
-                                         this,  //OK button handler\r
-                                         null); //no CANCEL button handler\r
-     }\r
-\r
-     /**\r
-      * Handles events from the editor button and from\r
-      * the dialog's OK button.\r
-      */\r
-     public void actionPerformed(ActionEvent e) {\r
-\r
-          if (EDIT.equals(e.getActionCommand())) {\r
-             //The user has clicked the cell, so\r
-             //bring up the dialog.\r
-             button.setBackground(currentColor);\r
-             colorChooser.setColor(currentColor);\r
-             dialog.setVisible(true);\r
-\r
-             //Make the renderer reappear.\r
-             fireEditingStopped();\r
-\r
-         } else { //User pressed dialog's "OK" button.\r
-             currentColor = colorChooser.getColor();\r
-         }\r
-     }\r
-\r
-     //Implement the one CellEditor method that AbstractCellEditor doesn't.\r
-     public Object getCellEditorValue() {\r
-         return currentColor;\r
-     }\r
-\r
-     //Implement the one method defined by TableCellEditor.\r
-     public Component getTableCellEditorComponent(JTable table,\r
-                                                  Object value,\r
-                                                  boolean isSelected,\r
-                                                  int row,\r
-                                                  int column) {\r
-         currentColor = (Color)value;\r
-         return button;\r
-     }\r
+class ColorEditor\r
+    extends AbstractCellEditor implements TableCellEditor,\r
+    ActionListener\r
+{\r
+  Color currentColor;\r
+  JButton button;\r
+  JColorChooser colorChooser;\r
+  JDialog dialog;\r
+  protected static final String EDIT = "edit";\r
+\r
+  public ColorEditor()\r
+  {\r
+    //Set up the editor (from the table's point of view),\r
+    //which is a button.\r
+    //This button brings up the color chooser dialog,\r
+    //which is the editor from the user's point of view.\r
+    button = new JButton();\r
+    button.setActionCommand(EDIT);\r
+    button.addActionListener(this);\r
+    button.setBorderPainted(false);\r
+    //Set up the dialog that the button brings up.\r
+    colorChooser = new JColorChooser();\r
+    dialog = JColorChooser.createDialog(button,\r
+                                        "Select new Colour",\r
+                                        true, //modal\r
+                                        colorChooser,\r
+                                        this, //OK button handler\r
+                                        null); //no CANCEL button handler\r
+  }\r
+\r
+  /**\r
+   * Handles events from the editor button and from\r
+   * the dialog's OK button.\r
+   */\r
+  public void actionPerformed(ActionEvent e)\r
+  {\r
+\r
+    if (EDIT.equals(e.getActionCommand()))\r
+    {\r
+      //The user has clicked the cell, so\r
+      //bring up the dialog.\r
+      button.setBackground(currentColor);\r
+      colorChooser.setColor(currentColor);\r
+      dialog.setVisible(true);\r
+\r
+      //Make the renderer reappear.\r
+      fireEditingStopped();\r
+\r
+    }\r
+    else\r
+    { //User pressed dialog's "OK" button.\r
+      currentColor = colorChooser.getColor();\r
+    }\r
+  }\r
+\r
+  //Implement the one CellEditor method that AbstractCellEditor doesn't.\r
+  public Object getCellEditorValue()\r
+  {\r
+    return currentColor;\r
+  }\r
+\r
+  //Implement the one method defined by TableCellEditor.\r
+  public Component getTableCellEditorComponent(JTable table,\r
+                                               Object value,\r
+                                               boolean isSelected,\r
+                                               int row,\r
+                                               int column)\r
+  {\r
+    currentColor = (Color) value;\r
+    return button;\r
+  }\r
 }\r