From 72b3f05a1157da32ada5aea139139996dddea219 Mon Sep 17 00:00:00 2001
From: "j.procter@dundee.ac.uk"
Date: Fri, 8 Aug 2014 18:11:21 +0100
Subject: [PATCH] JAL-1482 feature renderer and manipulation code refactored
to renderer and abstract model
---
src/jalview/appletgui/APopupMenu.java | 2 +-
src/jalview/appletgui/AlignFrame.java | 48 +-
src/jalview/appletgui/FeatureColourChooser.java | 18 +-
src/jalview/appletgui/FeatureRenderer.java | 859 +---------------
src/jalview/appletgui/FeatureSettings.java | 164 +--
src/jalview/appletgui/OverviewPanel.java | 4 +-
src/jalview/appletgui/SeqPanel.java | 12 +-
src/jalview/gui/AlignFrame.java | 2 +-
src/jalview/gui/AlignmentPanel.java | 2 +-
src/jalview/gui/AnnotationExporter.java | 38 +-
src/jalview/gui/FeatureColourChooser.java | 8 +-
src/jalview/gui/FeatureRenderer.java | 1088 +-------------------
src/jalview/gui/FeatureSettings.java | 218 +---
src/jalview/gui/IdPanel.java | 2 +-
src/jalview/gui/Jalview2XML.java | 62 +-
src/jalview/gui/Jalview2XML_V1.java | 12 +-
src/jalview/gui/OverviewPanel.java | 2 +-
src/jalview/gui/PopupMenu.java | 2 +-
src/jalview/gui/SeqPanel.java | 62 +-
src/jalview/io/FeaturesFile.java | 14 +-
src/jalview/io/HTMLOutput.java | 2 +-
src/jalview/io/SequenceAnnotationReport.java | 53 +-
.../renderer/seqfeatures/FeatureRenderer.java | 435 ++++++++
.../seqfeatures/FeatureRendererModel.java | 2 +-
src/jalview/ws/AWSThread.java | 2 +-
25 files changed, 700 insertions(+), 2413 deletions(-)
create mode 100644 src/jalview/renderer/seqfeatures/FeatureRenderer.java
diff --git a/src/jalview/appletgui/APopupMenu.java b/src/jalview/appletgui/APopupMenu.java
index 7a77935..51ecd88 100644
--- a/src/jalview/appletgui/APopupMenu.java
+++ b/src/jalview/appletgui/APopupMenu.java
@@ -707,7 +707,7 @@ public class APopupMenu extends java.awt.PopupMenu implements
true,
true,
false,
- (ap.seqPanel.seqCanvas.fr != null) ? ap.seqPanel.seqCanvas.fr.minmax
+ (ap.seqPanel.seqCanvas.fr != null) ? ap.seqPanel.seqCanvas.fr.getMinMax()
: null);
contents.append("
");
}
diff --git a/src/jalview/appletgui/AlignFrame.java b/src/jalview/appletgui/AlignFrame.java
index e0dad58..8d1255c 100644
--- a/src/jalview/appletgui/AlignFrame.java
+++ b/src/jalview/appletgui/AlignFrame.java
@@ -25,6 +25,7 @@ import jalview.analysis.Conservation;
import jalview.api.AlignViewControllerGuiI;
import jalview.api.AlignViewControllerI;
import jalview.api.SequenceStructureBinding;
+import jalview.api.FeatureRenderer;
import jalview.bin.JalviewLite;
import jalview.commands.CommandI;
import jalview.commands.EditCommand;
@@ -90,9 +91,12 @@ import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;
+import java.util.Arrays;
import java.util.Enumeration;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.StringTokenizer;
import java.util.Vector;
@@ -286,7 +290,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
{
featuresFile = new jalview.io.FeaturesFile(file, type)
.parse(viewport.getAlignment(), alignPanel.seqPanel.seqCanvas
- .getFeatureRenderer().featureColours, featureLinks,
+ .getFeatureRenderer().getFeatureColours(), featureLinks,
true, viewport.applet.getDefaultParameter(
"relaxedidmatch", false));
} catch (Exception ex)
@@ -305,6 +309,11 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
viewport.setShowSequenceFeatures(true);
sequenceFeatures.setState(true);
}
+ if (alignPanel.seqPanel.seqCanvas.fr != null)
+ {
+ // update the min/max ranges where necessary
+ alignPanel.seqPanel.seqCanvas.fr.findAllFeatures(true);
+ }
if (viewport.featureSettings != null)
{
viewport.featureSettings.refreshTable();
@@ -1201,20 +1210,13 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
return annotation;
}
- private Hashtable getDisplayedFeatureCols()
+ private Map getDisplayedFeatureCols()
{
if (alignPanel.getFeatureRenderer() != null
- && viewport.featuresDisplayed != null)
+ && viewport.getFeaturesDisplayed()!= null)
{
- FeatureRenderer fr = alignPanel.getFeatureRenderer();
- Hashtable fcols = new Hashtable();
- Enumeration en = viewport.featuresDisplayed.keys();
- while (en.hasMoreElements())
- {
- Object col = en.nextElement();
- fcols.put(col, fr.featureColours.get(col));
- }
- return fcols;
+ return alignPanel.getFeatureRenderer().getDisplayedFeatureCols();
+
}
return null;
}
@@ -1418,6 +1420,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
/**
* TODO: JAL-1104
*/
+ @Override
public void addHistoryItem(CommandI command)
{
if (command.getSize() > 0)
@@ -2240,7 +2243,14 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
if (alignPanel != null
&& (fr = alignPanel.getFeatureRenderer()) != null)
{
- return fr.getGroups();
+ List gps = fr.getFeatureGroups();
+ int p=0;
+ String[] _gps = new String[gps.size()];
+ for (Object gp:gps)
+ {
+ _gps[p++] = gp.toString();
+ }
+ return _gps;
}
return null;
}
@@ -2258,7 +2268,14 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
if (alignPanel != null
&& (fr = alignPanel.getFeatureRenderer()) != null)
{
- return fr.getGroups(visible);
+ List gps = fr.getGroups(visible);
+ int p=0;
+ String[] _gps = new String[gps.size()];
+ for (Object gp:gps)
+ {
+ _gps[p++] = gp.toString();
+ }
+ return _gps;
}
return null;
}
@@ -2279,7 +2296,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener,
if (alignPanel != null
&& (fr = alignPanel.getFeatureRenderer()) != null)
{
- fr.setGroupState(groups, state);
+
+ fr.setGroupVisibility((List)Arrays.asList(groups), state);
alignPanel.seqPanel.seqCanvas.repaint();
if (alignPanel.overviewPanel != null)
{
diff --git a/src/jalview/appletgui/FeatureColourChooser.java b/src/jalview/appletgui/FeatureColourChooser.java
index 32ffdbf..c87803c 100644
--- a/src/jalview/appletgui/FeatureColourChooser.java
+++ b/src/jalview/appletgui/FeatureColourChooser.java
@@ -73,10 +73,10 @@ public class FeatureColourChooser extends Panel implements ActionListener,
{
this.type = type;
fr = frenderer;
- float mm[] = ((float[][]) fr.minmax.get(type))[0];
+ float mm[] = ((float[][]) fr.getMinMax().get(type))[0];
min = mm[0];
max = mm[1];
- oldcs = fr.featureColours.get(type);
+ oldcs = fr.getFeatureColours().get(type);
if (oldcs instanceof GraduatedColor)
{
cs = new GraduatedColor((GraduatedColor) oldcs, min, max);
@@ -130,7 +130,7 @@ public class FeatureColourChooser extends Panel implements ActionListener,
{
// cancel
reset();
- PaintRefresher.Refresh(this, fr.av.getSequenceSetId());
+ PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
frame.setVisible(false);
}
}
@@ -289,7 +289,7 @@ public class FeatureColourChooser extends Panel implements ActionListener,
threshline.value = (float) slider.getValue() / 1000f;
cs.setThresh(threshline.value);
changeColour();
- PaintRefresher.Refresh(this, fr.av.getSequenceSetId());
+ PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
// ap.paintAlignment(false);
}
@@ -402,16 +402,16 @@ public class FeatureColourChooser extends Panel implements ActionListener,
}
}
- fr.featureColours.put(type, acg);
+ fr.setColour(type, acg);
cs = acg;
- PaintRefresher.Refresh(this, fr.av.getSequenceSetId());
+ PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
// ap.paintAlignment(false);
}
void reset()
{
- fr.featureColours.put(type, oldcs);
- PaintRefresher.Refresh(this, fr.av.getSequenceSetId());
+ fr.setColour(type, oldcs);
+ PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
// ap.paintAlignment(true);
}
@@ -433,7 +433,7 @@ public class FeatureColourChooser extends Panel implements ActionListener,
}
else
{
- PaintRefresher.Refresh(this, fr.av.getSequenceSetId());
+ PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
}
// ap.paintAlignment(true);
}
diff --git a/src/jalview/appletgui/FeatureRenderer.java b/src/jalview/appletgui/FeatureRenderer.java
index 14338fa..ac1f58c 100644
--- a/src/jalview/appletgui/FeatureRenderer.java
+++ b/src/jalview/appletgui/FeatureRenderer.java
@@ -21,15 +21,14 @@
package jalview.appletgui;
import java.util.*;
-
import java.awt.*;
-
import java.awt.event.*;
import jalview.datamodel.*;
import jalview.schemes.AnnotationColourGradient;
import jalview.schemes.GraduatedColor;
import jalview.util.MessageManager;
+import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
/**
* DOCUMENT ME!
@@ -37,34 +36,13 @@ import jalview.util.MessageManager;
* @author $author$
* @version $Revision$
*/
-public class FeatureRenderer implements jalview.api.FeatureRenderer
+public class FeatureRenderer extends jalview.renderer.seqfeatures.FeatureRenderer
{
- AlignViewport av;
-
- Hashtable featureColours = new Hashtable();
-
- // A higher level for grouping features of a
- // particular type
- Hashtable featureGroups = null;
// Holds web links for feature groups and feature types
// in the form label|link
Hashtable featureLinks = null;
- // This is actually an Integer held in the hashtable,
- // Retrieved using the key feature type
- Object currentColour;
-
- String[] renderOrder;
-
- FontMetrics fm;
-
- int charOffset;
-
- float transparency = 1f;
-
- TransparencySetter transparencySetter = null;
-
/**
* Creates a new FeatureRenderer object.
*
@@ -73,49 +51,10 @@ public class FeatureRenderer implements jalview.api.FeatureRenderer
*/
public FeatureRenderer(AlignViewport av)
{
+ super();
this.av = av;
- if (!System.getProperty("java.version").startsWith("1.1"))
- {
- transparencySetter = new TransparencySetter();
- }
- }
-
- public void transferSettings(jalview.api.FeatureRenderer _fr)
- {
- if (_fr instanceof FeatureRenderer)
- {
- FeatureRenderer fr = (FeatureRenderer) _fr;
- renderOrder = fr.renderOrder;
- featureGroups = fr.featureGroups;
- featureColours = fr.featureColours;
- transparency = fr.transparency;
- if (av != null && fr.av != null && fr.av != av)
- {
- if (fr.av.featuresDisplayed != null)
- {
- if (av.featuresDisplayed == null)
- {
- av.featuresDisplayed = new Hashtable();
- }
- else
- {
- av.featuresDisplayed.clear();
- }
- Enumeration en = fr.av.featuresDisplayed.keys();
- while (en.hasMoreElements())
- {
- av.featuresDisplayed.put(en.nextElement(), Boolean.TRUE);
- }
- }
- }
- }
- else
- {
- throw new Error(
- "Implementation error: cannot port feature settings from implementation of type "
- + _fr.getClass() + " to " + getClass());
- }
+ setTransparencyAvailable(!System.getProperty("java.version").startsWith("1.1"));
}
static String lastFeatureAdded;
@@ -462,6 +401,7 @@ public class FeatureRenderer implements jalview.api.FeatureRenderer
}
ffile.parseDescriptionHTML(sf, false);
+ setVisible(lastFeatureAdded); // if user edited name then make sure new type is visible
}
if (deleteFeature)
{
@@ -482,36 +422,17 @@ public class FeatureRenderer implements jalview.api.FeatureRenderer
ffile.parseDescriptionHTML(features[i], false);
}
- if (av.featuresDisplayed == null)
- {
- av.featuresDisplayed = new Hashtable();
- }
-
- if (featureGroups == null)
- {
- featureGroups = new Hashtable();
- }
-
col = colourPanel.getBackground();
// setColour(lastFeatureAdded, fcol);
if (lastFeatureGroupAdded != null)
{
- featureGroups.put(lastFeatureGroupAdded, new Boolean(true));
- }
- if (fcol instanceof Color)
- {
- setColour(lastFeatureAdded, fcol);
+ setGroupVisibility(lastFeatureGroupAdded, true);
}
- av.featuresDisplayed.put(lastFeatureAdded,
- getFeatureStyle(lastFeatureAdded));
-
- findAllFeatures();
-
- String[] tro = new String[renderOrder.length];
- tro[0] = renderOrder[renderOrder.length - 1];
- System.arraycopy(renderOrder, 0, tro, 1, renderOrder.length - 1);
- renderOrder = tro;
+ setColour(lastFeatureAdded, fcol);
+ setVisible(lastFeatureAdded);
+ findAllFeatures(false); // different to original applet behaviour ?
+ // findAllFeatures();
}
else
{
@@ -520,9 +441,9 @@ public class FeatureRenderer implements jalview.api.FeatureRenderer
}
}
// refresh the alignment and the feature settings dialog
- if (av.featureSettings != null)
+ if (((jalview.appletgui.AlignViewport) av).featureSettings != null)
{
- av.featureSettings.refreshTable();
+ ((jalview.appletgui.AlignViewport) av).featureSettings.refreshTable();
}
// findAllFeatures();
@@ -530,760 +451,4 @@ public class FeatureRenderer implements jalview.api.FeatureRenderer
return true;
}
-
- public Color findFeatureColour(Color initialCol, SequenceI seq, int i)
- {
- overview = true;
- if (!av.showSequenceFeatures)
- {
- return initialCol;
- }
-
- lastSeq = seq;
- sequenceFeatures = lastSeq.getSequenceFeatures();
- if (sequenceFeatures == null)
- {
- return initialCol;
- }
-
- sfSize = sequenceFeatures.length;
-
- if (jalview.util.Comparison.isGap(lastSeq.getCharAt(i)))
- {
- return Color.white;
- }
-
- currentColour = null;
-
- drawSequence(null, lastSeq, lastSeq.findPosition(i), -1, -1);
-
- if (currentColour == null)
- {
- return initialCol;
- }
-
- return new Color(((Integer) currentColour).intValue());
- }
-
- /**
- * This is used by the Molecule Viewer to get the accurate colour of the
- * rendered sequence
- */
- boolean overview = false;
-
- /**
- * DOCUMENT ME!
- *
- * @param g
- * DOCUMENT ME!
- * @param seq
- * DOCUMENT ME!
- * @param sg
- * DOCUMENT ME!
- * @param start
- * DOCUMENT ME!
- * @param end
- * DOCUMENT ME!
- * @param x1
- * DOCUMENT ME!
- * @param y1
- * DOCUMENT ME!
- * @param width
- * DOCUMENT ME!
- * @param height
- * DOCUMENT ME!
- */
- // String type;
- // SequenceFeature sf;
- SequenceI lastSeq;
-
- SequenceFeature[] sequenceFeatures;
-
- int sfSize, sfindex, spos, epos;
-
- synchronized public void drawSequence(Graphics g, SequenceI seq,
- int start, int end, int y1)
- {
- if (seq.getSequenceFeatures() == null
- || seq.getSequenceFeatures().length == 0)
- {
- return;
- }
-
- if (transparencySetter != null && g != null)
- {
- transparencySetter.setTransparency(g, transparency);
- }
-
- if (lastSeq == null || seq != lastSeq
- || sequenceFeatures != seq.getSequenceFeatures())
- {
- lastSeq = seq;
- sequenceFeatures = seq.getSequenceFeatures();
- sfSize = sequenceFeatures.length;
- }
-
- if (av.featuresDisplayed == null || renderOrder == null)
- {
- findAllFeatures();
- if (av.featuresDisplayed.size() < 1)
- {
- return;
- }
-
- sequenceFeatures = seq.getSequenceFeatures();
- sfSize = sequenceFeatures.length;
- }
- if (!overview)
- {
- spos = lastSeq.findPosition(start);
- epos = lastSeq.findPosition(end);
- if (g != null)
- {
- fm = g.getFontMetrics();
- }
- }
- String type;
- for (int renderIndex = 0; renderIndex < renderOrder.length; renderIndex++)
- {
- type = renderOrder[renderIndex];
- if (!av.featuresDisplayed.containsKey(type))
- {
- continue;
- }
-
- // loop through all features in sequence to find
- // current feature to render
- for (sfindex = 0; sfindex < sfSize; sfindex++)
- {
- if (!sequenceFeatures[sfindex].type.equals(type))
- {
- continue;
- }
-
- if (featureGroups != null
- && sequenceFeatures[sfindex].featureGroup != null
- && featureGroups
- .containsKey(sequenceFeatures[sfindex].featureGroup)
- && !((Boolean) featureGroups
- .get(sequenceFeatures[sfindex].featureGroup))
- .booleanValue())
- {
- continue;
- }
-
- if (!overview
- && (sequenceFeatures[sfindex].getBegin() > epos || sequenceFeatures[sfindex]
- .getEnd() < spos))
- {
- continue;
- }
-
- if (overview)
- {
- if (sequenceFeatures[sfindex].begin <= start
- && sequenceFeatures[sfindex].end >= start)
- {
- currentColour = new Integer(
- getColour(sequenceFeatures[sfindex]).getRGB());// av.featuresDisplayed
- // .get(sequenceFeatures[sfindex].type);
- }
-
- }
- else if (sequenceFeatures[sfindex].type.equals("disulfide bond"))
- {
-
- renderFeature(g, seq,
- seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
- seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
- getColour(sequenceFeatures[sfindex])
- // new Color(((Integer) av.featuresDisplayed
- // .get(sequenceFeatures[sfindex].type)).intValue())
- , start, end, y1);
- renderFeature(g, seq,
- seq.findIndex(sequenceFeatures[sfindex].end) - 1,
- seq.findIndex(sequenceFeatures[sfindex].end) - 1,
- getColour(sequenceFeatures[sfindex])
- // new Color(((Integer) av.featuresDisplayed
- // .get(sequenceFeatures[sfindex].type)).intValue())
- , start, end, y1);
-
- }
- else
- {
- if (showFeature(sequenceFeatures[sfindex]))
- {
- renderFeature(g, seq,
- seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
- seq.findIndex(sequenceFeatures[sfindex].end) - 1,
- getColour(sequenceFeatures[sfindex]), start, end, y1);
- }
- }
-
- }
- }
-
- if (transparencySetter != null && g != null)
- {
- transparencySetter.setTransparency(g, 1.0f);
- }
- }
-
- char s;
-
- int i;
-
- void renderFeature(Graphics g, SequenceI seq, int fstart, int fend,
- Color featureColour, int start, int end, int y1)
- {
-
- if (((fstart <= end) && (fend >= start)))
- {
- if (fstart < start)
- { // fix for if the feature we have starts before the sequence start,
- fstart = start; // but the feature end is still valid!!
- }
-
- if (fend >= end)
- {
- fend = end;
- }
-
- for (i = fstart; i <= fend; i++)
- {
- s = seq.getCharAt(i);
-
- if (jalview.util.Comparison.isGap(s))
- {
- continue;
- }
-
- g.setColor(featureColour);
-
- g.fillRect((i - start) * av.charWidth, y1, av.charWidth,
- av.charHeight);
-
- if (!av.validCharWidth)
- {
- continue;
- }
-
- g.setColor(Color.white);
- charOffset = (av.charWidth - fm.charWidth(s)) / 2;
- g.drawString(String.valueOf(s), charOffset
- + (av.charWidth * (i - start)), (y1 + av.charHeight)
- - av.charHeight / 5); // pady = height / 5;
-
- }
- }
- }
-
- Hashtable minmax = null;
-
- /**
- * Called when alignment in associated view has new/modified features to
- * discover and display.
- *
- */
- public void featuresAdded()
- {
- lastSeq = null;
- findAllFeatures();
- }
-
- /**
- * find all features on the alignment
- */
- void findAllFeatures()
- {
- jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme();
-
- av.featuresDisplayed = new Hashtable();
- Vector allfeatures = new Vector();
- minmax = new Hashtable();
- AlignmentI alignment = av.getAlignment();
- for (int i = 0; i < alignment.getHeight(); i++)
- {
- SequenceFeature[] features = alignment.getSequenceAt(i)
- .getSequenceFeatures();
-
- if (features == null)
- {
- continue;
- }
-
- int index = 0;
- while (index < features.length)
- {
- if (features[index].begin == 0 && features[index].end == 0)
- {
- index++;
- continue;
- }
- if (!av.featuresDisplayed.containsKey(features[index].getType()))
- {
- if (getColour(features[index].getType()) == null)
- {
- featureColours.put(features[index].getType(),
- ucs.createColourFromName(features[index].getType()));
- }
-
- av.featuresDisplayed.put(features[index].getType(), new Integer(
- getColour(features[index].getType()).getRGB()));
- allfeatures.addElement(features[index].getType());
- }
- if (features[index].score != Float.NaN)
- {
- int nonpos = features[index].getBegin() >= 1 ? 0 : 1;
- float[][] mm = (float[][]) minmax.get(features[index].getType());
- if (mm == null)
- {
- mm = new float[][]
- { null, null };
- minmax.put(features[index].getType(), mm);
- }
- if (mm[nonpos] == null)
- {
- mm[nonpos] = new float[]
- { features[index].score, features[index].score };
-
- }
- else
- {
- if (mm[nonpos][0] > features[index].score)
- {
- mm[nonpos][0] = features[index].score;
- }
- if (mm[nonpos][1] < features[index].score)
- {
- mm[nonpos][1] = features[index].score;
- }
- }
- }
-
- index++;
- }
- }
-
- renderOrder = new String[allfeatures.size()];
- Enumeration en = allfeatures.elements();
- int i = allfeatures.size() - 1;
- while (en.hasMoreElements())
- {
- renderOrder[i] = en.nextElement().toString();
- i--;
- }
- }
-
- /**
- * get a feature style object for the given type string. Creates a
- * java.awt.Color for a featureType with no existing colourscheme. TODO:
- * replace return type with object implementing standard abstract colour/style
- * interface
- *
- * @param featureType
- * @return java.awt.Color or GraduatedColor
- */
- public Object getFeatureStyle(String featureType)
- {
- Object fc = featureColours.get(featureType);
- if (fc == null)
- {
- jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme();
- Color col = ucs.createColourFromName(featureType);
- featureColours.put(featureType, fc = col);
- }
- return fc;
- }
-
- public Color getColour(String featureType)
- {
- Object fc = getFeatureStyle(featureType);
-
- if (fc instanceof Color)
- {
- return (Color) fc;
- }
- else
- {
- if (fc instanceof GraduatedColor)
- {
- return ((GraduatedColor) fc).getMaxColor();
- }
- }
- throw new Error("Implementation Error: Unrecognised render object "
- + fc.getClass() + " for features of type " + featureType);
- }
-
- /**
- *
- * @param sequenceFeature
- * @return true if feature is visible.
- */
- private boolean showFeature(SequenceFeature sequenceFeature)
- {
- Object fc = getFeatureStyle(sequenceFeature.type);
- if (fc instanceof GraduatedColor)
- {
- return ((GraduatedColor) fc).isColored(sequenceFeature);
- }
- else
- {
- return true;
- }
- }
-
- /**
- * implement graduated colouring for features with scores
- *
- * @param feature
- * @return render colour for the given feature
- */
- public Color getColour(SequenceFeature feature)
- {
- Object fc = getFeatureStyle(feature.getType());
- if (fc instanceof Color)
- {
- return (Color) fc;
- }
- else
- {
- if (fc instanceof GraduatedColor)
- {
- return ((GraduatedColor) fc).findColor(feature);
- }
- }
- throw new Error("Implementation Error: Unrecognised render object "
- + fc.getClass() + " for features of type " + feature.getType());
- }
-
- public void setColour(String featureType, Object col)
- {
- // overwrite
- // Color _col = (col instanceof Color) ? ((Color) col) : (col instanceof
- // GraduatedColor) ? ((GraduatedColor) col).getMaxColor() : null;
- // Object c = featureColours.get(featureType);
- // if (c == null || c instanceof Color || (c instanceof GraduatedColor &&
- // !((GraduatedColor)c).getMaxColor().equals(_col)))
- {
- featureColours.put(featureType, col);
- }
- }
-
- public void setFeaturePriority(Object[][] data)
- {
- // The feature table will display high priority
- // features at the top, but theses are the ones
- // we need to render last, so invert the data
- if (av.featuresDisplayed != null)
- {
- av.featuresDisplayed.clear();
- }
-
- /*
- * if (visibleNew) { if (av.featuresDisplayed != null) {
- * av.featuresDisplayed.clear(); } else { av.featuresDisplayed = new
- * Hashtable(); } } if (data == null) { return; }
- */
-
- renderOrder = new String[data.length];
-
- if (data.length > 0)
- {
- for (int i = 0; i < data.length; i++)
- {
- String type = data[i][0].toString();
- setColour(type, data[i][1]);
- if (((Boolean) data[i][2]).booleanValue())
- {
- av.featuresDisplayed.put(type, new Integer(getColour(type)
- .getRGB()));
- }
-
- renderOrder[data.length - i - 1] = type;
- }
- }
- }
-
- /**
- * @return a simple list of feature group names or null
- */
- public String[] getGroups()
- {
- buildGroupHash();
- if (featureGroups != null)
- {
- String[] gps = new String[featureGroups.size()];
- Enumeration gn = featureGroups.keys();
- int i = 0;
- while (gn.hasMoreElements())
- {
- gps[i++] = (String) gn.nextElement();
- }
- return gps;
- }
- return null;
- }
-
- /**
- * get visible or invisible groups
- *
- * @param visible
- * true to return visible groups, false to return hidden ones.
- * @return list of groups
- */
- public String[] getGroups(boolean visible)
- {
- buildGroupHash();
- if (featureGroups != null)
- {
- Vector gp = new Vector();
-
- Enumeration gn = featureGroups.keys();
- while (gn.hasMoreElements())
- {
- String nm = (String) gn.nextElement();
- Boolean state = (Boolean) featureGroups.get(nm);
- if (state.booleanValue() == visible)
- {
- gp.addElement(nm);
- }
- }
- String[] gps = new String[gp.size()];
- gp.copyInto(gps);
-
- int i = 0;
- while (gn.hasMoreElements())
- {
- gps[i++] = (String) gn.nextElement();
- }
- return gps;
- }
- return null;
- }
-
- /**
- * set all feature groups in toset to be visible or invisible
- *
- * @param toset
- * group names
- * @param visible
- * the state of the named groups to set
- */
- public void setGroupState(String[] toset, boolean visible)
- {
- buildGroupHash();
- if (toset != null && toset.length > 0 && featureGroups != null)
- {
- boolean rdrw = false;
- for (int i = 0; i < toset.length; i++)
- {
- Object st = featureGroups.get(toset[i]);
- featureGroups.put(toset[i], new Boolean(visible));
- if (st != null)
- {
- rdrw = rdrw || (visible != ((Boolean) st).booleanValue());
- }
- }
- if (rdrw)
- {
- if (this.av != null)
- if (this.av.featureSettings != null)
- {
- av.featureSettings.rebuildGroups();
- this.av.featureSettings.resetTable(true);
- }
- else
- {
- buildFeatureHash();
- }
- if (av != null)
- {
- av.alignmentChanged(null);
- }
- }
- }
- }
-
- ArrayList hiddenGroups = new ArrayList();
-
- /**
- * analyse alignment for groups and hash tables (used to be embedded in
- * FeatureSettings.setTableData)
- *
- * @return true if features are on the alignment
- */
- public boolean buildGroupHash()
- {
- boolean alignmentHasFeatures = false;
- if (featureGroups == null)
- {
- featureGroups = new Hashtable();
- }
- hiddenGroups = new ArrayList();
- hiddenGroups.addAll(featureGroups.keySet());
- ArrayList allFeatures = new ArrayList();
- ArrayList allGroups = new ArrayList();
- SequenceFeature[] tmpfeatures;
- String group;
- AlignmentI alignment = av.getAlignment();
- for (int i = 0; i < alignment.getHeight(); i++)
- {
- if (alignment.getSequenceAt(i).getSequenceFeatures() == null)
- {
- continue;
- }
-
- alignmentHasFeatures = true;
-
- tmpfeatures = alignment.getSequenceAt(i).getSequenceFeatures();
- int index = 0;
- while (index < tmpfeatures.length)
- {
- if (tmpfeatures[index].getFeatureGroup() != null)
- {
- group = tmpfeatures[index].featureGroup;
- // Remove group from the hiddenGroup list
- hiddenGroups.remove(group);
- if (!allGroups.contains(group))
- {
- allGroups.add(group);
-
- boolean visible = true;
- if (featureGroups.containsKey(group))
- {
- visible = ((Boolean) featureGroups.get(group)).booleanValue();
- }
- else
- {
- featureGroups.put(group, new Boolean(visible));
- }
- }
- }
-
- if (!allFeatures.contains(tmpfeatures[index].getType()))
- {
- allFeatures.add(tmpfeatures[index].getType());
- }
- index++;
- }
- }
-
- return alignmentHasFeatures;
- }
-
- /**
- * rebuild the featuresDisplayed and renderorder list based on the
- * featureGroups hash and any existing display state and force a repaint if
- * necessary
- *
- * @return true if alignment has visible features
- */
- public boolean buildFeatureHash()
- {
- boolean alignmentHasFeatures = false;
- if (featureGroups == null)
- {
- alignmentHasFeatures = buildGroupHash();
- }
- if (!alignmentHasFeatures)
- return false;
- Hashtable fdisp = av.featuresDisplayed;
- Vector allFeatures = new Vector();
- SequenceFeature[] tmpfeatures;
- String group;
- AlignmentI alignment = av.getAlignment();
- for (int i = 0; i < alignment.getHeight(); i++)
- {
- if (alignment.getSequenceAt(i).getSequenceFeatures() == null)
- {
- continue;
- }
-
- alignmentHasFeatures = true;
-
- tmpfeatures = alignment.getSequenceAt(i).getSequenceFeatures();
- int index = 0;
- while (index < tmpfeatures.length)
- {
- boolean visible = true;
- if (tmpfeatures[index].getFeatureGroup() != null)
- {
- group = tmpfeatures[index].featureGroup;
- if (featureGroups.containsKey(group))
- {
- visible = ((Boolean) featureGroups.get(group)).booleanValue();
- }
- }
-
- if (visible && !allFeatures.contains(tmpfeatures[index].getType()))
- {
- allFeatures.addElement(tmpfeatures[index].getType());
- }
- index++;
- }
- }
- if (allFeatures.size() > 0)
- {
- String[] neworder = new String[allFeatures.size()];
- int p = neworder.length - 1;
- for (int i = renderOrder.length - 1; i >= 0; i--)
- {
- if (allFeatures.contains(renderOrder[i]))
- {
- neworder[p--] = renderOrder[i];
- allFeatures.removeElement(renderOrder[i]);
- }
- else
- {
- av.featuresDisplayed.remove(renderOrder[i]);
- }
- }
- for (int i = allFeatures.size() - 1; i > 0; i++)
- {
- Object e = allFeatures.elementAt(i);
- if (e != null)
- {
- neworder[p--] = (String) e;
- av.featuresDisplayed.put(e, getColour((String) e));
- }
- }
- renderOrder = neworder;
- return true;
- }
-
- return alignmentHasFeatures;
- }
-
- /**
- *
- * @return the displayed feature type as an array of strings
- */
- protected String[] getDisplayedFeatureTypes()
- {
- String[] typ = null;
- synchronized (renderOrder)
- {
- typ = new String[renderOrder.length];
- System.arraycopy(renderOrder, 0, typ, 0, typ.length);
- for (int i = 0; i < typ.length; i++)
- {
- if (av.featuresDisplayed.get(typ[i]) == null)
- {
- typ[i] = null;
- }
- }
- }
- return typ;
- }
-}
-
-class TransparencySetter
-{
- void setTransparency(Graphics g, float value)
- {
- Graphics2D g2 = (Graphics2D) g;
- g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
- value));
- }
}
diff --git a/src/jalview/appletgui/FeatureSettings.java b/src/jalview/appletgui/FeatureSettings.java
index f6e7772..bde68cc 100755
--- a/src/jalview/appletgui/FeatureSettings.java
+++ b/src/jalview/appletgui/FeatureSettings.java
@@ -21,7 +21,7 @@
package jalview.appletgui;
import java.util.*;
-
+import java.util.List;
import java.awt.*;
import java.awt.event.*;
@@ -50,8 +50,6 @@ public class FeatureSettings extends Panel implements ItemListener,
ScrollPane scrollPane;
- boolean alignmentHasFeatures = false;
-
Image linkImage;
Scrollbar transparency;
@@ -64,9 +62,9 @@ public class FeatureSettings extends Panel implements ItemListener,
fr = ap.seqPanel.seqCanvas.getFeatureRenderer();
transparency = new Scrollbar(Scrollbar.HORIZONTAL,
- 100 - (int) (fr.transparency * 100), 1, 1, 100);
+ 100 - (int) (fr.getTransparency() * 100), 1, 1, 100);
- if (fr.transparencySetter != null)
+ if (fr.isTransparencyAvailable())
{
transparency.addAdjustmentListener(this);
}
@@ -81,9 +79,9 @@ public class FeatureSettings extends Panel implements ItemListener,
linkImage = java.awt.Toolkit.getDefaultToolkit().getImage(url);
}
- if (av.featuresDisplayed == null)
+ if (av.isShowSequenceFeatures() || !fr.hasRenderOrder())
{
- fr.findAllFeatures();
+ fr.findAllFeatures(true); // was default - now true to make all visible
}
setTableData();
@@ -91,7 +89,7 @@ public class FeatureSettings extends Panel implements ItemListener,
this.setLayout(new BorderLayout());
scrollPane = new ScrollPane();
scrollPane.add(featurePanel);
- if (alignmentHasFeatures)
+ if (fr.getAllFeatureColours()!=null && fr.getAllFeatureColours().size()>0)
{
add(scrollPane, BorderLayout.CENTER);
}
@@ -104,7 +102,7 @@ public class FeatureSettings extends Panel implements ItemListener,
Panel tPanel = new Panel(new BorderLayout());
- if (fr.transparencySetter != null)
+ if (fr.isTransparencyAvailable())
{
tPanel.add(transparency, BorderLayout.CENTER);
tPanel.add(new Label("Transparency"), BorderLayout.EAST);
@@ -124,8 +122,8 @@ public class FeatureSettings extends Panel implements ItemListener,
{
groupPanel
.setLayout(new GridLayout(
- (fr.featureGroups.size() - fr.hiddenGroups.size()) / 4 + 1,
- 4));
+ (fr.getFeatureGroupsSize()) / 4 + 1,
+ 4)); // JBPNote - this was scaled on number of visible groups. seems broken
groupPanel.validate();
add(groupPanel, BorderLayout.NORTH);
@@ -185,7 +183,7 @@ public class FeatureSettings extends Panel implements ItemListener,
public void actionPerformed(ActionEvent e)
{
- me.sortByScore(new String[]
+ me.ap.alignFrame.avc.sortAlignmentByFeatureScore(new String[]
{ type });
}
@@ -197,7 +195,7 @@ public class FeatureSettings extends Panel implements ItemListener,
public void actionPerformed(ActionEvent e)
{
- me.sortByDens(new String[]
+ me.ap.alignFrame.avc.sortAlignmentByFeatureDensity(new String[]
{ type });
}
@@ -253,8 +251,7 @@ public class FeatureSettings extends Panel implements ItemListener,
public void setTableData()
{
- alignmentHasFeatures = fr.buildGroupHash();
- if (alignmentHasFeatures)
+ if (fr.getAllFeatureColours()!=null && fr.getAllFeatureColours().size()>0)
{
rebuildGroups();
@@ -279,18 +276,17 @@ public class FeatureSettings extends Panel implements ItemListener,
}
// TODO: JAL-964 - smoothly incorporate new group entries if panel already
// displayed and new groups present
- Enumeration gps = fr.featureGroups.keys();
- while (gps.hasMoreElements())
+ for (String group:(List)fr.getFeatureGroups())
{
- String group = (String) gps.nextElement();
- Boolean vis = (Boolean) fr.featureGroups.get(group);
- Checkbox check = new MyCheckbox(group, vis.booleanValue(),
+ boolean vis = fr.checkGroupVisibility(group, false);
+ Checkbox check = new MyCheckbox(group, vis,
(fr.featureLinks != null && fr.featureLinks
.containsKey(group)));
check.addMouseListener(this);
check.setFont(new Font("Serif", Font.BOLD, 12));
- check.addItemListener(this);
- check.setVisible(fr.hiddenGroups.contains(group));
+ check.addItemListener(groupItemListener);
+ // note - visibility seems to correlate with displayed. ???wtf ??
+ check.setVisible(vis);
groupPanel.add(check);
}
if (rdrw)
@@ -298,7 +294,6 @@ public class FeatureSettings extends Panel implements ItemListener,
groupPanel.validate();
}
}
-
// This routine adds and removes checkboxes depending on
// Group selection states
void resetTable(boolean groupsChanged)
@@ -320,8 +315,7 @@ public class FeatureSettings extends Panel implements ItemListener,
{
group = tmpfeatures[index].featureGroup;
- if (group == null || fr.featureGroups.get(group) == null
- || ((Boolean) fr.featureGroups.get(group)).booleanValue())
+ if (group == null || fr.checkGroupVisibility(group, true))
{
type = tmpfeatures[index].getType();
if (!visibleChecks.contains(type))
@@ -350,13 +344,14 @@ public class FeatureSettings extends Panel implements ItemListener,
}
}
- if (fr.renderOrder != null)
+ if (fr.getRenderOrder() != null)
{
// First add the checks in the previous render order,
// in case the window has been closed and reopened
- for (int ro = fr.renderOrder.length - 1; ro > -1; ro--)
+ List rol = fr.getRenderOrder();
+ for (int ro = rol.size() - 1; ro > -1; ro--)
{
- String item = fr.renderOrder[ro];
+ String item = rol.get(ro);
if (!visibleChecks.contains(item))
{
@@ -418,7 +413,7 @@ public class FeatureSettings extends Panel implements ItemListener,
if (addCheck)
{
boolean selected = false;
- if (groupsChanged || av.featuresDisplayed.containsKey(type))
+ if (groupsChanged || av.getFeaturesDisplayed().isVisible(type))
{
selected = true;
}
@@ -455,26 +450,22 @@ public class FeatureSettings extends Panel implements ItemListener,
selectionChanged();
}
- public void itemStateChanged(ItemEvent evt)
- {
- if (evt != null)
- {
- // Is the source a top level featureGroup?
+ private ItemListener groupItemListener = new ItemListener() {
+ public void itemStateChanged(ItemEvent evt) {
Checkbox source = (Checkbox) evt.getSource();
- if (fr.featureGroups.containsKey(source.getLabel()))
+ fr.setGroupVisibility(source.getLabel(),
+ source.getState());
+ ap.seqPanel.seqCanvas.repaint();
+ if (ap.overviewPanel != null)
{
- fr.featureGroups.put(source.getLabel(),
- new Boolean(source.getState()));
- ap.seqPanel.seqCanvas.repaint();
- if (ap.overviewPanel != null)
- {
- ap.overviewPanel.updateOverviewImage();
- }
-
- resetTable(true);
- return;
+ ap.overviewPanel.updateOverviewImage();
}
- }
+ resetTable(true);
+ return;
+ };
+ };
+ public void itemStateChanged(ItemEvent evt)
+ {
selectionChanged();
}
@@ -618,7 +609,7 @@ public class FeatureSettings extends Panel implements ItemListener,
MyCheckbox check = (MyCheckbox) evt.getSource();
if ((evt.getModifiers() & InputEvent.BUTTON3_MASK) != 0)
{
- this.popupSort(check, fr.minmax, evt.getX(), evt.getY());
+ this.popupSort(check, fr.getMinMax(), evt.getX(), evt.getY());
}
if (fr.featureLinks != null && fr.featureLinks.containsKey(check.type))
{
@@ -658,7 +649,7 @@ public class FeatureSettings extends Panel implements ItemListener,
public void adjustmentValueChanged(AdjustmentEvent evt)
{
- fr.transparency = ((float) (100 - transparency.getValue()) / 100f);
+ fr.setTransparency((float) (100 - transparency.getValue()) / 100f);
ap.seqPanel.seqCanvas.repaint();
}
@@ -772,81 +763,4 @@ public class FeatureSettings extends Panel implements ItemListener,
}
}
- protected void sortByDens(String[] typ)
- {
- sortBy(typ, "Sort by Density", AlignmentSorter.FEATURE_DENSITY);
- }
-
- private String[] getDisplayedFeatureTypes()
- {
- String[] typ = null;
- if (fr != null)
- {
- synchronized (fr.renderOrder)
- {
- typ = new String[fr.renderOrder.length];
- System.arraycopy(fr.renderOrder, 0, typ, 0, typ.length);
- for (int i = 0; i < typ.length; i++)
- {
- if (av.featuresDisplayed.get(typ[i]) == null)
- {
- typ[i] = null;
- }
- }
- }
- }
- return typ;
- }
-
- protected void sortBy(String[] typ, String methodText, final String method)
- {
- if (typ == null)
- {
- typ = getDisplayedFeatureTypes();
- }
- String gps[] = null;
- gps = fr.getGroups(true);
- if (typ != null)
- {
- for (int i = 0; i < typ.length; i++)
- {
- System.err.println("Sorting on Types:" + typ[i]);
- }
- }
- if (gps != null)
- {
-
- for (int i = 0; i < gps.length; i++)
- {
- System.err.println("Sorting on groups:" + gps[i]);
- }
- }
- AlignmentPanel alignPanel = ap;
- AlignmentI al = alignPanel.av.getAlignment();
-
- int start, stop;
- SequenceGroup sg = alignPanel.av.getSelectionGroup();
- if (sg != null)
- {
- start = sg.getStartRes();
- stop = sg.getEndRes();
- }
- else
- {
- start = 0;
- stop = al.getWidth();
- }
- SequenceI[] oldOrder = al.getSequencesArray();
- AlignmentSorter.sortByFeature(typ, gps, start, stop, al, method);
- this.ap.alignFrame.addHistoryItem(new OrderCommand(methodText,
- oldOrder, alignPanel.av.getAlignment()));
- alignPanel.paintAlignment(true);
-
- }
-
- protected void sortByScore(String[] typ)
- {
- sortBy(typ, "Sort by Feature Score", AlignmentSorter.FEATURE_SCORE);
- }
-
}
diff --git a/src/jalview/appletgui/OverviewPanel.java b/src/jalview/appletgui/OverviewPanel.java
index e646051..8486fe0 100755
--- a/src/jalview/appletgui/OverviewPanel.java
+++ b/src/jalview/appletgui/OverviewPanel.java
@@ -69,7 +69,6 @@ public class OverviewPanel extends Panel implements Runnable,
sr.renderGaps = false;
sr.forOverview = true;
fr = new FeatureRenderer(av);
- fr.overview = true;
// scale the initial size of overviewpanel to shape of alignment
float initialScale = (float) av.getAlignment().getWidth()
@@ -231,8 +230,7 @@ public class OverviewPanel extends Panel implements Runnable,
if (av.isShowSequenceFeatures())
{
- fr.featureGroups = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups;
- fr.featureColours = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours;
+ fr.transferSettings(ap.seqPanel.seqCanvas.fr);
}
resizing = true;
diff --git a/src/jalview/appletgui/SeqPanel.java b/src/jalview/appletgui/SeqPanel.java
index 5ba22b6..baf27f1 100644
--- a/src/jalview/appletgui/SeqPanel.java
+++ b/src/jalview/appletgui/SeqPanel.java
@@ -800,19 +800,17 @@ public class SeqPanel extends Panel implements MouseMotionListener,
{
for (int i = 0; i < features.length; i++)
{
- if (av.featuresDisplayed == null
- || !av.featuresDisplayed.containsKey(features[i].getType()))
+ if (av.getFeaturesDisplayed() == null
+ || !av.getFeaturesDisplayed().isVisible(features[i].getType()))
{
continue;
}
if (features[i].featureGroup != null
- && seqCanvas.fr.featureGroups != null
- && seqCanvas.fr.featureGroups
- .containsKey(features[i].featureGroup)
- && !((Boolean) seqCanvas.fr.featureGroups
- .get(features[i].featureGroup)).booleanValue())
+ && !seqCanvas.fr.checkGroupVisibility(features[i].featureGroup,false))
+ {
continue;
+ }
if ((features[i].getBegin() <= res)
&& (features[i].getEnd() >= res))
diff --git a/src/jalview/gui/AlignFrame.java b/src/jalview/gui/AlignFrame.java
index b958f90..f364f74 100644
--- a/src/jalview/gui/AlignFrame.java
+++ b/src/jalview/gui/AlignFrame.java
@@ -4786,7 +4786,7 @@ public class AlignFrame extends GAlignFrame implements DropTargetListener,
{
featuresFile = new FeaturesFile(file, type).parse(viewport
.getAlignment().getDataset(), alignPanel.seqPanel.seqCanvas
- .getFeatureRenderer().featureColours, false,
+ .getFeatureRenderer().getFeatureColours(), false,
jalview.bin.Cache.getDefault("RELAXEDSEQIDMATCHING", false));
} catch (Exception ex)
{
diff --git a/src/jalview/gui/AlignmentPanel.java b/src/jalview/gui/AlignmentPanel.java
index 8c18a15..1bc4ba7 100644
--- a/src/jalview/gui/AlignmentPanel.java
+++ b/src/jalview/gui/AlignmentPanel.java
@@ -1519,7 +1519,7 @@ public class AlignmentPanel extends GAlignmentPanel implements
{
return seqPanel.seqCanvas.getFeatureRenderer();
}
- public void updateFeatureRenderer(FeatureRenderer fr)
+ public void updateFeatureRenderer(jalview.renderer.seqfeatures.FeatureRenderer fr)
{
fr.transferSettings(seqPanel.seqCanvas.getFeatureRenderer());
}
diff --git a/src/jalview/gui/AnnotationExporter.java b/src/jalview/gui/AnnotationExporter.java
index 0975d24..61c5ee1 100644
--- a/src/jalview/gui/AnnotationExporter.java
+++ b/src/jalview/gui/AnnotationExporter.java
@@ -112,14 +112,16 @@ public class AnnotationExporter extends JPanel
if (GFFFormat.isSelected())
{
text = new FeaturesFile().printGFFFormat(ap.av.getAlignment()
- .getDataset().getSequencesArray(),
- getDisplayedFeatureCols(), true, ap.av.isShowNpFeats());// ap.av.featuresDisplayed//);
+ .getDataset().getSequencesArray(), ap
+ .getFeatureRenderer().getDisplayedFeatureCols(), true,
+ ap.av.isShowNpFeats());// ap.av.featuresDisplayed//);
}
else
{
text = new FeaturesFile().printJalviewFormat(ap.av.getAlignment()
- .getDataset().getSequencesArray(),
- getDisplayedFeatureCols(), true, ap.av.isShowNpFeats()); // ap.av.featuresDisplayed);
+ .getDataset().getSequencesArray(), ap
+ .getFeatureRenderer().getDisplayedFeatureCols(), true,
+ ap.av.isShowNpFeats()); // ap.av.featuresDisplayed);
}
}
else
@@ -159,14 +161,14 @@ public class AnnotationExporter extends JPanel
if (GFFFormat.isSelected())
{
text = new FeaturesFile().printGFFFormat(ap.av.getAlignment()
- .getDataset().getSequencesArray(),
- getDisplayedFeatureCols(), true, ap.av.isShowNpFeats());
+ .getDataset().getSequencesArray(), ap.getFeatureRenderer()
+ .getDisplayedFeatureCols(), true, ap.av.isShowNpFeats());
}
else
{
text = new FeaturesFile().printJalviewFormat(ap.av.getAlignment()
- .getDataset().getSequencesArray(),
- getDisplayedFeatureCols(), true, ap.av.isShowNpFeats());
+ .getDataset().getSequencesArray(), ap.getFeatureRenderer()
+ .getDisplayedFeatureCols(), true, ap.av.isShowNpFeats());
}
}
else if (!features)
@@ -207,26 +209,6 @@ public class AnnotationExporter extends JPanel
close_actionPerformed(null);
}
- private Hashtable getDisplayedFeatureCols()
- {
- Hashtable fcols = new Hashtable();
- if (ap.av.featuresDisplayed == null)
- {
- return fcols;
- }
- Enumeration en = ap.av.featuresDisplayed.keys();
- FeatureRenderer fr = ap.seqPanel.seqCanvas.getFeatureRenderer(); // consider
- // higher
- // level
- // method ?
- while (en.hasMoreElements())
- {
- Object col = en.nextElement();
- fcols.put(col, fr.featureColours.get(col));
- }
- return fcols;
- }
-
public void close_actionPerformed(ActionEvent e)
{
try
diff --git a/src/jalview/gui/FeatureColourChooser.java b/src/jalview/gui/FeatureColourChooser.java
index 8ab7c85..d1d1b6d 100644
--- a/src/jalview/gui/FeatureColourChooser.java
+++ b/src/jalview/gui/FeatureColourChooser.java
@@ -109,10 +109,10 @@ public class FeatureColourChooser extends JalviewDialog
}
});
- float mm[] = ((float[][]) fr.minmax.get(type))[0];
+ float mm[] = ((float[][]) fr.getMinMax().get(type))[0];
min = mm[0];
max = mm[1];
- oldcs = fr.featureColours.get(type);
+ oldcs = fr.getFeatureColours().get(type);
if (oldcs instanceof GraduatedColor)
{
if (((GraduatedColor) oldcs).isAutoScale())
@@ -470,7 +470,7 @@ public class FeatureColourChooser extends JalviewDialog
maxColour.setForeground(oldmaxColour);
minColour.setForeground(oldminColour);
}
- fr.featureColours.put(type, acg);
+ fr.setColour(type, acg);
cs = acg;
ap.paintAlignment(false);
}
@@ -495,7 +495,7 @@ public class FeatureColourChooser extends JalviewDialog
void reset()
{
- fr.featureColours.put(type, oldcs);
+ fr.setColour(type, oldcs);
ap.paintAlignment(false);
cs = null;
}
diff --git a/src/jalview/gui/FeatureRenderer.java b/src/jalview/gui/FeatureRenderer.java
index d36105a..ccb8ad1 100644
--- a/src/jalview/gui/FeatureRenderer.java
+++ b/src/jalview/gui/FeatureRenderer.java
@@ -21,13 +21,10 @@
package jalview.gui;
import java.util.*;
-import java.util.concurrent.ConcurrentHashMap;
-
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
import javax.swing.*;
@@ -41,38 +38,11 @@ import jalview.util.MessageManager;
* @author $author$
* @version $Revision$
*/
-public class FeatureRenderer extends jalview.viewmodel.FeatureRenderer implements jalview.api.FeatureRenderer
+public class FeatureRenderer extends jalview.renderer.seqfeatures.FeatureRenderer implements jalview.api.FeatureRenderer
{
- AlignmentPanel ap;
-
- AlignViewport av;
-
Color resBoxColour;
- /**
- * global transparency for feature
- */
- float transparency = 1.0f;
-
- FontMetrics fm;
-
- int charOffset;
-
- Map featureColours = new ConcurrentHashMap();
-
- // A higher level for grouping features of a
- // particular type
- Map featureGroups = new ConcurrentHashMap();
-
- // This is actually an Integer held in the hashtable,
- // Retrieved using the key feature type
- Object currentColour;
-
- String[] renderOrder;
-
- PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
-
- Vector allfeatures;
+ AlignmentPanel ap;
/**
* Creates a new FeatureRenderer object.
@@ -82,6 +52,7 @@ public class FeatureRenderer extends jalview.viewmodel.FeatureRenderer implement
*/
public FeatureRenderer(AlignmentPanel ap)
{
+ super();
this.ap = ap;
this.av = ap.av;
if (ap != null && ap.seqPanel != null && ap.seqPanel.seqCanvas != null
@@ -91,898 +62,6 @@ public class FeatureRenderer extends jalview.viewmodel.FeatureRenderer implement
}
}
- public class FeatureRendererSettings implements Cloneable
- {
- String[] renderOrder;
-
- Map featureGroups;
-
- Map featureColours;
-
- float transparency;
-
- Map featureOrder;
-
- public FeatureRendererSettings(String[] renderOrder,
- Hashtable featureGroups, Hashtable featureColours,
- float transparency, Hashtable featureOrder)
- {
- super();
- this.renderOrder = renderOrder;
- this.featureGroups = featureGroups;
- this.featureColours = featureColours;
- this.transparency = transparency;
- this.featureOrder = featureOrder;
- }
-
- /**
- * create an independent instance of the feature renderer settings
- *
- * @param fr
- */
- public FeatureRendererSettings(FeatureRenderer fr)
- {
- renderOrder = null;
- featureGroups = new ConcurrentHashMap();
- featureColours = new ConcurrentHashMap();
- featureOrder = new ConcurrentHashMap();
- if (fr.renderOrder != null)
- {
- this.renderOrder = new String[fr.renderOrder.length];
- System.arraycopy(fr.renderOrder, 0, renderOrder, 0,
- fr.renderOrder.length);
- }
- if (fr.featureGroups != null)
- {
- this.featureGroups = new ConcurrentHashMap(fr.featureGroups);
- }
- if (fr.featureColours != null)
- {
- this.featureColours = new ConcurrentHashMap(fr.featureColours);
- }
- Iterator en = fr.featureColours.keySet().iterator();
- while (en.hasNext())
- {
- Object next = en.next();
- Object val = featureColours.get(next);
- if (val instanceof GraduatedColor)
- {
- featureColours
- .put(next, new GraduatedColor((GraduatedColor) val));
- }
- }
- this.transparency = fr.transparency;
- if (fr.featureOrder != null)
- {
- this.featureOrder = new ConcurrentHashMap(fr.featureOrder);
- }
- }
- }
-
- public FeatureRendererSettings getSettings()
- {
- return new FeatureRendererSettings(this);
- }
-
- public void transferSettings(FeatureRendererSettings fr)
- {
- this.renderOrder = fr.renderOrder;
- this.featureGroups = fr.featureGroups;
- this.featureColours = fr.featureColours;
- this.transparency = fr.transparency;
- this.featureOrder = fr.featureOrder;
- }
-
- /**
- * update from another feature renderer
- *
- * @param fr
- * settings to copy
- */
- public void transferSettings(jalview.api.FeatureRenderer _fr)
- {
- FeatureRenderer fr = (FeatureRenderer) _fr;
- FeatureRendererSettings frs = new FeatureRendererSettings(fr);
- this.renderOrder = frs.renderOrder;
- this.featureGroups = frs.featureGroups;
- this.featureColours = frs.featureColours;
- this.transparency = frs.transparency;
- this.featureOrder = frs.featureOrder;
- if (av != null && av != fr.av)
- {
- // copy over the displayed feature settings
- if (fr.av != null)
- {
- if (fr.av.featuresDisplayed != null)
- {
- // update display settings
- if (av.featuresDisplayed == null)
- {
- av.featuresDisplayed = new Hashtable(fr.av.featuresDisplayed);
- }
- else
- {
- av.featuresDisplayed.clear();
- Enumeration en = fr.av.featuresDisplayed.keys();
- while (en.hasMoreElements())
- {
- av.featuresDisplayed.put(en.nextElement(), Boolean.TRUE);
- }
-
- }
- }
- }
- }
- }
-
- BufferedImage offscreenImage;
-
- boolean offscreenRender = false;
-
- public Color findFeatureColour(Color initialCol, SequenceI seq, int res)
- {
- return new Color(findFeatureColour(initialCol.getRGB(), seq, res));
- }
-
- /**
- * This is used by the Molecule Viewer and Overview to get the accurate
- * colourof the rendered sequence
- */
- public synchronized int findFeatureColour(int initialCol, SequenceI seq,
- int column)
- {
- if (!av.showSequenceFeatures)
- {
- return initialCol;
- }
-
- if (seq != lastSeq)
- {
- lastSeq = seq;
- sequenceFeatures = lastSeq.getDatasetSequence().getSequenceFeatures();
- if (sequenceFeatures != null)
- {
- sfSize = sequenceFeatures.length;
- }
- }
-
- if (sequenceFeatures != lastSeq.getDatasetSequence()
- .getSequenceFeatures())
- {
- sequenceFeatures = lastSeq.getDatasetSequence().getSequenceFeatures();
- if (sequenceFeatures != null)
- {
- sfSize = sequenceFeatures.length;
- }
- }
-
- if (sequenceFeatures == null || sfSize == 0)
- {
- return initialCol;
- }
-
- if (jalview.util.Comparison.isGap(lastSeq.getCharAt(column)))
- {
- return Color.white.getRGB();
- }
-
- // Only bother making an offscreen image if transparency is applied
- if (transparency != 1.0f && offscreenImage == null)
- {
- offscreenImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
- }
-
- currentColour = null;
- // TODO: non-threadsafe - each rendering thread needs its own instance of
- // the feature renderer - or this should be synchronized.
- offscreenRender = true;
-
- if (offscreenImage != null)
- {
- offscreenImage.setRGB(0, 0, initialCol);
- drawSequence(offscreenImage.getGraphics(), lastSeq, column, column, 0);
-
- return offscreenImage.getRGB(0, 0);
- }
- else
- {
- drawSequence(null, lastSeq, lastSeq.findPosition(column), -1, -1);
-
- if (currentColour == null)
- {
- return initialCol;
- }
- else
- {
- return ((Integer) currentColour).intValue();
- }
- }
-
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param g
- * DOCUMENT ME!
- * @param seq
- * DOCUMENT ME!
- * @param sg
- * DOCUMENT ME!
- * @param start
- * DOCUMENT ME!
- * @param end
- * DOCUMENT ME!
- * @param x1
- * DOCUMENT ME!
- * @param y1
- * DOCUMENT ME!
- * @param width
- * DOCUMENT ME!
- * @param height
- * DOCUMENT ME!
- */
- // String type;
- // SequenceFeature sf;
- SequenceI lastSeq;
-
- SequenceFeature[] sequenceFeatures;
-
- int sfSize, sfindex, spos, epos;
-
- /**
- * show scores as heights
- */
- protected boolean varyHeight = false;
-
- synchronized public void drawSequence(Graphics g, SequenceI seq,
- int start, int end, int y1)
- {
-
- if (seq.getDatasetSequence().getSequenceFeatures() == null
- || seq.getDatasetSequence().getSequenceFeatures().length == 0)
- {
- return;
- }
-
- if (g != null)
- {
- fm = g.getFontMetrics();
- }
-
- if (av.featuresDisplayed == null || renderOrder == null
- || newFeatureAdded)
- {
- findAllFeatures();
- if (av.featuresDisplayed.size() < 1)
- {
- return;
- }
-
- sequenceFeatures = seq.getDatasetSequence().getSequenceFeatures();
- }
-
- if (lastSeq == null
- || seq != lastSeq
- || seq.getDatasetSequence().getSequenceFeatures() != sequenceFeatures)
- {
- lastSeq = seq;
- sequenceFeatures = seq.getDatasetSequence().getSequenceFeatures();
- }
-
- if (transparency != 1 && g != null)
- {
- Graphics2D g2 = (Graphics2D) g;
- g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
- transparency));
- }
-
- if (!offscreenRender)
- {
- spos = lastSeq.findPosition(start);
- epos = lastSeq.findPosition(end);
- }
-
- sfSize = sequenceFeatures.length;
- String type;
- for (int renderIndex = 0; renderIndex < renderOrder.length; renderIndex++)
- {
- type = renderOrder[renderIndex];
-
- if (type == null || !av.featuresDisplayed.containsKey(type))
- {
- continue;
- }
-
- // loop through all features in sequence to find
- // current feature to render
- for (sfindex = 0; sfindex < sfSize; sfindex++)
- {
- if (!sequenceFeatures[sfindex].type.equals(type))
- {
- continue;
- }
-
- if (featureGroups != null
- && sequenceFeatures[sfindex].featureGroup != null
- && sequenceFeatures[sfindex].featureGroup.length() != 0
- && featureGroups
- .containsKey(sequenceFeatures[sfindex].featureGroup)
- && !((Boolean) featureGroups
- .get(sequenceFeatures[sfindex].featureGroup))
- .booleanValue())
- {
- continue;
- }
-
- if (!offscreenRender
- && (sequenceFeatures[sfindex].getBegin() > epos || sequenceFeatures[sfindex]
- .getEnd() < spos))
- {
- continue;
- }
-
- if (offscreenRender && offscreenImage == null)
- {
- if (sequenceFeatures[sfindex].begin <= start
- && sequenceFeatures[sfindex].end >= start)
- {
- // this is passed out to the overview and other sequence renderers
- // (e.g. molecule viewer) to get displayed colour for rendered
- // sequence
- currentColour = new Integer(
- getColour(sequenceFeatures[sfindex]).getRGB());
- // used to be retreived from av.featuresDisplayed
- // currentColour = av.featuresDisplayed
- // .get(sequenceFeatures[sfindex].type);
-
- }
- }
- else if (sequenceFeatures[sfindex].type.equals("disulfide bond"))
- {
-
- renderFeature(g, seq,
- seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
- seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
- getColour(sequenceFeatures[sfindex])
- // new Color(((Integer) av.featuresDisplayed
- // .get(sequenceFeatures[sfindex].type)).intValue())
- , start, end, y1);
- renderFeature(g, seq,
- seq.findIndex(sequenceFeatures[sfindex].end) - 1,
- seq.findIndex(sequenceFeatures[sfindex].end) - 1,
- getColour(sequenceFeatures[sfindex])
- // new Color(((Integer) av.featuresDisplayed
- // .get(sequenceFeatures[sfindex].type)).intValue())
- , start, end, y1);
-
- }
- else if (showFeature(sequenceFeatures[sfindex]))
- {
- if (av.showSeqFeaturesHeight
- && sequenceFeatures[sfindex].score != Float.NaN)
- {
- renderScoreFeature(g, seq,
- seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
- seq.findIndex(sequenceFeatures[sfindex].end) - 1,
- getColour(sequenceFeatures[sfindex]), start, end, y1,
- normaliseScore(sequenceFeatures[sfindex]));
- }
- else
- {
- renderFeature(g, seq,
- seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
- seq.findIndex(sequenceFeatures[sfindex].end) - 1,
- getColour(sequenceFeatures[sfindex]), start, end, y1);
- }
- }
-
- }
-
- }
-
- if (transparency != 1.0f && g != null)
- {
- Graphics2D g2 = (Graphics2D) g;
- g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
- 1.0f));
- }
- }
-
- Hashtable minmax = new Hashtable();
-
- /**
- * normalise a score against the max/min bounds for the feature type.
- *
- * @param sequenceFeature
- * @return byte[] { signed, normalised signed (-127 to 127) or unsigned
- * (0-255) value.
- */
- private final byte[] normaliseScore(SequenceFeature sequenceFeature)
- {
- float[] mm = ((float[][]) minmax.get(sequenceFeature.type))[0];
- final byte[] r = new byte[]
- { 0, (byte) 255 };
- if (mm != null)
- {
- if (r[0] != 0 || mm[0] < 0.0)
- {
- r[0] = 1;
- r[1] = (byte) ((int) 128.0 + 127.0 * (sequenceFeature.score / mm[1]));
- }
- else
- {
- r[1] = (byte) ((int) 255.0 * (sequenceFeature.score / mm[1]));
- }
- }
- return r;
- }
-
- char s;
-
- int i;
-
- void renderFeature(Graphics g, SequenceI seq, int fstart, int fend,
- Color featureColour, int start, int end, int y1)
- {
-
- if (((fstart <= end) && (fend >= start)))
- {
- if (fstart < start)
- { // fix for if the feature we have starts before the sequence start,
- fstart = start; // but the feature end is still valid!!
- }
-
- if (fend >= end)
- {
- fend = end;
- }
- int pady = (y1 + av.charHeight) - av.charHeight / 5;
- for (i = fstart; i <= fend; i++)
- {
- s = seq.getCharAt(i);
-
- if (jalview.util.Comparison.isGap(s))
- {
- continue;
- }
-
- g.setColor(featureColour);
-
- g.fillRect((i - start) * av.charWidth, y1, av.charWidth,
- av.charHeight);
-
- if (offscreenRender || !av.validCharWidth)
- {
- continue;
- }
-
- g.setColor(Color.white);
- charOffset = (av.charWidth - fm.charWidth(s)) / 2;
- g.drawString(String.valueOf(s), charOffset
- + (av.charWidth * (i - start)), pady);
-
- }
- }
- }
-
- void renderScoreFeature(Graphics g, SequenceI seq, int fstart, int fend,
- Color featureColour, int start, int end, int y1, byte[] bs)
- {
-
- if (((fstart <= end) && (fend >= start)))
- {
- if (fstart < start)
- { // fix for if the feature we have starts before the sequence start,
- fstart = start; // but the feature end is still valid!!
- }
-
- if (fend >= end)
- {
- fend = end;
- }
- int pady = (y1 + av.charHeight) - av.charHeight / 5;
- int ystrt = 0, yend = av.charHeight;
- if (bs[0] != 0)
- {
- // signed - zero is always middle of residue line.
- if (bs[1] < 128)
- {
- yend = av.charHeight * (128 - bs[1]) / 512;
- ystrt = av.charHeight - yend / 2;
- }
- else
- {
- ystrt = av.charHeight / 2;
- yend = av.charHeight * (bs[1] - 128) / 512;
- }
- }
- else
- {
- yend = av.charHeight * bs[1] / 255;
- ystrt = av.charHeight - yend;
-
- }
- for (i = fstart; i <= fend; i++)
- {
- s = seq.getCharAt(i);
-
- if (jalview.util.Comparison.isGap(s))
- {
- continue;
- }
-
- g.setColor(featureColour);
- int x = (i - start) * av.charWidth;
- g.drawRect(x, y1, av.charWidth, av.charHeight);
- g.fillRect(x, y1 + ystrt, av.charWidth, yend);
-
- if (offscreenRender || !av.validCharWidth)
- {
- continue;
- }
-
- g.setColor(Color.black);
- charOffset = (av.charWidth - fm.charWidth(s)) / 2;
- g.drawString(String.valueOf(s), charOffset
- + (av.charWidth * (i - start)), pady);
-
- }
- }
- }
-
- boolean newFeatureAdded = false;
-
- /**
- * Called when alignment in associated view has new/modified features to
- * discover and display.
- *
- */
- public void featuresAdded()
- {
- lastSeq = null;
- findAllFeatures();
- }
-
- boolean findingFeatures = false;
-
- /**
- * search the alignment for all new features, give them a colour and display
- * them. Then fires a PropertyChangeEvent on the changeSupport object.
- *
- */
- void findAllFeatures()
- {
- synchronized (firing)
- {
- if (firing.equals(Boolean.FALSE))
- {
- firing = Boolean.TRUE;
- findAllFeatures(true); // add all new features as visible
- changeSupport.firePropertyChange("changeSupport", null, null);
- firing = Boolean.FALSE;
- }
- }
- }
-
- /**
- * Searches alignment for all features and updates colours
- *
- * @param newMadeVisible
- * if true newly added feature types will be rendered immediatly
- */
- synchronized void findAllFeatures(boolean newMadeVisible)
- {
- newFeatureAdded = false;
-
- if (findingFeatures)
- {
- newFeatureAdded = true;
- return;
- }
-
- findingFeatures = true;
-
- if (av.featuresDisplayed == null)
- {
- av.featuresDisplayed = new Hashtable();
- }
-
- allfeatures = new Vector();
- Vector oldfeatures = new Vector();
- if (renderOrder != null)
- {
- for (int i = 0; i < renderOrder.length; i++)
- {
- if (renderOrder[i] != null)
- {
- oldfeatures.addElement(renderOrder[i]);
- }
- }
- }
- if (minmax == null)
- {
- minmax = new Hashtable();
- }
- AlignmentI alignment = av.getAlignment();
- for (int i = 0; i < alignment.getHeight(); i++)
- {
- SequenceFeature[] features = alignment.getSequenceAt(i)
- .getDatasetSequence().getSequenceFeatures();
-
- if (features == null)
- {
- continue;
- }
-
- int index = 0;
- while (index < features.length)
- {
- if (!av.featuresDisplayed.containsKey(features[index].getType()))
- {
-
- if (featureGroups.containsKey(features[index].getType()))
- {
- boolean visible = ((Boolean) featureGroups
- .get(features[index].featureGroup)).booleanValue();
-
- if (!visible)
- {
- index++;
- continue;
- }
- }
-
- if (!(features[index].begin == 0 && features[index].end == 0))
- {
- // If beginning and end are 0, the feature is for the whole sequence
- // and we don't want to render the feature in the normal way
-
- if (newMadeVisible
- && !oldfeatures.contains(features[index].getType()))
- {
- // this is a new feature type on the alignment. Mark it for
- // display.
- av.featuresDisplayed.put(features[index].getType(),
- new Integer(getColour(features[index].getType())
- .getRGB()));
- setOrder(features[index].getType(), 0);
- }
- }
- }
- if (!allfeatures.contains(features[index].getType()))
- {
- allfeatures.addElement(features[index].getType());
- }
- if (features[index].score != Float.NaN)
- {
- int nonpos = features[index].getBegin() >= 1 ? 0 : 1;
- float[][] mm = (float[][]) minmax.get(features[index].getType());
- if (mm == null)
- {
- mm = new float[][]
- { null, null };
- minmax.put(features[index].getType(), mm);
- }
- if (mm[nonpos] == null)
- {
- mm[nonpos] = new float[]
- { features[index].score, features[index].score };
-
- }
- else
- {
- if (mm[nonpos][0] > features[index].score)
- {
- mm[nonpos][0] = features[index].score;
- }
- if (mm[nonpos][1] < features[index].score)
- {
- mm[nonpos][1] = features[index].score;
- }
- }
- }
- index++;
- }
- }
- updateRenderOrder(allfeatures);
- findingFeatures = false;
- }
-
- protected Boolean firing = Boolean.FALSE;
-
- /**
- * replaces the current renderOrder with the unordered features in
- * allfeatures. The ordering of any types in both renderOrder and allfeatures
- * is preserved, and all new feature types are rendered on top of the existing
- * types, in the order given by getOrder or the order given in allFeatures.
- * Note. this operates directly on the featureOrder hash for efficiency. TODO:
- * eliminate the float storage for computing/recalling the persistent ordering
- * New Cability: updates min/max for colourscheme range if its dynamic
- *
- * @param allFeatures
- */
- private void updateRenderOrder(Vector allFeatures)
- {
- Vector allfeatures = new Vector(allFeatures);
- String[] oldRender = renderOrder;
- renderOrder = new String[allfeatures.size()];
- Object mmrange, fc = null;
- boolean initOrders = (featureOrder == null);
- int opos = 0;
- if (oldRender != null && oldRender.length > 0)
- {
- for (int j = 0; j < oldRender.length; j++)
- {
- if (oldRender[j] != null)
- {
- if (initOrders)
- {
- setOrder(oldRender[j], (1 - (1 + (float) j)
- / (float) oldRender.length));
- }
- if (allfeatures.contains(oldRender[j]))
- {
- renderOrder[opos++] = oldRender[j]; // existing features always
- // appear below new features
- allfeatures.removeElement(oldRender[j]);
- if (minmax != null)
- {
- mmrange = minmax.get(oldRender[j]);
- if (mmrange != null)
- {
- fc = featureColours.get(oldRender[j]);
- if (fc != null && fc instanceof GraduatedColor
- && ((GraduatedColor) fc).isAutoScale())
- {
- ((GraduatedColor) fc).updateBounds(
- ((float[][]) mmrange)[0][0],
- ((float[][]) mmrange)[0][1]);
- }
- }
- }
- }
- }
- }
- }
- if (allfeatures.size() == 0)
- {
- // no new features - leave order unchanged.
- return;
- }
- int i = allfeatures.size() - 1;
- int iSize = i;
- boolean sort = false;
- String[] newf = new String[allfeatures.size()];
- float[] sortOrder = new float[allfeatures.size()];
- Enumeration en = allfeatures.elements();
- // sort remaining elements
- while (en.hasMoreElements())
- {
- newf[i] = en.nextElement().toString();
- if (minmax != null)
- {
- // update from new features minmax if necessary
- mmrange = minmax.get(newf[i]);
- if (mmrange != null)
- {
- fc = featureColours.get(newf[i]);
- if (fc != null && fc instanceof GraduatedColor
- && ((GraduatedColor) fc).isAutoScale())
- {
- ((GraduatedColor) fc).updateBounds(((float[][]) mmrange)[0][0],
- ((float[][]) mmrange)[0][1]);
- }
- }
- }
- if (initOrders || !featureOrder.containsKey(newf[i]))
- {
- int denom = initOrders ? allfeatures.size() : featureOrder.size();
- // new unordered feature - compute persistent ordering at head of
- // existing features.
- setOrder(newf[i], i / (float) denom);
- }
- // set order from newly found feature from persisted ordering.
- sortOrder[i] = 2 - ((Float) featureOrder.get(newf[i])).floatValue();
- if (i < iSize)
- {
- // only sort if we need to
- sort = sort || sortOrder[i] > sortOrder[i + 1];
- }
- i--;
- }
- if (iSize > 1 && sort)
- {
- jalview.util.QuickSort.sort(sortOrder, newf);
- }
- sortOrder = null;
- System.arraycopy(newf, 0, renderOrder, opos, newf.length);
- }
-
- /**
- * get a feature style object for the given type string. Creates a
- * java.awt.Color for a featureType with no existing colourscheme. TODO:
- * replace return type with object implementing standard abstract colour/style
- * interface
- *
- * @param featureType
- * @return java.awt.Color or GraduatedColor
- */
- public Object getFeatureStyle(String featureType)
- {
- Object fc = featureColours.get(featureType);
- if (fc == null)
- {
- jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme();
- Color col = ucs.createColourFromName(featureType);
- featureColours.put(featureType, fc = col);
- }
- return fc;
- }
-
- /**
- * return a nominal colour for this feature
- *
- * @param featureType
- * @return standard color, or maximum colour for graduated colourscheme
- */
- public Color getColour(String featureType)
- {
- Object fc = getFeatureStyle(featureType);
-
- if (fc instanceof Color)
- {
- return (Color) fc;
- }
- else
- {
- if (fc instanceof GraduatedColor)
- {
- return ((GraduatedColor) fc).getMaxColor();
- }
- }
- throw new Error("Implementation Error: Unrecognised render object "
- + fc.getClass() + " for features of type " + featureType);
- }
-
- /**
- * calculate the render colour for a specific feature using current feature
- * settings.
- *
- * @param feature
- * @return render colour for the given feature
- */
- public Color getColour(SequenceFeature feature)
- {
- Object fc = getFeatureStyle(feature.getType());
- if (fc instanceof Color)
- {
- return (Color) fc;
- }
- else
- {
- if (fc instanceof GraduatedColor)
- {
- return ((GraduatedColor) fc).findColor(feature);
- }
- }
- throw new Error("Implementation Error: Unrecognised render object "
- + fc.getClass() + " for features of type " + feature.getType());
- }
-
- private boolean showFeature(SequenceFeature sequenceFeature)
- {
- Object fc = getFeatureStyle(sequenceFeature.type);
- if (fc instanceof GraduatedColor)
- {
- return ((GraduatedColor) fc).isColored(sequenceFeature);
- }
- else
- {
- return true;
- }
- }
-
// // /////////////
// // Feature Editing Dialog
// // Will be refactored in next release.
@@ -1256,7 +335,7 @@ public class FeatureRenderer extends jalview.viewmodel.FeatureRenderer implement
sf.description = lastDescriptionAdded;
setColour(sf.type, fcol);
- av.featuresDisplayed.put(sf.type, getColour(sf.type));
+ getFeaturesDisplayed().setVisible(sf.type);
try
{
@@ -1277,27 +356,20 @@ public class FeatureRenderer extends jalview.viewmodel.FeatureRenderer implement
for (int i = 0; i < sequences.length; i++)
{
features[i].type = lastFeatureAdded;
- if (lastFeatureGroupAdded != null)
- features[i].featureGroup = lastFeatureGroupAdded;
+ // fix for JAL-1538 - always set feature group here
+ features[i].featureGroup = lastFeatureGroupAdded;
features[i].description = lastDescriptionAdded;
sequences[i].addSequenceFeature(features[i]);
ffile.parseDescriptionHTML(features[i], false);
}
- if (av.featuresDisplayed == null)
- {
- av.featuresDisplayed = new Hashtable();
- }
-
+
if (lastFeatureGroupAdded != null)
{
- if (featureGroups == null)
- featureGroups = new Hashtable();
- featureGroups.put(lastFeatureGroupAdded, new Boolean(true));
+ setGroupVisibility(lastFeatureGroupAdded, true);
}
setColour(lastFeatureAdded, fcol);
- av.featuresDisplayed.put(lastFeatureAdded,
- getColour(lastFeatureAdded));
+ setVisible(lastFeatureAdded);
findAllFeatures(false);
@@ -1316,6 +388,7 @@ public class FeatureRenderer extends jalview.viewmodel.FeatureRenderer implement
return true;
}
+
/**
* update the amend feature button dependent on the given style
*
@@ -1343,145 +416,4 @@ public class FeatureRenderer extends jalview.viewmodel.FeatureRenderer implement
// colour.setForeground(colour.getBackground());
}
}
-
- public void setColour(String featureType, Object col)
- {
- // overwrite
- // Color _col = (col instanceof Color) ? ((Color) col) : (col instanceof
- // GraduatedColor) ? ((GraduatedColor) col).getMaxColor() : null;
- // Object c = featureColours.get(featureType);
- // if (c == null || c instanceof Color || (c instanceof GraduatedColor &&
- // !((GraduatedColor)c).getMaxColor().equals(_col)))
- {
- featureColours.put(featureType, col);
- }
- }
-
- public void setTransparency(float value)
- {
- transparency = value;
- }
-
- public float getTransparency()
- {
- return transparency;
- }
-
- /**
- * Replace current ordering with new ordering
- *
- * @param data
- * { String(Type), Colour(Type), Boolean(Displayed) }
- */
- public void setFeaturePriority(Object[][] data)
- {
- setFeaturePriority(data, true);
- }
-
- /**
- *
- * @param data
- * { String(Type), Colour(Type), Boolean(Displayed) }
- * @param visibleNew
- * when true current featureDisplay list will be cleared
- */
- public void setFeaturePriority(Object[][] data, boolean visibleNew)
- {
- if (visibleNew)
- {
- if (av.featuresDisplayed != null)
- {
- av.featuresDisplayed.clear();
- }
- else
- {
- av.featuresDisplayed = new Hashtable();
- }
- }
- if (data == null)
- {
- return;
- }
-
- // The feature table will display high priority
- // features at the top, but theses are the ones
- // we need to render last, so invert the data
- renderOrder = new String[data.length];
-
- if (data.length > 0)
- {
- for (int i = 0; i < data.length; i++)
- {
- String type = data[i][0].toString();
- setColour(type, data[i][1]); // todo : typesafety - feature color
- // interface object
- if (((Boolean) data[i][2]).booleanValue())
- {
- av.featuresDisplayed.put(type, new Integer(getColour(type)
- .getRGB()));
- }
-
- renderOrder[data.length - i - 1] = type;
- }
- }
-
- }
-
- Map featureOrder = null;
-
- /**
- * analogous to colour - store a normalized ordering for all feature types in
- * this rendering context.
- *
- * @param type
- * Feature type string
- * @param position
- * normalized priority - 0 means always appears on top, 1 means
- * always last.
- */
- public float setOrder(String type, float position)
- {
- if (featureOrder == null)
- {
- featureOrder = new Hashtable();
- }
- featureOrder.put(type, new Float(position));
- return position;
- }
-
- /**
- * get the global priority (0 (top) to 1 (bottom))
- *
- * @param type
- * @return [0,1] or -1 for a type without a priority
- */
- public float getOrder(String type)
- {
- if (featureOrder != null)
- {
- if (featureOrder.containsKey(type))
- {
- return ((Float) featureOrder.get(type)).floatValue();
- }
- }
- return -1;
- }
-
- /**
- * @param listener
- * @see java.beans.PropertyChangeSupport#addPropertyChangeListener(java.beans.PropertyChangeListener)
- */
- public void addPropertyChangeListener(PropertyChangeListener listener)
- {
- changeSupport.addPropertyChangeListener(listener);
- }
-
- /**
- * @param listener
- * @see java.beans.PropertyChangeSupport#removePropertyChangeListener(java.beans.PropertyChangeListener)
- */
- public void removePropertyChangeListener(PropertyChangeListener listener)
- {
- changeSupport.removePropertyChangeListener(listener);
- }
}
diff --git a/src/jalview/gui/FeatureSettings.java b/src/jalview/gui/FeatureSettings.java
index 3dae4e5..d30f5a0 100644
--- a/src/jalview/gui/FeatureSettings.java
+++ b/src/jalview/gui/FeatureSettings.java
@@ -33,6 +33,7 @@ import javax.swing.event.*;
import javax.swing.table.*;
import jalview.analysis.AlignmentSorter;
+import jalview.api.FeaturesDisplayedI;
import jalview.bin.Cache;
import jalview.commands.OrderCommand;
import jalview.datamodel.*;
@@ -58,6 +59,8 @@ public class FeatureSettings extends JPanel
Object[][] originalData;
+ private float originalTransparency;
+
final JInternalFrame frame;
JScrollPane scrollPane = new JScrollPane();
@@ -74,8 +77,8 @@ public class FeatureSettings extends JPanel
{
this.af = af;
fr = af.getFeatureRenderer();
-
- transparency.setMaximum(100 - (int) (fr.transparency * 100));
+ // allow transparency to be recovered
+ transparency.setMaximum(100 - (int) ((originalTransparency=fr.getTransparency()) * 100));
try
{
@@ -104,8 +107,8 @@ public class FeatureSettings extends JPanel
if (evt.isPopupTrigger())
{
popupSort(selectedRow, (String) table.getValueAt(selectedRow, 0),
- table.getValueAt(selectedRow, 1), fr.minmax, evt.getX(),
- evt.getY());
+ table.getValueAt(selectedRow, 1), fr.getMinMax(),
+ evt.getX(), evt.getY());
}
else if (evt.getClickCount() == 2)
{
@@ -150,8 +153,7 @@ public class FeatureSettings extends JPanel
dassourceBrowser = new DasSourceBrowser(this);
dasSettingsPane.add(dassourceBrowser, BorderLayout.CENTER);
- if (af.getViewport().featuresDisplayed == null
- || fr.renderOrder == null)
+ if (af.getViewport().isShowSequenceFeatures() || !fr.hasRenderOrder())
{
fr.findAllFeatures(true); // display everything!
}
@@ -216,7 +218,7 @@ public class FeatureSettings extends JPanel
public void actionPerformed(ActionEvent e)
{
- me.sortByScore(new String[]
+ me.af.avc.sortAlignmentByFeatureScore(new String[]
{ type });
}
@@ -228,7 +230,7 @@ public class FeatureSettings extends JPanel
public void actionPerformed(ActionEvent e)
{
- me.sortByDens(new String[]
+ me.af.avc.sortAlignmentByFeatureDensity(new String[]
{ type });
}
@@ -352,10 +354,6 @@ public class FeatureSettings extends JPanel
synchronized public void setTableData()
{
- if (fr.featureGroups == null)
- {
- fr.featureGroups = new Hashtable();
- }
Vector allFeatures = new Vector();
Vector allGroups = new Vector();
SequenceFeature[] tmpfeatures;
@@ -386,10 +384,7 @@ public class FeatureSettings extends JPanel
if (!allGroups.contains(group))
{
allGroups.addElement(group);
- if (group != null)
- {
- checkGroupState(group);
- }
+ checkGroupState(group);
}
}
@@ -407,21 +402,14 @@ public class FeatureSettings extends JPanel
}
/**
+ * Synchronise gui group list and check visibility of group
*
* @param group
- * @return true if group has been seen before and is already added to set.
+ * @return true if group is visible
*/
private boolean checkGroupState(String group)
{
- boolean visible;
- if (fr.featureGroups.containsKey(group))
- {
- visible = ((Boolean) fr.featureGroups.get(group)).booleanValue();
- }
- else
- {
- visible = true; // new group is always made visible
- }
+ boolean visible = fr.checkGroupVisibility(group, true);
if (groupPanel == null)
{
@@ -442,10 +430,8 @@ public class FeatureSettings extends JPanel
if (alreadyAdded)
{
- return true;
+ return visible;
}
-
- fr.featureGroups.put(group, new Boolean(visible));
final String grp = group;
final JCheckBox check = new JCheckBox(group, visible);
check.setFont(new Font("Serif", Font.BOLD, 12));
@@ -453,8 +439,7 @@ public class FeatureSettings extends JPanel
{
public void itemStateChanged(ItemEvent evt)
{
- fr.featureGroups.put(check.getText(),
- new Boolean(check.isSelected()));
+ fr.setGroupVisibility(check.getText(), check.isSelected());
af.alignPanel.seqPanel.seqCanvas.repaint();
if (af.alignPanel.overviewPanel != null)
{
@@ -466,7 +451,7 @@ public class FeatureSettings extends JPanel
}
});
groupPanel.add(check);
- return false;
+ return visible;
}
boolean resettingTable = false;
@@ -510,11 +495,8 @@ public class FeatureSettings extends JPanel
continue;
}
- if (group == null || fr.featureGroups.get(group) == null
- || ((Boolean) fr.featureGroups.get(group)).booleanValue())
+ if (group == null || checkGroupState(group))
{
- if (group != null)
- checkGroupState(group);
type = tmpfeatures[index].getType();
if (!visibleChecks.contains(type))
{
@@ -549,17 +531,20 @@ public class FeatureSettings extends JPanel
Object[][] data = new Object[fSize][3];
int dataIndex = 0;
- if (fr.renderOrder != null)
+ if (fr.hasRenderOrder())
{
if (!handlingUpdate)
+ {
fr.findAllFeatures(groupChanged != null); // prod to update
- // colourschemes. but don't
- // affect display
- // First add the checks in the previous render order,
- // in case the window has been closed and reopened
- for (int ro = fr.renderOrder.length - 1; ro > -1; ro--)
+ // colourschemes. but don't
+ // affect display
+ // First add the checks in the previous render order,
+ // in case the window has been closed and reopened
+ }
+ List frl = fr.getRenderOrder();
+ for (int ro = frl.size() - 1; ro > -1; ro--)
{
- type = fr.renderOrder[ro];
+ type = frl.get(ro);
if (!visibleChecks.contains(type))
{
@@ -568,8 +553,8 @@ public class FeatureSettings extends JPanel
data[dataIndex][0] = type;
data[dataIndex][1] = fr.getFeatureStyle(type);
- data[dataIndex][2] = new Boolean(
- af.getViewport().featuresDisplayed.containsKey(type));
+ data[dataIndex][2] = new Boolean(af.getViewport()
+ .getFeaturesDisplayed().isVisible(type));
dataIndex++;
visibleChecks.removeElement(type);
}
@@ -587,7 +572,7 @@ public class FeatureSettings extends JPanel
if (data[dataIndex][1] == null)
{
// "Colour has been updated in another view!!"
- fr.renderOrder = null;
+ fr.clearRenderOrder();
return;
}
@@ -609,8 +594,8 @@ public class FeatureSettings extends JPanel
if (groupPanel != null)
{
- groupPanel.setLayout(new GridLayout(fr.featureGroups.size() / 4 + 1,
- 4));
+ groupPanel.setLayout(new GridLayout(
+ fr.getFeatureGroupsSize() / 4 + 1, 4));
groupPanel.validate();
bigPanel.add(groupPanel, BorderLayout.NORTH);
@@ -761,9 +746,10 @@ public class FeatureSettings extends JPanel
PrintWriter out = new PrintWriter(new OutputStreamWriter(
new FileOutputStream(choice), "UTF-8"));
- Iterator e = fr.featureColours.keySet().iterator();
- float[] sortOrder = new float[fr.featureColours.size()];
- String[] sortTypes = new String[fr.featureColours.size()];
+ Set fr_colours = fr.getAllFeatureColours();
+ Iterator e = fr_colours.iterator();
+ float[] sortOrder = new float[fr_colours.size()];
+ String[] sortTypes = new String[fr_colours.size()];
int i = 0;
while (e.hasNext())
{
@@ -976,7 +962,7 @@ public class FeatureSettings extends JPanel
{
public void actionPerformed(ActionEvent e)
{
- sortByScore(null);
+ af.avc.sortAlignmentByFeatureScore(null);
}
});
sortByDens.setFont(JvSwingUtils.getLabelFont());
@@ -986,7 +972,7 @@ public class FeatureSettings extends JPanel
{
public void actionPerformed(ActionEvent e)
{
- sortByDens(null);
+ af.avc.sortAlignmentByFeatureDensity(null);
}
});
cancel.setFont(JvSwingUtils.getLabelFont());
@@ -995,6 +981,7 @@ public class FeatureSettings extends JPanel
{
public void actionPerformed(ActionEvent e)
{
+ fr.setTransparency(originalTransparency);
updateFeatureRenderer(originalData);
close();
}
@@ -1086,131 +1073,6 @@ public class FeatureSettings extends JPanel
settingsPane.add(buttonPanel, java.awt.BorderLayout.SOUTH);
}
- protected void sortByDens(String[] typ)
- {
- sortBy(typ, "Sort by Density", AlignmentSorter.FEATURE_DENSITY);
- }
-
- protected void sortBy(String[] typ, String methodText, final String method)
- {
- if (typ == null)
- {
- typ = getDisplayedFeatureTypes();
- }
- String gps[] = null;
- gps = getDisplayedFeatureGroups();
- if (typ != null)
- {
- ArrayList types = new ArrayList();
- for (int i = 0; i < typ.length; i++)
- {
- if (typ[i] != null)
- {
- types.add(typ[i]);
- }
- typ = new String[types.size()];
- types.toArray(typ);
- }
- }
- if (gps != null)
- {
- ArrayList grps = new ArrayList();
-
- for (int i = 0; i < gps.length; i++)
- {
- if (gps[i] != null)
- {
- grps.add(gps[i]);
- }
- }
- gps = new String[grps.size()];
- grps.toArray(gps);
- }
- AlignmentPanel alignPanel = af.alignPanel;
- AlignmentI al = alignPanel.av.getAlignment();
-
- int start, stop;
- SequenceGroup sg = alignPanel.av.getSelectionGroup();
- if (sg != null)
- {
- start = sg.getStartRes();
- stop = sg.getEndRes();
- }
- else
- {
- start = 0;
- stop = al.getWidth();
- }
- SequenceI[] oldOrder = al.getSequencesArray();
- AlignmentSorter.sortByFeature(typ, gps, start, stop, al, method);
- af.addHistoryItem(new OrderCommand(methodText, oldOrder, alignPanel.av
- .getAlignment()));
- alignPanel.paintAlignment(true);
-
- }
-
- protected void sortByScore(String[] typ)
- {
- sortBy(typ, "Sort by Feature Score", AlignmentSorter.FEATURE_SCORE);
- }
-
- private String[] getDisplayedFeatureTypes()
- {
- String[] typ = null;
- if (fr != null)
- {
- synchronized (fr.renderOrder)
- {
- typ = new String[fr.renderOrder.length];
- System.arraycopy(fr.renderOrder, 0, typ, 0, typ.length);
- for (int i = 0; i < typ.length; i++)
- {
- if (af.viewport.featuresDisplayed.get(typ[i]) == null)
- {
- typ[i] = null;
- }
- }
- }
- }
- return typ;
- }
-
- private String[] getDisplayedFeatureGroups()
- {
- String[] gps = null;
- ArrayList _gps = new ArrayList();
- if (fr != null)
- {
-
- if (fr.featureGroups != null)
- {
- Iterator en = fr.featureGroups.keySet().iterator();
- int g = 0;
- boolean valid = false;
- while (en.hasNext())
- {
- String gp = (String) en.next();
- Boolean on = (Boolean) fr.featureGroups.get(gp);
- if (on != null && on.booleanValue())
- {
- valid = true;
- _gps.add(gp);
- }
- }
- if (!valid)
- {
- return null;
- }
- else
- {
- gps = new String[_gps.size()];
- _gps.toArray(gps);
- }
- }
- }
- return gps;
- }
-
public void fetchDAS_actionPerformed(ActionEvent e)
{
fetchDAS.setEnabled(false);
diff --git a/src/jalview/gui/IdPanel.java b/src/jalview/gui/IdPanel.java
index ee779f7..30a8a5e 100755
--- a/src/jalview/gui/IdPanel.java
+++ b/src/jalview/gui/IdPanel.java
@@ -100,7 +100,7 @@ public class IdPanel extends JPanel implements MouseListener,
seqAnnotReport
.createSequenceAnnotationReport(tip, sequence,
av.isShowDbRefs(), av.isShowNpFeats(),
- sp.seqCanvas.fr.minmax);
+ sp.seqCanvas.fr.getMinMax());
setToolTipText("" + sequence.getDisplayId(true) + " "
+ tip.toString() + "");
}
diff --git a/src/jalview/gui/Jalview2XML.java b/src/jalview/gui/Jalview2XML.java
index 3ab5a8d..d7453c8 100644
--- a/src/jalview/gui/Jalview2XML.java
+++ b/src/jalview/gui/Jalview2XML.java
@@ -42,6 +42,8 @@ import jalview.schemes.*;
import jalview.util.Platform;
import jalview.util.jarInputStreamProvider;
import jalview.viewmodel.AlignmentViewport;
+import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
+import jalview.viewmodel.seqfeatures.FeaturesDisplayed;
import jalview.ws.jws2.Jws2Discoverer;
import jalview.ws.jws2.dm.AAConSettings;
import jalview.ws.jws2.jabaws2.Jws2Instance;
@@ -1081,11 +1083,12 @@ public class Jalview2XML
view.setFollowHighlight(av.followHighlight);
view.setFollowSelection(av.followSelection);
view.setIgnoreGapsinConsensus(av.getIgnoreGapsConsensus());
- if (av.featuresDisplayed != null)
+ if (av.getFeaturesDisplayed() != null)
{
jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
- String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer().renderOrder;
+ String[] renderOrder = ap.seqPanel.seqCanvas.getFeatureRenderer()
+ .getRenderOrder().toArray(new String[0]);
Vector settingsAdded = new Vector();
Object gstyle = null;
@@ -1116,8 +1119,8 @@ public class Jalview2XML
.getColour(renderOrder[ro]).getRGB());
}
- setting.setDisplay(av.featuresDisplayed
- .containsKey(renderOrder[ro]));
+ setting.setDisplay(av.getFeaturesDisplayed().isVisible(
+ renderOrder[ro]));
float rorder = ap.seqPanel.seqCanvas.getFeatureRenderer()
.getOrder(renderOrder[ro]);
if (rorder > -1)
@@ -1130,8 +1133,8 @@ public class Jalview2XML
}
// Make sure we save none displayed feature settings
- Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureColours
- .keySet().iterator();
+ Iterator en = ap.seqPanel.seqCanvas.getFeatureRenderer()
+ .getFeatureColours().keySet().iterator();
while (en.hasNext())
{
String key = en.next().toString();
@@ -1155,8 +1158,9 @@ public class Jalview2XML
fs.addSetting(setting);
settingsAdded.addElement(key);
}
- en = ap.seqPanel.seqCanvas.getFeatureRenderer().featureGroups
- .keySet().iterator();
+ // is groups actually supposed to be a map here ?
+ en = ap.seqPanel.seqCanvas.getFeatureRenderer().getFeatureGroups()
+ .iterator();
Vector groupsAdded = new Vector();
while (en.hasNext())
{
@@ -1168,7 +1172,7 @@ public class Jalview2XML
Group g = new Group();
g.setName(grp);
g.setDisplay(((Boolean) ap.seqPanel.seqCanvas
- .getFeatureRenderer().featureGroups.get(grp))
+ .getFeatureRenderer().checkGroupVisibility(grp, false))
.booleanValue());
fs.addGroup(g);
groupsAdded.addElement(grp);
@@ -3500,9 +3504,14 @@ public class Jalview2XML
// recover featre settings
if (jms.getFeatureSettings() != null)
{
- af.viewport.featuresDisplayed = new Hashtable();
+ FeaturesDisplayed fdi;
+ af.viewport.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
String[] renderOrder = new String[jms.getFeatureSettings()
.getSettingCount()];
+ Hashtable featureGroups = new Hashtable();
+ Hashtable featureColours = new Hashtable();
+ Hashtable featureOrder = new Hashtable();
+
for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
{
Setting setting = jms.getFeatureSettings().getSetting(fs);
@@ -3529,37 +3538,42 @@ public class Jalview2XML
gc.setColourByLabel(setting.getColourByLabel());
}
// and put in the feature colour table.
- af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
- setting.getType(), gc);
+ featureColours.put(setting.getType(), gc);
}
else
{
- af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
- setting.getType(),
+ featureColours.put(setting.getType(),
new java.awt.Color(setting.getColour()));
}
renderOrder[fs] = setting.getType();
if (setting.hasOrder())
- af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
- setting.getType(), setting.getOrder());
+ {
+ featureOrder.put(setting.getType(), setting.getOrder());
+ }
else
- af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setOrder(
- setting.getType(),
- fs / jms.getFeatureSettings().getSettingCount());
+ {
+ featureOrder.put(setting.getType(), new Float(fs
+ / jms.getFeatureSettings().getSettingCount()));
+ }
if (setting.getDisplay())
{
- af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
- setting.getColour()));
+ fdi.setVisible(setting.getType());
}
}
- af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
- Hashtable fgtable;
- af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().featureGroups = fgtable = new Hashtable();
+ Hashtable fgtable = new Hashtable();
for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
{
Group grp = jms.getFeatureSettings().getGroup(gs);
fgtable.put(grp.getName(), new Boolean(grp.getDisplay()));
}
+ // FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder,
+ // fgtable, featureColours, jms.getFeatureSettings().hasTransparency() ?
+ // jms.getFeatureSettings().getTransparency() : 0.0, featureOrder);
+ FeatureRendererSettings frs = new FeatureRendererSettings(
+ renderOrder, fgtable, featureColours, 1.0f, featureOrder);
+ af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer()
+ .transferSettings(frs);
+
}
if (view.getHiddenColumnsCount() > 0)
diff --git a/src/jalview/gui/Jalview2XML_V1.java b/src/jalview/gui/Jalview2XML_V1.java
index 718677c..f246fd3 100755
--- a/src/jalview/gui/Jalview2XML_V1.java
+++ b/src/jalview/gui/Jalview2XML_V1.java
@@ -27,10 +27,12 @@ import java.util.jar.*;
import javax.swing.*;
import org.exolab.castor.xml.*;
+
import jalview.binding.*;
import jalview.schemes.*;
import jalview.util.MessageManager;
import jalview.util.jarInputStreamProvider;
+import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
/**
* DOCUMENT ME!
@@ -394,25 +396,27 @@ public class Jalview2XML_V1
if (jms.getFeatureSettings() != null)
{
- af.viewport.featuresDisplayed = new Hashtable();
+ Hashtable featuresDisplayed = new Hashtable();
+ Hashtable featureColours = new Hashtable();
String[] renderOrder = new String[jms.getFeatureSettings()
.getSettingCount()];
for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
{
Setting setting = jms.getFeatureSettings().getSetting(fs);
- af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().setColour(
+ featureColours.put(
setting.getType(), new java.awt.Color(setting.getColour()));
renderOrder[fs] = setting.getType();
if (setting.getDisplay())
{
- af.viewport.featuresDisplayed.put(setting.getType(), new Integer(
+ featuresDisplayed.put(setting.getType(), new Integer(
setting.getColour()));
}
}
- af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
+ FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder, new Hashtable(), featureColours, 1.0f, null);
+ af.alignPanel.seqPanel.seqCanvas.getFeatureRenderer().transferSettings(frs);
}
af.setMenusFromViewport(af.viewport);
diff --git a/src/jalview/gui/OverviewPanel.java b/src/jalview/gui/OverviewPanel.java
index 5edf218..8829692 100755
--- a/src/jalview/gui/OverviewPanel.java
+++ b/src/jalview/gui/OverviewPanel.java
@@ -67,7 +67,7 @@ public class OverviewPanel extends JPanel implements Runnable
// main visible SeqCanvas
SequenceRenderer sr;
- FeatureRenderer fr;
+ jalview.renderer.seqfeatures.FeatureRenderer fr;
/**
* Creates a new OverviewPanel object.
diff --git a/src/jalview/gui/PopupMenu.java b/src/jalview/gui/PopupMenu.java
index 3cf4fe0..6b5040e 100644
--- a/src/jalview/gui/PopupMenu.java
+++ b/src/jalview/gui/PopupMenu.java
@@ -1470,7 +1470,7 @@ public class PopupMenu extends JPopupMenu
true,
true,
false,
- (ap.seqPanel.seqCanvas.fr != null) ? ap.seqPanel.seqCanvas.fr.minmax
+ (ap.seqPanel.seqCanvas.fr != null) ? ap.seqPanel.seqCanvas.fr.getMinMax()
: null);
contents.append("");
}
diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java
index 4c2cff2..a13d5f6 100644
--- a/src/jalview/gui/SeqPanel.java
+++ b/src/jalview/gui/SeqPanel.java
@@ -225,42 +225,6 @@ public class SeqPanel extends JPanel implements MouseListener,
return seq;
}
- SequenceFeature[] findFeaturesAtRes(SequenceI sequence, int res)
- {
- Vector tmp = new Vector();
- SequenceFeature[] features = sequence.getSequenceFeatures();
- if (features != null)
- {
- for (int i = 0; i < features.length; i++)
- {
- if (av.featuresDisplayed == null
- || !av.featuresDisplayed.containsKey(features[i].getType()))
- {
- continue;
- }
-
- if (features[i].featureGroup != null
- && seqCanvas.fr.featureGroups != null
- && seqCanvas.fr.featureGroups
- .containsKey(features[i].featureGroup)
- && !((Boolean) seqCanvas.fr.featureGroups
- .get(features[i].featureGroup)).booleanValue())
- continue;
-
- if ((features[i].getBegin() <= res)
- && (features[i].getEnd() >= res))
- {
- tmp.addElement(features[i]);
- }
- }
- }
-
- features = new SequenceFeature[tmp.size()];
- tmp.copyInto(features);
-
- return features;
- }
-
void endEditing()
{
if (editCommand != null && editCommand.getSize() > 0)
@@ -729,11 +693,11 @@ public class SeqPanel extends JPanel implements MouseListener,
if (av.isShowSequenceFeatures())
{
int rpos;
- SequenceFeature[] features = findFeaturesAtRes(
+ List features = ap.getFeatureRenderer().findFeaturesAtRes(
sequence.getDatasetSequence(),
rpos = sequence.findPosition(res));
seqARep.appendFeatures(tooltipText, rpos, features,
- this.ap.seqPanel.seqCanvas.fr.minmax);
+ this.ap.seqPanel.seqCanvas.fr.getMinMax());
}
if (tooltipText.length() == 6) //
{
@@ -1370,21 +1334,21 @@ public class SeqPanel extends JPanel implements MouseListener,
av.setSelectionGroup(null);
}
- SequenceFeature[] features = findFeaturesAtRes(
+ List features = seqCanvas.getFeatureRenderer().findFeaturesAtRes(
sequence.getDatasetSequence(),
sequence.findPosition(findRes(evt)));
- if (features != null && features.length > 0)
+ if (features != null && features.size()> 0)
{
SearchResults highlight = new SearchResults();
- highlight.addResult(sequence, features[0].getBegin(),
- features[0].getEnd());
+ highlight.addResult(sequence, features.get(0).getBegin(),
+ features.get(0).getEnd());
seqCanvas.highlightSearchResults(highlight);
}
- if (features != null && features.length > 0)
+ if (features != null && features.size()> 0)
{
seqCanvas.getFeatureRenderer().amendFeatures(new SequenceI[]
- { sequence }, features, false, ap);
+ { sequence }, features.toArray(new SequenceFeature[features.size()]), false, ap);
seqCanvas.highlightSearchResults(null);
}
@@ -1499,16 +1463,16 @@ public class SeqPanel extends JPanel implements MouseListener,
if (javax.swing.SwingUtilities.isRightMouseButton(evt))
{
- SequenceFeature[] allFeatures = findFeaturesAtRes(
+ List allFeatures = ap.getFeatureRenderer().findFeaturesAtRes(
sequence.getDatasetSequence(), sequence.findPosition(res));
Vector links = new Vector();
- for (int i = 0; i < allFeatures.length; i++)
+ for (SequenceFeature sf:allFeatures)
{
- if (allFeatures[i].links != null)
+ if (sf.links != null)
{
- for (int j = 0; j < allFeatures[i].links.size(); j++)
+ for (int j = 0; j < sf.links.size(); j++)
{
- links.addElement(allFeatures[i].links.elementAt(j));
+ links.addElement(sf.links.elementAt(j));
}
}
}
diff --git a/src/jalview/io/FeaturesFile.java b/src/jalview/io/FeaturesFile.java
index 87b829f..5b621e7 100755
--- a/src/jalview/io/FeaturesFile.java
+++ b/src/jalview/io/FeaturesFile.java
@@ -678,7 +678,7 @@ public class FeaturesFile extends AlignFile
* hash of feature types and colours
* @return features file contents
*/
- public String printJalviewFormat(SequenceI[] seqs, Hashtable visible)
+ public String printJalviewFormat(SequenceI[] seqs, Map visible)
{
return printJalviewFormat(seqs, visible, true, true);
}
@@ -697,7 +697,7 @@ public class FeaturesFile extends AlignFile
* of group or type)
* @return features file contents
*/
- public String printJalviewFormat(SequenceI[] seqs, Hashtable visible,
+ public String printJalviewFormat(SequenceI[] seqs, Map visible,
boolean visOnly, boolean nonpos)
{
StringBuffer out = new StringBuffer();
@@ -714,11 +714,11 @@ public class FeaturesFile extends AlignFile
// write feature colours only if we're given them and we are generating
// viewed features
// TODO: decide if feature links should also be written here ?
- Enumeration en = visible.keys();
+ Iterator en = visible.keySet().iterator();
String type, color;
- while (en.hasMoreElements())
+ while (en.hasNext())
{
- type = en.nextElement().toString();
+ type = en.next().toString();
if (visible.get(type) instanceof GraduatedColor)
{
@@ -926,12 +926,12 @@ public class FeaturesFile extends AlignFile
* @param visible
* @return
*/
- public String printGFFFormat(SequenceI[] seqs, Hashtable visible)
+ public String printGFFFormat(SequenceI[] seqs, Map visible)
{
return printGFFFormat(seqs, visible, true, true);
}
- public String printGFFFormat(SequenceI[] seqs, Hashtable visible,
+ public String printGFFFormat(SequenceI[] seqs, Map visible,
boolean visOnly, boolean nonpos)
{
StringBuffer out = new StringBuffer();
diff --git a/src/jalview/io/HTMLOutput.java b/src/jalview/io/HTMLOutput.java
index ac7f5b3..af5fc03 100755
--- a/src/jalview/io/HTMLOutput.java
+++ b/src/jalview/io/HTMLOutput.java
@@ -34,7 +34,7 @@ public class HTMLOutput
SequenceRenderer sr;
- FeatureRenderer fr;
+ jalview.renderer.seqfeatures.FeatureRenderer fr;
Color color;
diff --git a/src/jalview/io/SequenceAnnotationReport.java b/src/jalview/io/SequenceAnnotationReport.java
index 6fba9c6..1757239 100644
--- a/src/jalview/io/SequenceAnnotationReport.java
+++ b/src/jalview/io/SequenceAnnotationReport.java
@@ -22,6 +22,7 @@ package jalview.io;
import java.util.ArrayList;
import java.util.Hashtable;
+import java.util.List;
import java.util.Vector;
import jalview.datamodel.DBRefEntry;
@@ -54,30 +55,30 @@ public class SequenceAnnotationReport
* TODO refactor to Jalview 'utilities' somehow.
*/
public void appendFeatures(final StringBuffer tooltipText2, int rpos,
- SequenceFeature[] features)
+ List features)
{
appendFeatures(tooltipText2, rpos, features, null);
}
public void appendFeatures(final StringBuffer tooltipText2, int rpos,
- SequenceFeature[] features, Hashtable minmax)
+ List features, Hashtable minmax)
{
String tmpString;
if (features != null)
{
- for (int i = 0; i < features.length; i++)
+ for (SequenceFeature feature:features)
{
- if (features[i].getType().equals("disulfide bond"))
+ if (feature.getType().equals("disulfide bond"))
{
- if (features[i].getBegin() == rpos
- || features[i].getEnd() == rpos)
+ if (feature.getBegin() == rpos
+ || feature.getEnd() == rpos)
{
if (tooltipText2.length() > 6)
{
tooltipText2.append("
");
}
- tooltipText2.append("disulfide bond " + features[i].getBegin()
- + ":" + features[i].getEnd());
+ tooltipText2.append("disulfide bond " + feature.getBegin()
+ + ":" + feature.getEnd());
}
}
else
@@ -87,25 +88,25 @@ public class SequenceAnnotationReport
tooltipText2.append("
");
}
// TODO: remove this hack to display link only features
- boolean linkOnly = features[i].getValue("linkonly") != null;
+ boolean linkOnly = feature.getValue("linkonly") != null;
if (!linkOnly)
{
- tooltipText2.append(features[i].getType() + " ");
+ tooltipText2.append(feature.getType() + " ");
if (rpos != 0)
{
// we are marking a positional feature
- tooltipText2.append(features[i].begin);
+ tooltipText2.append(feature.begin);
}
- if (features[i].begin != features[i].end)
+ if (feature.begin != feature.end)
{
- tooltipText2.append(" " + features[i].end);
+ tooltipText2.append(" " + feature.end);
}
- if (features[i].getDescription() != null
- && !features[i].description.equals(features[i]
+ if (feature.getDescription() != null
+ && !feature.description.equals(feature
.getType()))
{
- tmpString = features[i].getDescription();
+ tmpString = feature.getDescription();
String tmp2up = tmpString.toUpperCase();
int startTag = tmp2up.indexOf("");
if (startTag > -1)
@@ -150,27 +151,27 @@ public class SequenceAnnotationReport
}
}
// check score should be shown
- if (features[i].getScore() != Float.NaN)
+ if (feature.getScore() != Float.NaN)
{
float[][] rng = (minmax == null) ? null : ((float[][]) minmax
- .get(features[i].getType()));
+ .get(feature.getType()));
if (rng != null && rng[0] != null && rng[0][0] != rng[0][1])
{
- tooltipText2.append(" Score=" + features[i].getScore());
+ tooltipText2.append(" Score=" + feature.getScore());
}
}
- if (features[i].getValue("status") != null)
+ if (feature.getValue("status") != null)
{
- String status = features[i].getValue("status").toString();
+ String status = feature.getValue("status").toString();
if (status.length() > 0)
{
- tooltipText2.append("; (" + features[i].getValue("status")
+ tooltipText2.append("; (" + feature.getValue("status")
+ ")");
}
}
}
}
- if (features[i].links != null)
+ if (feature.links != null)
{
if (linkImageURL != null)
{
@@ -178,7 +179,7 @@ public class SequenceAnnotationReport
}
else
{
- for (String urlstring : (Vector) features[i].links)
+ for (String urlstring : (Vector) feature.links)
{
try
{
@@ -364,7 +365,6 @@ public class SequenceAnnotationReport
// ADD NON POSITIONAL SEQUENCE INFO
SequenceFeature[] features = ds.getSequenceFeatures();
- SequenceFeature[] tfeat = new SequenceFeature[1];
if (showNpFeats && features != null)
{
for (int i = 0; i < features.length; i++)
@@ -372,7 +372,8 @@ public class SequenceAnnotationReport
if (features[i].begin == 0 && features[i].end == 0)
{
int sz = -tip.length();
- tfeat[0] = features[i];
+ List tfeat = new ArrayList();
+ tfeat.add(features[i]);
appendFeatures(tip, 0, tfeat, minmax);
sz += tip.length();
maxWidth = Math.max(maxWidth, sz);
diff --git a/src/jalview/renderer/seqfeatures/FeatureRenderer.java b/src/jalview/renderer/seqfeatures/FeatureRenderer.java
new file mode 100644
index 0000000..909ee10
--- /dev/null
+++ b/src/jalview/renderer/seqfeatures/FeatureRenderer.java
@@ -0,0 +1,435 @@
+package jalview.renderer.seqfeatures;
+
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.image.BufferedImage;
+
+public class FeatureRenderer extends
+ jalview.viewmodel.seqfeatures.FeatureRendererModel
+{
+
+ FontMetrics fm;
+
+ int charOffset;
+
+ boolean offscreenRender = false;
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param g
+ * DOCUMENT ME!
+ * @param seq
+ * DOCUMENT ME!
+ * @param sg
+ * DOCUMENT ME!
+ * @param start
+ * DOCUMENT ME!
+ * @param end
+ * DOCUMENT ME!
+ * @param x1
+ * DOCUMENT ME!
+ * @param y1
+ * DOCUMENT ME!
+ * @param width
+ * DOCUMENT ME!
+ * @param height
+ * DOCUMENT ME!
+ */
+ protected SequenceI lastSeq;
+
+ char s;
+
+ int i;
+
+ int av_charHeight, av_charWidth;
+
+ boolean av_validCharWidth, av_isShowSeqFeatureHeight;
+
+ protected void updateAvConfig()
+ {
+ av_charHeight = av.getCharHeight();
+ av_charWidth = av.getCharWidth();
+ av_validCharWidth = av.isValidCharWidth();
+ av_isShowSeqFeatureHeight = av.isShowSequenceFeaturesHeight();
+ }
+
+ void renderFeature(Graphics g, SequenceI seq, int fstart, int fend,
+ Color featureColour, int start, int end, int y1)
+ {
+ updateAvConfig();
+ if (((fstart <= end) && (fend >= start)))
+ {
+ if (fstart < start)
+ { // fix for if the feature we have starts before the sequence start,
+ fstart = start; // but the feature end is still valid!!
+ }
+
+ if (fend >= end)
+ {
+ fend = end;
+ }
+ int pady = (y1 + av_charHeight) - av_charHeight / 5;
+ for (i = fstart; i <= fend; i++)
+ {
+ s = seq.getCharAt(i);
+
+ if (jalview.util.Comparison.isGap(s))
+ {
+ continue;
+ }
+
+ g.setColor(featureColour);
+
+ g.fillRect((i - start) * av_charWidth, y1, av_charWidth,
+ av_charHeight);
+
+ if (offscreenRender || !av_validCharWidth)
+ {
+ continue;
+ }
+
+ g.setColor(Color.white);
+ charOffset = (av_charWidth - fm.charWidth(s)) / 2;
+ g.drawString(String.valueOf(s), charOffset
+ + (av_charWidth * (i - start)), pady);
+
+ }
+ }
+ }
+
+ void renderScoreFeature(Graphics g, SequenceI seq, int fstart, int fend,
+ Color featureColour, int start, int end, int y1, byte[] bs)
+ {
+ updateAvConfig();
+ if (((fstart <= end) && (fend >= start)))
+ {
+ if (fstart < start)
+ { // fix for if the feature we have starts before the sequence start,
+ fstart = start; // but the feature end is still valid!!
+ }
+
+ if (fend >= end)
+ {
+ fend = end;
+ }
+ int pady = (y1 + av_charHeight) - av_charHeight / 5;
+ int ystrt = 0, yend = av_charHeight;
+ if (bs[0] != 0)
+ {
+ // signed - zero is always middle of residue line.
+ if (bs[1] < 128)
+ {
+ yend = av_charHeight * (128 - bs[1]) / 512;
+ ystrt = av_charHeight - yend / 2;
+ }
+ else
+ {
+ ystrt = av_charHeight / 2;
+ yend = av_charHeight * (bs[1] - 128) / 512;
+ }
+ }
+ else
+ {
+ yend = av_charHeight * bs[1] / 255;
+ ystrt = av_charHeight - yend;
+
+ }
+ for (i = fstart; i <= fend; i++)
+ {
+ s = seq.getCharAt(i);
+
+ if (jalview.util.Comparison.isGap(s))
+ {
+ continue;
+ }
+
+ g.setColor(featureColour);
+ int x = (i - start) * av_charWidth;
+ g.drawRect(x, y1, av_charWidth, av_charHeight);
+ g.fillRect(x, y1 + ystrt, av_charWidth, yend);
+
+ if (offscreenRender || !av_validCharWidth)
+ {
+ continue;
+ }
+
+ g.setColor(Color.black);
+ charOffset = (av_charWidth - fm.charWidth(s)) / 2;
+ g.drawString(String.valueOf(s), charOffset
+ + (av_charWidth * (i - start)), pady);
+
+ }
+ }
+ }
+
+ BufferedImage offscreenImage;
+
+ public Color findFeatureColour(Color initialCol, SequenceI seq, int res)
+ {
+ return new Color(findFeatureColour(initialCol.getRGB(), seq, res));
+ }
+
+ /**
+ * This is used by the Molecule Viewer and Overview to get the accurate
+ * colourof the rendered sequence
+ */
+ public synchronized int findFeatureColour(int initialCol, final SequenceI seq,
+ int column)
+ {
+ if (!av.isShowSequenceFeatures())
+ {
+ return initialCol;
+ }
+
+ final SequenceI aseq = (seq.getDatasetSequence() != null) ? seq
+ .getDatasetSequence() : seq;
+ if (seq != lastSeq)
+ {
+ lastSeq = seq;
+ sequenceFeatures = aseq.getSequenceFeatures();
+ if (sequenceFeatures != null)
+ {
+ sfSize = sequenceFeatures.length;
+ }
+ }
+ else
+ {
+ if (sequenceFeatures != lastSeq.getSequenceFeatures())
+ {
+ sequenceFeatures = lastSeq.getSequenceFeatures();
+ if (sequenceFeatures != null)
+ {
+ sfSize = sequenceFeatures.length;
+ }
+ }
+ }
+
+ if (sequenceFeatures == null || sfSize == 0)
+ {
+ return initialCol;
+ }
+
+ if (jalview.util.Comparison.isGap(lastSeq.getCharAt(column)))
+ {
+ return Color.white.getRGB();
+ }
+
+ // Only bother making an offscreen image if transparency is applied
+ if (transparency != 1.0f && offscreenImage == null)
+ {
+ offscreenImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB);
+ }
+
+ currentColour = null;
+ // TODO: non-threadsafe - each rendering thread needs its own instance of
+ // the feature renderer - or this should be synchronized.
+ offscreenRender = true;
+
+ if (offscreenImage != null)
+ {
+ offscreenImage.setRGB(0, 0, initialCol);
+ drawSequence(offscreenImage.getGraphics(), lastSeq, column, column, 0);
+
+ return offscreenImage.getRGB(0, 0);
+ }
+ else
+ {
+ drawSequence(null, lastSeq, lastSeq.findPosition(column), -1, -1);
+
+ if (currentColour == null)
+ {
+ return initialCol;
+ }
+ else
+ {
+ return ((Integer) currentColour).intValue();
+ }
+ }
+
+ }
+
+ private volatile SequenceFeature[] sequenceFeatures;
+
+ int sfSize;
+
+ int sfindex;
+
+ int spos;
+
+ int epos;
+
+ public synchronized void drawSequence(Graphics g, final SequenceI seq,
+ int start, int end, int y1)
+ {
+ final SequenceI aseq = (seq.getDatasetSequence() != null) ? seq
+ .getDatasetSequence() : seq;
+ if (aseq.getSequenceFeatures() == null
+ || aseq.getSequenceFeatures().length == 0)
+ {
+ return;
+ }
+
+ if (g != null)
+ {
+ fm = g.getFontMetrics();
+ }
+
+ updateFeatures();
+
+ if (lastSeq == null || seq != lastSeq
+ || aseq.getSequenceFeatures() != sequenceFeatures)
+ {
+ lastSeq = seq;
+ sequenceFeatures = aseq.getSequenceFeatures();
+ }
+
+ if (transparency != 1 && g != null)
+ {
+ Graphics2D g2 = (Graphics2D) g;
+ g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
+ transparency));
+ }
+
+ if (!offscreenRender)
+ {
+ spos = lastSeq.findPosition(start);
+ epos = lastSeq.findPosition(end);
+ }
+
+ sfSize = sequenceFeatures.length;
+ String type;
+ for (int renderIndex = 0; renderIndex < renderOrder.length; renderIndex++)
+ {
+ type = renderOrder[renderIndex];
+
+ if (type == null || !showFeatureOfType(type))
+ {
+ continue;
+ }
+
+ // loop through all features in sequence to find
+ // current feature to render
+ for (sfindex = 0; sfindex < sfSize; sfindex++)
+ {
+ if (!sequenceFeatures[sfindex].type.equals(type))
+ {
+ continue;
+ }
+
+ if (featureGroups != null
+ && sequenceFeatures[sfindex].featureGroup != null
+ && sequenceFeatures[sfindex].featureGroup.length() != 0
+ && featureGroups
+ .containsKey(sequenceFeatures[sfindex].featureGroup)
+ && !((Boolean) featureGroups
+ .get(sequenceFeatures[sfindex].featureGroup))
+ .booleanValue())
+ {
+ continue;
+ }
+
+ if (!offscreenRender
+ && (sequenceFeatures[sfindex].getBegin() > epos || sequenceFeatures[sfindex]
+ .getEnd() < spos))
+ {
+ continue;
+ }
+
+ if (offscreenRender && offscreenImage == null)
+ {
+ if (sequenceFeatures[sfindex].begin <= start
+ && sequenceFeatures[sfindex].end >= start)
+ {
+ // this is passed out to the overview and other sequence renderers
+ // (e.g. molecule viewer) to get displayed colour for rendered
+ // sequence
+ currentColour = new Integer(
+ getColour(sequenceFeatures[sfindex]).getRGB());
+ // used to be retreived from av.featuresDisplayed
+ // currentColour = av.featuresDisplayed
+ // .get(sequenceFeatures[sfindex].type);
+
+ }
+ }
+ else if (sequenceFeatures[sfindex].type.equals("disulfide bond"))
+ {
+
+ renderFeature(g, seq,
+ seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
+ seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
+ getColour(sequenceFeatures[sfindex])
+ // new Color(((Integer) av.featuresDisplayed
+ // .get(sequenceFeatures[sfindex].type)).intValue())
+ , start, end, y1);
+ renderFeature(g, seq,
+ seq.findIndex(sequenceFeatures[sfindex].end) - 1,
+ seq.findIndex(sequenceFeatures[sfindex].end) - 1,
+ getColour(sequenceFeatures[sfindex])
+ // new Color(((Integer) av.featuresDisplayed
+ // .get(sequenceFeatures[sfindex].type)).intValue())
+ , start, end, y1);
+
+ }
+ else if (showFeature(sequenceFeatures[sfindex]))
+ {
+ if (av_isShowSeqFeatureHeight
+ && sequenceFeatures[sfindex].score != Float.NaN)
+ {
+ renderScoreFeature(g, seq,
+ seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
+ seq.findIndex(sequenceFeatures[sfindex].end) - 1,
+ getColour(sequenceFeatures[sfindex]), start, end, y1,
+ normaliseScore(sequenceFeatures[sfindex]));
+ }
+ else
+ {
+ renderFeature(g, seq,
+ seq.findIndex(sequenceFeatures[sfindex].begin) - 1,
+ seq.findIndex(sequenceFeatures[sfindex].end) - 1,
+ getColour(sequenceFeatures[sfindex]), start, end, y1);
+ }
+ }
+
+ }
+
+ }
+
+ if (transparency != 1.0f && g != null && transparencyAvailable)
+ {
+ Graphics2D g2 = (Graphics2D) g;
+ g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
+ 1.0f));
+ }
+ }
+
+ boolean transparencyAvailable = true;
+
+ protected void setTransparencyAvailable(boolean isTransparencyAvailable)
+ {
+ transparencyAvailable = isTransparencyAvailable;
+ }
+
+ @Override
+ public boolean isTransparencyAvailable()
+ {
+ return transparencyAvailable;
+ }
+
+ /**
+ * Called when alignment in associated view has new/modified features to
+ * discover and display.
+ *
+ */
+ public void featuresAdded()
+ {
+ lastSeq = null;
+ findAllFeatures();
+ }
+}
diff --git a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java
index a53004d..c3b6c1e 100644
--- a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java
+++ b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java
@@ -252,7 +252,7 @@ public abstract class FeatureRendererModel implements
{
for (int i = 0; i < features.length; i++)
{
- if (av.areFeaturesDisplayed()
+ if (!av.areFeaturesDisplayed()
|| !av.getFeaturesDisplayed().isVisible(
features[i].getType()))
{
diff --git a/src/jalview/ws/AWSThread.java b/src/jalview/ws/AWSThread.java
index 7ab1781..1fa4663 100644
--- a/src/jalview/ws/AWSThread.java
+++ b/src/jalview/ws/AWSThread.java
@@ -28,7 +28,7 @@ import jalview.datamodel.AlignmentView;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
import jalview.gui.WebserviceInfo;
-import jalview.gui.FeatureRenderer.FeatureRendererSettings;
+import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
public abstract class AWSThread extends Thread
{
--
1.7.10.2