/*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
- * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ * Jalview - A Sequence Alignment Editor and Viewer (Development Version 2.4.1)
+ * Copyright (C) 2009 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
import jalview.appletgui.FeatureSettings.MyCheckbox;
import jalview.datamodel.*;
+import jalview.schemes.AnnotationColourGradient;
+import jalview.schemes.GraduatedColor;
/**
* DOCUMENT ME!
* Creates a new FeatureRenderer object.
*
* @param av
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
public FeatureRenderer(AlignViewport av)
{
boolean deleteFeature = false;
- Panel colourPanel;
+ FeatureColourPanel colourPanel;
+ class FeatureColourPanel extends Panel {
+ String label="";
+
+ private Color maxCol;
+ private boolean isColourByLabel,isGcol;
+ /**
+ * render a feature style in the amend feature dialog box
+ */
+ public void updateColor(Object newcol)
+ {
+
+ Color bg,col=null;
+ GraduatedColor gcol=null;
+ String vlabel = "";
+ if (newcol instanceof Color)
+ {
+ isGcol=false;
+ col = (Color) newcol;
+ gcol = null;
+ }
+ else if (newcol instanceof GraduatedColor)
+ {
+ isGcol=true;
+ gcol = (GraduatedColor) newcol;
+ col = null;
+ }
+ else
+ {
+ throw new Error("Invalid color for MyCheckBox");
+ }
+ if (col != null)
+ {
+ setBackground(bg=col);
+ }
+ else
+ {
+ if (gcol.getThreshType()!=AnnotationColourGradient.NO_THRESHOLD)
+ {
+ vlabel += " "+((gcol.getThreshType()==AnnotationColourGradient.ABOVE_THRESHOLD) ? "(>)" : "(<)");
+ }
+ if (isColourByLabel=gcol.isColourByLabel()) {
+ setBackground(bg=Color.white);
+ vlabel += " (by Label)";
+ } else {
+ setBackground(bg=gcol.getMinColor());
+ maxCol = gcol.getMaxColor();
+ }
+ }
+ label=vlabel;
+ setBackground(bg);
+ repaint();
+ }
+ FeatureColourPanel() {
+ super(null);
+ }
+ public void paint(Graphics g)
+ {
+ Dimension d = getSize();
+ if (isGcol) {
+ if (isColourByLabel)
+ {
+ g.setColor(Color.white);
+ g.fillRect(d.width/2, 0,d.width/2, d.height);
+ g.setColor(Color.black);
+ Font f=new Font("Verdana", Font.PLAIN,
+ 10);
+ g.setFont(f);
+ g.drawString("Label", 0, 0);
+ }
+ else
+ {
+ g.setColor(maxCol);
+ g.fillRect(d.width/2, 0,d.width/2, d.height);
+
+ }
+ }
+ }
+
+ }
boolean amendFeatures(final SequenceI[] sequences,
final SequenceFeature[] features, boolean newFeatures,
Button deleteButton = new Button("Delete");
deleteFeature = false;
- colourPanel = new Panel(null);
+ colourPanel = new FeatureColourPanel();
colourPanel.setSize(110, 15);
final FeatureRenderer fr = this;
Panel panel = new Panel(new GridLayout(3, 1));
-
+
+ featureIndex = 0; // feature to be amended.
Panel tmp;
// /////////////////////////////////////
ap.seqPanel.seqCanvas.highlightSearchResults(highlight);
}
- Color col = getColour(name.getText());
+ Object col = getFeatureStyle(name.getText());
if (col == null)
{
col = new jalview.schemes.UserColourScheme()
.createColourFromName(name.getText());
}
- colourPanel.setBackground(col);
+ colourPanel.updateColor(col);
}
});
start.setText(features[0].getBegin() + "");
end.setText(features[0].getEnd() + "");
description.setText(features[0].getDescription());
-
Color col = getColour(name.getText());
if (col == null)
{
col = new jalview.schemes.UserColourScheme()
.createColourFromName(name.getText());
}
-
- colourPanel.setBackground(col);
-
+ Object fcol = getFeatureStyle(name.getText());
+ // simply display the feature color in a box
+ colourPanel.updateColor(fcol);
dialog.setResizable(true);
-
+ // TODO: render the graduated color in the box.
colourPanel.addMouseListener(new java.awt.event.MouseAdapter()
- {
- public void mousePressed(java.awt.event.MouseEvent evt)
{
- new UserDefinedColours(fr, ap.alignFrame);
- }
- });
-
+ public void mousePressed(java.awt.event.MouseEvent evt)
+ {
+ if (!colourPanel.isGcol)
+ {
+ new UserDefinedColours(fr, ap.alignFrame);
+ } else {
+ FeatureColourChooser fcc = new FeatureColourChooser(ap.alignFrame, name.getText());
+ dialog.transferFocus();
+ }
+ }
+ });
dialog.setVisible(true);
jalview.io.FeaturesFile ffile = new jalview.io.FeaturesFile();
if (!newFeatures)
{
- SequenceFeature sf = features[featureIndex];
+ SequenceFeature sf = features[featureIndex];
if (dialog.accept)
{
sf.type = lastFeatureAdded;
sf.featureGroup = lastFeatureGroupAdded;
sf.description = lastDescriptionAdded;
- setColour(sf.type, colourPanel.getBackground());
+ if (!colourPanel.isGcol) {
+ // update colour - otherwise its already done.
+ setColour(sf.type, colourPanel.getBackground());
+ }
try
{
sf.begin = Integer.parseInt(start.getText());
}
col = colourPanel.getBackground();
- setColour(lastFeatureAdded, col);
+ //setColour(lastFeatureAdded, fcol);
if (lastFeatureGroupAdded != null)
{
featureGroups.put(lastFeatureGroupAdded, new Boolean(true));
- av.featuresDisplayed.put(lastFeatureGroupAdded, new Integer(col
- .getRGB()));
}
+ if (fcol instanceof Color) {
+ setColour(lastFeatureAdded, fcol);
+ }
+ 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;
-
- ap.paintAlignment(true);
-
- return true;
}
else
{
+ // no update to the alignment
return false;
}
}
-
- findAllFeatures();
+ // refresh the alignment and the feature settings dialog
+ if (av.featureSettings!=null)
+ {
+ av.featureSettings.refreshTable();
+ }
+ // findAllFeatures();
ap.paintAlignment(true);
* DOCUMENT ME!
*
* @param g
- * DOCUMENT ME!
+ * DOCUMENT ME!
* @param seq
- * DOCUMENT ME!
+ * DOCUMENT ME!
* @param sg
- * DOCUMENT ME!
+ * DOCUMENT ME!
* @param start
- * DOCUMENT ME!
+ * DOCUMENT ME!
* @param end
- * DOCUMENT ME!
+ * DOCUMENT ME!
* @param x1
- * DOCUMENT ME!
+ * DOCUMENT ME!
* @param y1
- * DOCUMENT ME!
+ * DOCUMENT ME!
* @param width
- * DOCUMENT ME!
+ * DOCUMENT ME!
* @param height
- * DOCUMENT ME!
+ * DOCUMENT ME!
*/
// String type;
// SequenceFeature sf;
if (sequenceFeatures[sfindex].begin <= start
&& sequenceFeatures[sfindex].end >= start)
{
- currentColour = av.featuresDisplayed
- .get(sequenceFeatures[sfindex].type);
+ 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,
- 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,
- new Color(((Integer) av.featuresDisplayed
- .get(sequenceFeatures[sfindex].type)).intValue()),
- start, end, y1);
+ 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
{
- renderFeature(g, seq, seq
+ if (showFeature(sequenceFeatures[sfindex]))
+ { renderFeature(g, seq, seq
.findIndex(sequenceFeatures[sfindex].begin) - 1, seq
.findIndex(sequenceFeatures[sfindex].end) - 1,
- getColour(sequenceFeatures[sfindex].type), start, end, y1);
+ getColour(sequenceFeatures[sfindex]), start, end, y1);
+ }
}
}
}
}
+ Hashtable minmax = null;
+
void findAllFeatures()
{
jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme();
av.featuresDisplayed = new Hashtable();
Vector allfeatures = new Vector();
+ minmax = new Hashtable();
+
for (int i = 0; i < av.alignment.getHeight(); i++)
{
SequenceFeature[] features = av.alignment.getSequenceAt(i)
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)
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++;
}
}
}
}
- public Color getColour(String featureType)
+ /**
+ * 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)
{
- if (!featureColours.containsKey(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, col);
- return col;
+ featureColours.put(featureType, fc = col);
+ }
+ return fc;
+ }
+
+ public Color getColour(String featureType)
+ {
+ Object fc = getFeatureStyle(featureType);
+
+ if (fc instanceof Color)
+ {
+ return (Color) fc;
}
else
- return (Color) featureColours.get(featureType);
+ {
+ if (fc instanceof GraduatedColor)
+ {
+ return ((GraduatedColor) fc).getMaxColor();
+ }
+ }
+ throw new Error("Implementation Error: Unrecognised render object "
+ + fc.getClass() + " for features of type " + featureType);
+ }
+ /**
+ *
+ * @param sequenceFeature
+ * @return true if feature is visible.
+ */
+ private boolean showFeature(SequenceFeature sequenceFeature)
+ {
+ Object fc = getFeatureStyle(sequenceFeature.type);
+ if (fc instanceof GraduatedColor)
+ {
+ return ((GraduatedColor) fc).isColored(sequenceFeature);
+ } else { return true; }
+ }
+
+ /**
+ * implement graduated colouring for features with scores
+ *
+ * @param feature
+ * @return render colour for the given feature
+ */
+ public Color getColour(SequenceFeature feature)
+ {
+ Object fc = getFeatureStyle(feature.getType());
+ if (fc instanceof Color)
+ {
+ return (Color) fc;
+ }
+ else
+ {
+ if (fc instanceof GraduatedColor)
+ {
+ return ((GraduatedColor) fc).findColor(feature);
+ }
+ }
+ throw new Error("Implementation Error: Unrecognised render object "
+ + fc.getClass() + " for features of type " + feature.getType());
}
- public void setColour(String featureType, Color col)
+ public void setColour(String featureType, Object col)
{
- featureColours.put(featureType, 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)
for (int i = 0; i < data.length; i++)
{
String type = data[i][0].toString();
- setColour(type, (Color) data[i][1]);
+ setColour(type, data[i][1]);
if (((Boolean) data[i][2]).booleanValue())
{
av.featuresDisplayed.put(type, new Integer(getColour(type)
* get visible or invisible groups
*
* @param visible
- * true to return visible groups, false to return hidden ones.
+ * true to return visible groups, false to return hidden ones.
* @return list of groups
*/
public String[] getGroups(boolean visible)
* set all feature groups in toset to be visible or invisible
*
* @param toset
- * group names
+ * group names
* @param visible
- * the state of the named groups to set
+ * the state of the named groups to set
*/
public void setGroupState(String[] toset, boolean visible)
{
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