/*
* AncestralStatesPanel.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.beauti.ancestralStatesPanel;
import dr.app.beauti.BeautiFrame;
import dr.app.beauti.BeautiPanel;
import dr.app.beauti.components.ancestralstates.AncestralStatesComponentOptions;
import dr.app.beauti.options.AbstractPartitionData;
import dr.app.beauti.options.BeautiOptions;
import dr.app.gui.table.TableEditorStopper;
import dr.evolution.datatype.DataType;
import jam.framework.Exportable;
import jam.table.TableRenderer;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.plaf.BorderUIResource;
import javax.swing.table.*;
import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
/**
* @author Andrew Rambaut
* @author Alexei Drummond
* @version $Id: ModelPanel.java,v 1.17 2006/09/05 13:29:34 rambaut Exp $
*/
public class AncestralStatesPanel extends BeautiPanel implements Exportable {
private static final long serialVersionUID = 2778103564318492601L;
private static final int MINIMUM_TABLE_WIDTH = 140;
JTable partitionTable = null;
PartitionTableModel partitionTableModel = null;
BeautiOptions options = null;
JPanel optionsPanelParent;
AbstractPartitionData currentPartition = null;
Map<AbstractPartitionData, AncestralStatesOptionsPanel> optionsPanels = new HashMap<AbstractPartitionData, AncestralStatesOptionsPanel>();
TitledBorder optionsBorder;
BeautiFrame frame = null;
boolean settingOptions = false;
public AncestralStatesPanel(BeautiFrame parent) {
super();
this.frame = parent;
partitionTableModel = new PartitionTableModel();
partitionTable = new JTable(partitionTableModel);
partitionTable.getTableHeader().setReorderingAllowed(false);
partitionTable.getTableHeader().setResizingAllowed(false);
// modelTable.getTableHeader().setDefaultRenderer(
// new HeaderRenderer(SwingConstants.LEFT, new Insets(0, 4, 0, 4)));
final TableColumnModel model = partitionTable.getColumnModel();
final TableColumn tableColumn0 = model.getColumn(0);
TableEditorStopper.ensureEditingStopWhenTableLosesFocus(partitionTable);
partitionTable.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
partitionTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
selectionChanged();
}
});
JScrollPane scrollPane = new JScrollPane(partitionTable,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setOpaque(false);
JPanel panel = new JPanel(new BorderLayout(0, 0));
panel.setOpaque(false);
panel.add(scrollPane, BorderLayout.CENTER);
panel.setMinimumSize(new Dimension(MINIMUM_TABLE_WIDTH, 0));
optionsPanelParent = new JPanel(new FlowLayout(FlowLayout.CENTER));
optionsPanelParent.setOpaque(false);
optionsBorder = new TitledBorder("Ancestral state options:");
optionsPanelParent.setBorder(optionsBorder);
setCurrentPartition(null);
JScrollPane scrollPane2 = new JScrollPane(optionsPanelParent, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane2.setOpaque(false);
scrollPane2.setBorder(null);
scrollPane2.getViewport().setOpaque(false);
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panel, scrollPane2);
splitPane.setDividerLocation(MINIMUM_TABLE_WIDTH);
splitPane.setContinuousLayout(true);
splitPane.setBorder(BorderFactory.createEmptyBorder());
splitPane.setOpaque(false);
setOpaque(false);
setBorder(new BorderUIResource.EmptyBorderUIResource(new Insets(12, 12, 12, 12)));
setLayout(new BorderLayout(0, 0));
add(splitPane, BorderLayout.CENTER);
}
private void resetPanel() {
if (!options.hasData()) {
currentPartition = null;
optionsPanels.clear();
optionsPanelParent.removeAll();
}
}
public void setOptions(BeautiOptions options) {
this.options = options;
resetPanel();
settingOptions = true;
int selRow = partitionTable.getSelectedRow();
partitionTableModel.fireTableDataChanged();
if (options.getDataPartitions().size() > 0) {
if (selRow < 0) {
selRow = 0;
}
partitionTable.getSelectionModel().setSelectionInterval(selRow, selRow);
setCurrentPartition(options.getDataPartitions().get(selRow));
}
AncestralStatesOptionsPanel panel = optionsPanels.get(currentPartition);
if (panel != null) {
panel.setupPanel();
}
settingOptions = false;
validate();
repaint();
}
public void getOptions(BeautiOptions options) {
}
public void fireModelChanged() {
frame.setDirty();
}
private void selectionChanged() {
if (settingOptions) return;
int selRow = partitionTable.getSelectedRow();
if (selRow >= options.getDataPartitions().size()) {
selRow = 0;
partitionTable.getSelectionModel().setSelectionInterval(selRow, selRow);
}
if (selRow >= 0) {
setCurrentPartition(options.getDataPartitions().get(selRow));
// frame.modelSelectionChanged(!isUsed(selRow));
}
}
/**
* Sets the current partition that this panel is displaying
*
* @param partition the new partition to display
*/
private void setCurrentPartition(AbstractPartitionData partition) {
if (partition != null) {
if (currentPartition != null) optionsPanelParent.removeAll();
AncestralStatesOptionsPanel panel = optionsPanels.get(partition);
if (panel == null) {
panel = new AncestralStatesOptionsPanel(this, options, partition);
optionsPanels.put(partition, panel);
}
currentPartition = partition;
panel.setupPanel();
optionsPanelParent.add(panel);
updateBorder();
}
}
private void updateBorder() {
String title;
switch (currentPartition.getDataType().getType()) {
case DataType.NUCLEOTIDES:
title = "Nucleotide";
break;
case DataType.AMINO_ACIDS:
title = "Amino Acid";
break;
case DataType.TWO_STATES:
title = "Binary";
break;
case DataType.GENERAL:
title = "Discrete Traits";
break;
case DataType.CONTINUOUS:
title = "Continuous Traits";
break;
case DataType.MICRO_SAT:
title = "Microsatellite";
break;
default:
throw new IllegalArgumentException("Unsupported data type");
}
optionsBorder.setTitle(title + " Partition - " + currentPartition.getName());
repaint();
}
public JComponent getExportableComponent() {
return this;
}
class PartitionTableModel extends AbstractTableModel {
/**
*
*/
private static final long serialVersionUID = -6707994233020715574L;
String[] columnNames = {"Partition"};
public PartitionTableModel() {
}
public int getColumnCount() {
return columnNames.length;
}
public int getRowCount() {
if (options == null) return 0;
return options.getDataPartitions().size();
}
public Object getValueAt(int row, int col) {
AbstractPartitionData partition = options.getDataPartitions().get(row);
switch (col) {
case 0:
return partition.getName();
default:
throw new IllegalArgumentException("unknown column, " + col);
}
}
public boolean isCellEditable(int row, int col) {
return false;
}
public String getColumnName(int column) {
return columnNames[column];
}
public Class getColumnClass(int c) {
if (getRowCount() == 0) {
return Object.class;
}
return getValueAt(0, c).getClass();
}
public String toString() {
StringBuffer buffer = new StringBuffer();
buffer.append(getColumnName(0));
for (int j = 1; j < getColumnCount(); j++) {
buffer.append("\t");
buffer.append(getColumnName(j));
}
buffer.append("\n");
for (int i = 0; i < getRowCount(); i++) {
buffer.append(getValueAt(i, 0));
for (int j = 1; j < getColumnCount(); j++) {
buffer.append("\t");
buffer.append(getValueAt(i, j));
}
buffer.append("\n");
}
return buffer.toString();
}
}
}