// 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.gui.handler; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import javax.swing.JTable; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import org.pathvisio.core.ApplicationEvent; import org.pathvisio.core.Engine.ApplicationEventListener; import org.pathvisio.core.model.PathwayElement; import org.pathvisio.core.model.PathwayElementEvent; import org.pathvisio.core.model.PathwayElementListener; import org.pathvisio.core.view.Graphics; import org.pathvisio.core.view.SelectionBox.SelectionEvent; import org.pathvisio.core.view.SelectionBox.SelectionListener; import org.pathvisio.core.view.VPathway; import org.pathvisio.gui.SwingEngine; /** * The model for the table in the Properties side panel. * Each row corresponds to a Property, the first column is the name of the * property and the second column its value. * * This will pass through the properties for zero, one or many selected * PathwayElements. If many are selected, the subset of shared Properties * is used as row set. */ public class PathwayTableModel extends AbstractTableModel implements SelectionListener, PathwayElementListener, ApplicationEventListener { private JTable table; final private Collection input; final private Map propertyValues; final private List shownProperties; private SwingEngine swingEngine; public PathwayTableModel(SwingEngine swingEngine) { input = new HashSet(); propertyValues = new HashMap(); shownProperties = new ArrayList(); this.swingEngine = swingEngine; swingEngine.getEngine().addApplicationEventListener(this); VPathway vp = swingEngine.getEngine().getActiveVPathway(); if(vp != null) vp.addSelectionListener(this); } public void setTable(JTable table) { this.table = table; } private void reset() { stopEditing(); for(PathwayElement e : input) { //System.err.println("Removed " + e); e.removeListener(this); } propertyValues.clear(); shownProperties.clear(); input.clear(); refresh(true); } private void removeInput(PathwayElement pwElm) { stopEditing(); //System.err.println("Input removed"); input.remove(pwElm); if (input.size() > 0) { updatePropertyCounts(pwElm, true); pwElm.removeListener(this); refresh(true); } else { reset(); } } private void stopEditing() { if(table != null && table.getCellEditor() != null) { table.getCellEditor().stopCellEditing(); } } private void addInput(PathwayElement pwElm) { stopEditing(); //System.err.println("Input added"); input.add(pwElm); updatePropertyCounts(pwElm, false); pwElm.addListener(this); refresh(true); } protected void refresh() { refresh(false); } public void refresh(boolean propertyCount) { if(propertyCount) { updateShownProperties(); } refreshPropertyValues(); fireTableDataChanged(); } /** * Add/remove properties to/from the table model. * * @param e the PathwayElement with the properties of interest * @param remove true if the PathwayElement's visible properties should be removed from the table model, * false if it should be added to the table model */ public void updatePropertyCounts(PathwayElement e, boolean remove) { for(Object o : PropertyDisplayManager.getVisiblePropertyKeys(e)) { PropertyView tp = propertyValues.get(o); if(tp == null) { propertyValues.put(o, tp = new PropertyView(swingEngine.getEngine().getActiveVPathway(), o)); } if(remove) { tp.removeElement(e); } else { tp.addElement(e); } } } protected void updateShownProperties() { for(PropertyView tp : propertyValues.values()) { boolean shown = shownProperties.contains(tp); if(tp.elementCount() == input.size()) { //System.err.println("\tadding " + tp + " from shown"); if(!shown) shownProperties.add(tp); } else { //System.err.println("\tremoveing " + tp + " from shown"); shownProperties.remove(tp); } Collections.sort(shownProperties); } } protected void refreshPropertyValues() { for(PropertyView p : shownProperties) { p.refreshValue(); } } public int getColumnCount() { return 2; } public int getRowCount() { return shownProperties.size(); } public PropertyView getPropertyAt(int row) { return shownProperties.get(row); } public Object getValueAt(int rowIndex, int columnIndex) { PropertyView p = getPropertyAt(rowIndex); if(columnIndex == 0) return p.getName(); else return p.getValue(); } public void setValueAt(Object aValue, int rowIndex, int columnIndex) { if(columnIndex != 0) { PropertyView p = getPropertyAt(rowIndex); p.setValue(aValue); } swingEngine.getEngine().getActiveVPathway().redrawDirtyRect(); } public String getColumnName(int column) { if(column == 0) return "Property"; return "Value"; } public boolean isCellEditable(int rowIndex, int columnIndex) { return columnIndex == 1 && swingEngine.getEngine().hasVPathway() && swingEngine.getEngine().getActiveVPathway().isEditMode(); } public void selectionEvent(SelectionEvent e) { switch(e.type) { case SelectionEvent.OBJECT_ADDED: //System.err.println("OBJECT ADDED"); if(e.affectedObject instanceof Graphics) addInput(((Graphics)e.affectedObject).getPathwayElement()); break; case SelectionEvent.OBJECT_REMOVED: //System.err.println("OBJECT REMOVED"); if(e.affectedObject instanceof Graphics) removeInput(((Graphics)e.affectedObject).getPathwayElement()); break; case SelectionEvent.SELECTION_CLEARED: //System.err.println("CLEARED"); reset(); break; } } public TableCellRenderer getCellRenderer(int row, int column) { PropertyView propHandler = getPropertyAt(row); if (propHandler != null) { if (column == 0) { return propHandler.getLabelRenderer(); } else { return propHandler.getCellRenderer(); } } return null; } public TableCellEditor getCellEditor(int row, int column) { if(column != 0) { PropertyView tp = getPropertyAt(row); if(tp != null) return tp.getCellEditor(swingEngine); } return null; } public void gmmlObjectModified(PathwayElementEvent e) { refresh(); } public void applicationEvent(ApplicationEvent e) { switch(e.getType()) { case ApplicationEvent.VPATHWAY_CREATED: ((VPathway)e.getSource()).addSelectionListener(this); break; case ApplicationEvent.VPATHWAY_DISPOSED: ((VPathway)e.getSource()).removeSelectionListener(this); reset(); // clear selected set break; } } }