/*
* TaxaEditor.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.bss;
import jam.panels.ActionPanel;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.PrintWriter;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import dr.evolution.util.Taxa;
import dr.evolution.util.Taxon;
public class TaxaEditor {
private PartitionDataList dataList;
private MainFrame frame;
private int row;
// private MutableTaxonList taxonList;
private int taxonCount;
private static final int minCount = 0;
// Window
private JDialog window;
private Frame owner;
// Menubar
private JMenuBar menu;
// Buttons with options
private JButton load;
private JButton save;
private JButton done;
private JButton cancel;
// Data, model & stuff for JTable
private JTable table;
private TaxaEditorTableModel taxaEditorTableModel;
@SuppressWarnings("serial")
private Action addTaxonAction = new AbstractAction("+") {
public void actionPerformed(ActionEvent ae) {
taxaEditorTableModel.addEmptyRow();
setTaxa();
}// END: actionPerformed
};
@SuppressWarnings("serial")
private Action removeTaxonAction = new AbstractAction("-") {
public void actionPerformed(ActionEvent ae) {
if (taxonCount > minCount) {
taxaEditorTableModel.removeLastRow();
setTaxa();
}
}// END: actionPerformed
};
public TaxaEditor(MainFrame frame, PartitionDataList dataList, int row) {
this.frame = frame;
this.dataList = dataList;
this.row = row;
// taxonList = new Taxa();
taxaEditorTableModel = new TaxaEditorTableModel();
// Setup Main Menu buttons
load = new JButton("Load", Utils.createImageIcon(Utils.TEXT_FILE_ICON));
save = new JButton("Save", Utils.createImageIcon(Utils.SAVE_ICON));
done = new JButton("Done", Utils.createImageIcon(Utils.CHECK_ICON));
cancel = new JButton("Cancel", Utils.createImageIcon(Utils.CLOSE_ICON));
// Add Main Menu buttons listeners
load.addActionListener(new ListenLoadTaxaFile());
save.addActionListener(new ListenSaveTaxaFile());
done.addActionListener(new ListenOk());
cancel.addActionListener(new ListenCancel());
// Setup menu
menu = new JMenuBar();
menu.setLayout(new BorderLayout());
JPanel buttonsHolder = new JPanel();
buttonsHolder.setOpaque(false);
buttonsHolder.add(load);
buttonsHolder.add(save);
buttonsHolder.add(done);
buttonsHolder.add(cancel);
menu.add(buttonsHolder, BorderLayout.WEST);
// Setup table
table = new JTable();
table.setModel(taxaEditorTableModel);
table.setSurrendersFocusOnKeystroke(true);
JScrollPane scrollPane = new JScrollPane(table,
ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
RowNumberTable rowNumberTable = new RowNumberTable(table);
scrollPane.setRowHeaderView(rowNumberTable);
scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER,
rowNumberTable.getTableHeader());
ActionPanel actionPanel = new ActionPanel(false);
actionPanel.setAddAction(addTaxonAction);
actionPanel.setRemoveAction(removeTaxonAction);
// Setup window
owner = Utils.getActiveFrame();
window = new JDialog(owner, "Edit taxa set...");
window.getContentPane().add(menu, BorderLayout.NORTH);
window.getContentPane().add(scrollPane);
window.getContentPane().add(actionPanel, BorderLayout.SOUTH);
window.pack();
window.setLocationRelativeTo(owner);
setTaxa();
}// END: LocationCoordinatesEditor()
public void launch() {
if (SwingUtilities.isEventDispatchThread()) {
showWindow();
} else {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
showWindow();
}
});
}// END: edt check
}// END: launch
public void showWindow() {
// Display Frame
window.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
window.setSize(new Dimension(400, 400));
window.setMinimumSize(new Dimension(100, 100));
window.setResizable(true);
window.setVisible(true);
}// END: showWindow
private void setTaxa() {
taxonCount = taxaEditorTableModel.getRowCount();
addTaxonAction.setEnabled(true);
if (taxonCount == minCount) {
removeTaxonAction.setEnabled(false);
} else {
removeTaxonAction.setEnabled(true);
}
ColumnResizer.adjustColumnPreferredWidths(table);
}// END: setPartitions
private class ListenLoadTaxaFile implements ActionListener {
public void actionPerformed(ActionEvent ev) {
JFileChooser chooser = new JFileChooser();
chooser.setDialogTitle("Select taxa file...");
chooser.setMultiSelectionEnabled(false);
chooser.setCurrentDirectory(frame.getWorkingDirectory());
int returnValue = chooser.showOpenDialog(Utils.getActiveFrame());
if (returnValue == JFileChooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile();
if (file != null) {
loadTaxaFile(file);
File tmpDir = chooser.getCurrentDirectory();
if (tmpDir != null) {
frame.setWorkingDirectory(tmpDir);
}
}// END: file opened check
}// END: dialog cancelled check
}// END: actionPerformed
}// END: ListenLoadTaxaFile
private void loadTaxaFile(File file) {
try {
Taxa taxa = new Taxa();
String[] lines = Utils.loadStrings(file.getAbsolutePath());
Taxon taxon;
for (int i = 0; i < lines.length; i++) {
String[] line = lines[i].split("\\s+");
taxon = new Taxon(line[TaxaEditorTableModel.NAME_INDEX]);
taxon.setAttribute(Utils.ABSOLUTE_HEIGHT,
Double.valueOf(line[TaxaEditorTableModel.HEIGHT_INDEX]));
taxa.addTaxon(taxon);
}// END: i loop
updateTable(taxa);
} catch (Exception e) {
Utils.handleException(e);
}// END: try-catch block
}// END: loadTaxaFile
private class ListenSaveTaxaFile implements ActionListener {
public void actionPerformed(ActionEvent ev) {
JFileChooser chooser = new JFileChooser();
chooser.setDialogTitle("Save taxa file...");
chooser.setMultiSelectionEnabled(false);
chooser.setCurrentDirectory(frame.getWorkingDirectory());
int returnVal = chooser.showSaveDialog(Utils.getActiveFrame());
if (returnVal == JFileChooser.APPROVE_OPTION) {
File file = chooser.getSelectedFile();
saveTaxaFile(file.getAbsolutePath());
File tmpDir = chooser.getCurrentDirectory();
if (tmpDir != null) {
frame.setWorkingDirectory(tmpDir);
}
}// END: approve check
}// END: actionPerformed
}// END: ListenSaveLocationCoordinates
private void saveTaxaFile(String filename) {
try {
boolean header = false;
PrintWriter writer = new PrintWriter(filename);
writer.print(taxaEditorTableModel.toString(header));
writer.close();
} catch (Exception e) {
Utils.handleException(e);
}
}// END: save2DArray
private class ListenOk implements ActionListener {
public void actionPerformed(ActionEvent ev) {
doOk();
}// END: actionPerformed
}// END: ListenOk
private void doOk() {
frame.setBusy();
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
// Executed in background thread
public Void doInBackground() {
try {
// delete taxa connected to this row
String value = dataList.recordsList.get(row).getName();
Utils.removeTaxaWithAttributeValue(dataList,
Utils.TREE_FILENAME, value);
String name = String.valueOf("TaxaSet").concat(
String.valueOf(row + 1));
Taxa taxa = taxaEditorTableModel.getTaxaSet();
TreesTableRecord record = new TreesTableRecord(name, taxa);
dataList.recordsList.set(row, record);
dataList.allTaxa.addTaxa(taxa);
// treesTableModel.setRow(row, record);
} catch (Exception e) {
Utils.handleException(e);
}// END: try-catch block
return null;
}// END: doInBackground()
// Executed in event dispatch thread
public void done() {
frame.setIdle();
frame.fireTaxaChanged();
window.setVisible(false);
}// END: done
};
worker.execute();
}// END: doOk
private class ListenCancel implements ActionListener {
public void actionPerformed(ActionEvent ev) {
window.setVisible(false);
}// END: actionPerformed
}// END: ListenCancel
public void updateTable(Taxa taxa) {
taxaEditorTableModel.setTaxaSet(taxa);
taxaEditorTableModel.fireTaxonListChanged();
setTaxa();
}// END: updateTable
}// END: class