--- /dev/null
+/*
+ * Jalview - A Sequence Alignment Editor and Viewer (Version 2.4)
+ * Copyright (C) 2008 AM Waterhouse, J Procter, G Barton, M Clamp, S Searle
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+package jalview.appletgui;
+
+import java.util.*;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import jalview.datamodel.*;
+import jalview.schemes.*;
+import java.awt.Rectangle;
+
+public class FeatureColourChooser extends Panel implements
+ ActionListener, AdjustmentListener, ItemListener, MouseListener
+{
+ Frame frame;
+
+ FeatureRenderer fr;
+ FeatureSettings fs;
+ AlignmentPanel ap;
+
+ GraduatedColor cs;
+ Object oldcs;
+
+ Hashtable oldgroupColours;
+
+
+ boolean adjusting = false;
+ private float min,max;
+ String type=null;
+
+ public FeatureColourChooser(FeatureSettings fsettings, String type)
+ {
+ this.fs = fsettings;
+ this.type = type;
+ fr = fsettings.fr;
+ ap = fsettings.ap;
+ float mm[] = ((float[][]) fr.minmax.get(type))[0];
+ min = mm[0];
+ max = mm[1];
+ oldcs = fr.featureColours.get(type);
+ if (oldcs instanceof GraduatedColor)
+ {
+ cs = new GraduatedColor((GraduatedColor) oldcs, min, max);
+ } else {
+ // promote original color to a graduated color
+ Color bl = Color.black;
+ if (oldcs instanceof Color)
+ {
+ bl = (Color) oldcs;
+ }
+ // original colour becomes the maximum colour
+ cs = new GraduatedColor(Color.white,bl,mm[0],mm[1]);
+ }
+ minColour.setBackground(cs.getMinColor());
+ maxColour.setBackground(cs.getMaxColor());
+ adjusting = true;
+
+ try
+ {
+ jbInit();
+ } catch (Exception ex)
+ {
+ }
+ // To HERE!
+ adjusting = false;
+ changeColour();
+ slider.addAdjustmentListener(this);
+ slider.addMouseListener(this);
+ frame = new Frame();
+ frame.add(this);
+ jalview.bin.JalviewLite.addFrame(frame, "Graduated Feature Colour for "+type, 480,
+ 145);
+ validate();
+ }
+
+ public FeatureColourChooser()
+ {
+ try
+ {
+ jbInit();
+ } catch (Exception ex)
+ {
+ ex.printStackTrace();
+ }
+ }
+
+ private void jbInit() throws Exception
+ {
+ minColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+ minColour.setLabel("Min Colour");
+ minColour.addActionListener(this);
+
+ maxColour.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+ maxColour.setLabel("Max Colour");
+ maxColour.addActionListener(this);
+
+ thresholdIsMin.addItemListener(this);
+ ok.setLabel("OK");
+ ok.addActionListener(this);
+
+ cancel.setLabel("Cancel");
+ cancel.addActionListener(this);
+
+ this.setLayout(borderLayout1);
+ jPanel2.setLayout(flowLayout1);
+
+ jPanel1.setBackground(Color.white);
+ jPanel2.setBackground(Color.white);
+ threshold.addItemListener(this);
+ threshold.addItem("No Threshold");
+ threshold.addItem("Above Threshold");
+ threshold.addItem("Below Threshold");
+ jPanel3.setLayout(null);
+ thresholdValue.addActionListener(this);
+
+ slider.setBackground(Color.white);
+ slider.setEnabled(false);
+ slider.setBounds(new Rectangle(153, 3, 93, 21));
+ thresholdValue.setEnabled(false);
+ thresholdValue.setBounds(new Rectangle(248, 2, 79, 22));
+ thresholdValue.setColumns(5);
+ jPanel3.setBackground(Color.white);
+ //currentColours.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11));
+ //currentColours.setLabel("Use Original Colours");
+ //currentColours.addItemListener(this);
+
+ threshold.setBounds(new Rectangle(11, 3, 139, 22));
+ thresholdIsMin.setBackground(Color.white);
+ thresholdIsMin.setLabel("Threshold is min/max");
+ thresholdIsMin.setBounds(new Rectangle(328, 3, 135, 23));
+ jPanel1.add(ok);
+ jPanel1.add(cancel);
+ //jPanel2.add(currentColours);
+ jPanel2.add(minColour);
+ jPanel2.add(maxColour);
+ jPanel3.add(threshold);
+ jPanel3.add(slider);
+ jPanel3.add(thresholdValue);
+ jPanel3.add(thresholdIsMin);
+ this.add(jPanel2, java.awt.BorderLayout.NORTH);
+ this.add(jPanel3, java.awt.BorderLayout.CENTER);
+ this.add(jPanel1, java.awt.BorderLayout.SOUTH);
+ }
+
+ Button minColour = new Button();
+
+ Button maxColour = new Button();
+
+ Button ok = new Button();
+
+ Button cancel = new Button();
+
+ Panel jPanel1 = new Panel();
+
+ Panel jPanel2 = new Panel();
+
+ Choice threshold = new Choice();
+
+ FlowLayout flowLayout1 = new FlowLayout();
+
+ Panel jPanel3 = new Panel();
+
+ Scrollbar slider = new Scrollbar(Scrollbar.HORIZONTAL);
+
+ TextField thresholdValue = new TextField(20);
+
+
+ BorderLayout borderLayout1 = new BorderLayout();
+
+ Checkbox thresholdIsMin = new Checkbox();
+
+ private GraphLine threshline;
+
+ public void actionPerformed(ActionEvent evt)
+ {
+ if (evt.getSource() == thresholdValue)
+ {
+ try
+ {
+ float f = new Float(thresholdValue.getText()).floatValue();
+ slider.setValue((int) (f * 1000));
+ adjustmentValueChanged(null);
+ } catch (NumberFormatException ex)
+ {
+ }
+ }
+ else if (evt.getSource() == minColour)
+ {
+ minColour_actionPerformed(null);
+ }
+ else if (evt.getSource() == maxColour)
+ {
+ maxColour_actionPerformed(null);
+ }
+
+ else if (evt.getSource() == ok)
+ {
+ changeColour();
+ frame.setVisible(false);
+ }
+ else if (evt.getSource() == cancel)
+ {
+ reset();
+ ap.paintAlignment(true);
+ frame.setVisible(false);
+ }
+
+ else
+ {
+ changeColour();
+ }
+ }
+
+ public void itemStateChanged(ItemEvent evt)
+ {
+
+ changeColour();
+ }
+
+ public void adjustmentValueChanged(AdjustmentEvent evt)
+ {
+ if (!adjusting)
+ {
+ thresholdValue.setText(((float) slider.getValue() / 1000f) + "");
+ valueChanged();
+ }
+ }
+ protected void valueChanged() {
+ changeColour();
+ threshline.value = (float) slider.getValue() / 1000f;
+ ap.paintAlignment(false);
+ }
+ public void minColour_actionPerformed(Color newCol)
+ {
+ if (newCol != null)
+ {
+ minColour.setBackground(newCol);
+ minColour.repaint();
+ changeColour();
+ }
+ else
+ {
+ new UserDefinedColours(this, "Select Colour for Minimum Value", minColour.getBackground());
+ }
+
+ }
+
+ public void maxColour_actionPerformed(Color newCol)
+ {
+ if (newCol != null)
+ {
+ maxColour.setBackground(newCol);
+ maxColour.repaint();
+ changeColour();
+ }
+ else
+ {
+ new UserDefinedColours(this, "Select Colour for Maximum Value", maxColour.getBackground());
+ }
+ }
+
+ void changeColour()
+ {
+ // Check if combobox is still adjusting
+ if (adjusting)
+ {
+ return;
+ }
+
+ int aboveThreshold = AnnotationColourGradient.NO_THRESHOLD;
+ if (threshold.getSelectedItem().equals("Above Threshold"))
+ {
+ aboveThreshold = AnnotationColourGradient.ABOVE_THRESHOLD;
+ }
+ else if (threshold.getSelectedItem().equals("Below Threshold"))
+ {
+ aboveThreshold = AnnotationColourGradient.BELOW_THRESHOLD;
+ }
+
+ slider.setEnabled(true);
+ thresholdValue.setEnabled(true);
+ GraduatedColor acg = new GraduatedColor(minColour.getBackground(), maxColour.getBackground(), min, max);
+
+ if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD)
+ {
+ slider.setEnabled(false);
+ thresholdValue.setEnabled(false);
+ thresholdValue.setText("");
+ }
+
+ else if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD
+ && threshline == null)
+ {
+ // todo visual indication of feature threshold
+ threshline = new jalview.datamodel.GraphLine(
+ (max - min) / 2f,
+ "Threshold", Color.black);
+ }
+
+ if (aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
+ {
+ adjusting = true;
+ acg.setThresh(threshline.value);
+
+ float range = max * 1000f
+ - min * 1000f;
+
+ slider.setMinimum((int) (min * 1000));
+ slider.setMaximum((int) (max * 1000));
+ slider.setValue((int) (threshline.value * 1000));
+ thresholdValue.setText(threshline.value + "");
+ slider.setEnabled(true);
+ thresholdValue.setEnabled(true);
+ adjusting = false;
+ }
+
+ acg.setThreshType(aboveThreshold);
+ if (thresholdIsMin.getState() && aboveThreshold != AnnotationColourGradient.NO_THRESHOLD)
+ {
+ if (aboveThreshold==AnnotationColourGradient.ABOVE_THRESHOLD)
+ {
+ acg = new GraduatedColor(acg, threshline.value, max);
+ } else {
+ acg = new GraduatedColor(acg, min,threshline.value);
+ }
+ }
+
+ fr.featureColours.put(type,acg);
+ cs = acg;
+ ap.paintAlignment(false);
+ }
+
+ void reset()
+ {
+ fr.featureColours.put(type, oldcs);
+ ap.paintAlignment(true);
+
+ }
+
+ public void mouseClicked(MouseEvent evt)
+ {
+ }
+
+ public void mousePressed(MouseEvent evt)
+ {
+ }
+
+ public void mouseReleased(MouseEvent evt)
+ {
+ ap.paintAlignment(true);
+ }
+
+ public void mouseEntered(MouseEvent evt)
+ {
+ }
+
+ public void mouseExited(MouseEvent evt)
+ {
+ }
+
+}
import jalview.appletgui.FeatureSettings.MyCheckbox;
import jalview.datamodel.*;
+import jalview.schemes.GraduatedColor;
/**
* DOCUMENT ME!
if (sequenceFeatures[sfindex].begin <= start
&& sequenceFeatures[sfindex].end >= start)
{
- currentColour = av.featuresDisplayed
- .get(sequenceFeatures[sfindex].type);
+ currentColour = new Integer(getColour(sequenceFeatures[sfindex]).getRGB());//av.featuresDisplayed
+ //.get(sequenceFeatures[sfindex].type);
}
}
renderFeature(g, seq, seq
.findIndex(sequenceFeatures[sfindex].begin) - 1, seq
.findIndex(sequenceFeatures[sfindex].end) - 1,
- getColour(sequenceFeatures[sfindex].type), start, end, y1);
+ getColour(sequenceFeatures[sfindex]), start, end, y1);
}
}
}
}
}
-
+ Hashtable minmax=null;
void findAllFeatures()
{
jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme();
av.featuresDisplayed = new Hashtable();
Vector allfeatures = new Vector();
+ minmax = new Hashtable();
+
for (int i = 0; i < av.alignment.getHeight(); i++)
{
SequenceFeature[] features = av.alignment.getSequenceAt(i)
int index = 0;
while (index < features.length)
{
+ if (features[index].begin==0 && features[index].end==0) {
+ index++;
+ continue;
+ }
if (!av.featuresDisplayed.containsKey(features[index].getType()))
{
if (getColour(features[index].getType()) == null)
getColour(features[index].getType()).getRGB()));
allfeatures.addElement(features[index].getType());
}
+ if (features[index].score != Float.NaN)
+ {
+ int nonpos= features[index].getBegin()>=1 ? 0 : 1;
+ float[][] mm = (float[][]) minmax.get(features[index].getType());
+ if (mm == null)
+ {
+ mm = new float[][] {null, null };
+ minmax.put(features[index].getType(), mm);
+ }
+ if (mm[nonpos]==null)
+ {
+ mm[nonpos] = new float[] { features[index].score, features[index].score };
+
+ }
+ else
+ {
+ if (mm[nonpos][0] > features[index].score)
+ {
+ mm[nonpos][0] = features[index].score;
+ }
+ if (mm[nonpos][1] < features[index].score)
+ {
+ mm[nonpos][1] = features[index].score;
+ }
+ }
+ }
+
index++;
}
}
public Color getColour(String featureType)
{
- if (!featureColours.containsKey(featureType))
+ Object fc = featureColours.get(featureType);
+ if (fc == null)
{
jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme();
Color col = ucs.createColourFromName(featureType);
featureColours.put(featureType, col);
return col;
}
+ else if (fc instanceof Color)
+ {
+ return (Color) fc;
+ }
else
- return (Color) featureColours.get(featureType);
+ {
+ if (fc instanceof GraduatedColor)
+ {
+ return ((GraduatedColor) fc).getMinColor();
+ }
+ // TODO: raise an implementation error here.
+ return null; // Color.white;
+ }
+ }
+ /**
+ * implement graduated colouring for features with scores
+ *
+ * @param feature
+ * @return render colour for the given feature
+ */
+ public Color getColour(SequenceFeature feature)
+ {
+ Object fc = featureColours.get(feature.type);
+ if (fc == null)
+ {
+ jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme();
+ Color col = ucs.createColourFromName(feature.type);
+ featureColours.put(feature.type, col);
+ return col;
+ }
+ else if (fc instanceof Color)
+ {
+ return (Color) fc;
+ }
+ else
+ {
+ if (fc instanceof GraduatedColor)
+ {
+ return ((GraduatedColor) fc).findColor(feature);
+ }
+ // TODO: raise an implementation error here.
+ return null; // Color.white;
+ }
}
public void setColour(String featureType, Color col)
return alignmentHasFeatures;
}
+ /**
+ *
+ * @return the displayed feature type as an array of strings
+ */
+ protected String[] getDisplayedFeatureTypes()
+ {
+ String[] typ = null;
+ synchronized (renderOrder)
+ {
+ typ = new String[renderOrder.length];
+ System.arraycopy(renderOrder, 0, typ, 0, typ.length);
+ for (int i = 0; i < typ.length; i++)
+ {
+ if (av.featuresDisplayed.get(typ[i]) == null)
+ {
+ typ[i] = null;
+ }
+ }
+ }
+ return typ;
+ }
}
class TransparencySetter
import java.awt.*;
import java.awt.event.*;
+import jalview.analysis.AlignmentSorter;
+import jalview.commands.OrderCommand;
import jalview.datamodel.*;
public class FeatureSettings extends Panel implements ItemListener,
g.drawString("(Features can be added from searches or", 10, 40);
g.drawString("from Jalview / GFF features files)", 10, 60);
}
+ protected void popupSort(final String type, final Hashtable minmax,
+ int x, int y)
+ {
+ java.awt.PopupMenu men = new PopupMenu("Settings for " + type);
+ java.awt.MenuItem scr = new MenuItem("Sort by Score");
+ men.add(scr);
+ final FeatureSettings me = this;
+ scr.addActionListener(new ActionListener()
+ {
+
+ public void actionPerformed(ActionEvent e)
+ {
+ me.sortByScore(new String[]
+ { type });
+ }
+
+ });
+ MenuItem dens = new MenuItem("Sort by Density");
+ dens.addActionListener(new ActionListener()
+ {
+
+ public void actionPerformed(ActionEvent e)
+ {
+ me.sortByDens(new String[]
+ { type });
+ }
+
+ });
+ men.add(dens);
+ if (minmax != null)
+ {
+ final Object typeMinMax = minmax.get(type);
+ final java.awt.CheckboxMenuItem chb = new java.awt.CheckboxMenuItem("Vary Height");
+ // this is broken at the moment
+ chb.setState(minmax.get(type) != null);
+ chb.addActionListener(new ActionListener()
+ {
+
+ public void actionPerformed(ActionEvent e)
+ {
+ chb.setState(chb.getState());
+ if (chb.getState())
+ {
+ minmax.put(type, null);
+ }
+ else
+ {
+ minmax.put(type, typeMinMax);
+ }
+ }
+
+ });
+ men.add(chb);
+ if (typeMinMax != null && ((float[][]) typeMinMax)[0] != null)
+ {
+ // graduated colourschemes for those where minmax exists for the positional features
+ MenuItem mxcol = new MenuItem("Min Max Colour");
+ men.add(mxcol);
+ mxcol.addActionListener(new ActionListener()
+ {
+
+ public void actionPerformed(ActionEvent e)
+ {
+ new FeatureColourChooser(me, type);
+ }
+
+ });
+ }
+ }
+ this.featurePanel.add(men);
+ men.show(this.featurePanel, x, y);
+ }
public void setTableData()
{
public void mouseClicked(MouseEvent evt)
{
MyCheckbox check = (MyCheckbox) evt.getSource();
-
+ if ((evt.getModifiers() & InputEvent.BUTTON3_MASK)!=0)
+ {
+ this.popupSort(check.getLabel(), fr.minmax, evt.getX(), evt.getY());
+ }
if (fr.featureLinks != null
&& fr.featureLinks.containsKey(check.getLabel()))
{
}
}
}
+ protected void sortByDens(String[] typ)
+ {
+ sortBy(typ, "Sort by Density", AlignmentSorter.FEATURE_DENSITY);
+ }
+ private String[] getDisplayedFeatureTypes()
+ {
+ String[] typ = null;
+ if (fr != null)
+ {
+ synchronized (fr.renderOrder)
+ {
+ typ = new String[fr.renderOrder.length];
+ System.arraycopy(fr.renderOrder, 0, typ, 0, typ.length);
+ for (int i = 0; i < typ.length; i++)
+ {
+ if (av.featuresDisplayed.get(typ[i]) == null)
+ {
+ typ[i] = null;
+ }
+ }
+ }
+ }
+ return typ;
+ }
+
+
+ protected void sortBy(String[] typ, String methodText, final String method)
+ {
+ if (typ == null)
+ {
+ typ = getDisplayedFeatureTypes();
+ }
+ String gps[] = null;
+ gps = fr.getGroups(true);
+ if (typ != null)
+ {
+ for (int i = 0; i < typ.length; i++)
+ {
+ System.err.println("Sorting on Types:" + typ[i]);
+ }
+ }
+ if (gps != null)
+ {
+
+ for (int i = 0; i < gps.length; i++)
+ {
+ System.err.println("Sorting on groups:" + gps[i]);
+ }
+ }
+ AlignmentPanel alignPanel = ap;
+ AlignmentI al = alignPanel.av.getAlignment();
+
+ int start, stop;
+ SequenceGroup sg = alignPanel.av.getSelectionGroup();
+ if (sg != null)
+ {
+ start = sg.getStartRes();
+ stop = sg.getEndRes();
+ }
+ else
+ {
+ start = 0;
+ stop = al.getWidth();
+ }
+ SequenceI[] oldOrder = al.getSequencesArray();
+ AlignmentSorter.sortByFeature(typ, gps, start, stop, al, method);
+ this.ap.alignFrame.addHistoryItem(new OrderCommand(methodText, oldOrder, alignPanel.av
+ .getAlignment()));
+ alignPanel.paintAlignment(true);
+
+ }
+
+ protected void sortByScore(String[] typ)
+ {
+ sortBy(typ, "Sort by Feature Score", AlignmentSorter.FEATURE_SCORE);
+ }
+
}