2009-05-06 2 views
10

У меня есть объект данных, представленный в TreeModel, и я хотел бы показать только его часть в моем JTree - ради аргумента, скажем, листья и их родители. Как я могу скрыть/отфильтровать ненужные узлы?Скрытие/фильтрация узлов в JTree?

+0

Это устаревшая и менее информативная тема, чем этот дубликат: http://stackoverflow.com/questions/9234297/filtering-on-a-jtree – bobjandal

ответ

0

Если вы все еще являетесь деревом, которое вы показываете, то TreeModel, который фильтрует существующие вами TreeModel, должен быть достаточно простым.

+0

Можете ли вы объяснить это дальше? –

+0

Что вы хотите знать. Вам будет легче найти примеры, которые делают то же самое с TableModel. Вы хотите создать TreeModel, который делегирует вашу текущую модель, но удаляет узлы, которые вы не хотите отображать.Я предлагаю, по крайней мере, начать с того, что вы делаете все событие распространенным как structChanged (хотя подумайте об этом, что приведет к срыву расширения дерева). –

+1

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

0

Используйте код, используемый для создания TreeNode (ов), и перестройте TreeNode (ы), только включая нужные элементы. Установите корневой узел в TreeModel с фильтрованным корневым узлом.

+0

Это выполнимо, но когда вы устанавливаете другую модель, JTree делает много вещей под капотом, особенно если обнаруживает структурные изменения. Это не очень хорошо с точки зрения производительности, как для скорости, так и для памяти. – gouessej

8

Моя возможная реализация:

  • Есть два TreeModel с, лежащий в основе один и отфильтрованный один.
  • Когда происходит изменение в базовом TreeModel, перестройте отфильтрованный TreeModel с нуля. Клонировать каждый узел, который должен быть видимым, и добавить его к его первому видимому предшественнику в отфильтрованном TreeModel (или корень, если ни один из них не виден). См. Ниже код, если вам интересно.
  • У этого есть несчастливый побочный эффект, разрушающий каждый путь, который открыл пользователь. Чтобы обойти это, я добавил TreeModelListener фильтруемому TreeModel. Когда модель изменяется, я сохраняю расширенные пути в JTree (используя getExpandedDescendants()), а затем повторно расширяет их позже (используя SwingUtilities.invokeLater()).

    Мне пришлось переопределить equals() в классе TreeNode, который я использовал, чтобы новые клонированные узлы были такими же, как старые клонированные узлы.


... 
    populateFilteredNode(unfilteredRoot, filteredRoot); 
    ... 

    void populateFilteredNode(TreeNode unfilteredNode, TreeNode filteredNode) 
    { 
    for (int i = 0; i < unfilteredNode.getChildCount(); i++) 
    { 
     TreeNode unfilteredChildNode = unfilteredNode.getChildAt(i); 

     if (unfilteredChildNode.getType() == Type.INVISIBLE_FOLDER) 
     { 
     populateFilteredNode(unfilteredChildNode, filteredNode); 
     } 
     else 
     { 
     TreeNode filteredChildNode = unfilteredChildNode.clone(); 

     filteredNode.add(filteredChildNode); 

     populateFilteredNode(unfilteredChildNode, filteredChildNode); 
     } 
    } 
    } 
2

Вы пробовали JXTree? (к сожалению, сайт сейчас недоступен, но вы можете использовать Google для зеркал)

+0

На самом деле, поддержка фильтров в JXTree никогда не была реализована, хотя это было запланировано, я просто вижу защищенное неиспользуемое поле о фильтрации в своем исходном коде. – gouessej

1

Если вы ищете коммерческое решение, JideSoft имеет фильтруемую тремодель. Помимо этого, SwingX имеет API фильтра, который будет работать на JXTable, JXTreeTable, JXTree и JXList.

+0

Спасибо! Я попробовал Jide, но я не мог заставить его делать то, что я хотел. Когда я получаю шанс, я посмотрю на SwingX API. –

+0

Что именно вы пытаетесь сделать? Если вы предоставите подробные сведения, я могу дать конкретный код. Насколько я понимаю, отфильтрованные листья из критериев поиска будут показаны вместе со своими родителями. Это показано в их демонстрации в Интернете, по адресу http://www.jidesoft.com/products/download.htm, «Демо для всех продуктов JIDE». В этом случае посмотрите демонстрацию QuickFilter (Дерево). – Aakash

+0

Насколько я помню, у меня возникли проблемы с тем, чтобы модель Jide tree продемонстрировала видимые дети невидимых родителей. –

3

Вы должны знать о GlazedLists. Это фантастическая библиотека для выполнения сложных табличных преобразований без особых усилий. Они также расширились и до деревьев. Это может потребовать небольшого рефакторинга вашего существующего кода, чтобы заставить его работать в режиме GlazedLists. Но ознакомьтесь с демо и веб-трансляциями, чтобы узнать, насколько он силен. (Это одна из основных библиотек Swing, на мой взгляд, и это с открытым исходным кодом.)

+0

Я ничего не вижу в GlazedLists для деревьев: https://java.net/projects/glazedlists/sources/svn/show/trunk/source/ca/odell/glazedlists/swing?rev=2375 Пожалуйста, расскажите, где вы нашли его фильтрующие API для деревьев? – gouessej

+0

@gouessej находится в папке с расширениями: https://java.net/projects/glazedlists/sources/svn/show/trunk/extensions/treetable/source/ca/odell/glazedlists/swing?rev=2375 – arooaroo

+1

Спасибо, но это работает на таблицах деревьев, а не на деревьях. – gouessej

1

Взгляните на этой реализации: http://www.java2s.com/Code/Java/Swing-Components/InvisibleNodeTreeExample.htm

Это создает подклассы DefaultMutableNode добавлении «IsVisible» собственность, а затем на самом деле удаление/добавление узлов из TreeModel.

+0

Мне недавно нужно было внедрить фильтрацию в JTree, и это решение было на сегодняшний день самым чистым и простым. – Aaron

Смежные вопросы