J'ai un problème et j'espère, quelqu'un sait ce qui ne va pas et pourquoi et est capable de me donner l'explication de ce qui me manque en ce moment pour faire fonctionner cette chose comme suggéré.Swing question/JTree/modèle d'arbre personnalisé
J'ai un JTree qui est construit sur un TreeModel personnalisé ("WRTreeModel", voir ci-dessous). La structure de données pour laquelle ce modèle doit être utilisé est la construction d'un objet racine qui contient des champs et en outre une liste qui est sauvegardée par le "ArrayListModel" montré ci-dessous. L'arborescence est parfaite lorsque je la compile à l'aide de WRTreeModel. Je suis capable de développer et de réduire les nœuds qui représentent les listes et les champs contenus dans les objets. Je peux développer et réduire ces listes et voir leur contenu et ainsi de suite.
Maintenant, je veux supprimer un enfant de l'une des listes et - comme je le sais déjà - le faire en le supprimant du modèle appelant la méthode remove de ArrayListModel. Pour rendre le WRTreeModel conscient de cette suppression, la première chose à faire est d'appeler sa méthode fireIntervalRemoved qui est appelée, jusqu'ici tout va bien.
Dans la WRTreeModels classe interne ArrayModelListener la méthode intervalRemoved prépare l'appel de fireTreeNodesRemoved qui a ensuite construit une TreeEvent qui est transmis à tous les inscrits TreeModelListeners (et donc le JTree qui s'enregistre automaticall lorsqu'il est connecté au modèle).
Maintenant je m'attendrais à ce que l'arbre reflète le changement et mette à jour sa représentation interne et visuelle pour montrer le nouvel état. Malheureusement, cela ne semble pas fonctionner de cette façon. Quelque chose arrive. Mais quand je clique sur le nœud que j'ai juste changé, certaines EventHandler-Exceptions sont levées. De toute évidence, quelque chose est devenu vraiment confus.
Je sais que ce n'est pas facile de répondre à une telle question à la volée, mais j'apprécierais vraiment une réponse rapide. Il serait également utile, si quelqu'un connaissait des sites Web expliquant l'utilisation de modèles d'arborescence personnalisés (pas sur DefaultMutableTreeNode ou une classe basée sur l'implémentation donnée) et comment la gestion et la mise à jour des événements JTree fonctionnent.
Avec mes meilleures salutations,
Arts Thomas
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);
}
}
}
...
}
Ne sait pas si c'est d'aide supplémentaire, mais quand j'essaye de réduire puis de développer le nœud parent du nœud supprimé, je reçois l'exception suivante: Exception dans le fil "AWT-EventQueue-0" java.lang. NullPointerException \t à javax.swing.plaf.basic.BasicTreeUI.ensureRowsAreVisible (BasicTreeUI.java:1881) \t à javax.swing.plaf.basic.BasicTreeUI.toggleExpandState (BasicTreeUI.java:2208) \t à javax.swing. plaf.basic.BasicTreeUI.handleExpandControlClick (BasicTreeUI.java:2191) \t at javax.swing.plaf.base.BasicTreeUI.checkForClickInExpandControl (BasicTreeUI.java:2149) \t à ... et ainsi de suite –
Tous les problèmes sont urgents par définition :-) Je ne mentionnerais pas "pression du temps" dans une question. Et votre question est destinée à rester et à aider les autres quand vous l'oubliez depuis longtemps. Le rend plus canonique. – raoulsson