<classpathentry kind="lib" path="lib/log4j-to-slf4j-2.0-rc2.jar"/>
<classpathentry kind="lib" path="lib/slf4j-log4j12-1.7.7.jar"/>
<classpathentry kind="lib" path="lib/VARNAv3-91.jar"/>
- <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin.jar"/>
<classpathentry kind="lib" path="lib/xml-apis.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Plugin.jar"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/plugin"/>
<classpathentry kind="lib" path="lib/jfreesvg-2.1.jar"/>
<classpathentry kind="output" path="classes"/>
</classpath>
StructureMapping[] mapping = ssm.getMapping(pdbentry.getFile());
boolean showFeatures = false;
- if (ap.av.getShowSequenceFeatures())
+ if (ap.av.isShowSequenceFeatures())
{
if (fr == null)
{
boolean seqColoursReady = false;
- jalview.gui.FeatureRenderer fr;
+ jalview.renderer.seqfeatures.FeatureRenderer fr;
Color backgroundColour = Color.black;
StructureMapping[] mapping = ssm.getMapping(pdbentry.getFile());
boolean showFeatures = false;
- if (ap.av.getShowSequenceFeatures())
+ if (ap.av.isShowSequenceFeatures())
{
if (fr == null)
{
int[][] cons2;
+ private String[] consSymbs;
+
/**
* Creates a new Conservation object.
*
{
consString.append('-');
}
-
+ consSymbs = new String[end-start+1];
for (int i = start; i <= end; i++)
{
gapcons = countConsNGaps(i);
totGaps = gapcons[1];
pgaps = ((float) totGaps * 100) / (float) sequences.length;
-
+ consSymbs[i-start]=new String();
+
if (percentageGaps > pgaps)
{
resultHash = total[i - start];
-
// Now find the verdict
count = 0;
enumeration = resultHash.keys();
{
type = (String) enumeration.nextElement();
result = (Integer) resultHash.get(type);
-
// Do we want to count +ve conservation or +ve and -ve cons.?
if (consflag)
{
if (result.intValue() == 1)
{
+ consSymbs[i-start] = type+" "+consSymbs[i-start];
count++;
}
}
{
if (result.intValue() != -1)
{
+ {
+ if (result.intValue()==0) {
+ consSymbs[i-start] = consSymbs[i-start]+ " !"+type;
+ } else {
+ consSymbs[i-start] = type+" "+consSymbs[i-start];
+ }
+ }
+
count++;
}
}
float vprop = value - min;
vprop /= max;
conservation.annotations[i] = new Annotation(String.valueOf(c),
- String.valueOf(value), ' ', value, new Color(minR
+ consSymbs[i-start], ' ', value, new Color(minR
+ (maxR * vprop), minG + (maxG * vprop), minB
+ (maxB * vprop)));
{
continue;
}
-
+// if invalid string used, then regex has no matched to/from
int sres = seq
.findPosition(resIndex
+ Integer.parseInt(spaces.elementAt(resIndex)
*/
package jalview.analysis;
-import java.util.*;
-
import jalview.api.analysis.ScoreModelI;
-import jalview.datamodel.*;
-import jalview.io.*;
-import jalview.schemes.*;
-import jalview.util.*;
+import jalview.datamodel.AlignmentView;
+import jalview.datamodel.BinaryNode;
+import jalview.datamodel.CigarArray;
+import jalview.datamodel.NodeTransformI;
+import jalview.datamodel.SeqCigar;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.SequenceNode;
+import jalview.io.NewickFile;
+import jalview.schemes.ResidueProperties;
+
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Vector;
/**
* DOCUMENT ME!
* DOCUMENT ME!
*/
public NJTree(SequenceI[] sequence, AlignmentView seqData, String type,
- String pwtype, int start, int end)
+ String pwtype, ScoreModelI sm, int start, int end)
{
this.sequence = sequence;
this.node = new Vector();
type = "AV";
}
- if (!(pwtype.equals("PID")))
+ if (sm == null && !(pwtype.equals("PID")))
{
if (ResidueProperties.getScoreMatrix(pwtype) == null)
{
noseqs = i++;
- distance = findDistances();
+ distance = findDistances(sm);
// System.err.println("Made distances");// dbg
makeLeaves();
// System.err.println("Made leaves");// dbg
for (int j = 0; j < seqs.length; j++)
{
- seqs[j] = (SequenceI) list.get(j);
+ seqs[j] = list.get(j);
}
seqmatcher = new SequenceIdMatcher(seqs);
*
* @return similarity matrix used to compute tree
*/
- public float[][] findDistances()
+ public float[][] findDistances(ScoreModelI _pwmatrix)
{
float[][] distance = new float[noseqs][noseqs];
-
- // Pairwise substitution score (with no gap penalties)
- ScoreModelI _pwmatrix = ResidueProperties.getScoreModel(pwtype);
if (_pwmatrix == null)
{
- _pwmatrix = ResidueProperties.getScoreMatrix("BLOSUM62");
+ // Resolve substitution model
+ _pwmatrix = ResidueProperties.getScoreModel(pwtype);
+ if (_pwmatrix == null)
+ {
+ _pwmatrix = ResidueProperties.getScoreMatrix("BLOSUM62");
+ }
}
distance = _pwmatrix.findDistances(seqData);
return distance;
{
System.out
.println("Leaf = " + ((SequenceI) node.element()).getName());
- System.out.println("Dist " + ((SequenceNode) node).dist);
+ System.out.println("Dist " + node.dist);
System.out.println("Boot " + node.getBootstrap());
}
else
{
- System.out.println("Dist " + ((SequenceNode) node).dist);
+ System.out.println("Dist " + node.dist);
printNode((SequenceNode) node.left());
printNode((SequenceNode) node.right());
}
if ((node.left() == null) && (node.right() == null))
{
- float dist = ((SequenceNode) node).dist;
+ float dist = node.dist;
if (dist > maxDistValue)
{
- maxdist = (SequenceNode) node;
+ maxdist = node;
maxDistValue = dist;
}
}
+ ((SequenceI) node.element()).getName());
}
- System.out.println(" dist = " + ((SequenceNode) node).dist + " "
- + ((SequenceNode) node).count + " "
- + ((SequenceNode) node).height);
+ System.out.println(" dist = " + node.dist + " "
+ + node.count + " "
+ + node.height);
}
/**
SequenceNode l = (SequenceNode) node.left();
SequenceNode r = (SequenceNode) node.right();
- ((SequenceNode) node).count = l.count + r.count;
- ((SequenceNode) node).ycount = (l.ycount + r.ycount) / 2;
+ node.count = l.count + r.count;
+ node.ycount = (l.ycount + r.ycount) / 2;
}
else
{
- ((SequenceNode) node).count = 1;
- ((SequenceNode) node).ycount = ycount++;
+ node.count = 1;
+ node.ycount = ycount++;
}
_lycount--;
}
{
for (Enumeration nodes = node.elements(); nodes.hasMoreElements(); nodeTransformI
.transform((BinaryNode) nodes.nextElement()))
+ {
;
+ }
}
}
// TODO: deal with ID collisions - SequenceI should be appended to list
// associated with this key.
names.put(new SeqIdName(seqs[i].getDisplayId(true)), seqs[i]);
+ SequenceI dbseq = seqs[i];
+ while (dbseq.getDatasetSequence()!=null)
+ {
+ dbseq = dbseq.getDatasetSequence();
+ }
// add in any interesting identifiers
- if (seqs[i].getDBRef() != null)
+ if (dbseq.getDBRef() != null)
{
- DBRefEntry dbr[] = seqs[i].getDBRef();
+ DBRefEntry dbr[] = dbseq.getDBRef();
SeqIdName sid = null;
for (int r = 0; r < dbr.length; r++)
{
--- /dev/null
+package jalview.analysis.scoremodels;
+
+import jalview.api.analysis.ScoreModelI;
+import jalview.api.analysis.ViewBasedAnalysisI;
+import jalview.datamodel.AlignmentView;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.util.Comparison;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.List;
+
+public class FeatureScoreModel implements ScoreModelI, ViewBasedAnalysisI
+{
+ jalview.api.FeatureRenderer fr;
+
+ @Override
+ public boolean configureFromAlignmentView(
+ jalview.api.AlignmentViewPanel view)
+ {
+ fr = view.cloneFeatureRenderer();
+ return true;
+ }
+
+ @Override
+ public float[][] findDistances(AlignmentView seqData)
+ {
+ int nofeats = 0;
+ List<String> dft = Arrays.asList(fr.getDisplayedFeatureTypes());
+
+ if (dft != null)
+ {
+ nofeats = dft.size();
+ }
+
+ SequenceI[] sequenceString = seqData.getVisibleAlignment(
+ Comparison.GapChars.charAt(0)).getSequencesArray();
+ int noseqs = sequenceString.length;
+ int cpwidth = seqData.getWidth();
+ float[][] distance = new float[noseqs][noseqs];
+ if (nofeats == 0)
+ {
+ for (float[] d : distance)
+ {
+ for (int i = 0; i < d.length; d[i++] = 0f)
+ {
+ ;
+ }
+ }
+ return distance;
+ }
+ float max = 0;
+ for (int cpos = 0; cpos < cpwidth; cpos++)
+ {
+ // get visible features at cpos under view's display settings and compare
+ // them
+ List<Hashtable<String, SequenceFeature>> sfap = new ArrayList<Hashtable<String, SequenceFeature>>();
+ for (int i = 0; i < noseqs; i++)
+ {
+ Hashtable<String, SequenceFeature> types = new Hashtable<String, SequenceFeature>();
+ List<SequenceFeature> sfs = fr.findFeaturesAtRes(sequenceString[i],
+ sequenceString[i].findPosition(cpos));
+ for (SequenceFeature sf : sfs)
+ {
+ types.put(sf.getType(), sf);
+ }
+ sfap.add(types);
+ }
+ for (int i = 0; i < (noseqs - 1); i++)
+ {
+ if (cpos == 0)
+ {
+ distance[i][i] = 0f;
+ }
+ for (int j = i + 1; j < noseqs; j++)
+ {
+ int sfcommon = 0;
+ // compare the two lists of features...
+ Hashtable<String, SequenceFeature> fi = sfap.get(i), fk, fj = sfap
+ .get(j);
+ if (fi.size() > fj.size())
+ {
+ fk = fj;
+ }
+ else
+ {
+ fk = fi;
+ fi = fj;
+ }
+ for (String k : fi.keySet())
+ {
+ SequenceFeature sfj = fk.get(k);
+ if (sfj != null)
+ {
+ sfcommon++;
+ }
+ }
+ distance[i][j] += (fi.size() + fk.size() - 2f * sfcommon);
+ distance[j][i] += distance[i][j];
+ }
+ }
+ }
+ for (int i = 0; i < noseqs; i++)
+ {
+ for (int j = i + 1; j < noseqs; j++)
+ {
+ distance[i][j] /= cpwidth;
+ distance[j][i] = distance[i][j];
+ }
+ }
+ return distance;
+ }
+
+ @Override
+ public String getName()
+ {
+ return "Sequence Feature Similarity";
+ }
+
+ @Override
+ public boolean isDNA()
+ {
+ return true;
+ }
+
+ @Override
+ public boolean isProtein()
+ {
+ return true;
+ }
+
+ public String toString()
+ {
+ return "Score between sequences based on hamming distance between binary vectors marking features displayed at each column";
+ }
+}
*/
package jalview.api;
+import jalview.commands.CommandI;
+
/**
* Interface implemented by gui implementations managing a Jalview Alignment
* View
*/
void setStatus(String string);
+ void addHistoryItem(CommandI command);
+
}
boolean markColumnsContainingFeatures(boolean invert,
boolean extendCurrent, boolean clearColumns, String featureType);
+ /**
+ * sort the alignment or current selection by average score over the given set of features
+ * @param typ list of feature names or null to use currently displayed features
+ */
+ void sortAlignmentByFeatureScore(String[] typ);
+
+ /**
+ * sort the alignment or current selection by distribution of the given set of features
+ * @param typ list of feature names or null to use currently displayed features
+ */
+ void sortAlignmentByFeatureDensity(String[] typ);
+
}
List<AlignmentAnnotation> getVisibleAlignmentAnnotation(
boolean selectedOnly);
+ FeaturesDisplayedI getFeaturesDisplayed();
+
+ String getSequenceSetId();
+
+ boolean isShowSequenceFeatures();
+
+ void setShowSequenceFeatures(boolean b);
+
}
*/
void adjustAnnotationHeight();
+ FeatureRenderer getFeatureRenderer();
+
+ FeatureRenderer cloneFeatureRenderer();
+
/**
*
* @return displayed name for the view
*/
package jalview.api;
+import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import java.awt.Color;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
/**
* Abstract feature renderer interface
void featuresAdded();
+ Object getFeatureStyle(String ft);
+
+ void setColour(String ft, Object ggc);
+
+ AlignViewportI getViewport();
+
+ FeaturesDisplayedI getFeaturesDisplayed();
+
+ Map<String,Object> getFeatureColours();
+
+ void findAllFeatures(boolean newMadeVisible);
+
+ Map<String,Object> getDisplayedFeatureCols();
+
+ List<String> getFeatureGroups();
+
+ List<String> getGroups(boolean visible);
+
+ void setGroupVisibility(List<String> toset, boolean visible);
+
+ void setGroupVisibility(String group, boolean visible);
+
+ List<SequenceFeature> findFeaturesAtRes(SequenceI sequence, int res);
+
+ boolean isTransparencyAvailable();
+
+ String[] getDisplayedFeatureTypes();
+
+ String[] getDisplayedFeatureGroups();
+
+ void setAllVisible(List<String> featureTypes);
+
+ void setVisible(String featureType);
+
}
--- /dev/null
+package jalview.api;
+
+public interface FeatureSettingsControllerI
+{
+
+}
--- /dev/null
+package jalview.api;
+
+public interface FeatureSettingsModelI
+{
+
+}
--- /dev/null
+package jalview.api;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+public interface FeaturesDisplayedI
+{
+
+ Iterator<String> getVisibleFeatures();
+
+ boolean isVisible(String featureType);
+
+ boolean areVisible(Collection<String> featureTypes);
+
+ void clear();
+
+ void setVisible(String featureType);
+
+ void setAllVisible(Collection<String> featureTypes);
+
+ boolean isRegistered(String type);
+
+ void setAllRegisteredVisible();
+
+ int getVisibleFeatureCount();
+
+ int getRegisterdFeaturesCount();
+
+}
--- /dev/null
+package jalview.api.analysis;
+
+import jalview.api.AlignViewportI;
+import jalview.api.AlignmentViewPanel;
+
+public interface ViewBasedAnalysisI
+{
+
+ /**
+ * Parameterise the analysis model using the current view
+ * @param view
+ * @return true if model is applicable and calculation should proceed
+ */
+
+ boolean configureFromAlignmentView(AlignmentViewPanel view);
+
+}
features, true, ap))
{
ap.alignFrame.sequenceFeatures.setState(true);
- ap.av.showSequenceFeatures(true);
+ ap.av.setShowSequenceFeatures(true);;
ap.highlightSearchResults(null);
}
}
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("</p>");
}
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;
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;
{
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)
}
if (autoenabledisplay)
{
- viewport.showSequenceFeatures = true;
+ 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();
}
else if (evt.getSource() == sequenceFeatures)
{
- viewport.showSequenceFeatures(sequenceFeatures.getState());
+ viewport.setShowSequenceFeatures(sequenceFeatures.getState());
alignPanel.seqPanel.seqCanvas.repaint();
}
else if (evt.getSource() == conservationMenuItem)
return annotation;
}
- private Hashtable getDisplayedFeatureCols()
+ private Map<String,Object> 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;
}
/**
* TODO: JAL-1104
*/
+ @Override
public void addHistoryItem(CommandI command)
{
if (command.getSize() > 0)
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;
}
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;
}
{
FeatureRenderer fr = null;
this.sequenceFeatures.setState(true);
- viewport.showSequenceFeatures(true);
+ viewport.setShowSequenceFeatures(true);
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)
{
boolean renderGaps = true;
- boolean showSequenceFeatures = false;
-
boolean showAnnotation = true;
boolean upperCasebold = false;
boolean scaleRightWrapped = true;
- // The following vector holds the features which are
- // currently visible, in the correct order or rendering
- public Hashtable featuresDisplayed;
-
boolean showHiddenMarkers = true;
public jalview.bin.JalviewLite applet;
}
- public void showSequenceFeatures(boolean b)
- {
- showSequenceFeatures = b;
- }
-
- public boolean getShowSequenceFeatures()
- {
- return showSequenceFeatures;
- }
-
/**
* get the consensus sequence as displayed under the PID consensus annotation
* row.
{
return seqPanel.seqCanvas.sr;
}
-
- public FeatureRenderer getFeatureRenderer()
+ @Override
+ public jalview.api.FeatureRenderer getFeatureRenderer()
{
return seqPanel.seqCanvas.fr;
}
-
+ @Override
+ public jalview.api.FeatureRenderer cloneFeatureRenderer()
+ {
+ FeatureRenderer nfr = new FeatureRenderer(av);
+ nfr.transferSettings(seqPanel.seqCanvas.fr);
+ return nfr;
+ }
public void alignmentChanged()
{
av.alignmentChanged(this);
else if (evt.getSource() == seqColour)
{
setEnabled(seqColour);
- jmb.colourBySequence(ap.av.getShowSequenceFeatures(), ap);
+ jmb.colourBySequence(ap.av.isShowSequenceFeatures(), ap);
}
else if (!allChainsSelected)
centerViewer();
public void updateColours(Object source)
{
AlignmentPanel ap = (AlignmentPanel) source;
- jmb.colourBySequence(ap.av.getShowSequenceFeatures(), ap);
+ jmb.colourBySequence(ap.av.isShowSequenceFeatures(), ap);
}
public void updateTitleAndMenus()
return;
}
setChainMenuItems(jmb.chainNames);
- jmb.colourBySequence(ap.av.getShowSequenceFeatures(), ap);
+ jmb.colourBySequence(ap.av.isShowSequenceFeatures(), ap);
setTitle(jmb.getViewerTitle());
}
AlignmentViewPanel alignment)
{
AlignmentPanel ap = (AlignmentPanel) alignment;
- if (appletJmolBinding.ap.av.showSequenceFeatures)
+ if (appletJmolBinding.ap.av.isShowSequenceFeatures())
{
if (appletJmolBinding.fr == null)
{
public void updateColours(Object source)
{
AlignmentPanel ap = (AlignmentPanel) source;
- colourBySequence(ap.av.getShowSequenceFeatures(), ap);
+ colourBySequence(ap.av.isShowSequenceFeatures(), ap);
}
public void showUrl(String url)
public FeatureRenderer getFeatureRenderer(AlignmentViewPanel alignment)
{
AlignmentPanel ap = (AlignmentPanel) alignment;
- if (ap.av.showSequenceFeatures)
+ if (ap.av.isShowSequenceFeatures())
{
return ap.getFeatureRenderer();
}
{
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);
{
// cancel
reset();
- PaintRefresher.Refresh(this, fr.av.getSequenceSetId());
+ PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
frame.setVisible(false);
}
}
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);
}
}
}
- 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);
}
}
else
{
- PaintRefresher.Refresh(this, fr.av.getSequenceSetId());
+ PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
}
// ap.paintAlignment(true);
}
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!
* @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.
*
*/
public FeatureRenderer(AlignViewport av)
{
+ super();
this.av = av;
- if (!System.getProperty("java.version").startsWith("1.1"))
- {
- transparencySetter = new TransparencySetter();
- }
- }
-
- public void transferSettings(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);
- }
- }
- }
+ setTransparencyAvailable(!System.getProperty("java.version").startsWith("1.1"));
}
static String lastFeatureAdded;
}
ffile.parseDescriptionHTML(sf, false);
+ setVisible(lastFeatureAdded); // if user edited name then make sure new type is visible
}
if (deleteFeature)
{
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
{
}
}
// 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();
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(MessageManager.formatMessage("error.implementation_error_unrecognised_render_object_for_features_type", new String[]{fc.getClass().getCanonicalName(),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<String> hiddenGroups = new ArrayList<String>();
-
- /**
- * 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<String>();
- 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));
- }
}
package jalview.appletgui;
import java.util.*;
-
+import java.util.List;
import java.awt.*;
import java.awt.event.*;
ScrollPane scrollPane;
- boolean alignmentHasFeatures = false;
-
Image linkImage;
Scrollbar transparency;
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);
}
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();
this.setLayout(new BorderLayout());
scrollPane = new ScrollPane();
scrollPane.add(featurePanel);
- if (alignmentHasFeatures)
+ if (fr.getAllFeatureColours()!=null && fr.getAllFeatureColours().size()>0)
{
add(scrollPane, BorderLayout.CENTER);
}
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);
{
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);
public void actionPerformed(ActionEvent e)
{
- me.sortByScore(new String[]
+ me.ap.alignFrame.avc.sortAlignmentByFeatureScore(new String[]
{ type });
}
public void actionPerformed(ActionEvent e)
{
- me.sortByDens(new String[]
+ me.ap.alignFrame.avc.sortAlignmentByFeatureDensity(new String[]
{ type });
}
public void setTableData()
{
- alignmentHasFeatures = fr.buildGroupHash();
- if (alignmentHasFeatures)
+ if (fr.getAllFeatureColours()!=null && fr.getAllFeatureColours().size()>0)
{
rebuildGroups();
}
// 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<String>)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)
groupPanel.validate();
}
}
-
// This routine adds and removes checkboxes depending on
// Group selection states
void resetTable(boolean groupsChanged)
{
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))
}
}
- 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<String> 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))
{
if (addCheck)
{
boolean selected = false;
- if (groupsChanged || av.featuresDisplayed.containsKey(type))
+ if (groupsChanged || av.getFeaturesDisplayed().isVisible(type))
{
selected = true;
}
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();
}
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))
{
public void adjustmentValueChanged(AdjustmentEvent evt)
{
- fr.transparency = ((float) (100 - transparency.getValue()) / 100f);
+ fr.setTransparency((float) (100 - transparency.getValue()) / 100f);
ap.seqPanel.seqCanvas.repaint();
}
}
}
- 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);
- }
-
}
features, true, ap))
{
ap.alignFrame.sequenceFeatures.setState(true);
- av.showSequenceFeatures(true);
+ av.setShowSequenceFeatures(true);
ap.highlightSearchResults(null);
}
}
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()
return;
}
- if (av.showSequenceFeatures)
+ 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;
int alwidth = av.getAlignment().getWidth();
int alheight = av.getAlignment().getHeight();
- if (av.showSequenceFeatures)
+ if (av.isShowSequenceFeatures())
{
fr.transferSettings(ap.seqPanel.seqCanvas.getFeatureRenderer());
}
{
color = sr.getResidueBoxColour(seq, lastcol);
- if (av.showSequenceFeatures)
+ if (av.isShowSequenceFeatures())
{
color = fr.findFeatureColour(color, seq, lastcol);
}
sr.drawSequence(nextSeq, av.getAlignment().findAllGroups(nextSeq),
startRes, endRes, offset + ((i - startSeq) * av.charHeight));
- if (av.showSequenceFeatures)
+ if (av.isShowSequenceFeatures())
{
fr.drawSequence(g, nextSeq, startRes, endRes, offset
+ ((i - startSeq) * av.charHeight));
{
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;
}
*/
package jalview.appletgui;
-import java.awt.*;
-import java.awt.event.*;
-
-import jalview.analysis.*;
-import jalview.datamodel.*;
-import jalview.io.*;
+import jalview.analysis.NJTree;
+import jalview.api.analysis.ScoreModelI;
+import jalview.api.analysis.ViewBasedAnalysisI;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentView;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.SequenceI;
+import jalview.io.NewickFile;
+import jalview.schemes.ResidueProperties;
import jalview.util.MessageManager;
+import java.awt.BorderLayout;
+import java.awt.CheckboxMenuItem;
+import java.awt.Color;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuItem;
+import java.awt.ScrollPane;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+
public class TreePanel extends EmbmenuFrame implements ActionListener,
ItemListener
{
{
int start, end;
SequenceI[] seqs;
- boolean selview = (av.getSelectionGroup() != null)
- && (av.getSelectionGroup().getSize() > 1);
+ boolean selview = av.getSelectionGroup() != null
+ && av.getSelectionGroup().getSize() > 1;
AlignmentView seqStrings = av.getAlignmentView(selview);
if (!selview)
{
seqs = av.getSelectionGroup().getSequencesInOrder(
av.getAlignment());
}
-
- tree = new NJTree(seqs, seqStrings, type, pwtype, start, end);
+ ScoreModelI sm = ResidueProperties.getScoreModel(pwtype);
+ if (sm instanceof ViewBasedAnalysisI)
+ {
+ try
+ {
+ sm = sm.getClass().newInstance();
+ ((ViewBasedAnalysisI) sm)
+ .configureFromAlignmentView(treeCanvas.ap);
+ } catch (Exception q)
+ {
+ System.err.println("Couldn't create a scoremodel instance for "
+ + sm.getName());
+ q.printStackTrace();
+ }
+ tree = new NJTree(seqs, seqStrings, type, pwtype, sm, start, end);
+ }
+ else
+ {
+ tree = new NJTree(seqs, seqStrings, type, pwtype, null, start,
+ end);
+ }
}
tree.reCount(tree.getTopNode());
param = applet.getParameter("showFeatureSettings");
if (param != null && param.equalsIgnoreCase("true"))
{
- newAlignFrame.viewport.showSequenceFeatures(true);
+ newAlignFrame.viewport.setShowSequenceFeatures(true);
new FeatureSettings(newAlignFrame.alignPanel);
}
package jalview.controller;
import java.awt.Color;
+import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;
+import jalview.analysis.AlignmentSorter;
import jalview.api.AlignViewControllerGuiI;
import jalview.api.AlignViewControllerI;
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
+import jalview.api.FeatureRenderer;
+import jalview.commands.OrderCommand;
import jalview.datamodel.AlignmentI;
-import jalview.datamodel.AnnotatedCollectionI;
import jalview.datamodel.ColumnSelection;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceFeature;
return false;
}
}
+
+ @Override
+ public void sortAlignmentByFeatureDensity(String[] typ)
+ {
+ sortBy(typ, "Sort by Density", AlignmentSorter.FEATURE_DENSITY);
+ }
+
+ protected void sortBy(String[] typ, String methodText, final String method)
+ {
+ FeatureRenderer fr = alignPanel.getFeatureRenderer();
+ if (typ == null)
+ {
+ typ = fr==null ? null : fr.getDisplayedFeatureTypes();
+ }
+ String gps[] = null;
+ gps = fr==null ? null : fr.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);
+ }
+ AlignmentI al = viewport.getAlignment();
+
+ int start, stop;
+ SequenceGroup sg = viewport.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);
+ avcg.addHistoryItem(new OrderCommand(methodText, oldOrder, viewport
+ .getAlignment()));
+ alignPanel.paintAlignment(true);
+
+ }
+
+ @Override
+ public void sortAlignmentByFeatureScore(String[] typ)
+ {
+ sortBy(typ, "Sort by Feature Score", AlignmentSorter.FEATURE_SCORE);
+ }
}
--- /dev/null
+package jalview.controller;
+
+import jalview.api.FeatureRenderer;
+import jalview.api.FeatureSettingsModelI;
+
+public class FeatureSettingsController implements jalview.api.FeatureSettingsControllerI
+{
+ FeatureSettingsControllerGuiI settingUI;
+ FeatureRenderer fr;
+ FeatureSettingsModelI fsettings;
+
+}
--- /dev/null
+package jalview.controller;
+
+public interface FeatureSettingsControllerGuiI
+{
+
+}
setColourSelected(ColourSchemeProperty.getColourName(av
.getGlobalColourScheme()));
- showSeqFeatures.setSelected(av.showSequenceFeatures);
+ showSeqFeatures.setSelected(av.isShowSequenceFeatures());
hiddenMarkers.setState(av.showHiddenMarkers);
applyToAllGroups.setState(av.getColourAppliesToAllGroups());
showNpFeatsMenuitem.setSelected(av.isShowNpFeats());
{
viewport.setShowSequenceFeaturesHeight(showSeqFeaturesHeight
.isSelected());
- if (viewport.getShowSequenceFeaturesHeight())
+ if (viewport.isShowSequenceFeaturesHeight())
{
// ensure we're actually displaying features
viewport.setShowSequenceFeatures(true);
{
featuresFile = new FeaturesFile(file, type).parse(viewport
.getAlignment().getDataset(), alignPanel.getSeqPanel().seqCanvas
- .getFeatureRenderer().featureColours, false,
+ .getFeatureRenderer().getFeatureColours(), false,
jalview.bin.Cache.getDefault("RELAXEDSEQIDMATCHING", false));
} catch (Exception ex)
{
if (featuresFile)
{
- viewport.showSequenceFeatures = true;
+ viewport.setShowSequenceFeatures(true);
showSeqFeatures.setSelected(true);
if (alignPanel.getSeqPanel().seqCanvas.fr != null)
{
boolean renderGaps = true;
- boolean showSequenceFeatures = false;
-
- private boolean showAnnotation = true;
-
SequenceAnnotationOrder sortAnnotationsBy = null;
int charHeight;
boolean cursorMode = false;
- /**
- * Keys are the feature types which are currently visible. Note: Values are
- * not used!
- */
- private Hashtable featuresDisplayed = null;
-
boolean antiAlias = false;
Rectangle explodedPosition;
Color textColour = Color.black;
Color textColour2 = Color.white;
-
- private boolean rightAlignIds = false;
-
/**
* Creates a new AlignViewport object.
*
}
/**
- * set the flag
- *
- * @param b
- * features are displayed if true
- */
- public void setShowSequenceFeatures(boolean b)
- {
- showSequenceFeatures = b;
- }
-
- public boolean getShowSequenceFeatures()
- {
- return showSequenceFeatures;
- }
-
- /**
* centre columnar annotation labels in displayed alignment annotation TODO:
* add to jalviewXML and annotation display settings
*/
*
* @return DOCUMENT ME!
*/
- public boolean getShowAnnotation()
- {
- return isShowAnnotation();
- }
-
- /**
- * DOCUMENT ME!
- *
- * @param b
- * DOCUMENT ME!
- */
- public void setShowAnnotation(boolean b)
- {
- showAnnotation = b;
- }
-
- /**
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
public boolean getScaleAboveWrapped()
{
return scaleAboveWrapped;
return followSelection;
}
- boolean showSeqFeaturesHeight;
-
public void sendSelection()
{
jalview.structure.StructureSelectionManager
new ColumnSelection(getColumnSelection()), this);
}
- public void setShowSequenceFeaturesHeight(boolean selected)
- {
- showSeqFeaturesHeight = selected;
- }
-
- public boolean getShowSequenceFeaturesHeight()
- {
- return showSeqFeaturesHeight;
- }
-
/**
* return the alignPanel containing the given viewport. Use this to get the
* components currently handling the given viewport.
}
}
-
- public Hashtable getFeaturesDisplayed()
- {
- return featuresDisplayed;
- }
-
- public void setFeaturesDisplayed(Hashtable featuresDisplayed)
- {
- this.featuresDisplayed = featuresDisplayed;
- }
protected SequenceAnnotationOrder getSortAnnotationsBy()
{
return sortAnnotationsBy;
{
this.showAutocalculatedAbove = showAutocalculatedAbove;
}
-
- public boolean isShowAnnotation()
- {
- return showAnnotation;
- }
-
- public boolean isRightAlignIds()
- {
- return rightAlignIds;
- }
-
- public void setRightAlignIds(boolean rightAlignIds)
- {
- this.rightAlignIds = rightAlignIds;
- }
}
new OOMWarning(string, error, this);
}
- public FeatureRenderer cloneFeatureRenderer()
+ @Override
+ public jalview.api.FeatureRenderer cloneFeatureRenderer()
{
return new FeatureRenderer(this);
}
-
- public void updateFeatureRenderer(FeatureRenderer fr)
+ @Override
+ public jalview.api.FeatureRenderer getFeatureRenderer()
+ {
+ return seqPanel.seqCanvas.getFeatureRenderer();
+ }
+ public void updateFeatureRenderer(jalview.renderer.seqfeatures.FeatureRenderer fr)
{
fr.transferSettings(getSeqPanel().seqCanvas.getFeatureRenderer());
}
- public void updateFeatureRendererFrom(FeatureRenderer fr)
+ public void updateFeatureRendererFrom(jalview.api.FeatureRenderer fr)
{
if (getSeqPanel().seqCanvas.getFeatureRenderer() != null)
{
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
-import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
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
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)
close_actionPerformed(null);
}
-
- private Hashtable getDisplayedFeatureCols()
- {
- Hashtable fcols = new Hashtable();
- if (ap.av.getFeaturesDisplayed() == null)
- {
- return fcols;
- }
-
- Enumeration en = ap.av.getFeaturesDisplayed().keys();
- FeatureRenderer fr = ap.getSeqPanel().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
// Set the colour using the current view for the associated alignframe
for (AlignmentPanel ap : _colourwith)
{
- jmb.colourBySequence(ap.av.showSequenceFeatures, ap);
+ jmb.colourBySequence(ap.av.isShowSequenceFeatures(), ap);
}
}
}
{
AlignmentPanel ap = (alignment == null) ? appJmolWindow.ap
: (AlignmentPanel) alignment;
- if (ap.av.showSequenceFeatures)
+ if (ap.av.isShowSequenceFeatures())
{
if (fr == null)
{
- fr = ap.cloneFeatureRenderer();
+ fr = (jalview.gui.FeatureRenderer) ap.cloneFeatureRenderer();
}
else
{
return;
if (!isLoadingFromArchive())
{
- colourBySequence(ap.av.getShowSequenceFeatures(), ap);
+ colourBySequence(ap.av.isShowSequenceFeatures(), ap);
}
}
// Set the colour using the current view for the associated alignframe
for (AlignmentPanel ap : _colourwith)
{
- jmb.colourBySequence(ap.av.showSequenceFeatures, ap);
+ jmb.colourBySequence(ap.av.isShowSequenceFeatures(), ap);
}
}
}
}
});
- 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())
maxColour.setForeground(oldmaxColour);
minColour.setForeground(oldminColour);
}
- fr.featureColours.put(type, acg);
+ fr.setColour(type, acg);
cs = acg;
ap.paintAlignment(false);
}
void reset()
{
- fr.featureColours.put(type, oldcs);
+ fr.setColour(type, oldcs);
ap.paintAlignment(false);
cs = null;
}
*/
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.*;
-
-import jalview.datamodel.*;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
import jalview.schemes.GraduatedColor;
import jalview.util.MessageManager;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+import javax.swing.JColorChooser;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSpinner;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.SwingConstants;
+
/**
* DOCUMENT ME!
*
* @author $author$
* @version $Revision$
*/
-public class 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.
*/
public FeatureRenderer(AlignmentPanel ap)
{
+ super();
this.ap = ap;
this.av = ap.av;
if (ap != null && ap.getSeqPanel() != null && ap.getSeqPanel().seqCanvas != null
}
}
- 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(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.getFeaturesDisplayed() != null)
- {
- // update display settings
- if (av.getFeaturesDisplayed() == null)
- {
- av.setFeaturesDisplayed(new Hashtable(fr.av.getFeaturesDisplayed()));
- }
- else
- {
- av.getFeaturesDisplayed().clear();
- Enumeration en = fr.av.getFeaturesDisplayed().keys();
- while (en.hasMoreElements())
- {
- av.getFeaturesDisplayed().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.getFeaturesDisplayed() == null || renderOrder == null
- || newFeatureAdded)
- {
- findAllFeatures();
- if (av.getFeaturesDisplayed().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.getFeaturesDisplayed().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.getFeaturesDisplayed() == null)
- {
- av.setFeaturesDisplayed(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.getFeaturesDisplayed().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.getFeaturesDisplayed().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(MessageManager.formatMessage("error.implementation_error_unrecognised_render_object_for_features_type", new String[]{fc.getClass().toString(),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(MessageManager.formatMessage("error.implementation_error_unrecognised_render_object_for_features_type", new String[]{fc.getClass().toString(),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.
lastDescriptionAdded = description.getText().replaceAll("\n", " ");
// TODO: determine if the null feature group is valid
if (lastFeatureGroupAdded.length() < 1)
+ {
lastFeatureGroupAdded = null;
+ }
}
if (!newFeatures)
sf.description = lastDescriptionAdded;
setColour(sf.type, fcol);
- av.getFeaturesDisplayed().put(sf.type, getColour(sf.type));
+ getFeaturesDisplayed().setVisible(sf.type);
try
{
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.getFeaturesDisplayed() == null)
- {
- av.setFeaturesDisplayed(new Hashtable());
- }
-
if (lastFeatureGroupAdded != null)
{
- if (featureGroups == null)
- featureGroups = new Hashtable();
- featureGroups.put(lastFeatureGroupAdded, new Boolean(true));
+ setGroupVisibility(lastFeatureGroupAdded, true);
}
setColour(lastFeatureAdded, fcol);
- av.getFeaturesDisplayed().put(lastFeatureAdded,
- getColour(lastFeatureAdded));
+ setVisible(lastFeatureAdded);
findAllFeatures(false);
return true;
}
+
/**
* update the amend feature button dependent on the given style
*
// 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.getFeaturesDisplayed() != null)
- {
- av.getFeaturesDisplayed().clear();
- }
- else
- {
- av.setFeaturesDisplayed(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.getFeaturesDisplayed().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);
- }
}
*/
package jalview.gui;
-import jalview.analysis.AlignmentSorter;
import jalview.bin.Cache;
-import jalview.commands.OrderCommand;
-import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceFeature;
-import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
import jalview.gui.Help.HelpId;
import jalview.io.JalviewFileChooser;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
-import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
+import java.util.Set;
import java.util.Vector;
import javax.help.HelpSetException;
Object[][] originalData;
+ private float originalTransparency;
+
final JInternalFrame frame;
JScrollPane scrollPane = new JScrollPane();
{
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
{
if (SwingUtilities.isRightMouseButton(evt))
{
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)
{
if (evt.isPopupTrigger())
{
popupSort(selectedRow, (String) table.getValueAt(selectedRow, 0),
- table.getValueAt(selectedRow, 1), fr.minmax, evt.getX(),
+ table.getValueAt(selectedRow, 1), fr.getMinMax(),
+ evt.getX(),
evt.getY());
}
}
dassourceBrowser = new DasSourceBrowser(this);
dasSettingsPane.add(dassourceBrowser, BorderLayout.CENTER);
- if (af.getViewport().getFeaturesDisplayed() == null
- || fr.renderOrder == null)
+ if (af.getViewport().isShowSequenceFeatures() || !fr.hasRenderOrder())
{
fr.findAllFeatures(true); // display everything!
}
public void actionPerformed(ActionEvent e)
{
- me.sortByScore(new String[]
+ me.af.avc.sortAlignmentByFeatureScore(new String[]
{ type });
}
public void actionPerformed(ActionEvent e)
{
- me.sortByDens(new String[]
+ me.af.avc.sortAlignmentByFeatureDensity(new String[]
{ type });
}
synchronized public void setTableData()
{
- if (fr.featureGroups == null)
- {
- fr.featureGroups = new Hashtable();
- }
Vector allFeatures = new Vector();
Vector allGroups = new Vector();
SequenceFeature[] tmpfeatures;
if (!allGroups.contains(group))
{
allGroups.addElement(group);
- if (group != null)
- {
- checkGroupState(group);
- }
+ checkGroupState(group);
}
}
}
/**
+ * 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)
{
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));
{
public void itemStateChanged(ItemEvent evt)
{
- fr.featureGroups.put(check.getText(),
- new Boolean(check.isSelected()));
+ fr.setGroupVisibility(check.getText(), check.isSelected());
af.alignPanel.getSeqPanel().seqCanvas.repaint();
if (af.alignPanel.overviewPanel != null)
{
}
});
groupPanel.add(check);
- return false;
+ return visible;
}
boolean resettingTable = false;
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))
{
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
}
- // 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--)
+ List<String> frl = fr.getRenderOrder();
+ for (int ro = frl.size() - 1; ro > -1; ro--)
{
- type = fr.renderOrder[ro];
+ type = frl.get(ro);
if (!visibleChecks.contains(type))
{
data[dataIndex][0] = type;
data[dataIndex][1] = fr.getFeatureStyle(type);
- data[dataIndex][2] = new Boolean(
- af.getViewport().getFeaturesDisplayed().containsKey(type));
+ data[dataIndex][2] = new Boolean(af.getViewport()
+ .getFeaturesDisplayed().isVisible(type));
dataIndex++;
visibleChecks.removeElement(type);
}
if (data[dataIndex][1] == null)
{
// "Colour has been updated in another view!!"
- fr.renderOrder = null;
+ fr.clearRenderOrder();
return;
}
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);
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())
{
{
public void actionPerformed(ActionEvent e)
{
- sortByScore(null);
+ af.avc.sortAlignmentByFeatureScore(null);
}
});
sortByDens.setFont(JvSwingUtils.getLabelFont());
{
public void actionPerformed(ActionEvent e)
{
- sortByDens(null);
+ af.avc.sortAlignmentByFeatureDensity(null);
+ }
+ });
+ help.setFont(JvSwingUtils.getLabelFont());
+ help.setText(MessageManager.getString("action.help"));
+ help.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ try
+ {
+ Help.showHelpWindow(HelpId.SequenceFeatureSettings);
+ } catch (HelpSetException e1)
+ {
+ e1.printStackTrace();
+ }
}
});
help.setFont(JvSwingUtils.getLabelFont());
{
public void actionPerformed(ActionEvent e)
{
+ fr.setTransparency(originalTransparency);
updateFeatureRenderer(originalData);
close();
}
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.getFeaturesDisplayed().get(typ[i]) == null)
- {
- typ[i] = null;
- }
- }
- }
- }
- return typ;
- }
-
- private String[] getDisplayedFeatureGroups()
- {
- String[] gps = null;
- ArrayList<String> _gps = new ArrayList<String>();
- 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);
seqAnnotReport
.createSequenceAnnotationReport(tip, sequence,
av.isShowDbRefs(), av.isShowNpFeats(),
- sp.seqCanvas.fr.minmax);
+ sp.seqCanvas.fr.getMinMax());
setToolTipText("<html>" + sequence.getDisplayId(true) + " "
+ tip.toString() + "</html>");
}
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;
view.setShowColourText(av.getColourText());
view.setShowFullId(av.getShowJVSuffix());
view.setRightAlignIds(av.isRightAlignIds());
- view.setShowSequenceFeatures(av.showSequenceFeatures);
+ view.setShowSequenceFeatures(av.isShowSequenceFeatures());
view.setShowText(av.getShowText());
view.setShowUnconserved(av.getShowUnconserved());
view.setWrapAlignment(av.getWrapAlignment());
{
jalview.schemabinding.version2.FeatureSettings fs = new jalview.schemabinding.version2.FeatureSettings();
- String[] renderOrder = ap.getSeqPanel().seqCanvas.getFeatureRenderer().renderOrder;
+ String[] renderOrder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
+ .getRenderOrder().toArray(new String[0]);
Vector settingsAdded = new Vector();
Object gstyle = null;
.getColour(renderOrder[ro]).getRGB());
}
- setting.setDisplay(av.getFeaturesDisplayed()
- .containsKey(renderOrder[ro]));
+ setting.setDisplay(av.getFeaturesDisplayed().isVisible(
+ renderOrder[ro]));
float rorder = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
.getOrder(renderOrder[ro]);
if (rorder > -1)
}
// Make sure we save none displayed feature settings
- Iterator en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().featureColours
- .keySet().iterator();
+ Iterator en = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
+ .getFeatureColours().keySet().iterator();
while (en.hasNext())
{
String key = en.next().toString();
fs.addSetting(setting);
settingsAdded.addElement(key);
}
- en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().featureGroups
- .keySet().iterator();
+ // is groups actually supposed to be a map here ?
+ en = ap.getSeqPanel().seqCanvas.getFeatureRenderer().getFeatureGroups()
+ .iterator();
Vector groupsAdded = new Vector();
while (en.hasNext())
{
Group g = new Group();
g.setName(grp);
g.setDisplay(((Boolean) ap.getSeqPanel().seqCanvas
- .getFeatureRenderer().featureGroups.get(grp))
+ .getFeatureRenderer().checkGroupVisibility(grp, false))
.booleanValue());
fs.addGroup(g);
groupsAdded.addElement(grp);
an.addProperty(prop);
}
}
+
AnnotationElement ae;
if (aa[i].annotations != null)
{
af.viewport.setColourAppliesToAllGroups(true);
- if (view.getShowSequenceFeatures())
- {
- af.viewport.showSequenceFeatures = true;
- }
+ af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
+
if (view.hasCentreColumnLabels())
{
af.viewport.setCentreColumnLabels(view.getCentreColumnLabels());
// recover featre settings
if (jms.getFeatureSettings() != null)
{
- af.viewport.setFeaturesDisplayed(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);
gc.setColourByLabel(setting.getColourByLabel());
}
// and put in the feature colour table.
- af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setColour(
- setting.getType(), gc);
+ featureColours.put(setting.getType(), gc);
}
else
{
- af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setColour(
- setting.getType(),
+ featureColours.put(setting.getType(),
new java.awt.Color(setting.getColour()));
}
renderOrder[fs] = setting.getType();
if (setting.hasOrder())
{
- af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setOrder(
- setting.getType(), setting.getOrder());
+ featureOrder.put(setting.getType(), setting.getOrder());
}
else
{
- af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().setOrder(
- setting.getType(),
- fs / jms.getFeatureSettings().getSettingCount());
+ featureOrder.put(setting.getType(), new Float(fs
+ / jms.getFeatureSettings().getSettingCount()));
}
if (setting.getDisplay())
{
- af.viewport.getFeaturesDisplayed().put(setting.getType(), new Integer(
- setting.getColour()));
+ fdi.setVisible(setting.getType());
}
}
- af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
- Hashtable fgtable;
- af.alignPanel.getSeqPanel().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.getSeqPanel().seqCanvas.getFeatureRenderer()
+ .transferSettings(frs);
+
}
if (view.getHiddenColumnsCount() > 0)
{
skipList = skipList2;
}
-
}
import jalview.structure.StructureSelectionManager;
import jalview.util.MessageManager;
import jalview.util.jarInputStreamProvider;
+import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
import java.io.InputStreamReader;
import java.util.Hashtable;
}
af.viewport.setColourAppliesToAllGroups(true);
- af.viewport.showSequenceFeatures = view.getShowSequenceFeatures();
+ af.viewport.setShowSequenceFeatures(view.getShowSequenceFeatures());
if (jms.getFeatureSettings() != null)
{
- af.viewport.setFeaturesDisplayed(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.getSeqPanel().seqCanvas.getFeatureRenderer().setColour(
+ featureColours.put(
setting.getType(), new java.awt.Color(setting.getColour()));
renderOrder[fs] = setting.getType();
if (setting.getDisplay())
{
- af.viewport.getFeaturesDisplayed().put(setting.getType(), new Integer(
+ featuresDisplayed.put(setting.getType(), new Integer(
setting.getColour()));
}
}
- af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().renderOrder = renderOrder;
+ FeatureRendererSettings frs = new FeatureRendererSettings(renderOrder, new Hashtable(), featureColours, 1.0f, null);
+ af.alignPanel.getSeqPanel().seqCanvas.getFeatureRenderer().transferSettings(frs);
}
af.setMenusFromViewport(af.viewport);
{
AlignmentPanel ap = (alignment == null) ? cvf.ap
: (AlignmentPanel) alignment;
- if (ap.av.showSequenceFeatures)
+ if (ap.av.isShowSequenceFeatures())
{
if (fr == null)
{
- fr = ap.cloneFeatureRenderer();
+ fr = (jalview.gui.FeatureRenderer) ap.cloneFeatureRenderer();
}
else
{
}
if (!isLoadingFromArchive())
{
- colourBySequence(ap.av.getShowSequenceFeatures(), ap);
+ colourBySequence(ap.av.isShowSequenceFeatures(), ap);
}
}
@Override
// main visible SeqCanvas
SequenceRenderer sr;
- FeatureRenderer fr;
+ jalview.renderer.seqfeatures.FeatureRenderer fr;
/**
* Creates a new OverviewPanel object.
sr.renderGaps = false;
sr.forOverview = true;
fr = new FeatureRenderer(ap);
-
+
// scale the initial size of overviewpanel to shape of alignment
float initialScale = (float) av.getAlignment().getWidth()
/ (float) av.getAlignment().getHeight();
{
miniMe = null;
- if (av.showSequenceFeatures)
+ if (av.isShowSequenceFeatures())
{
fr.transferSettings(ap.getSeqPanel().seqCanvas.getFeatureRenderer());
}
{
color = sr.getResidueBoxColour(seq, lastcol).getRGB();
- if (av.showSequenceFeatures)
+ if (av.isShowSequenceFeatures())
{
color = fr.findFeatureColour(color, seq, lastcol);
}
true,
true,
false,
- (ap.getSeqPanel().seqCanvas.fr != null) ? ap.getSeqPanel().seqCanvas.fr.minmax
+ (ap.getSeqPanel().seqCanvas.fr != null) ? ap
+ .getSeqPanel().seqCanvas.fr
+ .getMinMax()
: null);
contents.append("</p>");
}
sr.drawSequence(nextSeq, av.getAlignment().findAllGroups(nextSeq),
startRes, endRes, offset + ((i - startSeq) * av.charHeight));
- if (av.showSequenceFeatures)
+ if (av.isShowSequenceFeatures())
{
fr.drawSequence(g, nextSeq, startRes, endRes, offset
+ ((i - startSeq) * av.charHeight));
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.getFeaturesDisplayed() == null
- || !av.getFeaturesDisplayed().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)
}
// use aa to see if the mouse pointer is on a
- if (av.showSequenceFeatures)
+ if (av.isShowSequenceFeatures())
{
int rpos;
- SequenceFeature[] features = findFeaturesAtRes(
+ List<SequenceFeature> features = ap.getFeatureRenderer().findFeaturesAtRes(
sequence.getDatasetSequence(),
rpos = sequence.findPosition(res));
seqARep.appendFeatures(tooltipText, rpos, features,
- this.ap.getSeqPanel().seqCanvas.fr.minmax);
+ this.ap.getSeqPanel().seqCanvas.fr.getMinMax());
}
if (tooltipText.length() == 6) // <html></html>
{
av.setSelectionGroup(null);
}
- SequenceFeature[] features = findFeaturesAtRes(
+ List<SequenceFeature> 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);
}
if (javax.swing.SwingUtilities.isRightMouseButton(evt))
{
- SequenceFeature[] allFeatures = findFeaturesAtRes(
+ List<SequenceFeature> 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));
}
}
}
*/
package jalview.gui;
-import java.beans.*;
-import java.io.*;
-import java.util.*;
-import java.util.List;
-
-import javax.imageio.*;
-
-import java.awt.*;
-import java.awt.event.*;
-import java.awt.image.*;
-import javax.swing.*;
-
-import org.jibble.epsgraphics.*;
-import jalview.analysis.*;
+import jalview.analysis.AlignmentSorter;
+import jalview.analysis.NJTree;
+import jalview.api.analysis.ScoreModelI;
+import jalview.api.analysis.ViewBasedAnalysisI;
+import jalview.bin.Cache;
import jalview.commands.CommandI;
import jalview.commands.OrderCommand;
-import jalview.datamodel.*;
-import jalview.io.*;
-import jalview.jbgui.*;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.AlignmentView;
+import jalview.datamodel.BinaryNode;
+import jalview.datamodel.ColumnSelection;
+import jalview.datamodel.DBRefEntry;
+import jalview.datamodel.NodeTransformI;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.datamodel.SequenceNode;
+import jalview.io.JalviewFileChooser;
+import jalview.io.JalviewFileView;
+import jalview.io.NewickFile;
+import jalview.jbgui.GTreePanel;
+import jalview.schemes.ResidueProperties;
import jalview.util.MessageManager;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.image.BufferedImage;
+import java.beans.PropertyChangeEvent;
+import java.io.FileOutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.imageio.ImageIO;
+import javax.swing.ButtonGroup;
+import javax.swing.JMenuItem;
+import javax.swing.JRadioButtonMenuItem;
+
+import org.jibble.epsgraphics.EpsGraphics2D;
+
/**
* DOCUMENT ME!
*
seqs = av.getSelectionGroup().getSequencesInOrder(
av.getAlignment());
}
-
- tree = new NJTree(seqs, seqStrings, type, pwtype, start, end);
+ ScoreModelI sm = ResidueProperties.getScoreModel(pwtype);
+ if (sm instanceof ViewBasedAnalysisI)
+ {
+ try
+ {
+ sm = sm.getClass().newInstance();
+ ((ViewBasedAnalysisI) sm)
+ .configureFromAlignmentView(treeCanvas.ap);
+ } catch (Exception q)
+ {
+ Cache.log.error("Couldn't create a scoremodel instance for "
+ + sm.getName());
+ }
+ tree = new NJTree(seqs, seqStrings, type, pwtype, sm, start, end);
+ }
+ else
+ {
+ tree = new NJTree(seqs, seqStrings, type, pwtype, null, start,
+ end);
+ }
showDistances(true);
}
package jalview.io;
+import jalview.api.FeaturesDisplayedI;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.schemes.ColourSchemeProperty;
import jalview.util.MessageManager;
+import java.awt.Color;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ArrayList;
-import java.util.Hashtable;
import com.json.JSONException;
{
private AlignViewport av;
- private FeatureRenderer fr;
+ private jalview.api.FeatureRenderer fr;
private String globalColorScheme;
- private Hashtable displayedFeatures;
+ private FeaturesDisplayedI displayedFeatures;
private String jalviewVersion;
this.av = ap.av;
this.globalColorScheme = ColourSchemeProperty.getColourName(av
.getGlobalColourScheme());
- this.fr = new FeatureRenderer(ap);
- fr.transferSettings(fr1);
+ this.fr = ap.cloneFeatureRenderer();
displayedFeatures = av.getFeaturesDisplayed();
-
- exportJalviewAlignmentAsBioJsHtmlFile();
- }
+ }
}
private void exportJalviewAlignmentAsBioJsHtmlFile()
for (SequenceFeature sf : seqFeatures)
{
if (displayedFeatures != null
- && displayedFeatures.get(sf.getType()) != null)
+ && displayedFeatures.isVisible(sf.getType()))
{
+
+ // TODO: translate graduated/complex colourschemes to biojs model
String featureColour = jalview.util.Format.getHexString(fr
- .getColour(sf));
+ .findFeatureColour(Color.white, seq,
+ seq.findIndex(sf.getBegin())));
BioJsFeaturePojo bjsFeature = new BioJsFeaturePojo();
bjsFeature.setFillColor(featureColour);
bjsFeature.setXstart(seq.findIndex(sf.getBegin()) - 1);
* hash of feature types and colours
* @return features file contents
*/
- public String printJalviewFormat(SequenceI[] seqs, Hashtable visible)
+ public String printJalviewFormat(SequenceI[] seqs, Map<String,Object> visible)
{
return printJalviewFormat(seqs, visible, true, true);
}
* 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();
// 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)
{
* @param visible
* @return
*/
- public String printGFFFormat(SequenceI[] seqs, Hashtable visible)
+ public String printGFFFormat(SequenceI[] seqs, Map<String,Object> visible)
{
return printGFFFormat(seqs, visible, true, true);
}
- public String printGFFFormat(SequenceI[] seqs, Hashtable visible,
+ public String printGFFFormat(SequenceI[] seqs, Map<String,Object> visible,
boolean visOnly, boolean nonpos)
{
StringBuffer out = new StringBuffer();
SequenceRenderer sr;
- FeatureRenderer fr;
+ jalview.renderer.seqfeatures.FeatureRenderer fr;
Color color;
import java.util.ArrayList;
import java.util.Hashtable;
+import java.util.List;
import java.util.Vector;
import jalview.datamodel.DBRefEntry;
* TODO refactor to Jalview 'utilities' somehow.
*/
public void appendFeatures(final StringBuffer tooltipText2, int rpos,
- SequenceFeature[] features)
+ List<SequenceFeature> features)
{
appendFeatures(tooltipText2, rpos, features, null);
}
public void appendFeatures(final StringBuffer tooltipText2, int rpos,
- SequenceFeature[] features, Hashtable minmax)
+ List<SequenceFeature> 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("<br>");
}
- tooltipText2.append("disulfide bond " + features[i].getBegin()
- + ":" + features[i].getEnd());
+ tooltipText2.append("disulfide bond " + feature.getBegin()
+ + ":" + feature.getEnd());
}
}
else
tooltipText2.append("<br>");
}
// 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("<HTML>");
if (startTag > -1)
}
}
// 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)
{
}
else
{
- for (String urlstring : (Vector<String>) features[i].links)
+ for (String urlstring : (Vector<String>) feature.links)
{
try
{
// 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++)
if (features[i].begin == 0 && features[i].end == 0)
{
int sz = -tip.length();
- tfeat[0] = features[i];
+ List<SequenceFeature> tfeat = new ArrayList<SequenceFeature>();
+ tfeat.add(features[i]);
appendFeatures(tip, 0, tfeat, minmax);
sz += tip.length();
maxWidth = Math.max(maxWidth, sz);
SequenceRenderer sr = ((jalview.appletgui.AlignmentPanel) source)
.getSequenceRenderer();
FeatureRenderer fr = ((jalview.appletgui.AlignmentPanel) source).av
- .getShowSequenceFeatures() ? new jalview.appletgui.FeatureRenderer(
+ .isShowSequenceFeatures() ? new jalview.appletgui.FeatureRenderer(
((jalview.appletgui.AlignmentPanel) source).av) : null;
if (fr != null)
{
--- /dev/null
+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();
+ }
+}
public Color findColour(char c, int j, SequenceI seq)
{
Color currentColour = Color.white;
- AlignmentAnnotation annotation = (seqAssociated ? seqannot.get(seq)
+ AlignmentAnnotation annotation = (seqAssociated && seqannot!=null ? seqannot.get(seq)
: this.annotation);
if (annotation == null)
{
*/
package jalview.schemes;
+import jalview.analysis.scoremodels.FeatureScoreModel;
import jalview.analysis.scoremodels.PIDScoreModel;
import jalview.api.analysis.ScoreModelI;
// scoreMatrices.put("Conservation EnhPos", new
// ScoreMatrix("Conservation EnhPos",propMatrixEpos,0));
scoreMatrices.put("PID", new PIDScoreModel());
+ scoreMatrices.put("Displayed Features", new FeatureScoreModel());
}
private ResidueProperties()
import jalview.api.AlignCalcManagerI;
import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
+import jalview.api.FeaturesDisplayedI;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentView;
sequenceSetID = new String(newid);
}
+ @Override
public String getSequenceSetId()
{
if (sequenceSetID == null)
{
sequenceColours = null;
};
+
+ FeaturesDisplayedI featuresDisplayed = null;
+
+ @Override
+ public FeaturesDisplayedI getFeaturesDisplayed()
+ {
+ return featuresDisplayed;
+ }
+
+ public void setFeaturesDisplayed(FeaturesDisplayedI featuresDisplayedI)
+ {
+ featuresDisplayed = featuresDisplayedI;
+ }
+
+ public boolean areFeaturesDisplayed()
+ {
+ return featuresDisplayed != null && featuresDisplayed.getRegisterdFeaturesCount()>0;
+ }
+
+ /**
+ * display setting for showing/hiding sequence features on alignment view
+ */
+ boolean showSequenceFeatures = false;
+
+ /**
+ * set the flag
+ *
+ * @param b
+ * features are displayed if true
+ */
+ @Override
+ public void setShowSequenceFeatures(boolean b)
+ {
+ showSequenceFeatures = b;
+ }
+ @Override
+ public boolean isShowSequenceFeatures()
+ {
+ return showSequenceFeatures;
+ }
+
+ boolean showSeqFeaturesHeight;
+
+ public void setShowSequenceFeaturesHeight(boolean selected)
+ {
+ showSeqFeaturesHeight = selected;
+ }
+
+ public boolean isShowSequenceFeaturesHeight()
+ {
+ return showSeqFeaturesHeight;
+ }
+
+ private boolean showAnnotation = true;
+
+ private boolean rightAlignIds = false;
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ public boolean getShowAnnotation()
+ {
+ return isShowAnnotation();
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param b
+ * DOCUMENT ME!
+ */
+ public void setShowAnnotation(boolean b)
+ {
+ showAnnotation = b;
+ }
+
+ public boolean isShowAnnotation()
+ {
+ return showAnnotation;
+ }
+
+ public boolean isRightAlignIds()
+ {
+ return rightAlignIds;
+ }
+
+ public void setRightAlignIds(boolean rightAlignIds)
+ {
+ this.rightAlignIds = rightAlignIds;
+ }
+
}
--- /dev/null
+package jalview.viewmodel.seqfeatures;
+
+import jalview.api.AlignViewportI;
+import jalview.api.FeaturesDisplayedI;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.renderer.seqfeatures.FeatureRenderer;
+import jalview.schemes.GraduatedColor;
+import jalview.viewmodel.AlignmentViewport;
+
+import java.awt.Color;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+public abstract class FeatureRendererModel implements
+ jalview.api.FeatureRenderer
+{
+
+ /**
+ * global transparency for feature
+ */
+ protected float transparency = 1.0f;
+
+ protected Map<String, Object> featureColours = new ConcurrentHashMap<String, Object>();
+
+ protected Map<String, Boolean> featureGroups = new ConcurrentHashMap<String, Boolean>();
+
+ protected Object currentColour;
+
+ protected String[] renderOrder;
+
+ protected PropertyChangeSupport changeSupport = new PropertyChangeSupport(
+ this);
+
+ protected AlignmentViewport av;
+
+ public AlignViewportI getViewport()
+ {
+ return av;
+ }
+
+ 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.getViewport())
+ {
+ // copy over the displayed feature settings
+ if (_fr.getFeaturesDisplayed() != null)
+ {
+ FeaturesDisplayedI fd = getFeaturesDisplayed();
+ if (fd == null)
+ {
+ setFeaturesDisplayedFrom(_fr.getFeaturesDisplayed());
+ }
+ else
+ {
+ synchronized (fd)
+ {
+ fd.clear();
+ java.util.Iterator<String> fdisp = _fr.getFeaturesDisplayed()
+ .getVisibleFeatures();
+ while (fdisp.hasNext())
+ {
+ fd.setVisible(fdisp.next());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ public void setFeaturesDisplayedFrom(FeaturesDisplayedI featuresDisplayed)
+ {
+ av.setFeaturesDisplayed(new FeaturesDisplayed(featuresDisplayed));
+ }
+
+ @Override
+ public void setVisible(String featureType)
+ {
+ FeaturesDisplayedI fdi = av.getFeaturesDisplayed();
+ if (fdi == null)
+ {
+ av.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
+ }
+ if (!fdi.isRegistered(featureType))
+ {
+ pushFeatureType(Arrays.asList(new String[]
+ { featureType }));
+ }
+ fdi.setVisible(featureType);
+ }
+
+ @Override
+ public void setAllVisible(List<String> featureTypes)
+ {
+ FeaturesDisplayedI fdi = av.getFeaturesDisplayed();
+ if (fdi == null)
+ {
+ av.setFeaturesDisplayed(fdi = new FeaturesDisplayed());
+ }
+ List<String> nft = new ArrayList<String>();
+ for (String featureType : featureTypes)
+ {
+ if (!fdi.isRegistered(featureType))
+ {
+ nft.add(featureType);
+ }
+ }
+ if (nft.size() > 0)
+ {
+ pushFeatureType(nft);
+ }
+ fdi.setAllVisible(featureTypes);
+ }
+
+ /**
+ * push a set of new types onto the render order stack. Note - this is a
+ * direct mechanism rather than the one employed in updateRenderOrder
+ *
+ * @param types
+ */
+ private void pushFeatureType(List<String> types)
+ {
+
+ int ts = types.size();
+ String neworder[] = new String[(renderOrder == null ? 0
+ : renderOrder.length) + ts];
+ types.toArray(neworder);
+ if (renderOrder != null)
+ {
+ System.arraycopy(neworder,0,neworder,renderOrder.length,ts);
+ System.arraycopy(renderOrder, 0, neworder, 0, renderOrder.length);
+ }
+ renderOrder = neworder;
+ }
+
+ protected Hashtable minmax = new Hashtable();
+
+ public Hashtable getMinMax()
+ {
+ return minmax;
+ }
+
+ /**
+ * 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.
+ */
+ protected 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;
+ }
+
+ boolean newFeatureAdded = false;
+
+ boolean findingFeatures = false;
+
+ protected boolean updateFeatures()
+ {
+ if (av.getFeaturesDisplayed() == null || renderOrder == null
+ || newFeatureAdded)
+ {
+ findAllFeatures();
+ if (av.getFeaturesDisplayed().getVisibleFeatureCount() < 1)
+ {
+ return false;
+ }
+ }
+ // TODO: decide if we should check for the visible feature count first
+ return true;
+ }
+
+ /**
+ * search the alignment for all new features, give them a colour and display
+ * them. Then fires a PropertyChangeEvent on the changeSupport object.
+ *
+ */
+ protected 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;
+ }
+ }
+ }
+
+ @Override
+ public List<SequenceFeature> findFeaturesAtRes(SequenceI sequence, int res)
+ {
+ ArrayList<SequenceFeature> tmp = new ArrayList<SequenceFeature>();
+ SequenceFeature[] features = sequence.getSequenceFeatures();
+
+ while (features == null && sequence.getDatasetSequence() != null)
+ {
+ sequence = sequence.getDatasetSequence();
+ features = sequence.getSequenceFeatures();
+ }
+
+ if (features != null)
+ {
+ for (int i = 0; i < features.length; i++)
+ {
+ if (!av.areFeaturesDisplayed()
+ || !av.getFeaturesDisplayed().isVisible(
+ features[i].getType()))
+ {
+ continue;
+ }
+
+ if (features[i].featureGroup != null
+ && featureGroups != null
+ && featureGroups.containsKey(features[i].featureGroup)
+ && !featureGroups.get(features[i].featureGroup)
+ .booleanValue())
+ {
+ continue;
+ }
+
+ if ((features[i].getBegin() <= res)
+ && (features[i].getEnd() >= res))
+ {
+ tmp.add(features[i]);
+ }
+ }
+ }
+ return tmp;
+ }
+
+ /**
+ * Searches alignment for all features and updates colours
+ *
+ * @param newMadeVisible
+ * if true newly added feature types will be rendered immediatly
+ * TODO: check to see if this method should actually be proxied so
+ * repaint events can be propagated by the renderer code
+ */
+ @Override
+ public synchronized void findAllFeatures(boolean newMadeVisible)
+ {
+ newFeatureAdded = false;
+
+ if (findingFeatures)
+ {
+ newFeatureAdded = true;
+ return;
+ }
+
+ findingFeatures = true;
+ if (av.getFeaturesDisplayed() == null)
+ {
+ av.setFeaturesDisplayed(new FeaturesDisplayed());
+ }
+ FeaturesDisplayedI featuresDisplayed = av.getFeaturesDisplayed();
+
+ ArrayList<String> allfeatures = new ArrayList<String>();
+ ArrayList<String> oldfeatures = new ArrayList<String>();
+ if (renderOrder != null)
+ {
+ for (int i = 0; i < renderOrder.length; i++)
+ {
+ if (renderOrder[i] != null)
+ {
+ oldfeatures.add(renderOrder[i]);
+ }
+ }
+ }
+ if (minmax == null)
+ {
+ minmax = new Hashtable();
+ }
+ AlignmentI alignment = av.getAlignment();
+ for (int i = 0; i < alignment.getHeight(); i++)
+ {
+ SequenceI asq = alignment.getSequenceAt(i);
+ SequenceI dasq = asq.getDatasetSequence();
+ SequenceFeature[] features = dasq != null ? dasq
+ .getSequenceFeatures() : asq.getSequenceFeatures();
+
+ if (features == null)
+ {
+ continue;
+ }
+
+ int index = 0;
+ while (index < features.length)
+ {
+ if (!featuresDisplayed.isRegistered(features[index].getType()))
+ {
+ String fgrp = features[index].getFeatureGroup();
+ if (fgrp != null)
+ {
+ Boolean groupDisplayed = featureGroups.get(fgrp);
+ if (groupDisplayed == null)
+ {
+ groupDisplayed = Boolean.valueOf(newMadeVisible);
+ featureGroups.put(fgrp, groupDisplayed);
+ }
+ if (!groupDisplayed.booleanValue())
+ {
+ 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.
+ featuresDisplayed.setVisible(features[index].getType());
+ setOrder(features[index].getType(), 0);
+ }
+ }
+ }
+ if (!allfeatures.contains(features[index].getType()))
+ {
+ allfeatures.add(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(List<String> allFeatures)
+ {
+ List<String> allfeatures = new ArrayList<String>(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)
+ / oldRender.length));
+ }
+ if (allfeatures.contains(oldRender[j]))
+ {
+ renderOrder[opos++] = oldRender[j]; // existing features always
+ // appear below new features
+ allfeatures.remove(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()];
+ for (String newfeat : allfeatures)
+ {
+ newf[i] = newfeat;
+ 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());
+ }
+
+ protected boolean showFeature(SequenceFeature sequenceFeature)
+ {
+ Object fc = getFeatureStyle(sequenceFeature.type);
+ if (fc instanceof GraduatedColor)
+ {
+ return ((GraduatedColor) fc).isColored(sequenceFeature);
+ }
+ else
+ {
+ return true;
+ }
+ }
+
+ protected boolean showFeatureOfType(String type)
+ {
+ return av.getFeaturesDisplayed().isVisible(type);
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ @Override
+ public Map<String, Object> getFeatureColours()
+ {
+ return new ConcurrentHashMap<String, Object>(featureColours);
+ }
+
+ /**
+ * 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)
+ {
+ FeaturesDisplayedI av_featuresdisplayed = null;
+ if (visibleNew)
+ {
+ if ((av_featuresdisplayed = av.getFeaturesDisplayed()) != null)
+ {
+ av.getFeaturesDisplayed().clear();
+ }
+ else
+ {
+ av.setFeaturesDisplayed(av_featuresdisplayed = new FeaturesDisplayed());
+ }
+ }
+ else
+ {
+ av_featuresdisplayed = av.getFeaturesDisplayed();
+ }
+ 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.setVisible(type);
+ }
+
+ renderOrder[data.length - i - 1] = type;
+ }
+ }
+
+ }
+
+ /**
+ * @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);
+ }
+
+ public Set getAllFeatureColours()
+ {
+ return featureColours.keySet();
+ }
+
+ public void clearRenderOrder()
+ {
+ renderOrder = null;
+ }
+
+ public boolean hasRenderOrder()
+ {
+ return renderOrder != null;
+ }
+
+ public List<String> getRenderOrder()
+ {
+ if (renderOrder == null)
+ {
+ return Arrays.asList(new String[]
+ {});
+ }
+ return Arrays.asList(renderOrder);
+ }
+
+ public int getFeatureGroupsSize()
+ {
+ return featureGroups != null ? 0 : featureGroups.size();
+ }
+
+ @Override
+ public List<String> getFeatureGroups()
+ {
+ // conflict between applet and desktop - featureGroups returns the map in
+ // the desktop featureRenderer
+ return (featureGroups == null) ? Arrays.asList(new String[0]) : Arrays
+ .asList(featureGroups.keySet().toArray(new String[0]));
+ }
+
+ public boolean checkGroupVisibility(String group, boolean newGroupsVisible)
+ {
+ if (featureGroups == null)
+ {
+ // then an exception happens next..
+ }
+ if (featureGroups.containsKey(group))
+ {
+ return featureGroups.get(group).booleanValue();
+ }
+ if (newGroupsVisible)
+ {
+ featureGroups.put(group, new Boolean(true));
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * get visible or invisible groups
+ *
+ * @param visible
+ * true to return visible groups, false to return hidden ones.
+ * @return list of groups
+ */
+ @Override
+ public List getGroups(boolean visible)
+ {
+ if (featureGroups != null)
+ {
+ ArrayList gp = new ArrayList();
+
+ for (Object grp : featureGroups.keySet())
+ {
+ Boolean state = featureGroups.get(grp);
+ if (state.booleanValue() == visible)
+ {
+ gp.add(grp);
+ }
+ }
+ return gp;
+ }
+ return null;
+ }
+
+ @Override
+ public void setGroupVisibility(String group, boolean visible)
+ {
+ featureGroups.put(group, new Boolean(visible));
+ }
+
+ @Override
+ public void setGroupVisibility(List<String> toset, boolean visible)
+ {
+ if (toset != null && toset.size() > 0 && featureGroups != null)
+ {
+ boolean rdrw = false;
+ for (String gst : toset)
+ {
+ Boolean st = featureGroups.get(gst);
+ featureGroups.put(gst, new Boolean(visible));
+ if (st != null)
+ {
+ rdrw = rdrw || (visible != st.booleanValue());
+ }
+ }
+ if (rdrw)
+ {
+ // set local flag indicating redraw needed ?
+ }
+ }
+ }
+
+ @Override
+ public Hashtable getDisplayedFeatureCols()
+ {
+ Hashtable fcols = new Hashtable();
+ if (getViewport().getFeaturesDisplayed() == null)
+ {
+ return fcols;
+ }
+ Iterator<String> en = getViewport().getFeaturesDisplayed()
+ .getVisibleFeatures();
+ while (en.hasNext())
+ {
+ String col = en.next();
+ fcols.put(col, getColour(col));
+ }
+ return fcols;
+ }
+
+ @Override
+ public FeaturesDisplayedI getFeaturesDisplayed()
+ {
+ return av.getFeaturesDisplayed();
+ }
+
+ @Override
+ public String[] getDisplayedFeatureTypes()
+ {
+ String[] typ = null;
+ typ = getRenderOrder().toArray(new String[0]);
+ FeaturesDisplayedI feature_disp = av.getFeaturesDisplayed();
+ if (feature_disp != null)
+ {
+ synchronized (feature_disp)
+ {
+ for (int i = 0; i < typ.length; i++)
+ {
+ if (!feature_disp.isVisible(typ[i]))
+ {
+ typ[i] = null;
+ }
+ }
+ }
+ }
+ return typ;
+ }
+
+ @Override
+ public String[] getDisplayedFeatureGroups()
+ {
+ String[] gps = null;
+ ArrayList<String> _gps = new ArrayList<String>();
+ Iterator en = getFeatureGroups().iterator();
+ int g = 0;
+ boolean valid = false;
+ while (en.hasNext())
+ {
+ String gp = (String) en.next();
+ if (checkGroupVisibility(gp, false))
+ {
+ valid = true;
+ _gps.add(gp);
+ }
+ if (!valid)
+ {
+ return null;
+ }
+ else
+ {
+ gps = new String[_gps.size()];
+ _gps.toArray(gps);
+ }
+ }
+ return gps;
+ }
+
+}
--- /dev/null
+package jalview.viewmodel.seqfeatures;
+
+import jalview.schemes.GraduatedColor;
+
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+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 = Arrays.copyOf(renderOrder,renderOrder.length);
+ this.featureGroups = new ConcurrentHashMap(featureGroups);
+ this.featureColours = new ConcurrentHashMap(featureColours);
+ this.transparency = transparency;
+ this.featureOrder = new ConcurrentHashMap(featureOrder);
+ }
+
+ /**
+ * create an independent instance of the feature renderer settings
+ *
+ * @param fr
+ */
+ public FeatureRendererSettings(
+ jalview.viewmodel.seqfeatures.FeatureRendererModel 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);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+package jalview.viewmodel.seqfeatures;
+
+import jalview.api.FeatureSettingsModelI;
+
+public class FeatureSettingsModel implements FeatureSettingsModelI
+{
+
+}
--- /dev/null
+package jalview.viewmodel.seqfeatures;
+
+import jalview.api.FeaturesDisplayedI;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+
+public class FeaturesDisplayed implements FeaturesDisplayedI
+{
+ private HashSet<String> featuresDisplayed = new HashSet<String>();
+
+ private HashSet<String> featuresRegistered = new HashSet<String>();
+
+ public FeaturesDisplayed(FeaturesDisplayedI featuresDisplayed2)
+ {
+ Iterator<String> fdisp = featuresDisplayed2.getVisibleFeatures();
+ String ftype;
+ while (fdisp.hasNext())
+ {
+ ftype = fdisp.next();
+ featuresDisplayed.add(ftype);
+ featuresRegistered.add(ftype);
+ }
+ }
+
+ public FeaturesDisplayed()
+ {
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ public Iterator<String> getVisibleFeatures()
+ {
+ return featuresDisplayed.iterator();
+ }
+
+ @Override
+ public boolean isVisible(String featureType)
+ {
+ return featuresDisplayed.contains(featureType);
+ }
+
+ @Override
+ public boolean areVisible(Collection featureTypes)
+ {
+ return featuresDisplayed.containsAll(featureTypes);
+ }
+
+ @Override
+ public void clear()
+ {
+ featuresDisplayed.clear();
+ featuresRegistered.clear();
+ }
+
+ @Override
+ public void setAllVisible(Collection makeVisible)
+ {
+ featuresDisplayed.addAll(makeVisible);
+ featuresRegistered.addAll(makeVisible);
+ }
+
+ @Override
+ public void setAllRegisteredVisible()
+ {
+ featuresDisplayed.addAll(featuresRegistered);
+ }
+
+ @Override
+ public void setVisible(String featureType)
+ {
+ featuresDisplayed.add(featureType);
+ featuresRegistered.add(featureType);
+ }
+
+ @Override
+ public boolean isRegistered(String type)
+ {
+ return featuresRegistered.contains(type);
+ }
+
+ @Override
+ public int getVisibleFeatureCount()
+ {
+ return featuresDisplayed.size();
+ }
+
+ @Override
+ public int getRegisterdFeaturesCount()
+ {
+ return featuresRegistered.size();
+ }
+}
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
import jalview.gui.WebserviceInfo;
-import jalview.gui.FeatureRenderer.FeatureRendererSettings;
+import jalview.viewmodel.seqfeatures.FeatureRendererSettings;
import jalview.util.MessageManager;
public abstract class AWSThread extends Thread
{
if (dispFeatures)
{
- jalview.gui.FeatureRenderer fr = ((jalview.gui.AlignmentPanel) ap)
+ jalview.api.FeatureRenderer fr = ((jalview.gui.AlignmentPanel) ap)
.cloneFeatureRenderer();
for (String ft : fc.keySet())
{
--- /dev/null
+package jalview.analysis.scoremodels;
+
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.gui.AlignFrame;
+import jalview.io.FileLoader;
+import jalview.io.FormatAdapter;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class FeatureScoreModelTest
+{
+ public static String alntestFile = "FER1_MESCR/72-76 DVYIL\nFER1_SPIOL/71-75 DVYIL\nFER3_RAPSA/21-25 DVYVL\nFER1_MAIZE/73-77 DVYIL\n";
+
+ int[] sf1 = new int[]
+ { 74, 74, 73, 73, 23, 23, -1, -1 };
+
+ int[] sf2 = new int[]
+ { -1, -1, 74, 75, -1, -1, 76, 77 };
+
+ int[] sf3 = new int[]
+ { -1, -1, -1, -1, -1, -1, 76, 77 };
+
+ @Test
+ public void testFeatureScoreModel() throws Exception
+ {
+ AlignFrame alf = new FileLoader(false).LoadFileWaitTillLoaded(alntestFile,
+ FormatAdapter.PASTE);
+ AlignmentI al = alf.getViewport().getAlignment();
+ Assert.assertEquals(4, al.getHeight());
+ Assert.assertEquals(5, al.getWidth());
+ for (int i = 0; i < 4; i++)
+ {
+ SequenceI ds = al.getSequenceAt(i).getDatasetSequence();
+ if (sf1[i * 2] > 0)
+ {
+ ds.addSequenceFeature(new SequenceFeature("sf1", "sf1", "sf1",
+ sf1[i * 2], sf1[i * 2 + 1], "sf1"));
+ }
+ if (sf2[i * 2] > 0)
+ {
+ ds.addSequenceFeature(new SequenceFeature("sf2", "sf2", "sf2",
+ sf2[i * 2], sf2[i * 2 + 1], "sf2"));
+ }
+ if (sf3[i * 2] > 0)
+ {
+ ds.addSequenceFeature(new SequenceFeature("sf3", "sf3", "sf3",
+ sf3[i * 2], sf3[i * 2 + 1], "sf3"));
+ }
+ }
+ alf.setShowSeqFeatures(true);
+ alf.getFeatureRenderer().setVisible("sf1");
+ alf.getFeatureRenderer().setVisible("sf2");
+ alf.getFeatureRenderer().setVisible("sf3");
+ alf.getFeatureRenderer().findAllFeatures(true);
+ Assert.assertEquals("Number of feature types", 3, alf
+ .getFeatureRenderer().getDisplayedFeatureTypes().length);
+ Assert.assertTrue(alf.getCurrentView().areFeaturesDisplayed());
+ FeatureScoreModel fsm = new FeatureScoreModel();
+ Assert.assertTrue(fsm.configureFromAlignmentView(alf.getCurrentView()
+ .getAlignPanel()));
+ alf.selectAllSequenceMenuItem_actionPerformed(null);
+ float[][] dm = fsm.findDistances(alf.getViewport().getAlignmentView(
+ true));
+ Assert.assertTrue("FER1_MESCR should be identical with RAPSA (2)",
+ dm[0][2] == 0f);
+ Assert.assertTrue(
+ "FER1_MESCR should be further from SPIOL (1) than it is from RAPSA (2)",
+ dm[0][1] > dm[0][2]);
+
+ }
+}