// PathVisio, // a tool for data visualization and analysis using Biological Pathways // Copyright 2006-2011 BiGCaT Bioinformatics // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // package org.pathvisio.visualization.gui; import com.jgoodies.forms.factories.ButtonBarFactory; import com.jgoodies.forms.layout.CellConstraints; import com.jgoodies.forms.layout.FormLayout; import java.awt.Color; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.List; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.border.Border; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; import org.pathvisio.core.debug.Logger; import org.pathvisio.desktop.gex.GexManager; import org.pathvisio.desktop.visualization.ColorGradient; import org.pathvisio.desktop.visualization.ColorRule; import org.pathvisio.desktop.visualization.ColorSet; import org.pathvisio.desktop.visualization.ColorSetEvent; import org.pathvisio.desktop.visualization.ColorSetManager.ColorSetListener; /** * Panel for editing a color set, a combination of * rules and/or a gradient */ public class ColorSetPanel extends JPanel implements ActionListener { static final String ACTION_GRADIENT = "Gradient:"; static final String ACTION_ADD_RULE = "Add rule"; static final String ACTION_REMOVE_RULE = "Remove rule"; static final String ACTION_COMBO = "combo"; private ColorSet colorSet; private ColorGradientCombo gradientCombo; private JCheckBox gradientCheck; private ColorRulePanel rulesPanel; private ColorRuleTableModel crtm; private JPanel valuesPanel; private JPanel gradientPanel; private ColorGradient gradient; private JTable rulesTable; ColorSetPanel (ColorSet cs, GexManager gexManager) { colorSet = cs; setLayout (new FormLayout( "pref:grow", "pref, 3dlu, pref, 3dlu, [pref,100dlu], 3dlu, pref, 3dlu, pref" )); gradientPanel = new JPanel(); CellConstraints cc = new CellConstraints(); add(gradientPanel, cc.xy(1, 1)); gradientPanel.setLayout(new FormLayout( "pref, 3dlu, pref:grow", "pref, pref, pref" )); gradientCheck = new JCheckBox(ACTION_GRADIENT); gradientCheck.setActionCommand(ACTION_GRADIENT); gradientCheck.addActionListener(this); gradientCombo = new ColorGradientCombo(); gradientCombo.setActionCommand(ACTION_COMBO); gradientCombo.addActionListener(this); gradientPanel.add(gradientCheck, cc.xy(1,1)); gradientPanel.add(gradientCombo, cc.xy(3, 1)); add(new JLabel("Rules:"), cc.xy(1, 3, "l, c")); rulesPanel = new ColorRulePanel(gexManager); rulesPanel.setBorder(BorderFactory.createEtchedBorder()); crtm = new ColorRuleTableModel(colorSet); rulesTable = new JTable(crtm); rulesTable.setDefaultRenderer(Color.class, new ColorRenderer(true)); add(new JScrollPane(rulesTable), cc.xy(1, 5)); add(new JScrollPane(rulesPanel), cc.xy(1, 7)); JButton add = new JButton(ACTION_ADD_RULE); add.setActionCommand(ACTION_ADD_RULE); add.addActionListener(this); JButton remove = new JButton(ACTION_REMOVE_RULE); remove.setActionCommand(ACTION_REMOVE_RULE); remove.addActionListener(this); JPanel btnPanel = ButtonBarFactory.buildAddRemoveBar(add, remove); add(btnPanel, cc.xy(1, 9)); refresh(); } /** TableCellRenderer that displays a single RGB color */ public class ColorRenderer extends JLabel implements TableCellRenderer { Border unselectedBorder = null; Border selectedBorder = null; boolean isBordered = true; public ColorRenderer(boolean isBordered) { this.isBordered = isBordered; setOpaque(true); //MUST do this for background to show up. } public Component getTableCellRendererComponent( JTable table, Object color, boolean isSelected, boolean hasFocus, int row, int column) { Color newColor = (Color)color; setBackground(newColor); if (isBordered) { if (isSelected) { if (selectedBorder == null) { selectedBorder = BorderFactory.createMatteBorder(2,5,2,5, table.getSelectionBackground()); } setBorder(selectedBorder); } else { if (unselectedBorder == null) { unselectedBorder = BorderFactory.createMatteBorder(2,5,2,5, table.getBackground()); } setBorder(unselectedBorder); } } setToolTipText("RGB value: " + newColor.getRed() + ", " + newColor.getGreen() + ", " + newColor.getBlue()); return this; } } private static class ColorRuleTableModel extends AbstractTableModel implements ColorSetListener { private final ColorSet cs; private List colorRules; ColorRuleTableModel (ColorSet cs) { this.cs = cs; cs.getColorSetManager().addListener(this); colorRules = cs.getColorRules(); } ColorRule getRule (int index) { return colorRules.get (index); } public int getColumnCount() { return 2; } public int getRowCount() { return colorRules.size(); } public Object getValueAt(int row, int col) { switch (col) { case 0: return colorRules.get(row).getColor(); default: return "" + colorRules.get(row).getExpression(); } } public String getColumnName (int col) { final String colNames[] = {"Color", "Rule" }; return colNames[col]; } public Class getColumnClass (int col) { switch (col) { case 0: return Color.BLACK.getClass(); default: return "".getClass(); } } // triggered by changes in any color set // TODO: distinghuish changes in # of rows and changes in row data public void colorSetEvent(ColorSetEvent e) { fireTableDataChanged(); // fireTableRowsUpdated(0, getRowCount()); } } private void refresh() { //Get default gradients List gradients = ColorGradient.createDefaultGradients(); //Set gradients gradient = colorSet.getGradient(); if(gradient != null) { gradientCheck.setSelected(true); ColorGradient preset = null; for(ColorGradient cg : gradients) { if(cg.equalsPreset(gradient)) { preset = cg; } } gradients.remove(preset); gradients.add(gradient); } else { gradientCheck.setSelected(false); } gradientCombo.setGradients(gradients); gradientCombo.setSelectedGradient(gradient); //Refresh gradient values refreshValuesPanel(); //Generate rules panel rulesTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() { public void valueChanged(ListSelectionEvent e) { int selected = rulesTable.getSelectedRow(); rulesPanel.setInput (selected >= 0 ? crtm.getRule(selected) : null); } } ); revalidate(); } private void refreshValuesPanel() { if(valuesPanel != null) { gradientPanel.remove(valuesPanel); } if(gradient != null) { valuesPanel = new ColorGradientPanel(gradient); gradientPanel.add(valuesPanel, new CellConstraints().xy(3, 2)); } revalidate(); } public void actionPerformed(ActionEvent e) { String action = e.getActionCommand(); Logger.log.info(action); if(ACTION_ADD_RULE.equals(action)) { colorSet.addRule(new ColorRule()); int selected = crtm.getRowCount() - 1; rulesTable.getSelectionModel().setSelectionInterval(selected, selected); } else if(ACTION_REMOVE_RULE.equals(action)) { int lead = rulesTable.getSelectedRow(); for (int index : rulesTable.getSelectedRows()) { ColorRule cr = crtm.getRule(index); colorSet.removeRule(cr); } if (lead > crtm.getRowCount()) lead = crtm.getRowCount() - 1; rulesTable.getSelectionModel().setSelectionInterval (lead, lead); } else if(ACTION_GRADIENT.equals(action)) { if(gradientCheck.isSelected()) { gradientCombo.setSelectedIndex(0); } else { gradientCombo.setSelectedIndex(-1); } } else if(ACTION_COMBO.equals(action)) { gradient = gradientCombo.getSelectedGradient(); colorSet.setGradient(gradient); if(gradient != null) { gradientCheck.setSelected(true); } else { gradientCheck.setSelected(false); } refreshValuesPanel(); } } }