diff --git a/src/java/com/threerings/admin/client/DSetEditor.java b/src/java/com/threerings/admin/client/DSetEditor.java index 3a8fe1e12..f70738d6c 100644 --- a/src/java/com/threerings/admin/client/DSetEditor.java +++ b/src/java/com/threerings/admin/client/DSetEditor.java @@ -95,7 +95,7 @@ public class DSetEditor extends JPanel DObject setter, String setName, Class entryClass, String[] editableFields, ObjectEditorTable.FieldInterpreter interp) { - this(setter, setName, entryClass, editableFields, interp, null); + this(setter, setName, entryClass, editableFields, interp, null, null); } /** @@ -106,11 +106,12 @@ public class DSetEditor extends JPanel * @param entryClass The Class of the DSet.Entry elements contained in the set. * @param editableFields The names of the fields in the entryClass that should be editable. * @param interp The FieldInterpreter to use. + * @param displayFields The fields to display, or null for all. * @param entryFilter The Predicate to use. */ public DSetEditor ( DObject setter, String setName, Class entryClass, String[] editableFields, - ObjectEditorTable.FieldInterpreter interp, Predicate entryFilter) + ObjectEditorTable.FieldInterpreter interp, String[] displayFields, Predicate entryFilter) { super(new BorderLayout()); @@ -119,7 +120,7 @@ public class DSetEditor extends JPanel _set = _setter.getSet(setName); _entryFilter = entryFilter; - _table = new ObjectEditorTable(entryClass, editableFields, interp); + _table = new ObjectEditorTable(entryClass, editableFields, interp, displayFields); add(new JScrollPane(_table), BorderLayout.CENTER); } diff --git a/src/java/com/threerings/admin/client/TabbedDSetEditor.java b/src/java/com/threerings/admin/client/TabbedDSetEditor.java index 252baebf4..b2c16d505 100644 --- a/src/java/com/threerings/admin/client/TabbedDSetEditor.java +++ b/src/java/com/threerings/admin/client/TabbedDSetEditor.java @@ -22,7 +22,8 @@ package com.threerings.admin.client; import java.lang.reflect.Field; -import java.util.HashSet; +import java.util.Comparator; +import java.util.Set; import javax.swing.JPanel; import javax.swing.JTabbedPane; @@ -30,7 +31,9 @@ import javax.swing.JTabbedPane; import com.google.common.base.Predicate; import com.google.common.collect.Sets; +import com.samskivert.util.Comparators; import com.samskivert.util.Logger; +import com.samskivert.util.QuickSort; import com.samskivert.util.StringUtil; import com.samskivert.swing.ObjectEditorTable; @@ -44,58 +47,135 @@ import com.threerings.presents.dobj.DSet; */ public class TabbedDSetEditor extends JPanel { + /** + * Used to divide various entires into different groups. + */ + public static abstract class EntryGrouper + { + /** + * Record & return the group for a given entry. + */ + public String getGroup (E entry) + { + String group = computeGroup(entry); + _allGroups.add(group); + return group; + } + + /** + * Subclasses implement the actual logic to figure out a group name from an entry here. + */ + protected abstract String computeGroup (E entry); + + protected Predicate getPredicate (final String group) { + return new Predicate() { + public boolean apply (E entry) { + return group.equals(getGroup(entry)); + } + }; + } + + /** + * Grinds through the + * @param entries + */ + public void computeGroups (Iterable entries) { + for (E entry : entries) { + getGroup(entry); + } + } + + /** + * Returns all the groups we know about, ordered as they should be displayed. + */ + public String[] getAllGroups () { + String[] list = _allGroups.toArray(new String[_allGroups.size()]); + QuickSort.sort(list, getComparator()); + + return list; + } + + protected Comparator getComparator () { + return Comparators.LEXICAL_CASE_INSENSITIVE; + } + + + protected Set _allGroups = Sets.newHashSet(); + } + + public static class FieldGrouper extends EntryGrouper + { + public FieldGrouper (String fieldName, Class entryClass) { + try { + _field = entryClass.getField(fieldName); + } catch (NoSuchFieldException nsfe) { + throw new IllegalArgumentException(Logger.format( + "Group field not found in prototype class!", + "proto", entryClass, "groupField", fieldName)); + } + } + + @Override + protected String computeGroup (E entry) { + try { + return StringUtil.toString(_field.get(entry)); + } catch (IllegalAccessException iae) { + // This ain't good, but let's soldier on. + return ""; + } + } + + protected final Field _field; + } + + + /** + * Convenience function to make an edittor that groups based on the values of a given field. + */ + public TabbedDSetEditor ( + DObject setter, String setName, Class entryClass, String[] editableFields, + ObjectEditorTable.FieldInterpreter interp, String groupField) + { + this(setter, setName, entryClass, editableFields, interp, + new FieldGrouper(groupField, entryClass)); + } + /** * A set of tabs containing DSetEditors grouping entries by the String value stored in * a given field of the Entry. */ public TabbedDSetEditor ( - DObject setter, String setName, Class entryClass, - String[] editableFields, ObjectEditorTable.FieldInterpreter interp, String groupField) + DObject setter, String setName, Class entryClass, String[] editableFields, + ObjectEditorTable.FieldInterpreter interp, EntryGrouper grouper) { - DSet set = setter.getSet(setName); - - Field field; - - try { - field = entryClass.getField(groupField); - } catch (NoSuchFieldException nsfe) { - throw new IllegalArgumentException(Logger.format( - "Group field not found in prototype class!", - "proto", entryClass, "groupField", groupField)); - } - - HashSet groups = Sets.newHashSet(); - try { - for (E entry : set) { - groups.add(StringUtil.toString(field.get(entry))); - } - } catch (IllegalAccessException iae) { - throw new IllegalArgumentException(Logger.format( - "Could not access group field on entry", "groupField", groupField), iae); - } + grouper.computeGroups(setter.getSet(setName)); JTabbedPane tabs = new JTabbedPane(); add(tabs); + String[] groups = grouper.getAllGroups(); for (String group : groups) { - tabs.addTab(group, new DSetEditor(setter, setName, entryClass, editableFields, - interp, createPredicate(field, group))); + tabs.addTab(group, + createEditor(setter, setName, entryClass, editableFields, interp, grouper, group)); } } - protected Predicate createPredicate (final Field field, final String group) + /** + * Creates a DSetEditor for displaying the given group. + */ + protected DSetEditor createEditor ( + DObject setter, String setName, Class entryClass, String[] editableFields, + ObjectEditorTable.FieldInterpreter interp, EntryGrouper grouper, String group) { - return new Predicate() { - public boolean apply (E entry) { - String val = null; - try { - val = StringUtil.toString(field.get(entry)); - } catch (IllegalAccessException iae) { - // Badness, but let's just compare to the null string and be done - } + return new DSetEditor(setter, setName, entryClass, editableFields, + interp, getDisplayFields(group), grouper.getPredicate(group)); + } - return group.equals(val); - } - }; + /** + * Choose which fields to display for the given group. + */ + protected String[] getDisplayFields (String group) + { + return null; // Override to display only a subset } }