How to initiate a change event for a TreeModel in Java?

301 Views Asked by At

Suppose you got a JTree with a model that implements TreeModel, and all nodes implement TreeNode. Suppose then that something happens in the background with the model (not through the GUI) like a CRUD-event, that update the model and should update the JTree. Since the model is CRUD-affected from other views it does not seems like a good idea to use the DefaultTreeModel for this task, correct me if I'm wrong.

I guess you need to signal the change to the TreeModel in somehow, like fire some event in some way?

Btw I have not managed to implement the methods:

public void addTreeModelListener( TreeModelListener l )
public void removeTreeModelListener( TreeModelListener l )

I guess these methods need to be implemented for such a feature.

1

There are 1 best solutions below

1
Maurice Perry On

I like to use this kind of generic ListenerList:

public class ListenerList {
    private final List<Object> list = new ArrayList<Object>();

    public ListenerList() {
    }

    public void addListener(Object listener) {
        list.add(listener);
    }

    public void removeListener(Object listener) {
        list.remove(listener);
    }

    public <T> T getNotifier(Class<T> intf) {
        ClassLoader cl = intf.getClassLoader();
        return intf.cast(Proxy.newProxyInstance(cl, new Class[] {intf},
                (Object proxy, Method method, Object[] args)
                        -> actualInvoke(method, args)));
    }

    private Object actualInvoke(Method method, Object args[]) {
        Object result = null;
        for (Object listener: list) {
            try {
                result = method.invoke(listener, args);
            } catch (IllegalAccessException e) {
                LOG.error("Error invoking listener method", e);
            } catch (InvocationTargetException e) {
                LOG.error("Error invoking listener method", e);
            }
        }
        return result;
    }
}

That I use in my model class:

public class MyTreeModel implements TreeModel {
    private final ListenerList listeners = new ListenerList();
    private final TreeModelListener notifier = listeners.getNotifier(TreeModelListener.class);

    public void addTreeModelListener( TreeModelListener l ) {
        listeners.addListener(l);
    }

    public void removeTreeModelListener( TreeModelListener l ) {
        listeners.removeListener(l);
    }

    protected void fireTreeNodesChanged(TreeModelEvent e) {
        notifier.treeNodesChanged(e);
    }

    protected void fireTreeNodesInserted(TreeModelEvent e) {
        notifier.treeNodesInserted(e);
    }

    protected void fireTreeNodesRemoved(TreeModelEvent e) {
        notifier.treeNodesRemoved(e);
    }

    protected void fireTreeStructureChanged(TreeModelEvent e)
        notifier.treeStructureChanged(e);
    }

    ...
}