From 07108e505ff923f3b5135ffbdbb79259fe53432e Mon Sep 17 00:00:00 2001 From: gmungoc Date: Thu, 23 Nov 2017 12:52:45 +0000 Subject: [PATCH] JAL-2808 update spike to latest (filter range, Present option) --- resources/lang/Messages.properties | 2 + resources/lang/Messages_es.properties | 2 + src/jalview/appletgui/FeatureSettings.java | 35 +++------ src/jalview/gui/FeatureSettings.java | 45 ++++++++--- src/jalview/gui/FeatureTypeSettings.java | 82 ++++++++++++++++++-- src/jalview/io/vcf/VCFLoader.java | 7 +- src/jalview/util/matcher/Condition.java | 1 + src/jalview/util/matcher/KeyedMatcher.java | 16 ++-- src/jalview/util/matcher/Matcher.java | 12 ++- .../seqfeatures/FeatureRendererModel.java | 46 +++++++---- .../seqfeatures/FeatureColourFinderTest.java | 33 ++++---- .../renderer/seqfeatures/FeatureRendererTest.java | 26 ++++--- test/jalview/util/matcher/ConditionTest.java | 2 + test/jalview/util/matcher/KeyedMatcherTest.java | 8 ++ test/jalview/util/matcher/MatcherTest.java | 16 ++++ 15 files changed, 238 insertions(+), 95 deletions(-) diff --git a/resources/lang/Messages.properties b/resources/lang/Messages.properties index a592282..00888d5 100644 --- a/resources/lang/Messages.properties +++ b/resources/lang/Messages.properties @@ -1327,6 +1327,8 @@ label.matchCondition_contains = Contains label.matchCondition_notcontains = Does not contain label.matchCondition_matches = Matches label.matchCondition_notmatches = Does not match +label.matchCondition_present = Is present +label.matchCondition_notpresent = Is not present label.matchCondition_eq = = label.matchCondition_ne = not = label.matchCondition_lt = < diff --git a/resources/lang/Messages_es.properties b/resources/lang/Messages_es.properties index 31c3a86..616cb9d 100644 --- a/resources/lang/Messages_es.properties +++ b/resources/lang/Messages_es.properties @@ -1328,6 +1328,8 @@ label.matchCondition_contains = Contiene label.matchCondition_notcontains = No contiene label.matchCondition_matches = Es igual a label.matchCondition_notmatches = No es igual a +label.matchCondition_present = Está presente +label.matchCondition_notpresent = No está presente label.matchCondition_eq = = label.matchCondition_ne = not = label.matchCondition_lt = < diff --git a/src/jalview/appletgui/FeatureSettings.java b/src/jalview/appletgui/FeatureSettings.java index 39a2747..ad04171 100755 --- a/src/jalview/appletgui/FeatureSettings.java +++ b/src/jalview/appletgui/FeatureSettings.java @@ -20,15 +20,12 @@ */ package jalview.appletgui; -import static jalview.viewmodel.seqfeatures.FeatureRendererModel.COLOUR_COLUMN; -import static jalview.viewmodel.seqfeatures.FeatureRendererModel.SHOW_COLUMN; -import static jalview.viewmodel.seqfeatures.FeatureRendererModel.TYPE_COLUMN; - import jalview.api.FeatureColourI; import jalview.api.FeatureSettingsControllerI; import jalview.datamodel.AlignmentI; import jalview.datamodel.SequenceI; import jalview.util.MessageManager; +import jalview.viewmodel.seqfeatures.FeatureRendererModel.FeatureSettingsBean; import java.awt.BorderLayout; import java.awt.Button; @@ -587,27 +584,19 @@ public class FeatureSettings extends Panel { Component[] comps = featurePanel.getComponents(); int cSize = comps.length; - - /* - * temporary! leave column[2] empty - used for Filter in - * gui.FeatureSettings - */ - int columnCount = 4; - Object[][] tmp = new Object[cSize][columnCount]; - int tmpSize = 0; - for (int i = 0; i < cSize; i++) - { - MyCheckbox check = (MyCheckbox) comps[i]; - tmp[tmpSize][TYPE_COLUMN /* 0 */] = check.type; - tmp[tmpSize][COLOUR_COLUMN /* 1 */] = fr.getFeatureStyle(check.type); - tmp[tmpSize][SHOW_COLUMN /* 3 */] = new Boolean(check.getState()); - tmpSize++; + FeatureSettingsBean[] rowData = new FeatureSettingsBean[cSize]; + int i = 0; + for (Component comp : comps) + { + MyCheckbox check = (MyCheckbox) comp; + // feature filter set to null as not (yet) offered in applet + FeatureColourI colour = fr.getFeatureStyle(check.type); + rowData[i] = new FeatureSettingsBean(check.type, colour, null, + check.getState()); + i++; } - Object[][] data = new Object[tmpSize][columnCount]; - System.arraycopy(tmp, 0, data, 0, tmpSize); - - fr.setFeaturePriority(data); + fr.setFeaturePriority(rowData); ap.paintAlignment(updateOverview, updateOverview); } diff --git a/src/jalview/gui/FeatureSettings.java b/src/jalview/gui/FeatureSettings.java index fedfe3f..2b3688f 100644 --- a/src/jalview/gui/FeatureSettings.java +++ b/src/jalview/gui/FeatureSettings.java @@ -20,10 +20,10 @@ */ package jalview.gui; -import static jalview.viewmodel.seqfeatures.FeatureRendererModel.COLOUR_COLUMN; -import static jalview.viewmodel.seqfeatures.FeatureRendererModel.FILTER_COLUMN; -import static jalview.viewmodel.seqfeatures.FeatureRendererModel.SHOW_COLUMN; -import static jalview.viewmodel.seqfeatures.FeatureRendererModel.TYPE_COLUMN; +import static jalview.gui.FeatureSettings.FeatureTableModel.COLOUR_COLUMN; +import static jalview.gui.FeatureSettings.FeatureTableModel.FILTER_COLUMN; +import static jalview.gui.FeatureSettings.FeatureTableModel.SHOW_COLUMN; +import static jalview.gui.FeatureSettings.FeatureTableModel.TYPE_COLUMN; import jalview.api.FeatureColourI; import jalview.api.FeatureSettingsControllerI; @@ -42,6 +42,7 @@ import jalview.util.QuickSort; import jalview.util.matcher.KeyedMatcherSet; import jalview.util.matcher.KeyedMatcherSetI; import jalview.viewmodel.AlignmentViewport; +import jalview.viewmodel.seqfeatures.FeatureRendererModel.FeatureSettingsBean; import jalview.ws.DasSequenceFeatureFetcher; import jalview.ws.dbsources.das.api.jalviewSourceI; @@ -111,14 +112,10 @@ public class FeatureSettings extends JPanel { private static final int COLUMN_COUNT = 4; - private static final String COLON = ":"; - private static final int MIN_WIDTH = 400; private static final int MIN_HEIGHT = 400; - private static final int MAX_TOOLTIP_LENGTH = 50; - DasSourceBrowser dassourceBrowser; DasSequenceFeatureFetcher dasFeatureFetcher; @@ -1105,12 +1102,32 @@ public class FeatureSettings extends JPanel */ private void updateFeatureRenderer(Object[][] data, boolean visibleNew) { - if (fr.setFeaturePriority(data, visibleNew)) + FeatureSettingsBean[] rowData = getTableAsBeans(data); + + if (fr.setFeaturePriority(rowData, visibleNew)) { af.alignPanel.paintAlignment(true, true); } } + /** + * Converts table data into an array of data beans + */ + private FeatureSettingsBean[] getTableAsBeans(Object[][] data) + { + FeatureSettingsBean[] rowData = new FeatureSettingsBean[data.length]; + for (int i = 0; i < data.length; i++) + { + String type = (String) data[i][TYPE_COLUMN]; + FeatureColourI colour = (FeatureColourI) data[i][COLOUR_COLUMN]; + KeyedMatcherSetI theFilter = (KeyedMatcherSetI) data[i][FILTER_COLUMN]; + Boolean isShown = (Boolean) data[i][SHOW_COLUMN]; + rowData[i] = new FeatureSettingsBean(type, colour, theFilter, + isShown); + } + return rowData; + } + private void jbInit() throws Exception { this.setLayout(new BorderLayout()); @@ -1492,6 +1509,16 @@ public class FeatureSettings extends JPanel // /////////////////////////////////////////////////////////////////////// class FeatureTableModel extends AbstractTableModel { + /* + * column indices of fields in Feature Settings table + */ + static final int TYPE_COLUMN = 0; + + static final int COLOUR_COLUMN = 1; + + static final int FILTER_COLUMN = 2; + + static final int SHOW_COLUMN = 3; private String[] columnNames = { MessageManager.getString("label.feature_type"), diff --git a/src/jalview/gui/FeatureTypeSettings.java b/src/jalview/gui/FeatureTypeSettings.java index e280091..1dd12aa 100644 --- a/src/jalview/gui/FeatureTypeSettings.java +++ b/src/jalview/gui/FeatureTypeSettings.java @@ -47,6 +47,7 @@ import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; @@ -94,6 +95,9 @@ public class FeatureTypeSettings extends JalviewDialog private static final int BELOW_THRESHOLD_OPTION = 2; + private static final DecimalFormat DECFMT_2_2 = new DecimalFormat( + "##.##"); + /* * FeatureRenderer holds colour scheme and filters for feature types */ @@ -1238,7 +1242,7 @@ public class FeatureTypeSettings extends JalviewDialog * and an empty filter for the user to populate (add) */ KeyedMatcherI noFilter = new KeyedMatcher(Condition.values()[0], "", - (String) null); + (String[]) null); filters.add(noFilter); /* @@ -1330,7 +1334,20 @@ public class FeatureTypeSettings extends JalviewDialog { attCombo.setSelectedItem(toAttributeDisplayName(attName)); } - attCombo.addItemListener(itemListener); + attCombo.addItemListener(new ItemListener() + { + @Override + public void itemStateChanged(ItemEvent e) + { + /* + * on change of attribute, refresh the conditions list to + * ensure it is appropriate for the attribute datatype + */ + populateConditions((String) attCombo.getSelectedItem(), + (Condition) condCombo.getSelectedItem(), condCombo); + actionListener.actionPerformed(null); + } + }); filterRow.add(attCombo); @@ -1339,6 +1356,7 @@ public class FeatureTypeSettings extends JalviewDialog */ populateConditions((String) attCombo.getSelectedItem(), cond, condCombo); + condCombo.setPreferredSize(new Dimension(150, 20)); condCombo.addItemListener(itemListener); filterRow.add(condCombo); @@ -1358,6 +1376,32 @@ public class FeatureTypeSettings extends JalviewDialog filterRow.add(patternField); /* + * disable pattern field for condition 'Present / NotPresent' + */ + Condition selectedCondition = (Condition) condCombo.getSelectedItem(); + if (selectedCondition == Condition.Present + || selectedCondition == Condition.NotPresent) + { + patternField.setEnabled(false); + } + + /* + * if a numeric condition is selected, show the value range + * as a tooltip on the value input field + */ + if (selectedCondition.isNumeric()) + { + float[] minMax = FeatureAttributes.getInstance() + .getMinMax(featureType, attName); + if (minMax != null) + { + String tip = String.format("(%s - %s)", + DECFMT_2_2.format(minMax[0]), DECFMT_2_2.format(minMax[1])); + patternField.setToolTipText(tip); + } + } + + /* * add remove button if filter is populated (non-empty pattern) */ if (pattern != null && pattern.trim().length() > 0) @@ -1395,7 +1439,7 @@ public class FeatureTypeSettings extends JalviewDialog JComboBox condCombo) { Datatype type = FeatureAttributes.getInstance().getDatatype(featureType, - attName); + fromAttributeDisplayName(attName)); if (MessageManager.getString("label.label").equals(attName)) { type = Datatype.Character; @@ -1405,30 +1449,47 @@ public class FeatureTypeSettings extends JalviewDialog type = Datatype.Number; } + /* + * remove itemListener before starting + */ + ItemListener listener = condCombo.getItemListeners()[0]; + condCombo.removeItemListener(listener); + boolean condIsValid = false; + condCombo.removeAllItems(); for (Condition c : Condition.values()) { if ((c.isNumeric() && type != Datatype.Character) || (!c.isNumeric() && type != Datatype.Number)) { condCombo.addItem(c); + if (c == cond) + { + condIsValid = true; + } } } /* * set the selected condition (does nothing if not in the list) */ - if (cond != null) + if (condIsValid) { condCombo.setSelectedItem(cond); } + else + { + condCombo.setSelectedIndex(0); + } + + condCombo.addItemListener(listener); } /** * Answers true unless a numeric condition has been selected with a non-numeric * value. Sets the value field to RED with a tooltip if in error. *

- * If the pattern entered is empty, this method returns false, but does not mark - * the field as invalid. This supports selecting an attribute for a new + * If the pattern is expected but is empty, this method returns false, but does + * not mark the field as invalid. This supports selecting an attribute for a new * condition before a match pattern has been entered. * * @param value @@ -1443,6 +1504,11 @@ public class FeatureTypeSettings extends JalviewDialog } Condition cond = (Condition) condCombo.getSelectedItem(); + if (cond == Condition.Present || cond == Condition.NotPresent) + { + return true; + } + value.setBackground(Color.white); value.setToolTipText(""); String v1 = value.getText().trim(); @@ -1523,7 +1589,9 @@ public class FeatureTypeSettings extends JalviewDialog for (KeyedMatcherI filter : filters) { String pattern = filter.getMatcher().getPattern(); - if (pattern.trim().length() > 0) + Condition condition = filter.getMatcher().getCondition(); + if (pattern.trim().length() > 0 || condition == Condition.Present + || condition == Condition.NotPresent) { if (anded) { diff --git a/src/jalview/io/vcf/VCFLoader.java b/src/jalview/io/vcf/VCFLoader.java index 2847bd7..155e773 100644 --- a/src/jalview/io/vcf/VCFLoader.java +++ b/src/jalview/io/vcf/VCFLoader.java @@ -27,6 +27,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.SortedMap; +import java.util.TreeMap; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; @@ -55,7 +57,7 @@ public class VCFLoader private static final String VCF_FIELDS_PREF = "VCF_FIELDS"; - private static final String DEFAULT_VCF_FIELDS = "AF,AC*"; + private static final String DEFAULT_VCF_FIELDS = ".*"; private static final String DEFAULT_VEP_FIELDS = ".*";// "Allele,Consequence,IMPACT,SWISSPROT,SIFT,PolyPhen,CLIN_SIG"; @@ -915,7 +917,8 @@ public class VCFLoader * inspect CSQ consequences; where possible restrict to the consequence * associated with the current transcript (Feature) */ - Map csqValues = new HashMap<>(); + SortedMap csqValues = new TreeMap<>( + String.CASE_INSENSITIVE_ORDER); for (String consequence : consequences) { diff --git a/src/jalview/util/matcher/Condition.java b/src/jalview/util/matcher/Condition.java index 455f805..4d14063 100644 --- a/src/jalview/util/matcher/Condition.java +++ b/src/jalview/util/matcher/Condition.java @@ -12,6 +12,7 @@ import java.util.Map; public enum Condition { Contains(false), NotContains(false), Matches(false), NotMatches(false), + Present(false), NotPresent(false), EQ(true), NE(true), LT(true), LE(true), GT(true), GE(true); private static Map displayNames = new HashMap<>(); diff --git a/src/jalview/util/matcher/KeyedMatcher.java b/src/jalview/util/matcher/KeyedMatcher.java index ef1c702..f21756a 100644 --- a/src/jalview/util/matcher/KeyedMatcher.java +++ b/src/jalview/util/matcher/KeyedMatcher.java @@ -73,22 +73,24 @@ public class KeyedMatcher implements KeyedMatcherI } /** - * Answers a string description of this matcher, suitable for debugging or - * logging. The format may change in future. + * Answers a string description of this matcher, suitable for display, debugging + * or logging. The format may change in future. */ @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(String.join(COLON, key)).append(" ") - .append(matcher.getCondition().toString()).append(" "); - if (matcher.getCondition().isNumeric()) + .append(matcher.getCondition().toString()); + Condition condition = matcher.getCondition(); + if (condition.isNumeric()) { - sb.append(matcher.getPattern()); + sb.append(" ").append(matcher.getPattern()); } - else + else if (condition != Condition.Present + && condition != Condition.NotPresent) { - sb.append("'").append(matcher.getPattern()).append("'"); + sb.append(" '").append(matcher.getPattern()).append("'"); } return sb.toString(); diff --git a/src/jalview/util/matcher/Matcher.java b/src/jalview/util/matcher/Matcher.java index 715694c..14a8585 100644 --- a/src/jalview/util/matcher/Matcher.java +++ b/src/jalview/util/matcher/Matcher.java @@ -53,7 +53,7 @@ public class Matcher implements MatcherI else { // pattern matches will be non-case-sensitive - pattern = compareTo.toUpperCase(); + pattern = compareTo == null ? null : compareTo.toUpperCase(); } // if we add regex conditions (e.g. matchesPattern), then @@ -105,7 +105,8 @@ public class Matcher implements MatcherI if (val == null) { return condition == Condition.NotContains - || condition == Condition.NotMatches; + || condition == Condition.NotMatches + || condition == Condition.NotPresent; } String upper = val.toUpperCase().trim(); @@ -123,6 +124,11 @@ public class Matcher implements MatcherI case NotContains: matched = upper.indexOf(pattern) == -1; break; + case Present: + matched = true; + break; + default: + break; } return matched; } @@ -161,6 +167,8 @@ public class Matcher implements MatcherI case GE: matched = f >= value; break; + default: + break; } return matched; diff --git a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java index 4797675..8bdcad4 100644 --- a/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java +++ b/src/jalview/viewmodel/seqfeatures/FeatureRendererModel.java @@ -50,16 +50,27 @@ public abstract class FeatureRendererModel implements jalview.api.FeatureRenderer { /* - * column indices of fields in Feature Settings table - * todo: transfer valuers as data beans instead of Object[][] + * a data bean to hold one row of feature settings from the gui */ - public static final int TYPE_COLUMN = 0; + public static class FeatureSettingsBean + { + public final String featureType; + + public final FeatureColourI featureColour; - public static final int COLOUR_COLUMN = 1; + public final KeyedMatcherSetI filter; - public static final int FILTER_COLUMN = 2; + public final Boolean show; - public static final int SHOW_COLUMN = 3; + public FeatureSettingsBean(String type, FeatureColourI colour, + KeyedMatcherSetI theFilter, Boolean isShown) + { + featureType = type; + featureColour = colour; + filter = theFilter; + show = isShown; + } + } /* * global transparency for feature @@ -673,26 +684,27 @@ public abstract class FeatureRendererModel * Replace current ordering with new ordering * * @param data - * { String(Type), Colour(Type), Boolean(Displayed) } + * an array of { Type, Colour, Filter, Boolean } * @return true if any visible features have been reordered, else false */ - public boolean setFeaturePriority(Object[][] data) + public boolean setFeaturePriority(FeatureSettingsBean[] data) { return setFeaturePriority(data, true); } /** - * Sets the priority order for features, with the highest priority (displayed - * on top) at the start of the data array + * Sets the priority order for features, with the highest priority (displayed on + * top) at the start of the data array * * @param data - * { String(Type), Colour(Type), Boolean(Displayed) } + * an array of { Type, Colour, Filter, Boolean } * @param visibleNew * when true current featureDisplay list will be cleared - * @return true if any visible features have been reordered or recoloured, - * else false (i.e. no need to repaint) + * @return true if any visible features have been reordered or recoloured, else + * false (i.e. no need to repaint) */ - public boolean setFeaturePriority(Object[][] data, boolean visibleNew) + public boolean setFeaturePriority(FeatureSettingsBean[] data, + boolean visibleNew) { /* * note visible feature ordering and colours before update @@ -731,9 +743,9 @@ public abstract class FeatureRendererModel { for (int i = 0; i < data.length; i++) { - String type = data[i][TYPE_COLUMN].toString(); - setColour(type, (FeatureColourI) data[i][COLOUR_COLUMN]); - if (((Boolean) data[i][SHOW_COLUMN]).booleanValue()) + String type = data[i].featureType; + setColour(type, data[i].featureColour); + if (data[i].show) { av_featuresdisplayed.setVisible(type); } diff --git a/test/jalview/renderer/seqfeatures/FeatureColourFinderTest.java b/test/jalview/renderer/seqfeatures/FeatureColourFinderTest.java index f6dfed6..d8b905e 100644 --- a/test/jalview/renderer/seqfeatures/FeatureColourFinderTest.java +++ b/test/jalview/renderer/seqfeatures/FeatureColourFinderTest.java @@ -15,6 +15,7 @@ import jalview.gui.FeatureRenderer; import jalview.io.DataSourceType; import jalview.io.FileLoader; import jalview.schemes.FeatureColour; +import jalview.viewmodel.seqfeatures.FeatureRendererModel.FeatureSettingsBean; import java.awt.Color; import java.util.List; @@ -172,9 +173,9 @@ public class FeatureColourFinderTest * - currently no way other than mimicking reordering of * table in Feature Settings */ - Object[][] data = new Object[2][]; - data[0] = new Object[] { "Metal", red, true }; - data[1] = new Object[] { "Domain", green, true }; + FeatureSettingsBean[] data = new FeatureSettingsBean[2]; + data[0] = new FeatureSettingsBean("Metal", red, null, true); + data[1] = new FeatureSettingsBean("Domain", green, null, true); fr.setFeaturePriority(data); c = finder.findFeatureColour(Color.blue, seq, 10); assertEquals(c, Color.red); @@ -182,7 +183,7 @@ public class FeatureColourFinderTest /* * ..and turn off display of Metal */ - data[0][2] = false; + data[0] = new FeatureSettingsBean("Metal", red, null, false); fr.setFeaturePriority(data); c = finder.findFeatureColour(Color.blue, seq, 10); assertEquals(c, Color.green); @@ -216,8 +217,8 @@ public class FeatureColourFinderTest /* * turn off display of Metal - is this the easiest way to do it?? */ - Object[][] data = new Object[1][]; - data[0] = new Object[] { "Metal", red, false }; + FeatureSettingsBean[] data = new FeatureSettingsBean[1]; + data[0] = new FeatureSettingsBean("Metal", red, null, false); fr.setFeaturePriority(data); c = finder.findFeatureColour(Color.blue, seq, 10); assertEquals(c, Color.blue); @@ -225,7 +226,7 @@ public class FeatureColourFinderTest /* * turn display of Metal back on */ - data[0] = new Object[] { "Metal", red, true }; + data[0] = new FeatureSettingsBean("Metal", red, null, true); fr.setFeaturePriority(data); c = finder.findFeatureColour(Color.blue, seq, 10); assertEquals(c, Color.red); @@ -399,9 +400,9 @@ public class FeatureColourFinderTest * 1) 0.6 * green(0, 255, 0) + 0.4 * cyan(0, 255, 255) = (0, 255, 102) * 2) 0.6* red(255, 0, 0) + 0.4 * (0, 255, 102) = (153, 102, 41) rounded */ - Object[][] data = new Object[2][]; - data[0] = new Object[] { "Metal", red, true }; - data[1] = new Object[] { "Domain", green, true }; + FeatureSettingsBean[] data = new FeatureSettingsBean[2]; + data[0] = new FeatureSettingsBean("Metal", red, null, true); + data[1] = new FeatureSettingsBean("Domain", green, null, true); fr.setFeaturePriority(data); c = finder.findFeatureColour(Color.cyan, seq, 10); assertEquals(c, new Color(153, 102, 41)); @@ -411,7 +412,7 @@ public class FeatureColourFinderTest * Domain (green) above background (pink) * 0.6 * green(0, 255, 0) + 0.4 * pink(255, 175, 175) = (102, 223, 70) */ - data[0][2] = false; + data[0] = new FeatureSettingsBean("Metal", red, null, false); fr.setFeaturePriority(data); c = finder.findFeatureColour(Color.pink, seq, 10); assertEquals(c, new Color(102, 223, 70)); @@ -447,8 +448,8 @@ public class FeatureColourFinderTest /* * turn off display of Metal */ - Object[][] data = new Object[1][]; - data[0] = new Object[] { "Metal", red, false }; + FeatureSettingsBean[] data = new FeatureSettingsBean[1]; + data[0] = new FeatureSettingsBean("Metal", red, null, false); fr.setFeaturePriority(data); assertTrue(finder.noFeaturesDisplayed()); @@ -503,9 +504,9 @@ public class FeatureColourFinderTest /* * render order is kd above Metal */ - Object[][] data = new Object[2][]; - data[0] = new Object[] { kdFeature, fc, true }; - data[1] = new Object[] { metalFeature, green, true }; + FeatureSettingsBean[] data = new FeatureSettingsBean[2]; + data[0] = new FeatureSettingsBean(kdFeature, fc, null, true); + data[1] = new FeatureSettingsBean(metalFeature, green, null, true); fr.setFeaturePriority(data); av.setShowSequenceFeatures(true); diff --git a/test/jalview/renderer/seqfeatures/FeatureRendererTest.java b/test/jalview/renderer/seqfeatures/FeatureRendererTest.java index 745eec3..73ae9d7 100644 --- a/test/jalview/renderer/seqfeatures/FeatureRendererTest.java +++ b/test/jalview/renderer/seqfeatures/FeatureRendererTest.java @@ -17,6 +17,7 @@ import jalview.util.matcher.Condition; import jalview.util.matcher.KeyedMatcher; import jalview.util.matcher.KeyedMatcherSet; import jalview.util.matcher.KeyedMatcherSetI; +import jalview.viewmodel.seqfeatures.FeatureRendererModel.FeatureSettingsBean; import java.awt.Color; import java.util.ArrayList; @@ -122,11 +123,11 @@ public class FeatureRendererTest * change render order (todo: an easier way) * nb here last comes first in the data array */ - Object[][] data = new Object[3][]; + FeatureSettingsBean[] data = new FeatureSettingsBean[3]; FeatureColourI colour = new FeatureColour(Color.RED); - data[0] = new Object[] { "Rfam", colour, true }; - data[1] = new Object[] { "Pfam", colour, false }; - data[2] = new Object[] { "Scop", colour, false }; + data[0] = new FeatureSettingsBean("Rfam", colour, null, true); + data[1] = new FeatureSettingsBean("Pfam", colour, null, false); + data[2] = new FeatureSettingsBean("Scop", colour, null, false); fr.setFeaturePriority(data); assertEquals(fr.getRenderOrder(), Arrays.asList("Scop", "Pfam", "Rfam")); assertEquals(fr.getDisplayedFeatureTypes(), Arrays.asList("Rfam")); @@ -223,12 +224,13 @@ public class FeatureRendererTest /* * make "Type2" not displayed */ - Object[][] data = new Object[4][]; FeatureColourI colour = new FeatureColour(Color.RED); - data[0] = new Object[] { "Type1", colour, true }; - data[1] = new Object[] { "Type2", colour, false }; - data[2] = new Object[] { "Type3", colour, true }; - data[3] = new Object[] { "Disulphide Bond", colour, true }; + FeatureSettingsBean[] data = new FeatureSettingsBean[4]; + data[0] = new FeatureSettingsBean("Type1", colour, null, true); + data[1] = new FeatureSettingsBean("Type2", colour, null, false); + data[2] = new FeatureSettingsBean("Type3", colour, null, true); + data[3] = new FeatureSettingsBean("Disulphide Bond", colour, null, + true); fr.setFeaturePriority(data); features = fr.findFeaturesAtColumn(seq, 15); @@ -377,11 +379,11 @@ public class FeatureRendererTest /* * hide feature type, then unhide */ - Object[][] data = new Object[1][]; - data[0] = new Object[] { "Cath", fc, false }; + FeatureSettingsBean[] data = new FeatureSettingsBean[1]; + data[0] = new FeatureSettingsBean("Cath", fc, null, false); fr.setFeaturePriority(data); assertNull(fr.getColour(sf1)); - data[0] = new Object[] { "Cath", fc, true }; + data[0] = new FeatureSettingsBean("Cath", fc, null, true); fr.setFeaturePriority(data); assertEquals(fr.getColour(sf1), Color.red); diff --git a/test/jalview/util/matcher/ConditionTest.java b/test/jalview/util/matcher/ConditionTest.java index 9d8b225..883596a 100644 --- a/test/jalview/util/matcher/ConditionTest.java +++ b/test/jalview/util/matcher/ConditionTest.java @@ -16,6 +16,8 @@ public class ConditionTest assertEquals(Condition.NotContains.toString(), "Does not contain"); assertEquals(Condition.Matches.toString(), "Matches"); assertEquals(Condition.NotMatches.toString(), "Does not match"); + assertEquals(Condition.Present.toString(), "Is present"); + assertEquals(Condition.NotPresent.toString(), "Is not present"); assertEquals(Condition.LT.toString(), "<"); assertEquals(Condition.LE.toString(), "<="); assertEquals(Condition.GT.toString(), ">"); diff --git a/test/jalview/util/matcher/KeyedMatcherTest.java b/test/jalview/util/matcher/KeyedMatcherTest.java index 01d0067..3fd7800 100644 --- a/test/jalview/util/matcher/KeyedMatcherTest.java +++ b/test/jalview/util/matcher/KeyedMatcherTest.java @@ -39,6 +39,14 @@ public class KeyedMatcherTest */ KeyedMatcherI km = new KeyedMatcher(Condition.LT, 1.2f, "AF"); assertEquals(km.toString(), "AF < 1.2"); + + /* + * Present / NotPresent omit the value pattern + */ + km = new KeyedMatcher(Condition.Present, "", "AF"); + assertEquals(km.toString(), "AF Is present"); + km = new KeyedMatcher(Condition.NotPresent, "", "AF"); + assertEquals(km.toString(), "AF Is not present"); } @Test diff --git a/test/jalview/util/matcher/MatcherTest.java b/test/jalview/util/matcher/MatcherTest.java index ee0ff82..f4c8181 100644 --- a/test/jalview/util/matcher/MatcherTest.java +++ b/test/jalview/util/matcher/MatcherTest.java @@ -167,6 +167,22 @@ public class MatcherTest assertTrue(m.matches(null)); /* + * value is present (is not null) + */ + m = new Matcher(Condition.Present, null); + assertTrue(m.matches("benign")); + assertTrue(m.matches("")); + assertFalse(m.matches(null)); + + /* + * value is not present (is null) + */ + m = new Matcher(Condition.NotPresent, null); + assertFalse(m.matches("benign")); + assertFalse(m.matches("")); + assertTrue(m.matches(null)); + + /* * a float with a string match condition will be treated as string */ Matcher m1 = new Matcher(Condition.Contains, "32"); -- 1.7.10.2