/*******************************************************************************
* GenPlay, Einstein Genome Analyzer
* Copyright (C) 2009, 2014 Albert Einstein College of Medicine
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* Authors: Julien Lajugie <julien.lajugie@einstein.yu.edu>
* Nicolas Fourel <nicolas.fourel@einstein.yu.edu>
* Eric Bouhassira <eric.bouhassira@einstein.yu.edu>
*
* Website: <http://genplay.einstein.yu.edu>
******************************************************************************/
package edu.yu.einstein.genplay.gui.dialog.layerChooser;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import edu.yu.einstein.genplay.gui.customComponent.tableComponents.BooleanRadioButtonEditor;
import edu.yu.einstein.genplay.gui.customComponent.tableComponents.BooleanRadioButtonRenderer;
import edu.yu.einstein.genplay.gui.projectFrame.ProjectFrame;
import edu.yu.einstein.genplay.gui.track.layer.ColoredLayer;
import edu.yu.einstein.genplay.gui.track.layer.Layer;
import edu.yu.einstein.genplay.gui.track.layer.LayerType;
import edu.yu.einstein.genplay.util.JTables;
import edu.yu.einstein.genplay.util.Utils;
import edu.yu.einstein.genplay.util.colors.Colors;
/**
* Panel to select or unselect layers.
* A list of selectable layer types can be specified.
* A list of layers already selected can be specified.
* @author Julien Lajugie
*/
public class LayerChooserPanel extends JPanel implements TableModelListener {
/**
* Simple {@link TableCellRenderer} that returns a disabled component for the lines where the layer type is not selectable
* @author Julien Lajugie
*/
private class LayerTableCellRenderer extends DefaultTableCellRenderer implements TableCellRenderer {
private static final long serialVersionUID = 9025676810770612025L; // generated serial ID
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value == null) {
return table.getDefaultRenderer(String.class).getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
Component renderedComponent = table.getDefaultRenderer(value.getClass()).getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
renderedComponent.setEnabled(true);
Layer<?> layer = layers.get(row);
// write the layer name with the color of the layer
if ((layer != null) && (layer instanceof ColoredLayer) && !isSelected) {
Color layerColor = ((ColoredLayer) layer).getColor();
renderedComponent.setForeground(layerColor);
}
// make the unselectable row (because the layer type is not accepted) different
if (layer != null) {
LayerType layerType = layer.getType();
if ((selectableLayerTypes != null) && !layerType.isContainedIn(selectableLayerTypes)) {
renderedComponent.setForeground(Colors.GREY);
renderedComponent.setFont(renderedComponent.getFont().deriveFont(Font.ITALIC));
} else {
renderedComponent.setFont(renderedComponent.getFont().deriveFont(Font.BOLD));
}
}
return renderedComponent;
}
}
/** Generated ID */
private static final long serialVersionUID = 3444530544106287254L;
/** Selected layers change property name */
public static final String SELECTED_LAYERS_PROPERTY_NAME = "Selected Layers Change";
private final JTable layerTable; // layer table
private final LayerChooserTableModel tableModel; // layer table model
private final List<Layer<?>> layers; // List of layers displayed in the table
private final List<Layer<?>> selectedLayers; // List of layers selected
private final LayerType[] selectableLayerTypes; // type of layer types that can be selected. Any type can be selected if null
private final boolean isMultiselectable; // true if more than one layer can be selected
/**
* Constructor of {@link LayerChooserDialog}
* @param layers List of layers displayed in the table
* @param selectedLayers List of layers selected
* @param selectableLayerTypes type of layer types that can be selected. Any type can be selected if null
* @param isMultiselectable true if more than one layer can be selected
*/
public LayerChooserPanel (List<Layer<?>> layers,
List<Layer<?>> selectedLayers,
LayerType[] selectableLayerTypes,
boolean isMultiselectable) {
super();
this.layers = layers;
if (selectedLayers == null) {
this.selectedLayers = new ArrayList<Layer<?>>();
} else {
this.selectedLayers = selectedLayers;
}
this.selectableLayerTypes = selectableLayerTypes;
this.isMultiselectable = isMultiselectable;
// table
layerTable = new JTable();
// table model
tableModel = new LayerChooserTableModel(layers, this.selectedLayers, selectableLayerTypes, isMultiselectable);
tableModel.addTableModelListener(this);
init();
}
/**
* @return the first element of the list of selected layers.
* This method return the only layer selected if the property
* isMultiselectable is set to false.
*/
public Layer<?> getSelectedLayer() {
if (selectedLayers.isEmpty()) {
return null;
} else {
return selectedLayers.get(0);
}
}
/**
* @return the list of selected layers
*/
public List<Layer<?>> getSelectedLayers() {
return selectedLayers;
}
/**
* @return the table displaying the layers
*/
public JTable getTable() {
return layerTable;
}
/**
* Initializes dialog components
*/
private void init() {
layerTable.setModel(tableModel);
// other table properties
layerTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
JScrollPane scrollPane = new JScrollPane(layerTable);
scrollPane.getVerticalScrollBar().setUnitIncrement(Utils.SCROLL_INCREMENT_UNIT);
scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
initializeColumnProperties();
// table renderer and editors if the multiselectable property is set to false so we have radio buttons instead of check boxes
if (!isMultiselectable) {
layerTable.getColumnModel().getColumn(LayerChooserTableModel.LAYER_SELECTION_INDEX).setCellRenderer(new BooleanRadioButtonRenderer());
layerTable.getColumnModel().getColumn(LayerChooserTableModel.LAYER_SELECTION_INDEX).setCellEditor(new BooleanRadioButtonEditor());
}
//Select button
JButton jbSelect = new JButton("Select");
jbSelect.setToolTipText(ProjectFrame.SELECT_FILES);
jbSelect.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
tableModel.setSelectedValues(layerTable.getSelectedRows(), true);
}
});
//Unselect button
JButton jbUnselect = new JButton("Unselect");
jbUnselect.setToolTipText(ProjectFrame.UNSELECT_FILES);
jbUnselect.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
tableModel.setSelectedValues(layerTable.getSelectedRows(), false);
}
});
//TopPane
JPanel buttonPanel = new JPanel();
buttonPanel.add(jbSelect);
buttonPanel.add(jbUnselect);
//Add panels
BorderLayout border = new BorderLayout();
setLayout(border);
add(scrollPane, BorderLayout.CENTER);
add(buttonPanel, BorderLayout.SOUTH);
}
/**
* This method initializes the column properties:
* - name
* - width
* - resizable
*/
private void initializeColumnProperties () {
TableCellRenderer tableCellRenderer = new LayerTableCellRenderer();
TableColumn column = null;
for (int i = 0; i < LayerChooserTableModel.COLUMN_NAMES.length; i++) {
column = layerTable.getColumnModel().getColumn(i);
column.setHeaderValue(LayerChooserTableModel.COLUMN_NAMES[i]);
column.setResizable(true);
column.setCellRenderer(tableCellRenderer);
JTables.packColumn(layerTable, i, 2);
}
}
@Override
public void tableChanged(TableModelEvent e) {
firePropertyChange(SELECTED_LAYERS_PROPERTY_NAME, null, selectedLayers);
}
}