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