/******************************************************************************* * GenPlay, Einstein Genome Analyzer * Copyright (C) 2009, 2014 Albert Einstein College of Medicine * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * Authors: Julien Lajugie <julien.lajugie@einstein.yu.edu> * Nicolas Fourel <nicolas.fourel@einstein.yu.edu> * Eric Bouhassira <eric.bouhassira@einstein.yu.edu> * * Website: <http://genplay.einstein.yu.edu> ******************************************************************************/ package edu.yu.einstein.genplay.gui.dialog.multiGenomeDialog.MGProperties.filterDialog.idEditors; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import javax.swing.ButtonGroup; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JTextField; import edu.yu.einstein.genplay.core.multiGenome.VCF.VCFHeaderType.VCFHeaderBasicType; import edu.yu.einstein.genplay.core.multiGenome.VCF.VCFHeaderType.VCFHeaderType; import edu.yu.einstein.genplay.core.multiGenome.filter.VCFID.IDFilterInterface; import edu.yu.einstein.genplay.core.multiGenome.filter.VCFID.NumberIDFilter; import edu.yu.einstein.genplay.core.multiGenome.filter.VCFID.NumberIDFilterInterface; import edu.yu.einstein.genplay.core.multiGenome.filter.VCFID.QualFilter; import edu.yu.einstein.genplay.dataStructure.enums.ComparisonOperators; import edu.yu.einstein.genplay.dataStructure.enums.VCFColumnName; /** * @author Nicolas Fourel * @author Julien Lajugie */ public class IDNumberEditor implements IDEditor { private final static String VALUE_LABEL_TTT = "The data in the file."; private final static String INEQUATION_TTT = "Select an operator."; private final static String VALUE_JTF_TTT = "Constraint value."; private final static String AND_OPERATOR_TTT = "Both equation will have to be true in order to accept the VCF line."; private final static String OR_OPERATOR_TTT = "Only one equation will have to be true in order to accept the VCF line."; private JPanel panel; private VCFHeaderType header; // Header ID private JComboBox inequationBox01; // First inequation private JComboBox inequationBox02; // Second inequation private JTextField valueField01; // First value private JTextField valueField02; // Second value private JRadioButton andButton; // AND operator button private JRadioButton orButton; // OR operator button private boolean isSelectionValid; // return true if the current selection is valid, false otherwise /** * Checks if the current selection made by the user is valid and update the * {@link #isSelectionValid} property. Fire a property change event if the * property changes. */ private final void checkIfSelectionIsValid() { if (panel != null) { boolean newIsSelectionValid = true; // First value MUST be filed if (inequationBox01.isEnabled() && inequationBox01.getSelectedItem().toString().equals(" ")) { newIsSelectionValid = false; } try { Float.parseFloat(valueField01.getText()); } catch (Exception e) { newIsSelectionValid = false; } if (inequationBox02.isEnabled() && !inequationBox02.getSelectedItem().toString().equals(" ")) { //errors += "Second equation operator invalid\n"; try { Float.parseFloat(valueField02.getText()); } catch (Exception e) { newIsSelectionValid = false; } } if (newIsSelectionValid != isSelectionValid) { boolean oldIsSelectionValid = isSelectionValid; isSelectionValid = newIsSelectionValid; panel.firePropertyChange(IDEditor.IS_SELECTION_VALID_PROPERTY_NAME, oldIsSelectionValid, newIsSelectionValid); } } } /** * Initializes a box * @param box box to initialize */ private JComboBox getBox (JComboBox box) { DefaultComboBoxModel model = new DefaultComboBoxModel(); model.addElement(" "); model.addElement(ComparisonOperators.LESS); model.addElement(ComparisonOperators.LESS_OR_EQUAL); model.addElement(ComparisonOperators.EQUAL); model.addElement(ComparisonOperators.DIFFERENT); model.addElement(ComparisonOperators.GREATER); model.addElement(ComparisonOperators.GREATER_OR_EQUAL); box = new JComboBox(model); box.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { refreshBoxes(); } }); return box; } /** * Checks the validity and gets the selected operator of a combo box * @param comboBox the combo box * @return its operator, null if not valid (disabled box/empty selection */ private ComparisonOperators getComparisonOperators (JComboBox comboBox) { ComparisonOperators operator = null; if (comboBox.isEnabled() && (comboBox.getSelectedItem() != null) && !comboBox.getSelectedItem().equals(" ")) { operator = (ComparisonOperators) comboBox.getSelectedItem(); } return operator; } @Override public IDFilterInterface getFilter() { NumberIDFilterInterface filter = null; if ((header instanceof VCFHeaderBasicType) && (header.getColumnCategory() == VCFColumnName.QUAL)) { filter = new QualFilter(); } else { filter = new NumberIDFilter(); } filter.setHeaderType(header); if (inequationBox01.isEnabled() && !inequationBox01.getSelectedItem().equals(" ")){ filter.setInequation01((ComparisonOperators)inequationBox01.getSelectedItem()); try { filter.setValue01(Float.parseFloat(valueField01.getText())); } catch (Exception e) { filter.setValue01(null); } } if (inequationBox02.isEnabled() && !inequationBox02.getSelectedItem().toString().equals(" ")) { filter.setInequation02((ComparisonOperators)inequationBox02.getSelectedItem()); try { filter.setValue02(Float.parseFloat(valueField02.getText())); } catch (Exception e) { filter.setValue02(null); } } else { filter.setInequation02(null); filter.setValue02(null); } if (andButton.isSelected()) { filter.setCumulative(true); } else { filter.setCumulative(false); } return filter; } /** * Create and return a combo box model containing the full list of operators. * @return the full model of operator */ private DefaultComboBoxModel getFullModel () { DefaultComboBoxModel model = new DefaultComboBoxModel(); model.addElement(" "); model.addElement(ComparisonOperators.GREATER); model.addElement(ComparisonOperators.GREATER_OR_EQUAL); model.addElement(ComparisonOperators.LESS); model.addElement(ComparisonOperators.LESS_OR_EQUAL); model.addElement(ComparisonOperators.DIFFERENT); model.addElement(ComparisonOperators.EQUAL); return model; } @Override public VCFHeaderType getHeaderType () { return header; } /** * Create a panel that contain a "value" label, a combo box (inequation) and a text field to provide the value. * @param box the box to use * @param field the text field to use * @return the panel */ private JPanel getInequationPanel (JComboBox box, JTextField field) { JPanel panel = new JPanel(); JLabel valueLabel = new JLabel("Keep Values"); valueLabel.setToolTipText(VALUE_LABEL_TTT); // Layout settings GridBagLayout layout = new GridBagLayout(); panel.setLayout(layout); GridBagConstraints gbc = new GridBagConstraints(); gbc.anchor = GridBagConstraints.LINE_START; gbc.weightx = 1; gbc.weighty = 1; gbc.gridy = 0; // Label gbc.gridx = 0; panel.add(valueLabel, gbc); // Combobox gbc.gridx = 1; gbc.insets = new Insets(0, 10, 0, 0); panel.add(box, gbc); // Text field gbc.gridx = 2; gbc.weightx = 1; panel.add(field, gbc); // Return the panel return panel; } /** * Create and return a combo box model containing the full list of inferior operators and the different one. * @return the full model of operator */ private DefaultComboBoxModel getInferiorModel () { DefaultComboBoxModel model = new DefaultComboBoxModel(); model.addElement(" "); model.addElement(ComparisonOperators.LESS); model.addElement(ComparisonOperators.LESS_OR_EQUAL); model.addElement(ComparisonOperators.DIFFERENT); return model; } private JPanel getOperatorPanel () { JPanel panel = new JPanel(); // Initializes radio boxes andButton = new JRadioButton("And"); andButton.setSelected(true); andButton.setToolTipText(AND_OPERATOR_TTT); andButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { refreshBoxes(); } }); orButton = new JRadioButton("Or"); orButton.setToolTipText(OR_OPERATOR_TTT); orButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent arg0) { refreshBoxes(); } }); //Group the radio buttons. ButtonGroup group = new ButtonGroup(); group.add(andButton); group.add(orButton); // Layout settings GridBagLayout layout = new GridBagLayout(); panel.setLayout(layout); GridBagConstraints gbc = new GridBagConstraints(); gbc.anchor = GridBagConstraints.FIRST_LINE_START; gbc.weightx = 0; gbc.weighty = 0; gbc.gridy = 0; // AND radio button gbc.gridx = 0; gbc.insets = new Insets(0, 0, 0, 0); panel.add(andButton, gbc); // OR radio button gbc.gridx = 1; gbc.insets = new Insets(0, 20, 0, 0); panel.add(orButton, gbc); checkIfSelectionIsValid(); // Return the panel return panel; } /** * Create and return a combo box model containing the list of superior operators and the different one. * @return the full model of operator */ private DefaultComboBoxModel getSuperiorModel () { DefaultComboBoxModel model = new DefaultComboBoxModel(); model.addElement(" "); model.addElement(ComparisonOperators.GREATER); model.addElement(ComparisonOperators.GREATER_OR_EQUAL); model.addElement(ComparisonOperators.DIFFERENT); return model; } /** * Initializes a text field * @param box text field to initialize */ private JTextField getTextField (JTextField field) { field = new JTextField(); field.addKeyListener(new KeyAdapter() { @Override public void keyReleased(KeyEvent e) { checkIfSelectionIsValid(); } }); return field; } @Override public void initializesPanel(IDFilterInterface filter) { ComparisonOperators inequation01 = null; ComparisonOperators inequation02 = null; Float value01 = null; Float value02 = null; NumberIDFilterInterface castFilter = (NumberIDFilterInterface) filter; inequation01 = castFilter.getInequation01(); inequation02 = castFilter.getInequation02(); value01 = castFilter.getValue01(); value02 = castFilter.getValue02(); if (castFilter.isCumulative()) { andButton.setSelected(true); } else { orButton.setSelected(true); } inequationBox01.setSelectedItem(inequation01); valueField01.setText(value01.toString()); if ((inequation02 != null) && (value02 != null)) { inequationBox02.setSelectedItem(inequation02); valueField02.setText(value02.toString()); } else { inequationBox02.setSelectedIndex(0); valueField02.setText(""); } checkIfSelectionIsValid(); } @Override public boolean isSelectionValid() { return isSelectionValid; } @Override public boolean isVisible() { return panel.isVisible(); } /** * Refreshes the combo boxes according to their content and the "and" / "or" radio buttons. * A superior operator in a box will involve inferior operators in the second box. * The equal operator in the first box with the "and" box selected will disable the second box. * ... */ private void refreshBoxes () { ComparisonOperators operator01 = getComparisonOperators(inequationBox01); ComparisonOperators operator02 = getComparisonOperators(inequationBox02); if (operator01 == null){ inequationBox01.setModel(getFullModel()); inequationBox02.setEnabled(false); valueField02.setEnabled(false); } else { if (operator01.equals(ComparisonOperators.EQUAL)) { if (andButton.isSelected()) { inequationBox02.setEnabled(false); valueField02.setEnabled(false); } else { inequationBox02.setEnabled(true); valueField02.setEnabled(true); inequationBox02.setModel(getFullModel()); } } else { inequationBox02.setEnabled(true); valueField02.setEnabled(true); if ((operator01 == ComparisonOperators.GREATER) || (operator01 == ComparisonOperators.GREATER_OR_EQUAL)) { inequationBox02.setModel(getInferiorModel()); } else if ((operator01 == ComparisonOperators.LESS) || (operator01 == ComparisonOperators.LESS_OR_EQUAL)) { inequationBox02.setModel(getSuperiorModel()); } else { inequationBox02.setModel(getFullModel()); } if (orButton.isSelected()) { ((DefaultComboBoxModel)(inequationBox02.getModel())).addElement(ComparisonOperators.EQUAL); } } setSelectedItemInBox(inequationBox02, operator02); } checkIfSelectionIsValid(); } @Override public void setHeaderType(VCFHeaderType id) { header = id; } /** * Set an operator in a combo box, if the operator does not exist, the first value is selected. * @param comboBox the combo box * @param operator the operator */ private void setSelectedItemInBox (JComboBox comboBox, ComparisonOperators operator) { boolean found = false; if (operator != null) { DefaultComboBoxModel model = ((DefaultComboBoxModel)(inequationBox02.getModel())); if (model.getIndexOf(operator) >= 0) { found = true; } } if (found) { comboBox.setSelectedItem(operator); } else { comboBox.setSelectedIndex(0); } } @Override public void setVisible(boolean b) { if (panel != null) { panel.setVisible(b); } } @Override public JPanel updatePanel() { panel = new JPanel(); // Initializes boxes inequationBox01 = getBox(inequationBox01); inequationBox01.setToolTipText(INEQUATION_TTT); inequationBox02 = getBox(inequationBox02); inequationBox02.setToolTipText(INEQUATION_TTT); // Initializes text fields valueField01 = getTextField(valueField01); valueField01.setToolTipText(VALUE_JTF_TTT); valueField01.setColumns(8); valueField02 = getTextField(valueField02); valueField02.setToolTipText(VALUE_JTF_TTT); valueField02.setColumns(8); // Default setting inequationBox02.setEnabled(false); valueField02.setEnabled(false); // Layout settings GridBagLayout layout = new GridBagLayout(); panel.setLayout(layout); GridBagConstraints gbc = new GridBagConstraints(); gbc.anchor = GridBagConstraints.FIRST_LINE_START; gbc.weightx = 1; gbc.weighty = 1; // First inequation gbc.gridx = 0; gbc.gridy = 0; gbc.insets = new Insets(0, 10, 0, 0); panel.add(getInequationPanel(inequationBox01, valueField01), gbc); // Operators gbc.gridy++; gbc.insets = new Insets(10, 0, 10, 0); panel.add(getOperatorPanel(), gbc); // Second inequation gbc.gridy++; gbc.insets = new Insets(0, 10, 0, 0); panel.add(getInequationPanel(inequationBox02, valueField02), gbc); checkIfSelectionIsValid(); return panel; } }