// 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.HashSet; import java.util.List; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import org.pathvisio.core.model.PathwayElement; import org.pathvisio.core.model.Property; import org.pathvisio.core.view.VPathway; import org.pathvisio.gui.SwingEngine; /** * PropertyView ties together functionality to view / edit a property * on one or more PathwayElements at the same time. */ public class PropertyView implements Comparable { private VPathway vPathway; Collection elements; private Object value; private Object type; private int counter = 0; boolean different; private TableCellRenderer propertyLabelRenderer = new PropertyLabelRenderer(); /** * @param aType is either String for a dynamic property, * or StaticProperty for a static property; * @param aVPathway is used to register undo actions when setting a value * to this property. May be null, in which case no undo actions are registered. */ public PropertyView(VPathway aVPathway, Object aType) { type = aType; if (!(type instanceof String || type instanceof Property)) { throw new IllegalArgumentException(); } vPathway = aVPathway; elements = new HashSet(); } /** * Add a PathwayElement to the set of elements that are viewed / edited together */ public void addElement(PathwayElement e) { elements.add(e); refreshValue(); } /** * Remove a PathwayElement to the set of elements that are viewed / edited together */ public void removeElement(PathwayElement e) { elements.remove(e); refreshValue(); } /** * Refresh the viewer / editor value by checking all PathwayElements * This notifies the PropertyView that one of the PathwayElements has changed * or that the PathwayElement list has been changed, and a new value should be cached. */ public void refreshValue() { if(elements.size() == 1) { value = elements.iterator().next().getPropertyEx(type); } else { List SelectionValues = new ArrayList(); for(PathwayElement e : elements) { Object o = e.getPropertyEx(type); if(o != null){ SelectionValues.add(o); value = o; different = false; } } if(!SelectionValues.isEmpty()) { while(SelectionValues.size()-2 >= counter) { if(!SelectionValues.get(counter).equals(SelectionValues.get(counter+1))) { different = true; } counter ++; } counter = 0; } } } /** * Number of PathwayElement's being edited / viewed */ public int elementCount() { return elements.size(); } /** * Get a name for the property being edited. */ public String getName() { if (type instanceof Property) { return ((Property)type).getName(); } else { Property prop = PropertyDisplayManager.getDynamicProperty((String)type); if (prop != null) { return prop.getName(); } return type.toString(); } } /** * Get a description for the property being edited. */ public String getDescription() { if (type instanceof Property) { return ((Property)type).getDescription(); } else { Property prop = PropertyDisplayManager.getDynamicProperty((String)type); if (prop != null) { return prop.getDescription(); } return null; } } /** * Set a value for the property being edited. * This will update all PathwayElements that are being edited at once. */ public void setValue(Object value) { this.value = value; if(value != null) { if (vPathway != null) { vPathway.getUndoManager().newAction ( "Change " + type + " property"); } for(PathwayElement e : elements) { e.setPropertyEx(type, value); } } } /** * The value of the property being viewed / edited. * This value is cached, call refreshValue() to update the cache. */ public Object getValue() { return value; } /** * The type of the property being edited. This is a String * if the property is dynamic, or a Property if the property * is static. (See PathwayElement for an explanation of static / dynamic) */ public Object getType() { return type; } private TypeHandler getTypeHandler() { if (type instanceof Property) { return PropertyDisplayManager.getTypeHandler(((Property)type).getType()); } else { Property prop = PropertyDisplayManager.getDynamicProperty((String)type); if (prop != null) { return PropertyDisplayManager.getTypeHandler(prop.getType()); } return null; } } /** * Returns true if the PathwayElement's being edited differ for this Property. */ public boolean hasDifferentValues() { return different; } /** * Returns a TableCellRenderer suitable for rendering this property's label. */ public TableCellRenderer getLabelRenderer() { TypeHandler handler = getTypeHandler(); TableCellRenderer renderer = null; if (handler != null) { renderer = handler.getLabelRenderer(); } if (renderer == null && (type instanceof Property || PropertyDisplayManager.getDynamicProperty((String)type) != null)) { return propertyLabelRenderer; } return renderer; } /** * Returns a TableCellRenderer suitable for rendering this property's value. */ public TableCellRenderer getCellRenderer() { if(hasDifferentValues()) { return differentRenderer; } TypeHandler handler = getTypeHandler(); if (handler != null) { return handler.getValueRenderer(); } return null; } /** * Returns a TableCellEditor suitable for editing this property's value. * * @param swingEngine: the comments editor requires a connection to swingEngine, so you need to pass it here. */ public TableCellEditor getCellEditor(SwingEngine swingEngine) { TypeHandler handler = getTypeHandler(); if (handler != null) { if (handler instanceof ContextSensitiveEditor) { ((ContextSensitiveEditor)handler).updateEditor(swingEngine, elements, vPathway.getPathwayModel(), this); } return handler.getValueEditor(); } return null; } private static DefaultTableCellRenderer differentRenderer = new DefaultTableCellRenderer() { protected void setValue(Object value) { value = "Different values"; super.setValue(value); } }; public int compareTo(PropertyView arg0) { if (arg0 == null) throw new NullPointerException(); Object aType = type; int aOrder = -1; Object bType = arg0.getType(); int bOrder = -1; if (aType instanceof String) { if (PropertyDisplayManager.getDynamicProperty((String)aType) != null) { aType = PropertyDisplayManager.getDynamicProperty((String)aType); aOrder = PropertyDisplayManager.getPropertyOrder((Property)aType); } } else { aOrder = PropertyDisplayManager.getPropertyOrder((Property)aType); } if (bType instanceof String) { if (PropertyDisplayManager.getDynamicProperty((String)bType) != null) { bType = PropertyDisplayManager.getDynamicProperty((String)bType); bOrder = PropertyDisplayManager.getPropertyOrder((Property)bType); } } else { bOrder = PropertyDisplayManager.getPropertyOrder((Property)bType); } if (aOrder < 0 && bOrder < 0) { return ((String)aType).compareTo((String)bType); } int rez = aOrder - bOrder; if (rez == 0) { // same order, sort by alpha rez = ((Property)aType).getName().compareTo(((Property)bType).getName()); } return rez; } }