/*
* The MIT License (MIT)
*
* Copyright (c) 2007-2015 Broad Institute
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/*
* Created by JFormDesigner on Tue Mar 06 14:09:15 EST 2012
*/
package org.broad.igv.cbio;
import org.apache.log4j.Logger;
import org.broad.igv.DirectoryManager;
import org.broad.igv.lists.GeneList;
import org.broad.igv.prefs.Constants;
import org.broad.igv.prefs.PreferencesManager;
import org.broad.igv.ui.IGV;
import org.broad.igv.ui.WaitCursorManager;
import org.broad.igv.ui.util.*;
import org.broad.igv.util.BrowserLauncher;
import org.broad.igv.util.LongRunningTask;
import org.broad.igv.util.StringUtils;
import org.w3c.dom.Node;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;
import java.util.List;
/**
* Dialog for letting the user filter a GeneNetwork from
* cBio.
*
* @author Jacob Silterra
*/
public class FilterGeneNetworkUI extends JDialog {
private Logger log = Logger.getLogger(FilterGeneNetworkUI.class);
private GeneList seedGeneList;
private List<AttributeFilter> filterRows = new ArrayList<AttributeFilter>(1);
GeneNetwork network = null;
private GraphListModel listModel;
private Map<String, JTextField> thresholdsMap = new HashMap<String, JTextField>(5);
private static List<String> columnNames;
private static Map<Integer, String> columnNumToKeyMap;
/**
* For change events, we keep track of where we started from
*/
private Component lastSelectedTab;
static {
String[] firstLabels = {"Gene label", "Interactions"};
columnNumToKeyMap = new HashMap<Integer, String>(GeneNetwork.attributeMap.size());
columnNames = new ArrayList<String>(firstLabels.length + GeneNetwork.attributeMap.size());
for (String label : firstLabels) {
columnNames.add(label);
}
int ind = columnNames.size();
for (String key : GeneNetwork.attributeMap.keySet()) {
columnNumToKeyMap.put(ind, key);
ind++;
columnNames.add(AttributeFilter.keyToLabel(key));
}
}
public FilterGeneNetworkUI(Frame owner, GeneList seedGeneList) {
super(owner);
this.seedGeneList = seedGeneList;
}
@Override
public void setVisible(boolean visible) {
if (visible && network == null) {
loadcBioData();
} else {
super.setVisible(visible);
}
}
private void loadcBioData() {
network = null;
final List<String> geneLoci = seedGeneList.getLoci();
final IndefiniteProgressMonitor indefMonitor = new IndefiniteProgressMonitor();
final ProgressBar.ProgressDialog progressDialog = ProgressBar.showProgressDialog((Frame) getOwner(), "Loading cBio data...", indefMonitor, true);
progressDialog.getProgressBar().setIndeterminate(true);
indefMonitor.start();
//Since we load the data asynchronously, we run this when finished
final Runnable updateUI = new Runnable() {
@Override
public void run() {
boolean needSetup = !FilterGeneNetworkUI.this.isVisible();
if (needSetup) {
initComponents();
}
setGeneNetworkNeedsUpdate(false);
tabbedPane.setSelectedComponent(filterPane);
initComponentData();
if (needSetup) {
FilterGeneNetworkUI.super.setVisible(true);
}
}
};
final Runnable runnable = new Runnable() {
@Override
public void run() {
WaitCursorManager.CursorToken token = null;
try {
token = WaitCursorManager.showWaitCursor();
network = GeneNetwork.getFromCBIO(geneLoci);
if (network.vertexSet().size() == 0) {
MessageUtils.showMessage("No results found for " + StringUtils.join(geneLoci, ", "));
} else {
network.annotateAll(IGV.getInstance().getAllTracks());
UIUtilities.invokeOnEventThread(updateUI);
}
} catch (Throwable e) {
e.printStackTrace();
log.error(e.getMessage());
MessageUtils.showMessage("Error loading data: " + e.getMessage());
} finally {
WaitCursorManager.removeWaitCursor(token);
if (progressDialog != null) {
progressDialog.setVisible(false);
indefMonitor.stop();
}
}
}
};
LongRunningTask.submit(runnable);
}
private void initThresholdsMap() {
thresholdsMap.put(Constants.CBIO_MUTATION_THRESHOLD, mutInput);
thresholdsMap.put(Constants.CBIO_AMPLIFICATION_THRESHOLD, ampInput);
thresholdsMap.put(Constants.CBIO_DELETION_THRESHOLD, delInput);
thresholdsMap.put(Constants.CBIO_EXPRESSION_UP_THRESHOLD, expUpInput);
thresholdsMap.put(Constants.CBIO_EXPRESSION_DOWN_THRESHOLD, expDownInput);
}
/**
* Load data into visual components. This should be called
* AFTER loading network.
*/
private void initComponentData() {
refreshSeedGenesTextArea();
if (this.filterRows.size() == 0) {
add();
}
initThresholdsMap();
loadThresholds();
listModel = new GraphListModel();
geneTable.setModel(listModel);
initRenderers();
applySoftFilters();
}
private void modifyForSelection(JComponent component, boolean isSelected) {
if (isSelected) {
component.setForeground(geneTable.getSelectionForeground());
component.setBackground(geneTable.getSelectionBackground());
component.setOpaque(isSelected);
}
}
private void initRenderers() {
//Bold seed genes and format numbers nicely
TableCellRenderer stringRenderer = new TableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JLabel comp = new JLabel();
if (value != null) {
boolean isSeedGene = seedGeneList.getLoci().contains(value);
comp.setText(String.valueOf(value));
if (isSeedGene) {
comp.setFont(comp.getFont().deriveFont(comp.getFont().getStyle() | Font.BOLD));
}
}
modifyForSelection(comp, isSelected);
return comp;
}
};
TableCellRenderer intRenderer = new TableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JLabel comp = new JLabel("" + value);
modifyForSelection(comp, isSelected);
return comp;
}
};
TableCellRenderer doubleRenderer = new TableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JLabel comp = new JLabel();
if (value != null) {
String sVal;
Double dPerc = (Double) value;
if (dPerc == 0.0d) {
sVal = "0.0";
} else {
//If small, show in exponential format
//Otherwise just show 1 decimal place
String fmt = "%2.1f";
if (dPerc < 0.1d) {
fmt = "%2.1e";
}
sVal = String.format(fmt, dPerc);
}
comp.setText(sVal);
}
modifyForSelection(comp, isSelected);
return comp;
}
};
geneTable.setDefaultRenderer(String.class, stringRenderer);
geneTable.setDefaultRenderer(Integer.class, intRenderer);
geneTable.setDefaultRenderer(Double.class, doubleRenderer);
}
/**
* Update the displayed text area to show the genes in {@code seedGeneList}
* See {@linkplain #getNewSeedGeneList}
*/
private void refreshSeedGenesTextArea() {
String seedGenesString = StringUtils.join(seedGeneList.getLoci(), "\n");
seedGenesText.setText(seedGenesString);
}
/**
* Get the text content of {@code seedGenestext} and parse it into
* a GeneList.
* See {@linkplain #refreshSeedGenesTextArea()}
*
* @return new seedGeneList, which may be the same as the old
*/
private GeneList getNewSeedGeneList() {
String[] genes = seedGenesText.getText().toUpperCase().split("[\\r\\n]{1,2}");
boolean updated = !Arrays.equals(seedGeneList.getLoci().toArray(), genes);
if (updated) {
return new GeneList(null, Arrays.asList(genes));
} else {
return seedGeneList;
}
}
private boolean checkNewSeedGeneList() {
return getNewSeedGeneList() != seedGeneList;
}
private void remove(AttributeFilter row) {
contentPane.remove(row.getPanel());
filterRows.remove(row);
int numRows = filterRows.size();
filterRows.get(numRows - 1).setIsLast(true);
filterRows.get(0).setShowDel(numRows >= 2);
validate();
adjustWindowHeight(-row.getPanel().getHeight());
applySoftFilters();
}
private void add() {
final AttributeFilter row = new AttributeFilter();
row.getDelRow().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
remove(row);
}
});
row.getAddRow().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
add();
}
});
contentPane.add(row.getPanel());
//We want to refresh the
RefreshListener listener = new RefreshListener();
row.getAttrName().addActionListener(listener);
for (JTextField text : new JTextField[]{row.minVal, row.maxVal}) {
text.addActionListener(listener);
text.addFocusListener(listener);
}
//Set the status of being last
if (filterRows.size() >= 1) {
filterRows.get(filterRows.size() - 1).setIsLast(false);
}
filterRows.add(row);
int numRows = filterRows.size();
filterRows.get(numRows - 1).setIsLast(true);
filterRows.get(0).setShowDel(numRows >= 2);
validate();
adjustWindowHeight(row.getPanel().getHeight());
}
/**
* When adding/removing rows, we change the height of some components
* This method may have no effect
*
* @param heightDelta Number of pixels to increase (negative values allowed)
* the tab pane and dialog itself
*/
private void adjustWindowHeight(int heightDelta) {
int newWinHeight = getHeight() + heightDelta;
if (filterRows.size() >= 4 && (newWinHeight < Toolkit.getDefaultToolkit().getScreenSize().getHeight() - 100)) {
Dimension newSize = tabbedPane.getPreferredSize();
newSize.setSize(newSize.getWidth(), newSize.getHeight() + heightDelta);
tabbedPane.setPreferredSize(newSize);
newSize = getSize();
newSize.setSize(newSize.getWidth(), newWinHeight);
setSize(newSize);
validate();
}
}
private void cancelButtonActionPerformed(ActionEvent e) {
setVisible(false);
}
private void applySoftFilters() {
network.reset();
if (showSeedOnly.isSelected()) {
//Redundant, as filterGenes already preserves query genes
//But we want to be explicit
network.filterGenes(GeneNetwork.inQuery);
} else {
//TODO This is only AND, should also include OR
for (AttributeFilter filter : this.filterRows) {
String filt_el = (String) filter.getAttrName().getSelectedItem();
if (GeneNetwork.attributeMap.containsKey(filt_el) || GeneNetwork.PERCENT_ALTERED.equals(filt_el)) {
float min = Float.parseFloat(filter.minVal.getText());
float max = Float.parseFloat(filter.maxVal.getText());
network.filterGenesRange(filt_el, min / 100, max / 100);
}
}
if (!keepIsolated.isSelected()) {
network.pruneGraph();
}
}
totNumGenes.setText("Total Genes: " + network.geneVertexes().size());
this.listModel.markDirty();
}
private void showNetwork() {
Runnable runnable = new Runnable() {
@Override
public void run() {
try {
String url = network.outputForcBioView();
url = "file://" + url;
BrowserLauncher.openURL(url);
} catch (IOException err) {
log.error(err);
MessageUtils.showMessage("Error opening network for viewing. " + err.getMessage());
}
}
};
LongRunningTask.submit(runnable);
}
/**
* Sorting of the rows is done on the view, not the underlying model,
* so we must convert. See {@link TableRowSorter}
*
* @return int[] of model indices which are selected
*/
private int[] getModelIndices() {
int[] selection = geneTable.getSelectedRows();
for (int i = 0; i < selection.length; i++) {
selection[i] = geneTable.convertRowIndexToModel(selection[i]);
}
return selection;
}
private void okButtonActionPerformed(ActionEvent e) {
//setVisible(false);
showNetwork();
}
private void addRowActionPerformed(ActionEvent e) {
add();
}
/**
* Refresh the view based on filter input.
*/
private void refreshFilters() {
this.applySoftFilters();
listModel.markDirty();
this.validate();
}
private void refFilterActionPerformed(ActionEvent e) {
refreshFilters();
}
private boolean saveThresholds() {
try {
for (Map.Entry<String, JTextField> entry : thresholdsMap.entrySet()) {
float fval = Float.parseFloat(entry.getValue().getText());
String sval = "" + fval;
if (entry.getKey() == Constants.CBIO_MUTATION_THRESHOLD) {
int ival = Integer.parseInt(entry.getValue().getText());
sval = "" + ival;
}
PreferencesManager.getPreferences().put(entry.getKey(), sval);
}
} catch (NumberFormatException e) {
MessageUtils.showMessage("Invalid input. Mutation count must be integers, others must be numeric. " + e.getMessage());
return false;
}
return true;
}
private void loadThresholds() {
for (Map.Entry<String, JTextField> entry : thresholdsMap.entrySet()) {
String value = PreferencesManager.getPreferences().get(entry.getKey());
entry.getValue().setText(value);
}
}
private void tabbedPaneStateChanged(ChangeEvent e) {
if (tabbedPane == null || thresholdsPane == null) {
//Component not built yet
return;
}
if (lastSelectedTab != null) {
//If the user enters an invalid threshold, we don't let them switch away
if (lastSelectedTab == seedGenesPane && !saveThresholds()) {
tabbedPane.setSelectedComponent(thresholdsPane);
}
//Reload network when we change away from seed genes pane
//No-op if unchanged
// if (lastSelectedTab == seedGenesPane) {
// updateNetwork();
// }
}
lastSelectedTab = tabbedPane.getSelectedComponent();
}
private void saveButtonActionPerformed(ActionEvent e) {
File outPath = FileDialogUtils.chooseFile("Save table to...", DirectoryManager.getUserDirectory(), FileDialogUtils.SAVE);
if (outPath != null) {
try {
saveTable(outPath);
} catch (FileNotFoundException exc) {
MessageUtils.showMessage(exc.getMessage());
}
}
}
private void resetToDefaultsButtonActionPerformed(ActionEvent e) {
for (Map.Entry<String, JTextField> entry : thresholdsMap.entrySet()) {
String value = PreferencesManager.getPreferences().getDefaultValue(entry.getKey());
entry.getValue().setText(value);
}
saveThresholds();
}
private void cancel2ActionPerformed(ActionEvent e) {
cancelButton.doClick();
}
private void retrieveNetworkButtonActionPerformed(ActionEvent e) {
updateNetwork();
}
private void updateNetwork() {
GeneList newSeedGeneList = getNewSeedGeneList();
boolean updated = newSeedGeneList != seedGeneList;
if (updated) {
seedGeneList = newSeedGeneList;
loadcBioData();
}
}
private void resetSeedGeneTextAreaButtonActionPerformed(ActionEvent e) {
refreshSeedGenesTextArea();
setGeneNetworkNeedsUpdate(false);
}
private void seedGenesTextKeyReleased(KeyEvent e) {
boolean updated = checkNewSeedGeneList();
setGeneNetworkNeedsUpdate(updated);
}
private void setGeneNetworkNeedsUpdate(boolean updated) {
boolean tabsEnabled = !updated;
int filterIndex = tabbedPane.indexOfComponent(filterPane);
int thresholdsIndex = tabbedPane.indexOfComponent(thresholdsPane);
int[] indexes = {filterIndex, thresholdsIndex};
Color color = tabsEnabled ? Color.black : Color.gray;
for (int index : indexes) {
tabbedPane.setEnabledAt(index, tabsEnabled);
tabbedPane.setForegroundAt(index, color);
}
retrieveNetworkButton.setEnabled(updated);
}
private void showSeedOnlyActionPerformed(ActionEvent e) {
refreshFilters();
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
// Generated using JFormDesigner non-commercial license
tabbedPane = new JTabbedPane();
seedGenesPane = new JPanel();
vSpacer1 = new JPanel(null);
label5 = new JLabel();
scrollPane2 = new JScrollPane();
seedGenesText = new JTextArea();
textPane1 = new JTextPane();
seedButtonBar = new JPanel();
retrieveNetworkButton = new JButton();
resetSeedGeneTextAreaButton = new JButton();
cancel2 = new JButton();
filterPane = new JPanel();
panel1 = new JPanel();
addRow = new JButton();
contentPane = new JPanel();
scrollPane1 = new JScrollPane();
geneTable = new JTable();
buttonBar = new JPanel();
totNumGenes = new JLabel();
showSeedOnly = new JCheckBox();
refFilter = new JButton();
keepIsolated = new JCheckBox();
okButton = new JButton();
cancelButton = new JButton();
saveButton = new JButton();
helpButton = new JButton();
thresholdsPane = new JPanel();
contentPanel = new JPanel();
label2 = new JLabel();
label3 = new JLabel();
delInput = new JTextField();
label4 = new JLabel();
expUpInput = new JTextField();
label7 = new JLabel();
expDownInput = new JTextField();
ampInput = new JTextField();
label1 = new JLabel();
mutInput = new JTextField();
label6 = new JLabel();
label8 = new JLabel();
separator1 = new JSeparator();
separator3 = new JSeparator();
separator2 = new JSeparator();
panel2 = new JPanel();
textArea1 = new JTextArea();
resetToDefaultsButton = new JButton();
//======== this ========
setMinimumSize(new Dimension(600, 22));
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
setModal(true);
setModalityType(Dialog.ModalityType.DOCUMENT_MODAL);
Container contentPane2 = getContentPane();
contentPane2.setLayout(new BorderLayout());
//======== tabbedPane ========
{
tabbedPane.setPreferredSize(new Dimension(571, 400));
tabbedPane.setMinimumSize(new Dimension(571, 346));
tabbedPane.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
tabbedPaneStateChanged(e);
}
});
//======== seedGenesPane ========
{
seedGenesPane.setLayout(new GridBagLayout());
((GridBagLayout) seedGenesPane.getLayout()).rowHeights = new int[]{0, 0, 0, 0, 0, 0};
((GridBagLayout) seedGenesPane.getLayout()).rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 1.0E-4};
seedGenesPane.add(vSpacer1, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 0), 0, 0));
//---- label5 ----
label5.setText("Seed Genes (one per line):");
label5.setLabelFor(seedGenesText);
seedGenesPane.add(label5, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 0), 0, 0));
//======== scrollPane2 ========
{
scrollPane2.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
//---- seedGenesText ----
seedGenesText.setRows(12);
seedGenesText.setToolTipText("cBio will be queried to find what genes interact with these genes");
seedGenesText.setDragEnabled(false);
seedGenesText.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
seedGenesTextKeyReleased(e);
}
});
scrollPane2.setViewportView(seedGenesText);
}
seedGenesPane.add(scrollPane2, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 0), 0, 0));
//---- textPane1 ----
textPane1.setBorder(null);
textPane1.setEditable(false);
textPane1.setText("IGV will query cBio to find genes which interact with the seed genes entered here.");
textPane1.setBackground(UIManager.getColor("Button.background"));
seedGenesPane.add(textPane1, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 0), 0, 0));
//======== seedButtonBar ========
{
seedButtonBar.setLayout(new GridBagLayout());
((GridBagLayout) seedButtonBar.getLayout()).columnWidths = new int[]{0, 0, 0, 0};
((GridBagLayout) seedButtonBar.getLayout()).rowHeights = new int[]{0, 0};
((GridBagLayout) seedButtonBar.getLayout()).columnWeights = new double[]{0.0, 0.0, 0.0, 1.0E-4};
((GridBagLayout) seedButtonBar.getLayout()).rowWeights = new double[]{0.0, 1.0E-4};
//---- retrieveNetworkButton ----
retrieveNetworkButton.setText("Retrieve Network");
retrieveNetworkButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
retrieveNetworkButtonActionPerformed(e);
}
});
seedButtonBar.add(retrieveNetworkButton, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 5), 0, 0));
//---- resetSeedGeneTextAreaButton ----
resetSeedGeneTextAreaButton.setText("Reset to Original");
resetSeedGeneTextAreaButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
resetSeedGeneTextAreaButtonActionPerformed(e);
}
});
seedButtonBar.add(resetSeedGeneTextAreaButton, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 5), 0, 0));
//---- cancel2 ----
cancel2.setText("Cancel");
cancel2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
cancel2ActionPerformed(e);
}
});
seedButtonBar.add(cancel2, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 0), 0, 0));
}
seedGenesPane.add(seedButtonBar, new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 0), 0, 0));
}
tabbedPane.addTab("Seed Genes", seedGenesPane);
//======== filterPane ========
{
filterPane.setBorder(new EmptyBorder(12, 12, 12, 12));
filterPane.setMinimumSize(new Dimension(443, 300));
filterPane.setLayout(new GridBagLayout());
((GridBagLayout) filterPane.getLayout()).columnWidths = new int[]{0, 0};
((GridBagLayout) filterPane.getLayout()).rowHeights = new int[]{0, 0, 0, 0, 0, 0};
((GridBagLayout) filterPane.getLayout()).columnWeights = new double[]{1.0, 1.0E-4};
((GridBagLayout) filterPane.getLayout()).rowWeights = new double[]{0.0, 0.0, 1.0, 0.0, 0.0, 1.0E-4};
//======== panel1 ========
{
panel1.setLayout(new GridBagLayout());
((GridBagLayout) panel1.getLayout()).columnWidths = new int[]{0, 0, 0};
((GridBagLayout) panel1.getLayout()).rowHeights = new int[]{0, 0};
((GridBagLayout) panel1.getLayout()).columnWeights = new double[]{0.0, 0.0, 1.0E-4};
((GridBagLayout) panel1.getLayout()).rowWeights = new double[]{0.0, 1.0E-4};
//---- addRow ----
addRow.setText("Add Filter");
addRow.setMaximumSize(new Dimension(200, 28));
addRow.setMinimumSize(new Dimension(100, 28));
addRow.setPreferredSize(new Dimension(150, 28));
addRow.setVisible(false);
addRow.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
addRowActionPerformed(e);
}
});
panel1.add(addRow, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 0), 0, 0));
}
filterPane.add(panel1, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 0), 0, 0));
//======== contentPane ========
{
contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));
}
filterPane.add(contentPane, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 0), 0, 0));
//======== scrollPane1 ========
{
//---- geneTable ----
geneTable.setAutoCreateRowSorter(true);
scrollPane1.setViewportView(geneTable);
}
filterPane.add(scrollPane1, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 0), 0, 0));
//======== buttonBar ========
{
buttonBar.setBorder(new EmptyBorder(12, 0, 0, 0));
buttonBar.setMaximumSize(new Dimension(2147483647, 137));
buttonBar.setPreferredSize(new Dimension(421, 100));
buttonBar.setMinimumSize(new Dimension(421, 80));
buttonBar.setLayout(new GridBagLayout());
((GridBagLayout) buttonBar.getLayout()).columnWidths = new int[]{0, 85, 85, 80};
((GridBagLayout) buttonBar.getLayout()).columnWeights = new double[]{1.0, 0.0, 0.0, 0.0};
//---- totNumGenes ----
totNumGenes.setText("Total Genes: #");
buttonBar.add(totNumGenes, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 5), 0, 0));
//---- showSeedOnly ----
showSeedOnly.setText("Seed Genes Only");
showSeedOnly.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
showSeedOnlyActionPerformed(e);
}
});
buttonBar.add(showSeedOnly, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 5), 0, 0));
//---- refFilter ----
refFilter.setText("Refresh Filter");
refFilter.setVisible(false);
refFilter.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
refFilterActionPerformed(e);
}
});
buttonBar.add(refFilter, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 5), 0, 0));
//---- keepIsolated ----
keepIsolated.setText("Keep Isolated Genes");
keepIsolated.setVisible(false);
buttonBar.add(keepIsolated, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 5, 0), 0, 0));
//---- okButton ----
okButton.setText("View Network");
okButton.setToolTipText("Display the network in a web browser");
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
okButtonActionPerformed(e);
}
});
buttonBar.add(okButton, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 5), 0, 0));
//---- cancelButton ----
cancelButton.setText("Cancel");
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
cancelButtonActionPerformed(e);
}
});
buttonBar.add(cancelButton, new GridBagConstraints(3, 1, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 0), 0, 0));
//---- saveButton ----
saveButton.setText("Save Table");
saveButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
saveButtonActionPerformed(e);
}
});
buttonBar.add(saveButton, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 5), 0, 0));
//---- helpButton ----
helpButton.setText("Help");
helpButton.setVisible(false);
buttonBar.add(helpButton, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 5), 0, 0));
}
filterPane.add(buttonBar, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0,
GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL,
new Insets(0, 0, 0, 0), 0, 0));
}
tabbedPane.addTab("Filter", filterPane);
//======== thresholdsPane ========
{
thresholdsPane.setPreferredSize(new Dimension(550, 196));
thresholdsPane.setMinimumSize(new Dimension(550, 196));
thresholdsPane.setLayout(null);
//======== contentPanel ========
{
contentPanel.setBorder(new EtchedBorder());
contentPanel.setLayout(null);
//---- label2 ----
label2.setText("Amplification:");
label2.setHorizontalAlignment(SwingConstants.RIGHT);
label2.setLabelFor(ampInput);
label2.setToolTipText("Amplification score, on a log-normalized scale");
label2.setPreferredSize(new Dimension(90, 18));
contentPanel.add(label2);
label2.setBounds(140, 96, label2.getPreferredSize().width, 18);
//---- label3 ----
label3.setText("Deletion:");
label3.setHorizontalAlignment(SwingConstants.RIGHT);
label3.setLabelFor(delInput);
label3.setToolTipText("Deletion score, on a log-normalized scale");
label3.setPreferredSize(new Dimension(60, 16));
contentPanel.add(label3);
label3.setBounds(360, 96, label3.getPreferredSize().width, 18);
//---- delInput ----
delInput.setText("0.9");
delInput.setMinimumSize(new Dimension(34, 28));
delInput.setPreferredSize(new Dimension(45, 28));
delInput.setMaximumSize(new Dimension(50, 2147483647));
contentPanel.add(delInput);
delInput.setBounds(new Rectangle(new Point(430, 91), delInput.getPreferredSize()));
//---- label4 ----
label4.setText("Up:");
label4.setHorizontalAlignment(SwingConstants.RIGHT);
label4.setLabelFor(expUpInput);
label4.setToolTipText("Expression score, log-normalized scale");
label4.setPreferredSize(new Dimension(100, 18));
contentPanel.add(label4);
label4.setBounds(130, 168, label4.getPreferredSize().width, 18);
//---- expUpInput ----
expUpInput.setText("1.0");
expUpInput.setMinimumSize(new Dimension(34, 28));
expUpInput.setPreferredSize(new Dimension(45, 28));
contentPanel.add(expUpInput);
expUpInput.setBounds(new Rectangle(new Point(240, 162), expUpInput.getPreferredSize()));
//---- label7 ----
label7.setText("Down:");
label7.setHorizontalAlignment(SwingConstants.RIGHT);
label7.setLabelFor(expDownInput);
label7.setToolTipText("Expression score, log-normalized scale");
label7.setPreferredSize(new Dimension(120, 16));
contentPanel.add(label7);
label7.setBounds(300, 168, label7.getPreferredSize().width, 18);
//---- expDownInput ----
expDownInput.setText("1.0");
expDownInput.setPreferredSize(new Dimension(45, 28));
expDownInput.setMinimumSize(new Dimension(34, 28));
expDownInput.setMaximumSize(new Dimension(50, 2147483647));
contentPanel.add(expDownInput);
expDownInput.setBounds(new Rectangle(new Point(430, 162), expDownInput.getPreferredSize()));
//---- ampInput ----
ampInput.setText("0.9");
ampInput.setMinimumSize(new Dimension(34, 28));
ampInput.setPreferredSize(new Dimension(45, 28));
contentPanel.add(ampInput);
ampInput.setBounds(new Rectangle(new Point(240, 91), ampInput.getPreferredSize()));
//---- label1 ----
label1.setText("Mutation:");
label1.setHorizontalAlignment(SwingConstants.RIGHT);
label1.setLabelFor(mutInput);
label1.setToolTipText("Minimum number of mutations found");
label1.setPreferredSize(new Dimension(66, 18));
contentPanel.add(label1);
label1.setBounds(50, 26, label1.getPreferredSize().width, 18);
//---- mutInput ----
mutInput.setText("1");
mutInput.setAutoscrolls(false);
mutInput.setMinimumSize(new Dimension(34, 28));
mutInput.setPreferredSize(new Dimension(45, 28));
contentPanel.add(mutInput);
mutInput.setBounds(new Rectangle(new Point(240, 21), mutInput.getPreferredSize()));
//---- label6 ----
label6.setText("Copy Number:");
contentPanel.add(label6);
label6.setBounds(30, 96, label6.getPreferredSize().width, 18);
//---- label8 ----
label8.setText("Expression:");
label8.setHorizontalAlignment(SwingConstants.RIGHT);
contentPanel.add(label8);
label8.setBounds(30, 168, 86, 18);
contentPanel.add(separator1);
separator1.setBounds(0, 135, 500, 10);
contentPanel.add(separator3);
separator3.setBounds(0, 65, 500, 10);
//---- separator2 ----
separator2.setPreferredSize(new Dimension(10, 210));
separator2.setOrientation(SwingConstants.VERTICAL);
contentPanel.add(separator2);
separator2.setBounds(new Rectangle(new Point(120, 0), separator2.getPreferredSize()));
{ // compute preferred size
Dimension preferredSize = new Dimension();
for (int i = 0; i < contentPanel.getComponentCount(); i++) {
Rectangle bounds = contentPanel.getComponent(i).getBounds();
preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
}
Insets insets = contentPanel.getInsets();
preferredSize.width += insets.right;
preferredSize.height += insets.bottom;
contentPanel.setMinimumSize(preferredSize);
contentPanel.setPreferredSize(preferredSize);
}
}
thresholdsPane.add(contentPanel);
contentPanel.setBounds(12, 80, 500, 210);
//======== panel2 ========
{
panel2.setLayout(null);
{ // compute preferred size
Dimension preferredSize = new Dimension();
for (int i = 0; i < panel2.getComponentCount(); i++) {
Rectangle bounds = panel2.getComponent(i).getBounds();
preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
}
Insets insets = panel2.getInsets();
preferredSize.width += insets.right;
preferredSize.height += insets.bottom;
panel2.setMinimumSize(preferredSize);
panel2.setPreferredSize(preferredSize);
}
}
thresholdsPane.add(panel2);
panel2.setBounds(new Rectangle(new Point(55, 25), panel2.getPreferredSize()));
//---- textArea1 ----
textArea1.setText("Samples are considered to have a given \"event\" if the value is above the thresholds below.");
textArea1.setEditable(false);
textArea1.setLineWrap(true);
textArea1.setBackground(UIManager.getColor("Button.background"));
thresholdsPane.add(textArea1);
textArea1.setBounds(15, 10, 430, 40);
//---- resetToDefaultsButton ----
resetToDefaultsButton.setText("Reset to Defaults");
resetToDefaultsButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
resetToDefaultsButtonActionPerformed(e);
}
});
thresholdsPane.add(resetToDefaultsButton);
resetToDefaultsButton.setBounds(new Rectangle(new Point(10, 50), resetToDefaultsButton.getPreferredSize()));
{ // compute preferred size
Dimension preferredSize = new Dimension();
for (int i = 0; i < thresholdsPane.getComponentCount(); i++) {
Rectangle bounds = thresholdsPane.getComponent(i).getBounds();
preferredSize.width = Math.max(bounds.x + bounds.width, preferredSize.width);
preferredSize.height = Math.max(bounds.y + bounds.height, preferredSize.height);
}
Insets insets = thresholdsPane.getInsets();
preferredSize.width += insets.right;
preferredSize.height += insets.bottom;
thresholdsPane.setMinimumSize(preferredSize);
thresholdsPane.setPreferredSize(preferredSize);
}
}
tabbedPane.addTab("Thresholds", thresholdsPane);
}
contentPane2.add(tabbedPane, BorderLayout.NORTH);
pack();
setLocationRelativeTo(getOwner());
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
// Generated using JFormDesigner non-commercial license
private JTabbedPane tabbedPane;
private JPanel seedGenesPane;
private JPanel vSpacer1;
private JLabel label5;
private JScrollPane scrollPane2;
private JTextArea seedGenesText;
private JTextPane textPane1;
private JPanel seedButtonBar;
private JButton retrieveNetworkButton;
private JButton resetSeedGeneTextAreaButton;
private JButton cancel2;
private JPanel filterPane;
private JPanel panel1;
private JButton addRow;
private JPanel contentPane;
private JScrollPane scrollPane1;
private JTable geneTable;
private JPanel buttonBar;
private JLabel totNumGenes;
private JCheckBox showSeedOnly;
private JButton refFilter;
private JCheckBox keepIsolated;
private JButton okButton;
private JButton cancelButton;
private JButton saveButton;
private JButton helpButton;
private JPanel thresholdsPane;
private JPanel contentPanel;
private JLabel label2;
private JLabel label3;
private JTextField delInput;
private JLabel label4;
private JTextField expUpInput;
private JLabel label7;
private JTextField expDownInput;
private JTextField ampInput;
private JLabel label1;
private JTextField mutInput;
private JLabel label6;
private JLabel label8;
private JSeparator separator1;
private JSeparator separator3;
private JSeparator separator2;
private JPanel panel2;
private JTextArea textArea1;
private JButton resetToDefaultsButton;
// JFormDesigner - End of variables declaration //GEN-END:variables
/**
* Export the current table to a tab-delimited file.
* String exported should be the same as what user sees
*
* @param outFile
* @throws IOException
*/
private void saveTable(File outFile) throws FileNotFoundException {
PrintWriter writer = new PrintWriter(outFile);
TableModel model = geneTable.getModel();
String delimiter = "\t";
//Write header
String header = model.getColumnName(0);
for (int col = 1; col < model.getColumnCount(); col++) {
header += delimiter + model.getColumnName(col);
}
writer.println(header);
for (int row = 0; row < model.getRowCount(); row++) {
String rowStr = "" + model.getValueAt(row, 0);
for (int col = 1; col < model.getColumnCount(); col++) {
rowStr += delimiter + model.getValueAt(row, col);
}
writer.println(rowStr);
}
writer.flush();
writer.close();
}
private class GraphListModel extends AbstractTableModel {
private List<Node> geneVertices = null;
private List<Node> getGeneVertices() {
if (geneVertices == null) {
Collection<Node> nodes = network.geneVertexes();
geneVertices = Arrays.asList(nodes.toArray(new Node[0]));
}
return geneVertices;
}
public void markDirty() {
this.geneVertices = null;
this.fireTableStructureChanged();
}
@Override
public int getRowCount() {
return getGeneVertices().size();
}
@Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0:
return String.class;
case 1:
return Integer.class;
default:
return Double.class;
}
}
@Override
public int getColumnCount() {
return columnNames.size();
}
public String getColumnName(int col) {
return columnNames.get(col);
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
Node n = getGeneVertices().get(rowIndex);
String nm = GeneNetwork.getNodeKeyData(n, "label");
switch (columnIndex) {
case 0:
return nm;
case 1:
return network.edgesOf(n).size();
default:
String key = columnNumToKeyMap.get(columnIndex);
if (key == null) {
return null;
}
String val = GeneNetwork.getNodeKeyData(n, key);
if ("nan".equalsIgnoreCase(val) || val == null) {
return null;
}
//Change from fraction to percent
double dPerc = Double.parseDouble(val) * 100;
return dPerc;
}
}
@Override
public boolean isCellEditable(int row, int col) {
return false;
}
}
private class RefreshListener implements FocusListener, ActionListener {
@Override
public void focusGained(FocusEvent e) {
//pass
}
@Override
public void focusLost(FocusEvent e) {
refreshFilters();
}
@Override
public void actionPerformed(ActionEvent e) {
refreshFilters();
}
}
}