All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.l2fprod.common.propertysheet.PropertySheetTableModel Maven / Gradle / Ivy

Go to download

Orbit, a versatile image analysis software for biological image-based quantification

There is a newer version: 3.15
Show newest version
/**
 * $ $ License.
 *
 * Copyright $ L2FProd.com
 *
 * 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 com.l2fprod.common.propertysheet;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import javax.swing.table.AbstractTableModel;

import com.l2fprod.common.swing.ObjectTableModel;

/**
 * PropertySheetTableModel. 
* */ public class PropertySheetTableModel extends AbstractTableModel implements PropertyChangeListener, PropertySheet, ObjectTableModel { public static final int NAME_COLUMN = 0; public static final int VALUE_COLUMN = 1; public static final int NUM_COLUMNS = 2; private PropertyChangeSupport listeners = new PropertyChangeSupport(this); private List model; private List publishedModel; private List properties; private int mode; private boolean sortingCategories; private boolean sortingProperties; private Comparator categorySortingComparator; private Comparator propertySortingComparator; public PropertySheetTableModel() { model = new ArrayList(); publishedModel = new ArrayList(); properties = new ArrayList(); mode = PropertySheet.VIEW_AS_FLAT_LIST; sortingCategories = false; sortingProperties = false; } /* (non-Javadoc) * @see com.l2fprod.common.propertysheet.PropertySheet#setProperties(com.l2fprod.common.propertysheet.Property[]) */ public void setProperties(Property[] newProperties) { // unregister the listeners from previous properties for (Iterator iter = properties.iterator(); iter.hasNext();) { Property prop = (Property) iter.next(); prop.removePropertyChangeListener(this); Property[] subProp = prop.getSubProperties(); if (subProp != null) for (int i = 0; i < subProp.length; ++i) subProp[i].removePropertyChangeListener(this); } // replace the current properties properties.clear(); properties.addAll(Arrays.asList(newProperties)); // add listeners for (Iterator iter = properties.iterator(); iter.hasNext();) { Property prop = (Property) iter.next(); prop.addPropertyChangeListener(this); Property[] subProp = prop.getSubProperties(); if (subProp != null) for (int i = 0; i < subProp.length; ++i) subProp[i].addPropertyChangeListener(this); } buildModel(); } /* (non-Javadoc) * @see com.l2fprod.common.propertysheet.PropertySheet#getProperties() */ public Property[] getProperties() { return (Property[]) properties.toArray(new Property[properties.size()]); } /* (non-Javadoc) * @see com.l2fprod.common.propertysheet.PropertySheet#addProperty(com.l2fprod.common.propertysheet.Property) */ public void addProperty(Property property) { properties.add(property); property.addPropertyChangeListener(this); buildModel(); } /* (non-Javadoc) * @see com.l2fprod.common.propertysheet.PropertySheet#addProperty(int, com.l2fprod.common.propertysheet.Property) */ public void addProperty(int index, Property property) { properties.add(index, property); property.addPropertyChangeListener(this); buildModel(); } /* (non-Javadoc) * @see com.l2fprod.common.propertysheet.PropertySheet#removeProperty(com.l2fprod.common.propertysheet.Property) */ public void removeProperty(Property property) { properties.remove(property); property.removePropertyChangeListener(this); buildModel(); } /* (non-Javadoc) * @see com.l2fprod.common.propertysheet.PropertySheet#getPropertyCount() */ public int getPropertyCount() { return properties.size(); } /* (non-Javadoc) * @see com.l2fprod.common.propertysheet.PropertySheet#propertyIterator() */ public Iterator propertyIterator() { return properties.iterator(); } /** * Set the current mode, either {@link PropertySheet#VIEW_AS_CATEGORIES} * or {@link PropertySheet#VIEW_AS_FLAT_LIST}. */ public void setMode(int mode) { if (this.mode == mode) { return; } this.mode = mode; buildModel(); } /** * Get the current mode, either {@link PropertySheet#VIEW_AS_CATEGORIES} * or {@link PropertySheet#VIEW_AS_FLAT_LIST}. */ public int getMode() { return mode; } /* (non-Javadoc) * @see javax.swing.table.TableModel#getColumnClass(int) */ public Class getColumnClass(int columnIndex) { return super.getColumnClass(columnIndex); } /* (non-Javadoc) * @see javax.swing.table.TableModel#getColumnCount() */ public int getColumnCount() { return NUM_COLUMNS; } /* (non-Javadoc) * @see javax.swing.table.TableModel#getRowCount() */ public int getRowCount() { return publishedModel.size(); } /* (non-Javadoc) * @see com.l2fprod.common.swing.ObjectTableModel#getObject(int) */ public Object getObject(int rowIndex) { return getPropertySheetElement(rowIndex); } /** * Get the current property sheet element, of type {@link Item}, at * the specified row. */ public Item getPropertySheetElement(int rowIndex) { return (Item) publishedModel.get(rowIndex); } /** * Get whether this model is currently sorting categories. */ public boolean isSortingCategories() { return sortingCategories; } /** * Set whether this model is currently sorting categories. * If this changes the sorting, the model will be rebuilt. */ public void setSortingCategories(boolean value) { boolean old = sortingCategories; sortingCategories = value; if (sortingCategories != old) buildModel(); } /** * Get whether this model is currently sorting properties. */ public boolean isSortingProperties() { return sortingProperties; } /** * Set whether this model is currently sorting properties. * If this changes the sorting, the model will be rebuilt. */ public void setSortingProperties(boolean value) { boolean old = sortingProperties; sortingProperties = value; if (sortingProperties != old) buildModel(); } /** * Set the comparator used for sorting categories. If this * changes the comparator, the model will be rebuilt. */ public void setCategorySortingComparator(Comparator comp) { Comparator old = categorySortingComparator; categorySortingComparator = comp; if (categorySortingComparator != old) buildModel(); } /** * Set the comparator used for sorting properties. If this * changes the comparator, the model will be rebuilt. */ public void setPropertySortingComparator(Comparator comp) { Comparator old = propertySortingComparator; propertySortingComparator = comp; if (propertySortingComparator != old) buildModel(); } /** * Retrieve the value at the specified row and column location. * When the row contains a category or the column is * {@link #NAME_COLUMN}, an {@link Item} object will be returned. * If the row is a property and the column is {@link #VALUE_COLUMN}, * the value of the property will be returned. * * @see javax.swing.table.TableModel#getValueAt(int, int) */ public Object getValueAt(int rowIndex, int columnIndex) { Object result = null; Item item = getPropertySheetElement(rowIndex); if (item.isProperty()) { switch (columnIndex) { case NAME_COLUMN: result = item; break; case VALUE_COLUMN: try { result = item.getProperty().getValue(); } catch (Exception e) { e.printStackTrace(); } break; default: // should not happen } } else { result = item; } return result; } /** * Sets the value at the specified row and column. This will have * no effect unless the row is a property and the column is * {@link #VALUE_COLUMN}. * * @see javax.swing.table.TableModel#setValueAt(java.lang.Object, int, int) */ public void setValueAt(Object value, int rowIndex, int columnIndex) { Item item = getPropertySheetElement(rowIndex); if (item.isProperty() ) { if (columnIndex == VALUE_COLUMN) { try { item.getProperty().setValue(value); } catch (Exception e) { e.printStackTrace(); } } } } /** * Add a {@link PropertyChangeListener} to the current model. */ public void addPropertyChangeListener(PropertyChangeListener listener) { listeners.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { listeners.removePropertyChangeListener(listener); } public void propertyChange(PropertyChangeEvent evt) { // forward the event to registered listeners listeners.firePropertyChange(evt); } protected void visibilityChanged() { publishedModel.clear(); for (Iterator iter = model.iterator(); iter.hasNext();) { Item item = (Item) iter.next(); Item parent = item.getParent(); if (parent == null || parent.isVisible()) publishedModel.add(item); } fireTableDataChanged(); } private void buildModel() { model.clear(); publishedModel.clear(); if (properties != null && properties.size() > 0) { List sortedProperties = sortProperties(properties); switch (mode) { case PropertySheet.VIEW_AS_FLAT_LIST: // just add all the properties without categories addPropertiesToModel(sortedProperties, null); break; case PropertySheet.VIEW_AS_CATEGORIES: { // add properties by category List categories = sortCategories(getPropertyCategories(sortedProperties)); for (Iterator iter = categories.iterator(); iter.hasNext();) { String category = (String) iter.next(); Item categoryItem = new Item(category, null); model.add(categoryItem); addPropertiesToModel( sortProperties(getPropertiesForCategory(properties, category)), categoryItem); } break; } default: // should not happen } } visibilityChanged(); fireTableDataChanged(); } protected List sortProperties(List localProperties) { List sortedProperties = new ArrayList(localProperties); if (sortingProperties) { if (propertySortingComparator == null) { // if no comparator was defined by the user, use the default propertySortingComparator = new PropertyComparator(); } Collections.sort(sortedProperties, propertySortingComparator); } return sortedProperties; } protected List sortCategories(List localCategories) { List sortedCategories = new ArrayList(localCategories); if (sortingCategories) { if (categorySortingComparator == null) { // if no comparator was defined by the user, use the default categorySortingComparator = STRING_COMPARATOR; } Collections.sort(sortedCategories, categorySortingComparator); } return sortedCategories; } protected List getPropertyCategories(List localProperties) { List categories = new ArrayList(); for (Iterator iter = localProperties.iterator(); iter.hasNext();) { Property property = (Property) iter.next(); if (!categories.contains(property.getCategory())) categories.add(property.getCategory()); } return categories; } /** * Add the specified properties to the model using the specified parent. * * @param localProperties the properties to add to the end of the model * @param parent the {@link Item} parent of these properties, null if none */ private void addPropertiesToModel(List localProperties, Item parent) { for (Iterator iter = localProperties.iterator(); iter.hasNext();) { Property property = (Property) iter.next(); Item propertyItem = new Item(property, parent); model.add(propertyItem); // add any sub-properties Property[] subProperties = property.getSubProperties(); if (subProperties != null && subProperties.length > 0) addPropertiesToModel(Arrays.asList(subProperties), propertyItem); } } /** * Convenience method to get all the properties of one category. */ private List getPropertiesForCategory(List localProperties, String category) { List categoryProperties = new ArrayList(); for (Iterator iter = localProperties.iterator(); iter.hasNext();) { Property property = (Property) iter.next(); if ((category == property.getCategory()) || (category != null && category.equals(property.getCategory()))) { categoryProperties.add(property); } } return categoryProperties; } public class Item { private String name; private Property property; private Item parent; private boolean hasToggle = true; private boolean visible = true; private Item(String name, Item parent) { this.name = name; this.parent = parent; // this is not a property but a category, always has toggle this.hasToggle = true; } private Item(Property property, Item parent) { this.name = property.getDisplayName(); this.property = property; this.parent = parent; this.visible = (property == null); // properties toggle if there are sub-properties Property[] subProperties = property.getSubProperties(); hasToggle = subProperties != null && subProperties.length > 0; } public String getName() { return name; } public boolean isProperty() { return property != null; } public Property getProperty() { return property; } public Item getParent() { return parent; } public int getDepth() { int depth = 0; if (parent != null) { depth = parent.getDepth(); if (parent.isProperty()) ++depth; } return depth; } public boolean hasToggle() { return hasToggle; } public void toggle() { if (hasToggle()) { visible = !visible; visibilityChanged(); } } public boolean isVisible() { return (parent == null || parent.isVisible()) && (!hasToggle || visible); } } /** * The default comparator for Properties. Used if no other comparator is * defined. */ public static class PropertyComparator implements Comparator { public int compare(Object o1, Object o2) { if (o1 instanceof Property && o2 instanceof Property) { Property prop1 = (Property) o1; Property prop2 = (Property) o2; if (prop1 == null) { return prop2==null?0:-1; } else { return STRING_COMPARATOR.compare(prop1.getDisplayName()==null?null:prop1.getDisplayName().toLowerCase(), prop2.getDisplayName() == null ? null : prop2.getDisplayName().toLowerCase()); } } else { return 0; } } } private static final Comparator STRING_COMPARATOR = new NaturalOrderStringComparator(); public static class NaturalOrderStringComparator implements Comparator { public int compare(Object o1, Object o2) { String s1 = (String) o1; String s2 = (String) o2; if (s1 == null) { return s2==null?0:-1; } else { if (s2 == null) { return 1; } else { return s1.compareTo(s2); } } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy