/* * Copyright (c) 2010 The Jackson Laboratory * * This 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 software 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 software. If not, see <http://www.gnu.org/licenses/>. */ package org.jax.bham.io; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.Writer; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.JDialog; import javax.swing.JFileChooser; import org.jax.bham.BhamApplication; import org.jax.bham.project.BhamProject; import org.jax.haplotype.analysis.PhylogenyDataSource; import org.jax.util.concurrent.MultiTaskProgressPanel; import org.jax.util.gui.MessageDialogUtilities; import org.jax.util.io.CommonFlatFileFormat; import org.jax.util.io.FlatFileFormat; import org.jax.util.io.FlatFileWriter; /** * A dialog for exporting phylogeny data to the newick format * @author <A HREF="mailto:keith.sheppard@jax.org">Keith Sheppard</A> */ public class ExportPhylogenyToNewickDialog extends JDialog { /** * every {@link java.io.Serializable} is supposed to have one of these */ private static final long serialVersionUID = -1940230316225163444L; private static final Logger LOG = Logger.getLogger( ExportPhylogenyToNewickDialog.class.getName()); private static final String MULTI_STRAIN_SEPARATE = "Separate Strain Names With a Pipe \"|\""; private static final String MULTI_STRAIN_RESOLVE = "Resolve Strains With 0-Length Branches"; private final BhamProject project; /** * Constructor * @param parent * the parent frame * @param project * the project */ public ExportPhylogenyToNewickDialog(Frame parent, BhamProject project) { super(parent, "Export Phylogeny Data to Newick Format"); this.project = project; this.initComponents(); this.postGuiInit(); } /** * Take care of the initialization that was not handled by the GUI builder */ private void postGuiInit() { this.outputFileButton.addActionListener(new ActionListener() { /** * {@inheritDoc} */ public void actionPerformed(ActionEvent e) { ExportPhylogenyToNewickDialog.this.browseOutputFiles(); } }); this.okButton.addActionListener(new ActionListener() { /** * {@inheritDoc} */ public void actionPerformed(ActionEvent e) { ExportPhylogenyToNewickDialog.this.ok(); } }); this.cancelButton.addActionListener(new ActionListener() { /** * {@inheritDoc} */ public void actionPerformed(ActionEvent e) { ExportPhylogenyToNewickDialog.this.cancel(); } }); this.helpButton.addActionListener(new ActionListener() { /** * {@inheritDoc} */ public void actionPerformed(ActionEvent e) { ExportPhylogenyToNewickDialog.this.showHelp(); } }); for(PhylogenyDataSource phyloData: this.project.getPhylogenyDataSources()) { this.phylogenyDataComboBox.addItem(phyloData); } this.fileFormatComboBox.addItem(CommonFlatFileFormat.CSV_UNIX); this.fileFormatComboBox.addItem(CommonFlatFileFormat.TAB_DELIMITED_UNIX); this.forMultiStrainNodesComboBox.addItem(MULTI_STRAIN_SEPARATE); this.forMultiStrainNodesComboBox.addItem(MULTI_STRAIN_RESOLVE); } private boolean getFullyResolveStrains() { return this.forMultiStrainNodesComboBox.getSelectedItem().equals( MULTI_STRAIN_RESOLVE); } private FlatFileFormat getFileFormat() { return (FlatFileFormat)this.fileFormatComboBox.getSelectedItem(); } private PhylogenyDataSource getSelectedPhylogenyData() { return (PhylogenyDataSource)this.phylogenyDataComboBox.getSelectedItem(); } private void ok() { try { if(this.validateData()) { Writer writer = new BufferedWriter( new FileWriter(this.getOutputFile())); FlatFileFormat format = this.getFileFormat(); FlatFileWriter flatFileWriter = new FlatFileWriter( writer, format); PhylogenyDataSource phyloData = this.getSelectedPhylogenyData(); ExportPhylogenyToNewickTask exportTask = new ExportPhylogenyToNewickTask( phyloData, this.getFullyResolveStrains(), flatFileWriter, true); MultiTaskProgressPanel progressTracker = BhamApplication.getInstance().getBhamFrame().getMultiTaskProgress(); progressTracker.addTaskToTrack(exportTask, true); new Thread(exportTask).start(); this.dispose(); } } catch(Exception ex) { String title = "Failed to Export Phylogenetic Data"; LOG.log(Level.SEVERE, title, ex); MessageDialogUtilities.error( this, ex.getMessage(), title); } } private void cancel() { this.dispose(); } private void showHelp() { MessageDialogUtilities.inform( this, "Sorry, no help yet..", "Help Not Implemented"); } private void browseOutputFiles() { JFileChooser fileChooser = new JFileChooser(); fileChooser.setDialogTitle( "Output File"); fileChooser.setMultiSelectionEnabled(false); fileChooser.setFileSelectionMode( JFileChooser.FILES_ONLY); int outputUserSelection = fileChooser.showSaveDialog(this); if(outputUserSelection == JFileChooser.APPROVE_OPTION) { File selectedOutputFile = fileChooser.getSelectedFile(); this.outputFileTextField.setText( selectedOutputFile.getAbsolutePath()); } else { LOG.fine("user canceled output file selection"); } } private boolean validateData() { String errorMessage = null; File outputFile = this.getOutputFile(); if(outputFile.isDirectory()) { errorMessage = "Cannot write output to \"" + outputFile.getAbsolutePath() + "\" because it is a directory"; } else if(outputFile.isFile()) { boolean overwrite = MessageDialogUtilities.ask( this, "\"" + outputFile.getAbsolutePath() + "\" already exists. " + "Would you like to overwrite this file?", "Confim File Overwrite"); if(!overwrite) { return false; } } if(errorMessage == null) { return true; } else { MessageDialogUtilities.warn( this, errorMessage, "Invalid User Input"); return false; } } private File getOutputFile() { String fileName = this.outputFileTextField.getText().trim(); return new File(fileName); } /** * 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("all") // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents private void initComponents() { javax.swing.JLabel outputFileLabel = new javax.swing.JLabel(); outputFileTextField = new javax.swing.JTextField(); outputFileButton = new javax.swing.JButton(); phylogenyDataLabel = new javax.swing.JLabel(); phylogenyDataComboBox = new javax.swing.JComboBox(); actionPanel = new javax.swing.JPanel(); okButton = new javax.swing.JButton(); cancelButton = new javax.swing.JButton(); helpButton = new javax.swing.JButton(); javax.swing.JLabel fileFormatLabel = new javax.swing.JLabel(); fileFormatComboBox = new javax.swing.JComboBox(); forMultiStrainNodesLabel = new javax.swing.JLabel(); forMultiStrainNodesComboBox = new javax.swing.JComboBox(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); outputFileLabel.setText("Output File:"); outputFileButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/browse-16x16.png"))); // NOI18N outputFileButton.setText("Browse..."); phylogenyDataLabel.setText("Phylogeny Data:"); okButton.setText("OK"); actionPanel.add(okButton); cancelButton.setText("Cancel"); actionPanel.add(cancelButton); helpButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/help-16x16.png"))); // NOI18N helpButton.setText("Help..."); actionPanel.add(helpButton); fileFormatLabel.setText("File Format:"); forMultiStrainNodesLabel.setText("For Multi-Strain Nodes:"); org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .addContainerGap() .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(phylogenyDataLabel) .add(outputFileLabel) .add(fileFormatLabel) .add(forMultiStrainNodesLabel)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .add(forMultiStrainNodesComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .addContainerGap()) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .add(fileFormatComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .addContainerGap(261, Short.MAX_VALUE)) .add(layout.createSequentialGroup() .add(outputFileTextField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 191, Short.MAX_VALUE) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(outputFileButton) .add(27, 27, 27)) .add(layout.createSequentialGroup() .add(phylogenyDataComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE) .addContainerGap(261, Short.MAX_VALUE))))) .add(org.jdesktop.layout.GroupLayout.TRAILING, actionPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 486, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) .add(layout.createSequentialGroup() .addContainerGap() .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(outputFileLabel) .add(outputFileButton) .add(outputFileTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(fileFormatLabel) .add(fileFormatComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(phylogenyDataLabel) .add(phylogenyDataComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) .add(forMultiStrainNodesLabel) .add(forMultiStrainNodesComboBox, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 8, Short.MAX_VALUE) .add(actionPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) ); pack(); }// </editor-fold>//GEN-END:initComponents // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JPanel actionPanel; private javax.swing.JButton cancelButton; private javax.swing.JComboBox fileFormatComboBox; private javax.swing.JComboBox forMultiStrainNodesComboBox; private javax.swing.JLabel forMultiStrainNodesLabel; private javax.swing.JButton helpButton; private javax.swing.JButton okButton; private javax.swing.JButton outputFileButton; private javax.swing.JTextField outputFileTextField; private javax.swing.JComboBox phylogenyDataComboBox; private javax.swing.JLabel phylogenyDataLabel; // End of variables declaration//GEN-END:variables }