Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > JTree + TreeModel. CellRenderer


Автор: chief39 12.7.2005, 11:45
Суть такая:

есть дерево и есть модель для него.
Из файла тяну древовидную структуру. Методы доступа к ней реализованы в моей TreeModel.

Рисую СеллРендерером в каждом ноде панельку с несколькими лейблами, извлечёнными из объекта моей древесины(TreeModel).

В общем всё неплохо...

Но!

Пытаюсь удалять....

Поскольку ноды у меня - это ссылки на мои специфические объекты - то их и надо у далять из этой структуры. В каждом объекте есть эррейлист ссылок на сыновей из которого удаляю нужного сына.
Всё хорошо, всё отлично.... но элемент отображается по прежнему. smile
В листе его нет ( проверял ), каунт листа уменьшился на единицу....
И всё-таки, фугас ему в глаз, он отображается!!!!
но ссылочка есть.... Потому как вытягиваются из него данные рендерером и на станд. вывод тоже.....

Мне кажется, что для него создаётся нод, который на него указывает и который надо удалить.... Но как???

Пытаясь получить селекшн - получаю свой элемент но никак не ноду.

Рэпейнты и ревалидейты пробовал...

КАК ЕГО УБРАТЬ???




Автор: batigoal 12.7.2005, 11:48
Может, в лоб - создание копии дерева без этого нода и его отображение?

Автор: AntonSaburov 12.7.2005, 12:08
Хорошо бы конечно код посмотреть. И надо бы в FAQ заглянуть. http://vingrad.ru/JAVA-JAV-000114

Автор: chief39 12.7.2005, 12:21
Цитата(AntonSaburov @ 12.7.2005, 12:08)
Хорошо бы конечно код посмотреть. И надо бы в FAQ заглянуть. Пример работы с JTree


Я туда и заглядывал smile По сайтикам и факам полазил.
Там всё о TreeNode


Автор: Andyb 12.7.2005, 12:30
Попробуй treeModel.reload(); после удаления, а потом перерисовать родительский узел

Автор: chief39 12.7.2005, 12:32
Это из фака:

Код

DefaultTreeModel model = (DefaultTreeModel)jTree.getModel();
        Object obj = jTree.getLastSelectedPathComponent();
        if(obj!=null)
        {
            DefaultMutableTreeNode sel = (DefaultMutableTreeNode)obj;


В последней строчке у меня возвращается не DefaultMutableTreeNode а Question (мой классик. Всякая информация о себе же и там же списочек на другие ноды)

Только что проверил - если вытягивать элемент который не удалился через переписаную мной функцию public Object getChild(Object parent, int index) для TreeModel - там нулл как и должно быть. с count этих подНодов тоже всё в порядке.

То есть модель работает корректно.... (когда я её потом сохраняю в файл - там всё как и должно быть)

Но из самого JTree судя по всему остаётся ссылка на этот объект Question!!!
То есть подтягивает данные из тримодела а потом работает само... по своим ссылочкам, или нет?
smile
Добавлено @ 12:35
Цитата
Попробуй treeModel.reload();, а потом перерисовать родительский узел


можно поподробнее?

Меня тоже потянуло поискать чёт на "re" но там такого нет smile
не находит....


Перерисовываю всё дерево (вернее repaint, revalidate)

что за релоад и с чем его едят???

Автор: Andyb 12.7.2005, 12:39
Цитата
что за релоад и с чем его едят???

Релоад модели дерева
Код

DefaultTreeModel model = (DefaultTreeModel)jTree.getModel();
   model.reload();

Автор: chief39 12.7.2005, 12:54
Я имплементил свою от TreeModel

Там такого нет...

унаследовал от DefaultTreeModel - хочет конструктор с рутом. В рут хочет нод а не мой класс.

Тупик. Как это обойти? Сегодня почти не спал и туго соображаю....

просто с TreeModel это можно сделать (что-то похожее) ?


Автор: DarkDS 12.7.2005, 12:59
TreeModel у тебя от Дефолт наследованна или просто реализация своя?
Если от дефолт, то поможет вызов метода: fireTreeStructureChanged
Добавлено @ 13:00
Увидел. Поздно. Сейчас пример кину своей имплементации fireTreeStructureChanged
Добавлено @ 13:01
Лишее нужно удалить, но идея я думаю понятна smile
Код

import java.util.ArrayList;

import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

/**
 * @author dsilinski
 *
 */
public class LearTreeModel implements TreeModel
{
    private RootNode m_root;
    private ArrayList m_treeModelListeners;
    /**
     * 
     */
    public LearTreeModel( RootNode root )
    {
        super();
        
        m_treeModelListeners = new ArrayList();
        m_root = root;
    }

    public Object getRoot()
    {
        return m_root;
    }

    public Object getChild( Object parent, int index )
    {
        if ( parent instanceof MultiChildNode )
        {
            return ((MultiChildNode)parent).get( index );
        }
        return null;
    }

    public int getChildCount( Object parent )
    {
        if ( parent instanceof MultiChildNode )
        {
            return ((MultiChildNode)parent).getCount();
        }
        return 0;
    }

    public boolean isLeaf( Object node )
    {
        return (getChildCount( node ) > 0)?false:true;
    }

    public void valueForPathChanged( TreePath path, Object newValue ) {}

    public int getIndexOfChild( Object parent, Object child )
    {
        if ( parent instanceof MultiChildNode )
            return ((MultiChildNode)parent).indexOf( child );
        return -1;
    }

    public void addTreeModelListener( TreeModelListener l )
    {
        m_treeModelListeners.add( l );
    }

    public void removeTreeModelListener( TreeModelListener l )
    {
        m_treeModelListeners.remove( l );
    }
    
    protected void fireTreeStructureChanged( TreeModelEvent e )
    {
        for (int i = 0; i < m_treeModelListeners.size(); i++)
        {
            ((TreeModelListener)m_treeModelListeners.get(i)).
                        treeStructureChanged( e );                
        }
    }
}

Добавлено @ 13:03
ЗЫ. Дерево тут не обновляется. Обновление происходит из наследника вызовом метода fireTreeStructureChanged.
По идее единственное что нужно перенести - addTreeModelListener, removeTreeModelListener, fireTreeStructureChanged

Автор: Andyb 12.7.2005, 13:38
Цитата
DefaultTreeModel - хочет конструктор с рутом. В рут хочет нод а не мой класс.

можно сделать так:
Код

DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
    DefaultTreeModel model= new DefaultTreeModel(root);
    JTree tree = new JTree(model);
    MyClass myClass = new  MyClass();//Твой класс
    DefaultMutableTreeNode node = new DefaultMutableTreeNode(myClass);
    int n = root.getChildCount();
    model.insertNodeInto(node,root,n);
......................


Автор: chief39 12.7.2005, 17:38

smile

Я чуть не опупел.....

Вчера до 11 сидел и сегодня с 7 на работе... аж обидно.... smile

оказывается.....

Код


parent.remove(question); // это я удалял из своей модели элементик....

SwingUtilities.updateComponentTreeUI(tree);  // а вот что помогло.....





Всё работает без нодов и дефолт деревяной модели

просто имплементировал деревянную модель и переписал чтоб она тягала данные из моей деревянной smile

Спасибо всем за советы. Покопался smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)