I've broken out how the FieldEditors access their data into a separate Accessor plugin. This way, we can replace the default DObjectAccessor with (for example) an accessor that deals with multiple DObjects simultaneously.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6030 542714f4-19e9-0310-aa3c-eee0fc999fb1
This commit is contained in:
@@ -40,7 +40,6 @@ import com.samskivert.util.ComparableArrayList;
|
|||||||
|
|
||||||
import com.samskivert.swing.ObjectEditorTable;
|
import com.samskivert.swing.ObjectEditorTable;
|
||||||
import com.samskivert.swing.event.CommandEvent;
|
import com.samskivert.swing.event.CommandEvent;
|
||||||
|
|
||||||
import com.threerings.presents.dobj.AttributeChangeListener;
|
import com.threerings.presents.dobj.AttributeChangeListener;
|
||||||
import com.threerings.presents.dobj.AttributeChangedEvent;
|
import com.threerings.presents.dobj.AttributeChangedEvent;
|
||||||
import com.threerings.presents.dobj.DObject;
|
import com.threerings.presents.dobj.DObject;
|
||||||
@@ -54,8 +53,16 @@ import com.threerings.presents.dobj.SetListener;
|
|||||||
* Allows simple editing of DSets within a distributed object.
|
* Allows simple editing of DSets within a distributed object.
|
||||||
*/
|
*/
|
||||||
public class DSetEditor<E extends DSet.Entry> extends JPanel
|
public class DSetEditor<E extends DSet.Entry> extends JPanel
|
||||||
implements AttributeChangeListener, SetListener<E>, ActionListener
|
implements ActionListener
|
||||||
{
|
{
|
||||||
|
public interface Accessor<F extends DSet.Entry>
|
||||||
|
{
|
||||||
|
void added ();
|
||||||
|
void removed ();
|
||||||
|
void updateEntry (String setName, DSet.Entry entry);
|
||||||
|
ObjectEditorTable.FieldInterpreter getInterp (ObjectEditorTable.FieldInterpreter interp);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a DSet editor to merely display the specified set.
|
* Construct a DSet editor to merely display the specified set.
|
||||||
*
|
*
|
||||||
@@ -115,13 +122,24 @@ public class DSetEditor<E extends DSet.Entry> extends JPanel
|
|||||||
{
|
{
|
||||||
super(new BorderLayout());
|
super(new BorderLayout());
|
||||||
|
|
||||||
_setter = setter;
|
|
||||||
_setName = setName;
|
_setName = setName;
|
||||||
_set = _setter.getSet(setName);
|
|
||||||
_entryFilter = entryFilter;
|
_entryFilter = entryFilter;
|
||||||
|
|
||||||
_table = new ObjectEditorTable(entryClass, editableFields, interp, displayFields);
|
_entryClass = entryClass;
|
||||||
|
_editableFields = editableFields;
|
||||||
|
_interp = interp;
|
||||||
|
_displayFields = displayFields;
|
||||||
|
|
||||||
|
setAccessor(new DObjectAccessor<E>(setter, setName));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAccessor (Accessor accessor)
|
||||||
|
{
|
||||||
|
removeAll();
|
||||||
|
_accessor = accessor;
|
||||||
|
_table = new ObjectEditorTable(_entryClass, _editableFields, _accessor.getInterp(_interp),
|
||||||
|
_displayFields);
|
||||||
add(new JScrollPane(_table), BorderLayout.CENTER);
|
add(new JScrollPane(_table), BorderLayout.CENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,17 +171,14 @@ public class DSetEditor<E extends DSet.Entry> extends JPanel
|
|||||||
public void addNotify ()
|
public void addNotify ()
|
||||||
{
|
{
|
||||||
super.addNotify();
|
super.addNotify();
|
||||||
_setter.addListener(this);
|
_accessor.added();
|
||||||
_table.addActionListener(this);
|
_table.addActionListener(this);
|
||||||
|
|
||||||
// populate the table
|
|
||||||
refreshData();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void removeNotify ()
|
public void removeNotify ()
|
||||||
{
|
{
|
||||||
_setter.removeListener(this);
|
_accessor.removed();
|
||||||
_table.removeActionListener(this);
|
_table.removeActionListener(this);
|
||||||
super.removeNotify();
|
super.removeNotify();
|
||||||
}
|
}
|
||||||
@@ -191,85 +206,27 @@ public class DSetEditor<E extends DSet.Entry> extends JPanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface SetListener
|
|
||||||
public void entryAdded (EntryAddedEvent<E> event)
|
|
||||||
{
|
|
||||||
if (event.getName().equals(_setName)) {
|
|
||||||
addEntry(event.getEntry());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// documentation inherited from interface SetListener
|
|
||||||
public void entryRemoved (EntryRemovedEvent<E> event)
|
|
||||||
{
|
|
||||||
if (event.getName().equals(_setName)) {
|
|
||||||
removeKey(event.getKey());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// documentation inherited from interface SetListener
|
|
||||||
public void entryUpdated (EntryUpdatedEvent<E> event)
|
|
||||||
{
|
|
||||||
if (event.getName().equals(_setName)) {
|
|
||||||
E entry = event.getEntry();
|
|
||||||
int index = _keys.indexOf(entry.getKey());
|
|
||||||
if (index != -1) {
|
|
||||||
// We have it, so either update or remove
|
|
||||||
if (_entryFilter == null || _entryFilter.apply(entry)) {
|
|
||||||
_table.updateDatum(entry, index);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
removeKey(entry.getKey());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// We DON'T have it, so try to add it in case we care about it
|
|
||||||
addEntry(entry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// documentation inherited from interface SetListener
|
|
||||||
public void attributeChanged (AttributeChangedEvent event)
|
|
||||||
{
|
|
||||||
if (event.getName().equals(_setName)) {
|
|
||||||
// the whole set changed so we need to refetch it from the object
|
|
||||||
_set = _setter.getSet(_setName);
|
|
||||||
refreshData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// documentation inherited from interface ActionListener
|
// documentation inherited from interface ActionListener
|
||||||
public void actionPerformed (ActionEvent event)
|
public void actionPerformed (ActionEvent event)
|
||||||
{
|
{
|
||||||
CommandEvent ce = (CommandEvent)event;
|
CommandEvent ce = (CommandEvent)event;
|
||||||
_setter.updateSet(_setName, (DSet.Entry)ce.getArgument());
|
_accessor.updateEntry(_setName, (DSet.Entry)ce.getArgument());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void refreshData ()
|
public void setData (ComparableArrayList<Comparable<Object>> keys, Object[] data)
|
||||||
{
|
{
|
||||||
_keys = new ComparableArrayList<Comparable<Object>>();
|
_keys = keys;
|
||||||
E[] entries;
|
_table.setData(data);
|
||||||
|
}
|
||||||
|
|
||||||
if (_entryFilter == null) {
|
public Predicate<E> getFilter ()
|
||||||
@SuppressWarnings("unchecked") E[] tmp = (E[])new DSet.Entry[_set.size()];
|
{
|
||||||
entries = tmp;
|
return _entryFilter;
|
||||||
_set.toArray(entries);
|
}
|
||||||
|
|
||||||
} else {
|
public String getSetName ()
|
||||||
// Do some shuffling to get out a filtered array.
|
{
|
||||||
Iterator<E> itr = Iterators.filter(_set.iterator(), _entryFilter);
|
return _setName;
|
||||||
ArrayList<E> list = Lists.newArrayList();
|
|
||||||
Iterators.addAll(list, itr);
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked") E[] tmp = (E[])new DSet.Entry[list.size()];
|
|
||||||
entries = tmp;
|
|
||||||
list.toArray(entries);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (E entry : entries) {
|
|
||||||
_keys.insertSorted(getKey(entry));
|
|
||||||
}
|
|
||||||
_table.setData(entries); // this works because DSet itself is sorted
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@@ -278,8 +235,135 @@ public class DSetEditor<E extends DSet.Entry> extends JPanel
|
|||||||
return (Comparable<Object>)entry.getKey();
|
return (Comparable<Object>)entry.getKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The object that contains the set we're displaying. */
|
protected class DObjectAccessor<F extends E>
|
||||||
protected DObject _setter;
|
implements AttributeChangeListener, SetListener<F>, Accessor<F>
|
||||||
|
{
|
||||||
|
public DObjectAccessor (DObject obj, String setName)
|
||||||
|
{
|
||||||
|
_obj = obj;
|
||||||
|
_setName = setName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectEditorTable.FieldInterpreter getInterp (
|
||||||
|
ObjectEditorTable.FieldInterpreter interp)
|
||||||
|
{
|
||||||
|
return interp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void added ()
|
||||||
|
{
|
||||||
|
_obj.addListener(this);
|
||||||
|
refreshSet();
|
||||||
|
refreshData();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removed ()
|
||||||
|
{
|
||||||
|
_obj.removeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void refreshSet ()
|
||||||
|
{
|
||||||
|
_set = _obj.getSet(_setName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateEntry (String setName, DSet.Entry entry)
|
||||||
|
{
|
||||||
|
_obj.updateSet(setName, entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited from interface SetListener
|
||||||
|
public void entryAdded (EntryAddedEvent<F> event)
|
||||||
|
{
|
||||||
|
if (event.getName().equals(_setName)) {
|
||||||
|
addEntry(event.getEntry());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited from interface SetListener
|
||||||
|
public void entryRemoved (EntryRemovedEvent<F> event)
|
||||||
|
{
|
||||||
|
if (event.getName().equals(_setName)) {
|
||||||
|
removeKey(event.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void refreshData ()
|
||||||
|
{
|
||||||
|
ComparableArrayList<Comparable<Object>> keys =
|
||||||
|
new ComparableArrayList<Comparable<Object>>();
|
||||||
|
E[] entries;
|
||||||
|
|
||||||
|
if (_entryFilter == null) {
|
||||||
|
entries = createArray();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Do some shuffling to get out a filtered array.
|
||||||
|
Iterator<F> itr = Iterators.filter(iterator(), _entryFilter);
|
||||||
|
ArrayList<F> list = Lists.newArrayList();
|
||||||
|
Iterators.addAll(list, itr);
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked") F[] tmp = (F[])new DSet.Entry[list.size()];
|
||||||
|
entries = tmp;
|
||||||
|
list.toArray(entries);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (E entry : entries) {
|
||||||
|
keys.insertSorted(getKey(entry));
|
||||||
|
}
|
||||||
|
setData(keys, entries); // this works because DSet itself is sorted
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited from interface SetListener
|
||||||
|
public void entryUpdated (EntryUpdatedEvent<F> event)
|
||||||
|
{
|
||||||
|
if (event.getName().equals(_setName)) {
|
||||||
|
E entry = event.getEntry();
|
||||||
|
int index = _keys.indexOf(entry.getKey());
|
||||||
|
if (index != -1) {
|
||||||
|
// We have it, so either update or remove
|
||||||
|
if (_entryFilter == null || _entryFilter.apply(entry)) {
|
||||||
|
_table.updateDatum(entry, index);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
removeKey(entry.getKey());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We DON'T have it, so try to add it in case we care about it
|
||||||
|
addEntry(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// documentation inherited from interface SetListener
|
||||||
|
public void attributeChanged (AttributeChangedEvent event)
|
||||||
|
{
|
||||||
|
if (event.getName().equals(_setName)) {
|
||||||
|
// the whole set changed so we need to refetch it from the object
|
||||||
|
refreshSet();
|
||||||
|
refreshData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public E[] createArray ()
|
||||||
|
{
|
||||||
|
@SuppressWarnings("unchecked") F[] tmp = (F[])new DSet.Entry[_set.size()];
|
||||||
|
F[] entries = tmp;
|
||||||
|
_set.toArray(entries);
|
||||||
|
return entries;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<F> iterator ()
|
||||||
|
{
|
||||||
|
return _set.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected DObject _obj;
|
||||||
|
|
||||||
|
protected DSet<F> _set;
|
||||||
|
|
||||||
|
protected String _setName;
|
||||||
|
}
|
||||||
|
|
||||||
/** The name of the set in that object. */
|
/** The name of the set in that object. */
|
||||||
protected String _setName;
|
protected String _setName;
|
||||||
@@ -287,15 +371,20 @@ public class DSetEditor<E extends DSet.Entry> extends JPanel
|
|||||||
/** An optional predicate to decide whether actually care about displaying a given entry. */
|
/** An optional predicate to decide whether actually care about displaying a given entry. */
|
||||||
protected Predicate<E> _entryFilter;
|
protected Predicate<E> _entryFilter;
|
||||||
|
|
||||||
/** The set itself. */
|
/** Provides access to our data we're editing. */
|
||||||
protected DSet<E> _set;
|
protected Accessor<E> _accessor;
|
||||||
|
|
||||||
/** An array we use to track our entries' positions by key. */
|
|
||||||
protected ComparableArrayList<Comparable<Object>> _keys;
|
|
||||||
|
|
||||||
/** The table used to edit. */
|
/** The table used to edit. */
|
||||||
protected ObjectEditorTable _table;
|
protected ObjectEditorTable _table;
|
||||||
|
|
||||||
|
/** An array we use to track our entries' positions by key. */
|
||||||
|
protected ComparableArrayList<Comparable<Object>> _keys;
|
||||||
|
|
||||||
|
protected Class<?> _entryClass;
|
||||||
|
protected String[] _editableFields;
|
||||||
|
protected ObjectEditorTable.FieldInterpreter _interp;
|
||||||
|
protected String[] _displayFields;
|
||||||
|
|
||||||
/** The minimum height for our editor UI. */
|
/** The minimum height for our editor UI. */
|
||||||
protected static final int MIN_HEIGHT = 200;
|
protected static final int MIN_HEIGHT = 200;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,11 +51,20 @@ import static com.threerings.admin.Log.log;
|
|||||||
public abstract class FieldEditor extends JPanel
|
public abstract class FieldEditor extends JPanel
|
||||||
implements AttributeChangeListener, ActionListener, FocusListener
|
implements AttributeChangeListener, ActionListener, FocusListener
|
||||||
{
|
{
|
||||||
|
/** The interface defining how the editor interacts with its data. */
|
||||||
|
public interface Accessor
|
||||||
|
{
|
||||||
|
void added ();
|
||||||
|
void removed ();
|
||||||
|
void set (Field field, Object value);
|
||||||
|
Object get (Field field);
|
||||||
|
}
|
||||||
|
|
||||||
public FieldEditor (PresentsContext ctx, Field field, DObject object)
|
public FieldEditor (PresentsContext ctx, Field field, DObject object)
|
||||||
{
|
{
|
||||||
_ctx = ctx;
|
_ctx = ctx;
|
||||||
_field = field;
|
_field = field;
|
||||||
_object = object;
|
setAccessor(new DObjectAccessor(object));
|
||||||
|
|
||||||
// create our interface elements
|
// create our interface elements
|
||||||
setLayout(new HGroupLayout(HGroupLayout.STRETCH));
|
setLayout(new HGroupLayout(HGroupLayout.STRETCH));
|
||||||
@@ -67,13 +76,18 @@ public abstract class FieldEditor extends JPanel
|
|||||||
updateBorder(false);
|
updateBorder(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAccessor (Accessor accessor)
|
||||||
|
{
|
||||||
|
_accessor = accessor;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addNotify ()
|
public void addNotify ()
|
||||||
{
|
{
|
||||||
super.addNotify();
|
super.addNotify();
|
||||||
|
|
||||||
// listen to the object while we're visible
|
// listen to the object while we're visible
|
||||||
_object.addListener(FieldEditor.this);
|
_accessor.added();
|
||||||
displayValue(getValue());
|
displayValue(getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,11 +97,17 @@ public abstract class FieldEditor extends JPanel
|
|||||||
super.removeNotify();
|
super.removeNotify();
|
||||||
|
|
||||||
// stop listening when we're hidden
|
// stop listening when we're hidden
|
||||||
_object.removeListener(FieldEditor.this);
|
_accessor.removed();
|
||||||
}
|
}
|
||||||
|
|
||||||
// documentation inherited from interface
|
// documentation inherited from interface
|
||||||
public void attributeChanged (AttributeChangedEvent event)
|
public void attributeChanged (AttributeChangedEvent event)
|
||||||
|
{
|
||||||
|
noteUpdatedExternally();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update ourselves to reflect a change from outside the editor. */
|
||||||
|
public void noteUpdatedExternally ()
|
||||||
{
|
{
|
||||||
displayValue(getValue());
|
displayValue(getValue());
|
||||||
updateBorder(false);
|
updateBorder(false);
|
||||||
@@ -105,11 +125,7 @@ public abstract class FieldEditor extends JPanel
|
|||||||
|
|
||||||
// submit an attribute changed event with the new value
|
// submit an attribute changed event with the new value
|
||||||
if (!ObjectUtil.equals(value, getValue())) {
|
if (!ObjectUtil.equals(value, getValue())) {
|
||||||
try {
|
_accessor.set(_field, value);
|
||||||
_object.changeAttribute(_field.getName(), value);
|
|
||||||
} catch (ObjectAccessException oae) {
|
|
||||||
log.warning("Failed to update field " + _field.getName() + ": " + oae);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,12 +167,7 @@ public abstract class FieldEditor extends JPanel
|
|||||||
*/
|
*/
|
||||||
protected Object getValue ()
|
protected Object getValue ()
|
||||||
{
|
{
|
||||||
try {
|
return _accessor.get(_field);
|
||||||
return _field.get(_object);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warning("Failed to fetch field", "field", _field, "object", _object, "error", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -172,8 +183,51 @@ public abstract class FieldEditor extends JPanel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple accessor that knows how to interact with a DObject - this is normally what is used.
|
||||||
|
*/
|
||||||
|
protected class DObjectAccessor
|
||||||
|
implements Accessor
|
||||||
|
{
|
||||||
|
public DObjectAccessor (DObject obj)
|
||||||
|
{
|
||||||
|
_obj = obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void added ()
|
||||||
|
{
|
||||||
|
_obj.addListener(FieldEditor.this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removed ()
|
||||||
|
{
|
||||||
|
_obj.removeListener(FieldEditor.this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void set (Field field, Object value)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
_obj.changeAttribute(field.getName(), value);
|
||||||
|
} catch (ObjectAccessException oae) {
|
||||||
|
log.warning("Failed to update field " + field.getName() + ": " + oae);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object get (Field field)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return field.get(_obj);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warning("Failed to fetch field", "field", field, "object", _obj, "error", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected DObject _obj;
|
||||||
|
}
|
||||||
|
|
||||||
protected PresentsContext _ctx;
|
protected PresentsContext _ctx;
|
||||||
protected Field _field;
|
protected Field _field;
|
||||||
protected DObject _object;
|
protected Accessor _accessor;
|
||||||
protected JLabel _label;
|
protected JLabel _label;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,11 @@ import com.threerings.presents.dobj.SetListener;
|
|||||||
public class TabbedDSetEditor<E extends DSet.Entry> extends JPanel
|
public class TabbedDSetEditor<E extends DSet.Entry> extends JPanel
|
||||||
implements AttributeChangeListener, SetListener<E>
|
implements AttributeChangeListener, SetListener<E>
|
||||||
{
|
{
|
||||||
|
public interface AccessorFactory
|
||||||
|
{
|
||||||
|
public DSetEditor.Accessor createAccessor (DSetEditor editor);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to divide various entires into different groups.
|
* Used to divide various entires into different groups.
|
||||||
*/
|
*/
|
||||||
@@ -170,6 +175,11 @@ public class TabbedDSetEditor<E extends DSet.Entry> extends JPanel
|
|||||||
add(_tabs);
|
add(_tabs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAccessorFactory (AccessorFactory accessorFactory)
|
||||||
|
{
|
||||||
|
_accessorFactory = accessorFactory;
|
||||||
|
}
|
||||||
|
|
||||||
protected void computeTabs ()
|
protected void computeTabs ()
|
||||||
{
|
{
|
||||||
_grouper.computeGroups(_setter.<E>getSet(_setName));
|
_grouper.computeGroups(_setter.<E>getSet(_setName));
|
||||||
@@ -179,6 +189,9 @@ public class TabbedDSetEditor<E extends DSet.Entry> extends JPanel
|
|||||||
if (!_editors.containsKey(group)) {
|
if (!_editors.containsKey(group)) {
|
||||||
DSetEditor<E> editor = createEditor(
|
DSetEditor<E> editor = createEditor(
|
||||||
_setter, _setName, _entryClass, _editableFields, _interp, _grouper, group);
|
_setter, _setName, _entryClass, _editableFields, _interp, _grouper, group);
|
||||||
|
if (_accessorFactory != null) {
|
||||||
|
editor.setAccessor(_accessorFactory.createAccessor(editor));
|
||||||
|
}
|
||||||
_tabs.add(group, editor);
|
_tabs.add(group, editor);
|
||||||
_editors.put(group, editor);
|
_editors.put(group, editor);
|
||||||
}
|
}
|
||||||
@@ -257,6 +270,7 @@ public class TabbedDSetEditor<E extends DSet.Entry> extends JPanel
|
|||||||
protected final String[] _editableFields;
|
protected final String[] _editableFields;
|
||||||
protected final ObjectEditorTable.FieldInterpreter _interp;
|
protected final ObjectEditorTable.FieldInterpreter _interp;
|
||||||
protected final EntryGrouper<E> _grouper;
|
protected final EntryGrouper<E> _grouper;
|
||||||
|
protected AccessorFactory _accessorFactory;
|
||||||
|
|
||||||
protected JTabbedPane _tabs;
|
protected JTabbedPane _tabs;
|
||||||
protected HashMap<String, DSetEditor<E>> _editors = Maps.newHashMap();
|
protected HashMap<String, DSetEditor<E>> _editors = Maps.newHashMap();
|
||||||
|
|||||||
Reference in New Issue
Block a user