From 1d4b37e9bd54c095aa00e643b741c931eb61c58b Mon Sep 17 00:00:00 2001 From: Charles Ofoegbu Date: Thu, 22 Jan 2015 18:33:43 +0000 Subject: [PATCH] JAL-1553 added applet support for the select-column-by-annotation-row feature --- src/jalview/appletgui/AlignFrame.java | 17 +- src/jalview/appletgui/AlignViewport.java | 33 +- src/jalview/appletgui/AnnotationColourChooser.java | 45 +- src/jalview/appletgui/AnnotationColumnChooser.java | 913 ++++++++++++++++++++ src/jalview/appletgui/AnnotationRowFilter.java | 198 +++++ src/jalview/appletgui/TitledPanel.java | 75 ++ src/jalview/controller/AlignViewController.java | 86 -- src/jalview/datamodel/ColumnSelection.java | 87 ++ src/jalview/gui/AnnotationColourChooser.java | 3 - src/jalview/gui/AnnotationColumnChooser.java | 14 +- src/jalview/gui/AnnotationRowFilter.java | 6 + src/jalview/gui/JvSwingUtils.java | 6 +- 12 files changed, 1358 insertions(+), 125 deletions(-) create mode 100644 src/jalview/appletgui/AnnotationColumnChooser.java create mode 100644 src/jalview/appletgui/AnnotationRowFilter.java create mode 100644 src/jalview/appletgui/TitledPanel.java diff --git a/src/jalview/appletgui/AlignFrame.java b/src/jalview/appletgui/AlignFrame.java index 9fb91ed..dbdc23f 100644 --- a/src/jalview/appletgui/AlignFrame.java +++ b/src/jalview/appletgui/AlignFrame.java @@ -23,8 +23,8 @@ package jalview.appletgui; import jalview.analysis.AlignmentSorter; import jalview.api.AlignViewControllerGuiI; import jalview.api.AlignViewControllerI; -import jalview.api.SequenceStructureBinding; import jalview.api.FeatureRenderer; +import jalview.api.SequenceStructureBinding; import jalview.bin.JalviewLite; import jalview.commands.CommandI; import jalview.commands.EditCommand; @@ -91,9 +91,7 @@ import java.io.IOException; import java.net.URL; import java.net.URLEncoder; import java.util.Arrays; -import java.util.Enumeration; import java.util.Hashtable; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.StringTokenizer; @@ -1108,6 +1106,10 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, { new AnnotationColourChooser(viewport, alignPanel); } + else if (source == annotationColumnSelection) + { + new AnnotationColumnChooser(viewport, alignPanel); + } else if (source == sortPairwiseMenuItem) { sortPairwiseMenuItem_actionPerformed(); @@ -2328,7 +2330,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, && (fr = alignPanel.getFeatureRenderer()) != null) { - fr.setGroupVisibility((List)Arrays.asList(groups), state); + fr.setGroupVisibility(Arrays.asList(groups), state); alignPanel.seqPanel.seqCanvas.repaint(); if (alignPanel.overviewPanel != null) { @@ -3275,6 +3277,10 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, annotationColour.setLabel(MessageManager .getString("action.by_annotation")); annotationColour.addActionListener(this); + + annotationColumnSelection.setLabel("Select by Annotation"); + annotationColumnSelection.addActionListener(this); + invertSequenceMenuItem.setLabel(MessageManager .getString("action.invert_sequence_selection")); invertColSel.setLabel(MessageManager @@ -3463,6 +3469,7 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, selectMenu.add(unGroup); selectMenu.add(grpsFromSelection); selectMenu.add(deleteGroups); + selectMenu.add(annotationColumnSelection); } @@ -3477,6 +3484,8 @@ public class AlignFrame extends EmbmenuFrame implements ActionListener, MenuItem annotationColour = new MenuItem(); + MenuItem annotationColumnSelection = new MenuItem(); + MenuItem invertColSel = new MenuItem(); Menu menu1 = new Menu(); diff --git a/src/jalview/appletgui/AlignViewport.java b/src/jalview/appletgui/AlignViewport.java index 9a15e10..1767164 100644 --- a/src/jalview/appletgui/AlignViewport.java +++ b/src/jalview/appletgui/AlignViewport.java @@ -20,19 +20,23 @@ */ package jalview.appletgui; -import java.util.*; - -import java.awt.*; - -import jalview.analysis.*; +import jalview.analysis.NJTree; import jalview.api.AlignViewportI; -import jalview.bin.*; -import jalview.datamodel.*; -import jalview.schemes.*; +import jalview.bin.JalviewLite; +import jalview.datamodel.AlignmentI; +import jalview.datamodel.ColumnSelection; +import jalview.datamodel.Sequence; +import jalview.datamodel.SequenceGroup; +import jalview.datamodel.SequenceI; +import jalview.schemes.ColourSchemeProperty; +import jalview.schemes.UserColourScheme; import jalview.structure.SelectionSource; import jalview.structure.VamsasSource; import jalview.viewmodel.AlignmentViewport; +import java.awt.Font; +import java.util.Stack; + public class AlignViewport extends AlignmentViewport implements AlignViewportI, SelectionSource, VamsasSource { @@ -94,6 +98,8 @@ public class AlignViewport extends AlignmentViewport implements Stack redoList = new Stack(); + private AnnotationColumnChooser annotationColumnSelectionState; + public void finalize() { applet = null; @@ -648,4 +654,15 @@ public class AlignViewport extends AlignmentViewport implements return validCharWidth; } + public AnnotationColumnChooser getAnnotationColumnSelectionState() + { + return annotationColumnSelectionState; + } + + public void setAnnotationColumnSelectionState( + AnnotationColumnChooser annotationColumnSelectionState) + { + this.annotationColumnSelectionState = annotationColumnSelectionState; + } + } diff --git a/src/jalview/appletgui/AnnotationColourChooser.java b/src/jalview/appletgui/AnnotationColourChooser.java index c7b7c6c..cc2e530 100644 --- a/src/jalview/appletgui/AnnotationColourChooser.java +++ b/src/jalview/appletgui/AnnotationColourChooser.java @@ -20,15 +20,34 @@ */ package jalview.appletgui; -import java.util.*; - -import java.awt.*; -import java.awt.event.*; - -import jalview.datamodel.*; -import jalview.schemes.*; +import jalview.datamodel.SequenceGroup; +import jalview.schemes.AnnotationColourGradient; +import jalview.schemes.ColourSchemeI; import jalview.util.MessageManager; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Checkbox; +import java.awt.Choice; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Scrollbar; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.Hashtable; +import java.util.Vector; + public class AnnotationColourChooser extends Panel implements ActionListener, AdjustmentListener, ItemListener, MouseListener { @@ -104,9 +123,13 @@ public class AnnotationColourChooser extends Panel implements { String label = av.getAlignment().getAlignmentAnnotation()[i].label; if (!list.contains(label)) + { list.addElement(label); + } else + { list.addElement(label + "_" + (index++)); + } } for (int i = 0; i < list.size(); i++) @@ -137,7 +160,9 @@ public class AnnotationColourChooser extends Panel implements threshold.select(1); break; default: - throw new Error(MessageManager.getString("error.implementation_error_dont_know_thereshold_annotationcolourgradient")); + throw new Error( + MessageManager + .getString("error.implementation_error_dont_know_thereshold_annotationcolourgradient")); } thresholdIsMin.setState(acg.thresholdIsMinMax); thresholdValue.setText("" + acg.getAnnotationThreshold()); @@ -348,14 +373,14 @@ public class AnnotationColourChooser extends Panel implements { if (!adjusting) { - thresholdValue.setText(((float) slider.getValue() / 1000f) + ""); + thresholdValue.setText((slider.getValue() / 1000f) + ""); if (currentColours.getState() && !(av.getGlobalColourScheme() instanceof AnnotationColourGradient)) { changeColour(); } - currentAnnotation.threshold.value = (float) slider.getValue() / 1000f; + currentAnnotation.threshold.value = slider.getValue() / 1000f; ap.paintAlignment(false); } } diff --git a/src/jalview/appletgui/AnnotationColumnChooser.java b/src/jalview/appletgui/AnnotationColumnChooser.java new file mode 100644 index 0000000..496d4a4 --- /dev/null +++ b/src/jalview/appletgui/AnnotationColumnChooser.java @@ -0,0 +1,913 @@ +package jalview.appletgui; + +import jalview.datamodel.AlignmentAnnotation; +import jalview.datamodel.ColumnSelection; +import jalview.gui.JvSwingUtils; +import jalview.schemes.AnnotationColourGradient; +import jalview.util.MessageManager; +import jalview.viewmodel.annotationfilter.AnnotationFilterParameter; + +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Checkbox; +import java.awt.Choice; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.AdjustmentEvent; +import java.awt.event.AdjustmentListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.event.TextEvent; +import java.awt.event.TextListener; +import java.util.Iterator; +import java.util.Vector; + +import net.miginfocom.swing.MigLayout; + +public class AnnotationColumnChooser extends AnnotationRowFilter implements + ActionListener, AdjustmentListener, ItemListener, MouseListener +{ + + private Choice annotations = new Choice(); + + private Panel actionPanel = new Panel(); + + private TitledPanel thresholdPanel = new TitledPanel(); + + private Panel switchableViewsPanel = new Panel(new CardLayout()); + + private CardLayout switchableViewsLayout = (CardLayout) (switchableViewsPanel + .getLayout()); + + private Panel noGraphFilterView = new Panel(); + + private Panel graphFilterView = new Panel(); + + private Panel annotationComboBoxPanel = new Panel(); + + private BorderLayout borderLayout1 = new BorderLayout(); + + private Choice threshold = new Choice(); + + private StructureFilterPanel gStructureFilterPanel; + + private StructureFilterPanel ngStructureFilterPanel; + + private StructureFilterPanel currentStructureFilterPanel; + + private SearchPanel currentSearchPanel; + + private SearchPanel gSearchPanel; + + private SearchPanel ngSearchPanel; + + private FurtherActionPanel currentFurtherActionPanel; + + private FurtherActionPanel gFurtherActionPanel; + + private FurtherActionPanel ngFurtherActionPanel; + + public static final int ACTION_OPTION_SELECT = 1; + + public static int ACTION_OPTION_HIDE = 2; + + public static String NO_GRAPH_VIEW = "0"; + + public static String GRAPH_VIEW = "1"; + + private int actionOption = ACTION_OPTION_SELECT; + + private ColumnSelection oldColumnSelection; + + public AnnotationColumnChooser() + { + try + { + jbInit(); + } catch (Exception ex) + { + ex.printStackTrace(); + } + } + + public AnnotationColumnChooser(AlignViewport av, final AlignmentPanel ap) + { + super(av, ap); + frame = new Frame(); + frame.add(this); + jalview.bin.JalviewLite.addFrame(frame, + MessageManager.getString("label.select_by_annotation"), 520, + 215); + + slider.addAdjustmentListener(this); + slider.addMouseListener(this); + + if (av.getAlignment().getAlignmentAnnotation() == null) + { + return; + } + setOldColumnSelection(av.getColumnSelection()); + adjusting = true; + Vector list = new Vector(); + int index = 1; + for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++) + { + String label = av.getAlignment().getAlignmentAnnotation()[i].label; + if (!list.contains(label)) + { + list.addElement(label); + } + else + { + list.addElement(label + "_" + (index++)); + } + } + + for (int i = 0; i < list.size(); i++) + { + annotations.addItem(list.elementAt(i).toString()); + } + + populateThresholdComboBox(threshold); + + // restore Object state from the previous session if one exists + if (av.getAnnotationColumnSelectionState() != null) + { + currentSearchPanel = av.getAnnotationColumnSelectionState() + .getCurrentSearchPanel(); + currentStructureFilterPanel = av.getAnnotationColumnSelectionState() + .getCurrentStructureFilterPanel(); + annotations.select(av.getAnnotationColumnSelectionState() + .getAnnotations().getSelectedIndex()); + threshold.select(av.getAnnotationColumnSelectionState() + .getThreshold().getSelectedIndex()); + actionOption = av.getAnnotationColumnSelectionState() + .getActionOption(); + } + + try + { + jbInit(); + } catch (Exception ex) + { + } + adjusting = false; + + updateView(); + frame.invalidate(); + frame.pack(); + } + + private void jbInit() throws Exception + { + ok.setLabel(MessageManager.getString("action.ok")); + + cancel.setLabel(MessageManager.getString("action.cancel")); + + thresholdValue.setEnabled(false); + thresholdValue.setColumns(7); + + ok.addActionListener(this); + cancel.addActionListener(this); + annotations.addItemListener(this); + thresholdValue.addActionListener(this); + threshold.addItemListener(this); + + slider.setBackground(Color.white); + slider.setEnabled(false); + slider.setPreferredSize(new Dimension(100, 32)); + + thresholdPanel.setBackground(Color.white); + thresholdPanel.setFont(JvSwingUtils.getLabelFont()); + thresholdPanel.setLayout(new MigLayout("", "[left][right]", "[][]")); + + actionPanel.setBackground(Color.white); + actionPanel.setFont(JvSwingUtils.getLabelFont()); + + graphFilterView.setLayout(new MigLayout("", "[left][right]", "[][]")); + graphFilterView.setBackground(Color.white); + + noGraphFilterView.setLayout(new MigLayout("", "[left][right]", "[][]")); + noGraphFilterView.setBackground(Color.white); + + annotationComboBoxPanel.setBackground(Color.white); + annotationComboBoxPanel.setFont(JvSwingUtils.getLabelFont()); + + gSearchPanel = new SearchPanel(this); + ngSearchPanel = new SearchPanel(this); + gFurtherActionPanel = new FurtherActionPanel(this); + ngFurtherActionPanel = new FurtherActionPanel(this); + gStructureFilterPanel = new StructureFilterPanel(this); + ngStructureFilterPanel = new StructureFilterPanel(this); + + thresholdPanel.setTitle("Threshold Filter"); + thresholdPanel.add(getThreshold(), "grow"); + thresholdPanel.add(thresholdValue, "grow, wrap"); + thresholdPanel.add(slider, "grow, span, wrap"); + + actionPanel.add(ok); + actionPanel.add(cancel); + + graphFilterView.add(gSearchPanel, "grow, span, wrap"); + graphFilterView.add(gStructureFilterPanel, "grow, span, wrap"); + graphFilterView.add(thresholdPanel, "grow, span, wrap"); + graphFilterView.add(gFurtherActionPanel); + + noGraphFilterView.add(ngSearchPanel, "grow, span, wrap"); + noGraphFilterView.add(ngStructureFilterPanel, "grow, span, wrap"); + noGraphFilterView.add(ngFurtherActionPanel); + + annotationComboBoxPanel.add(getAnnotations()); + switchableViewsPanel.add(noGraphFilterView, + AnnotationColumnChooser.NO_GRAPH_VIEW); + switchableViewsPanel.add(graphFilterView, + AnnotationColumnChooser.GRAPH_VIEW); + + this.setLayout(borderLayout1); + this.add(annotationComboBoxPanel, java.awt.BorderLayout.PAGE_START); + this.add(switchableViewsPanel, java.awt.BorderLayout.CENTER); + this.add(actionPanel, java.awt.BorderLayout.SOUTH); + + selectedAnnotationChanged(); + this.validate(); + } + + @SuppressWarnings("unchecked") + public void reset() + { + if (this.getOldColumnSelection() != null) + { + av.getColumnSelection().clear(); + + if (av.getAnnotationColumnSelectionState() != null) + { + ColumnSelection oldSelection = av + .getAnnotationColumnSelectionState() + .getOldColumnSelection(); + if (oldSelection != null && oldSelection.getHiddenColumns() != null + && !oldSelection.getHiddenColumns().isEmpty()) + { + for (Iterator itr = oldSelection.getHiddenColumns() + .iterator(); itr.hasNext();) + { + int positions[] = itr.next(); + av.hideColumns(positions[0], positions[1]); + } + } + av.setColumnSelection(oldSelection); + } + ap.paintAlignment(true); + } + + } + + public void adjustmentValueChanged(AdjustmentEvent evt) + { + if (!adjusting) + { + thresholdValue.setText((slider.getValue() / 1000f) + ""); + valueChanged(!sliderDragging); + } + } + + protected void addSliderMouseListeners() + { + + slider.addMouseListener(new MouseAdapter() + { + @Override + public void mousePressed(MouseEvent e) + { + sliderDragging = true; + super.mousePressed(e); + } + + @Override + public void mouseDragged(MouseEvent e) + { + sliderDragging = true; + super.mouseDragged(e); + } + + @Override + public void mouseReleased(MouseEvent evt) + { + if (sliderDragging) + { + sliderDragging = false; + valueChanged(true); + } + ap.paintAlignment(true); + } + }); + } + + public void valueChanged(boolean updateAllAnnotation) + { + if (slider.isEnabled()) + { + getCurrentAnnotation().threshold.value = slider.getValue() / 1000f; + updateView(); + ap.paintAlignment(false); + } + } + + public Choice getThreshold() + { + return threshold; + } + + public void setThreshold(Choice threshold) + { + this.threshold = threshold; + } + + public Choice getAnnotations() + { + return annotations; + } + + public void setAnnotations(Choice annotations) + { + this.annotations = annotations; + } + + @Override + public void updateView() + { + // Check if combobox is still adjusting + if (adjusting) + { + return; + } + + AnnotationFilterParameter filterParams = new AnnotationFilterParameter(); + setCurrentAnnotation(av.getAlignment().getAlignmentAnnotation()[getAnnotations() + .getSelectedIndex()]); + + int selectedThresholdItem = getSelectedThresholdItem(getThreshold() + .getSelectedIndex()); + + slider.setEnabled(true); + thresholdValue.setEnabled(true); + + if (selectedThresholdItem == AnnotationColourGradient.NO_THRESHOLD) + { + slider.setEnabled(false); + thresholdValue.setEnabled(false); + thresholdValue.setText(""); + // build filter params + } + else if (selectedThresholdItem != AnnotationColourGradient.NO_THRESHOLD) + { + if (getCurrentAnnotation().threshold == null) + { + getCurrentAnnotation() + .setThreshold( + new jalview.datamodel.GraphLine( + (getCurrentAnnotation().graphMax - getCurrentAnnotation().graphMin) / 2f, + "Threshold", Color.black)); + } + + adjusting = true; + float range = getCurrentAnnotation().graphMax * 1000 + - getCurrentAnnotation().graphMin * 1000; + + slider.setMinimum((int) (getCurrentAnnotation().graphMin * 1000)); + slider.setMaximum((int) (getCurrentAnnotation().graphMax * 1000)); + slider.setValue((int) (getCurrentAnnotation().threshold.value * 1000)); + thresholdValue.setText(getCurrentAnnotation().threshold.value + ""); + // slider.setMajorTickSpacing((int) (range / 10f)); + slider.setEnabled(true); + thresholdValue.setEnabled(true); + adjusting = false; + + // build filter params + filterParams + .setThresholdType(AnnotationFilterParameter.ThresholdType.NO_THRESHOLD); + if (getCurrentAnnotation().graph != AlignmentAnnotation.NO_GRAPH) + { + filterParams + .setThresholdValue(getCurrentAnnotation().threshold.value); + + if (selectedThresholdItem == AnnotationColourGradient.ABOVE_THRESHOLD) + { + filterParams + .setThresholdType(AnnotationFilterParameter.ThresholdType.ABOVE_THRESHOLD); + } + else if (selectedThresholdItem == AnnotationColourGradient.BELOW_THRESHOLD) + { + filterParams + .setThresholdType(AnnotationFilterParameter.ThresholdType.BELOW_THRESHOLD); + } + } + } + + if (currentStructureFilterPanel != null) + { + if (currentStructureFilterPanel.alphaHelix.getState()) + { + filterParams.setFilterAlphaHelix(true); + } + if (currentStructureFilterPanel.betaStrand.getState()) + { + filterParams.setFilterBetaSheet(true); + } + if (currentStructureFilterPanel.turn.getState()) + { + filterParams.setFilterTurn(true); + } + } + + if (currentSearchPanel != null) + { + + if (!currentSearchPanel.searchBox.getText().isEmpty()) + { + currentSearchPanel.description.setEnabled(true); + currentSearchPanel.displayName.setEnabled(true); + filterParams.setRegexString(currentSearchPanel.searchBox.getText()); + if (currentSearchPanel.displayName.getState()) + { + filterParams + .addRegexSearchField(AnnotationFilterParameter.SearchableAnnotationField.DISPLAY_STRING); + } + if (currentSearchPanel.description.getState()) + { + filterParams + .addRegexSearchField(AnnotationFilterParameter.SearchableAnnotationField.DESCRIPTION); + } + } + else + { + currentSearchPanel.description.setEnabled(false); + currentSearchPanel.displayName.setEnabled(false); + } + } + + av.getColumnSelection().filterAnnotations( + getCurrentAnnotation().annotations, filterParams); + + av.showAllHiddenColumns(); + if (getActionOption() == ACTION_OPTION_HIDE) + { + av.hideSelectedColumns(); + } + + filterParams = null; + av.setAnnotationColumnSelectionState(this); + ap.paintAlignment(true); + } + + public ColumnSelection getOldColumnSelection() + { + return oldColumnSelection; + } + + public void setOldColumnSelection(ColumnSelection currentColumnSelection) + { + if (currentColumnSelection != null) + { + this.oldColumnSelection = new ColumnSelection(currentColumnSelection); + } + } + + public FurtherActionPanel getCurrentFutherActionPanel() + { + return currentFurtherActionPanel; + } + + public void setCurrentFutherActionPanel( + FurtherActionPanel currentFutherActionPanel) + { + this.currentFurtherActionPanel = currentFutherActionPanel; + } + + public SearchPanel getCurrentSearchPanel() + { + return currentSearchPanel; + } + + public void setCurrentSearchPanel(SearchPanel currentSearchPanel) + { + this.currentSearchPanel = currentSearchPanel; + } + + public int getActionOption() + { + return actionOption; + } + + public void setActionOption(int actionOption) + { + this.actionOption = actionOption; + } + + public StructureFilterPanel getCurrentStructureFilterPanel() + { + return currentStructureFilterPanel; + } + + public void setCurrentStructureFilterPanel( + StructureFilterPanel currentStructureFilterPanel) + { + this.currentStructureFilterPanel = currentStructureFilterPanel; + } + + @Override + public void itemStateChanged(ItemEvent e) + { + if (e.getSource() == annotations) + { + selectedAnnotationChanged(); + } + else if (e.getSource() == threshold) + { + threshold_actionPerformed(null); + } + } + + public void selectedAnnotationChanged() + { + String currentView = AnnotationColumnChooser.NO_GRAPH_VIEW; + if (av.getAlignment().getAlignmentAnnotation()[getAnnotations() + .getSelectedIndex()].graph != AlignmentAnnotation.NO_GRAPH) + { + currentView = AnnotationColumnChooser.GRAPH_VIEW; + } + + gSearchPanel.syncState(); + gFurtherActionPanel.syncState(); + gStructureFilterPanel.syncState(); + + ngSearchPanel.syncState(); + ngFurtherActionPanel.syncState(); + ngStructureFilterPanel.syncState(); + + switchableViewsLayout.show(switchableViewsPanel, currentView); + updateView(); + } + + public class FurtherActionPanel extends Panel implements + ItemListener + { + private AnnotationColumnChooser aColChooser; + + private Choice furtherAction = new Choice(); + + public FurtherActionPanel(AnnotationColumnChooser aColChooser) + { + this.aColChooser = aColChooser; + furtherAction.addItem("Select"); + furtherAction.addItem("Hide"); + furtherAction.addItemListener(this); + syncState(); + + // this.setTitle("Filter Actions"); + // this.setFont(JvSwingUtils.getLabelFont()); + + this.add(furtherAction); + } + + public void syncState() + { + if (aColChooser.getActionOption() == AnnotationColumnChooser.ACTION_OPTION_HIDE) + { + furtherAction.select("Hide"); + } + else + { + furtherAction.select("Select"); + } + } + + @Override + public void itemStateChanged(ItemEvent e) + { + aColChooser.setCurrentFutherActionPanel(this); + if (furtherAction.getSelectedItem().equalsIgnoreCase("Select")) + { + setActionOption(ACTION_OPTION_SELECT); + updateView(); + } + else + { + setActionOption(ACTION_OPTION_HIDE); + updateView(); + } + + } + } + + public class StructureFilterPanel extends TitledPanel implements + ItemListener + { + private AnnotationColumnChooser aColChooser; + + private Checkbox alphaHelix = new Checkbox(); + + private Checkbox betaStrand = new Checkbox(); + + private Checkbox turn = new Checkbox(); + + private Checkbox all = new Checkbox(); + + public StructureFilterPanel(AnnotationColumnChooser aColChooser) + { + this.aColChooser = aColChooser; + + alphaHelix.setLabel(MessageManager.getString("label.alpha_helix")); + alphaHelix.setBackground(Color.white); + + alphaHelix.addItemListener(this); + + betaStrand.setLabel(MessageManager.getString("label.beta_strand")); + betaStrand.setBackground(Color.white); + betaStrand.addItemListener(this); + + turn.setLabel(MessageManager.getString("label.turn")); + turn.setBackground(Color.white); + turn.addItemListener(this); + + all.setLabel(MessageManager.getString("label.select_all")); + all.setBackground(Color.white); + all.addItemListener(this); + + this.setBackground(Color.white); + this.setTitle("Structure Filter"); + this.setFont(JvSwingUtils.getLabelFont()); + + this.add(all); + this.add(alphaHelix); + this.add(betaStrand); + this.add(turn); + } + + public void alphaHelix_actionPerformed() + { + updateSelectAllState(); + aColChooser.setCurrentStructureFilterPanel(this); + aColChooser.updateView(); + } + + public void betaStrand_actionPerformed() + { + updateSelectAllState(); + aColChooser.setCurrentStructureFilterPanel(this); + aColChooser.updateView(); + } + + public void turn_actionPerformed() + { + updateSelectAllState(); + aColChooser.setCurrentStructureFilterPanel(this); + aColChooser.updateView(); + } + + public void all_actionPerformed() + { + if (all.getState()) + { + alphaHelix.setState(true); + betaStrand.setState(true); + turn.setState(true); + } + else + { + alphaHelix.setState(false); + betaStrand.setState(false); + turn.setState(false); + } + aColChooser.setCurrentStructureFilterPanel(this); + aColChooser.updateView(); + } + + public void updateSelectAllState() + { + if (alphaHelix.getState() && betaStrand.getState() && turn.getState()) + { + all.setState(true); + } + else + { + all.setState(false); + } + } + + public void syncState() + { + StructureFilterPanel sfp = aColChooser + .getCurrentStructureFilterPanel(); + if (sfp != null) + { + alphaHelix.setState(sfp.alphaHelix.getState()); + betaStrand.setState(sfp.betaStrand.getState()); + turn.setState(sfp.turn.getState()); + if (sfp.all.getState()) + { + all.setState(true); + alphaHelix.setState(true); + betaStrand.setState(true); + turn.setState(true); + } + } + + } + + @Override + public void itemStateChanged(ItemEvent e) + { + if (e.getSource() == alphaHelix) + { + alphaHelix_actionPerformed(); + } + else if (e.getSource() == betaStrand) + { + betaStrand_actionPerformed(); + } + else if (e.getSource() == turn) + { + turn_actionPerformed(); + } + else if (e.getSource() == all) + { + all_actionPerformed(); + } + } + } + + public class SearchPanel extends TitledPanel implements ItemListener + { + private AnnotationColumnChooser aColChooser; + + private Checkbox displayName = new Checkbox(); + + private Checkbox description = new Checkbox(); + + private TextField searchBox = new TextField(10); + + public SearchPanel(AnnotationColumnChooser aColChooser) + { + + this.aColChooser = aColChooser; + searchBox.addTextListener(new TextListener() + { + + @Override + public void textValueChanged(TextEvent e) + { + searchStringAction(); + + } + + }); + + displayName.setLabel(MessageManager.getString("label.display_name")); + displayName.setEnabled(false); + displayName.addItemListener(this); + + description.setLabel(MessageManager.getString("label.description")); + description.setEnabled(false); + description.addItemListener(this); + this.setTitle("Search Filter"); + this.setFont(JvSwingUtils.getLabelFont()); + + syncState(); + this.add(searchBox); + this.add(displayName); + this.add(description); + } + + public void displayNameCheckboxAction() + { + aColChooser.setCurrentSearchPanel(this); + aColChooser.updateView(); + } + + public void discriptionCheckboxAction() + { + aColChooser.setCurrentSearchPanel(this); + aColChooser.updateView(); + } + + public void searchStringAction() + { + aColChooser.setCurrentSearchPanel(this); + aColChooser.updateView(); + } + + public void syncState() + { + SearchPanel sp = aColChooser.getCurrentSearchPanel(); + if (sp != null) + { + description.setEnabled(sp.description.isEnabled()); + description.setState(sp.description.getState()); + + displayName.setEnabled(sp.displayName.isEnabled()); + displayName.setState(sp.displayName.getState()); + + searchBox.setText(sp.searchBox.getText()); + } + } + + @Override + public void itemStateChanged(ItemEvent e) + { + if (e.getSource() == displayName) + { + displayNameCheckboxAction(); + } + else if (e.getSource() == description) + { + discriptionCheckboxAction(); + } + + } + } + + public void actionPerformed(ActionEvent evt) + { + if (evt.getSource() == thresholdValue) + { + try + { + float f = new Float(thresholdValue.getText()).floatValue(); + slider.setValue((int) (f * 1000)); + adjustmentValueChanged(null); + } catch (NumberFormatException ex) + { + } + } + + else if (evt.getSource() == ok) + { + ok_actionPerformed(null); + } + else if (evt.getSource() == cancel) + { + cancel_actionPerformed(null); + } + else if (evt.getSource() == thresholdValue) + { + thresholdValue_actionPerformed(null); + } + else + { + updateView(); + } + } + + @Override + public void mouseClicked(MouseEvent e) + { + // TODO Auto-generated method stub + + } + + @Override + public void mousePressed(MouseEvent e) + { + if (e.getSource() == slider) + { + updateView(); + } + + } + + @Override + public void mouseReleased(MouseEvent e) + { + if (e.getSource() == slider) + { + updateView(); + } + } + + @Override + public void mouseEntered(MouseEvent e) + { + if (e.getSource() == slider) + { + updateView(); + } + } + + @Override + public void mouseExited(MouseEvent e) + { + if (e.getSource() == slider) + { + updateView(); + } + } + +} diff --git a/src/jalview/appletgui/AnnotationRowFilter.java b/src/jalview/appletgui/AnnotationRowFilter.java new file mode 100644 index 0000000..8a0a44a --- /dev/null +++ b/src/jalview/appletgui/AnnotationRowFilter.java @@ -0,0 +1,198 @@ +package jalview.appletgui; + +import jalview.schemes.AnnotationColourGradient; +import jalview.util.MessageManager; + +import java.awt.Button; +import java.awt.Checkbox; +import java.awt.Choice; +import java.awt.Frame; +import java.awt.Panel; +import java.awt.Scrollbar; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.util.Vector; + + + +@SuppressWarnings("serial") +public abstract class AnnotationRowFilter extends Panel +{ + protected AlignViewport av; + + protected AlignmentPanel ap; + + protected int[] annmap; + + protected boolean enableSeqAss = false; + + private jalview.datamodel.AlignmentAnnotation currentAnnotation; + + protected boolean adjusting = false; + + protected Checkbox currentColours = new Checkbox(); + + protected Panel minColour = new Panel(); + + protected Panel maxColour = new Panel(); + + protected Checkbox seqAssociated = new Checkbox(); + + protected Checkbox thresholdIsMin = new Checkbox(); + + protected Scrollbar slider = new Scrollbar(Scrollbar.HORIZONTAL); + + protected TextField thresholdValue = new TextField(20); + + protected Frame frame; + + protected Button ok = new Button(); + + protected Button cancel = new Button(); + + /** + * enabled if the user is dragging the slider - try to keep updates to a + * minimun + */ + protected boolean sliderDragging = false; + + + public AnnotationRowFilter(AlignViewport av, final AlignmentPanel ap) + { + this.av = av; + this.ap = ap; + } + + public AnnotationRowFilter() + { + + } + + + public Vector getAnnotationItems(boolean isSeqAssociated) + { + Vector list = new Vector(); + int index = 1; + int[] anmap = new int[av.getAlignment().getAlignmentAnnotation().length]; + for (int i = 0; i < av.getAlignment().getAlignmentAnnotation().length; i++) + { + if (av.getAlignment().getAlignmentAnnotation()[i].sequenceRef == null) + { + if (isSeqAssociated) + { + continue; + } + } + else + { + enableSeqAss = true; + } + String label = av.getAlignment().getAlignmentAnnotation()[i].label; + if (!list.contains(label)) + { + anmap[list.size()] = i; + list.add(label); + + } + else + { + if (!isSeqAssociated) + { + anmap[list.size()] = i; + list.add(label + "_" + (index++)); + } + } + } + this.annmap = new int[list.size()]; + System.arraycopy(anmap, 0, this.annmap, 0, this.annmap.length); + return list; + } + + protected int getSelectedThresholdItem(int indexValue) + { + int selectedThresholdItem = -1; + if (indexValue == 1) + { + selectedThresholdItem = AnnotationColourGradient.ABOVE_THRESHOLD; + } + else if (indexValue == 2) + { + selectedThresholdItem = AnnotationColourGradient.BELOW_THRESHOLD; + } + return selectedThresholdItem; + } + + public void modelChanged() + { + seqAssociated.setEnabled(enableSeqAss); + } + + public void ok_actionPerformed(ActionEvent e) + { + updateView(); + frame.setVisible(false); + } + + public void cancel_actionPerformed(ActionEvent e) + { + reset(); + ap.paintAlignment(true); + frame.setVisible(false); + } + + public void thresholdCheck_actionPerformed(ActionEvent e) + { + updateView(); + } + + public void annotations_actionPerformed(ActionEvent e) + { + updateView(); + } + + public void threshold_actionPerformed(ActionEvent e) + { + updateView(); + } + + public void thresholdValue_actionPerformed(ActionEvent e) + { + try + { + float f = Float.parseFloat(thresholdValue.getText()); + slider.setValue((int) (f * 1000)); + updateView(); + } catch (NumberFormatException ex) + { + } + } + + + protected void populateThresholdComboBox(Choice threshold) + { + threshold.addItem(MessageManager + .getString("label.threshold_feature_no_thereshold")); + threshold.addItem(MessageManager + .getString("label.threshold_feature_above_thereshold")); + threshold.addItem(MessageManager + .getString("label.threshold_feature_below_thereshold")); + } + + + public jalview.datamodel.AlignmentAnnotation getCurrentAnnotation() + { + return currentAnnotation; + } + + public void setCurrentAnnotation( + jalview.datamodel.AlignmentAnnotation currentAnnotation) + { + this.currentAnnotation = currentAnnotation; + } + + public abstract void valueChanged(boolean updateAllAnnotation); + + public abstract void updateView(); + + public abstract void reset(); +} \ No newline at end of file diff --git a/src/jalview/appletgui/TitledPanel.java b/src/jalview/appletgui/TitledPanel.java new file mode 100644 index 0000000..1ae36f4 --- /dev/null +++ b/src/jalview/appletgui/TitledPanel.java @@ -0,0 +1,75 @@ +package jalview.appletgui; + +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.Insets; +import java.awt.Label; +import java.awt.Panel; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class TitledPanel extends Panel +{ + + private String title; + + private Insets insets = new Insets(10, 10, 10, 10); + + public TitledPanel() + { + this(""); + } + + public TitledPanel(String title) + { + this.setTitle(title); + } + + public Insets getInsets() + { + return insets; + } + + public void paint(Graphics g) + { + super.paint(g); + g.setColor(getForeground()); + g.drawRect(5, 5, getWidth() - 10, getHeight() - 10); + int width = g.getFontMetrics().stringWidth(getTitle()); + g.setColor(getBackground()); + g.fillRect(10, 0, width, 10); + g.setColor(getForeground()); + g.drawString(getTitle(), 10, 10); + } + + public static void main(String[] args) + { + Frame f = new Frame("TitledPanel Tester"); + + TitledPanel p = new TitledPanel("Title of Panel"); + p.add(new Label("Label 1")); + p.add(new Label("Label 2")); + p.add(new Label("Label 3")); + f.add(p); + + f.addWindowListener(new WindowAdapter() + { + public void windowClosing(WindowEvent e) + { + System.exit(0); + } + }); + f.setBounds(300, 300, 300, 300); + f.setVisible(true); + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } +} \ No newline at end of file diff --git a/src/jalview/controller/AlignViewController.java b/src/jalview/controller/AlignViewController.java index 7b42a30..4d734c7 100644 --- a/src/jalview/controller/AlignViewController.java +++ b/src/jalview/controller/AlignViewController.java @@ -28,15 +28,12 @@ import jalview.api.AlignmentViewPanel; import jalview.api.FeatureRenderer; import jalview.commands.OrderCommand; import jalview.datamodel.AlignmentI; -import jalview.datamodel.Annotation; import jalview.datamodel.ColumnSelection; import jalview.datamodel.SequenceCollectionI; import jalview.datamodel.SequenceFeature; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.util.MessageManager; -import jalview.viewmodel.annotationfilter.AnnotationFilterParameter; -import jalview.viewmodel.annotationfilter.AnnotationFilterParameter.SearchableAnnotationField; import java.awt.Color; import java.util.ArrayList; @@ -305,90 +302,7 @@ public class AlignViewController implements AlignViewControllerI } } - public static boolean filterAnnotations(Annotation[] annotations, - AnnotationFilterParameter filterParams, ColumnSelection cs) - { - cs.revealAllHiddenColumns(); - cs.clear(); - int count = 0; - do - { - if (annotations[count] != null) - { - - boolean itemMatched = false; - - if (filterParams.getThresholdType() == AnnotationFilterParameter.ThresholdType.ABOVE_THRESHOLD - && annotations[count].value > filterParams - .getThresholdValue()) - { - itemMatched = true; - } - if (filterParams.getThresholdType() == AnnotationFilterParameter.ThresholdType.BELOW_THRESHOLD - && annotations[count].value < filterParams - .getThresholdValue()) - { - itemMatched = true; - } - - if (filterParams.isFilterAlphaHelix() - && annotations[count].secondaryStructure == 'H') - { - itemMatched = true; - } - - if (filterParams.isFilterBetaSheet() - && annotations[count].secondaryStructure == 'E') - { - itemMatched = true; - } - - if (filterParams.isFilterTurn() - && annotations[count].secondaryStructure == 'S') - { - itemMatched = true; - } - String regexSearchString = filterParams.getRegexString(); - if (regexSearchString != null - && !filterParams.getRegexSearchFields().isEmpty()) - { - List fields = filterParams - .getRegexSearchFields(); - try - { - if (fields.contains(SearchableAnnotationField.DISPLAY_STRING) - && annotations[count].displayCharacter - .matches(regexSearchString)) - { - itemMatched = true; - } - } catch (java.util.regex.PatternSyntaxException pse) - { - if (annotations[count].displayCharacter - .equals(regexSearchString)) - { - itemMatched = true; - } - } - if (fields.contains(SearchableAnnotationField.DESCRIPTION) - && annotations[count].description != null - && annotations[count].description - .matches(regexSearchString)) - { - itemMatched = true; - } - } - - if (itemMatched) - { - cs.addElement(count); - } - } - count++; - } while (count < annotations.length); - return false; - } @Override public void sortAlignmentByFeatureDensity(String[] typ) diff --git a/src/jalview/datamodel/ColumnSelection.java b/src/jalview/datamodel/ColumnSelection.java index f414d13..93e03d1 100644 --- a/src/jalview/datamodel/ColumnSelection.java +++ b/src/jalview/datamodel/ColumnSelection.java @@ -21,6 +21,8 @@ package jalview.datamodel; import jalview.util.ShiftList; +import jalview.viewmodel.annotationfilter.AnnotationFilterParameter; +import jalview.viewmodel.annotationfilter.AnnotationFilterParameter.SearchableAnnotationField; import java.util.ArrayList; import java.util.Enumeration; @@ -1265,4 +1267,89 @@ public class ColumnSelection } } } + + public boolean filterAnnotations(Annotation[] annotations, + AnnotationFilterParameter filterParams) + { + this.revealAllHiddenColumns(); + this.clear(); + int count = 0; + do + { + if (annotations[count] != null) + { + + boolean itemMatched = false; + + if (filterParams.getThresholdType() == AnnotationFilterParameter.ThresholdType.ABOVE_THRESHOLD + && annotations[count].value >= filterParams + .getThresholdValue()) + { + itemMatched = true; + } + if (filterParams.getThresholdType() == AnnotationFilterParameter.ThresholdType.BELOW_THRESHOLD + && annotations[count].value <= filterParams + .getThresholdValue()) + { + itemMatched = true; + } + + if (filterParams.isFilterAlphaHelix() + && annotations[count].secondaryStructure == 'H') + { + itemMatched = true; + } + + if (filterParams.isFilterBetaSheet() + && annotations[count].secondaryStructure == 'E') + { + itemMatched = true; + } + + if (filterParams.isFilterTurn() + && annotations[count].secondaryStructure == 'S') + { + itemMatched = true; + } + + String regexSearchString = filterParams.getRegexString(); + if (regexSearchString != null + && !filterParams.getRegexSearchFields().isEmpty()) + { + List fields = filterParams + .getRegexSearchFields(); + try + { + if (fields.contains(SearchableAnnotationField.DISPLAY_STRING) + && annotations[count].displayCharacter + .matches(regexSearchString)) + { + itemMatched = true; + } + } catch (java.util.regex.PatternSyntaxException pse) + { + if (annotations[count].displayCharacter + .equals(regexSearchString)) + { + itemMatched = true; + } + } + if (fields.contains(SearchableAnnotationField.DESCRIPTION) + && annotations[count].description != null + && annotations[count].description + .matches(regexSearchString)) + { + itemMatched = true; + } + } + + if (itemMatched) + { + this.addElement(count); + } + } + count++; + } while (count < annotations.length); + return false; + } } diff --git a/src/jalview/gui/AnnotationColourChooser.java b/src/jalview/gui/AnnotationColourChooser.java index 3c6fd88..2ad0bd2 100644 --- a/src/jalview/gui/AnnotationColourChooser.java +++ b/src/jalview/gui/AnnotationColourChooser.java @@ -63,9 +63,6 @@ public class AnnotationColourChooser extends AnnotationRowFilter JButton defColours = new JButton(); - JButton ok = new JButton(); - - JButton cancel = new JButton(); JPanel jPanel1 = new JPanel(); diff --git a/src/jalview/gui/AnnotationColumnChooser.java b/src/jalview/gui/AnnotationColumnChooser.java index 9f3aa7b..00c4217 100644 --- a/src/jalview/gui/AnnotationColumnChooser.java +++ b/src/jalview/gui/AnnotationColumnChooser.java @@ -1,6 +1,5 @@ package jalview.gui; -import jalview.controller.AlignViewController; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.ColumnSelection; import jalview.schemes.AnnotationColourGradient; @@ -18,7 +17,6 @@ import java.awt.event.ItemListener; import java.util.Iterator; import javax.swing.ButtonGroup; -import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JInternalFrame; @@ -39,9 +37,9 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements private JComboBox annotations; - private JButton ok = new JButton(); - - private JButton cancel = new JButton(); + // private JButton ok = new JButton(); + // + // private JButton cancel = new JButton(); private JPanel actionPanel = new JPanel(); @@ -51,7 +49,6 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements private CardLayout switchableViewsLayout = (CardLayout) (switchableViewsPanel .getLayout()); - private JPanel noGraphFilterView = new JPanel(); private JPanel graphFilterView = new JPanel(); @@ -437,9 +434,8 @@ public class AnnotationColumnChooser extends AnnotationRowFilter implements } } - AlignViewController.filterAnnotations( - getCurrentAnnotation().annotations, filterParams, - av.getColumnSelection()); + av.getColumnSelection().filterAnnotations( + getCurrentAnnotation().annotations, filterParams); av.showAllHiddenColumns(); if (getActionOption() == ACTION_OPTION_HIDE) diff --git a/src/jalview/gui/AnnotationRowFilter.java b/src/jalview/gui/AnnotationRowFilter.java index c0eea38..21c91d8 100644 --- a/src/jalview/gui/AnnotationRowFilter.java +++ b/src/jalview/gui/AnnotationRowFilter.java @@ -11,6 +11,7 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.Vector; +import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JInternalFrame; @@ -50,6 +51,11 @@ public abstract class AnnotationRowFilter extends JPanel protected JTextField thresholdValue = new JTextField(20); protected JInternalFrame frame; + + protected JButton ok = new JButton(); + + protected JButton cancel = new JButton(); + /** * enabled if the user is dragging the slider - try to keep updates to a * minimun diff --git a/src/jalview/gui/JvSwingUtils.java b/src/jalview/gui/JvSwingUtils.java index c404e2f..b4e0e00 100644 --- a/src/jalview/gui/JvSwingUtils.java +++ b/src/jalview/gui/JvSwingUtils.java @@ -226,14 +226,10 @@ public final class JvSwingUtils setColorAndFont(comp); } - // public static void jvInitComponent(JComponent comp, String name){ - // setColorAndFont(comp); - // comp.setText(MessageManager.getString("label.select_all")); - // } - private static void setColorAndFont(JComponent comp) { comp.setBackground(Color.white); comp.setFont(JvSwingUtils.getLabelFont()); } + } -- 1.7.10.2