/* * LogCombinerDialog.java * * Copyright (c) 2002-2015 Alexei Drummond, Andrew Rambaut and Marc Suchard * * This file is part of BEAST. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership and licensing. * * BEAST is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * BEAST 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with BEAST; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ package dr.app.tools; import dr.app.gui.FileDrop; import dr.app.util.Utils; import dr.app.gui.table.TableEditorStopper; import dr.app.gui.components.WholeNumberField; import jam.panels.ActionPanel; import jam.panels.OptionsPanel; import jam.table.TableRenderer; import javax.swing.*; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.util.ArrayList; import java.util.List; public class LogCombinerDialog { private final JFrame frame; private final OptionsPanel optionPanel; private JTable filesTable = null; private FilesTableModel filesTableModel = null; private final JComboBox fileTypeCombo = new JComboBox(new String[] { "Log Files", "Tree Files" }); private final JCheckBox decimalCheck = new JCheckBox("Convert numbers from scientific to decimal notation"); private final JCheckBox renumberOutput = new JCheckBox("Renumber output states"); private final JCheckBox resampleCheck = new JCheckBox("Resample states at lower frequency: "); private final WholeNumberField resampleText = new WholeNumberField(0, Integer.MAX_VALUE); private final List<FileInfo> files = new ArrayList<FileInfo>(); private final JTextField fileNameText = new JTextField("not selected", 16); private File outputFile = null; public LogCombinerDialog(final JFrame frame) { this.frame = frame; optionPanel = new OptionsPanel(12, 12); //this.frame = frame; JPanel panel = new JPanel(new BorderLayout()); panel.setOpaque(false); // Taxon Sets filesTableModel = new FilesTableModel(); filesTable = new JTable(filesTableModel); filesTable.getColumnModel().getColumn(0).setCellRenderer( new TableRenderer(SwingConstants.LEFT, new Insets(0, 4, 0, 4))); filesTable.getColumnModel().getColumn(0).setPreferredWidth(120); filesTable.getColumnModel().getColumn(0).setPreferredWidth(80); TableEditorStopper.ensureEditingStopWhenTableLosesFocus(filesTable); filesTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent evt) { filesTableSelectionChanged(); } }); JScrollPane scrollPane1 = new JScrollPane(filesTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); ActionPanel actionPanel1 = new ActionPanel(false); actionPanel1.setAddAction(addFileAction); actionPanel1.setRemoveAction(removeFileAction); removeFileAction.setEnabled(false); JPanel controlPanel1 = new JPanel(new FlowLayout(FlowLayout.LEFT)); controlPanel1.add(actionPanel1); panel.setBorder(BorderFactory.createEmptyBorder(6,6,6,6)); panel.add(new JLabel("Select input files:"), BorderLayout.NORTH); panel.add(scrollPane1, BorderLayout.CENTER); panel.add(actionPanel1, BorderLayout.SOUTH); Color focusColor = UIManager.getColor("Focus.color"); Border focusBorder = BorderFactory.createMatteBorder( 2, 2, 2, 2, focusColor ); new FileDrop( null, scrollPane1, focusBorder, new FileDrop.Listener() { public void filesDropped( java.io.File[] files ) { addFiles(files); } // end filesDropped }); // end FileDrop.Listener resampleText.setEnabled(false); resampleText.setColumns(12); resampleCheck.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { resampleText.setEnabled(resampleCheck.isSelected()); } }); ActionListener buttonListener = new ActionListener() { public void actionPerformed(ActionEvent ae) { FileDialog dialog = new FileDialog(frame, "Select output file...", FileDialog.SAVE); dialog.setVisible(true); if( dialog.getFile() == null ) { // the dialog was cancelled... return; } outputFile = new File(dialog.getDirectory(), dialog.getFile()); fileNameText.setText(outputFile.getName()); } }; JButton button = new JButton("Choose File..."); button.addActionListener(buttonListener); JPanel panel2 = new JPanel(new BorderLayout(0,0)); panel2.add(resampleCheck, BorderLayout.CENTER); panel2.add(resampleText, BorderLayout.EAST); optionPanel.addComponentWithLabel("File type: ", fileTypeCombo); optionPanel.addComponent(decimalCheck); optionPanel.addComponent(renumberOutput); optionPanel.addComponent(panel2); optionPanel.addSpanningComponent(panel); fileNameText.setEditable(false); JPanel panel3 = new JPanel(new BorderLayout(0,0)); panel3.add(fileNameText, BorderLayout.CENTER); panel3.add(button, BorderLayout.EAST); optionPanel.addComponentWithLabel("Output File: ", panel3); } public boolean showDialog(String title) { addFileAction.setEnabled(true); removeFileAction.setEnabled(false); filesTableModel.fireTableDataChanged(); JOptionPane optionPane = new JOptionPane(optionPanel, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null, new String[] { "Run", "Quit" }, null); optionPane.setBorder(new EmptyBorder(12, 12, 12, 12)); final JDialog dialog = optionPane.createDialog(frame, title); //dialog.setResizable(true); dialog.pack(); dialog.setVisible(true); return optionPane.getValue().equals("Run"); } public String[] getFileNames() { String[] fileArray = new String[files.size()]; for (int i = 0; i < files.size(); i++) { FileInfo fileInfo = files.get(i); fileArray[i] = fileInfo.file.getPath(); } return fileArray; } public long[] getBurnins() { long[] burnins = new long[files.size()]; for (int i = 0; i < files.size(); i++) { FileInfo fileInfo = files.get(i); burnins[i] = fileInfo.burnin; } return burnins; } public boolean isTreeFiles() { return fileTypeCombo.getSelectedIndex() == 1; } public boolean convertToDecimal() { return decimalCheck.isSelected(); } public boolean renumberOutputStates() { return renumberOutput.isSelected(); } public boolean isResampling() { return resampleCheck.isSelected(); } public long getResampleFrequency() { return resampleText.getValue(); } public String getOutputFileName() { if (outputFile == null) return null; return outputFile.getPath(); } private void filesTableSelectionChanged() { if (filesTable.getSelectedRowCount() == 0) { removeFileAction.setEnabled(false); } else { removeFileAction.setEnabled(true); } } private void addFiles(File[] fileArray) { int sel1 = files.size(); for (File file : fileArray) { FileInfo fileInfo = new FileInfo(); fileInfo.file = file; fileInfo.burnin = 0; files.add(fileInfo); } filesTableModel.fireTableDataChanged(); int sel2 = files.size() - 1; filesTable.setRowSelectionInterval(sel1, sel2); } Action addFileAction = new AbstractAction("+") { /** * */ private static final long serialVersionUID = 7602227478402204088L; public void actionPerformed(ActionEvent ae) { File file = Utils.getLoadFile("Select log file"); if (file != null) { addFiles(new File[] { file }); } } }; Action removeFileAction = new AbstractAction("-") { /** * */ private static final long serialVersionUID = 5934278375005327047L; public void actionPerformed(ActionEvent ae) { int row = filesTable.getSelectedRow(); if (row != -1) { files.remove(row); } filesTableModel.fireTableDataChanged(); if (row >= files.size()) row = files.size() - 1; if (row >= 0) { filesTable.setRowSelectionInterval(row, row); } } }; class FilesTableModel extends AbstractTableModel { /** * */ private static final long serialVersionUID = 4153326364833213013L; private final String[] columns = { "File", "Burnin" }; public FilesTableModel() { } public int getColumnCount() { return columns.length; } public int getRowCount() { return files.size(); } public Object getValueAt(int rowIndex, int columnIndex) { FileInfo fileInfo = files.get(rowIndex); if (columnIndex == 0) { return fileInfo.file.getName(); } else { return fileInfo.burnin; } } public boolean isCellEditable(int rowIndex, int columnIndex) { return (columnIndex == 1); } /** * This empty implementation is provided so users don't have to implement * this method if their data model is not editable. * * @param aValue value to assign to cell * @param rowIndex row of cell * @param columnIndex column of cell */ public void setValueAt(Object aValue, int rowIndex, int columnIndex) { FileInfo fileInfo = files.get(rowIndex); if (columnIndex == 1) { fileInfo.burnin = (Integer)aValue; } } public String getColumnName(int columnIndex) { return columns[columnIndex]; } public Class getColumnClass(int columnIndex) {return getValueAt(0, columnIndex).getClass();} } class FileInfo { File file; Integer burnin; } }