Java-деревоузел:Как предотвратить выполнение дорогостоящей операции getChildCount?

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

  •  03-07-2019
  •  | 
  •  

Вопрос

Я пишу дерево Java, в котором узлы дерева могут иметь дочерние элементы, вычисления которых занимают много времени (в данном случае это файловая система, в которой могут быть сетевые тайм-ауты, которые не позволяют получить список файлов с подключенного диска).

Проблема, которую я обнаружил, заключается в следующем:

  1. getChildCount() вызывается перед тем, как пользователь конкретно запрашивает открытие определенной ветки дерева.Я считаю, что это сделано для того, чтобы JTree знает, показывать ли значок + рядом с узлом.

  2. Точный подсчет детей из getChildCount() потребуется выполнить потенциально дорогостоящую операцию

  3. Если я подделаю значение getChildCount(), дерево выделяет пространство только для такого количества дочерних узлов, прежде чем запросить перечисление дочерних узлов.(Если я верну «1», я увижу в списке только 1 ребенка, несмотря на то, что их больше)

Перечисление детей может оказаться дорогостоящим и трудоемким занятием, меня это устраивает.Но меня это не устраивает getChildCount() нужно знать точное количество детей.

Как-нибудь я могу обойти это?

Добавлен: Другая проблема заключается в том, что если один из узлов представляет собой дисковод (как архаично!), дисковод будет опрошен до того, как пользователь запросит его файлы;если в приводе нет диска, это приводит к системной ошибке.

Обновлять: К сожалению, реализация TreeWillExpand слушатель - это не решение.Это может позволить вам наложить вето на расширение, но количество отображаемых узлов по-прежнему ограничено значением, возвращаемым TreeNode.getChildCount().

Это было полезно?

Решение 4

Решение состоит из нескольких частей:

  • Как сказал Лоренцо Боккачча, используйте ДеревоВоляРазвернутьСлушатель

  • Также, необходимо вызвать nodesWereInserted в дереве, чтобы отобразилось правильное количество узлов. См. этот код

  • Я определил, что если вы не знаете количество дочерних элементов, TreeNode.getChildCount() должен вернуть как минимум 1 (он не может вернуть 0).

Другие советы

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

прокрутите немного вниз, там есть точное руководство о том, как создавать узлы отложенной загрузки для jtree, с примерами и документацией.

Я не уверен, что это полностью применимо, но недавно я решил проблемы с медленным деревом, предварительно вычислив ответы на методы, которые обычно требуют просмотра списка дочерних элементов.Я пересчитываю их только тогда, когда дочерние элементы добавляются, удаляются или обновляются.В моем случае некоторым методам пришлось бы рекурсивно спускаться по дереву, чтобы выяснить такие вещи, как «сколько байтов хранится» для каждого узла.

Если вам нужен большой доступ к определенной функции вашей структуры данных, вычисление которой требует больших затрат, возможно, имеет смысл предварительно вычислить ее.

В случае TreeNodes это означает, что вашим TreeNodes придется хранить количество своих дочерних элементов.Чтобы объяснить это немного подробнее:когда вы создаете узел n0 этот узел имеет дочерний счетчик (cc) из 0.Когда вы добавляете узел n1 будучи ребенком этого, ты n1.cc + cc++.

Сложнее всего является операция удаления.Вы должны сохранять обратные ссылки на родителей и подниматься по иерархии, чтобы вычесть cc вашего текущего узла.

Если вы просто хотите иметь hasChildren функция для ваших узлов или переопределить getChildCount, логического значения может быть достаточно, и оно не заставит вас подниматься по всей иерархии в случае удаления.Или вы можете удалить обратные ссылки и просто сказать, что теряете точность при операциях удаления.А TreeNode Интерфейс на самом деле не заставляет вас выполнять операцию удаления, но вы, вероятно, все равно захотите ее.

Ну, в этом и дело.Чтобы получить заранее вычисленные точные значения, вам придется сохранить некоторые виды обратных ссылок.Если вы этого не сделаете, вам лучше вызвать свой метод hasHadChildren или что более забавно isVirgin.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top