package dr.app.bss;
import jam.framework.Exportable;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import org.virion.jam.panels.ActionPanel;
@SuppressWarnings("serial")
public class PartitionsPanel extends JPanel implements Exportable {
private BeagleSequenceSimulatorFrame frame = null;
private PartitionDataList dataList = null;
private JTable partitionTable = null;
private PartitionTableModel partitionTableModel = null;
private JScrollPane scrollPane;
private TableColumn column;
private int partitionsCount = 1;
private Action addPartitionAction = new AbstractAction("+") {
public void actionPerformed(ActionEvent ae) {
partitionTableModel.addDefaultRow();
partitionsCount++;
setPartitions();
}// END: actionPerformed
};
private Action removePartitionAction = new AbstractAction("-") {
public void actionPerformed(ActionEvent ae) {
if (partitionsCount > 1) {
partitionTableModel.deleteRow(partitionsCount - 1);
partitionsCount--;
setPartitions();
}
}// END: actionPerformed
};
public PartitionsPanel(final BeagleSequenceSimulatorFrame frame,
final PartitionDataList dataList) {
super();
this.frame = frame;
this.dataList = dataList;
partitionTableModel = new PartitionTableModel(this.dataList);
partitionTableModel
.addTableModelListener(new PartitionTableModelListener());
partitionTable = new JTable(partitionTableModel);
partitionTable.setFillsViewportHeight(true);
partitionTable.getTableHeader().setReorderingAllowed(false);
partitionTable.addMouseListener(new JTableButtonMouseListener(
partitionTable));
setLayout(new BorderLayout());
scrollPane = new JScrollPane(partitionTable,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
RowNumberTable rowNumberTable = new RowNumberTable(partitionTable);
scrollPane.setRowHeaderView(rowNumberTable);
scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER,
rowNumberTable.getTableHeader());
scrollPane.getViewport().setOpaque(false);
add(scrollPane, BorderLayout.CENTER);
column = partitionTable.getColumnModel().getColumn(
PartitionTableModel.PARTITION_TREE_INDEX);
column.setCellEditor(new JTableComboBoxCellEditor());
column.setCellRenderer(new JTableComboBoxCellRenderer());
column = partitionTable.getColumnModel().getColumn(
PartitionTableModel.BRANCH_SUBSTITUTION_MODEL_INDEX);
column.setCellRenderer(new JTableButtonCellRenderer());
column.setCellEditor(new JTableButtonCellEditor());
column = partitionTable.getColumnModel().getColumn(
PartitionTableModel.SITE_RATE_MODEL_INDEX);
column.setCellRenderer(new JTableButtonCellRenderer());
column.setCellEditor(new JTableButtonCellEditor());
column = partitionTable.getColumnModel().getColumn(
PartitionTableModel.CLOCK_RATE_MODEL_INDEX);
column.setCellRenderer(new JTableButtonCellRenderer());
column.setCellEditor(new JTableButtonCellEditor());
column = partitionTable.getColumnModel().getColumn(
PartitionTableModel.FREQUENCY_MODEL_INDEX);
column.setCellRenderer(new JTableButtonCellRenderer());
column.setCellEditor(new JTableButtonCellEditor());
ActionPanel actionPanel = new ActionPanel(false);
actionPanel.setAddAction(addPartitionAction);
actionPanel.setRemoveAction(removePartitionAction);
add(actionPanel, BorderLayout.SOUTH);
setPartitions();
}// END: Constructor
public JComponent getExportableComponent() {
return this;
}// END: getExportableComponent
private void setPartitions() {
addPartitionAction.setEnabled(true);
if (partitionsCount == 1) {
removePartitionAction.setEnabled(false);
} else {
removePartitionAction.setEnabled(true);
}
ColumnResizer.adjustColumnPreferredWidths(partitionTable);
partitionTable.revalidate();
this.updateUI();
}// END: setPartitions
// Listen to tree choices, set tree model in partition data
private class PartitionTableModelListener implements TableModelListener {
public void tableChanged(TableModelEvent ev) {
if (ev.getType() == TableModelEvent.UPDATE) {
int row = ev.getFirstRow();
int column = ev.getColumn();
if (column == PartitionTableModel.PARTITION_TREE_INDEX) {
File value = (File) partitionTableModel.getValueAt(row, column);
// System.out.println(value);
dataList.get(row).treeModel = dataList.forestMap.get(value);
}// END: column check
}// END: event check
frame.fireModelChanged();
}// END: tableChanged
}// END: InteractiveTableModelListener
public class JTableComboBoxCellRenderer extends JComboBox implements
TableCellRenderer {
public JTableComboBoxCellRenderer() {
super();
setOpaque(true);
}// END: Constructor
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
if (isSelected) {
this.setForeground(table.getSelectionForeground());
this.setBackground(table.getSelectionBackground());
} else {
this.setForeground(table.getForeground());
this.setBackground(table.getBackground());
}
// Select the current value
setSelectedItem(value);
if (value != null) {
removeAllItems();
addItem(value);
}
return this;
}
}// END: JTableComboBoxCellRenderer class
private class JTableComboBoxCellEditor extends DefaultCellEditor {
public JTableComboBoxCellEditor() {
super(new JComboBox());
}
public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column) {
((JComboBox) editorComponent).removeAllItems();
if (column == PartitionTableModel.PARTITION_TREE_INDEX) {
for (File file : dataList.forestMap.keySet()) {
((JComboBox) editorComponent).addItem(file);
}
}
((JComboBox) editorComponent).setSelectedItem(value);
delegate.setValue(value);
return editorComponent;
}
}// END: JTableComboBoxCellEditor class
private class JTableButtonCellRenderer extends JButton implements
TableCellRenderer {
public JTableButtonCellRenderer() {
super();
setOpaque(true);
}// END: Constructor
@Override
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus, int row,
int column) {
setEnabled(table.isEnabled());
JButton button = (JButton) value;
setBackground(isSelected ? table.getSelectionBackground() : table
.getBackground());
// button.setText((value == null) ? "" : value.toString());
return button;
}
}// END: JTableButtonRenderer class
private class JTableButtonCellEditor extends DefaultCellEditor {
protected JButton button;
private String label;
private boolean isPushed;
public JTableButtonCellEditor() {
super(new JCheckBox());
button = new JButton();
button.setOpaque(true);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
fireEditingStopped();
}
});
}
public Component getTableCellEditorComponent(JTable table,
Object value, boolean isSelected, int row, int column) {
if (isSelected) {
button.setForeground(table.getSelectionForeground());
button.setBackground(table.getSelectionBackground());
} else {
button.setForeground(table.getForeground());
button.setBackground(table.getBackground());
}
// TODO: set label from model name
label = (value == null) ? "" : value.toString();
button.setText(label);
isPushed = true;
return button;
}
public Object getCellEditorValue() {
if (isPushed) {
//
}
isPushed = false;
return new String(label);
}
public boolean stopCellEditing() {
isPushed = false;
return super.stopCellEditing();
}
protected void fireEditingStopped() {
super.fireEditingStopped();
}
}// END: JTableButtonCellEditor
private class JTableButtonMouseListener extends MouseAdapter {
private final JTable table;
public JTableButtonMouseListener(JTable table) {
this.table = table;
}// END: Constructor
public void mouseClicked(MouseEvent e) {
int column = table.getColumnModel().getColumnIndexAtX(e.getX());
int row = e.getY() / table.getRowHeight();
if (row < table.getRowCount() && row >= 0 && column < table.getColumnCount() && column >= 0) {
Object value = table.getValueAt(row, column);
if (value instanceof JButton) {
((JButton) value).doClick();
}// END: JButton check
}// END: placement check
}// END: mouseClicked
}// END: JTableButtonMouseListener class
}// END: class