Java TreeNode: ¿Cómo evitar que getChildCount realice una operación costosa?

StackOverflow https://stackoverflow.com/questions/154791

  •  03-07-2019
  •  | 
  •  

Pregunta

Estoy escribiendo un árbol Java en el que los nodos de árbol podrían tener hijos que tardan mucho tiempo en calcularse (en este caso, es un sistema de archivos, donde puede haber tiempos de espera de red que impiden obtener una lista de archivos de un archivo adjunto). conducir).

El problema que estoy encontrando es el siguiente:

    Se llama a
  1. getChildCount () antes de que el usuario solicite específicamente abrir una rama particular del árbol. Creo que esto se hace para que JTree sepa si debe mostrar un icono + al lado del nodo.

  2. Un recuento preciso de hijos de getChildCount () necesitaría realizar la operación potencialmente costosa

  3. Si falsifico el valor de getChildCount () , el árbol solo asigna espacio para tantos nodos secundarios antes de solicitar una enumeración de los secundarios. (Si devuelvo '1', solo veré 1 niño en la lista, a pesar de que hay más)

La enumeración de los niños puede ser costosa y llevar mucho tiempo, estoy de acuerdo con eso. Pero no estoy de acuerdo con que getChildCount () necesite saber la cantidad exacta de hijos.

¿Hay alguna forma de solucionar esto?

Añadido: El otro problema es que si uno de los nodos representa una unidad de disquete (¡qué arcaico!), la unidad se sondeará antes de que el usuario solicite sus archivos; si no hay un disco en la unidad, esto produce un error del sistema.

Actualización: Desafortunadamente, implementar la escucha TreeWillExpand no es la solución. Eso puede permitirle vetar una expansión, pero el número de nodos que se muestra todavía está restringido por el valor devuelto por TreeNode.getChildCount () .

¿Fue útil?

Solución 4

La solución tiene algunas partes:

  • Como dijo Lorenzo Boccaccia, use TreeWillExpandListener

  • También , debe llamar a nodesWereInserted en el árbol, para que se muestre el número adecuado de nodos. Consulte este código

  • He determinado que si no conoce el recuento de hijos, TreeNode.getChildCount () debe devolver al menos 1 (no puede devolver 0)

Otros consejos

http://java.sun.com /docs/books/tutorial/uiswing/components/tree.html#data

desplácese un poco hacia abajo, encontrará el tutorial exacto sobre cómo crear nodos de carga lenta para el jtree, con ejemplos y documentación

No estoy seguro de si es completamente aplicable, pero recientemente resolví problemas con un árbol lento al pre-calcular las respuestas a los métodos que normalmente requieren revisar la lista de niños. Solo los recompongo cuando se agregan, eliminan o actualizan niños. En mi caso, algunos de los métodos habrían tenido que ir recursivamente por el árbol para descubrir cosas como "cuántos bytes se almacenan" para cada nodo.

Si necesita un montón de acceso a una característica particular de su estructura de datos que sea costosa de computar, puede tener sentido hacerlo previamente.

En el caso de TreeNodes, esto significa que sus TreeNodes tendrían que almacenar su recuento de hijos. Para explicarlo un poco más detalladamente: cuando crea un nodo n0 este nodo tiene un recuento de niños ( cc ) de 0. Cuando agrega un nodo n1 como hijo de éste, n1.cc + cc ++ .

El bit complicado es la operación de eliminación. Debe mantener los vínculos de retroceso con los padres y subir la jerarquía para restar el cc de su nodo actual.

En caso de que solo quieras tener la función hasChildren para tus nodos o anular getChildCount , un booleano podría ser suficiente y no te obligaría a subir por completo Jerarquía en caso de expulsión. O puede eliminar los vínculos de retroceso y simplemente decir que pierde precisión en las operaciones de eliminación. La interfaz TreeNode en realidad no lo obliga a proporcionar una operación de eliminación, pero probablemente desee una de todas formas.

Bueno, ese es el trato. Para poder obtener valores precisos precomputados, tendrá que mantener backlinks de algún tipo. Si no es así, es mejor que llames a tu método hasHadChildren o al más interesante es

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top