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