Здравствуйте, форумчане!
Пожалуйста, помогите разобраться. Не получается перерисовывать дерево. Дерево представляет собой группы связанных лиц. То есть: 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; } }
|
Заранее спасибо! |