From 262352d44a49e6102a9e80b0c006ea9331ed0c67 Mon Sep 17 00:00:00 2001 From: jprocter Date: Fri, 16 Apr 2010 14:32:29 +0000 Subject: [PATCH] graduated feature color editing --- src/jalview/appletgui/FeatureColourChooser.java | 159 ++++++------ src/jalview/appletgui/FeatureRenderer.java | 309 ++++++++++++++++------- src/jalview/appletgui/FeatureSettings.java | 181 +++++++++---- src/jalview/appletgui/UserDefinedColours.java | 41 ++- 4 files changed, 469 insertions(+), 221 deletions(-) diff --git a/src/jalview/appletgui/FeatureColourChooser.java b/src/jalview/appletgui/FeatureColourChooser.java index f4ad1d5..e3ab8eb 100644 --- a/src/jalview/appletgui/FeatureColourChooser.java +++ b/src/jalview/appletgui/FeatureColourChooser.java @@ -30,11 +30,11 @@ import java.awt.Rectangle; public class FeatureColourChooser extends Panel implements ActionListener, AdjustmentListener, ItemListener, MouseListener { - Frame frame; + JVDialog frame; FeatureRenderer fr; - FeatureSettings fs; - AlignmentPanel ap; + FeatureSettings fs = null; + // AlignmentPanel ap; GraduatedColor cs; Object oldcs; @@ -45,13 +45,22 @@ public class FeatureColourChooser extends Panel implements boolean adjusting = false; private float min,max; String type=null; - + + private AlignFrame af=null; + public FeatureColourChooser(AlignFrame af, String type) + { + this.af = af; + init(af.getSeqcanvas().getFeatureRenderer(), type); + } public FeatureColourChooser(FeatureSettings fsettings, String type) { this.fs = fsettings; + init(fsettings.fr, type); + // this.ap = fsettings.ap; + } + private void init(FeatureRenderer frenderer,String type) { this.type = type; - fr = fsettings.fr; - ap = fsettings.ap; + fr = frenderer; float mm[] = ((float[][]) fr.minmax.get(type))[0]; min = mm[0]; max = mm[1]; @@ -71,6 +80,7 @@ public class FeatureColourChooser extends Panel implements } minColour.setBackground(cs.getMinColor()); maxColour.setBackground(cs.getMaxColor()); + colourFromLabel.setState(cs.isColourByLabel()); adjusting = true; try @@ -79,16 +89,26 @@ public class FeatureColourChooser extends Panel implements } catch (Exception ex) { } - // To HERE! + threshold.select(cs.getThreshType()==AnnotationColourGradient.NO_THRESHOLD ? 0 : cs.getThreshType() == AnnotationColourGradient.ABOVE_THRESHOLD ? 1 : 2); + adjusting = false; changeColour(); + colourFromLabel.addItemListener(this); slider.addAdjustmentListener(this); slider.addMouseListener(this); - frame = new Frame(); - frame.add(this); - jalview.bin.JalviewLite.addFrame(frame, "Graduated Feature Colour for "+type, 480, - 145); + Frame owner = (af!=null) ? af : fs.frame; + frame = new JVDialog(owner,"Graduated Feature Colour for "+type,true,480,248); + frame.setMainPanel(this); validate(); + frame.setVisible(true); + if (frame.accept) { + changeColour(); + } else { + // cancel + reset(); + PaintRefresher.Refresh(this, fr.av.getSequenceSetId()); + frame.setVisible(false); + } } public FeatureColourChooser() @@ -113,79 +133,72 @@ public class FeatureColourChooser extends Panel implements maxColour.addActionListener(this); thresholdIsMin.addItemListener(this); - ok.setLabel("OK"); - ok.addActionListener(this); - - cancel.setLabel("Cancel"); - cancel.addActionListener(this); - - this.setLayout(borderLayout1); - jPanel2.setLayout(flowLayout1); + this.setLayout(new GridLayout(4,1)); + jPanel1.setLayout(new FlowLayout()); + jPanel2.setLayout(new FlowLayout()); + jPanel3.setLayout(new GridLayout(1,1)); + jPanel4.setLayout(new FlowLayout()); jPanel1.setBackground(Color.white); jPanel2.setBackground(Color.white); + jPanel4.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)); + slider.setSize(new Dimension(93, 21)); thresholdValue.setEnabled(false); - thresholdValue.setBounds(new Rectangle(248, 2, 79, 22)); + thresholdValue.setSize(new Dimension(79,22)); //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)); + + colourFromLabel.setFont(new java.awt.Font("Verdana", Font.PLAIN, 11)); + colourFromLabel.setLabel("Colour by Label"); + colourFromLabel.setSize(new Dimension(139,22)); + //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); + thresholdIsMin.setSize(new Dimension(135,23)); + //thresholdIsMin.setBounds(new Rectangle(328, 3, 135, 23)); + jPanel1.add(minColour); + jPanel1.add(maxColour); + jPanel1.add(colourFromLabel); + jPanel2.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); + jPanel4.add(thresholdValue); + jPanel4.add(thresholdIsMin); + this.add(jPanel1);//, java.awt.BorderLayout.NORTH); + this.add(jPanel2);//, java.awt.BorderLayout.NORTH); + this.add(jPanel3);//, java.awt.BorderLayout.CENTER); + this.add(jPanel4);//, java.awt.BorderLayout.CENTER); } 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(); + Panel jPanel4 = new Panel(); Scrollbar slider = new Scrollbar(Scrollbar.HORIZONTAL); TextField thresholdValue = new TextField(20); - BorderLayout borderLayout1 = new BorderLayout(); +// BorderLayout borderLayout1 = new BorderLayout(); Checkbox thresholdIsMin = new Checkbox(); + Checkbox colourFromLabel = new Checkbox(); private GraphLine threshline; @@ -210,19 +223,6 @@ public class FeatureColourChooser extends Panel implements { 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(); @@ -231,7 +231,8 @@ public class FeatureColourChooser extends Panel implements public void itemStateChanged(ItemEvent evt) { - + maxColour.setEnabled(!colourFromLabel.getState()); + minColour.setEnabled(!colourFromLabel.getState()); changeColour(); } @@ -244,37 +245,35 @@ public class FeatureColourChooser extends Panel implements } } protected void valueChanged() { - changeColour(); threshline.value = (float) slider.getValue() / 1000f; - ap.paintAlignment(false); + cs.setThresh(threshline.value); + changeColour(); + PaintRefresher.Refresh(this, fr.av.getSequenceSetId()); + // ap.paintAlignment(false); } public void minColour_actionPerformed(Color newCol) { - if (newCol != null) + if (newCol == null) { + UserDefinedColours udc = new UserDefinedColours(this,minColour.getBackground(), frame, "Select Colour for Minimum Value"); + } else { 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) + if (newCol == null) { + UserDefinedColours udc = new UserDefinedColours(this,maxColour.getBackground(), frame, "Select Colour for Maximum Value");// this, "Select Colour for Maximum Value", maxColour.getBackground()); + } else { maxColour.setBackground(newCol); maxColour.repaint(); changeColour(); } - else - { - new UserDefinedColours(this, "Select Colour for Maximum Value", maxColour.getBackground()); - } } void changeColour() @@ -299,6 +298,9 @@ public class FeatureColourChooser extends Panel implements thresholdValue.setEnabled(true); GraduatedColor acg = new GraduatedColor(minColour.getBackground(), maxColour.getBackground(), min, max); + acg.setColourByLabel(colourFromLabel.getState()); + maxColour.setEnabled(!colourFromLabel.getState()); + minColour.setEnabled(!colourFromLabel.getState()); if (aboveThreshold == AnnotationColourGradient.NO_THRESHOLD) { slider.setEnabled(false); @@ -345,13 +347,15 @@ public class FeatureColourChooser extends Panel implements fr.featureColours.put(type,acg); cs = acg; - ap.paintAlignment(false); + PaintRefresher.Refresh(this, fr.av.getSequenceSetId()); + // ap.paintAlignment(false); } void reset() { fr.featureColours.put(type, oldcs); - ap.paintAlignment(true); + PaintRefresher.Refresh(this, fr.av.getSequenceSetId()); + // ap.paintAlignment(true); } @@ -365,7 +369,8 @@ public class FeatureColourChooser extends Panel implements public void mouseReleased(MouseEvent evt) { - ap.paintAlignment(true); + PaintRefresher.Refresh(this, fr.av.getSequenceSetId()); + // ap.paintAlignment(true); } public void mouseEntered(MouseEvent evt) diff --git a/src/jalview/appletgui/FeatureRenderer.java b/src/jalview/appletgui/FeatureRenderer.java index 08b0970..c2c2462 100755 --- a/src/jalview/appletgui/FeatureRenderer.java +++ b/src/jalview/appletgui/FeatureRenderer.java @@ -26,6 +26,7 @@ import java.awt.event.*; import jalview.appletgui.FeatureSettings.MyCheckbox; import jalview.datamodel.*; +import jalview.schemes.AnnotationColourGradient; import jalview.schemes.GraduatedColor; /** @@ -66,7 +67,7 @@ public class FeatureRenderer * Creates a new FeatureRenderer object. * * @param av - * DOCUMENT ME! + * DOCUMENT ME! */ public FeatureRenderer(AlignViewport av) { @@ -96,7 +97,86 @@ public class FeatureRenderer boolean deleteFeature = false; - Panel colourPanel; + FeatureColourPanel colourPanel; + class FeatureColourPanel extends Panel { + String label=""; + + private Color maxCol; + private boolean isColourByLabel,isGcol; + /** + * render a feature style in the amend feature dialog box + */ + public void updateColor(Object newcol) + { + + Color bg,col=null; + GraduatedColor gcol=null; + String vlabel = ""; + if (newcol instanceof Color) + { + isGcol=false; + col = (Color) newcol; + gcol = null; + } + else if (newcol instanceof GraduatedColor) + { + isGcol=true; + gcol = (GraduatedColor) newcol; + col = null; + } + else + { + throw new Error("Invalid color for MyCheckBox"); + } + if (col != null) + { + setBackground(bg=col); + } + else + { + if (gcol.getThreshType()!=AnnotationColourGradient.NO_THRESHOLD) + { + vlabel += " "+((gcol.getThreshType()==AnnotationColourGradient.ABOVE_THRESHOLD) ? "(>)" : "(<)"); + } + if (isColourByLabel=gcol.isColourByLabel()) { + setBackground(bg=Color.white); + vlabel += " (by Label)"; + } else { + setBackground(bg=gcol.getMinColor()); + maxCol = gcol.getMaxColor(); + } + } + label=vlabel; + setBackground(bg); + repaint(); + } + FeatureColourPanel() { + super(null); + } + public void paint(Graphics g) + { + int width=getWidth(),height=getHeight(); + if (isGcol) { + if (isColourByLabel) + { + g.setColor(Color.white); + g.fillRect(width/2, 0,width/2, height); + g.setColor(Color.black); + Font f=new Font("Verdana", Font.PLAIN, + 10); + g.setFont(f); + g.drawString("Label", 0, 0); + } + else + { + g.setColor(maxCol); + g.fillRect(width/2, 0,width/2, height); + + } + } + } + + } boolean amendFeatures(final SequenceI[] sequences, final SequenceFeature[] features, boolean newFeatures, @@ -112,12 +192,13 @@ public class FeatureRenderer Button deleteButton = new Button("Delete"); deleteFeature = false; - colourPanel = new Panel(null); + colourPanel = new FeatureColourPanel(); colourPanel.setSize(110, 15); final FeatureRenderer fr = this; Panel panel = new Panel(new GridLayout(3, 1)); - + + featureIndex = 0; // feature to be amended. Panel tmp; // ///////////////////////////////////// @@ -169,7 +250,7 @@ public class FeatureRenderer .createColourFromName(name.getText()); } - colourPanel.setBackground(col); + colourPanel.updateColor(col); } }); @@ -271,26 +352,40 @@ public class FeatureRenderer start.setText(features[0].getBegin() + ""); end.setText(features[0].getEnd() + ""); description.setText(features[0].getDescription()); - Color col = getColour(name.getText()); if (col == null) { col = new jalview.schemes.UserColourScheme() .createColourFromName(name.getText()); } - - colourPanel.setBackground(col); - + Object fcol = getFeatureStyle(name.getText()); + // simply display the feature color in a box + colourPanel.updateColor(fcol); dialog.setResizable(true); - - colourPanel.addMouseListener(new java.awt.event.MouseAdapter() + // TODO: render the graduated color in the box. + if (fcol instanceof Color) { - public void mousePressed(java.awt.event.MouseEvent evt) + colourPanel.addMouseListener(new java.awt.event.MouseAdapter() { - new UserDefinedColours(fr, ap.alignFrame); - } - }); + public void mousePressed(java.awt.event.MouseEvent evt) + { + new UserDefinedColours(fr, ap.alignFrame); + } + }); + } + else + { + colourPanel.addMouseListener(new java.awt.event.MouseAdapter() + { + public void mousePressed(java.awt.event.MouseEvent evt) + { + FeatureColourChooser fcc = new FeatureColourChooser(ap.alignFrame, name.getText()); + fcc.setFocusable(true); + dialog.transferFocus(); + } + }); + } dialog.setVisible(true); jalview.io.FeaturesFile ffile = new jalview.io.FeaturesFile(); @@ -310,14 +405,17 @@ public class FeatureRenderer if (!newFeatures) { - SequenceFeature sf = features[featureIndex]; + SequenceFeature sf = features[featureIndex]; if (dialog.accept) { sf.type = lastFeatureAdded; sf.featureGroup = lastFeatureGroupAdded; sf.description = lastDescriptionAdded; - setColour(sf.type, colourPanel.getBackground()); + if (fcol instanceof Color) { + // update colour - otherwise its already done. + setColour(sf.type, colourPanel.getBackground()); + } try { sf.begin = Integer.parseInt(start.getText()); @@ -358,14 +456,18 @@ public class FeatureRenderer } col = colourPanel.getBackground(); - setColour(lastFeatureAdded, col); + //setColour(lastFeatureAdded, fcol); if (lastFeatureGroupAdded != null) { featureGroups.put(lastFeatureGroupAdded, new Boolean(true)); - av.featuresDisplayed.put(lastFeatureGroupAdded, new Integer(col - .getRGB())); } + if (fcol instanceof Color) { + setColour(lastFeatureAdded, fcol); + } + av.featuresDisplayed.put(lastFeatureAdded, + getFeatureStyle(lastFeatureAdded)); + findAllFeatures(); String[] tro = new String[renderOrder.length]; @@ -383,7 +485,7 @@ public class FeatureRenderer } } - findAllFeatures(); + // findAllFeatures(); ap.paintAlignment(true); @@ -434,23 +536,23 @@ public class FeatureRenderer * DOCUMENT ME! * * @param g - * DOCUMENT ME! + * DOCUMENT ME! * @param seq - * DOCUMENT ME! + * DOCUMENT ME! * @param sg - * DOCUMENT ME! + * DOCUMENT ME! * @param start - * DOCUMENT ME! + * DOCUMENT ME! * @param end - * DOCUMENT ME! + * DOCUMENT ME! * @param x1 - * DOCUMENT ME! + * DOCUMENT ME! * @param y1 - * DOCUMENT ME! + * DOCUMENT ME! * @param width - * DOCUMENT ME! + * DOCUMENT ME! * @param height - * DOCUMENT ME! + * DOCUMENT ME! */ // String type; // SequenceFeature sf; @@ -543,38 +645,39 @@ public class FeatureRenderer if (sequenceFeatures[sfindex].begin <= start && sequenceFeatures[sfindex].end >= start) { - currentColour = new Integer(getColour(sequenceFeatures[sfindex]).getRGB());//av.featuresDisplayed - //.get(sequenceFeatures[sfindex].type); + currentColour = new Integer( + getColour(sequenceFeatures[sfindex]).getRGB());// av.featuresDisplayed + // .get(sequenceFeatures[sfindex].type); } } else if (sequenceFeatures[sfindex].type.equals("disulfide bond")) { - renderFeature( - g, - seq, - seq.findIndex(sequenceFeatures[sfindex].begin) - 1, - seq.findIndex(sequenceFeatures[sfindex].begin) - 1, - new Color(((Integer) av.featuresDisplayed - .get(sequenceFeatures[sfindex].type)).intValue()), - start, end, y1); - renderFeature( - g, - seq, - seq.findIndex(sequenceFeatures[sfindex].end) - 1, - seq.findIndex(sequenceFeatures[sfindex].end) - 1, - new Color(((Integer) av.featuresDisplayed - .get(sequenceFeatures[sfindex].type)).intValue()), - start, end, y1); + renderFeature(g, seq, seq + .findIndex(sequenceFeatures[sfindex].begin) - 1, seq + .findIndex(sequenceFeatures[sfindex].begin) - 1, + getColour(sequenceFeatures[sfindex]) + // new Color(((Integer) av.featuresDisplayed + // .get(sequenceFeatures[sfindex].type)).intValue()) + , start, end, y1); + renderFeature(g, seq, seq + .findIndex(sequenceFeatures[sfindex].end) - 1, seq + .findIndex(sequenceFeatures[sfindex].end) - 1, + getColour(sequenceFeatures[sfindex]) + // new Color(((Integer) av.featuresDisplayed + // .get(sequenceFeatures[sfindex].type)).intValue()) + , start, end, y1); } else { - renderFeature(g, seq, seq + if (showFeature(sequenceFeatures[sfindex])) + { renderFeature(g, seq, seq .findIndex(sequenceFeatures[sfindex].begin) - 1, seq .findIndex(sequenceFeatures[sfindex].end) - 1, getColour(sequenceFeatures[sfindex]), start, end, y1); + } } } @@ -634,7 +737,9 @@ public class FeatureRenderer } } } - Hashtable minmax=null; + + Hashtable minmax = null; + void findAllFeatures() { jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(); @@ -642,7 +747,7 @@ public class FeatureRenderer 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) @@ -656,7 +761,8 @@ public class FeatureRenderer int index = 0; while (index < features.length) { - if (features[index].begin==0 && features[index].end==0) { + if (features[index].begin == 0 && features[index].end == 0) + { index++; continue; } @@ -672,19 +778,21 @@ public class FeatureRenderer getColour(features[index].getType()).getRGB())); allfeatures.addElement(features[index].getType()); } - if (features[index].score != Float.NaN) + if (features[index].score != Float.NaN) { - int nonpos= features[index].getBegin()>=1 ? 0 : 1; + int nonpos = features[index].getBegin() >= 1 ? 0 : 1; float[][] mm = (float[][]) minmax.get(features[index].getType()); if (mm == null) { - mm = new float[][] {null, 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 }; - + if (mm[nonpos] == null) + { + mm[nonpos] = new float[] + { features[index].score, features[index].score }; + } else { @@ -698,7 +806,7 @@ public class FeatureRenderer } } } - + index++; } } @@ -713,17 +821,32 @@ public class FeatureRenderer } } - public Color getColour(String featureType) + /** + * get a feature style object for the given type string. Creates a + * java.awt.Color for a featureType with no existing colourscheme. TODO: + * replace return type with object implementing standard abstract colour/style + * interface + * + * @param featureType + * @return java.awt.Color or GraduatedColor + */ + public Object getFeatureStyle(String featureType) { Object fc = featureColours.get(featureType); if (fc == null) { jalview.schemes.UserColourScheme ucs = new jalview.schemes.UserColourScheme(); Color col = ucs.createColourFromName(featureType); - featureColours.put(featureType, col); - return col; + featureColours.put(featureType, fc = col); } - else if (fc instanceof Color) + return fc; + } + + public Color getColour(String featureType) + { + Object fc = getFeatureStyle(featureType); + + if (fc instanceof Color) { return (Color) fc; } @@ -733,10 +856,24 @@ public class FeatureRenderer { return ((GraduatedColor) fc).getMaxColor(); } - // TODO: raise an implementation error here. - return null; // Color.white; } + 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 * @@ -745,15 +882,8 @@ public class FeatureRenderer */ 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) + Object fc = getFeatureStyle(feature.getType()); + if (fc instanceof Color) { return (Color) fc; } @@ -763,14 +893,22 @@ public class FeatureRenderer { return ((GraduatedColor) fc).findColor(feature); } - // TODO: raise an implementation error here. - return null; // Color.white; } + throw new Error("Implementation Error: Unrecognised render object " + + fc.getClass() + " for features of type " + feature.getType()); } - public void setColour(String featureType, Color col) + public void setColour(String featureType, Object col) { - featureColours.put(featureType, col); + // overwrite + // Color _col = (col instanceof Color) ? ((Color) col) : (col instanceof + // GraduatedColor) ? ((GraduatedColor) col).getMaxColor() : null; + // Object c = featureColours.get(featureType); + // if (c == null || c instanceof Color || (c instanceof GraduatedColor && + // !((GraduatedColor)c).getMaxColor().equals(_col))) + { + featureColours.put(featureType, col); + } } public void setFeaturePriority(Object[][] data) @@ -796,7 +934,7 @@ public class FeatureRenderer for (int i = 0; i < data.length; i++) { String type = data[i][0].toString(); - setColour(type, (Color) data[i][1]); + setColour(type, data[i][1]); if (((Boolean) data[i][2]).booleanValue()) { av.featuresDisplayed.put(type, new Integer(getColour(type) @@ -832,7 +970,7 @@ public class FeatureRenderer * get visible or invisible groups * * @param visible - * true to return visible groups, false to return hidden ones. + * true to return visible groups, false to return hidden ones. * @return list of groups */ public String[] getGroups(boolean visible) @@ -869,9 +1007,9 @@ public class FeatureRenderer * set all feature groups in toset to be visible or invisible * * @param toset - * group names + * group names * @param visible - * the state of the named groups to set + * the state of the named groups to set */ public void setGroupState(String[] toset, boolean visible) { @@ -1049,6 +1187,7 @@ public class FeatureRenderer return alignmentHasFeatures; } + /** * * @return the displayed feature type as an array of strings @@ -1065,9 +1204,9 @@ public class FeatureRenderer if (av.featuresDisplayed.get(typ[i]) == null) { typ[i] = null; - } - } + } } + } return typ; } } diff --git a/src/jalview/appletgui/FeatureSettings.java b/src/jalview/appletgui/FeatureSettings.java index 2eb203c..80559bd 100755 --- a/src/jalview/appletgui/FeatureSettings.java +++ b/src/jalview/appletgui/FeatureSettings.java @@ -26,6 +26,8 @@ import java.awt.event.*; import jalview.analysis.AlignmentSorter; import jalview.commands.OrderCommand; import jalview.datamodel.*; +import jalview.schemes.AnnotationColourGradient; +import jalview.schemes.GraduatedColor; public class FeatureSettings extends Panel implements ItemListener, MouseListener, MouseMotionListener, ActionListener, @@ -154,9 +156,11 @@ 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, + + protected void popupSort(final MyCheckbox check, final Hashtable minmax, int x, int y) { + final String type = check.type; java.awt.PopupMenu men = new PopupMenu("Settings for " + type); java.awt.MenuItem scr = new MenuItem("Sort by Score"); men.add(scr); @@ -186,31 +190,23 @@ public class FeatureSettings extends Panel implements ItemListener, 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); + /* + * 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"); + // graduated colourschemes for those where minmax exists for the + // positional features + MenuItem mxcol = new MenuItem("Graduated Colour"); men.add(mxcol); mxcol.addActionListener(new ActionListener() { @@ -218,6 +214,8 @@ public class FeatureSettings extends Panel implements ItemListener, public void actionPerformed(ActionEvent e) { new FeatureColourChooser(me, type); + // write back the current colour object to update the table + check.updateColor(fr.getFeatureStyle(type)); } }); @@ -309,14 +307,14 @@ public class FeatureSettings extends Panel implements ItemListener, Component[] comps; int cSize = featurePanel.getComponentCount(); - Checkbox check; + MyCheckbox check; // This will remove any checkboxes which shouldn't be // visible for (int i = 0; i < cSize; i++) { comps = featurePanel.getComponents(); - check = (Checkbox) comps[i]; - if (!visibleChecks.contains(check.getLabel())) + check = (MyCheckbox) comps[i]; + if (!visibleChecks.contains(check.type)) { featurePanel.remove(i); cSize--; @@ -368,21 +366,21 @@ public class FeatureSettings extends Panel implements ItemListener, * update the checklist of feature types with the given type * * @param groupsChanged - * true means if the type is not in the display list then it - * will be added and displayed + * true means if the type is not in the display list then it will be + * added and displayed * @param type - * feature type to be checked for in the list. + * feature type to be checked for in the list. */ void addCheck(boolean groupsChanged, String type) { boolean addCheck; Component[] comps = featurePanel.getComponents(); - Checkbox check; + MyCheckbox check; addCheck = true; for (int i = 0; i < featurePanel.getComponentCount(); i++) { - check = (Checkbox) comps[i]; - if (check.getLabel().equals(type)) + check = (MyCheckbox) comps[i]; + if (check.type.equals(type)) { addCheck = false; break; @@ -400,11 +398,11 @@ public class FeatureSettings extends Panel implements ItemListener, check = new MyCheckbox( type, selected, - (fr.featureLinks != null && fr.featureLinks.containsKey(type))); + (fr.featureLinks != null && fr.featureLinks.containsKey(type)), + fr.getFeatureStyle(type)); check.addMouseListener(this); check.addMouseMotionListener(this); - check.setBackground(fr.getColour(type)); check.addItemListener(this); if (groupsChanged) { @@ -461,9 +459,9 @@ public class FeatureSettings extends Panel implements ItemListener, int tmpSize = 0; for (int i = 0; i < cSize; i++) { - Checkbox check = (Checkbox) comps[i]; - tmp[tmpSize][0] = check.getLabel(); - tmp[tmpSize][1] = fr.getColour(check.getLabel()); + MyCheckbox check = (MyCheckbox) comps[i]; + tmp[tmpSize][0] = check.type; + tmp[tmpSize][1] = fr.getFeatureStyle(check.type); tmp[tmpSize][2] = new Boolean(check.getState()); tmpSize++; } @@ -486,7 +484,7 @@ public class FeatureSettings extends Panel implements ItemListener, selectedCheck = (MyCheckbox) evt.getSource(); if (fr.featureLinks != null - && fr.featureLinks.containsKey(selectedCheck.getLabel())) + && fr.featureLinks.containsKey(selectedCheck.type)) { if (evt.getX() > selectedCheck.stringWidth + 20) { @@ -576,17 +574,17 @@ public class FeatureSettings extends Panel implements ItemListener, public void mouseClicked(MouseEvent evt) { MyCheckbox check = (MyCheckbox) evt.getSource(); - if ((evt.getModifiers() & InputEvent.BUTTON3_MASK)!=0) + if ((evt.getModifiers() & InputEvent.BUTTON3_MASK) != 0) { - this.popupSort(check.getLabel(), fr.minmax, evt.getX(), evt.getY()); + this.popupSort(check, fr.minmax, evt.getX(), evt.getY()); } if (fr.featureLinks != null - && fr.featureLinks.containsKey(check.getLabel())) + && fr.featureLinks.containsKey(check.type)) { if (evt.getX() > check.stringWidth + 20) { evt.consume(); - String link = fr.featureLinks.get(check.getLabel()).toString(); + String link = fr.featureLinks.get(check.type).toString(); ap.alignFrame.showURL(link.substring(link.indexOf("|") + 1), link .substring(0, link.indexOf("|"))); } @@ -599,8 +597,15 @@ public class FeatureSettings extends Panel implements ItemListener, if (evt.getClickCount() > 1) { - new UserDefinedColours(this, check.getLabel(), fr.getColour(check - .getLabel())); + Object fcol = fr.getFeatureStyle(check.type); + if (fcol instanceof Color) + { + new UserDefinedColours(this, check.type, (Color) fcol); + } else { + new FeatureColourChooser(this, check.type); + // write back the current colour object to update the table + check.updateColor(fr.getFeatureStyle(check.type)); + } } } @@ -617,21 +622,98 @@ public class FeatureSettings extends Panel implements ItemListener, class MyCheckbox extends Checkbox { + public String type; public int stringWidth; boolean hasLink; + GraduatedColor gcol; + + Color col; + + public void updateColor(Object newcol) + { + if (newcol instanceof Color) + { + col = (Color) newcol; + gcol = null; + } + else if (newcol instanceof GraduatedColor) + { + gcol = (GraduatedColor) newcol; + col = null; + } + else + { + throw new Error("Invalid color for MyCheckBox"); + } + if (col != null) + { + setBackground(col); + } + else + { + String vlabel = type; + if (gcol.getThreshType()!=AnnotationColourGradient.NO_THRESHOLD) + { + vlabel += " "+((gcol.getThreshType()==AnnotationColourGradient.ABOVE_THRESHOLD) ? "(>)" : "(<)"); + } + if (gcol.isColourByLabel()) { + setBackground(Color.white); + vlabel += " (by Label)"; + } else { + setBackground(gcol.getMinColor()); + } + this.setLabel(vlabel); + } + repaint(); + } + public MyCheckbox(String label, boolean checked, boolean haslink) { super(label, checked); - + type = label; FontMetrics fm = av.nullFrame.getFontMetrics(av.nullFrame.getFont()); stringWidth = fm.stringWidth(label); this.hasLink = haslink; } + public MyCheckbox(String type, boolean selected, boolean b, + Object featureStyle) + { + this(type,selected,b); + updateColor(featureStyle); + } + public void paint(Graphics g) { + int width = getWidth(), height = getHeight(); + if (gcol != null) + { + if (gcol.isColourByLabel()) + { + g.setColor(Color.white); + g.fillRect(width/2, 0,width/2, 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(width/2, 0,width/2, height); + + } + } + if (hasLink) { g.drawImage(linkImage, stringWidth + 25, @@ -639,10 +721,12 @@ public class FeatureSettings extends Panel implements ItemListener, } } } + protected void sortByDens(String[] typ) { sortBy(typ, "Sort by Density", AlignmentSorter.FEATURE_DENSITY); } + private String[] getDisplayedFeatureTypes() { String[] typ = null; @@ -664,7 +748,6 @@ public class FeatureSettings extends Panel implements ItemListener, return typ; } - protected void sortBy(String[] typ, String methodText, final String method) { if (typ == null) @@ -705,8 +788,8 @@ public class FeatureSettings extends Panel implements ItemListener, } SequenceI[] oldOrder = al.getSequencesArray(); AlignmentSorter.sortByFeature(typ, gps, start, stop, al, method); - this.ap.alignFrame.addHistoryItem(new OrderCommand(methodText, oldOrder, alignPanel.av - .getAlignment())); + this.ap.alignFrame.addHistoryItem(new OrderCommand(methodText, + oldOrder, alignPanel.av.getAlignment())); alignPanel.paintAlignment(true); } diff --git a/src/jalview/appletgui/UserDefinedColours.java b/src/jalview/appletgui/UserDefinedColours.java index 825cfd3..5da1fbf 100755 --- a/src/jalview/appletgui/UserDefinedColours.java +++ b/src/jalview/appletgui/UserDefinedColours.java @@ -100,13 +100,16 @@ public class UserDefinedColours extends Panel implements ActionListener, setTargetColour(fr.colourPanel.getBackground()); dialog.setVisible(true); } - public UserDefinedColours(Component caller, Color col1, Frame alignframe) { + this(caller, col1, alignframe, "Select Colour"); + } + public UserDefinedColours(Component caller, Color col1, Container alignframe, String title) + { this.caller = caller; originalColour = col1; - originalLabel = "Select Colour"; - setForDialog("Select Colour", alignframe); + originalLabel = title; + setForDialog(title, alignframe); setTargetColour(col1); dialog.setVisible(true); } @@ -126,12 +129,21 @@ public class UserDefinedColours extends Panel implements ActionListener, frame.setSize(420, 200); } - void setForDialog(String title, Frame alignframe) + void setForDialog(String title, Container alignframe) { init(); frame.setVisible(false); remove(buttonPanel); - dialog = new Dialog(alignframe, title, true); + if (alignframe instanceof Frame) + { + dialog = new Dialog((Frame)alignframe, title, true); + } + else + if (alignframe instanceof JVDialog){ + dialog = new Dialog(((JVDialog)alignframe), title, true); + } else { + throw new Error("Unsupported owner for User Colour scheme dialog."); + } dialog.add(this); this.setSize(400, 123); @@ -320,14 +332,15 @@ public class UserDefinedColours extends Panel implements ActionListener, { final Button button = new Button(); Color col = Color.white; - + if (oldColourScheme!=null) + { try { col = oldColourScheme.findColour(aa.charAt(0), -1); } catch (Exception ex) { } - + } button.setBackground(col); oldColours.addElement(col); button.setLabel(label); @@ -381,7 +394,7 @@ public class UserDefinedColours extends Panel implements ActionListener, } else if (caller instanceof FeatureRenderer) { - ((FeatureRenderer) caller).colourPanel.setBackground(getColor()); + ((FeatureRenderer) caller).colourPanel.updateColor(getColor()); } else if (caller instanceof FeatureColourChooser) { @@ -456,11 +469,19 @@ public class UserDefinedColours extends Panel implements ActionListener, } else if (caller instanceof FeatureRenderer) { - ((FeatureRenderer) caller).colourPanel - .setBackground(originalColour); + ((FeatureRenderer) caller).colourPanel.updateColor(originalColour); } + else if (caller instanceof FeatureColourChooser) + { + if (originalLabel.indexOf("inimum")>-1) + { + ((FeatureColourChooser) caller).minColour_actionPerformed(originalColour); + } else { + ((FeatureColourChooser) caller).maxColour_actionPerformed(originalColour); + } + } if (dialog != null) dialog.setVisible(false); -- 1.7.10.2