/*
- * Jalview - A Sequence Alignment Editor and Viewer (Version 2.5)
- * Copyright (C) 2010 J Procter, AM Waterhouse, G Barton, M Clamp, S Searle
+ * 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.
- *
+ * 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/>.
+ * 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.appletgui;
-import java.util.*;
-
-import java.awt.*;
-
-import java.awt.event.*;
-
-import jalview.appletgui.FeatureSettings.MyCheckbox;
-import jalview.datamodel.*;
-import jalview.schemes.AnnotationColourGradient;
-import jalview.schemes.GraduatedColor;
+import jalview.api.FeatureColourI;
+import jalview.datamodel.SearchResults;
+import jalview.datamodel.SearchResultsI;
+import jalview.datamodel.SequenceFeature;
+import jalview.datamodel.SequenceI;
+import jalview.io.FeaturesFile;
+import jalview.schemes.FeatureColour;
+import jalview.util.ColorUtils;
+import jalview.util.MessageManager;
+import jalview.viewmodel.AlignmentViewport;
+
+import java.awt.BorderLayout;
+import java.awt.Button;
+import java.awt.Choice;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.GridLayout;
+import java.awt.Label;
+import java.awt.Panel;
+import java.awt.ScrollPane;
+import java.awt.TextArea;
+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.awt.event.TextEvent;
+import java.awt.event.TextListener;
+import java.util.Hashtable;
+import java.util.List;
/**
* DOCUMENT ME!
* @version $Revision$
*/
public class FeatureRenderer
+ extends jalview.renderer.seqfeatures.FeatureRenderer
{
- AlignViewport av;
-
- Hashtable featureColours = new Hashtable();
+ /*
+ * creating a new feature defaults to the type and group as
+ * the last one created
+ */
+ static String lastFeatureAdded = "feature_1";
- // A higher level for grouping features of a
- // particular type
- Hashtable featureGroups = null;
+ static String lastFeatureGroupAdded = "Jalview";
// Holds web links for feature groups and feature types
// in the form label|link
Hashtable featureLinks = null;
- // This is actually an Integer held in the hashtable,
- // Retrieved using the key feature type
- Object currentColour;
-
- String[] renderOrder;
-
- FontMetrics fm;
-
- int charOffset;
-
- float transparency = 1f;
-
- TransparencySetter transparencySetter = null;
-
/**
* Creates a new FeatureRenderer object.
*
* @param av
- * DOCUMENT ME!
*/
- public FeatureRenderer(AlignViewport av)
+ public FeatureRenderer(AlignmentViewport av)
{
- this.av = av;
-
- if (!System.getProperty("java.version").startsWith("1.1"))
- {
- transparencySetter = new TransparencySetter();
- }
- }
+ super(av);
- public void transferSettings(FeatureRenderer fr)
- {
- renderOrder = fr.renderOrder;
- featureGroups = fr.featureGroups;
- featureColours = fr.featureColours;
- transparency = fr.transparency;
}
- static String lastFeatureAdded;
-
- static String lastFeatureGroupAdded;
-
- static String lastDescriptionAdded;
-
int featureIndex = 0;
boolean deleteFeature = false;
/**
* 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)
- {
- isGcol = false;
- col = (Color) newcol;
- gcol = null;
- }
- else if (newcol instanceof GraduatedColor)
+ if (newcol.isSimpleColour())
{
- isGcol = true;
- gcol = (GraduatedColor) newcol;
- col = null;
+ bg = newcol.getColour();
+ setBackground(bg);
}
else
{
- throw new Error("Invalid color 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;
super(null);
}
+ @Override
public void paint(Graphics g)
{
Dimension d = getSize();
g.setColor(Color.black);
Font f = new Font("Verdana", Font.PLAIN, 10);
g.setFont(f);
- g.drawString("Label", 0, 0);
+ g.drawString(MessageManager.getString("label.label"), 0, 0);
}
else
{
}
- boolean amendFeatures(final SequenceI[] sequences,
- final SequenceFeature[] features, boolean newFeatures,
+ /**
+ * Shows a dialog allowing the user to create, or amend or delete, sequence
+ * features. If null in the supplied feature(s), feature type and group
+ * default to those for the last feature created (with initial defaults of
+ * "feature_1" and "Jalview").
+ *
+ * @param sequences
+ * @param features
+ * @param create
+ * @param ap
+ * @return
+ */
+ boolean amendFeatures(final List<SequenceI> sequences,
+ final List<SequenceFeature> features, boolean create,
final AlignmentPanel ap)
{
- Panel bigPanel = new Panel(new BorderLayout());
+ final Panel bigPanel = new Panel(new BorderLayout());
final TextField name = new TextField(16);
- final TextField source = new TextField(16);
+ final TextField group = new TextField(16);
final TextArea description = new TextArea(3, 35);
final TextField start = new TextField(8);
final TextField end = new TextField(8);
Button deleteButton = new Button("Delete");
deleteFeature = false;
+ name.addTextListener(new TextListener()
+ {
+ @Override
+ public void textValueChanged(TextEvent e)
+ {
+ warnIfTypeHidden(ap.alignFrame, name.getText());
+ }
+ });
+ group.addTextListener(new TextListener()
+ {
+ @Override
+ public void textValueChanged(TextEvent e)
+ {
+ warnIfGroupHidden(ap.alignFrame, group.getText());
+ }
+ });
colourPanel = new FeatureColourPanel();
colourPanel.setSize(110, 15);
final FeatureRenderer fr = this;
// /////////////////////////////////////
// /MULTIPLE FEATURES AT SELECTED RESIDUE
- if (!newFeatures && features.length > 1)
+ if (!create && features.size() > 1)
{
panel = new Panel(new GridLayout(4, 1));
tmp = new Panel();
tmp.add(new Label("Select Feature: "));
overlaps = new Choice();
- for (int i = 0; i < features.length; i++)
+ for (SequenceFeature sf : features)
{
- String item = features[i].getType() + "/" + features[i].getBegin()
- + "-" + features[i].getEnd();
-
- if (features[i].getFeatureGroup() != null)
- item += " (" + features[i].getFeatureGroup() + ")";
-
+ String item = sf.getType() + "/" + sf.getBegin() + "-"
+ + sf.getEnd();
+ if (sf.getFeatureGroup() != null)
+ {
+ item += " (" + sf.getFeatureGroup() + ")";
+ }
overlaps.addItem(item);
}
overlaps.addItemListener(new java.awt.event.ItemListener()
{
+ @Override
public void itemStateChanged(java.awt.event.ItemEvent e)
{
int index = overlaps.getSelectedIndex();
if (index != -1)
{
featureIndex = index;
- name.setText(features[index].getType());
- description.setText(features[index].getDescription());
- source.setText(features[index].getFeatureGroup());
- start.setText(features[index].getBegin() + "");
- end.setText(features[index].getEnd() + "");
+ SequenceFeature sf = features.get(index);
+ name.setText(sf.getType());
+ description.setText(sf.getDescription());
+ group.setText(sf.getFeatureGroup());
+ start.setText(sf.getBegin() + "");
+ end.setText(sf.getEnd() + "");
- SearchResults highlight = new SearchResults();
- highlight.addResult(sequences[0], features[index].getBegin(),
- features[index].getEnd());
+ SearchResultsI highlight = new SearchResults();
+ highlight.addResult(sequences.get(0), sf.getBegin(),
+ sf.getEnd());
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 = ColorUtils
.createColourFromName(name.getText());
+ col = new FeatureColour(generatedColour);
}
colourPanel.updateColor(col);
tmp = new Panel();
panel.add(tmp);
- tmp.add(new Label("Name: ", Label.RIGHT));
+ tmp.add(new Label(MessageManager.getString("label.name:"),
+ Label.RIGHT));
tmp.add(name);
tmp = new Panel();
panel.add(tmp);
- tmp.add(new Label("Group: ", Label.RIGHT));
- tmp.add(source);
+ tmp.add(new Label(MessageManager.getString("label.group:"),
+ Label.RIGHT));
+ tmp.add(group);
tmp = new Panel();
panel.add(tmp);
- tmp.add(new Label("Colour: ", Label.RIGHT));
+ tmp.add(new Label(MessageManager.getString("label.colour"),
+ Label.RIGHT));
tmp.add(colourPanel);
bigPanel.add(panel, BorderLayout.NORTH);
panel = new Panel();
- panel.add(new Label("Description: ", Label.RIGHT));
+ panel.add(new Label(MessageManager.getString("label.description:"),
+ Label.RIGHT));
panel.add(new ScrollPane().add(description));
- if (!newFeatures)
+ if (!create)
{
bigPanel.add(panel, BorderLayout.SOUTH);
panel = new Panel();
- panel.add(new Label(" Start:", Label.RIGHT));
+ panel.add(new Label(MessageManager.getString("label.start"),
+ Label.RIGHT));
panel.add(start);
- panel.add(new Label(" End:", Label.RIGHT));
+ panel.add(new Label(MessageManager.getString("label.end"),
+ Label.RIGHT));
panel.add(end);
bigPanel.add(panel, BorderLayout.CENTER);
}
bigPanel.add(panel, BorderLayout.CENTER);
}
- if (lastFeatureAdded == null)
- {
- if (features[0].type != null)
- {
- lastFeatureAdded = features[0].type;
- }
- else
- {
- lastFeatureAdded = "feature_1";
- }
- }
-
- if (lastFeatureGroupAdded == null)
- {
- if (features[0].featureGroup != null)
- {
- lastFeatureGroupAdded = features[0].featureGroup;
- }
- else
- {
- lastFeatureAdded = "Jalview";
- }
- }
-
- String title = newFeatures ? "Create New Sequence Feature(s)"
- : "Amend/Delete Features for " + sequences[0].getName();
+ /*
+ * use defaults for type and group (and update them on Confirm) only
+ * if feature type has not been supplied by the caller
+ * (e.g. for Amend, or create features from Find)
+ */
+ SequenceFeature firstFeature = features.get(0);
+ boolean useLastDefaults = firstFeature.getType() == null;
+ String featureType = useLastDefaults ? lastFeatureAdded
+ : firstFeature.getType();
+ String featureGroup = useLastDefaults ? lastFeatureGroupAdded
+ : firstFeature.getFeatureGroup();
+
+ String title = create
+ ? MessageManager.getString("label.create_new_sequence_features")
+ : MessageManager.formatMessage("label.amend_delete_features",
+ new String[]
+ { sequences.get(0).getName() });
final JVDialog dialog = new JVDialog(ap.alignFrame, title, true, 385,
240);
dialog.setMainPanel(bigPanel);
- if (newFeatures)
- {
- name.setText(lastFeatureAdded);
- source.setText(lastFeatureGroupAdded);
- }
- else
+ name.setText(featureType);
+ group.setText(featureGroup);
+
+ if (!create)
{
- dialog.ok.setLabel("Amend");
+ dialog.ok.setLabel(MessageManager.getString("label.amend"));
dialog.buttonPanel.add(deleteButton, 1);
deleteButton.addActionListener(new ActionListener()
{
+ @Override
public void actionPerformed(ActionEvent evt)
{
deleteFeature = true;
dialog.setVisible(false);
}
});
- name.setText(features[0].getType());
- source.setText(features[0].getFeatureGroup());
}
- start.setText(features[0].getBegin() + "");
- end.setText(features[0].getEnd() + "");
- description.setText(features[0].getDescription());
- Color col = getColour(name.getText());
- if (col == null)
- {
- col = new jalview.schemes.UserColourScheme()
- .createColourFromName(name.getText());
- }
- Object fcol = getFeatureStyle(name.getText());
+ start.setText(firstFeature.getBegin() + "");
+ end.setText(firstFeature.getEnd() + "");
+ description.setText(firstFeature.getDescription());
+ // 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()
{
- public void mousePressed(java.awt.event.MouseEvent evt)
+ @Override
+ 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)
+ /*
+ * only update default type and group if we used defaults
+ */
+ final String enteredType = name.getText().trim();
+ final String enteredGroup = group.getText().trim();
+ final String enteredDesc = description.getText().replace('\n', ' ');
+
+ if (dialog.accept && useLastDefaults)
{
- // This ensures that the last sequence
- // is refreshed and new features are rendered
- lastSeq = null;
- lastFeatureAdded = name.getText().trim();
- lastFeatureGroupAdded = source.getText().trim();
- lastDescriptionAdded = description.getText().replace('\n', ' ');
+ lastFeatureAdded = enteredType;
+ lastFeatureGroupAdded = enteredGroup;
}
- if (lastFeatureGroupAdded != null && lastFeatureGroupAdded.length() < 1)
- lastFeatureGroupAdded = null;
-
- if (!newFeatures)
+ if (!create)
{
-
- SequenceFeature sf = features[featureIndex];
+ SequenceFeature sf = features.get(featureIndex);
if (dialog.accept)
{
- sf.type = lastFeatureAdded;
- sf.featureGroup = lastFeatureGroupAdded;
- sf.description = lastDescriptionAdded;
if (!colourPanel.isGcol)
{
// update colour - otherwise its already done.
- setColour(sf.type, colourPanel.getBackground());
+ setColour(enteredType,
+ new FeatureColour(colourPanel.getBackground()));
}
+ int newBegin = sf.begin;
+ int newEnd = sf.end;
try
{
- sf.begin = Integer.parseInt(start.getText());
- sf.end = Integer.parseInt(end.getText());
+ newBegin = Integer.parseInt(start.getText());
+ newEnd = Integer.parseInt(end.getText());
} catch (NumberFormatException ex)
{
+ //
}
+ /*
+ * replace the feature by deleting it and adding a new one
+ * (to ensure integrity of SequenceFeatures data store)
+ */
+ sequences.get(0).deleteFeature(sf);
+ SequenceFeature newSf = new SequenceFeature(sf, enteredType,
+ newBegin, newEnd, enteredGroup, sf.getScore());
+ newSf.setDescription(enteredDesc);
+ ffile.parseDescriptionHTML(newSf, false);
+ // amend features dialog only updates one sequence at a time
+ sequences.get(0).addSequenceFeature(newSf);
+ boolean typeOrGroupChanged = (!featureType.equals(newSf.getType()) || !featureGroup
+ .equals(newSf.getFeatureGroup()));
+
ffile.parseDescriptionHTML(sf, false);
+ if (typeOrGroupChanged)
+ {
+ featuresAdded();
+ }
}
if (deleteFeature)
{
- sequences[0].deleteFeature(sf);
+ sequences.get(0).deleteFeature(sf);
+ // ensure Feature Settings reflects removal of feature / group
+ featuresAdded();
}
-
}
else
{
+ /*
+ * adding feature(s)
+ */
if (dialog.accept && name.getText().length() > 0)
{
- for (int i = 0; i < sequences.length; i++)
+ for (int i = 0; i < sequences.size(); i++)
{
- features[i].type = lastFeatureAdded;
- features[i].featureGroup = lastFeatureGroupAdded;
- features[i].description = lastDescriptionAdded;
- sequences[i].addSequenceFeature(features[i]);
- ffile.parseDescriptionHTML(features[i], false);
+ SequenceFeature sf = features.get(i);
+ SequenceFeature sf2 = new SequenceFeature(enteredType,
+ enteredDesc, sf.getBegin(), sf.getEnd(), enteredGroup);
+ ffile.parseDescriptionHTML(sf2, false);
+ sequences.get(i).addSequenceFeature(sf2);
}
- if (av.featuresDisplayed == null)
- {
- av.featuresDisplayed = new Hashtable();
- }
-
- if (featureGroups == null)
- {
- featureGroups = new Hashtable();
- }
-
- col = colourPanel.getBackground();
+ Color newColour = colourPanel.getBackground();
// setColour(lastFeatureAdded, fcol);
- if (lastFeatureGroupAdded != null)
- {
- featureGroups.put(lastFeatureGroupAdded, new Boolean(true));
- }
- if (fcol instanceof Color)
- {
- setColour(lastFeatureAdded, fcol);
- }
- av.featuresDisplayed.put(lastFeatureAdded,
- getFeatureStyle(lastFeatureAdded));
-
- findAllFeatures();
-
- String[] tro = new String[renderOrder.length];
- tro[0] = renderOrder[renderOrder.length - 1];
- System.arraycopy(renderOrder, 0, tro, 1, renderOrder.length - 1);
- renderOrder = tro;
+ setColour(enteredType, new FeatureColour(newColour)); // was fcol
+ featuresAdded();
}
else
{
}
}
// refresh the alignment and the feature settings dialog
- if (av.featureSettings != null)
+ if (((jalview.appletgui.AlignViewport) av).featureSettings != null)
{
- av.featureSettings.refreshTable();
+ ((jalview.appletgui.AlignViewport) av).featureSettings.refreshTable();
}
// findAllFeatures();
- ap.paintAlignment(true);
+ ap.paintAlignment(true, true);
return true;
}
- public Color findFeatureColour(Color initialCol, SequenceI seq, int i)
- {
- overview = true;
- if (!av.showSequenceFeatures)
- {
- return initialCol;
- }
-
- lastSeq = seq;
- sequenceFeatures = lastSeq.getSequenceFeatures();
- if (sequenceFeatures == null)
- {
- return initialCol;
- }
-
- sfSize = sequenceFeatures.length;
-
- if (jalview.util.Comparison.isGap(lastSeq.getCharAt(i)))
- {
- return Color.white;
- }
-
- currentColour = null;
-
- drawSequence(null, lastSeq, lastSeq.findPosition(i), -1, -1);
-
- if (currentColour == null)
- {
- return initialCol;
- }
-
- return new Color(((Integer) currentColour).intValue());
- }
-
- /**
- * This is used by the Molecule Viewer to get the accurate colour of the
- * rendered sequence
- */
- boolean overview = false;
-
- /**
- * DOCUMENT ME!
- *
- * @param g
- * DOCUMENT ME!
- * @param seq
- * DOCUMENT ME!
- * @param sg
- * DOCUMENT ME!
- * @param start
- * DOCUMENT ME!
- * @param end
- * DOCUMENT ME!
- * @param x1
- * DOCUMENT ME!
- * @param y1
- * DOCUMENT ME!
- * @param width
- * DOCUMENT ME!
- * @param height
- * DOCUMENT ME!
- */
- // String type;
- // SequenceFeature sf;
- SequenceI lastSeq;
-
- SequenceFeature[] sequenceFeatures;
-
- int sfSize, sfindex, spos, epos;
-
- synchronized public void drawSequence(Graphics g, SequenceI seq,
- int start, int end, int y1)
- {
- if (seq.getSequenceFeatures() == null
- || seq.getSequenceFeatures().length == 0)
- {
- return;
- }
-
- if (transparencySetter != null && g != null)
- {
- transparencySetter.setTransparency(g, transparency);
- }
-
- if (lastSeq == null || seq != lastSeq
- || sequenceFeatures != seq.getSequenceFeatures())
- {
- lastSeq = seq;
- sequenceFeatures = seq.getSequenceFeatures();
- sfSize = sequenceFeatures.length;
- }
-
- if (av.featuresDisplayed == null || renderOrder == null)
- {
- findAllFeatures();
- if (av.featuresDisplayed.size() < 1)
- {
- return;
- }
-
- sequenceFeatures = seq.getSequenceFeatures();
- sfSize = sequenceFeatures.length;
- }
- if (!overview)
- {
- spos = lastSeq.findPosition(start);
- epos = lastSeq.findPosition(end);
- if (g != null)
- {
- fm = g.getFontMetrics();
- }
- }
- String type;
- for (int renderIndex = 0; renderIndex < renderOrder.length; renderIndex++)
- {
- type = renderOrder[renderIndex];
- if (!av.featuresDisplayed.containsKey(type))
- {
- continue;
- }
-
- // loop through all features in sequence to find
- // current feature to render
- for (sfindex = 0; sfindex < sfSize; sfindex++)
- {
- if (!sequenceFeatures[sfindex].type.equals(type))
- {
- continue;
- }
-
- if (featureGroups != null
- && sequenceFeatures[sfindex].featureGroup != null
- && featureGroups
- .containsKey(sequenceFeatures[sfindex].featureGroup)
- && !((Boolean) featureGroups
- .get(sequenceFeatures[sfindex].featureGroup))
- .booleanValue())
- {
- continue;
- }
-
- if (!overview
- && (sequenceFeatures[sfindex].getBegin() > epos || sequenceFeatures[sfindex]
- .getEnd() < spos))
- {
- continue;
- }
-
- if (overview)
- {
- if (sequenceFeatures[sfindex].begin <= start
- && sequenceFeatures[sfindex].end >= start)
- {
- currentColour = new Integer(
- getColour(sequenceFeatures[sfindex]).getRGB());// av.featuresDisplayed
- // .get(sequenceFeatures[sfindex].type);
- }
-
- }
- else if (sequenceFeatures[sfindex].type.equals("disulfide bond"))
- {
-
- renderFeature(g, seq, seq
- .findIndex(sequenceFeatures[sfindex].begin) - 1, seq
- .findIndex(sequenceFeatures[sfindex].begin) - 1,
- getColour(sequenceFeatures[sfindex])
- // new Color(((Integer) av.featuresDisplayed
- // .get(sequenceFeatures[sfindex].type)).intValue())
- , start, end, y1);
- renderFeature(g, seq, seq
- .findIndex(sequenceFeatures[sfindex].end) - 1, seq
- .findIndex(sequenceFeatures[sfindex].end) - 1,
- getColour(sequenceFeatures[sfindex])
- // new Color(((Integer) av.featuresDisplayed
- // .get(sequenceFeatures[sfindex].type)).intValue())
- , start, end, y1);
-
- }
- else
- {
- if (showFeature(sequenceFeatures[sfindex]))
- {
- renderFeature(g, seq, seq
- .findIndex(sequenceFeatures[sfindex].begin) - 1, seq
- .findIndex(sequenceFeatures[sfindex].end) - 1,
- getColour(sequenceFeatures[sfindex]), start, end, y1);
- }
- }
-
- }
- }
-
- if (transparencySetter != null && g != null)
- {
- transparencySetter.setTransparency(g, 1.0f);
- }
- }
-
- char s;
-
- int i;
-
- void renderFeature(Graphics g, SequenceI seq, int fstart, int fend,
- Color featureColour, int start, int end, int y1)
- {
-
- if (((fstart <= end) && (fend >= start)))
- {
- if (fstart < start)
- { // fix for if the feature we have starts before the sequence start,
- fstart = start; // but the feature end is still valid!!
- }
-
- if (fend >= end)
- {
- fend = end;
- }
-
- for (i = fstart; i <= fend; i++)
- {
- s = seq.getCharAt(i);
-
- if (jalview.util.Comparison.isGap(s))
- {
- continue;
- }
-
- g.setColor(featureColour);
-
- g.fillRect((i - start) * av.charWidth, y1, av.charWidth,
- av.charHeight);
-
- if (!av.validCharWidth)
- {
- continue;
- }
-
- g.setColor(Color.white);
- charOffset = (av.charWidth - fm.charWidth(s)) / 2;
- g.drawString(String.valueOf(s), charOffset
- + (av.charWidth * (i - start)), (y1 + av.charHeight)
- - av.charHeight / 5); // pady = height / 5;
-
- }
- }
- }
-
- Hashtable minmax = null;
-
- 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)
- .getSequenceFeatures();
-
- if (features == null)
- {
- continue;
- }
-
- int index = 0;
- while (index < features.length)
- {
- if (features[index].begin == 0 && features[index].end == 0)
- {
- index++;
- continue;
- }
- if (!av.featuresDisplayed.containsKey(features[index].getType()))
- {
- if (getColour(features[index].getType()) == null)
- {
- featureColours.put(features[index].getType(), ucs
- .createColourFromName(features[index].getType()));
- }
-
- av.featuresDisplayed.put(features[index].getType(), new Integer(
- getColour(features[index].getType()).getRGB()));
- allfeatures.addElement(features[index].getType());
- }
- if (features[index].score != Float.NaN)
- {
- int nonpos = features[index].getBegin() >= 1 ? 0 : 1;
- float[][] mm = (float[][]) minmax.get(features[index].getType());
- if (mm == null)
- {
- mm = new float[][]
- { null, null };
- minmax.put(features[index].getType(), mm);
- }
- if (mm[nonpos] == null)
- {
- mm[nonpos] = new float[]
- { features[index].score, features[index].score };
-
- }
- else
- {
- if (mm[nonpos][0] > features[index].score)
- {
- mm[nonpos][0] = features[index].score;
- }
- if (mm[nonpos][1] < features[index].score)
- {
- mm[nonpos][1] = features[index].score;
- }
- }
- }
-
- index++;
- }
- }
-
- renderOrder = new String[allfeatures.size()];
- Enumeration en = allfeatures.elements();
- int i = allfeatures.size() - 1;
- while (en.hasMoreElements())
- {
- renderOrder[i] = en.nextElement().toString();
- i--;
- }
- }
-
- /**
- * get a feature style object for the given type string. Creates a
- * java.awt.Color for a featureType with no existing colourscheme. TODO:
- * replace return type with object implementing standard abstract colour/style
- * interface
- *
- * @param featureType
- * @return java.awt.Color or GraduatedColor
- */
- public Object getFeatureStyle(String featureType)
- {
- Object fc = featureColours.get(featureType);
- if (fc == null)
- {
- jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme();
- Color col = ucs.createColourFromName(featureType);
- featureColours.put(featureType, fc = col);
- }
- return fc;
- }
-
- public Color getColour(String featureType)
- {
- Object fc = getFeatureStyle(featureType);
-
- if (fc instanceof Color)
- {
- return (Color) fc;
- }
- else
- {
- if (fc instanceof GraduatedColor)
- {
- return ((GraduatedColor) fc).getMaxColor();
- }
- }
- throw new Error("Implementation Error: Unrecognised render object "
- + fc.getClass() + " for features of type " + featureType);
- }
-
- /**
- *
- * @param sequenceFeature
- * @return true if feature is visible.
- */
- private boolean showFeature(SequenceFeature sequenceFeature)
- {
- Object fc = getFeatureStyle(sequenceFeature.type);
- if (fc instanceof GraduatedColor)
- {
- return ((GraduatedColor) fc).isColored(sequenceFeature);
- }
- else
- {
- return true;
- }
- }
-
- /**
- * implement graduated colouring for features with scores
- *
- * @param feature
- * @return render colour for the given feature
- */
- public Color getColour(SequenceFeature feature)
- {
- Object fc = getFeatureStyle(feature.getType());
- if (fc instanceof Color)
- {
- return (Color) fc;
- }
- else
- {
- if (fc instanceof GraduatedColor)
- {
- return ((GraduatedColor) fc).findColor(feature);
- }
- }
- throw new Error("Implementation Error: Unrecognised render object "
- + fc.getClass() + " for features of type " + feature.getType());
- }
-
- public void setColour(String featureType, Object col)
- {
- // overwrite
- // Color _col = (col instanceof Color) ? ((Color) col) : (col instanceof
- // GraduatedColor) ? ((GraduatedColor) col).getMaxColor() : null;
- // Object c = featureColours.get(featureType);
- // if (c == null || c instanceof Color || (c instanceof GraduatedColor &&
- // !((GraduatedColor)c).getMaxColor().equals(_col)))
- {
- featureColours.put(featureType, col);
- }
- }
-
- public void setFeaturePriority(Object[][] data)
- {
- // The feature table will display high priority
- // features at the top, but theses are the ones
- // we need to render last, so invert the data
- if (av.featuresDisplayed != null)
- {
- av.featuresDisplayed.clear();
- }
-
- /*
- * if (visibleNew) { if (av.featuresDisplayed != null) {
- * av.featuresDisplayed.clear(); } else { av.featuresDisplayed = new
- * Hashtable(); } } if (data == null) { return; }
- */
-
- renderOrder = new String[data.length];
-
- if (data.length > 0)
- {
- for (int i = 0; i < data.length; i++)
- {
- String type = data[i][0].toString();
- setColour(type, data[i][1]);
- if (((Boolean) data[i][2]).booleanValue())
- {
- av.featuresDisplayed.put(type, new Integer(getColour(type)
- .getRGB()));
- }
-
- renderOrder[data.length - i - 1] = type;
- }
- }
- }
-
- /**
- * @return a simple list of feature group names or null
- */
- public String[] getGroups()
- {
- buildGroupHash();
- if (featureGroups != null)
- {
- String[] gps = new String[featureGroups.size()];
- Enumeration gn = featureGroups.keys();
- int i = 0;
- while (gn.hasMoreElements())
- {
- gps[i++] = (String) gn.nextElement();
- }
- return gps;
- }
- return null;
- }
-
- /**
- * get visible or invisible groups
- *
- * @param visible
- * true to return visible groups, false to return hidden ones.
- * @return list of groups
- */
- public String[] getGroups(boolean visible)
+ protected void warnIfGroupHidden(Frame frame, String group)
{
- buildGroupHash();
- if (featureGroups != null)
+ if (featureGroups.containsKey(group) && !featureGroups.get(group))
{
- Vector gp = new Vector();
-
- Enumeration gn = featureGroups.keys();
- while (gn.hasMoreElements())
- {
- String nm = (String) gn.nextElement();
- Boolean state = (Boolean) featureGroups.get(nm);
- if (state.booleanValue() == visible)
- {
- gp.addElement(nm);
- }
- }
- String[] gps = new String[gp.size()];
- gp.copyInto(gps);
-
- int i = 0;
- while (gn.hasMoreElements())
- {
- gps[i++] = (String) gn.nextElement();
- }
- return gps;
+ String msg = MessageManager.formatMessage("label.warning_hidden",
+ MessageManager.getString("label.group"), group);
+ showWarning(frame, msg);
}
- return null;
}
- /**
- * set all feature groups in toset to be visible or invisible
- *
- * @param toset
- * group names
- * @param visible
- * the state of the named groups to set
- */
- public void setGroupState(String[] toset, boolean visible)
+ protected void warnIfTypeHidden(Frame frame, String type)
{
- buildGroupHash();
- if (toset != null && toset.length > 0 && featureGroups != null)
+ if (getRenderOrder().contains(type))
{
- boolean rdrw = false;
- for (int i = 0; i < toset.length; i++)
+ if (!showFeatureOfType(type))
{
- Object st = featureGroups.get(toset[i]);
- if (st != null)
- {
- featureGroups.put(toset[i], new Boolean(visible));
- rdrw = rdrw || (visible != ((Boolean) st).booleanValue());
- }
- }
- if (rdrw)
- {
- if (this.av != null)
- if (this.av.featureSettings != null)
- {
- av.featureSettings.rebuildGroups();
- this.av.featureSettings.resetTable(true);
- }
- else
- {
- buildFeatureHash();
- }
- if (av != null)
- {
- av.alignmentChanged(null);
- }
+ String msg = MessageManager.formatMessage("label.warning_hidden",
+ MessageManager.getString("label.feature_type"), type);
+ showWarning(frame, msg);
}
}
}
/**
- * analyse alignment for groups and hash tables (used to be embedded in
- * FeatureSettings.setTableData)
- *
- * @return true if features are on the alignment
+ * @param frame
+ * @param msg
*/
- public boolean buildGroupHash()
- {
- boolean alignmentHasFeatures = false;
- if (featureGroups == null)
- {
- featureGroups = new Hashtable();
- }
- Vector allFeatures = new Vector();
- Vector allGroups = new Vector();
- SequenceFeature[] tmpfeatures;
- String group;
- for (int i = 0; i < av.alignment.getHeight(); i++)
- {
- if (av.alignment.getSequenceAt(i).getSequenceFeatures() == null)
- {
- continue;
- }
-
- alignmentHasFeatures = true;
-
- tmpfeatures = av.alignment.getSequenceAt(i).getSequenceFeatures();
- int index = 0;
- while (index < tmpfeatures.length)
- {
- if (tmpfeatures[index].getFeatureGroup() != null)
- {
- group = tmpfeatures[index].featureGroup;
- if (!allGroups.contains(group))
- {
- allGroups.addElement(group);
-
- boolean visible = true;
- if (featureGroups.containsKey(group))
- {
- visible = ((Boolean) featureGroups.get(group)).booleanValue();
- }
- else
- {
- featureGroups.put(group, new Boolean(visible));
- }
- }
- }
-
- if (!allFeatures.contains(tmpfeatures[index].getType()))
- {
- allFeatures.addElement(tmpfeatures[index].getType());
- }
- index++;
- }
- }
-
- return alignmentHasFeatures;
- }
-
- /**
- * rebuild the featuresDisplayed and renderorder list based on the
- * featureGroups hash and any existing display state and force a repaint if
- * necessary
- *
- * @return true if alignment has visible features
- */
- public boolean buildFeatureHash()
- {
- boolean alignmentHasFeatures = false;
- if (featureGroups == null)
- {
- alignmentHasFeatures = buildGroupHash();
- }
- if (!alignmentHasFeatures)
- return false;
- Hashtable fdisp = av.featuresDisplayed;
- Vector allFeatures = new Vector();
- SequenceFeature[] tmpfeatures;
- String group;
- for (int i = 0; i < av.alignment.getHeight(); i++)
- {
- if (av.alignment.getSequenceAt(i).getSequenceFeatures() == null)
- {
- continue;
- }
-
- alignmentHasFeatures = true;
-
- tmpfeatures = av.alignment.getSequenceAt(i).getSequenceFeatures();
- int index = 0;
- while (index < tmpfeatures.length)
- {
- boolean visible = true;
- if (tmpfeatures[index].getFeatureGroup() != null)
- {
- group = tmpfeatures[index].featureGroup;
- if (featureGroups.containsKey(group))
- {
- visible = ((Boolean) featureGroups.get(group)).booleanValue();
- }
- }
-
- if (visible && !allFeatures.contains(tmpfeatures[index].getType()))
- {
- allFeatures.addElement(tmpfeatures[index].getType());
- }
- index++;
- }
- }
- if (allFeatures.size() > 0)
- {
- String[] neworder = new String[allFeatures.size()];
- int p = neworder.length - 1;
- for (int i = renderOrder.length - 1; i >= 0; i--)
- {
- if (allFeatures.contains(renderOrder[i]))
- {
- neworder[p--] = renderOrder[i];
- allFeatures.removeElement(renderOrder[i]);
- }
- else
- {
- av.featuresDisplayed.remove(renderOrder[i]);
- }
- }
- for (int i = allFeatures.size() - 1; i > 0; i++)
- {
- Object e = allFeatures.elementAt(i);
- if (e != null)
- {
- neworder[p--] = (String) e;
- av.featuresDisplayed.put(e, getColour((String) e));
- }
- }
- renderOrder = neworder;
- return true;
- }
-
- return alignmentHasFeatures;
- }
-
- /**
- *
- * @return the displayed feature type as an array of strings
- */
- protected String[] getDisplayedFeatureTypes()
- {
- String[] typ = null;
- synchronized (renderOrder)
- {
- typ = new String[renderOrder.length];
- System.arraycopy(renderOrder, 0, typ, 0, typ.length);
- for (int i = 0; i < typ.length; i++)
- {
- if (av.featuresDisplayed.get(typ[i]) == null)
- {
- typ[i] = null;
- }
- }
- }
- return typ;
- }
-}
-
-class TransparencySetter
-{
- void setTransparency(Graphics g, float value)
+ protected void showWarning(Frame frame, String msg)
{
- Graphics2D g2 = (Graphics2D) g;
- g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
- value));
+ JVDialog d = new JVDialog(frame, "", true, 350, 200);
+ Panel mp = new Panel();
+ d.ok.setLabel(MessageManager.getString("action.ok"));
+ d.cancel.setVisible(false);
+ mp.setLayout(new FlowLayout());
+ mp.add(new Label(msg));
+ d.setMainPanel(mp);
+ d.setVisible(true);
}
}