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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поиск по элементам дерева, как релизовать прокрутку 
:(
    Опции темы
cube
Дата 5.6.2008, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



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

 Это все работает, вот только вопрос как при больших деревьях, прокручивать еще содержимое дерева, чтобы выделенный узел (нода) всегда была в поле видимости пользователя?

дерево реализовал вот так:
Код

public class Tree extends JTree {
  
  private JPopupMenu searchPopup = new JPopupMenu();       // всплывающее меню 
  private JTextField searchText = new JTextField();                   // поле в который пользователь вводит текст для поиска
  private ArrayList<Node> matches = new ArrayList<Node>(); // список в котором я храню все узлы которые соответствуют поиску
  
  public Tree() 
 {
    searchPopup.setLayout(new BorderLayout());
    searchText.setColumns(5);
    searchPopup.add(new JLabel(" найти "), BorderLayout.WEST);
    searchPopup.add(searchText, BorderLayout.EAST);
    setComponentPopupMenu(searchPopup);
    initEvents();                                                                         //инициализация событий
  }

  private void initEvents()
  {
    final JTree my = this;
    searchText.getDocument().addDocumentListener(new DocumentListener() {
      public void insertUpdate(DocumentEvent e){search(e);}
      public void removeUpdate(DocumentEvent e){search(e);}
      public void changedUpdate(DocumentEvent e){search(e);}
    });
    searchText.addKeyListener(new KeyAdapter() {
      @Override
      public void keyPressed(KeyEvent e)
      {
// выделяю узлы соответсвующие поиску при нажатии на клавыши вниз или вверх из текстового поля
        if (getSelectedNodes().length>0 && (KeyEvent.VK_DOWN == e.getKeyCode() || KeyEvent.VK_UP == e.getKeyCode()))
        {
           int i = matches.indexOf(getSelectedNodes()[0]);
           if(KeyEvent.VK_DOWN == e.getKeyCode())selectMatch(++i); // выделение следуещего
           else selectMatch(--i); // выделение предыдущего
        }
      }
    });
    
    this.addKeyListener(new KeyAdapter() {
      @Override
      public void keyPressed(KeyEvent e)
      {
// если нажата клавиша символа на дереве показываю форму поиска
        if (Character.isLetter(e.getKeyChar()))
        {
          searchPopup.show(my, 90, 0);
          searchText.grabFocus();
        }
      }
    });
  }
  
  private void search(DocumentEvent e)
  {
    matches.clear(); // очищаю ранее найденные результаты
    search((Node)getModel().getRoot()); // начинаю поиск
    selectMatch(0); // выделяю первый найденный результат
  }
  
  private void search(Node parent)
  {
    for (int i=0; i<getModel().getChildCount(parent);i++)
    {
      Node child = (Node)getModel().getChild(parent, i);
      if (child.getLabel().getText().toLowerCase().startsWith(searchText.getText().toLowerCase())) // добавляю узел в список соответствующих поиску
        matches.add(child);
      if (child.getChildCount()>0) search(child); // рекурсия
    }
  }
  
  private void selectMatch(int index) 
  {
// если список найденных узлов не пуст и идекс соответствует размерности списка выделяю путь к этому узлу
    if (!matches.isEmpty() && index<matches.size() && index>=0)
        setSelectionPath(new TreePath(matches.get(index).getPath()));
  }

.... другие методы....
}


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


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

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



Код

  TreePath path = tree.getSelectionPath();
  Rectangle rect = tree.getPathBounds(path);
  ((JViewport)tree.getParent()).setViewPosition(new Point(rect.x, rect.y));//это если дерево лежит на JScrollPane

PM MAIL   Вверх
cube
Дата 5.6.2008, 13:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(dorogoyIV @ 5.6.2008,  12:04)
Код

  TreePath path = tree.getSelectionPath();
  Rectangle rect = tree.getPathBounds(path);
  ((JViewport)tree.getParent()).setViewPosition(new Point(rect.x, rect.y));//это если дерево лежит на JScrollPane

Спасибо большое! Работает, но вот только этот вьюпорт устанавливает на столько жестко, что курсор (при выделении) остается на одном месте, как бы дерево перемещаеться вокруг выделенного элемента... 

есть уже готовое решение как сделать это явление нормальным?
PM MAIL   Вверх
dorogoyIV
Дата 5.6.2008, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

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



ну попробуй еще jViewport.scrollRectToVisible(java.awt.Rectangle contentRect)

если не получится код покажи
PM MAIL   Вверх
cube
Дата 5.6.2008, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Цитата(dorogoyIV @ 5.6.2008,  13:57)
ну попробуй еще jViewport.scrollRectToVisible(java.awt.Rectangle contentRect)

если не получится код покажи

(((( неработает
 
вот метод selectMatch() в котором я выделяю узел соответствующий поиску

Код

  private void selectMatch(int index)
  {
    if (!matches.isEmpty() && index<matches.size() && index>=0)
    {
      TreePath path = new TreePath(matches.get(index).getPath()); // получаю путь к узлу
      setSelectionPath(path); // выделяю его
      Rectangle rect = getPathBounds(path); 
      JViewport viewport = (JViewport)getParent();
      viewport.scrollRectToVisible(rect);
    }
  }


спасибо!

на рисунке показано мое дерево в режиме поиска

Это сообщение отредактировал(а) cube - 5.6.2008, 14:36

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  tree3.PNG 17,63 Kb
PM MAIL   Вверх
cube
Дата 5.6.2008, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Еще срабатывает вот так:

Присоединённый файл ( Кол-во скачиваний: 9 )
Присоединённый файл  tree.PNG 19,59 Kb
PM MAIL   Вверх
dorogoyIV
Дата 5.6.2008, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1503
Регистрация: 26.3.2007

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



Цитата(cube @  5.6.2008,  13:43 Найти цитируемый пост)
 Работает, но вот только этот вьюпорт устанавливает на столько жестко, что курсор (при выделении) остается на одном месте, как бы дерево перемещаеться вокруг выделенного элемента... 

не понятно, у меня нормально скроллится
показал бы весь GUI
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.0691 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


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

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