From: gmungoc Date: Mon, 17 Jun 2019 12:17:20 +0000 (+0100) Subject: JAL-3187 add sequence to feature details table (and refactor PopupMenu) X-Git-Tag: Release_2_11_1_0~44 X-Git-Url: http://source.jalview.org/gitweb/?a=commitdiff_plain;h=4eb8d7a0f14e5dd1dc5ad5ad0960bae9b25fa043;p=jalview.git JAL-3187 add sequence to feature details table (and refactor PopupMenu) --- diff --git a/src/jalview/datamodel/SequenceFeature.java b/src/jalview/datamodel/SequenceFeature.java index 7052f34..e7e1342 100755 --- a/src/jalview/datamodel/SequenceFeature.java +++ b/src/jalview/datamodel/SequenceFeature.java @@ -345,6 +345,11 @@ public class SequenceFeature implements FeatureLocationI return featureGroup; } + /** + * Adds a hyperlink for the feature. This should have the format label|url. + * + * @param labelLink + */ public void addLink(String labelLink) { if (links == null) @@ -602,9 +607,11 @@ public class SequenceFeature implements FeatureLocationI /** * Answers an html-formatted report of feature details * + * @param sequence + * * @return */ - public String getDetailsReport() + public String getDetailsReport(SequenceI sequence) { FeatureSourceI metadata = FeatureSources.getInstance() .getSource(source); @@ -612,9 +619,10 @@ public class SequenceFeature implements FeatureLocationI StringBuilder sb = new StringBuilder(128); sb.append("
"); sb.append(""); + sb.append(String.format(ROW_DATA, "Location", sequence.getName(), + begin == end ? begin + : begin + (isContactFeature() ? ":" : "-") + end)); sb.append(String.format(ROW_DATA, "Type", type, "")); - sb.append(String.format(ROW_DATA, "Start/end", begin == end ? begin - : begin + (isContactFeature() ? ":" : "-") + end, "")); String desc = StringUtils.stripHtmlTags(description); sb.append(String.format(ROW_DATA, "Description", desc, "")); if (!Float.isNaN(score) && score != 0f) diff --git a/src/jalview/gui/PopupMenu.java b/src/jalview/gui/PopupMenu.java index 702773b..06e35cd 100644 --- a/src/jalview/gui/PopupMenu.java +++ b/src/jalview/gui/PopupMenu.java @@ -30,7 +30,6 @@ import jalview.commands.EditCommand; import jalview.commands.EditCommand.Action; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; -import jalview.datamodel.Annotation; import jalview.datamodel.DBRefEntry; import jalview.datamodel.HiddenColumns; import jalview.datamodel.PDBEntry; @@ -83,6 +82,19 @@ import javax.swing.JRadioButtonMenuItem; */ public class PopupMenu extends JPopupMenu implements ColourChangeListener { + /* + * true for ID Panel menu, false for alignment panel menu + */ + private final boolean forIdPanel; + + private final AlignmentPanel ap; + + /* + * the sequence under the cursor when clicked + * (additional sequences may be selected) + */ + private final SequenceI sequence; + JMenu groupMenu = new JMenu(); JMenuItem groupName = new JMenuItem(); @@ -97,28 +109,14 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener protected JMenuItem modifyConservation = new JMenuItem(); - AlignmentPanel ap; - JMenu sequenceMenu = new JMenu(); - JMenuItem sequenceName = new JMenuItem(); - - JMenuItem sequenceDetails = new JMenuItem(); - - JMenuItem sequenceSelDetails = new JMenuItem(); - JMenuItem makeReferenceSeq = new JMenuItem(); - JMenuItem chooseAnnotations = new JMenuItem(); - - SequenceI sequence; - JMenuItem createGroupMenuItem = new JMenuItem(); JMenuItem unGroupMenuItem = new JMenuItem(); - JMenuItem outline = new JMenuItem(); - JMenu colourMenu = new JMenu(); JCheckBoxMenuItem showBoxes = new JCheckBoxMenuItem(); @@ -131,18 +129,12 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener JMenu editMenu = new JMenu(); - JMenuItem cut = new JMenuItem(); - - JMenuItem copy = new JMenuItem(); - JMenuItem upperCase = new JMenuItem(); JMenuItem lowerCase = new JMenuItem(); JMenuItem toggle = new JMenuItem(); - JMenu pdbMenu = new JMenu(); - JMenu outputMenu = new JMenu(); JMenu seqShowAnnotationsMenu = new JMenu(); @@ -159,22 +151,14 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener JMenuItem groupAddReferenceAnnotations = new JMenuItem( MessageManager.getString("label.add_reference_annotations")); - JMenuItem sequenceFeature = new JMenuItem(); - JMenuItem textColour = new JMenuItem(); - JMenu jMenu1 = new JMenu(); + JMenu editGroupMenu = new JMenu(); - JMenuItem pdbStructureDialog = new JMenuItem(); + JMenuItem chooseStructure = new JMenuItem(); JMenu rnaStructureMenu = new JMenu(); - JMenuItem editSequence = new JMenuItem(); - - JMenu groupLinksMenu; - - JMenuItem hideInsertions = new JMenuItem(); - /** * Constructs a menu with sub-menu items for any hyperlinks for the sequence * and/or features provided. Hyperlinks may include a lookup by sequence id, @@ -185,7 +169,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener * @param features * @return */ - static JMenu buildLinkMenu(final SequenceI seq, + protected static JMenu buildLinkMenu(final SequenceI seq, List features) { JMenu linkMenu = new JMenu(MessageManager.getString("action.link")); @@ -357,41 +341,50 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener } /** - * Creates a new PopupMenu object. + * Constructor for a PopupMenu for a click in the alignment panel (on a residue) * * @param ap * @param seq * @param features - * non-positional features (for seq not null), or positional features - * at residue (for seq equal to null) + * sequence features overlapping the clicked residue */ public PopupMenu(final AlignmentPanel ap, SequenceI seq, List features) { - this(ap, seq, features, null); + this(false, ap, seq, features, null); } /** - * Constructor + * Constructor for a PopupMenu for a click in the sequence id panel * * @param alignPanel * @param seq - * the sequence under the cursor if in the Id panel, null if in the - * sequence panel * @param features - * non-positional features if in the Id panel, features at the - * clicked residue if in the sequence panel + * non-positional features for the sequence * @param groupLinks */ public PopupMenu(final AlignmentPanel alignPanel, final SequenceI seq, List features, List groupLinks) { - // ///////////////////////////////////////////////////////// - // If this is activated from the sequence panel, the user may want to - // edit or annotate a particular residue. Therefore display the residue menu - // - // If from the IDPanel, we must display the sequence menu - // //////////////////////////////////////////////////////// + this(true, alignPanel, seq, features, groupLinks); + } + + /** + * Private constructor that constructs a popup menu for either sequence ID + * Panel, or alignment context + * + * @param fromIdPanel + * @param alignPanel + * @param seq + * @param features + * @param groupLinks + */ + private PopupMenu(boolean fromIdPanel, + final AlignmentPanel alignPanel, + final SequenceI seq, List features, + List groupLinks) + { + this.forIdPanel = fromIdPanel; this.ap = alignPanel; sequence = seq; @@ -416,9 +409,9 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener * 'reference annotations' that may be added to the alignment. First for the * currently selected sequence (if there is one): */ - final List selectedSequence = (seq == null - ? Collections. emptyList() - : Arrays.asList(seq)); + final List selectedSequence = (forIdPanel + ? Arrays.asList(seq) + : Collections. emptyList()); buildAnnotationTypesMenus(seqShowAnnotationsMenu, seqHideAnnotationsMenu, selectedSequence); configureReferenceAnnotationsMenu(seqAddReferenceAnnotations, @@ -443,9 +436,9 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener e.printStackTrace(); } - JMenuItem menuItem; - if (seq != null) + if (forIdPanel) { + JMenuItem menuItem; sequenceMenu.setText(sequence.getName()); if (seq == alignPanel.av.getAlignment().getSeqrep()) { @@ -600,7 +593,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener } if (addOption) { - menuItem = new JMenuItem( + JMenuItem menuItem = new JMenuItem( MessageManager.getString("action.reveal_all")); menuItem.addActionListener(new ActionListener() { @@ -692,25 +685,25 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener { createGroupMenuItem.setVisible(true); unGroupMenuItem.setVisible(false); - jMenu1.setText(MessageManager.getString("action.edit_new_group")); + editGroupMenu.setText(MessageManager.getString("action.edit_new_group")); } else { createGroupMenuItem.setVisible(false); unGroupMenuItem.setVisible(true); - jMenu1.setText(MessageManager.getString("action.edit_group")); + editGroupMenu.setText(MessageManager.getString("action.edit_group")); } - if (seq == null) + if (!forIdPanel) { sequenceMenu.setVisible(false); - pdbStructureDialog.setVisible(false); + chooseStructure.setVisible(false); rnaStructureMenu.setVisible(false); } addLinks(seq, features); - if (seq == null) + if (!forIdPanel) { addFeatureDetails(features); } @@ -785,10 +778,10 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener protected void showFeatureDetails(SequenceFeature sf) { CutAndPasteHtmlTransfer cap = new CutAndPasteHtmlTransfer(); - // it appears Java's CSS does not support border-collaps :-( + // it appears Java's CSS does not support border-collapse :-( cap.addStylesheetRule("table { border-collapse: collapse;}"); cap.addStylesheetRule("table, td, th {border: 1px solid black;}"); - cap.setText(sf.getDetailsReport()); + cap.setText(sf.getDetailsReport(sequence)); Desktop.addInternalFrame(cap, MessageManager.getString("label.feature_details"), 500, 500); @@ -806,12 +799,12 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener */ void addLinks(final SequenceI seq, List features) { - JMenu linkMenu = buildLinkMenu(seq, features); + JMenu linkMenu = buildLinkMenu(forIdPanel ? seq : null, features); // only add link menu if it has entries if (linkMenu.getItemCount() > 0) { - if (sequence != null) + if (forIdPanel) { sequenceMenu.add(linkMenu); } @@ -959,7 +952,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener // menu appears asap // sequence only URLs // ID/regex match URLs - groupLinksMenu = new JMenu( + JMenu groupLinksMenu = new JMenu( MessageManager.getString("action.group_link")); // three types of url that might be created. JMenu[] linkMenus = new JMenu[] { null, @@ -1118,7 +1111,8 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener } }); sequenceMenu.setText(MessageManager.getString("label.sequence")); - sequenceName.setText( + + JMenuItem sequenceName = new JMenuItem( MessageManager.getString("label.edit_name_description")); sequenceName.addActionListener(new ActionListener() { @@ -1128,8 +1122,8 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener sequenceName_actionPerformed(); } }); - chooseAnnotations - .setText(MessageManager.getString("action.choose_annotations")); + JMenuItem chooseAnnotations = new JMenuItem( + MessageManager.getString("action.choose_annotations")); chooseAnnotations.addActionListener(new ActionListener() { @Override @@ -1138,24 +1132,24 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener chooseAnnotations_actionPerformed(e); } }); - sequenceDetails - .setText(MessageManager.getString("label.sequence_details")); + JMenuItem sequenceDetails = new JMenuItem( + MessageManager.getString("label.sequence_details")); sequenceDetails.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - sequenceDetails_actionPerformed(); + createSequenceDetailsReport(new SequenceI[] { sequence }); } }); - sequenceSelDetails - .setText(MessageManager.getString("label.sequence_details")); + JMenuItem sequenceSelDetails = new JMenuItem( + MessageManager.getString("label.sequence_details")); sequenceSelDetails.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - sequenceSelectionDetails_actionPerformed(); + createSequenceDetailsReport(ap.av.getSequenceSelection()); } }); @@ -1180,7 +1174,8 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener } }); - outline.setText(MessageManager.getString("action.border_colour")); + JMenuItem outline = new JMenuItem( + MessageManager.getString("action.border_colour")); outline.addActionListener(new ActionListener() { @Override @@ -1230,7 +1225,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener } }); editMenu.setText(MessageManager.getString("action.edit")); - cut.setText(MessageManager.getString("action.cut")); + JMenuItem cut = new JMenuItem(MessageManager.getString("action.cut")); cut.addActionListener(new ActionListener() { @Override @@ -1248,7 +1243,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener changeCase(e); } }); - copy.setText(MessageManager.getString("action.copy")); + JMenuItem copy = new JMenuItem(MessageManager.getString("action.copy")); copy.addActionListener(new ActionListener() { @Override @@ -1285,7 +1280,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener .setText(MessageManager.getString("label.show_annotations")); groupHideAnnotationsMenu .setText(MessageManager.getString("label.hide_annotations")); - sequenceFeature.setText( + JMenuItem sequenceFeature = new JMenuItem( MessageManager.getString("label.create_sequence_feature")); sequenceFeature.addActionListener(new ActionListener() { @@ -1295,10 +1290,10 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener sequenceFeature_actionPerformed(); } }); - jMenu1.setText(MessageManager.getString("label.group")); - pdbStructureDialog.setText( + editGroupMenu.setText(MessageManager.getString("label.group")); + chooseStructure.setText( MessageManager.getString("label.show_pdbstruct_dialog")); - pdbStructureDialog.addActionListener(new ActionListener() + chooseStructure.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) @@ -1316,7 +1311,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener .setText(MessageManager.getString("label.view_rna_structure")); // colStructureMenu.setText("Colour By Structure"); - editSequence.setText( + JMenuItem editSequence = new JMenuItem( MessageManager.getString("label.edit_sequence") + "..."); editSequence.addActionListener(new ActionListener() { @@ -1338,25 +1333,25 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener } }); - hideInsertions - .setText(MessageManager.getString("label.hide_insertions")); - hideInsertions.addActionListener(new ActionListener() - { - - @Override - public void actionPerformed(ActionEvent e) - { - hideInsertions_actionPerformed(e); - } - }); groupMenu.add(sequenceSelDetails); add(groupMenu); add(sequenceMenu); add(rnaStructureMenu); - add(pdbStructureDialog); - if (sequence != null) + add(chooseStructure); + if (forIdPanel) { + JMenuItem hideInsertions = new JMenuItem( + MessageManager.getString("label.hide_insertions")); + hideInsertions.addActionListener(new ActionListener() + { + + @Override + public void actionPerformed(ActionEvent e) + { + hideInsertions_actionPerformed(e); + } + }); add(hideInsertions); } // annotations configuration panel suppressed for now @@ -1377,7 +1372,7 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener groupMenu.add(sequenceFeature); groupMenu.add(createGroupMenuItem); groupMenu.add(unGroupMenuItem); - groupMenu.add(jMenu1); + groupMenu.add(editGroupMenu); sequenceMenu.add(sequenceName); sequenceMenu.add(sequenceDetails); sequenceMenu.add(makeReferenceSeq); @@ -1391,17 +1386,13 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener editMenu.add(upperCase); editMenu.add(lowerCase); editMenu.add(toggle); - // JBPNote: These shouldn't be added here - should appear in a generic - // 'apply web service to this sequence menu' - // pdbMenu.add(RNAFold); - // pdbMenu.add(ContraFold); - jMenu1.add(groupName); - jMenu1.add(colourMenu); - jMenu1.add(showBoxes); - jMenu1.add(showText); - jMenu1.add(showColourText); - jMenu1.add(outline); - jMenu1.add(displayNonconserved); + editGroupMenu.add(groupName); + editGroupMenu.add(colourMenu); + editGroupMenu.add(showBoxes); + editGroupMenu.add(showText); + editGroupMenu.add(showColourText); + editGroupMenu.add(outline); + editGroupMenu.add(displayNonconserved); } /** @@ -1664,11 +1655,6 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener createSequenceDetailsReport(ap.av.getSequenceSelection()); } - protected void sequenceDetails_actionPerformed() - { - createSequenceDetailsReport(new SequenceI[] { sequence }); - } - public void createSequenceDetailsReport(SequenceI[] sequences) { CutAndPasteHtmlTransfer cap = new CutAndPasteHtmlTransfer(); @@ -1856,10 +1842,9 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener } /** - * DOCUMENT ME! - * - * @param e - * DOCUMENT ME! + * Shows a dialog where the sequence name and description may be edited. If a + * name containing spaces is entered, these are converted to underscores, with a + * warning message. */ void sequenceName_actionPerformed() { @@ -1877,9 +1862,10 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener return; } - if (dialog.getName() != null) + String name = dialog.getName(); + if (name != null) { - if (dialog.getName().indexOf(" ") > -1) + if (name.indexOf(" ") > -1) { JvOptionPane.showMessageDialog(ap, MessageManager @@ -1887,9 +1873,10 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener MessageManager .getString("label.no_spaces_allowed_sequence_name"), JvOptionPane.WARNING_MESSAGE); + name = name.replace(' ', '_'); } - sequence.setName(dialog.getName().replace(' ', '_')); + sequence.setName(name); ap.paintAlignment(false, false); } @@ -2105,38 +2092,20 @@ public class PopupMenu extends JPopupMenu implements ColourChangeListener } } - public void colourByStructure(String pdbid) - { - Annotation[] anots = ap.av.getStructureSelectionManager() - .colourSequenceFromStructure(sequence, pdbid); - - AlignmentAnnotation an = new AlignmentAnnotation("Structure", - "Coloured by " + pdbid, anots); - - ap.av.getAlignment().addAnnotation(an); - an.createSequenceMapping(sequence, 0, true); - // an.adjustForAlignment(); - ap.av.getAlignment().setAnnotationIndex(an, 0); - - ap.adjustAnnotationHeight(); - - sequence.addAlignmentAnnotation(an); - - } - public void editSequence_actionPerformed(ActionEvent actionEvent) { SequenceGroup sg = ap.av.getSelectionGroup(); + SequenceI seq = sequence; if (sg != null) { - if (sequence == null) + if (seq == null) { - sequence = sg.getSequenceAt(0); + seq = sg.getSequenceAt(0); } EditNameDialog dialog = new EditNameDialog( - sequence.getSequenceAsString(sg.getStartRes(), + seq.getSequenceAsString(sg.getStartRes(), sg.getEndRes() + 1), null, MessageManager.getString("label.edit_sequence"), null, MessageManager.getString("label.edit_sequence"), diff --git a/src/jalview/gui/SeqPanel.java b/src/jalview/gui/SeqPanel.java index bc17cc2..e7bd200 100644 --- a/src/jalview/gui/SeqPanel.java +++ b/src/jalview/gui/SeqPanel.java @@ -2257,7 +2257,7 @@ public class SeqPanel extends JPanel List features = ap.getFeatureRenderer() .findFeaturesAtColumn(sequence, column + 1); - PopupMenu pop = new PopupMenu(ap, null, features); + PopupMenu pop = new PopupMenu(ap, sequence, features); pop.show(this, evt.getX(), evt.getY()); } diff --git a/test/jalview/datamodel/SequenceFeatureTest.java b/test/jalview/datamodel/SequenceFeatureTest.java index 9111e5a..2774a16 100644 --- a/test/jalview/datamodel/SequenceFeatureTest.java +++ b/test/jalview/datamodel/SequenceFeatureTest.java @@ -277,43 +277,45 @@ public class SequenceFeatureTest @Test(groups = { "Functional" }) public void testGetDetailsReport() { + SequenceI seq = new Sequence("TestSeq", "PLRFQMD"); + // single locus, no group, no score SequenceFeature sf = new SequenceFeature("variant", "G,C", 22, 22, null); - String expected = "
" - + "" + String expected = "
Typevariant
Start/end22
" + + "" + "
LocationTestSeq22
Typevariant
DescriptionG,C
"; - assertEquals(expected, sf.getDetailsReport()); + assertEquals(expected, sf.getDetailsReport(seq)); // contact feature sf = new SequenceFeature("Disulphide Bond", "a description", 28, 31, null); - expected = "
" - + "" + expected = "
TypeDisulphide Bond
Start/end28:31
" + + "" + "
LocationTestSeq28:31
TypeDisulphide Bond
Descriptiona description
"; - assertEquals(expected, sf.getDetailsReport()); + assertEquals(expected, sf.getDetailsReport(seq)); sf = new SequenceFeature("variant", "G,C", 22, 33, 12.5f, "group"); sf.setValue("Parent", "ENSG001"); sf.setValue("Child", "ENSP002"); - expected = "
" - + "" + expected = "
Typevariant
Start/end22-33
" + + "" + "" + "" + "" + "" + "
LocationTestSeq22-33
Typevariant
DescriptionG,C
Score12.5
Groupgroup
ChildENSP002
ParentENSG001
"; - assertEquals(expected, sf.getDetailsReport()); + assertEquals(expected, sf.getDetailsReport(seq)); /* * feature with embedded html link in description */ String desc = "Fer2 Status: True Positive Pfam 8_8"; sf = new SequenceFeature("Pfam", desc, 8, 83, "Uniprot"); - expected = "
" - + "" + expected = "
TypePfam
Start/end8-83
" + + "" + "" + "
LocationTestSeq8-83
TypePfam
DescriptionFer2 Status: True Positive Pfam 8_8
GroupUniprot
"; - assertEquals(expected, sf.getDetailsReport()); + assertEquals(expected, sf.getDetailsReport(seq)); } } diff --git a/test/jalview/gui/PopupMenuTest.java b/test/jalview/gui/PopupMenuTest.java index df30935..df86494 100644 --- a/test/jalview/gui/PopupMenuTest.java +++ b/test/jalview/gui/PopupMenuTest.java @@ -91,6 +91,8 @@ public class PopupMenuTest public void setUp() throws IOException { Cache.loadProperties("test/jalview/io/testProps.jvprops"); + Cache.initLogger(); + String inMenuString = ("EMBL-EBI Search | http://www.ebi.ac.uk/ebisearch/search.ebi?db=allebi&query=$" + SEQUENCE_ID + "$" @@ -534,7 +536,6 @@ public class PopupMenuTest * note dbref GENE3D is matched to link Gene3D, the latter is displayed */ linkMenu = PopupMenu.buildLinkMenu(seq1, noFeatures); - assertEquals(linkText, linkMenu.getText()); linkItems = linkMenu.getMenuComponents(); assertEquals(3, linkItems.length); assertEquals("EMBL-EBI Search", ((JMenuItem) linkItems[0]).getText()); @@ -553,10 +554,31 @@ public class PopupMenuTest Preferences.sequenceUrlLinks = factory.createUrlProvider(); linkMenu = PopupMenu.buildLinkMenu(seq1, noFeatures); - assertEquals(linkText, linkMenu.getText()); linkItems = linkMenu.getMenuComponents(); assertEquals(1, linkItems.length); assertEquals("EMBL-EBI Search", ((JMenuItem) linkItems[0]).getText()); + + /* + * if sequence is null, only feature links are shown (alignment popup submenu) + */ + linkMenu = PopupMenu.buildLinkMenu(null, noFeatures); + linkItems = linkMenu.getMenuComponents(); + assertEquals(0, linkItems.length); + + List features = new ArrayList<>(); + SequenceFeature sf = new SequenceFeature("type", "desc", 1, 20, null); + features.add(sf); + linkMenu = PopupMenu.buildLinkMenu(null, features); + linkItems = linkMenu.getMenuComponents(); + assertEquals(0, linkItems.length); // feature has no links + + sf.addLink("Pfam family|http://pfam.xfam.org/family/PF00111"); + linkMenu = PopupMenu.buildLinkMenu(null, features); + linkItems = linkMenu.getMenuComponents(); + assertEquals(1, linkItems.length); + JMenuItem item = (JMenuItem) linkItems[0]; + assertEquals("Pfam family", item.getText()); + // ? no way to verify URL, compiled into link's actionListener } @Test(groups = { "Functional" })