/* * #%L * gitools-ui-app * %% * Copyright (C) 2013 Universitat Pompeu Fabra - Biomedical Genomics group * %% * 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/gpl-3.0.html>. * #L% */ package org.gitools.ui.app.dialog.filter; import org.gitools.api.matrix.IMatrixLayer; import org.gitools.api.matrix.IMatrixLayers; import org.gitools.api.matrix.MatrixDimensionKey; import org.gitools.matrix.filter.ValueFilterFunction; import org.gitools.ui.platform.dialog.MessageStatus; import org.gitools.ui.platform.wizard.AbstractWizardPage; import org.gitools.utils.cutoffcmp.CutoffCmp; import javax.swing.*; import javax.swing.event.*; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumnModel; import java.awt.*; import java.util.List; /** * @noinspection ALL */ public class ValueFilterPage extends AbstractWizardPage { /** * A return status code - returned if Cancel button has been pressed */ private static final int RET_CANCEL = 0; /** * A return status code - returned if OK button has been pressed */ public static final int RET_OK = 1; private final IMatrixLayer visibleLayer; private static class ComboBoxCellRenderer extends JComboBox implements TableCellRenderer { public ComboBoxCellRenderer(Object[] values) { super(values); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (isSelected) { setForeground(table.getSelectionForeground()); super.setBackground(table.getSelectionBackground()); } else { setForeground(table.getForeground()); setBackground(table.getBackground()); } // Select the current value setSelectedItem(value); return this; } } private static class ComboBoxCellEditor extends DefaultCellEditor { public ComboBoxCellEditor(Object[] values) { super(new JComboBox(values)); } } private final IMatrixLayers layers; private final CutoffCmp[] comparators; private final ValueFilterCriteriaTableModel criteriaModel; /** * Creates new form FilterDialog */ public ValueFilterPage(Frame parent, IMatrixLayers layers, MatrixDimensionKey dimension, CutoffCmp[] comparators, List<ValueFilterFunction> initialCriteriaList, IMatrixLayer visibleLayer) { this.layers = layers; this.comparators = comparators; this.visibleLayer = visibleLayer; this.criteriaModel = new ValueFilterCriteriaTableModel(layers); initComponents(); if (dimension.equals(MatrixDimensionKey.COLUMNS)) { applyToColumnsRb.setSelected(true); } else if (dimension.equals(MatrixDimensionKey.ROWS)) { applyToRowsRb.setSelected(true); } table.setModel(criteriaModel); criteriaModel.addTableModelListener(new TableModelListener() { @Override public void tableChanged(TableModelEvent e) { tableRemoveBtn.setEnabled(criteriaModel.getList().size() > 0); updateFilterDescription(); } }); if (initialCriteriaList != null) { criteriaModel.addAllCriteria(initialCriteriaList); } CellEditorListener cellEditorListener = new CellEditorListener() { /** * This tells the listeners the editor has ended editing */ @Override public void editingStopped(ChangeEvent e) { updateFilterDescription(); } /** * This tells the listeners the editor has canceled editing */ @Override public void editingCanceled(ChangeEvent e) { updateFilterDescription(); } }; TableColumnModel columnModel = table.getColumnModel(); columnModel.getColumn(0).setCellEditor(new ComboBoxCellEditor(layers.getIds())); columnModel.getColumn(0).getCellEditor().addCellEditorListener(cellEditorListener); columnModel.getColumn(1).setCellEditor(new ComboBoxCellEditor(comparators)); columnModel.getColumn(1).getCellEditor().addCellEditorListener(cellEditorListener); columnModel.getColumn(2).setCellEditor(new DefaultCellEditor(new JTextField())); columnModel.getColumn(2).getCellEditor().addCellEditorListener(cellEditorListener); ChangeListener changeListener = new ChangeListener() { /** * Invoked when the target of the listener has changed its state. * * @param e a ChangeEvent object */ @Override public void stateChanged(ChangeEvent e) { updateFilterDescription(); } }; allCriteriaCheck.addChangeListener(changeListener); allElementsCheck.addChangeListener(changeListener); hideMatchingCheck.addChangeListener(changeListener); applyToRowsAndColumnsRb.addChangeListener(changeListener); applyToColumnsRb.addChangeListener(changeListener); applyToRowsRb.addChangeListener(changeListener); setTitle("Filter by values"); updateFilterDescription(); } /** * @return the return status of this dialog - one of RET_OK or RET_CANCEL */ public int getReturnStatus() { return returnStatus; } private void updateFilterDescription() { StringBuilder sb = new StringBuilder(); sb.append(isHideMatching() ? "<html><b>Hide</b> all " : "<html><b>Keep</b> all "); if (!isApplyToRows()) { sb.append("columns "); allElementsCheck.setText("All values in a column must match"); } else if (!isApplyToColumns()) { sb.append("rows "); allElementsCheck.setText("All values in a row must match"); } else { sb.append("rows and columns "); allElementsCheck.setText("All values in a row/columns must match"); } sb.append("where "); sb.append(isAllElementsMatch() ? "all elements have " : "at least 1 element has "); //list all criterias sb.append("<ul>"); for (ValueFilterFunction c : getCriteriaList()) { sb.append("<li>"); sb.append(c.getLayerId()); sb.append(" "); sb.append(c.getComparator().getLongName()); sb.append(" "); sb.append(c.getCutoffValue()); sb.append(" "); if (getCriteriaList().size() - 1 > getCriteriaList().indexOf(c)) { sb.append(isAllCriteriaMatch() ? "and " : "or "); } sb.append("</li>"); } sb.append("</ul></html>"); setMessage(MessageStatus.WARN, sb.toString()); updateComplete(); } private void updateComplete() { setComplete(getCriteriaList().size() > 0); } /** * This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { applyToGroup = new javax.swing.ButtonGroup(); jScrollPane1 = new javax.swing.JScrollPane(); table = new javax.swing.JTable(); tableAddBtn = new javax.swing.JButton(); tableRemoveBtn = new javax.swing.JButton(); allCriteriaCheck = new javax.swing.JCheckBox(); allElementsCheck = new javax.swing.JCheckBox(); hideMatchingCheck = new javax.swing.JCheckBox(); loadBtn = new javax.swing.JButton(); saveBtn = new javax.swing.JButton(); applyToRowsRb = new javax.swing.JRadioButton(); jLabel2 = new javax.swing.JLabel(); applyToRowsAndColumnsRb = new javax.swing.JRadioButton(); applyToColumnsRb = new javax.swing.JRadioButton(); table.setModel(new javax.swing.table.DefaultTableModel( new Object[][]{ }, new String[]{ "Value Dimension", "Condition", "Cell Value" } ) { Class[] types = new Class[]{ java.lang.String.class, java.lang.Object.class, java.lang.Double.class }; public Class getColumnClass(int columnIndex) { return types[columnIndex]; } }); table.setColumnSelectionAllowed(true); jScrollPane1.setViewportView(table); table.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_INTERVAL_SELECTION); tableAddBtn.setText("Add"); tableAddBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { tableAddBtnActionPerformed(evt); } }); tableRemoveBtn.setText("Remove"); tableRemoveBtn.setEnabled(false); tableRemoveBtn.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { tableRemoveBtnActionPerformed(evt); } }); allCriteriaCheck.setText("All of the above criteria should match"); allElementsCheck.setText("All values should match"); hideMatchingCheck.setText("Hide matching (Hide unmatching otherwise)"); loadBtn.setText("Load..."); loadBtn.setEnabled(false); saveBtn.setText("Save..."); saveBtn.setEnabled(false); applyToGroup.add(applyToRowsRb); applyToRowsRb.setSelected(true); applyToRowsRb.setText("rows"); jLabel2.setText("Apply to:"); applyToGroup.add(applyToRowsAndColumnsRb); applyToRowsAndColumnsRb.setText("rows and columns"); applyToGroup.add(applyToColumnsRb); applyToColumnsRb.setText("columns"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 481, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) .addComponent(saveBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(loadBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(tableAddBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(tableRemoveBtn, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(applyToRowsRb) .addComponent(applyToColumnsRb) .addComponent(applyToRowsAndColumnsRb) .addComponent(jLabel2) .addComponent(allCriteriaCheck) .addComponent(allElementsCheck) .addComponent(hideMatchingCheck)) .addGap(0, 0, Short.MAX_VALUE))) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addComponent(tableAddBtn) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(tableRemoveBtn) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(loadBtn) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(saveBtn)) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 177, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(allCriteriaCheck) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(allElementsCheck) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(hideMatchingCheck) .addGap(18, 18, 18) .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(applyToRowsRb) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(applyToColumnsRb) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(applyToRowsAndColumnsRb) .addContainerGap()) ); }// </editor-fold>//GEN-END:initComponents private void tableAddBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tableAddBtnActionPerformed criteriaModel.addCriteria(new ValueFilterFunction(visibleLayer, comparators[0], 0.0, null)); updateFilterDescription(); }//GEN-LAST:event_tableAddBtnActionPerformed private void tableRemoveBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_tableRemoveBtnActionPerformed criteriaModel.removeCriteria(table.getSelectedRows()); updateFilterDescription(); }//GEN-LAST:event_tableRemoveBtnActionPerformed // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JCheckBox allCriteriaCheck; private javax.swing.JCheckBox allElementsCheck; private javax.swing.JRadioButton applyToColumnsRb; private javax.swing.ButtonGroup applyToGroup; private javax.swing.JRadioButton applyToRowsAndColumnsRb; private javax.swing.JRadioButton applyToRowsRb; private javax.swing.JCheckBox hideMatchingCheck; private javax.swing.JLabel jLabel2; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JButton loadBtn; private javax.swing.JButton saveBtn; private javax.swing.JTable table; private javax.swing.JButton tableAddBtn; private javax.swing.JButton tableRemoveBtn; // End of variables declaration//GEN-END:variables private int returnStatus = RET_CANCEL; public boolean isApplyToRows() { return applyToRowsRb.isSelected() || applyToRowsAndColumnsRb.isSelected(); } public boolean isApplyToColumns() { return applyToColumnsRb.isSelected() || applyToRowsAndColumnsRb.isSelected(); } public boolean isAllCriteriaMatch() { return allCriteriaCheck.isSelected(); } public boolean isAllElementsMatch() { return allElementsCheck.isSelected(); } public boolean isHideMatching() { return hideMatchingCheck.isSelected(); } public List<ValueFilterFunction> getCriteriaList() { return criteriaModel.getList(); } }