Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> TreeModel and TreeModelListener - изменение модели, Не получается обновлять дерево 
:(
    Опции темы
User1302
  Дата 5.9.2011, 16:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 17.11.2010

Репутация: нет
Всего: нет



Здравствуйте, форумчане!

Пожалуйста, помогите разобраться.
Не получается перерисовывать дерево. Дерево представляет собой группы связанных лиц. То есть: List<List<Person>>. Из главного узла могут удаляться группы List<Person>, а также из конкретной группы List<Person> могут быть удалены лица Person.

Дерево строится из модели.
Модель реализует TreeModel. Данные берутся из списка списков List<List<Person>>.

Проблема: при удалении лица дерево совсем пропадает из контейнера.
В модели дерева такие переменные: List<List<Person>> root - корневой узел, группа лиц List<Person> group, лицо Person p
Уведомление слушателей происходит так:
Код

final EventListener[] listeners = listenerList.getListeners(TreeModelListener.class);
        final TreeModelEvent event = new TreeModelEvent(this, new Object[]{root, group, p});
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < listeners.length; i++) {
//                    ((TreeModelListener) listeners[i]).treeStructureChanged(event);
                    ((TreeModelListener) listeners[i]).treeNodesRemoved(event);
                }
            }
        });

Если вызываю метод TreeModelListener.treeStructureChanged(new TreeModelEvent(this, new Object[]{root})); - дерево перерисовывается, только сворачивается. Хочется, чтоб оставалось несвернутым.

Вот полный рабочий код:
Код


import java.awt.EventQueue;
import java.util.ArrayList;
import java.util.EventListener;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.EventListenerList;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;

public class TreeExample {

    public static void main(String[] args) throws InterruptedException {

        //Подготавливаем список для модели дерева
        List<List<Person>> groups = new ArrayList<List<Person>>();
        List<Person> group1 = new ArrayList<Person>();
        List<Person> group2 = new ArrayList<Person>();

        Person person1 = new Person();
        Person person2 = new Person();
        Person person3 = new Person();
        Person person4 = new Person();

        group1.add(person1);
        group2.add(person2);
        group2.add(person3);
        group2.add(person4);

        groups.add(group1);
        groups.add(group2);

        //Подготавливаем модель и дерево
        final JTree tree = new JTree();
        ExampleTreeModel model = new ExampleTreeModel();
        model.setRoot(groups);
        tree.setModel(model);

        //Подготавливаем фрейм и запускаем его
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setBounds(500, 500, 500, 500);

                JScrollPane scrollPane = new JScrollPane(tree);
                frame.add(scrollPane);

                frame.setVisible(true);
            }
        });

        //имитируем удаление Person-a из списка
        Thread.sleep(3000);
        group2.remove(person4);
        model.personRemoved(person4, group2);
    }
}

//Модель дерева. Источник данных - простой список списков List<List<Person>>
class ExampleTreeModel implements TreeModel {

    private List<List<Person>> root;
    private EventListenerList listenerList = new EventListenerList();

    public void setRoot(List<List<Person>> root) {
        this.root = root;
    }

    @Override
    public Object getRoot() {
        return root;
    }

    @Override
    public Object getChild(Object parent, int index) {
        if (((List) parent).size() <= index) {
            return null;
        }
        return ((List) parent).get(index);
    }

    @Override
    public int getChildCount(Object parent) {
        if (parent instanceof Person) {
            return 0;
        }
        return ((List) parent).size();
    }

    @Override
    public boolean isLeaf(Object node) {
        return (node instanceof Person);
    }

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

    @Override
    public int getIndexOfChild(Object parent, Object child) {
        if (parent instanceof Person) {
            return 0;
        }
        if (parent == root) {
            if (root.contains((List) child)) {
                return root.indexOf(child);
            } else {
                return 0;
            }
        } else {
            return ((List) parent).indexOf(child);
        }
    }

    @Override
    public void addTreeModelListener(TreeModelListener l) {
        listenerList.add(TreeModelListener.class, l);
    }

    @Override
    public void removeTreeModelListener(TreeModelListener l) {
        listenerList.remove(TreeModelListener.class, l);
    }

    //Метод для уведомления модели о том, что удален Person из списка.
    //В методе - уведомление слушателей модели. В нашем случае - tree
    public void personRemoved(Person p, List<Person> group) {
        final EventListener[] listeners = listenerList.getListeners(TreeModelListener.class);
        final TreeModelEvent event = new TreeModelEvent(this, new Object[]{root, group, p});
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                for (int i = 0; i < listeners.length; i++) {
//                    ((TreeModelListener) listeners[i]).treeStructureChanged(event);
                    ((TreeModelListener) listeners[i]).treeNodesRemoved(event);
                }
            }
        });
    }
}

//Сущность для построения иерархии в дереве
class Person {

    private long id;
    private String title;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }
}



Заранее спасибо!
PM MAIL   Вверх
jk1
Дата 6.9.2011, 03:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник
Сообщений: 1168
Регистрация: 17.10.2008
Где: Санкт-Петербург

Репутация: 21
Всего: 75



Код

TreeModelListener.treeStructureChanged()

предполагает, что структура дерева меняется очень сильно, так что текущие раскрытые пути сохранять смысла нет. Можно попробовать вызывать не от root, а от изменяемого узла, тогда он обновит поддерево, а остальное оставит нетронутым.


--------------------
Opinions are like assholes — everybody has one
PM MAIL   Вверх
User1302
Дата 6.9.2011, 09:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 17.11.2010

Репутация: нет
Всего: нет



Цитата

jk1 Можно попробовать вызывать не от root, а от изменяемого узла

Пробовал вместо:
Код

final TreeModelEvent event = new TreeModelEvent(this, new Object[]{root, group, p});

создавать событие так:
Код

final TreeModelEvent event = new TreeModelEvent(this, new Object[]{group, p});

То есть нет от корневого узла root, а от узла, кот. изменяется - проблема та же.

Думаю, что неверно формирую обьект события TreeModelEvent. 
Или, неверно реализую методы TreeModel.

Буду искать..
PM MAIL   Вверх
User1302
Дата 7.9.2011, 12:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 23
Регистрация: 17.11.2010

Репутация: нет
Всего: нет



В нете ничего не могу найти пока smile 

Может кто ответит на вопрос, если я сформулирую его несколько иначе:

Есть список внутри которого находятся обьекты. (В моем случае List<Person>).
Этот список наполняется пускай таким-себе "менеджером лиц" (что-то вроде PersonManager).

Я хочу построить из этого списка простенькое дерево такого вида: корневой узел - List, листы - Person.
Проще всего сделать дерево с помощью модели, так удобно и логично.

Теперь представим, что в логике программы менеджер лиц удаляет из списка лицо List<Person>.remove(person);

Вот теперь нужно сказать об этом дереву, чтоб оно отцепило от себя один лист Person.

Как это сделать правильно?

PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   jk1
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, jk1.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: GUI и Java FX приложения | Следующая тема »


 




[ Время генерации скрипта: 0.0683 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.