У меня проблема, и я надеюсь, что кто-то знает, что происходит не так и почему, и может дать мне объяснение того, что я упускаю прямо сейчас, чтобы заставить эту вещь работать, как было предложено.
У меня есть JTree, построенный на пользовательской TreeModel ("WRTreeModel", см. ниже). Структура данных, для которой должна использоваться эта модель, состоит из корневого объекта, который содержит несколько полей и, кроме того, список, поддерживаемый «ArrayListModel», показанным ниже. Дерево выглядит нормально, когда я строю его с помощью WRTreeModel. Я могу разворачивать и сворачивать узлы, представляющие списки и поля, содержащиеся в объектах. Я могу разворачивать и сворачивать эти списки, а также просматривать их содержимое и так далее.
Теперь я хочу удалить дочерний элемент одного из списков и, как я уже знаю, сделать это, удалив его из модели, вызвав метод удаления модели ArrayListModel. Чтобы сообщить WRTreeModel об этом удалении, первым делом нужно вызвать его метод fireIntervalRemoved, пока все хорошо.
Во внутреннем классе WRTreeModels ArrayModelListener метод intervalRemoved подготавливает вызов fireTreeNodesRemoved, который затем создает TreeEvent, который пересылается всем зарегистрированным TreeModelListeners (и, следовательно, JTree, который автоматически регистрируется при подключении к модели).
Теперь я ожидаю, что дерево отразит изменение и обновит свое внутреннее и визуальное представление, чтобы показать новое состояние. К сожалению, похоже, это так не работает. Что-то происходит. Но когда я нажимаю на узел, я только что изменил некоторые исключения EventHandler-Exceptions. Явно что-то сильно запуталось.
Я знаю, что нелегко ответить на такой вопрос на лету, но я был бы очень признателен за быстрый ответ. Также было бы полезно, если бы кто-то знал веб-сайты, объясняющие использование пользовательских моделей дерева (не в DefaultMutableTreeNode или любом данном классе, основанном на реализации) и как работает обработка событий и обновление JTree.
С наилучшими пожеланиями,
Томас Артс
public class ArrayListModel<E> extends ArrayList<E> implements ListModel {
...
public E remove(int index) {
fireIntervalRemoved(index, index);
E removedElement = super.remove(index);
return removedElement;
}
...
}
public class WRTreeModel extends LogAndMark implements TreeModel {
class ArrayModelListener implements ListDataListener {
...
@Override
public void intervalRemoved(ListDataEvent e) {
int[] indices = new int[e.getIndex1() - e.getIndex0() + 1];
for (int i = e.getIndex0(); i < e.getIndex1(); i++)
indices[i - e.getIndex0()] = i;
fireTreeNodesRemoved(e.getSource(), getPathToRoot(e.getSource()), indices, ((ArrayListModel<?>)e.getSource()).subList(e.getIndex0(), e.getIndex1()+1).toArray());
}
...
}
public Object[] getPathToRoot(Object child) {
ArrayList<Object> ret = new ArrayList<Object>();
if (child == null)
return ret.toArray();
ret.add(root);
if (child == root)
return ret.toArray();
int childType = 0;
if (child instanceof List<?> && ((List) child).get(0) instanceof Einleitungsstelle) {
childType = 1;
}
if (child instanceof Einleitungsstelle) {
childType = 2;
}
if (child instanceof List<?> && ((List) child).get(0) instanceof Messstelle) {
childType = 3;
}
if (child instanceof Messstelle) {
childType = 4;
}
if (child instanceof List<?> && ((List) child).get(0) instanceof Ueberwachungswert) {
childType = 5;
}
if (child instanceof Ueberwachungswert) {
childType = 6;
}
if (child instanceof List<?> && ((List) child).get(0) instanceof Selbstueberwachungswert) {
childType = 7;
}
if (child instanceof Selbstueberwachungswert) {
childType = 8;
}
switch (childType) {
// List of ESTs
case 1: {
ret.add(child);
break;
}
// EST
case 2: {
List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST();
ret.add(listOfEST);
ret.add(child);
break;
}
// List of MSTs
case 3: {
List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST();
ret.add(listOfEST);
// Find the EST containing the List of MSTs the child referes to
for (Einleitungsstelle einleitungsstelle : listOfEST) {
if (child == einleitungsstelle.getListOfMST()) {
ret.add(einleitungsstelle);
break;
}
}
ret.add(child);
break;
}
// MST
case 4: {
List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST();
ret.add(listOfEST);
// Find the EST containing the List of MSTs the child referes to
for (Einleitungsstelle einleitungsstelle : listOfEST) {
if (child == einleitungsstelle.getListOfMST()) {
ret.add(einleitungsstelle.getListOfMST());
break;
}
}
ret.add(child);
break;
}
// List of UEWs
case 5: {
List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST();
ret.add(listOfEST);
// Find the EST containing the List of MSTs the child referes to
for (Einleitungsstelle einleitungsstelle : listOfEST) {
ArrayListModel<Messstelle> listOfMST = einleitungsstelle.getListOfMST();
if (child == listOfMST) {
ret.add(listOfMST);
for (Messstelle messstelle : listOfMST) {
if (child == messstelle.getListOfUEW()) {
ret.add(messstelle.getListOfUEW());
break;
}
}
break;
}
}
break;
}
// UEW
case 6: {
List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST();
ret.add(listOfEST);
// Find the EST containing the List of MSTs the child referes to
for (Einleitungsstelle einleitungsstelle : listOfEST) {
ArrayListModel<Messstelle> listOfMST = einleitungsstelle.getListOfMST();
if (child == listOfMST) {
ret.add(listOfMST);
for (Messstelle messstelle : listOfMST) {
if (child == messstelle.getListOfUEW()) {
ret.add(messstelle.getListOfUEW());
break;
}
}
break;
}
}
ret.add(child);
break;
}
// List of SUEWs
case 7: {
List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST();
ret.add(listOfEST);
// Find the EST containing the List of MSTs the child referes to
for (Einleitungsstelle einleitungsstelle : listOfEST) {
ArrayListModel<Messstelle> listOfMST = einleitungsstelle.getListOfMST();
if (child == listOfMST) {
ret.add(listOfMST);
for (Messstelle messstelle : listOfMST) {
if (child == messstelle.getListOfSUEW()) {
ret.add(messstelle.getListOfSUEW());
break;
}
}
break;
}
}
break;
}
// SUEW
case 8: {
List<Einleitungsstelle> listOfEST = ((Wasserrecht) (root)).getListOfEST();
ret.add(listOfEST);
// Find the EST containing the List of MSTs the child referes to
for (Einleitungsstelle einleitungsstelle : listOfEST) {
ArrayListModel<Messstelle> listOfMST = einleitungsstelle.getListOfMST();
if (child == listOfMST) {
ret.add(listOfMST);
for (Messstelle messstelle : listOfMST) {
if (child == messstelle.getListOfSUEW()) {
ret.add(messstelle.getListOfSUEW());
break;
}
}
break;
}
}
ret.add(child);
break;
}
default:
ret = null;
}
return ret.toArray();
}
}
...
protected void fireTreeNodesRemoved(Object changed, Object path[], int childIndecies[], Object children[]) {
TreeModelEvent event = new TreeModelEvent(this, path, childIndecies, children);
synchronized (listeners) {
for (Enumeration e = listeners.elements(); e.hasMoreElements();) {
TreeModelListener tml = (TreeModelListener) e.nextElement();
tml.treeNodesRemoved(event);
}
}
}
...
}