0

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.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
user2902165
  • 303
  • 2
  • 14

1 Answers1

0

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);
    }

    ...
}
Maurice Perry
  • 9,261
  • 2
  • 12
  • 24
  • Hello Maurice, I have had a couple of busy weeks, but I will just let you know that your answer is gold! I will get back to you when I have implement it. Best regards Fredrik – user2902165 Nov 27 '19 at 06:06