import java.util.Map;
import javax.swing.JButton;
-import javax.swing.JCheckBox;
import javax.swing.JInternalFrame;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
* @author gmcarstairs
*
*/
+@SuppressWarnings("serial")
public class AnnotationChooser extends JPanel
{
for (final String type : annotationTypes)
{
- final JCheckBox check = new JCheckBox(type);
+ final Checkbox check = new Checkbox(type);
check.setFont(CHECKBOX_FONT);
check.addItemListener(new ItemListener()
{
{
AnnotationChooser.this.selectedTypes.remove(type);
}
- repaintAnnotations(false);
+ changeTypeSelected_actionPerformed(type);
}
});
jp.add(check);
}
/**
- * Set visibility flags on annotation rows then repaint the alignment panel.
+ * Update display when scope (All/Selected sequences/Unselected) is changed.
* <p>
- * Optionally, update all rows, including those not in the 'apply to' scope.
- * This makes more sense when switching between selected and unselected
- * sequences. When selecting annotation types, or show/hide, we only apply the
- * settings to the selected sequences.
+ * Set annotations (with one of the selected types) to the selected Show/Hide
+ * visibility, if they are in the new application scope. Set to the opposite
+ * if outside the scope.
* <p>
* Note this only affects sequence-specific annotations, others are left
* unchanged.
*/
- protected void repaintAnnotations(boolean updateAllRows)
+ protected void changeApplyTo_actionPerformed()
{
+ setAnnotationVisibility(true);
+
+ // copied from AnnotationLabel.actionPerformed (after show/hide row)...
+ // TODO should drive this functionality into AlignmentPanel
+ ap.updateAnnotation();
+ // this.ap.annotationPanel.adjustPanelHeight();
+ // this.ap.alabels.setSize(this.ap.alabels.getSize().width,
+ // this.ap.annotationPanel.getSize().height);
+ // this.ap.validate();
+ this.ap.paintAlignment(true);
+ }
+
+ /**
+ * Update display when an annotation type is selected or deselected.
+ * <p>
+ * If the type is selected, set visibility of annotations of that type which
+ * are in the application scope (all, selected or unselected sequences).
+ * <p>
+ * If the type is unselected, set visibility to the opposite value. That is,
+ * treat select/deselect as a 'toggle' operation.
+ *
+ * @param type
+ */
+ protected void changeTypeSelected_actionPerformed(String type)
+ {
+ boolean typeSelected = this.selectedTypes.containsKey(type);
for (AlignmentAnnotation aa : this.ap.getAlignment()
.getAlignmentAnnotation())
{
- if (aa.sequenceRef != null)
+ if (aa.sequenceRef != null && type.equals(aa.label)
+ && isInActionScope(aa))
{
- setAnnotationVisibility(aa, updateAllRows);
+ aa.visible = typeSelected ? this.showSelected : !this.showSelected;
}
}
- // copied from AnnotationLabel.actionPerformed (after show/hide row)...
- // TODO should drive this functionality into AlignmentPanel
ap.updateAnnotation();
- this.ap.annotationPanel.adjustPanelHeight();
- this.ap.alabels.setSize(this.ap.alabels.getSize().width,
- this.ap.annotationPanel.getSize().height);
- this.ap.validate();
+ // // this.ap.annotationPanel.adjustPanelHeight();
+ // this.ap.alabels.setSize(this.ap.alabels.getSize().width,
+ // this.ap.annotationPanel.getSize().height);
+ // this.ap.validate();
this.ap.paintAlignment(true);
}
/**
+ * Update display on change of choice of Show or Hide
+ * <p>
+ * For annotations of any selected type, set visibility of annotations of that
+ * type which are in the application scope (all, selected or unselected
+ * sequences).
+ *
+ * @param type
+ */
+ protected void changeShowHide_actionPerformed()
+ {
+ setAnnotationVisibility(false);
+
+ this.ap.updateAnnotation();
+ // this.ap.annotationPanel.adjustPanelHeight();
+ this.ap.paintAlignment(true);
+ }
+
+ /**
+ * Update visibility flags on annotation rows as per the current user choices.
+ *
+ * @param updateAllRows
+ */
+ protected void setAnnotationVisibility(boolean updateAllRows)
+ {
+ for (AlignmentAnnotation aa : this.ap.getAlignment()
+ .getAlignmentAnnotation())
+ {
+ if (aa.sequenceRef != null)
+ {
+ setAnnotationVisibility(aa, updateAllRows);
+ }
+ }
+ }
+
+ /**
* Determine and set the visibility of the given annotation from the currently
* selected options.
* <p>
- * If its sequence is in the selected application scope
- * (all/selected/unselected sequences), then we set its visibility.
+ * Only update annotations whose type is one of the selected types.
* <p>
- * If the annotation type is one of those currently selected by checkbox, set
- * its visibility to the selected value. If it is not currently selected, set
- * it to the opposite value. So, unselecting an annotation type with 'hide'
- * selected, will cause those annotations to be unhidden.
+ * If its sequence is in the selected application scope
+ * (all/selected/unselected sequences), then we set its visibility according
+ * to the current choice of Show or Hide.
* <p>
* If force update of all rows is wanted, then set rows not in the sequence
* selection scope to the opposite visibility to those in scope.
protected void setAnnotationVisibility(AlignmentAnnotation aa,
boolean updateAllRows)
{
- boolean setToVisible = false;
if (this.selectedTypes.containsKey(aa.label))
{
- setToVisible = this.showSelected;
- }
- else
- {
- setToVisible = !this.showSelected;
- }
- if (isInActionScope(aa))
- {
- aa.visible = setToVisible;
- }
- else if (updateAllRows)
- {
- aa.visible = !setToVisible;
+ if (isInActionScope(aa))
+ {
+ aa.visible = this.showSelected;
+ }
+ else if (updateAllRows)
+ {
+ aa.visible = !this.showSelected;
+ }
}
// TODO force not visible if associated sequence is hidden?
// currently hiding a sequence does not hide its annotation rows
// we don't care if the annotation's sequence is selected or not
result = true;
}
+ else if (this.sg == null)
+ {
+ // shouldn't happen - defensive programming
+ result = true;
+ }
else if (this.sg.getSequences().contains(aa.sequenceRef))
{
// annotation is for a member of the selection group
public static List<String> getAnnotationTypes(AlignmentI alignment,
boolean sequenceSpecificOnly)
{
- // stub
List<String> result = new ArrayList<String>();
for (AlignmentAnnotation aa : alignment.getAlignmentAnnotation())
{
if (evt.getStateChange() == ItemEvent.SELECTED) {
AnnotationChooser.this.setApplyToSelectedSequences(true);
AnnotationChooser.this.setApplyToUnselectedSequences(true);
- AnnotationChooser.this.repaintAnnotations(true);
+ AnnotationChooser.this.changeApplyTo_actionPerformed();
}
}
});
{
AnnotationChooser.this.setApplyToSelectedSequences(true);
AnnotationChooser.this.setApplyToUnselectedSequences(false);
- AnnotationChooser.this.repaintAnnotations(true);
+ AnnotationChooser.this.changeApplyTo_actionPerformed();
}
}
});
{
AnnotationChooser.this.setApplyToSelectedSequences(false);
AnnotationChooser.this.setApplyToUnselectedSequences(true);
- AnnotationChooser.this.repaintAnnotations(true);
+ AnnotationChooser.this.changeApplyTo_actionPerformed();
}
}
});
}
/**
- * Build a panel with radio buttons options to show or hide selected
+ * Build a panel with radio button options to show or hide selected
* annotations.
*
* @return
{
if (evt.getStateChange() == ItemEvent.SELECTED) {
AnnotationChooser.this.setShowSelected(true);
- AnnotationChooser.this.repaintAnnotations(false);
+ AnnotationChooser.this.changeShowHide_actionPerformed();
}
}
});
if (evt.getStateChange() == ItemEvent.SELECTED)
{
AnnotationChooser.this.setShowSelected(false);
- AnnotationChooser.this.repaintAnnotations(false);
+ AnnotationChooser.this.changeShowHide_actionPerformed();
}
}
});
this.applyToUnselectedSequences = applyToUnselectedSequences;
}
+ protected boolean isShowSelected()
+ {
+ return showSelected;
+ }
+
+ protected boolean isApplyToSelectedSequences()
+ {
+ return applyToSelectedSequences;
+ }
+
+ protected boolean isApplyToUnselectedSequences()
+ {
+ return applyToUnselectedSequences;
+ }
+
}
package jalview.gui;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.SequenceGroup;
+import jalview.datamodel.SequenceI;
import jalview.io.AppletFormatAdapter;
-import jalview.io.FileLoader;
+import jalview.util.MessageManager;
+
+import java.awt.BorderLayout;
+import java.awt.Checkbox;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.FlowLayout;
+import java.awt.event.ItemEvent;
+import java.io.IOException;
+import java.util.List;
+
+import javax.swing.JButton;
+import javax.swing.JPanel;
import org.junit.Before;
import org.junit.Test;
*/
public class AnnotationChooserTest
{
- final static String TEST_FILE = "./examples/uniref50.fa";
+ // 4 sequences x 13 positions
+ final static String TEST_DATA = ">FER_CAPAA Ferredoxin\n"
+ + "TIETHKEAELVG-\n"
+ + ">FER_CAPAN Ferredoxin, chloroplast precursor\n"
+ + "TIETHKEAELVG-\n"
+ + ">FER1_SOLLC Ferredoxin-1, chloroplast precursor\n"
+ + "TIETHKEEELTA-\n" + ">Q93XJ9_SOLTU Ferredoxin I precursor\n"
+ + "TIETHKEEELTA-\n";
+
AnnotationChooser testee;
+ AlignmentPanel parentPanel;
+
AlignFrame af;
@Before
- public void setUp()
+ public void setUp() throws IOException
+ {
+ AlignmentI al = new jalview.io.FormatAdapter().readFile(TEST_DATA,
+ AppletFormatAdapter.PASTE, "FASTA");
+ af = new AlignFrame(al, 700, 500);
+ parentPanel = new AlignmentPanel(af, af.getViewport());
+ addAnnotations();
+ }
+
+ /**
+ * Add 4 annotations, 3 of them sequence-specific.
+ *
+ * <PRE>
+ * ann1 - for sequence 0 - label 'IUPRED'
+ * ann2 - not sequence related - label 'Beauty'
+ * ann3 - for sequence 3 - label 'JMol'
+ * ann4 - for sequence 2 - label 'IUPRED'
+ * ann5 - for sequence 1 - label 'JMol'
+ */
+ private void addAnnotations()
+ {
+ Annotation an = new Annotation(2f);
+ Annotation[] anns = new Annotation[]
+ { an, an, an };
+ AlignmentAnnotation ann0 = new AlignmentAnnotation("IUPRED", "", anns);
+ AlignmentAnnotation ann1 = new AlignmentAnnotation("Beauty", "", anns);
+ AlignmentAnnotation ann2 = new AlignmentAnnotation("JMol", "", anns);
+ AlignmentAnnotation ann3 = new AlignmentAnnotation("IUPRED", "", anns);
+ AlignmentAnnotation ann4 = new AlignmentAnnotation("JMol", "", anns);
+ SequenceI[] seqs = parentPanel.getAlignment().getSequencesArray();
+ ann0.setSequenceRef(seqs[0]);
+ ann2.setSequenceRef(seqs[3]);
+ ann3.setSequenceRef(seqs[2]);
+ ann4.setSequenceRef(seqs[1]);
+ parentPanel.getAlignment().addAnnotation(ann0);
+ parentPanel.getAlignment().addAnnotation(ann1);
+ parentPanel.getAlignment().addAnnotation(ann2);
+ parentPanel.getAlignment().addAnnotation(ann3);
+ parentPanel.getAlignment().addAnnotation(ann4);
+ }
+
+ /**
+ * Test creation of panel with OK and Cancel buttons
+ */
+ @Test
+ public void testBuildActionButtonsPanel()
+ {
+ testee = new AnnotationChooser(parentPanel);
+ JPanel jp = testee.buildActionButtonsPanel();
+ assertTrue("Wrong layout", jp.getLayout() instanceof FlowLayout);
+
+ Component[] comps = jp.getComponents();
+ assertEquals("Not 2 action buttons", 2, comps.length);
+
+ final Component jb1 = comps[0];
+ final Component jb2 = comps[1];
+
+ assertEquals("Not 'OK' button", MessageManager.getString("action.ok"),
+ ((JButton) jb1).getText());
+ assertEquals("Wrong button font", JvSwingUtils.getLabelFont(),
+ jb1.getFont());
+
+ assertEquals("Not 'Cancel' button",
+ MessageManager.getString("action.cancel"),
+ ((JButton) jb2).getText());
+ assertEquals("Wrong button font", JvSwingUtils.getLabelFont(),
+ jb2.getFont());
+ }
+
+ /**
+ * Test 'Apply to' has 3 radio buttons enabled, 'Selected Sequences' selected,
+ * when there is a current selection group.
+ */
+ @Test
+ public void testBuildApplyToOptionsPanel_withSelectionGroup()
+ {
+ selectSequences(0, 2, 3);
+ testee = new AnnotationChooser(parentPanel);
+
+ JPanel jp = testee.buildApplyToOptionsPanel();
+ Component[] comps = jp.getComponents();
+ assertEquals("Not 3 radio buttons", 3, comps.length);
+
+ final Checkbox cb1 = (Checkbox) comps[0];
+ final Checkbox cb2 = (Checkbox) comps[1];
+ final Checkbox cb3 = (Checkbox) comps[2];
+
+ assertTrue("Not enabled", cb1.isEnabled());
+ assertTrue("Not enabled", cb2.isEnabled());
+ assertTrue("Not enabled", cb3.isEnabled());
+ assertEquals("Option not selected", cb2, cb2.getCheckboxGroup()
+ .getSelectedCheckbox());
+
+ // check state variables match checkbox selection
+ assertTrue(testee.isApplyToSelectedSequences());
+ assertFalse(testee.isApplyToUnselectedSequences());
+ }
+
+ /**
+ * Add a sequence group to the alignment with the specified sequences (base 0)
+ * in it
+ *
+ * @param i
+ * @param more
+ */
+ private void selectSequences(int... selected)
+ {
+ SequenceI[] seqs = parentPanel.getAlignment().getSequencesArray();
+ SequenceGroup sg = new SequenceGroup();
+ for (int i : selected)
+ {
+ sg.addSequence(seqs[i], false);
+ }
+ parentPanel.av.setSelectionGroup(sg);
+ }
+
+ /**
+ * Test 'Apply to' has 1 radio button enabled, 'All Sequences' selected, when
+ * there is no current selection group.
+ */
+ @Test
+ public void testBuildApplyToOptionsPanel_noSelectionGroup()
+ {
+ testee = new AnnotationChooser(parentPanel);
+ JPanel jp = testee.buildApplyToOptionsPanel();
+ verifyApplyToOptionsPanel_noSelectionGroup(jp);
+ }
+
+ protected void verifyApplyToOptionsPanel_noSelectionGroup(JPanel jp)
+ {
+ assertTrue("Wrong layout", jp.getLayout() instanceof FlowLayout);
+ Component[] comps = jp.getComponents();
+ assertEquals("Not 3 radio buttons", 3, comps.length);
+
+ final Checkbox cb1 = (Checkbox) comps[0];
+ final Checkbox cb2 = (Checkbox) comps[1];
+ final Checkbox cb3 = (Checkbox) comps[2];
+
+ assertTrue("Not enabled", cb1.isEnabled());
+ assertFalse("Enabled", cb2.isEnabled());
+ assertFalse("Enabled", cb3.isEnabled());
+ assertEquals("Not selected", cb1, cb1.getCheckboxGroup()
+ .getSelectedCheckbox());
+
+ // check state variables match checkbox selection
+ assertTrue(testee.isApplyToSelectedSequences());
+ assertTrue(testee.isApplyToUnselectedSequences());
+
+ assertEquals("Wrong text",
+ MessageManager.getString("label.all_sequences"), cb1.getLabel());
+ assertEquals("Wrong text",
+ MessageManager.getString("label.selected_sequences"),
+ cb2.getLabel());
+ assertEquals("Wrong text",
+ MessageManager.getString("label.except_selected_sequences"),
+ cb3.getLabel());
+ }
+
+ /**
+ * Test Show and Hide radio buttons created, with Hide initially selected.
+ */
+ @Test
+ public void testBuildShowHidePanel()
+ {
+ testee = new AnnotationChooser(parentPanel);
+ JPanel jp = testee.buildShowHidePanel();
+ verifyShowHidePanel(jp);
+
+ }
+
+ protected void verifyShowHidePanel(JPanel jp)
+ {
+ assertTrue("Wrong layout", jp.getLayout() instanceof FlowLayout);
+ Component[] comps = jp.getComponents();
+ assertEquals("Not 2 radio buttons", 2, comps.length);
+
+ final Checkbox cb1 = (Checkbox) comps[0];
+ final Checkbox cb2 = (Checkbox) comps[1];
+
+ assertTrue("Show not enabled", cb1.isEnabled());
+ assertTrue("Hide not enabled", cb2.isEnabled());
+
+ // Hide (button 2) selected; note this may change to none (null)
+ assertEquals("Not selected", cb2, cb2.getCheckboxGroup()
+ .getSelectedCheckbox());
+
+ assertTrue("Show is flagged", !testee.isShowSelected());
+
+ assertEquals("Wrong text",
+ MessageManager.getString("label.show_selected_annotations"),
+ cb1.getLabel());
+ assertEquals("Wrong text",
+ MessageManager.getString("label.hide_selected_annotations"),
+ cb2.getLabel());
+ }
+
+ /**
+ * Test construction of panel containing two sub-panels
+ */
+ @Test
+ public void testBuildShowHideOptionsPanel()
+ {
+ testee = new AnnotationChooser(parentPanel);
+ JPanel jp = testee.buildShowHideOptionsPanel();
+ assertTrue("Wrong layout", jp.getLayout() instanceof BorderLayout);
+ Component[] comps = jp.getComponents();
+ assertEquals("Not 2 sub-panels", 2, comps.length);
+
+ verifyShowHidePanel((JPanel) comps[0]);
+ verifyApplyToOptionsPanel_noSelectionGroup((JPanel) comps[1]);
+ }
+
+ /**
+ * Test that annotation types are (uniquely) identified.
+ *
+ */
+ @Test
+ public void testGetAnnotationTypes()
+ {
+ selectSequences(1);
+ testee = new AnnotationChooser(parentPanel);
+ // selection group should make no difference to the result
+ // as all annotation types for the alignment are considered
+
+ List<String> types = AnnotationChooser.getAnnotationTypes(
+ parentPanel.getAlignment(), true);
+ assertEquals("Not two annotation types", 2, types.size());
+ assertTrue("IUPRED missing", types.contains("IUPRED"));
+ assertTrue("JMol missing", types.contains("JMol"));
+
+ types = AnnotationChooser.getAnnotationTypes(
+ parentPanel.getAlignment(), false);
+ assertEquals("Not six annotation types", 6, types.size());
+ assertTrue("IUPRED missing", types.contains("IUPRED"));
+ assertTrue("JMol missing", types.contains("JMol"));
+ assertTrue("Beauty missing", types.contains("Beauty"));
+ // These are added by viewmodel.AlignViewport.initAutoAnnotation():
+ assertTrue("Consensus missing", types.contains("Consensus"));
+ assertTrue("Quality missing", types.contains("Quality"));
+ assertTrue("Conservation missing", types.contains("Conservation"));
+ }
+
+ /**
+ * Test result of selecting an annotation type, with 'Hide for all sequences'.
+ *
+ * We expect all annotations of that type to be set hidden. Other annotations
+ * should be left visible.
+ */
+ @Test
+ public void testSelectType_hideForAll()
+ {
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+ final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
+ setSelected(hideCheckbox, true);
+
+ final Checkbox allSequencesCheckbox = (Checkbox) getComponent(testee,
+ 1, 1, 0);
+ setSelected(allSequencesCheckbox, true);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+
+ assertTrue(anns[5].visible); // JMol for seq3
+ assertTrue(anns[7].visible); // JMol for seq1
+
+ setSelected(getTypeCheckbox("JMol"), true);
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertTrue(anns[3].visible); // IUPred for seq0
+ assertTrue(anns[4].visible); // Beauty
+ assertFalse(anns[5].visible); // JMol for seq3 - not selected but hidden
+ assertTrue(anns[6].visible); // IUPRED for seq2
+ assertFalse(anns[7].visible); // JMol for seq1 - selected and hidden
+ }
+
+ /**
+ * Test result of selecting an annotation type, with 'Hide for selected
+ * sequences'.
+ *
+ * We expect the annotations of that type, linked to the sequence group, to be
+ * set hidden. Other annotations should be left visible.
+ */
+ @Test
+ public void testSelectType_hideForSelected()
+ {
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+ final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
+ setSelected(hideCheckbox, true);
+
+ /*
+ * Don't set the 'selected sequences' radio button since this would trigger
+ * an update, including unselected sequences / annotation types
+ */
+ // setSelected(getSelectedSequencesCheckbox());
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+
+ assertTrue(anns[7].visible); // JMol for seq1
+
+ setSelected(getTypeCheckbox("JMol"), true);
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertTrue(anns[3].visible); // IUPred for seq0
+ assertTrue(anns[4].visible); // Beauty
+ assertTrue(anns[5].visible); // JMol for seq3 not in selection group
+ assertTrue(anns[6].visible); // IUPRED for seq2
+ assertFalse(anns[7].visible); // JMol for seq1 in selection group
+ }
+
+ /**
+ * Test result of deselecting an annotation type, with 'Hide for all
+ * sequences'.
+ *
+ * We expect all annotations of that type to be set visible. Other annotations
+ * should be left unchanged.
+ */
+ @Test
+ public void testDeselectType_hideForAll()
{
- FileLoader fl = new jalview.io.FileLoader(false);
- af = fl.LoadFileWaitTillLoaded(TEST_FILE,
- AppletFormatAdapter.FILE);
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+
+ final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
+ setSelected(hideCheckbox, true);
+
+ final Checkbox allSequencesCheckbox = (Checkbox) getComponent(testee,
+ 1, 1, 0);
+ setSelected(allSequencesCheckbox, true);
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+
+ final Checkbox typeCheckbox = getTypeCheckbox("JMol");
+
+ // select JMol - all hidden
+ setSelected(typeCheckbox, true);
+ assertFalse(anns[5].visible); // JMol for seq3
+ assertFalse(anns[7].visible); // JMol for seq1
+
+ // deselect JMol - all unhidden
+ setSelected(typeCheckbox, false);
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertTrue(anns[3].visible); // IUPred for seq0
+ assertTrue(anns[4].visible); // Beauty
+ assertTrue(anns[5].visible); // JMol for seq3
+ assertTrue(anns[6].visible); // IUPRED for seq2
+ assertTrue(anns[7].visible); // JMol for seq1
}
+ /**
+ * Test result of deselecting an annotation type, with 'Hide for selected
+ * sequences'.
+ *
+ * We expect the annotations of that type, linked to the sequence group, to be
+ * set visible. Other annotations should be left unchanged.
+ */
@Test
- public void testAlignmentLoader() throws Exception
+ public void testDeselectType_hideForSelected()
{
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+ final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
+ setSelected(hideCheckbox, true);
+
+ /*
+ * Don't set the 'selected sequences' radio button since this would trigger
+ * an update, including unselected sequences / annotation types
+ */
+ // setSelected(getSelectedSequencesCheckbox());
- AlignmentPanel parentPanel = new AlignmentPanel(af, af.getViewport());
+ setSelected(getTypeCheckbox("JMol"), true);
+ setSelected(getTypeCheckbox("JMol"), false);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertTrue(anns[3].visible); // IUPred for seq0
+ assertTrue(anns[4].visible); // Beauty
+ assertTrue(anns[5].visible); // JMol for seq3 not in selection group
+ assertTrue(anns[6].visible); // IUPRED for seq2
+ assertTrue(anns[7].visible); // JMol for seq1 in selection group
+ }
+
+ /**
+ * Test result of selecting an annotation type, with 'Show for all sequences'.
+ *
+ * We expect all annotations of that type to be set visible. Other annotations
+ * should be left unchanged
+ */
+ @Test
+ public void testSelectType_showForAll()
+ {
+ selectSequences(1, 2);
testee = new AnnotationChooser(parentPanel);
+ final Checkbox showCheckbox = (Checkbox) getComponent(testee, 1, 0, 0);
+ final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
+
+ final Checkbox allSequencesCheckbox = (Checkbox) getComponent(testee,
+ 1, 1, 0);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+
+ // hide all JMol annotations
+ setSelected(allSequencesCheckbox, true);
+ setSelected(hideCheckbox, true);
+ setSelected(getTypeCheckbox("JMol"), true);
+ assertFalse(anns[5].visible); // JMol for seq3
+ assertFalse(anns[7].visible); // JMol for seq1
+ // ...now show them...
+ setSelected(showCheckbox, true);
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertTrue(anns[3].visible); // IUPred for seq0
+ assertTrue(anns[4].visible); // Beauty
+ assertTrue(anns[5].visible); // JMol for seq3
+ assertTrue(anns[6].visible); // IUPRED for seq2
+ assertTrue(anns[7].visible); // JMol for seq1
+ }
+
+ /**
+ * Test result of selecting an annotation type, with 'Show for selected
+ * sequences'.
+ *
+ * We expect all annotations of that type, linked to the sequence group, to be
+ * set visible. Other annotations should be left unchanged
+ */
+ @Test
+ public void testSelectType_showForSelected()
+ {
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+ final Checkbox showCheckbox = (Checkbox) getComponent(testee, 1, 0, 0);
+ final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
+
+ final Checkbox selectedSequencesCheckbox = (Checkbox) getComponent(
+ testee, 1, 1, 1);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+
+ // hide all JMol annotations in the selection region (== annotation 7)
+ setSelected(selectedSequencesCheckbox, true);
+ setSelected(hideCheckbox, true);
+ setSelected(getTypeCheckbox("JMol"), true);
+ assertTrue(anns[5].visible); // JMol for seq3
+ assertFalse(anns[7].visible); // JMol for seq1
+ // ...now show them...
+ setSelected(showCheckbox, true);
+
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertTrue(anns[3].visible); // IUPred for seq0
+ assertTrue(anns[4].visible); // Beauty
+ assertTrue(anns[5].visible); // JMol for seq3
+ assertTrue(anns[6].visible); // IUPRED for seq2
+ assertTrue(anns[7].visible); // JMol for seq1
}
+ /**
+ * Test result of deselecting an annotation type, with 'Show for all
+ * sequences'.
+ *
+ * We expect all annotations of that type to be set hidden. Other annotations
+ * should be left unchanged.
+ */
@Test
- public void testBuildFrame()
+ public void testDeselectType_showForAll()
{
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+
+ final Checkbox showCheckbox = (Checkbox) getComponent(testee, 1, 0, 0);
+ setSelected(showCheckbox, true);
+
+ final Checkbox allSequencesCheckbox = (Checkbox) getComponent(testee,
+ 1, 1, 0);
+ setSelected(allSequencesCheckbox, true);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+
+ final Checkbox typeCheckbox = getTypeCheckbox("JMol");
+ // select JMol - all shown
+ setSelected(typeCheckbox, true);
+ assertTrue(anns[5].visible); // JMol for seq3
+ assertTrue(anns[7].visible); // JMol for seq1
+
+ // deselect JMol - all hidden
+ setSelected(typeCheckbox, false);
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertTrue(anns[3].visible); // IUPred for seq0
+ assertTrue(anns[4].visible); // Beauty
+ assertFalse(anns[5].visible); // JMol for seq3
+ assertTrue(anns[6].visible); // IUPRED for seq2
+ assertFalse(anns[7].visible); // JMol for seq1
+ }
+
+ /**
+ * Test result of deselecting an annotation type, with 'Show for selected
+ * sequences'.
+ *
+ * We expect the annotations of that type, linked to the sequence group, to be
+ * set hidden. Other annotations should be left unchanged.
+ */
+ @Test
+ public void testDeselectType_showForSelected()
+ {
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+ final Checkbox showCheckbox = (Checkbox) getComponent(testee, 1, 0, 0);
+ setSelected(showCheckbox, true);
+
+ /*
+ * Don't set the 'selected sequences' radio button since this would trigger
+ * an update, including unselected sequences / annotation types
+ */
+ // setSelected(getSelectedSequencesCheckbox());
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+
+ // select JMol - should remain visible
+ setSelected(getTypeCheckbox("JMol"), true);
+ assertTrue(anns[5].visible); // JMol for seq3
+ assertTrue(anns[7].visible); // JMol for seq1
+
+ // deselect JMol - should be hidden for selected sequences only
+ setSelected(getTypeCheckbox("JMol"), false);
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertTrue(anns[3].visible); // IUPred for seq0
+ assertTrue(anns[4].visible); // Beauty
+ assertTrue(anns[5].visible); // JMol for seq3 not in selection group
+ assertTrue(anns[6].visible); // IUPRED for seq2
+ assertFalse(anns[7].visible); // JMol for seq1 in selection group
+ }
+
+ /**
+ * Helper method to drill down to a sub-component in a Container hierarchy.
+ *
+ * @param cont
+ * @param i
+ * @param j
+ * @param k
+ * @return
+ */
+ public static Component getComponent(Container cont, int... positions)
+ {
+ Component comp = cont;
+ for (int i : positions)
+ {
+ comp = ((Container) comp).getComponent(i);
+ }
+ return comp;
+ }
+
+ /**
+ * Helper method to set or unset a checkbox and fire its action listener.
+ *
+ * @param cb
+ * @param select
+ */
+ protected void setSelected(Checkbox cb, boolean select)
+ {
+ // TODO refactor to a test utility class
+ cb.setState(select);
+ // have to manually fire the action listener
+ cb.getItemListeners()[0].itemStateChanged(new ItemEvent(cb,
+ ItemEvent.ITEM_STATE_CHANGED, cb, select ? ItemEvent.SELECTED
+ : ItemEvent.DESELECTED));
+ }
+
+ /**
+ * Helper method to drill down to the 'Annotation type' checkbox with given
+ * label.
+ *
+ * @return
+ */
+ private Checkbox getTypeCheckbox(String forLabel)
+ {
+ Component[] cbs = ((JPanel) testee.getComponent(0)).getComponents();
+ for (Component comp : cbs)
+ {
+ final Checkbox cb = (Checkbox) comp;
+ if (cb.getLabel().equals(forLabel))
+ {
+ return cb;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Test isInActionScope for the case where the scope is selected sequences.
+ * Test cases include sequences in the selection group, and others not in the
+ * group.
+ */
+ @Test
+ public void testIsInActionScope_selectedScope()
+ {
+ // sequences 1 and 2 have annotations 4 and 3 respectively
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+
+ final Checkbox selectedSequencesCheckbox = (Checkbox) getComponent(
+ testee, 1, 1, 1);
+ setSelected(selectedSequencesCheckbox, true);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+ // remember 3 annotations to skip (Conservation/Quality/Consensus)
+ assertFalse(testee.isInActionScope(anns[3]));
+ assertFalse(testee.isInActionScope(anns[4]));
+ assertFalse(testee.isInActionScope(anns[5]));
+ assertTrue(testee.isInActionScope(anns[6]));
+ assertTrue(testee.isInActionScope(anns[7]));
+ }
+
+ /**
+ * Test isInActionScope for the case where the scope is unselected sequences.
+ * Test cases include sequences in the selection group, and others not in the
+ * group.
+ */
+ @Test
+ public void testIsInActionScope_unselectedScope()
+ {
+ // sequences 1 and 2 have annotations 4 and 3 respectively
+ selectSequences(1, 2);
+ testee = new AnnotationChooser(parentPanel);
+
+ final Checkbox unselectedSequencesCheckbox = (Checkbox) getComponent(
+ testee, 1, 1, 2);
+ setSelected(unselectedSequencesCheckbox, true);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+ // remember 3 annotations to skip (Conservation/Quality/Consensus)
+ assertTrue(testee.isInActionScope(anns[3]));
+ assertTrue(testee.isInActionScope(anns[4]));
+ assertTrue(testee.isInActionScope(anns[5]));
+ assertFalse(testee.isInActionScope(anns[6]));
+ assertFalse(testee.isInActionScope(anns[7]));
+ }
+
+ /**
+ * Test that the reset method restores previous visibility flags.
+ */
+ @Test
+ public void testResetOriginalState()
+ {
+ testee = new AnnotationChooser(parentPanel);
+
+ AlignmentAnnotation[] anns = parentPanel.getAlignment()
+ .getAlignmentAnnotation();
+ // all start visible
+ for (int i = 0; i < anns.length; i++)
+ {
+ assertTrue(i + "'th sequence not visible", anns[i].visible);
+ }
+
+ final Checkbox hideCheckbox = (Checkbox) getComponent(testee, 1, 0, 1);
+ setSelected(hideCheckbox, true);
+
+ final Checkbox allSequencesCheckbox = (Checkbox) getComponent(testee,
+ 1, 1, 0);
+ setSelected(allSequencesCheckbox, true);
+
+ setSelected(getTypeCheckbox("JMol"), true);
+ setSelected(getTypeCheckbox("IUPRED"), true);
+
+ assertTrue(anns[0].visible); // Conservation
+ assertTrue(anns[1].visible); // Quality
+ assertTrue(anns[2].visible); // Consensus
+ assertFalse(anns[3].visible); // IUPRED
+ assertTrue(anns[4].visible); // Beauty (not seq-related)
+ assertFalse(anns[5].visible); // JMol
+ assertFalse(anns[6].visible); // IUPRED
+ assertFalse(anns[7].visible); // JMol
+ // reset - should all be visible
+ testee.resetOriginalState();
+ for (int i = 0; i < anns.length; i++)
+ {
+ assertTrue(i + "'th sequence not visible", anns[i].visible);
+ }
}
}