ACTACGACACGACGACGACGACG
>seq2
CDEQEATGTQDAQEQAQC
-
package jalview.api;
+import jalview.datamodel.SequenceFeature;
+
import java.awt.Color;
public interface FeatureColourI
{
/**
- * Answers true when either isColourByLabel, isAboveThreshold or
- * isBelowThreshold answers true
+ * Answers true when the feature colour varies across the score range
*
* @return
*/
Color getMaxColour();
/**
- * Answers true if the feature is coloured by label (description); only
- * applicable when isGraduatedColour answers true
+ * Answers true if the feature has a single colour, i.e. if isColourByLabel()
+ * and isGraduatedColour() both answer false
+ *
+ * @return
+ */
+ boolean isSimpleColour();
+
+ /**
+ * Answers true if the feature is coloured by label (description)
*
* @return
*/
boolean isColourByLabel();
+ void setColourByLabel(boolean b);
+
/**
* Answers true if the feature is coloured below a threshold value; only
* applicable when isGraduatedColour answers true
*/
boolean isBelowThreshold();
+ void setBelowThreshold(boolean b);
+
/**
* Answers true if the feature is coloured above a threshold value; only
* applicable when isGraduatedColour answers true
*/
boolean isAboveThreshold();
+ void setAboveThreshold(boolean b);
+
/**
- * Answers true if the threshold is the min (or max) of the colour range; only
- * applicable when isGraduatedColour answers true
+ * Answers true if the threshold is the minimum value (when
+ * isAboveThreshold()) or maximum value (when isBelowThreshold()) of the
+ * colour range; only applicable when isGraduatedColour and either
+ * isAboveThreshold() or isBelowThreshold() answers true
*
* @return
*/
boolean isThresholdMinMax();
+ void setThresholdMinMax(boolean b);
+
/**
* Returns the threshold value (if any), else zero
*
*/
float getThreshold();
+ void setThreshold(float f);
+
+ /**
+ * Answers true if the colour varies between the actual minimum and maximum
+ * score values of the feature, or false if between absolute minimum and
+ * maximum values (or if not a graduated colour).
+ *
+ * @return
+ */
+ boolean isAutoScaled();
+
+ void setAutoScaled(boolean b);
+
+ /**
+ * Returns the maximum score of the graduated colour range
+ *
+ * @return
+ */
+ float getMax();
+
+ /**
+ * Returns the minimum score of the graduated colour range
+ *
+ * @return
+ */
+ float getMin();
+
+ /**
+ * Answers true if either isAboveThreshold or isBelowThreshold answers true
+ *
+ * @return
+ */
+ boolean hasThreshold();
+
+ /**
+ * Returns the computed colour for the given sequence feature
+ *
+ * @param feature
+ * @return
+ */
+ Color getColor(SequenceFeature feature);
+
+ /**
+ * Answers true if the feature has a simple colour, or is coloured by label,
+ * or has a graduated colour and the score of this feature instance is within
+ * the range to render (if any), i.e. does not lie below or above any
+ * threshold set.
+ *
+ * @param feature
+ * @return
+ */
+ boolean isColored(SequenceFeature feature);
+
+ /**
+ * Update the min-max range for a graduated colour scheme
+ *
+ * @param min
+ * @param max
+ */
+ void updateBounds(float min, float max);
+
/**
- * Answers true if ?
+ * Returns the colour in Jalview features file format
*
* @return
*/
- boolean isLowToHigh();
+ String toJalviewFormat(String featureType);
}
* @param ft
* @return display style for a feature
*/
- Object getFeatureStyle(String ft);
+ FeatureColourI getFeatureStyle(String ft);
/**
* update the feature style for a particular feature
*
* @param ft
* @param ggc
- * - currently allows java.awt.Color and
- * jalview.schemes.GraduatedColor
*/
- void setColour(String ft, Object ggc);
+ void setColour(String ft, FeatureColourI ggc);
AlignViewportI getViewport();
*
* @return
*/
- Map<String, Object> getFeatureColours();
+ Map<String, FeatureColourI> getFeatureColours();
/**
* query the alignment view to find all features
*
* @return
*/
- Map<String, Object> getDisplayedFeatureCols();
+ Map<String, FeatureColourI> getDisplayedFeatureCols();
/**
* get all registered groups
import jalview.api.AlignViewControllerGuiI;
import jalview.api.AlignViewControllerI;
import jalview.api.AlignViewportI;
+import jalview.api.FeatureColourI;
import jalview.api.FeatureRenderer;
import jalview.api.FeatureSettingsControllerI;
import jalview.api.SequenceStructureBinding;
boolean featuresFile = false;
try
{
- Map<String, Object> colours = alignPanel.seqPanel.seqCanvas
+ Map<String, FeatureColourI> colours = alignPanel.seqPanel.seqCanvas
.getFeatureRenderer().getFeatureColours();
boolean relaxedIdMatching = viewport.applet.getDefaultParameter(
"relaxedidmatch", false);
return annotation;
}
- private Map<String, Object> getDisplayedFeatureCols()
+ private Map<String, FeatureColourI> getDisplayedFeatureCols()
{
if (alignPanel.getFeatureRenderer() != null
&& viewport.getFeaturesDisplayed() != null)
*/
package jalview.appletgui;
+import jalview.api.FeatureColourI;
import jalview.datamodel.GraphLine;
import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
import jalview.util.MessageManager;
import java.awt.Checkbox;
// AlignmentPanel ap;
- GraduatedColor cs;
+ FeatureColourI cs;
- Object oldcs;
+ FeatureColourI oldcs;
Hashtable oldgroupColours;
{
this.type = type;
fr = frenderer;
- float mm[] = ((float[][]) fr.getMinMax().get(type))[0];
+ float mm[] = fr.getMinMax().get(type)[0];
min = mm[0];
max = mm[1];
oldcs = fr.getFeatureColours().get(type);
- if (oldcs instanceof GraduatedColor)
+ if (oldcs.isGraduatedColour())
{
- cs = new GraduatedColor((GraduatedColor) oldcs, min, max);
+ cs = new FeatureColour((FeatureColour) oldcs, min, max);
}
else
{
// promote original color to a graduated color
Color bl = Color.black;
- if (oldcs instanceof Color)
+ if (oldcs.isSimpleColour())
{
- bl = (Color) oldcs;
+ bl = oldcs.getColour();
}
// original colour becomes the maximum colour
- cs = new GraduatedColor(Color.white, bl, mm[0], mm[1]);
+ cs = new FeatureColour(Color.white, bl, mm[0], mm[1]);
}
- minColour.setBackground(cs.getMinColor());
- maxColour.setBackground(cs.getMaxColor());
- minColour.setForeground(cs.getMinColor());
- maxColour.setForeground(cs.getMaxColor());
+ minColour.setBackground(cs.getMinColour());
+ maxColour.setBackground(cs.getMaxColour());
+ minColour.setForeground(cs.getMinColour());
+ maxColour.setForeground(cs.getMaxColour());
colourFromLabel.setState(cs.isColourByLabel());
adjusting = true;
} catch (Exception ex)
{
}
- threshold
- .select(cs.getThreshType() == AnnotationColourGradient.NO_THRESHOLD ? 0
- : cs.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD ? 1
- : 2);
+ threshold.select(cs.isAboveThreshold() ? 1 : (cs.isBelowThreshold() ? 2
+ : 0));
adjusting = false;
changeColour();
private GraphLine threshline;
+ @Override
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == thresholdValue)
}
}
+ @Override
public void itemStateChanged(ItemEvent evt)
{
maxColour.setEnabled(!colourFromLabel.getState());
changeColour();
}
+ @Override
public void adjustmentValueChanged(AdjustmentEvent evt)
{
if (!adjusting)
{
- thresholdValue.setText(((float) slider.getValue() / 1000f) + "");
+ thresholdValue.setText((slider.getValue() / 1000f) + "");
valueChanged();
}
}
protected void valueChanged()
{
- threshline.value = (float) slider.getValue() / 1000f;
- cs.setThresh(threshline.value);
+ threshline.value = slider.getValue() / 1000f;
+ cs.setThreshold(threshline.value);
changeColour();
PaintRefresher.Refresh(this, fr.getViewport().getSequenceSetId());
// ap.paintAlignment(false);
slider.setEnabled(true);
thresholdValue.setEnabled(true);
- GraduatedColor acg = new GraduatedColor(minColour.getBackground(),
+ FeatureColour acg = new FeatureColour(minColour.getBackground(),
maxColour.getBackground(), min, max);
acg.setColourByLabel(colourFromLabel.getState());
if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
{
adjusting = true;
- acg.setThresh(threshline.value);
+ acg.setThreshold(threshline.value);
float range = max * 1000f - min * 1000f;
adjusting = false;
}
- acg.setThreshType(aboveThreshold);
+ acg.setAboveThreshold(true);
if (thresholdIsMin.getState()
&& aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
{
if (aboveThreshold == AnnotationColourGradient.ABOVE_THRESHOLD)
{
- acg = new GraduatedColor(acg, threshline.value, max);
+ acg = new FeatureColour(acg, threshline.value, max);
}
else
{
- acg = new GraduatedColor(acg, min, threshline.value);
+ acg = new FeatureColour(acg, min, threshline.value);
}
}
}
+ @Override
public void mouseClicked(MouseEvent evt)
{
}
+ @Override
public void mousePressed(MouseEvent evt)
{
}
+ @Override
public void mouseReleased(MouseEvent evt)
{
if (evt.getSource() == minColour || evt.getSource() == maxColour)
// ap.paintAlignment(true);
}
+ @Override
public void mouseEntered(MouseEvent evt)
{
}
+ @Override
public void mouseExited(MouseEvent evt)
{
}
*/
package jalview.appletgui;
+import jalview.api.FeatureColourI;
import jalview.datamodel.SearchResults;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
-import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.GraduatedColor;
+import jalview.io.FeaturesFile;
+import jalview.schemes.FeatureColour;
+import jalview.schemes.UserColourScheme;
import jalview.util.MessageManager;
import jalview.viewmodel.AlignmentViewport;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.Hashtable;
/**
* DOCUMENT ME!
public class FeatureRenderer extends
jalview.renderer.seqfeatures.FeatureRenderer
{
+
+ // Holds web links for feature groups and feature types
+ // in the form label|link
+ Hashtable featureLinks = null;
+
/**
* Creates a new FeatureRenderer object.
*
* @param av
- * DOCUMENT ME!
*/
public FeatureRenderer(AlignmentViewport av)
{
/**
* render a feature style in the amend feature dialog box
*/
- public void updateColor(Object newcol)
+ public void updateColor(FeatureColourI newcol)
{
-
- Color bg, col = null;
- GraduatedColor gcol = null;
+ Color bg = null;
String vlabel = "";
- if (newcol instanceof Color)
+ if (newcol.isSimpleColour())
{
- isGcol = false;
- col = (Color) newcol;
- gcol = null;
- }
- else if (newcol instanceof GraduatedColor)
- {
- isGcol = true;
- gcol = (GraduatedColor) newcol;
- col = null;
+ bg = newcol.getColour();
+ setBackground(bg);
}
else
{
- throw new Error(
- MessageManager
- .getString("error.invalid_colour_for_mycheckbox"));
- }
- if (col != null)
- {
- setBackground(bg = col);
- }
- else
- {
- if (gcol.getThreshType() != AnnotationColourGradient.NO_THRESHOLD)
+ if (newcol.isAboveThreshold())
{
- vlabel += " "
- + ((gcol.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD) ? "(>)"
- : "(<)");
+ vlabel += " (>)";
}
- if (isColourByLabel = gcol.isColourByLabel())
+ else if (newcol.isBelowThreshold())
+ {
+ vlabel += " (<)";
+ }
+
+ if (isColourByLabel = newcol.isColourByLabel())
{
setBackground(bg = Color.white);
vlabel += " (by Label)";
}
else
{
- setBackground(bg = gcol.getMinColor());
- maxCol = gcol.getMaxColor();
+ setBackground(bg = newcol.getMinColour());
+ maxCol = newcol.getMaxColour();
}
}
label = vlabel;
ap.seqPanel.seqCanvas.highlightSearchResults(highlight);
}
- Object col = getFeatureStyle(name.getText());
+ FeatureColourI col = getFeatureStyle(name.getText());
if (col == null)
{
- col = new jalview.schemes.UserColourScheme()
+ Color generatedColour = UserColourScheme
.createColourFromName(name.getText());
+ col = new FeatureColour(generatedColour);
}
colourPanel.updateColor(col);
start.setText(features[0].getBegin() + "");
end.setText(features[0].getEnd() + "");
description.setText(features[0].getDescription());
- Object fcol = getFeatureStyle(name.getText());
+ // lookup (or generate) the feature colour
+ FeatureColourI 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()
+ colourPanel.addMouseListener(new MouseAdapter()
{
@Override
- public void mousePressed(java.awt.event.MouseEvent evt)
+ public void mousePressed(MouseEvent evt)
{
if (!colourPanel.isGcol)
{
}
else
{
- FeatureColourChooser fcc = new FeatureColourChooser(
- ap.alignFrame, name.getText());
+ new FeatureColourChooser(ap.alignFrame, name.getText());
dialog.transferFocus();
}
}
});
dialog.setVisible(true);
- jalview.io.FeaturesFile ffile = new jalview.io.FeaturesFile();
+ FeaturesFile ffile = new FeaturesFile();
if (dialog.accept)
{
if (!colourPanel.isGcol)
{
// update colour - otherwise its already done.
- setColour(sf.type, colourPanel.getBackground());
+ setColour(sf.type, new FeatureColour(colourPanel.getBackground()));
}
try
{
{
setGroupVisibility(lastFeatureGroupAdded, true);
}
- setColour(lastFeatureAdded, newColour); // was fcol
+ setColour(lastFeatureAdded, new FeatureColour(newColour)); // was fcol
setVisible(lastFeatureAdded);
findAllFeatures(false); // different to original applet behaviour ?
// findAllFeatures();
*/
package jalview.appletgui;
+import jalview.api.FeatureColourI;
import jalview.api.FeatureSettingsControllerI;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceFeature;
-import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.GraduatedColor;
import jalview.util.MessageManager;
import java.awt.BorderLayout;
int x, int y)
{
final String type = check.type;
- final Object typeCol = fr.getFeatureStyle(type);
- java.awt.PopupMenu men = new PopupMenu(MessageManager.formatMessage(
+ final FeatureColourI typeCol = fr.getFeatureStyle(type);
+ PopupMenu men = new PopupMenu(MessageManager.formatMessage(
"label.settings_for_type", new String[] { type }));
java.awt.MenuItem scr = new MenuItem(
MessageManager.getString("label.sort_by_score"));
// graduated colourschemes for those where minmax exists for the
// positional features
MenuItem mxcol = new MenuItem(
- (typeCol instanceof Color) ? "Graduated Colour"
+ (typeCol.isSimpleColour()) ? "Graduated Colour"
: "Single Colour");
men.add(mxcol);
mxcol.addActionListener(new ActionListener()
@Override
public void actionPerformed(ActionEvent e)
{
- if (typeCol instanceof Color)
+ if (typeCol.isSimpleColour())
{
new FeatureColourChooser(me, type);
// write back the current colour object to update the table
}
else
{
- new UserDefinedColours(me, check.type,
- ((GraduatedColor) typeCol));
+ new UserDefinedColours(me, check.type, typeCol);
}
}
}
}
- public void setUserColour(String feature, Object originalColour)
+ public void setUserColour(String feature, FeatureColourI originalColour)
{
- if (originalColour instanceof Color
- || originalColour instanceof GraduatedColor)
- {
- fr.setColour(feature, originalColour);
- }
- else
- {
- throw new Error(
- MessageManager
- .getString("error.implementation_error_unsupported_feature_colour_object"));
- }
+ fr.setColour(feature, originalColour);
refreshTable();
}
if (evt.getClickCount() > 1)
{
- Object fcol = fr.getFeatureStyle(check.type);
- if (fcol instanceof Color)
+ FeatureColourI fcol = fr.getFeatureStyle(check.type);
+ if (fcol.isSimpleColour())
{
- new UserDefinedColours(this, check.type, (Color) fcol);
+ new UserDefinedColours(this, check.type, fcol.getColour());
}
else
{
boolean hasLink;
- GraduatedColor gcol;
+ FeatureColourI col;
- Color col;
-
- public void updateColor(Object newcol)
+ public void updateColor(FeatureColourI newcol)
{
- if (newcol instanceof Color)
- {
- col = (Color) newcol;
- gcol = null;
- }
- else if (newcol instanceof GraduatedColor)
+ col = newcol;
+ if (col.isSimpleColour())
{
- gcol = (GraduatedColor) newcol;
- col = null;
- }
- else
- {
- throw new Error(
- MessageManager
- .getString("error.invalid_colour_for_mycheckbox"));
- }
- if (col != null)
- {
- setBackground(col);
+ setBackground(col.getColour());
}
else
{
String vlabel = type;
- if (gcol.getThreshType() != AnnotationColourGradient.NO_THRESHOLD)
+ if (col.isAboveThreshold())
{
- vlabel += " "
- + ((gcol.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD) ? "(>)"
- : "(<)");
+ vlabel += " (>)";
}
- if (gcol.isColourByLabel())
+ else if (col.isBelowThreshold())
+ {
+ vlabel += " (<)";
+ }
+ if (col.isColourByLabel())
{
setBackground(Color.white);
vlabel += " (by Label)";
}
else
{
- setBackground(gcol.getMinColor());
+ setBackground(col.getMinColour());
}
this.setLabel(vlabel);
}
}
public MyCheckbox(String type, boolean selected, boolean b,
- Object featureStyle)
+ FeatureColourI featureStyle)
{
this(type, selected, b);
updateColor(featureStyle);
public void paint(Graphics g)
{
Dimension d = getSize();
- if (gcol != null)
+ if (col.isColourByLabel())
{
- if (gcol.isColourByLabel())
- {
- g.setColor(Color.white);
- g.fillRect(d.width / 2, 0, d.width / 2, d.height);
- /*
- * g.setColor(Color.black); Font f=g.getFont().deriveFont(9);
- * g.setFont(f);
- *
- * // g.setFont(g.getFont().deriveFont( //
- * AffineTransform.getScaleInstance( //
- * width/g.getFontMetrics().stringWidth("Label"), //
- * height/g.getFontMetrics().getHeight()))); g.drawString("Label",
- * width/2, 0);
- */
+ g.setColor(Color.white);
+ g.fillRect(d.width / 2, 0, d.width / 2, d.height);
+ /*
+ * g.setColor(Color.black); Font f=g.getFont().deriveFont(9);
+ * g.setFont(f);
+ *
+ * // g.setFont(g.getFont().deriveFont( //
+ * AffineTransform.getScaleInstance( //
+ * width/g.getFontMetrics().stringWidth("Label"), //
+ * height/g.getFontMetrics().getHeight()))); g.drawString("Label",
+ * width/2, 0);
+ */
- }
- else
- {
- Color maxCol = gcol.getMaxColor();
- g.setColor(maxCol);
- g.fillRect(d.width / 2, 0, d.width / 2, d.height);
+ }
+ else if (col.isGraduatedColour())
+ {
+ Color maxCol = col.getMaxColour();
+ g.setColor(maxCol);
+ g.fillRect(d.width / 2, 0, d.width / 2, d.height);
- }
}
if (hasLink)
}
}
- @Override
- public void mousePressed(MouseEvent e)
- {
- }
-
/**
* Hide columns containing (or not containing) a given feature type
*
}
}
+ @Override
+ public void mousePressed(MouseEvent e)
+ {
+ // TODO Auto-generated method stub
+
+ }
+
}
*/
package jalview.appletgui;
+import jalview.api.FeatureColourI;
import jalview.datamodel.SequenceGroup;
import jalview.schemes.ColourSchemeI;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
import jalview.schemes.ResidueProperties;
import jalview.schemes.UserColourScheme;
import jalview.util.MessageManager;
Button selectedButton;
- Vector oldColours = new Vector();
+ Vector<Color> oldColours = new Vector<Color>();
ColourSchemeI oldColourScheme;
String originalLabel;
- Object originalColour;
+ FeatureColourI originalColour;
int R = 0, G = 0, B = 0;
public UserDefinedColours(FeatureRenderer fr, Frame alignframe)
{
caller = fr;
- originalColour = fr.colourPanel.getBackground();
+ originalColour = new FeatureColour(fr.colourPanel.getBackground());
originalLabel = "Feature Colour";
setForDialog("Select Feature Colour", alignframe);
setTargetColour(fr.colourPanel.getBackground());
*
* @param caller
* - handles events
- * @param col1
+ * @param col
* - original colour
* @param alignframe
* - the parent Frame for the dialog
* @param title
* - window title
*/
- public UserDefinedColours(Component caller, Color col1, Frame alignframe,
+ public UserDefinedColours(Component caller, Color col, Frame alignframe,
String title)
{
this.caller = caller;
- originalColour = col1;
+ originalColour = new FeatureColour(col);
originalLabel = title;
setForDialog(title, alignframe);
- setTargetColour(col1);
+ setTargetColour(col);
dialog.setVisible(true);
}
*/
public UserDefinedColours(Object caller, String label, Color colour)
{
- this(caller, label, colour, colour);
+ this(caller, label, new FeatureColour(colour), colour);
}
/**
* @param graduatedColor
*/
public UserDefinedColours(FeatureSettings me, String type,
- GraduatedColor graduatedColor)
+ FeatureColourI graduatedColor)
{
- this(me, type, graduatedColor, graduatedColor.getMaxColor());
+ this(me, type, graduatedColor, graduatedColor.getMaxColour());
}
- private UserDefinedColours(Object caller, String label, Object ocolour,
- Color colour)
+ private UserDefinedColours(Object caller, String label,
+ FeatureColourI ocolour, Color colour)
{
this.caller = caller;
originalColour = ocolour;
}
+ @Override
public void actionPerformed(ActionEvent evt)
{
final Object source = evt.getSource();
}
}
+ @Override
public void adjustmentValueChanged(AdjustmentEvent evt)
{
if (evt.getSource() == rScroller)
button.setFont(new java.awt.Font("Verdana", 1, 10));
button.addMouseListener(new java.awt.event.MouseAdapter()
{
+ @Override
public void mousePressed(MouseEvent e)
{
colourButtonPressed(e);
{
if (caller instanceof FeatureSettings)
{
- ((FeatureSettings) caller).setUserColour(originalLabel, getColor());
+ ((FeatureSettings) caller).setUserColour(originalLabel,
+ new FeatureColour(getColor()));
}
else if (caller instanceof AnnotationColourChooser)
{
}
else if (caller instanceof FeatureRenderer)
{
- ((FeatureRenderer) caller).colourPanel.updateColor(getColor());
+ ((FeatureRenderer) caller).colourPanel
+ .updateColor(new FeatureColour(getColor()));
}
else if (caller instanceof FeatureColourChooser)
{
if (originalLabel.equals("Min Colour"))
{
((AnnotationColourChooser) caller)
- .minColour_actionPerformed((Color) originalColour);
+ .minColour_actionPerformed(originalColour.getColour());
}
else
{
((AnnotationColourChooser) caller)
- .maxColour_actionPerformed((Color) originalColour);
+ .maxColour_actionPerformed(originalColour.getColour());
}
}
else if (caller instanceof FeatureRenderer)
if (originalLabel.indexOf("inimum") > -1)
{
((FeatureColourChooser) caller)
- .minColour_actionPerformed((Color) originalColour);
+ .minColour_actionPerformed(originalColour.getColour());
}
else
{
((FeatureColourChooser) caller)
- .maxColour_actionPerformed((Color) originalColour);
+ .maxColour_actionPerformed(originalColour.getColour());
}
}
if (dialog != null)
Color[] newColours = new Color[24];
for (int i = 0; i < 24; i++)
{
- newColours[i] = (Color) oldColours.elementAt(i);
+ newColours[i] = oldColours.elementAt(i);
buttonPanel.getComponent(i).setBackground(newColours[i]);
}
import jalview.datamodel.SequenceI;
import jalview.io.gff.SequenceOntologyFactory;
import jalview.io.gff.SequenceOntologyI;
-import jalview.schemes.FeatureColourAdapter;
+import jalview.schemes.FeatureColour;
import jalview.schemes.FeatureSettingsAdapter;
import jalview.util.MapList;
{
if (so.isA(type, SequenceOntologyI.EXON))
{
- return new FeatureColourAdapter()
+ return new FeatureColour()
{
@Override
public boolean isColourByLabel()
}
if (so.isA(type, SequenceOntologyI.SEQUENCE_VARIANT))
{
- return new FeatureColourAdapter()
+ return new FeatureColour()
{
@Override
*/
package jalview.gui;
+import jalview.api.FeatureColourI;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.SequenceI;
import jalview.io.AnnotationFile;
.getString("label.no_features_on_alignment");
if (features)
{
+ Map<String, FeatureColourI> displayedFeatureColours = ap
+ .getFeatureRenderer().getDisplayedFeatureCols();
FeaturesFile formatter = new FeaturesFile();
SequenceI[] sequences = ap.av.getAlignment().getSequencesArray();
- Map<String, Object> featureColours = ap.getFeatureRenderer()
+ Map<String, FeatureColourI> featureColours = ap.getFeatureRenderer()
.getDisplayedFeatureCols();
boolean includeNonPositional = ap.av.isShowNPFeats();
if (GFFFormat.isSelected())
{
+ text = new FeaturesFile().printGffFormat(ap.av.getAlignment()
+ .getDataset().getSequencesArray(), displayedFeatureColours,
+ true, ap.av.isShowNPFeats());
text = formatter.printGffFormat(sequences, featureColours, true,
includeNonPositional);
}
else
{
+ text = new FeaturesFile().printJalviewFormat(ap.av.getAlignment()
+ .getDataset().getSequencesArray(), displayedFeatureColours, true, ap.av.isShowNPFeats()); // ap.av.featuresDisplayed);
text = formatter.printJalviewFormat(sequences, featureColours,
true, includeNonPositional);
}
*/
package jalview.gui;
+import jalview.api.FeatureColourI;
import jalview.datamodel.GraphLine;
-import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
import jalview.util.MessageManager;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
-import java.util.Hashtable;
import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
// FeatureSettings fs;
FeatureRenderer fr;
- private GraduatedColor cs;
+ private FeatureColourI cs;
- private Object oldcs;
+ private FeatureColourI oldcs;
/**
*
* @return the last colour setting selected by user - either oldcs (which may
* be a java.awt.Color) or the new GraduatedColor
*/
- public Object getLastColour()
+ public FeatureColourI getLastColour()
{
if (cs == null)
{
return cs;
}
- Hashtable oldgroupColours;
-
AlignmentPanel ap;
boolean adjusting = false;
}
});
- float mm[] = ((float[][]) fr.getMinMax().get(type))[0];
+ float mm[] = fr.getMinMax().get(type)[0];
min = mm[0];
max = mm[1];
scaleFactor = (max == min) ? 1f : 100f / (max - min);
oldcs = fr.getFeatureColours().get(type);
- if (oldcs instanceof GraduatedColor)
+ if (!oldcs.isSimpleColour())
{
- if (((GraduatedColor) oldcs).isAutoScale())
+ if (oldcs.isAutoScaled())
{
// update the scale
- cs = new GraduatedColor((GraduatedColor) oldcs, min, max);
+ cs = new FeatureColour((FeatureColour) oldcs, min, max);
}
else
{
- cs = new GraduatedColor((GraduatedColor) oldcs);
+ cs = new FeatureColour((FeatureColour) oldcs);
}
}
else
{
// promote original color to a graduated color
- Color bl = Color.black;
- if (oldcs instanceof Color)
+ Color bl = oldcs.getColour();
+ if (bl == null)
{
- bl = (Color) oldcs;
+ bl = Color.BLACK;
}
// original colour becomes the maximum colour
- cs = new GraduatedColor(Color.white, bl, mm[0], mm[1]);
+ cs = new FeatureColour(Color.white, bl, mm[0], mm[1]);
cs.setColourByLabel(false);
}
- minColour.setBackground(oldminColour = cs.getMinColor());
- maxColour.setBackground(oldmaxColour = cs.getMaxColor());
+ minColour.setBackground(oldminColour = cs.getMinColour());
+ maxColour.setBackground(oldmaxColour = cs.getMaxColour());
adjusting = true;
try
{
}
// update the gui from threshold state
- thresholdIsMin.setSelected(!cs.isAutoScale());
+ thresholdIsMin.setSelected(!cs.isAutoScaled());
colourByLabel.setSelected(cs.isColourByLabel());
- if (cs.getThreshType() != AnnotationColourGradient.NO_THRESHOLD)
+ if (cs.hasThreshold())
{
// initialise threshold slider and selector
- threshold
- .setSelectedIndex(cs.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD ? 1
- : 2);
+ threshold.setSelectedIndex(cs.isAboveThreshold() ? 1 : 2);
slider.setEnabled(true);
thresholdValue.setEnabled(true);
- threshline = new jalview.datamodel.GraphLine((max - min) / 2f,
- "Threshold", Color.black);
+ threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black);
}
return;
}
- int aboveThreshold = AnnotationColourGradient.NO_THRESHOLD;
+ boolean aboveThreshold = false;
+ boolean belowThreshold = false;
if (threshold.getSelectedIndex() == 1)
{
- aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;
+ aboveThreshold = true;
}
else if (threshold.getSelectedIndex() == 2)
{
- aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;
+ belowThreshold = true;
}
+ boolean hasThreshold = aboveThreshold || belowThreshold;
slider.setEnabled(true);
thresholdValue.setEnabled(true);
- GraduatedColor acg;
+ FeatureColourI acg;
if (cs.isColourByLabel())
{
- acg = new GraduatedColor(oldminColour, oldmaxColour, min, max);
+ acg = new FeatureColour(oldminColour, oldmaxColour, min, max);
}
else
{
- acg = new GraduatedColor(oldminColour = minColour.getBackground(),
+ acg = new FeatureColour(oldminColour = minColour.getBackground(),
oldmaxColour = maxColour.getBackground(), min, max);
}
- if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)
+ if (!hasThreshold)
{
slider.setEnabled(false);
thresholdValue.setEnabled(false);
thresholdValue.setText("");
thresholdIsMin.setEnabled(false);
}
- else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD
- && threshline == null)
+ else if (threshline == null)
{
// todo visual indication of feature threshold
- threshline = new jalview.datamodel.GraphLine((max - min) / 2f,
- "Threshold", Color.black);
+ threshline = new GraphLine((max - min) / 2f, "Threshold", Color.black);
}
- if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
+ if (hasThreshold)
{
adjusting = true;
- acg.setThresh(threshline.value);
+ acg.setThreshold(threshline.value);
float range = (max - min) * scaleFactor;
adjusting = false;
}
- acg.setThreshType(aboveThreshold);
- if (thresholdIsMin.isSelected()
- && aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
+ acg.setAboveThreshold(aboveThreshold);
+ acg.setBelowThreshold(belowThreshold);
+ if (thresholdIsMin.isSelected() && hasThreshold)
{
acg.setAutoScaled(false);
- if (aboveThreshold == AnnotationColourGradient.ABOVE_THRESHOLD)
+ if (aboveThreshold)
{
- acg = new GraduatedColor(acg, threshline.value, max);
+ acg = new FeatureColour((FeatureColour) acg, threshline.value, max);
}
else
{
- acg = new GraduatedColor(acg, min, threshline.value);
+ acg = new FeatureColour((FeatureColour) acg, min, threshline.value);
}
}
else
public void valueChanged()
{
threshline.value = slider.getValue() / scaleFactor;
- cs.setThresh(threshline.value);
+ cs.setThreshold(threshline.value);
changeColour();
ap.paintAlignment(false);
}
*/
package jalview.gui;
+import jalview.api.FeatureColourI;
import jalview.datamodel.SearchResults;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
+import jalview.schemes.UserColourScheme;
import jalview.util.MessageManager;
import java.awt.BorderLayout;
static String lastDescriptionAdded;
- Object oldcol, fcol;
+ FeatureColourI oldcol, fcol;
int featureIndex = 0;
@Override
public void mousePressed(MouseEvent evt)
{
- if (fcol instanceof Color)
+ if (fcol.isSimpleColour())
{
Color col = JColorChooser.showDialog(Desktop.desktop,
MessageManager.getString("label.select_feature_colour"),
- ((Color) fcol));
+ fcol.getColour());
if (col != null)
{
- fcol = col;
- updateColourButton(bigPanel, colour, col);
+ fcol = new FeatureColour(col);
+ updateColourButton(bigPanel, colour, new FeatureColour(col));
}
}
else
{
-
if (fcc == null)
{
final String type = features[featureIndex].getType();
ap.getSeqPanel().seqCanvas.highlightSearchResults(highlight);
}
- Object col = getFeatureStyle(name.getText());
+ FeatureColourI col = getFeatureStyle(name.getText());
if (col == null)
{
- col = new jalview.schemes.UserColourScheme()
- .createColourFromName(name.getText());
+ col = new FeatureColour(UserColourScheme
+ .createColourFromName(name.getText()));
}
oldcol = fcol = col;
updateColourButton(bigPanel, colour, col);
*
* @param bigPanel
* @param col
- * @param col2
+ * @param col
*/
protected void updateColourButton(JPanel bigPanel, JLabel colour,
- Object col2)
+ FeatureColourI col)
{
colour.removeAll();
colour.setIcon(null);
colour.setToolTipText(null);
colour.setText("");
- if (col2 instanceof Color)
+ if (col.isSimpleColour())
{
- colour.setBackground((Color) col2);
+ colour.setBackground(col.getColour());
}
else
{
colour.setBackground(bigPanel.getBackground());
colour.setForeground(Color.black);
- FeatureSettings.renderGraduatedColor(colour, (GraduatedColor) col2);
- // colour.setForeground(colour.getBackground());
+ FeatureSettings.renderGraduatedColor(colour, col);
}
}
*/
package jalview.gui;
+import jalview.api.FeatureColourI;
import jalview.api.FeatureSettingsControllerI;
import jalview.bin.Cache;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.gui.Help.HelpId;
import jalview.io.JalviewFileChooser;
-import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.GraduatedColor;
+import jalview.schemabinding.version2.JalviewUserColours;
+import jalview.schemes.FeatureColour;
import jalview.util.Format;
import jalview.util.MessageManager;
+import jalview.util.Platform;
import jalview.util.QuickSort;
import jalview.viewmodel.AlignmentViewport;
import jalview.ws.dbsources.das.api.jalviewSourceI;
table.setDefaultEditor(Color.class, new ColorEditor(this));
- table.setDefaultEditor(GraduatedColor.class, new ColorEditor(this));
- table.setDefaultRenderer(GraduatedColor.class, new ColorRenderer());
+ table.setDefaultEditor(FeatureColour.class, new ColorEditor(this));
+ table.setDefaultRenderer(FeatureColour.class, new ColorRenderer());
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.addMouseListener(new MouseAdapter()
public void mousePressed(MouseEvent evt)
{
selectedRow = table.rowAtPoint(evt.getPoint());
- if (evt.isPopupTrigger())
+ if (SwingUtilities.isRightMouseButton(evt))
{
popupSort(selectedRow, (String) table.getValueAt(selectedRow, 0),
table.getValueAt(selectedRow, 1), fr.getMinMax(),
frame = new JInternalFrame();
frame.setContentPane(this);
- if (new jalview.util.Platform().isAMac())
+ if (Platform.isAMac())
{
Desktop.addInternalFrame(frame,
MessageManager.getString("label.sequence_feature_settings"),
final Object typeCol, final Map<String, float[][]> minmax, int x,
int y)
{
+ final FeatureColourI featureColour = (FeatureColourI) typeCol;
+
JPopupMenu men = new JPopupMenu(MessageManager.formatMessage(
"label.settings_for_param", new String[] { type }));
JMenuItem scr = new JMenuItem(
// positional features
final JCheckBoxMenuItem mxcol = new JCheckBoxMenuItem(
"Graduated Colour");
- mxcol.setSelected(!(typeCol instanceof Color));
+ mxcol.setSelected(!featureColour.isSimpleColour());
men.add(mxcol);
mxcol.addActionListener(new ActionListener()
{
{
if (e.getSource() == mxcol)
{
- if (typeCol instanceof Color)
+ if (featureColour.isSimpleColour())
{
FeatureColourChooser fc = new FeatureColourChooser(me.fr,
type);
"Select new Colour", true, // modal
colorChooser, this, // OK button handler
null); // no CANCEL button handler
- colorChooser.setColor(((GraduatedColor) typeCol)
- .getMaxColor());
+ colorChooser.setColor(featureColour.getMaxColour());
dialog.setVisible(true);
}
}
/**
* contains a float[3] for each feature type string. created by setTableData
*/
- Hashtable typeWidth = null;
+ Map<String, float[]> typeWidth = null;
@Override
synchronized public void discoverAllFeatureData()
{
- Vector allFeatures = new Vector();
- Vector allGroups = new Vector();
+ Vector<String> allFeatures = new Vector<String>();
+ Vector<String> allGroups = new Vector<String>();
SequenceFeature[] tmpfeatures;
String group;
for (int i = 0; i < af.getViewport().getAlignment().getHeight(); i++)
return;
}
resettingTable = true;
- typeWidth = new Hashtable();
+ typeWidth = new Hashtable<String, float[]>();
// TODO: change avWidth calculation to 'per-sequence' average and use long
// rather than float
float[] avWidth = null;
SequenceFeature[] tmpfeatures;
String group = null, type;
- Vector visibleChecks = new Vector();
+ Vector<String> visibleChecks = new Vector<String>();
// Find out which features should be visible depending on which groups
// are selected / deselected
}
else
{
- avWidth = (float[]) typeWidth.get(tmpfeatures[index].getType());
+ avWidth = typeWidth.get(tmpfeatures[index].getType());
}
avWidth[0]++;
if (tmpfeatures[index].getBegin() > tmpfeatures[index].getEnd())
InputStreamReader in = new InputStreamReader(new FileInputStream(
file), "UTF-8");
- jalview.schemabinding.version2.JalviewUserColours jucs = new jalview.schemabinding.version2.JalviewUserColours();
- jucs = jucs.unmarshal(in);
+ JalviewUserColours jucs = JalviewUserColours.unmarshal(in);
for (int i = jucs.getColourCount() - 1; i >= 0; i--)
{
Cache.log.warn("Couldn't parse out graduated feature color.",
e);
}
- GraduatedColor gcol = new GraduatedColor(mincol, maxcol,
+ FeatureColourI gcol = new FeatureColour(mincol, maxcol,
newcol.getMin(), newcol.getMax());
if (newcol.hasAutoScale())
{
}
if (newcol.hasThreshold())
{
- gcol.setThresh(newcol.getThreshold());
- gcol.setThreshType(AnnotationColourGradient.NO_THRESHOLD); // default
+ gcol.setThreshold(newcol.getThreshold());
}
if (newcol.getThreshType().length() > 0)
{
String ttyp = newcol.getThreshType();
- if (ttyp.equalsIgnoreCase("NONE"))
- {
- gcol.setThreshType(AnnotationColourGradient.NO_THRESHOLD);
- }
if (ttyp.equalsIgnoreCase("ABOVE"))
{
- gcol.setThreshType(AnnotationColourGradient.ABOVE_THRESHOLD);
+ gcol.setAboveThreshold(true);
}
if (ttyp.equalsIgnoreCase("BELOW"))
{
- gcol.setThreshType(AnnotationColourGradient.BELOW_THRESHOLD);
+ gcol.setBelowThreshold(true);
}
}
fr.setColour(name = newcol.getName(), gcol);
}
else
{
- fr.setColour(name = jucs.getColour(i).getName(), new Color(
- Integer.parseInt(jucs.getColour(i).getRGB(), 16)));
+ Color color = new Color(
+ Integer.parseInt(jucs.getColour(i).getRGB(), 16));
+ fr.setColour(name = jucs.getColour(i).getName(),
+ new FeatureColour(color));
}
fr.setOrder(name, (i == 0) ? 0 : i / jucs.getColourCount());
}
}
QuickSort.sort(sortOrder, sortTypes);
sortOrder = null;
- Object fcol;
- GraduatedColor gcol;
- for (String featureType : sortTypes)
+ for (i = 0; i < sortTypes.length; i++)
{
jalview.schemabinding.version2.Colour col = new jalview.schemabinding.version2.Colour();
- col.setName(featureType);
- fcol = fr.getFeatureStyle(featureType);
- Color colour = fcol instanceof Color ? (Color) fcol
- : ((GraduatedColor) fcol).getMaxColor();
- col.setRGB(Format.getHexString(colour));
- if (fcol instanceof GraduatedColor)
+ col.setName(sortTypes[i]);
+ FeatureColourI fcol = fr.getFeatureStyle(sortTypes[i]);
+ if (fcol.isSimpleColour())
{
- gcol = (GraduatedColor) fcol;
- col.setMin(gcol.getMin());
- col.setMax(gcol.getMax());
- col.setMinRGB(Format.getHexString(gcol
- .getMinColor()));
- col.setAutoScale(gcol.isAutoScale());
- col.setThreshold(gcol.getThresh());
- col.setColourByLabel(gcol.isColourByLabel());
- switch (gcol.getThreshType())
- {
- case AnnotationColourGradient.NO_THRESHOLD:
- col.setThreshType("NONE");
- break;
- case AnnotationColourGradient.ABOVE_THRESHOLD:
- col.setThreshType("ABOVE");
- break;
- case AnnotationColourGradient.BELOW_THRESHOLD:
- col.setThreshType("BELOW");
- break;
- }
+ col.setRGB(Format.getHexString(fcol.getColour()));
+ }
+ else
+ {
+ col.setRGB(Format.getHexString(fcol.getMaxColour()));
+ col.setMin(fcol.getMin());
+ col.setMax(fcol.getMax());
+ col.setMinRGB(jalview.util.Format.getHexString(fcol
+ .getMinColour()));
+ col.setAutoScale(fcol.isAutoScaled());
+ col.setThreshold(fcol.getThreshold());
+ col.setColourByLabel(fcol.isColourByLabel());
+ col.setThreshType(fcol.isAboveThreshold() ? "ABOVE" : (fcol
+ .isBelowThreshold() ? "BELOW" : "NONE"));
}
ucs.addColour(col);
}
int num = 0;
for (int i = 0; i < data.length; i++)
{
- awidth = (float[]) typeWidth.get(data[i][0]);
+ awidth = typeWidth.get(data[i][0]);
if (awidth[0] > 0)
{
width[i] = awidth[1] / awidth[0];// *awidth[0]*awidth[2]; - better
fetchDAS.setEnabled(false);
cancelDAS.setEnabled(true);
dassourceBrowser.setGuiEnabled(false);
- Vector selectedSources = dassourceBrowser.getSelectedSources();
+ Vector<jalviewSourceI> selectedSources = dassourceBrowser
+ .getSelectedSources();
doDasFeatureFetch(selectedSources, true, true);
}
* Vector of Strings to resolve to DAS source nicknames.
* @return sources that are present in source list.
*/
- public List<jalviewSourceI> resolveSourceNicknames(Vector sources)
+ public List<jalviewSourceI> resolveSourceNicknames(Vector<String> sources)
{
return dassourceBrowser.sourceRegistry.resolveSourceNicknames(sources);
}
* if true then runs in same thread, otherwise passes to the Swing
* executor
*/
- public void fetchDasFeatures(Vector sources, boolean block)
+ public void fetchDasFeatures(Vector<String> sources, boolean block)
{
initDasSources();
List<jalviewSourceI> resolved = dassourceBrowser.sourceRegistry
}
@Override
- public Component getTableCellRendererComponent(JTable table,
+ public Component getTableCellRendererComponent(JTable tbl,
Object color, boolean isSelected, boolean hasFocus, int row,
int column)
{
+ FeatureColourI cellColour = (FeatureColourI) color;
// JLabel comp = new JLabel();
// comp.
setOpaque(true);
// setBounds(getBounds());
Color newColor;
setToolTipText(baseTT);
- setBackground(table.getBackground());
- if (color instanceof GraduatedColor)
+ setBackground(tbl.getBackground());
+ if (!cellColour.isSimpleColour())
{
- Rectangle cr = table.getCellRect(row, column, false);
- FeatureSettings.renderGraduatedColor(this, (GraduatedColor) color,
+ Rectangle cr = tbl.getCellRect(row, column, false);
+ FeatureSettings.renderGraduatedColor(this, cellColour,
(int) cr.getWidth(), (int) cr.getHeight());
}
{
this.setText("");
this.setIcon(null);
- newColor = (Color) color;
- // comp.
+ newColor = cellColour.getColour();
setBackground(newColor);
- // comp.setToolTipText("RGB value: " + newColor.getRed() + ", "
- // + newColor.getGreen() + ", " + newColor.getBlue());
}
if (isSelected)
{
if (selectedBorder == null)
{
selectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5,
- table.getSelectionBackground());
+ tbl.getSelectionBackground());
}
- // comp.
setBorder(selectedBorder);
}
else
if (unselectedBorder == null)
{
unselectedBorder = BorderFactory.createMatteBorder(2, 5, 2, 5,
- table.getBackground());
+ tbl.getBackground());
}
- // comp.
setBorder(unselectedBorder);
}
* @param comp
* @param gcol
*/
- public static void renderGraduatedColor(JLabel comp, GraduatedColor gcol)
+ public static void renderGraduatedColor(JLabel comp, FeatureColourI gcol)
{
int w = comp.getWidth(), h = comp.getHeight();
if (w < 20)
renderGraduatedColor(comp, gcol, w, h);
}
- public static void renderGraduatedColor(JLabel comp, GraduatedColor gcol,
+ public static void renderGraduatedColor(JLabel comp, FeatureColourI gcol,
int w, int h)
{
boolean thr = false;
String tt = "";
String tx = "";
- if (gcol.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD)
+ if (gcol.isAboveThreshold())
{
thr = true;
tx += ">";
- tt += "Thresholded (Above " + gcol.getThresh() + ") ";
+ tt += "Thresholded (Above " + gcol.getThreshold() + ") ";
}
- if (gcol.getThreshType() == AnnotationColourGradient.BELOW_THRESHOLD)
+ if (gcol.isBelowThreshold())
{
thr = true;
tx += "<";
- tt += "Thresholded (Below " + gcol.getThresh() + ") ";
+ tt += "Thresholded (Below " + gcol.getThreshold() + ") ";
}
if (gcol.isColourByLabel())
{
}
else
{
- Color newColor = gcol.getMaxColor();
+ Color newColor = gcol.getMaxColour();
comp.setBackground(newColor);
// System.err.println("Width is " + w / 2);
Icon ficon = new FeatureIcon(gcol, comp.getBackground(), w, h, thr);
class FeatureIcon implements Icon
{
- GraduatedColor gcol;
+ FeatureColourI gcol;
Color backg;
Color mpcolour = Color.white;
- FeatureIcon(GraduatedColor gfc, Color bg, int w, int h, boolean mspace)
+ FeatureIcon(FeatureColourI gfc, Color bg, int w, int h, boolean mspace)
{
gcol = gfc;
backg = bg;
g.setColor(backg);
g.fillRect(0, 0, width, height);
// need an icon here.
- g.setColor(gcol.getMaxColor());
+ g.setColor(gcol.getMaxColour());
g.setFont(new Font("Verdana", Font.PLAIN, 9));
}
else
{
- Color minCol = gcol.getMinColor();
+ Color minCol = gcol.getMinColour();
g.setColor(minCol);
g.fillRect(0, 0, s1, height);
if (midspace)
g.setColor(Color.white);
g.fillRect(s1, 0, e1 - s1, height);
}
- g.setColor(gcol.getMaxColor());
+ g.setColor(gcol.getMaxColour());
g.fillRect(0, e1, width - e1, height);
}
}
{
FeatureSettings me;
- GraduatedColor currentGColor;
+ FeatureColourI currentColor;
FeatureColourChooser chooser;
String type;
- Color currentColor;
-
JButton button;
JColorChooser colorChooser;
{
// The user has clicked the cell, so
// bring up the dialog.
- if (currentColor != null)
+ if (currentColor.isSimpleColour())
{
// bring up simple color chooser
- button.setBackground(currentColor);
- colorChooser.setColor(currentColor);
+ button.setBackground(currentColor.getColour());
+ colorChooser.setColor(currentColor.getColour());
dialog.setVisible(true);
}
else
}
else
{ // User pressed dialog's "OK" button.
- if (currentColor != null)
+ if (currentColor.isSimpleColour())
{
- currentColor = colorChooser.getColor();
+ currentColor = new FeatureColour(colorChooser.getColor());
}
else
{
- // class cast exceptions may be raised if the chooser created on a
- // non-graduated color
- currentGColor = (GraduatedColor) chooser.getLastColour();
+ currentColor = chooser.getLastColour();
}
me.table.setValueAt(getCellEditorValue(), selectedRow, 1);
fireEditingStopped();
@Override
public Object getCellEditorValue()
{
- if (currentColor == null)
- {
- return currentGColor;
- }
return currentColor;
}
public Component getTableCellEditorComponent(JTable table, Object value,
boolean isSelected, int row, int column)
{
- currentGColor = null;
- currentColor = null;
+ currentColor = (FeatureColourI) value;
this.selectedRow = row;
type = me.table.getValueAt(row, 0).toString();
button.setOpaque(true);
button.setBackground(me.getBackground());
- if (value instanceof GraduatedColor)
+ if (!currentColor.isSimpleColour())
{
- currentGColor = (GraduatedColor) value;
JLabel btn = new JLabel();
btn.setSize(button.getSize());
- FeatureSettings.renderGraduatedColor(btn, currentGColor);
+ FeatureSettings.renderGraduatedColor(btn, currentColor);
button.setBackground(btn.getBackground());
button.setIcon(btn.getIcon());
button.setText(btn.getText());
{
button.setText("");
button.setIcon(null);
- currentColor = (Color) value;
- button.setBackground(currentColor);
+ button.setBackground(currentColor.getColour());
}
return button;
}
*/
package jalview.gui;
+import jalview.api.FeatureColourI;
import jalview.api.ViewStyleI;
import jalview.api.structures.JalviewStructureDisplayI;
import jalview.bin.Cache;
import jalview.schemes.AnnotationColourGradient;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
import jalview.schemes.ResidueColourScheme;
import jalview.schemes.ResidueProperties;
import jalview.schemes.UserColourScheme;
.toArray(new String[0]);
Vector<String> settingsAdded = new Vector<String>();
- Object gstyle = null;
- GraduatedColor gcol = null;
if (renderOrder != null)
{
for (String featureType : renderOrder)
{
- gstyle = ap.getSeqPanel().seqCanvas.getFeatureRenderer()
+ FeatureColourI fcol = ap.getSeqPanel().seqCanvas
+ .getFeatureRenderer()
.getFeatureStyle(featureType);
Setting setting = new Setting();
setting.setType(featureType);
- if (gstyle instanceof GraduatedColor)
+ if (!fcol.isSimpleColour())
{
- gcol = (GraduatedColor) gstyle;
- setting.setColour(gcol.getMaxColor().getRGB());
- setting.setMincolour(gcol.getMinColor().getRGB());
- setting.setMin(gcol.getMin());
- setting.setMax(gcol.getMax());
- setting.setColourByLabel(gcol.isColourByLabel());
- setting.setAutoScale(gcol.isAutoScale());
- setting.setThreshold(gcol.getThresh());
- setting.setThreshstate(gcol.getThreshType());
+ setting.setColour(fcol.getMaxColour().getRGB());
+ setting.setMincolour(fcol.getMinColour().getRGB());
+ setting.setMin(fcol.getMin());
+ setting.setMax(fcol.getMax());
+ setting.setColourByLabel(fcol.isColourByLabel());
+ setting.setAutoScale(fcol.isAutoScaled());
+ setting.setThreshold(fcol.getThreshold());
+ // -1 = No threshold, 0 = Below, 1 = Above
+ setting.setThreshstate(fcol.isAboveThreshold() ? 1
+ : (fcol.isBelowThreshold() ? 0 : -1));
}
else
{
- setting.setColour(((Color) gstyle).getRGB());
+ setting.setColour(fcol.getColour().getRGB());
}
setting.setDisplay(av.getFeaturesDisplayed().isVisible(
groupsAdded.addElement(grp);
}
jms.setFeatureSettings(fs);
-
}
if (av.hasHiddenColumns())
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();
+ Map<String, FeatureColourI> featureColours = new Hashtable<String, FeatureColourI>();
+ Map<String, Float> featureOrder = new Hashtable<String, Float>();
for (int fs = 0; fs < jms.getFeatureSettings().getSettingCount(); fs++)
{
Setting setting = jms.getFeatureSettings().getSetting(fs);
if (setting.hasMincolour())
{
- GraduatedColor gc = setting.hasMin() ? new GraduatedColor(
- new java.awt.Color(setting.getMincolour()),
- new java.awt.Color(setting.getColour()),
- setting.getMin(), setting.getMax()) : new GraduatedColor(
- new java.awt.Color(setting.getMincolour()),
- new java.awt.Color(setting.getColour()), 0, 1);
+ FeatureColourI gc = setting.hasMin() ? new FeatureColour(
+ new Color(setting.getMincolour()), new Color(
+ setting.getColour()), setting.getMin(),
+ setting.getMax()) : new FeatureColour(new Color(
+ setting.getMincolour()), new Color(setting.getColour()),
+ 0, 1);
if (setting.hasThreshold())
{
- gc.setThresh(setting.getThreshold());
- gc.setThreshType(setting.getThreshstate());
+ gc.setThreshold(setting.getThreshold());
+ int threshstate = setting.getThreshstate();
+ // -1 = None, 0 = Below, 1 = Above threshold
+ if (threshstate == 0)
+ {
+ gc.setBelowThreshold(true);
+ }
+ else if (threshstate == 1)
+ {
+ gc.setAboveThreshold(true);
+ }
}
gc.setAutoScaled(true); // default
if (setting.hasAutoScale())
}
else
{
- featureColours.put(setting.getType(),
- new java.awt.Color(setting.getColour()));
+ featureColours.put(setting.getType(), new FeatureColour(
+ new Color(setting.getColour())));
}
renderOrder[fs] = setting.getType();
if (setting.hasOrder())
fdi.setVisible(setting.getType());
}
}
- Hashtable fgtable = new Hashtable();
+ Map<String, Boolean> fgtable = new Hashtable<String, Boolean>();
for (int gs = 0; gs < jms.getFeatureSettings().getGroupCount(); gs++)
{
Group grp = jms.getFeatureSettings().getGroup(gs);
import jalview.analysis.AlignmentUtils;
import jalview.analysis.SequenceIdMatcher;
import jalview.api.AlignViewportI;
+import jalview.api.FeatureColourI;
import jalview.api.FeaturesSourceI;
import jalview.datamodel.AlignedCodonFrame;
import jalview.datamodel.Alignment;
import jalview.io.gff.GffHelperBase;
import jalview.io.gff.GffHelperFactory;
import jalview.io.gff.GffHelperI;
-import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
import jalview.schemes.UserColourScheme;
-import jalview.util.Format;
import jalview.util.MapList;
import jalview.util.ParseHtmlBodyAndLinks;
import jalview.util.StringUtils;
-import java.awt.Color;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.StringTokenizer;
/**
* Parses and writes features files, which may be in Jalview, GFF2 or GFF3
* - process html strings into plain text
* @return true if features were added
*/
- public boolean parse(AlignmentI align, Map<String, Object> colours,
+ public boolean parse(AlignmentI align,
+ Map<String, FeatureColourI> colours,
boolean removeHTML)
{
return parse(align, colours, removeHTML, false);
* - when true, ID matches to compound sequence IDs are allowed
* @return true if features were added
*/
- public boolean parse(AlignmentI align, Map<String, Object> colours,
+ public boolean parse(AlignmentI align,
+ Map<String, FeatureColourI> colours,
boolean removeHTML, boolean relaxedIdmatching)
{
Map<String, String> gffProps = new HashMap<String, String>();
else if (ft.equalsIgnoreCase("endgroup"))
{
// We should check whether this is the current group,
- // but at present theres no way of showing more than 1 group
+ // but at present there's no way of showing more than 1 group
featureGroup = null;
}
else
{
- parseFeatureColour(line, ft, gffColumns, colours);
+ String colscheme = gffColumns[1];
+ FeatureColourI colour = FeatureColour
+ .parseJalviewFeatureColour(colscheme);
+ if (colour != null)
+ {
+ colours.put(ft, colour);
+ }
}
continue;
}
* @param featureGroup
*/
protected boolean parseJalviewFeature(String line, String[] gffColumns,
- AlignmentI alignment, Map<String, Object> featureColours,
+ AlignmentI alignment, Map<String, FeatureColourI> featureColours,
boolean removeHTML, boolean relaxedIdMatching, String featureGroup)
{
/*
* synthesize a colour from the feature type
*/
UserColourScheme ucs = new UserColourScheme(ft);
- featureColours.put(ft, ucs.findColour('A'));
+ featureColours.put(ft, new FeatureColour(ucs.findColour('A')));
}
SequenceFeature sf = new SequenceFeature(ft, desc, "", startPos,
endPos, featureGroup);
}
/**
- * Process a feature type colour specification
- *
- * @param line
- * the current input line (for error messages only)
- * @param featureType
- * the first token on the line
- * @param gffColumns
- * holds tokens on the line
- * @param colours
- * map to which to add derived colour specification
- */
- protected void parseFeatureColour(String line, String featureType,
- String[] gffColumns, Map<String, Object> colours)
- {
- Object colour = null;
- String colscheme = gffColumns[1];
- if (colscheme.indexOf("|") > -1
- || colscheme.trim().equalsIgnoreCase("label"))
- {
- colour = parseGraduatedColourScheme(line, colscheme);
- }
- else
- {
- UserColourScheme ucs = new UserColourScheme(colscheme);
- colour = ucs.findColour('A');
- }
- if (colour != null)
- {
- colours.put(featureType, colour);
- }
- }
-
- /**
- * Parse a Jalview graduated colour descriptor
- *
- * @param line
- * @param colourDescriptor
- * @return
- */
- protected GraduatedColor parseGraduatedColourScheme(String line,
- String colourDescriptor)
- {
- // Parse '|' separated graduated colourscheme fields:
- // [label|][mincolour|maxcolour|[absolute|]minvalue|maxvalue|thresholdtype|thresholdvalue]
- // can either provide 'label' only, first is optional, next two
- // colors are required (but may be
- // left blank), next is optional, nxt two min/max are required.
- // first is either 'label'
- // first/second and third are both hexadecimal or word equivalent
- // colour.
- // next two are values parsed as floats.
- // fifth is either 'above','below', or 'none'.
- // sixth is a float value and only required when fifth is either
- // 'above' or 'below'.
- StringTokenizer gcol = new StringTokenizer(colourDescriptor, "|", true);
- // set defaults
- float min = Float.MIN_VALUE, max = Float.MAX_VALUE;
- boolean labelCol = false;
- // Parse spec line
- String mincol = gcol.nextToken();
- if (mincol == "|")
- {
- System.err
- .println("Expected either 'label' or a colour specification in the line: "
- + line);
- return null;
- }
- String maxcol = null;
- if (mincol.toLowerCase().indexOf("label") == 0)
- {
- labelCol = true;
- mincol = (gcol.hasMoreTokens() ? gcol.nextToken() : null); // skip '|'
- mincol = (gcol.hasMoreTokens() ? gcol.nextToken() : null);
- }
- String abso = null, minval, maxval;
- if (mincol != null)
- {
- // at least four more tokens
- if (mincol.equals("|"))
- {
- mincol = "";
- }
- else
- {
- gcol.nextToken(); // skip next '|'
- }
- // continue parsing rest of line
- maxcol = gcol.nextToken();
- if (maxcol.equals("|"))
- {
- maxcol = "";
- }
- else
- {
- gcol.nextToken(); // skip next '|'
- }
- abso = gcol.nextToken();
- gcol.nextToken(); // skip next '|'
- if (abso.toLowerCase().indexOf("abso") != 0)
- {
- minval = abso;
- abso = null;
- }
- else
- {
- minval = gcol.nextToken();
- gcol.nextToken(); // skip next '|'
- }
- maxval = gcol.nextToken();
- if (gcol.hasMoreTokens())
- {
- gcol.nextToken(); // skip next '|'
- }
- try
- {
- if (minval.length() > 0)
- {
- min = Float.valueOf(minval);
- }
- } catch (Exception e)
- {
- System.err
- .println("Couldn't parse the minimum value for graduated colour for type ("
- + colourDescriptor
- + ") - did you misspell 'auto' for the optional automatic colour switch ?");
- e.printStackTrace();
- }
- try
- {
- if (maxval.length() > 0)
- {
- max = Float.valueOf(maxval);
- }
- } catch (Exception e)
- {
- System.err
- .println("Couldn't parse the maximum value for graduated colour for type ("
- + colourDescriptor + ")");
- e.printStackTrace();
- }
- }
- else
- {
- // add in some dummy min/max colours for the label-only
- // colourscheme.
- mincol = "FFFFFF";
- maxcol = "000000";
- }
-
- GraduatedColor colour = null;
- try
- {
- colour = new GraduatedColor(
- new UserColourScheme(mincol).findColour('A'),
- new UserColourScheme(maxcol).findColour('A'), min, max);
- } catch (Exception e)
- {
- System.err.println("Couldn't parse the graduated colour scheme ("
- + colourDescriptor + ")");
- e.printStackTrace();
- }
- if (colour != null)
- {
- colour.setColourByLabel(labelCol);
- colour.setAutoScaled(abso == null);
- // add in any additional parameters
- String ttype = null, tval = null;
- if (gcol.hasMoreTokens())
- {
- // threshold type and possibly a threshold value
- ttype = gcol.nextToken();
- if (ttype.toLowerCase().startsWith("below"))
- {
- colour.setThreshType(AnnotationColourGradient.BELOW_THRESHOLD);
- }
- else if (ttype.toLowerCase().startsWith("above"))
- {
- colour.setThreshType(AnnotationColourGradient.ABOVE_THRESHOLD);
- }
- else
- {
- colour.setThreshType(AnnotationColourGradient.NO_THRESHOLD);
- if (!ttype.toLowerCase().startsWith("no"))
- {
- System.err.println("Ignoring unrecognised threshold type : "
- + ttype);
- }
- }
- }
- if (colour.getThreshType() != AnnotationColourGradient.NO_THRESHOLD)
- {
- try
- {
- gcol.nextToken();
- tval = gcol.nextToken();
- colour.setThresh(new Float(tval).floatValue());
- } catch (Exception e)
- {
- System.err.println("Couldn't parse threshold value as a float: ("
- + tval + ")");
- e.printStackTrace();
- }
- }
- // parse the thresh-is-min token ?
- if (gcol.hasMoreTokens())
- {
- System.err
- .println("Ignoring additional tokens in parameters in graduated colour specification\n");
- while (gcol.hasMoreTokens())
- {
- System.err.println("|" + gcol.nextToken());
- }
- System.err.println("\n");
- }
- }
- return colour;
- }
-
- /**
* clear any temporary handles used to speed up ID matching
*/
protected void resetMatcher()
* @return features file contents
*/
public String printJalviewFormat(SequenceI[] sequences,
- Map<String, Object> visible)
+ Map<String, FeatureColourI> visible)
{
return printJalviewFormat(sequences, visible, true, true);
}
* @return features file contents
*/
public String printJalviewFormat(SequenceI[] sequences,
- Map<String, Object> visible, boolean visOnly, boolean nonpos)
+ Map<String, FeatureColourI> visible, boolean visOnly,
+ boolean nonpos)
{
StringBuilder out = new StringBuilder(256);
boolean featuresGen = false;
// viewed features
// TODO: decide if feature links should also be written here ?
Iterator<String> en = visible.keySet().iterator();
- String featureType, color;
while (en.hasNext())
{
- featureType = en.next().toString();
-
- if (visible.get(featureType) instanceof GraduatedColor)
- {
- GraduatedColor gc = (GraduatedColor) visible.get(featureType);
- color = (gc.isColourByLabel() ? "label|" : "")
- + Format.getHexString(gc.getMinColor()) + "|"
- + Format.getHexString(gc.getMaxColor())
- + (gc.isAutoScale() ? "|" : "|abso|") + gc.getMin() + "|"
- + gc.getMax() + "|";
- if (gc.getThreshType() != AnnotationColourGradient.NO_THRESHOLD)
- {
- if (gc.getThreshType() == AnnotationColourGradient.BELOW_THRESHOLD)
- {
- color += "below";
- }
- else
- {
- if (gc.getThreshType() != AnnotationColourGradient.ABOVE_THRESHOLD)
- {
- System.err.println("WARNING: Unsupported threshold type ("
- + gc.getThreshType() + ") : Assuming 'above'");
- }
- color += "above";
- }
- // add the value
- color += "|" + gc.getThresh();
- }
- else
- {
- color += "none";
- }
- }
- else if (visible.get(featureType) instanceof Color)
- {
- color = Format.getHexString((Color) visible.get(featureType));
- }
- else
- {
- // legacy support for integer objects containing colour triplet values
- color = Format.getHexString(new Color(Integer.parseInt(visible
- .get(featureType).toString())));
- }
- out.append(featureType);
- out.append(TAB);
- out.append(color);
- out.append(newline);
+ String featureType = en.next().toString();
+ FeatureColourI colour = visible.get(featureType);
+ out.append(colour.toJalviewFormat(featureType)).append(newline);
}
}
+
// Work out which groups are both present and visible
List<String> groups = new ArrayList<String>();
int groupIndex = 0;
* @return
*/
public String printGffFormat(SequenceI[] sequences,
- Map<String, Object> visible)
+ Map<String, FeatureColourI> visible)
{
return printGffFormat(sequences, visible, true, true);
}
* @return
*/
public String printGffFormat(SequenceI[] sequences,
- Map<String, Object> visible, boolean outputVisibleOnly,
+ Map<String, FeatureColourI> visible, boolean outputVisibleOnly,
boolean includeNonPositionalFeatures)
{
StringBuilder out = new StringBuilder(256);
package jalview.io;
import jalview.api.FeatureColourI;
-import jalview.schemes.FeatureColourAdapter;
+import jalview.schemes.FeatureColour;
import jalview.schemes.FeatureSettingsAdapter;
import java.awt.Color;
{
if (type.equalsIgnoreCase(FEATURE_INSERTION))
{
- return new FeatureColourAdapter()
+ return new FeatureColour()
{
@Override
*/
package jalview.io.packed;
+import jalview.api.FeatureColourI;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
import jalview.io.NewickFile;
/**
* @return the featureColours
*/
- public Map<String, Object> getFeatureColours()
+ public Map<String, FeatureColourI> getFeatureColours()
{
return featureColours;
}
* @param featureColours
* the featureColours to set
*/
- public void setFeatureColours(Map<String, Object> featureColours)
+ public void setFeatureColours(Map<String, FeatureColourI> featureColours)
{
this.featureColours = featureColours;
}
/**
* current set of feature colours
*/
- Map<String, Object> featureColours;
+ Map<String, FeatureColourI> featureColours;
/**
* original identity of each sequence in results
seqDetails = new Hashtable();
al = new ArrayList<AlignmentSet>();
parentDataset = null;
- featureColours = new HashMap<String, Object>();
+ featureColours = new HashMap<String, FeatureColourI>();
}
/**
*
* @param parentAlignment
*/
- public JalviewDataset(AlignmentI aldataset, Map<String, Object> fc,
+ public JalviewDataset(AlignmentI aldataset,
+ Map<String, FeatureColourI> fc,
Hashtable seqDets)
{
// TODO not used - remove?
* (may be null) alignment to associate new annotation and trees
* with.
*/
- public JalviewDataset(AlignmentI aldataset, Map<String, Object> fc,
+ public JalviewDataset(AlignmentI aldataset,
+ Map<String, FeatureColourI> fc,
Hashtable seqDets, AlignmentI parentAlignment)
{
this();
*/
package jalview.io.packed;
+import jalview.api.FeatureColourI;
import jalview.datamodel.AlignmentI;
import jalview.io.AppletFormatAdapter;
import jalview.io.FileParse;
// if not, create one.
if (context.featureColours == null)
{
- context.featureColours = new HashMap<String, Object>();
+ context.featureColours = new HashMap<String, FeatureColourI>();
}
try
{
boolean av_validCharWidth, av_isShowSeqFeatureHeight;
+ private Integer currentColour;
+
protected void updateAvConfig()
{
av_charHeight = av.getCharHeight();
}
/**
- * This is used by the Molecule Viewer and Overview to get the accurate
- * colourof the rendered sequence
+ * This is used by the Molecule Viewer and Overview to get the accurate colour
+ * of the rendered sequence
*/
public synchronized int findFeatureColour(int initialCol,
final SequenceI seq, int column)
}
else
{
- return ((Integer) currentColour).intValue();
+ return currentColour.intValue();
}
}
--- /dev/null
+package jalview.schemes;
+
+import jalview.api.FeatureColourI;
+import jalview.datamodel.SequenceFeature;
+import jalview.util.Format;
+
+import java.awt.Color;
+import java.util.StringTokenizer;
+
+/**
+ * A class that wraps either a simple colour or a graduated colour
+ */
+public class FeatureColour implements FeatureColourI
+{
+ private static final String BAR = "|";
+
+ final private Color colour;
+
+ final private Color minColour;
+
+ final private Color maxColour;
+
+ private boolean graduatedColour;
+
+ private boolean colourByLabel;
+
+ private float threshold;
+
+ private float base;
+
+ private float range;
+
+ private boolean belowThreshold;
+
+ private boolean aboveThreshold;
+
+ private boolean thresholdIsMinOrMax;
+
+ private boolean isHighToLow;
+
+ private boolean autoScaled;
+
+ final private float minRed;
+
+ final private float minGreen;
+
+ final private float minBlue;
+
+ final private float deltaRed;
+
+ final private float deltaGreen;
+
+ final private float deltaBlue;
+
+ /**
+ * Parses a Jalview features file format colour descriptor
+ * [label|][mincolour|maxcolour
+ * |[absolute|]minvalue|maxvalue|thresholdtype|thresholdvalue] Examples:
+ * <ul>
+ * <li>red</li>
+ * <li>a28bbb</li>
+ * <li>25,125,213</li>
+ * <li>label</li>
+ * <li>label|||0.0|0.0|above|12.5</li>
+ * <li>label|||0.0|0.0|below|12.5</li>
+ * <li>red|green|12.0|26.0|none</li>
+ * <li>a28bbb|3eb555|12.0|26.0|above|12.5</li>
+ * <li>a28bbb|3eb555|abso|12.0|26.0|below|12.5</li>
+ * </ul>
+ *
+ * @param descriptor
+ * @return
+ * @throws IllegalArgumentException
+ * if not parseable
+ */
+ public static FeatureColour parseJalviewFeatureColour(String descriptor)
+ {
+ StringTokenizer gcol = new StringTokenizer(descriptor, "|", true);
+ float min = Float.MIN_VALUE;
+ float max = Float.MAX_VALUE;
+ boolean labelColour = false;
+
+ String mincol = gcol.nextToken();
+ if (mincol == "|")
+ {
+ throw new IllegalArgumentException(
+ "Expected either 'label' or a colour specification in the line: "
+ + descriptor);
+ }
+ String maxcol = null;
+ if (mincol.toLowerCase().indexOf("label") == 0)
+ {
+ labelColour = true;
+ mincol = (gcol.hasMoreTokens() ? gcol.nextToken() : null);
+ // skip '|'
+ mincol = (gcol.hasMoreTokens() ? gcol.nextToken() : null);
+ }
+
+ if (!labelColour && !gcol.hasMoreTokens())
+ {
+ /*
+ * only a simple colour specification - parse it
+ */
+ Color colour = UserColourScheme.getColourFromString(descriptor);
+ if (colour == null)
+ {
+ throw new IllegalArgumentException("Invalid colour descriptor: "
+ + descriptor);
+ }
+ return new FeatureColour(colour);
+ }
+
+ /*
+ * autoScaled == true: colours range over actual score range
+ * autoScaled == false ('abso'): colours range over min/max range
+ */
+ boolean autoScaled = true;
+ String tok = null, minval, maxval;
+ if (mincol != null)
+ {
+ // at least four more tokens
+ if (mincol.equals("|"))
+ {
+ mincol = "";
+ }
+ else
+ {
+ gcol.nextToken(); // skip next '|'
+ }
+ maxcol = gcol.nextToken();
+ if (maxcol.equals("|"))
+ {
+ maxcol = "";
+ }
+ else
+ {
+ gcol.nextToken(); // skip next '|'
+ }
+ tok = gcol.nextToken();
+ gcol.nextToken(); // skip next '|'
+ if (tok.toLowerCase().startsWith("abso"))
+ {
+ minval = gcol.nextToken();
+ gcol.nextToken(); // skip next '|'
+ autoScaled = false;
+ }
+ else
+ {
+ minval = tok;
+ }
+ maxval = gcol.nextToken();
+ if (gcol.hasMoreTokens())
+ {
+ gcol.nextToken(); // skip next '|'
+ }
+ try
+ {
+ if (minval.length() > 0)
+ {
+ min = new Float(minval).floatValue();
+ }
+ } catch (Exception e)
+ {
+ throw new IllegalArgumentException(
+ "Couldn't parse the minimum value for graduated colour ("
+ + descriptor + ")");
+ }
+ try
+ {
+ if (maxval.length() > 0)
+ {
+ max = new Float(maxval).floatValue();
+ }
+ } catch (Exception e)
+ {
+ throw new IllegalArgumentException(
+ "Couldn't parse the maximum value for graduated colour ("
+ + descriptor + ")");
+ }
+ }
+ else
+ {
+ // add in some dummy min/max colours for the label-only
+ // colourscheme.
+ mincol = "FFFFFF";
+ maxcol = "000000";
+ }
+
+ /*
+ * construct the FeatureColour
+ */
+ FeatureColour featureColour;
+ try
+ {
+ featureColour = new FeatureColour(
+ new UserColourScheme(mincol).findColour('A'),
+ new UserColourScheme(maxcol).findColour('A'), min, max);
+ featureColour.setColourByLabel(labelColour);
+ featureColour.setAutoScaled(autoScaled);
+ // add in any additional parameters
+ String ttype = null, tval = null;
+ if (gcol.hasMoreTokens())
+ {
+ // threshold type and possibly a threshold value
+ ttype = gcol.nextToken();
+ if (ttype.toLowerCase().startsWith("below"))
+ {
+ featureColour.setBelowThreshold(true);
+ }
+ else if (ttype.toLowerCase().startsWith("above"))
+ {
+ featureColour.setAboveThreshold(true);
+ }
+ else
+ {
+ if (!ttype.toLowerCase().startsWith("no"))
+ {
+ System.err.println("Ignoring unrecognised threshold type : "
+ + ttype);
+ }
+ }
+ }
+ if (featureColour.hasThreshold())
+ {
+ try
+ {
+ gcol.nextToken();
+ tval = gcol.nextToken();
+ featureColour.setThreshold(new Float(tval).floatValue());
+ } catch (Exception e)
+ {
+ System.err.println("Couldn't parse threshold value as a float: ("
+ + tval + ")");
+ }
+ }
+ if (gcol.hasMoreTokens())
+ {
+ System.err
+ .println("Ignoring additional tokens in parameters in graduated colour specification\n");
+ while (gcol.hasMoreTokens())
+ {
+ System.err.println("|" + gcol.nextToken());
+ }
+ System.err.println("\n");
+ }
+ return featureColour;
+ } catch (Exception e)
+ {
+ throw new IllegalArgumentException(e.getMessage());
+ }
+ }
+
+ /**
+ * Default constructor
+ */
+ public FeatureColour()
+ {
+ this((Color) null);
+ }
+
+ /**
+ * Constructor given a simple colour
+ *
+ * @param c
+ */
+ public FeatureColour(Color c)
+ {
+ minColour = Color.WHITE;
+ maxColour = Color.BLACK;
+ minRed = 0f;
+ minGreen = 0f;
+ minBlue = 0f;
+ deltaRed = 0f;
+ deltaGreen = 0f;
+ deltaBlue = 0f;
+ colour = c;
+ }
+
+ /**
+ * Constructor given a colour range and a score range
+ *
+ * @param low
+ * @param high
+ * @param min
+ * @param max
+ */
+ public FeatureColour(Color low, Color high, float min, float max)
+ {
+ graduatedColour = true;
+ colour = null;
+ minColour = low;
+ maxColour = high;
+ threshold = Float.NaN;
+ isHighToLow = min >= max;
+ minRed = low.getRed() / 255f;
+ minGreen = low.getGreen() / 255f;
+ minBlue = low.getBlue() / 255f;
+ deltaRed = (high.getRed() / 255f) - minRed;
+ deltaGreen = (high.getGreen() / 255f) - minGreen;
+ deltaBlue = (high.getBlue() / 255f) - minBlue;
+ if (isHighToLow)
+ {
+ base = max;
+ range = min - max;
+ }
+ else
+ {
+ base = min;
+ range = max - min;
+ }
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param fc
+ */
+ public FeatureColour(FeatureColour fc)
+ {
+ colour = fc.colour;
+ minColour = fc.minColour;
+ maxColour = fc.maxColour;
+ minRed = fc.minRed;
+ minGreen = fc.minGreen;
+ minBlue = fc.minBlue;
+ deltaRed = fc.deltaRed;
+ deltaGreen = fc.deltaGreen;
+ deltaBlue = fc.deltaBlue;
+ base = fc.base;
+ range = fc.range;
+ isHighToLow = fc.isHighToLow;
+ setAboveThreshold(fc.isAboveThreshold());
+ setBelowThreshold(fc.isBelowThreshold());
+ setThreshold(fc.getThreshold());
+ setAutoScaled(fc.isAutoScaled());
+ setColourByLabel(fc.isColourByLabel());
+ }
+
+ /**
+ * Copy constructor with new min/max ranges
+ * @param fc
+ * @param min
+ * @param max
+ */
+ public FeatureColour(FeatureColour fc, float min, float max)
+ {
+ this(fc);
+ graduatedColour = true;
+ updateBounds(min, max);
+ }
+
+ @Override
+ public boolean isGraduatedColour()
+ {
+ return graduatedColour;
+ }
+
+ /**
+ * Sets the 'graduated colour' flag. If true, also sets 'colour by label' to
+ * false.
+ */
+ void setGraduatedColour(boolean b)
+ {
+ graduatedColour = b;
+ if (b)
+ {
+ setColourByLabel(false);
+ }
+ }
+
+ @Override
+ public Color getColour()
+ {
+ return colour;
+ }
+
+ @Override
+ public Color getMinColour()
+ {
+ return minColour;
+ }
+
+ @Override
+ public Color getMaxColour()
+ {
+ return maxColour;
+ }
+
+ @Override
+ public boolean isColourByLabel()
+ {
+ return colourByLabel;
+ }
+
+ /**
+ * Sets the 'colour by label' flag. If true, also sets 'graduated colour' to
+ * false.
+ */
+ @Override
+ public void setColourByLabel(boolean b)
+ {
+ colourByLabel = b;
+ if (b)
+ {
+ setGraduatedColour(false);
+ }
+ }
+ @Override
+ public boolean isBelowThreshold()
+ {
+ return belowThreshold;
+ }
+
+ @Override
+ public void setBelowThreshold(boolean b)
+ {
+ belowThreshold = b;
+ if (b)
+ {
+ setAboveThreshold(false);
+ }
+ }
+
+ @Override
+ public boolean isAboveThreshold()
+ {
+ return aboveThreshold;
+ }
+
+ @Override
+ public void setAboveThreshold(boolean b)
+ {
+ aboveThreshold = b;
+ if (b)
+ {
+ setBelowThreshold(false);
+ }
+ }
+
+ @Override
+ public boolean isThresholdMinMax()
+ {
+ return thresholdIsMinOrMax;
+ }
+
+ @Override
+ public void setThresholdMinMax(boolean b)
+ {
+ thresholdIsMinOrMax = b;
+ }
+
+ @Override
+ public float getThreshold()
+ {
+ return threshold;
+ }
+
+ @Override
+ public void setThreshold(float f)
+ {
+ threshold = f;
+ }
+
+ @Override
+ public boolean isAutoScaled()
+ {
+ return autoScaled;
+ }
+
+ @Override
+ public void setAutoScaled(boolean b)
+ {
+ this.autoScaled = b;
+ }
+
+ /**
+ * Updates the base and range appropriately for the given minmax range
+ *
+ * @param min
+ * @param max
+ */
+ @Override
+ public void updateBounds(float min, float max)
+ {
+ if (max < min)
+ {
+ base = max;
+ range = min - max;
+ isHighToLow = true;
+ }
+ else
+ {
+ base = min;
+ range = max - min;
+ isHighToLow = false;
+ }
+ }
+
+ /**
+ * Returns the colour for the given instance of the feature. This may be a
+ * simple colour, a colour generated from the feature description (if
+ * isColourByLabel()), or a colour derived from the feature score (if
+ * isGraduatedColour()).
+ *
+ * @param feature
+ * @return
+ */
+ @Override
+ public Color getColor(SequenceFeature feature)
+ {
+ if (isColourByLabel())
+ {
+ return UserColourScheme
+ .createColourFromName(feature.getDescription());
+ }
+
+ if (!isGraduatedColour())
+ {
+ return getColour();
+ }
+
+ // todo should we check for above/below threshold here?
+ if (range == 0.0)
+ {
+ return getMaxColour();
+ }
+ float scr = feature.getScore();
+ if (Float.isNaN(scr))
+ {
+ return getMinColour();
+ }
+ float scl = (scr - base) / range;
+ if (isHighToLow)
+ {
+ scl = -scl;
+ }
+ if (scl < 0f)
+ {
+ scl = 0f;
+ }
+ if (scl > 1f)
+ {
+ scl = 1f;
+ }
+ return new Color(minRed + scl * deltaRed, minGreen + scl * deltaGreen, minBlue + scl * deltaBlue);
+ }
+
+ /**
+ * Returns the maximum score of the graduated colour range
+ *
+ * @return
+ */
+ @Override
+ public float getMax()
+ {
+ // regenerate the original values passed in to the constructor
+ return (isHighToLow) ? base : (base + range);
+ }
+
+ /**
+ * Returns the minimum score of the graduated colour range
+ *
+ * @return
+ */
+ @Override
+ public float getMin()
+ {
+ // regenerate the original value passed in to the constructor
+ return (isHighToLow) ? (base + range) : base;
+ }
+
+ /**
+ * Answers true if the feature has a simple colour, or is coloured by label,
+ * or has a graduated colour and the score of this feature instance is within
+ * the range to render (if any), i.e. does not lie below or above any
+ * threshold set.
+ *
+ * @param feature
+ * @return
+ */
+ @Override
+ public boolean isColored(SequenceFeature feature)
+ {
+ if (isColourByLabel() || !isGraduatedColour())
+ {
+ return true;
+ }
+
+ float val = feature.getScore();
+ if (Float.isNaN(val))
+ {
+ return true;
+ }
+ if (Float.isNaN(this.threshold))
+ {
+ return true;
+ }
+
+ if (isAboveThreshold() && val <= threshold)
+ {
+ return false;
+ }
+ if (isBelowThreshold() && val >= threshold)
+ {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public boolean isSimpleColour()
+ {
+ return (!isColourByLabel() && !isGraduatedColour());
+ }
+
+ @Override
+ public boolean hasThreshold()
+ {
+ return isAboveThreshold() || isBelowThreshold();
+ }
+
+ @Override
+ public String toJalviewFormat(String featureType)
+ {
+ String colourString = null;
+ if (isSimpleColour())
+ {
+ colourString = Format.getHexString(getColour());
+ }
+ else
+ {
+ StringBuilder sb = new StringBuilder(32);
+ if (isColourByLabel())
+ {
+ sb.append("label");
+ if (hasThreshold())
+ {
+ sb.append(BAR).append(BAR).append(BAR);
+ }
+ }
+ if (isGraduatedColour())
+ {
+ sb.append(Format.getHexString(getMinColour())).append(BAR);
+ sb.append(Format.getHexString(getMaxColour())).append(BAR);
+ if (!isAutoScaled())
+ {
+ sb.append("abso").append(BAR);
+ }
+ }
+ if (hasThreshold() || isGraduatedColour())
+ {
+ sb.append(getMin()).append(BAR);
+ sb.append(getMax()).append(BAR);
+ if (isBelowThreshold())
+ {
+ sb.append("below").append(BAR).append(getThreshold());
+ }
+ else if (isAboveThreshold())
+ {
+ sb.append("above").append(BAR).append(getThreshold());
+ }
+ else
+ {
+ sb.append("none");
+ }
+ }
+ colourString = sb.toString();
+ }
+ return String.format("%s\t%s", featureType, colourString);
+ }
+
+}
+++ /dev/null
-package jalview.schemes;
-
-import jalview.api.FeatureColourI;
-
-import java.awt.Color;
-
-/**
- * A convenience class with implementations of FeatureColourI methods. Override
- * methods as required in subclasses.
- */
-public class FeatureColourAdapter implements FeatureColourI
-{
- @Override
- public boolean isGraduatedColour()
- {
- return isColourByLabel() || isAboveThreshold() || isBelowThreshold();
- }
-
- @Override
- public Color getColour()
- {
- return Color.BLACK;
- }
-
- @Override
- public Color getMinColour()
- {
- return Color.WHITE;
- }
-
- @Override
- public Color getMaxColour()
- {
- return Color.BLACK;
- }
-
- @Override
- public boolean isColourByLabel()
- {
- return false;
- }
-
- @Override
- public boolean isBelowThreshold()
- {
- return false;
- }
-
- @Override
- public boolean isAboveThreshold()
- {
- return false;
- }
-
- @Override
- public boolean isThresholdMinMax()
- {
- return false;
- }
-
- @Override
- public float getThreshold()
- {
- return 0f;
- }
-
- @Override
- public boolean isLowToHigh()
- {
- return true;
- }
-
-}
+++ /dev/null
-/*
- * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
- * Copyright (C) $$Year-Rel$$ The Jalview Authors
- *
- * This file is part of Jalview.
- *
- * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *
- * Jalview is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
-package jalview.schemes;
-
-import jalview.api.FeatureColourI;
-import jalview.datamodel.SequenceFeature;
-
-import java.awt.Color;
-
-/**
- * Value and/or thresholded colour scale used for colouring by annotation and
- * feature score
- *
- * @author JimP
- *
- */
-public class GraduatedColor
-{
- int thresholdState = AnnotationColourGradient.NO_THRESHOLD; // or
- // ABOVE_THRESHOLD
- // or
- // BELOW_THRESHOLD
-
- float lr, lg, lb, dr, dg, db;
-
- /**
- * linear scaling parameters, base, minimum colour threshold, range of linear
- * scale from lower to upper
- */
- float base, range, thrsh;
-
- /**
- * when true, colour from u to u-d rather than u to u+d
- */
- boolean tolow = false;
-
- /**
- * when false, min/max range has been manually set so should not be
- * dynamically adjusted.
- */
- boolean autoScale = true;
-
- /**
- * construct a graduatedColor object from simple parameters
- *
- * @param low
- * @param high
- * @param min
- * @param max
- * color low->high from min->max
- */
- public GraduatedColor(Color low, Color high, float min, float max)
- {
- thrsh = Float.NaN;
- tolow = min >= max;
- lr = low.getRed() / 255f;
- lg = low.getGreen() / 255f;
- lb = low.getBlue() / 255f;
- dr = (high.getRed() / 255f) - lr;
- dg = (high.getGreen() / 255f) - lg;
- db = (high.getBlue() / 255f) - lb;
- if (tolow)
- {
- base = max;
- range = min - max;
- }
- else
- {
- base = min;
- range = max - min;
- }
- }
-
- public GraduatedColor(GraduatedColor oldcs)
- {
- lr = oldcs.lr;
- lg = oldcs.lg;
- lb = oldcs.lb;
- dr = oldcs.dr;
- dg = oldcs.dg;
- db = oldcs.db;
- base = oldcs.base;
- range = oldcs.range;
- tolow = oldcs.tolow;
- thresholdState = oldcs.thresholdState;
- thrsh = oldcs.thrsh;
- autoScale = oldcs.autoScale;
- colourByLabel = oldcs.colourByLabel;
- }
-
- /**
- * make a new gradient from an old one with a different scale range
- *
- * @param oldcs
- * @param min
- * @param max
- */
- public GraduatedColor(GraduatedColor oldcs, float min, float max)
- {
- this(oldcs);
- updateBounds(min, max);
- }
-
- public GraduatedColor(FeatureColourI col)
- {
- setColourByLabel(col.isColourByLabel());
- }
-
- public Color getMinColor()
- {
- return new Color(lr, lg, lb);
- }
-
- public Color getMaxColor()
- {
- return new Color(lr + dr, lg + dg, lb + db);
- }
-
- /**
- *
- * @return true if original min/max scale was from high to low
- */
- public boolean getTolow()
- {
- return tolow;
- }
-
- public void setTolow(boolean tolower)
- {
- tolow = tolower;
- }
-
- public boolean isColored(SequenceFeature feature)
- {
- float val = feature.getScore();
- if (Float.isNaN(val))
- {
- return true;
- }
- if (this.thresholdState == AnnotationColourGradient.NO_THRESHOLD)
- {
- return true;
- }
- if (Float.isNaN(this.thrsh))
- {
- return true;
- }
- boolean rtn = thresholdState == AnnotationColourGradient.ABOVE_THRESHOLD;
- if (val <= thrsh)
- {
- return !rtn; // ? !tolow : tolow;
- }
- else
- {
- return rtn; // ? tolow : !tolow;
- }
- }
-
- /**
- * default implementor of a getColourFromString method. TODO: abstract an
- * interface enabling pluggable colour from string
- */
- private UserColourScheme ucs = null;
-
- private boolean colourByLabel = false;
-
- /**
- *
- * @return true if colourByLabel style is set
- */
- public boolean isColourByLabel()
- {
- return colourByLabel;
- }
-
- /**
- * @param colourByLabel
- * the colourByLabel to set
- */
- public void setColourByLabel(boolean colourByLabel)
- {
- this.colourByLabel = colourByLabel;
- }
-
- public Color findColor(SequenceFeature feature)
- {
- if (colourByLabel)
- {
- // TODO: allow user defined feature label colourschemes. Colour space is
- // {type,regex,%anytype%}x{description string, regex, keyword}
- if (ucs == null)
- {
- ucs = new UserColourScheme();
- }
- return ucs.createColourFromName(feature.getDescription());
- }
- if (range == 0.0)
- {
- return getMaxColor();
- }
- float scr = feature.getScore();
- if (Float.isNaN(scr))
- {
- return getMinColor();
- }
- float scl = (scr - base) / range;
- if (tolow)
- {
- scl = -scl;
- }
- if (scl < 0f)
- {
- scl = 0f;
- }
- if (scl > 1f)
- {
- scl = 1f;
- }
- return new Color(lr + scl * dr, lg + scl * dg, lb + scl * db);
- }
-
- public void setThresh(float value)
- {
- thrsh = value;
- }
-
- public float getThresh()
- {
- return thrsh;
- }
-
- public void setThreshType(int aboveThreshold)
- {
- thresholdState = aboveThreshold;
- }
-
- public int getThreshType()
- {
- return thresholdState;
- }
-
- public float getMax()
- {
- // regenerate the original values passed in to the constructor
- return (tolow) ? base : (base + range);
- }
-
- public float getMin()
- {
- // regenerate the original value passed in to the constructor
- return (tolow) ? (base + range) : base;
- }
-
- public boolean isAutoScale()
- {
- return autoScale;
- }
-
- public void setAutoScaled(boolean autoscale)
- {
- autoScale = autoscale;
- }
-
- /**
- * update the base and range appropriatly for the given minmax range
- *
- * @param a
- * float[] {min,max} array containing minmax range for the associated
- * score values
- */
- public void updateBounds(float min, float max)
- {
- if (max < min)
- {
- base = max;
- range = min - max;
- tolow = true;
- }
- else
- {
- base = min;
- range = max - min;
- tolow = false;
- }
- }
-}
public static Color getColourFromString(String colour)
{
+ if (colour == null)
+ {
+ return null;
+ }
colour = colour.trim();
Color col = null;
}
- public Color createColourFromName(String name)
+ public static Color createColourFromName(String name)
{
int r, g, b;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.renderer.seqfeatures.FeatureRenderer;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
+import jalview.schemes.UserColourScheme;
import jalview.viewmodel.AlignmentViewport;
import java.awt.Color;
*/
protected float transparency = 1.0f;
- protected Map<String, Object> featureColours = new ConcurrentHashMap<String, Object>();
+ protected Map<String, FeatureColourI> featureColours = new ConcurrentHashMap<String, FeatureColourI>();
protected Map<String, Boolean> featureGroups = new ConcurrentHashMap<String, Boolean>();
- protected Object currentColour;
-
- /*
- * feature types in ordering of rendering, where last means on top
- */
protected String[] renderOrder;
+ Map<String, Float> featureOrder = null;
+
protected PropertyChangeSupport changeSupport = new PropertyChangeSupport(
this);
protected AlignmentViewport av;
- /*
- * map holds per feature type, {{min, max}, {min, max}} feature score
- * values for positional and non-positional features respectively
- */
- private Map<String, float[][]> minmax = new Hashtable<String, float[][]>();
-
@Override
public AlignViewportI getViewport()
{
renderOrder = neworder;
}
+ protected Map<String, float[][]> minmax = new Hashtable<String, float[][]>();
+
public Map<String, float[][]> getMinMax()
{
return minmax;
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)
allfeatures.remove(oldRender[j]);
if (minmax != null)
{
- mmrange = minmax.get(oldRender[j]);
+ float[][] mmrange = minmax.get(oldRender[j]);
if (mmrange != null)
{
- fc = featureColours.get(oldRender[j]);
- if (fc != null && fc instanceof GraduatedColor
- && ((GraduatedColor) fc).isAutoScale())
+ FeatureColourI fc = featureColours.get(oldRender[j]);
+ if (fc != null && !fc.isSimpleColour() && fc.isAutoScaled())
{
- ((GraduatedColor) fc).updateBounds(
- ((float[][]) mmrange)[0][0],
- ((float[][]) mmrange)[0][1]);
+ fc.updateBounds(mmrange[0][0], mmrange[0][1]);
}
}
}
if (minmax != null)
{
// update from new features minmax if necessary
- mmrange = minmax.get(newf[i]);
+ float[][] mmrange = minmax.get(newf[i]);
if (mmrange != null)
{
- fc = featureColours.get(newf[i]);
- if (fc != null && fc instanceof GraduatedColor
- && ((GraduatedColor) fc).isAutoScale())
+ FeatureColourI fc = featureColours.get(newf[i]);
+ if (fc != null && !fc.isSimpleColour() && fc.isAutoScaled())
{
- ((GraduatedColor) fc).updateBounds(((float[][]) mmrange)[0][0],
- ((float[][]) mmrange)[0][1]);
+ fc.updateBounds(mmrange[0][0], mmrange[0][1]);
}
}
}
setOrder(newf[i], i / (float) denom);
}
// set order from newly found feature from persisted ordering.
- sortOrder[i] = 2 - ((Float) featureOrder.get(newf[i])).floatValue();
+ sortOrder[i] = 2 - featureOrder.get(newf[i]).floatValue();
if (i < iSize)
{
// only sort if we need to
/**
* 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
+ * java.awt.Color for a featureType with no existing colourscheme.
*
* @param featureType
- * @return java.awt.Color or GraduatedColor
+ * @return
*/
@Override
- public Object getFeatureStyle(String featureType)
+ public FeatureColourI getFeatureStyle(String featureType)
{
- Object fc = featureColours.get(featureType);
+ FeatureColourI 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);
+ Color col = UserColourScheme.createColourFromName(featureType);
+ fc = new FeatureColour(col);
+ featureColours.put(featureType, fc);
}
return fc;
}
*/
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());
+ FeatureColourI fc = getFeatureStyle(feature.getType());
+ return fc.getColor(feature);
}
protected boolean showFeature(SequenceFeature sequenceFeature)
{
- Object fc = getFeatureStyle(sequenceFeature.type);
- if (fc instanceof GraduatedColor)
- {
- return ((GraduatedColor) fc).isColored(sequenceFeature);
- }
- else
- {
- return true;
- }
+ FeatureColourI fc = getFeatureStyle(sequenceFeature.type);
+ return fc.isColored(sequenceFeature);
}
protected boolean showFeatureOfType(String type)
}
@Override
- public void setColour(String featureType, Object col)
+ public void setColour(String featureType, FeatureColourI 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)))
- if (col instanceof FeatureColourI)
- {
- if (((FeatureColourI) col).isGraduatedColour())
- {
- col = new GraduatedColor((FeatureColourI) col);
- }
- else
- {
- col = ((FeatureColourI) col).getColour();
- }
- }
- featureColours.put(featureType, col);
+ featureColours.put(featureType, col);
}
public void setTransparency(float value)
return transparency;
}
- Map featureOrder = null;
-
/**
* analogous to colour - store a normalized ordering for all feature types in
* this rendering context.
{
if (featureOrder == null)
{
- featureOrder = new Hashtable();
+ featureOrder = new Hashtable<String, Float>();
}
featureOrder.put(type, new Float(position));
return position;
{
if (featureOrder.containsKey(type))
{
- return ((Float) featureOrder.get(type)).floatValue();
+ return featureOrder.get(type).floatValue();
}
}
return -1;
}
@Override
- public Map<String, Object> getFeatureColours()
+ public Map<String, FeatureColourI> getFeatureColours()
{
return featureColours;
}
* note visible feature ordering and colours before update
*/
List<String> visibleFeatures = getDisplayedFeatureTypes();
- Map<String, Object> visibleColours = new HashMap<String, Object>(
+ Map<String, FeatureColourI> visibleColours = new HashMap<String, FeatureColourI>(
getFeatureColours());
FeaturesDisplayedI av_featuresdisplayed = null;
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
+ setColour(type, (FeatureColourI) data[i][1]);
if (((Boolean) data[i][2]).booleanValue())
{
av_featuresdisplayed.setVisible(type);
{
if (featureGroups != null)
{
- ArrayList gp = new ArrayList();
+ List<String> gp = new ArrayList<String>();
- for (Object grp : featureGroups.keySet())
+ for (String grp : featureGroups.keySet())
{
Boolean state = featureGroups.get(grp);
if (state.booleanValue() == visible)
}
@Override
- public Hashtable getDisplayedFeatureCols()
+ public Map<String, FeatureColourI> getDisplayedFeatureCols()
{
- Hashtable fcols = new Hashtable();
+ Map<String, FeatureColourI> fcols = new Hashtable<String, FeatureColourI>();
if (getViewport().getFeaturesDisplayed() == null)
{
return fcols;
}
- Iterator<String> en = getViewport().getFeaturesDisplayed()
+ Iterator<String> features = getViewport().getFeaturesDisplayed()
.getVisibleFeatures();
- while (en.hasNext())
+ while (features.hasNext())
{
- String col = en.next();
- fcols.put(col, featureColours.get(col));
+ String feature = features.next();
+ fcols.put(feature, getFeatureStyle(feature));
}
return fcols;
}
*/
package jalview.viewmodel.seqfeatures;
-import jalview.schemes.GraduatedColor;
+import jalview.api.FeatureColourI;
+import jalview.schemes.FeatureColour;
import java.util.Arrays;
-import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
{
String[] renderOrder;
- Map featureGroups;
+ /*
+ * map of {groupName, isDisplayed}
+ */
+ Map<String, Boolean> featureGroups;
- Map featureColours;
+ /*
+ * map of {featureType, colourScheme}
+ */
+ Map<String, FeatureColourI> featureColours;
float transparency;
- Map featureOrder;
+ Map<String, Float> featureOrder;
public FeatureRendererSettings(String[] renderOrder,
- Hashtable featureGroups, Hashtable featureColours,
- float transparency, Hashtable featureOrder)
+ Map<String, Boolean> featureGroups,
+ Map<String, FeatureColourI> featureColours, float transparency,
+ Map<String, Float> featureOrder)
{
super();
this.renderOrder = Arrays.copyOf(renderOrder, renderOrder.length);
- this.featureGroups = new ConcurrentHashMap(featureGroups);
- this.featureColours = new ConcurrentHashMap(featureColours);
+ this.featureGroups = new ConcurrentHashMap<String, Boolean>(
+ featureGroups);
+ this.featureColours = new ConcurrentHashMap<String, FeatureColourI>(
+ featureColours);
this.transparency = transparency;
- this.featureOrder = new ConcurrentHashMap(featureOrder);
+ this.featureOrder = new ConcurrentHashMap<String, Float>(featureOrder);
}
/**
jalview.viewmodel.seqfeatures.FeatureRendererModel fr)
{
renderOrder = null;
- featureGroups = new ConcurrentHashMap();
- featureColours = new ConcurrentHashMap();
- featureOrder = new ConcurrentHashMap();
+ featureGroups = new ConcurrentHashMap<String, Boolean>();
+ featureColours = new ConcurrentHashMap<String, FeatureColourI>();
+ featureOrder = new ConcurrentHashMap<String, Float>();
if (fr.renderOrder != null)
{
this.renderOrder = new String[fr.renderOrder.length];
}
if (fr.featureGroups != null)
{
- this.featureGroups = new ConcurrentHashMap(fr.featureGroups);
+ this.featureGroups = new ConcurrentHashMap<String, Boolean>(
+ fr.featureGroups);
}
if (fr.featureColours != null)
{
- this.featureColours = new ConcurrentHashMap(fr.featureColours);
+ this.featureColours = new ConcurrentHashMap<String, FeatureColourI>(
+ fr.featureColours);
}
- Iterator en = fr.featureColours.keySet().iterator();
+ Iterator<String> en = fr.featureColours.keySet().iterator();
while (en.hasNext())
{
- Object next = en.next();
- Object val = featureColours.get(next);
- if (val instanceof GraduatedColor)
+ String next = en.next();
+ FeatureColourI val = featureColours.get(next);
+ // if (val instanceof GraduatedColor)
+ if (val.isGraduatedColour() || val.isColourByLabel()) // why this test?
{
- featureColours.put(next, new GraduatedColor((GraduatedColor) val));
+ featureColours.put(next, new FeatureColour((FeatureColour) val));
}
}
this.transparency = fr.transparency;
if (fr.featureOrder != null)
{
- this.featureOrder = new ConcurrentHashMap(fr.featureOrder);
+ this.featureOrder = new ConcurrentHashMap<String, Float>(
+ fr.featureOrder);
}
}
}
package jalview.ws.jws1;
import jalview.analysis.AlignSeq;
+import jalview.api.FeatureColourI;
import jalview.bin.Cache;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentView;
* @return null or { Alignment(+features and annotation), NewickFile)}
*/
public Object[] getAlignment(Alignment dataset,
- Map<String, Object> featureColours)
+ Map<String, FeatureColourI> featureColours)
{
if (result != null && result.isFinished())
// NewickFile nf[] = new NewickFile[jobs.length];
for (int j = 0; j < jobs.length; j++)
{
- Map<String, Object> featureColours = new HashMap<String, Object>();
+ Map<String, FeatureColourI> featureColours = new HashMap<String, FeatureColourI>();
Alignment al = null;
NewickFile nf = null;
if (jobs[j].hasResults())
*/
package jalview.ws.jws2;
+import jalview.api.AlignCalcWorkerI;
+import jalview.api.FeatureColourI;
import jalview.bin.Cache;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.GraphLine;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
-import jalview.schemes.GraduatedColor;
+import jalview.schemes.FeatureColour;
import jalview.schemes.UserColourScheme;
import jalview.ws.jws2.jabaws2.Jws2Instance;
import jalview.ws.params.WsParamSetI;
annot.description += "<br/>" + threshNote;
}
annot.description += "</html>";
- Color col = new UserColourScheme(typeName)
- .createColourFromName(typeName + scr.getMethod());
+ Color col = UserColourScheme.createColourFromName(typeName
+ + scr.getMethod());
for (int p = 0, ps = annot.annotations.length; p < ps; p++)
{
if (annot.annotations[p] != null)
.cloneFeatureRenderer();
for (String ft : fc.keySet())
{
- Object gc = fr.getFeatureStyle(ft);
- if (gc instanceof Color)
+ FeatureColourI gc = fr.getFeatureStyle(ft);
+ if (gc.isSimpleColour())
{
// set graduated color as fading to white for minimum, and
// autoscaling to values on alignment
- GraduatedColor ggc = new GraduatedColor(Color.white,
- (Color) gc, Float.MIN_VALUE, Float.MAX_VALUE);
+ FeatureColourI ggc = new FeatureColour(Color.white,
+ gc.getColour(), Float.MIN_VALUE, Float.MAX_VALUE);
ggc.setAutoScaled(true);
fr.setColour(ft, ggc);
}
import static org.testng.AssertJUnit.assertNull;
import static org.testng.AssertJUnit.assertTrue;
+import jalview.api.FeatureColourI;
import jalview.api.FeatureRenderer;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
import jalview.gui.AlignFrame;
-import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.GraduatedColor;
import java.awt.Color;
import java.io.File;
File f = new File("examples/uniref50.fa");
AlignmentI al = readAlignmentFile(f);
AlignFrame af = new AlignFrame(al, 500, 500);
- Map<String, Object> colours = af.getFeatureRenderer()
+ Map<String, FeatureColourI> colours = af.getFeatureRenderer()
.getFeatureColours();
FeaturesFile featuresFile = new FeaturesFile(
"examples/exampleFeatures.txt", FormatAdapter.FILE);
*/
colours = af.getFeatureRenderer().getFeatureColours();
assertEquals("26 feature group colours not found", 26, colours.size());
- assertEquals(colours.get("Cath"), new Color(0x93b1d1));
- assertEquals(colours.get("ASX-MOTIF"), new Color(0x6addbb));
+ assertEquals(colours.get("Cath").getColour(), new Color(0x93b1d1));
+ assertEquals(colours.get("ASX-MOTIF").getColour(), new Color(0x6addbb));
/*
* verify (some) features on sequences
File f = new File("examples/uniref50.fa");
AlignmentI al = readAlignmentFile(f);
AlignFrame af = new AlignFrame(al, 500, 500);
- Map<String, Object> colours = af.getFeatureRenderer()
+ Map<String, FeatureColourI> colours = af.getFeatureRenderer()
.getFeatureColours();
// GFF2 uses space as name/value separator in column 9
String gffData = "METAL\tcc9900\n" + "GFF\n"
// verify colours read or synthesized
colours = af.getFeatureRenderer().getFeatureColours();
assertEquals("1 feature group colours not found", 1, colours.size());
- assertEquals(colours.get("METAL"), new Color(0xcc9900));
+ assertEquals(colours.get("METAL").getColour(), new Color(0xcc9900));
// verify feature on FER_CAPAA
SequenceFeature[] sfs = al.getSequenceAt(0).getDatasetSequence()
}
/**
- * Test various ways of describing a feature colour scheme
- *
- * @throws Exception
- */
- @Test(groups = { "Functional" })
- public void testParseGraduatedColourScheme() throws Exception
- {
- FeaturesFile ff = new FeaturesFile();
-
- // colour by label:
- GraduatedColor gc = ff.parseGraduatedColourScheme(
- "BETA-TURN-IR\t9a6a94", "label");
- assertTrue(gc.isColourByLabel());
- assertEquals(Color.white, gc.getMinColor());
- assertEquals(Color.black, gc.getMaxColor());
- assertTrue(gc.isAutoScale());
-
- // using colour name, rgb, etc:
- String spec = "blue|255,0,255|absolute|20.0|95.0|below|66.0";
- gc = ff.parseGraduatedColourScheme("BETA-TURN-IR\t" + spec, spec);
- assertFalse(gc.isColourByLabel());
- assertEquals(Color.blue, gc.getMinColor());
- assertEquals(new Color(255, 0, 255), gc.getMaxColor());
- assertFalse(gc.isAutoScale());
- assertFalse(gc.getTolow());
- assertEquals(20.0f, gc.getMin(), 0.001f);
- assertEquals(95.0f, gc.getMax(), 0.001f);
- assertEquals(AnnotationColourGradient.BELOW_THRESHOLD,
- gc.getThreshType());
- assertEquals(66.0f, gc.getThresh(), 0.001f);
-
- // inverse gradient high to low:
- spec = "blue|255,0,255|95.0|20.0|below|66.0";
- gc = ff.parseGraduatedColourScheme("BETA-TURN-IR\t" + spec, spec);
- assertTrue(gc.isAutoScale());
- assertTrue(gc.getTolow());
- }
-
- /**
* Test parsing a features file with GFF formatted content only
*
* @throws Exception
File f = new File("examples/uniref50.fa");
AlignmentI al = readAlignmentFile(f);
AlignFrame af = new AlignFrame(al, 500, 500);
- Map<String, Object> colours = af.getFeatureRenderer()
+ Map<String, FeatureColourI> colours = af.getFeatureRenderer()
.getFeatureColours();
// GFF3 uses '=' separator for name/value pairs in colum 9
String gffData = "##gff-version 3\n"
File f = new File("examples/uniref50.fa");
AlignmentI al = readAlignmentFile(f);
AlignFrame af = new AlignFrame(al, 500, 500);
- Map<String, Object> colours = af.getFeatureRenderer()
+ Map<String, FeatureColourI> colours = af.getFeatureRenderer()
.getFeatureColours();
/*
File f = new File("examples/uniref50.fa");
AlignmentI al = readAlignmentFile(f);
AlignFrame af = new AlignFrame(al, 500, 500);
- Map<String, Object> colours = af.getFeatureRenderer()
+ Map<String, FeatureColourI> colours = af.getFeatureRenderer()
.getFeatureColours();
String features = "METAL\tcc9900\n"
+ "GAMMA-TURN\tred|0,255,255|20.0|95.0|below|66.0\n"
* first with no features displayed
*/
FeatureRenderer fr = af.alignPanel.getFeatureRenderer();
- Map<String, Object> visible = fr
+ Map<String, FeatureColourI> visible = fr
.getDisplayedFeatureCols();
String exported = featuresFile.printJalviewFormat(
al.getSequencesArray(), visible);
--- /dev/null
+package jalview.schemes;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertFalse;
+import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.AssertJUnit.fail;
+
+import jalview.datamodel.SequenceFeature;
+import jalview.util.Format;
+
+import java.awt.Color;
+
+import org.testng.annotations.Test;
+
+public class FeatureColourTest
+{
+ @Test(groups = { "Functional" })
+ public void testIsColored_simpleColour()
+ {
+ FeatureColour fc = new FeatureColour(Color.RED);
+ assertTrue(fc.isColored(new SequenceFeature()));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testIsColored_colourByLabel()
+ {
+ FeatureColour fc = new FeatureColour();
+ fc.setColourByLabel(true);
+ assertTrue(fc.isColored(new SequenceFeature()));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testIsColored_aboveThreshold()
+ {
+ // graduated colour range from score 20 to 100
+ FeatureColour fc = new FeatureColour(Color.WHITE, Color.BLACK, 20f,
+ 100f);
+
+ // score 0 is adjusted to bottom of range
+ SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 0f,
+ null);
+ assertTrue(fc.isColored(sf));
+ assertEquals(Color.WHITE, fc.getColor(sf));
+
+ // score 120 is adjusted to top of range
+ sf.setScore(120f);
+ assertEquals(Color.BLACK, fc.getColor(sf));
+
+ // value below threshold is still rendered
+ // setting threshold has no effect yet...
+ fc.setThreshold(60f);
+ sf.setScore(36f);
+ assertTrue(fc.isColored(sf));
+ assertEquals(new Color(204, 204, 204), fc.getColor(sf));
+
+ // now apply threshold:
+ fc.setAboveThreshold(true);
+ assertFalse(fc.isColored(sf));
+ // colour is still returned though ?!?
+ assertEquals(new Color(204, 204, 204), fc.getColor(sf));
+
+ sf.setScore(84); // above threshold now
+ assertTrue(fc.isColored(sf));
+ assertEquals(new Color(51, 51, 51), fc.getColor(sf));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testGetColor_simpleColour()
+ {
+ FeatureColour fc = new FeatureColour(Color.RED);
+ assertEquals(Color.RED, fc.getColor(new SequenceFeature()));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testGetColor_colourByLabel()
+ {
+ FeatureColour fc = new FeatureColour();
+ fc.setColourByLabel(true);
+ SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 1f,
+ null);
+ Color expected = UserColourScheme.createColourFromName("desc");
+ assertEquals(expected, fc.getColor(sf));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testGetColor_Graduated()
+ {
+ // graduated colour from score 0 to 100, gray(128, 128, 128) to red(255, 0, 0)
+ FeatureColour fc = new FeatureColour(Color.GRAY, Color.RED, 0f, 100f);
+ // feature score is 75 which is 3/4 of the way from GRAY to RED
+ SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 75f,
+ null);
+ // the colour gradient is computed in float values from 0-1 (where 1 == 255)
+ float red = 128 / 255f + 3 / 4f * (255 - 128) / 255f;
+ float green = 128 / 255f + 3 / 4f * (0 - 128) / 255f;
+ float blue = 128 / 255f + 3 / 4f * (0 - 128) / 255f;
+ Color expected = new Color(red, green, blue);
+ assertEquals(expected, fc.getColor(sf));
+ }
+
+ @Test(groups = { "Functional" })
+ public void testGetColor_belowThreshold()
+ {
+ // gradient from [50, 150] from WHITE(255, 255, 255) to BLACK(0, 0, 0)
+ FeatureColour fc = new FeatureColour(Color.WHITE, Color.BLACK, 50f,
+ 150f);
+ SequenceFeature sf = new SequenceFeature("type", "desc", 0, 20, 70f,
+ null);
+ fc.setThreshold(100f); // ignore for now
+ assertTrue(fc.isColored(sf));
+ assertEquals(new Color(204, 204, 204), fc.getColor(sf));
+
+ fc.setAboveThreshold(true); // feature lies below threshold
+ assertFalse(fc.isColored(sf));
+ assertEquals(new Color(204, 204, 204), fc.getColor(sf));
+ }
+
+ /**
+ * Test output of feature colours to Jalview features file format
+ */
+ @Test(groups = { "Functional" })
+ public void testToJalviewFormat()
+ {
+ /*
+ * plain colour - to RGB hex code
+ */
+ FeatureColour fc = new FeatureColour(Color.RED);
+ String redHex = Format.getHexString(Color.RED);
+ String hexColour = redHex;
+ assertEquals("domain\t" + hexColour, fc.toJalviewFormat("domain"));
+
+ /*
+ * colour by label (no threshold)
+ */
+ fc = new FeatureColour();
+ fc.setColourByLabel(true);
+ assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
+
+ /*
+ * colour by label (autoscaled) (an odd state you can reach by selecting
+ * 'above threshold', then deselecting 'threshold is min/max' then 'colour
+ * by label')
+ */
+ fc.setAutoScaled(true);
+ assertEquals("domain\tlabel", fc.toJalviewFormat("domain"));
+
+ /*
+ * colour by label (above threshold) (min/max values are output though not
+ * used by this scheme)
+ */
+ fc.setAutoScaled(false);
+ fc.setThreshold(12.5f);
+ fc.setAboveThreshold(true);
+ assertEquals("domain\tlabel|||0.0|0.0|above|12.5",
+ fc.toJalviewFormat("domain"));
+
+ /*
+ * colour by label (below threshold)
+ */
+ fc.setBelowThreshold(true);
+ assertEquals("domain\tlabel|||0.0|0.0|below|12.5",
+ fc.toJalviewFormat("domain"));
+
+ /*
+ * graduated colour, no threshold
+ */
+ fc = new FeatureColour(Color.GREEN, Color.RED, 12f, 25f);
+ String greenHex = Format.getHexString(Color.GREEN);
+ String expected = String.format("domain\t%s|%s|abso|12.0|25.0|none",
+ greenHex, redHex);
+ assertEquals(expected, fc.toJalviewFormat("domain"));
+
+ /*
+ * colour ranges over the actual score ranges (not min/max)
+ */
+ fc.setAutoScaled(true);
+ expected = String.format("domain\t%s|%s|12.0|25.0|none", greenHex,
+ redHex);
+ assertEquals(expected, fc.toJalviewFormat("domain"));
+
+ /*
+ * graduated colour below threshold
+ */
+ fc.setThreshold(12.5f);
+ fc.setBelowThreshold(true);
+ expected = String.format("domain\t%s|%s|12.0|25.0|below|12.5",
+ greenHex, redHex);
+ assertEquals(expected, fc.toJalviewFormat("domain"));
+
+ /*
+ * graduated colour above threshold
+ */
+ fc.setThreshold(12.5f);
+ fc.setAboveThreshold(true);
+ fc.setAutoScaled(false);
+ expected = String.format("domain\t%s|%s|abso|12.0|25.0|above|12.5",
+ greenHex, redHex);
+ assertEquals(expected, fc.toJalviewFormat("domain"));
+ }
+
+ /**
+ * Test parsing of feature colours from Jalview features file format
+ */
+ @Test(groups = { "Functional" })
+ public void testParseJalviewFeatureColour()
+ {
+ /*
+ * simple colour by name
+ */
+ FeatureColour fc = FeatureColour.parseJalviewFeatureColour("red");
+ assertTrue(fc.isSimpleColour());
+ assertEquals(Color.RED, fc.getColour());
+
+ /*
+ * simple colour by hex code
+ */
+ fc = FeatureColour.parseJalviewFeatureColour(Format
+ .getHexString(Color.RED));
+ assertTrue(fc.isSimpleColour());
+ assertEquals(Color.RED, fc.getColour());
+
+ /*
+ * simple colour by rgb triplet
+ */
+ fc = FeatureColour.parseJalviewFeatureColour("255,0,0");
+ assertTrue(fc.isSimpleColour());
+ assertEquals(Color.RED, fc.getColour());
+
+ /*
+ * malformed colour
+ */
+ try
+ {
+ fc = FeatureColour.parseJalviewFeatureColour("oops");
+ fail("expected exception");
+ } catch (IllegalArgumentException e)
+ {
+ assertEquals("Invalid colour descriptor: oops", e.getMessage());
+ }
+
+ /*
+ * colour by label (no threshold)
+ */
+ fc = FeatureColour.parseJalviewFeatureColour("label");
+ assertTrue(fc.isColourByLabel());
+ assertFalse(fc.hasThreshold());
+
+ /*
+ * colour by label (with threshold)
+ */
+ fc = FeatureColour
+ .parseJalviewFeatureColour("label|||0.0|0.0|above|12.0");
+ assertTrue(fc.isColourByLabel());
+ assertTrue(fc.isAboveThreshold());
+ assertEquals(12.0f, fc.getThreshold());
+
+ /*
+ * graduated colour (by name) (no threshold)
+ */
+ fc = FeatureColour.parseJalviewFeatureColour("red|green|10.0|20.0");
+ assertTrue(fc.isGraduatedColour());
+ assertFalse(fc.hasThreshold());
+ assertEquals(Color.RED, fc.getMinColour());
+ assertEquals(Color.GREEN, fc.getMaxColour());
+ assertEquals(10f, fc.getMin());
+ assertEquals(20f, fc.getMax());
+ assertTrue(fc.isAutoScaled());
+
+ /*
+ * graduated colour (by hex code) (above threshold)
+ */
+ String descriptor = String.format("%s|%s|10.0|20.0|above|15",
+ Format.getHexString(Color.RED),
+ Format.getHexString(Color.GREEN));
+ fc = FeatureColour.parseJalviewFeatureColour(descriptor);
+ assertTrue(fc.isGraduatedColour());
+ assertTrue(fc.hasThreshold());
+ assertTrue(fc.isAboveThreshold());
+ assertEquals(15f, fc.getThreshold());
+ assertEquals(Color.RED, fc.getMinColour());
+ assertEquals(Color.GREEN, fc.getMaxColour());
+ assertEquals(10f, fc.getMin());
+ assertEquals(20f, fc.getMax());
+ assertTrue(fc.isAutoScaled());
+
+ /*
+ * graduated colour (by RGB triplet) (below threshold), absolute scale
+ */
+ descriptor = String.format("255,0,0|0,255,0|abso|10.0|20.0|below|15");
+ fc = FeatureColour.parseJalviewFeatureColour(descriptor);
+ assertTrue(fc.isGraduatedColour());
+ assertFalse(fc.isAutoScaled());
+ assertTrue(fc.hasThreshold());
+ assertTrue(fc.isBelowThreshold());
+ assertEquals(15f, fc.getThreshold());
+ assertEquals(Color.RED, fc.getMinColour());
+ assertEquals(Color.GREEN, fc.getMaxColour());
+ assertEquals(10f, fc.getMin());
+ assertEquals(20f, fc.getMax());
+ }
+}
--- /dev/null
+package jalview.schemes;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNull;
+import static org.testng.AssertJUnit.assertSame;
+
+import java.awt.Color;
+
+import org.testng.annotations.Test;
+public class UserColourSchemeTest
+{
+
+ @Test(groups = "functional")
+ public void testGetColourFromString()
+ {
+ /*
+ * by colour name - if known to AWT, and included in
+ *
+ * @see ColourSchemeProperty.getAWTColorFromName()
+ */
+ assertSame(Color.RED, UserColourScheme.getColourFromString("red"));
+ assertSame(Color.RED, UserColourScheme.getColourFromString("Red"));
+ assertSame(Color.RED, UserColourScheme.getColourFromString(" RED "));
+
+ /*
+ * by RGB hex code
+ */
+ String hexColour = Integer.toHexString(Color.RED.getRGB() & 0xffffff);
+ assertEquals(Color.RED, UserColourScheme.getColourFromString(hexColour));
+ // 'hex' prefixes _not_ wanted here
+ assertNull(UserColourScheme.getColourFromString("0x" + hexColour));
+ assertNull(UserColourScheme.getColourFromString("#" + hexColour));
+
+ /*
+ * by RGB triplet
+ */
+ String rgb = String.format("%d,%d,%d", Color.red.getRed(),
+ Color.red.getGreen(), Color.red.getBlue());
+ assertEquals(Color.RED, UserColourScheme.getColourFromString(rgb));
+
+ /*
+ * odds and ends
+ */
+ assertNull(UserColourScheme.getColourFromString(null));
+ assertNull(UserColourScheme.getColourFromString("rubbish"));
+ assertEquals(Color.WHITE, UserColourScheme.getColourFromString("-1"));
+ assertNull(UserColourScheme.getColourFromString(String
+ .valueOf(Integer.MAX_VALUE)));
+ }
+}