私は問題を抱えており、誰かが何がうまくいかないのか、その理由を知っていて、提案どおりに機能させるために今見逃していることを説明してくれることを願っています。
カスタム TreeModel (「WRTreeModel」、以下を参照) に基づいて構築された JTree があります。このモデルが使用されるデータ構造は、いくつかのフィールドと、さらに以下に示す「ArrayListModel」に基づくリストを含むルート オブジェクトのビルドです。WRTreeModel を使用してツリーを構築すると、ツリーがきれいに見えます。オブジェクトに含まれるリストとフィールドを表すノードを展開および折りたたむことができます。これらのリストを展開したり折りたたんだり、その内容を確認したりできます。
ここで、リストの 1 つの子を削除したいと思います。既にわかっているように、ArrayListModel の remove メソッドを呼び出してモデルから子を削除します。WRTreeModel にその削除を認識させるには、まずその fireIntervalRemoved メソッドを呼び出す必要があります。これまでのところは問題ありません。
WRTreeModels の内部クラス ArrayModelListener では、intervalRemoved メソッドが fireTreeNodesRemoved の呼び出しを準備し、登録されているすべての TreeModelListeners (したがって、モデルに接続されたときに自動的に登録される JTree) に転送される TreeEvent を構築します。
ここで、ツリーが変更を反映し、内部および視覚的表現を更新して新しい状態を表示することを期待します。残念ながら、これはそのようには機能しないようです。何かが起こる。しかし、ノードをクリックすると、いくつかの EventHandler-Exceptions がスローされるように変更されました。明らかに、何かが本当に混乱しました。
その場でそのような質問に答えるのは簡単ではないことは承知していますが、迅速な回答をいただければ幸いです。カスタム ツリー モデル (DefaultMutableTreeNode または特定の実装ベースのクラスではなく) の使用と、JTree のイベント処理と更新がどのように機能するかを説明している Web サイトを誰かが知っていれば、それも役に立ちます。
敬具、
トーマス・アーツ
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);
}
}
}
...
}