/* * 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(); } } }