/*
* #%L
* org.gitools.ui.app
* %%
* Copyright (C) 2013 - 2014 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.plugins.mutex.ui;
import com.google.common.base.Function;
import com.jgoodies.binding.adapter.ComboBoxAdapter;
import com.jgoodies.binding.beans.PropertyAdapter;
import com.jgoodies.binding.list.SelectionInList;
import org.gitools.api.matrix.IMatrixDimension;
import org.gitools.api.matrix.MatrixDimensionKey;
import org.gitools.heatmap.Heatmap;
import org.gitools.heatmap.HeatmapDimension;
import org.gitools.heatmap.decorator.impl.NonEventToNullFunction;
import org.gitools.matrix.filter.PatternFunction;
import org.gitools.ui.core.Application;
import org.gitools.ui.core.pages.common.PatternSourcePage;
import org.gitools.ui.core.utils.DocumentChangeListener;
import org.gitools.ui.core.utils.FileChooserUtils;
import org.gitools.ui.platform.dialog.ExceptionGlassPane;
import org.gitools.ui.platform.settings.Settings;
import org.gitools.ui.platform.wizard.AbstractWizardPage;
import org.gitools.ui.platform.wizard.PageDialog;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static com.google.common.base.Predicates.in;
import static com.google.common.base.Predicates.not;
import static com.google.common.collect.Iterables.filter;
import static com.google.common.collect.Iterables.transform;
import static com.google.common.collect.Lists.newArrayList;
public class MutualExclusiveSortPage extends AbstractWizardPage {
private JPanel rootPanel;
private JTextField patternsField;
private JButton patternButton;
private JTextArea patternsArea;
private JButton loadButton;
private JButton saveButton;
private JButton pasteSelectedButton;
private JButton pasteUnselectedButton;
private JCheckBox useRegexCheck;
private JCheckBox performTest;
private JComboBox eventsFunctionComboBox;
private JLabel eventsFunctionDescription;
private JLabel testDescription;
private final Heatmap hm;
private final MatrixDimensionKey sortDimension;
private String pattern;
public MutualExclusiveSortPage(Heatmap hm, MatrixDimensionKey sortDimension) {
super();
patternsArea.getDocument().addDocumentListener(new DocumentChangeListener() {
@Override
protected void update(DocumentEvent e) {
saveButton.setEnabled(patternsArea.getDocument().getLength() > 0);
}
});
pattern = "${id}";
patternsField.setText("id");
setTitle("Sort by mutual exclusion");
setMessage("Puts the selected rows/columns at the top of the matrix and " + "sorts them by their mutual exclusion.");
setComplete(true);
loadButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
loadBtnAction();
}
});
saveButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
saveBtnAction();
}
});
pasteSelectedButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setValues(getSelected());
}
});
pasteUnselectedButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setValues(getUnselected());
}
});
patternButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
changePatternAction();
}
});
this.hm = hm;
this.sortDimension = sortDimension;
eventsFunctionComboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
updateEventDescription();
}
});
eventsFunctionComboBox.setModel(
new ComboBoxAdapter<>(
new SelectionInList<NonEventToNullFunction>(
hm.getLayers().getTopLayer().getDecorator().getEventFunctionAlternatives(),
new PropertyAdapter<>(hm.getLayers().getTopLayer(), "eventFunction")
)
)
);
updateEventDescription();
IMatrixDimension dimension = hm.getContents().getDimension(sortDimension);
testDescription.setText("All " + dimension.size() + " " + dimension.getId().getLabel() + "s will be taken into account " +
"for a weighted permutation test to assess probability of mutual exclusion and co-occurence");
}
private void updateEventDescription() {
if (eventsFunctionDescription!=null && eventsFunctionComboBox.getSelectedItem() != null) {
eventsFunctionDescription.setText(((NonEventToNullFunction) eventsFunctionComboBox.getSelectedItem()).getDescription());
}
}
private void saveBtnAction() {
try {
File file = FileChooserUtils.selectFile("Select file name ...", Settings.get().getLastFilterPath(), FileChooserUtils.MODE_SAVE).getFile();
if (file == null) {
return;
}
Settings.get().setLastFilterPath(file.getParent());
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
bw.append(patternsArea.getText()).append('\n');
bw.close();
} catch (Exception ex) {
ExceptionGlassPane edlg = new ExceptionGlassPane(Application.get(), ex);
edlg.setVisible(true);
}
}
public boolean performTest() {
return performTest.isSelected();
}
@Override
public JComponent createControls() {
return rootPanel;
}
private void loadBtnAction() {
try {
File file = FileChooserUtils.selectFile("Select the file containing values", Settings.get().getLastFilterPath(), FileChooserUtils.MODE_OPEN).getFile();
if (file == null) {
return;
}
Settings.get().setLastFilterPath(file.getParent());
patternsArea.setText(readNamesFromFile(file));
} catch (IOException ex) {
ExceptionGlassPane edlg = new ExceptionGlassPane(Application.get(), ex);
edlg.setVisible(true);
}
}
String readNamesFromFile(File file) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(file));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
line = line.trim();
if (!line.isEmpty()) {
sb.append(line).append('\n');
}
}
return sb.toString();
}
private void changePatternAction() {
PatternSourcePage page = new PatternSourcePage(hm.getDimension(sortDimension), true);
PageDialog dlg = new PageDialog(Application.get(), page);
dlg.setVisible(true);
if (dlg.isCancelled()) {
return;
}
pattern = page.getPattern();
patternsField.setText(page.getPatternTitle());
}
public MatrixDimensionKey getDimension() {
return sortDimension;
}
public String getPattern() {
return pattern;
}
private ArrayList<String> getSelected() {
HeatmapDimension dimension = hm.getDimension(getDimension());
Function<String, String> patternFunction = new PatternFunction(getPattern(), dimension.getAnnotations());
return newArrayList(transform(dimension.getSelected(), patternFunction));
}
private ArrayList<String> getUnselected() {
HeatmapDimension dimension = hm.getDimension(getDimension());
Function<String, String> patternFunction = new PatternFunction(getPattern(), dimension.getAnnotations());
Iterable<String> unselected = filter(dimension, not(in(dimension.getSelected())));
return newArrayList(transform(unselected, patternFunction));
}
public Set<String> getValues() {
Set<String> values = new HashSet<>();
StringReader sr = new StringReader(patternsArea.getText());
BufferedReader br = new BufferedReader(sr);
String line;
try {
while ((line = br.readLine()) != null) {
line = line.trim();
if (!line.isEmpty()) {
values.add(line);
}
}
} catch (IOException ex) {
ExceptionGlassPane dlg = new ExceptionGlassPane(Application.get(), ex);
dlg.setVisible(true);
}
return values;
}
void setValues(List<String> values) {
for (String value : values) {
patternsArea.append(value + "\n");
}
}
public boolean isUseRegexChecked() {
return useRegexCheck.isSelected();
}
}