Опубликован: 25.09.2009 | Уровень: специалист | Доступ: платный
Лекция 3:

Элемент дерево (Tree view)

< Лекция 2 || Лекция 3: 12 || Лекция 4 >
Аннотация: В этой лекции слушатель научится создавать и заполнять элемент дерево. Также будут рассмотрены примеры поиска по дереву и обработки триггеров.

Элемент Tree View является специфичным не только потому, что требует особых условий и настройки свойств, а еще и потому, что для управления этим элементом в Oracle Forms создан специальный встроенный пакет FTREE. Элемент дерево является очень функциональным, так как позволяет скоординировать и компактно отобразить большой набор данных, разбивая его на логические единицы - узлы. Вы можете заполнять деревья статически и динамически данными из таблиц. В дереве вы можете реализовать отношение Мастер-Деталь, выбирая в качестве родительского узла запись таблицы Мастер, а в качестве дочернего - запись из таблицы Деталь. Вы также можете использовать дерево как навигатор вашего приложения, в котором перечислены все блоки и элементы. Пакет FTREE содержит довольно небольшой объем процедур и функций, которые перечислены ниже:

  • ADD_TREE_DATA ;
  • ADD_TREE_NODE ;
  • DELETE_TREE_NODE ;
  • FIND_TREE_NODE ;
  • POPULATE_GROUP_FROM_TREE ;
  • POPULATE_TREE ;
  • SET_TREE NODE_PROPERTY.

Создание Tree View

Tree View представляет собой прямоугольную область, в которой отображается иерархическое дерево. Для того чтобы создать дерево, выполните следующие действия:

  1. Создайте новую форму и сохраните ее как TREE.
  2. Находясь в навигаторе объектов, создайте два небазовых блока. Первый блок назовите " TREE ", а второй " CONTR ".
  3. Находясь в редакторе разметки, создайте одну канву. Разместите на канве элемент Tree View и две кнопки.
  4. Установите для элемента TREE VIEW блок TREE, а все остальные элементы ассоциируйте с блоком " CONTR ".

В этом примере мы создали дополнительный управляющий блок данных "CONTR" для последующего использования в примерах.

Прежде чем построить дерево, рассмотрим основные методы пакета FTREE, которые нам для этого понадобятся.

Функция ADD_TREE_NODE

ADD_TREE_NODE (item_id [item_id] ITEM, node NODE, 
      offset_ type NUMBER, offset NUMBER, state NUMBER, 
     label VARCHAR2, icon VARCHAR2, value VARCHAR2) 
RETURN FTREE.NODE

- добавляет новый элемент в дерево.

Метод Параметр Тип Значение
FUNCTION ADD_TREE_NODE (параметры) RETURN NODE itemname [idname] VARCHAR2 [FORMS4C.ITEM] Определяет имя элемента или его идентификатор
node FTREE.NODE Определяет вершину дерева
offsettype NUMBER Определяет тип сдвига для вершины, возможные значения: PARENT_OFFSET, SIBLING_OFFSET
offset NUMBER Определяет позицию новой вершины: если это PARENT_OFFSET, то позиция 1-n,, или LAST_CHILD. Если тип сдвига SIBLING_OFFSET, то позицией сдвига может быть NEXT_NODE или PREVIOUS_NODE
state NUMBER Определяет состояние вершины: COLLAPSED_NODE, EXPANDED_NODE, LEAF_NODE
label VARCHAR2 Отображаемый текст для вершины
icon VARCHAR2 Имя файла иконки для вершины
value VARCHAR2 Значение, которое содержит вершина
Примечание:элемент дерево всегда должен размещаться в отдельном блоке и быть в нем единственным элементом. В предыдущем примере для того чтобы разместить кнопки, нам пришлось создать второй блок, так как блок, содержащий элемент Tree View, не может содержать других элементов. Если вы все же разместите еще один элемент в блоке "TREE", то получите ошибку "FRM-32089 - Деревья должны размещаться в однозаписных блоках с одним элементом".

Следующий пример описывает процесс добавления нового элемента в существующее дерево.

DECLARE
 Itree ITEM;
 top_node Ftree.Node;
 new_node Ftree.Node;
 i_value VARCHAR2(30);
BEGIN
 Itree := Find_Item('tree_block.tree_item ');
 new_node := Ftree.Add_Tree_Node(Itree, Ftree.ROOT_NODE,
   Ftree.PARENT_OFFSET, Ftree.LAST_CHILD,
   Ftree.EXPANDED_NODE, i_value, NULL, i_value);
END;
Листинг 3.1. Добавление элемента к дереву
Процедура DELETE_TREE_NODE

DELETE_TREE_NODE (item_name [item_id] VARCHAR2, node FTREE.NODE) - эта процедура выполняет действие, обратное ADD_ TREE_NODE, то есть удаляет элемент дерева.

Метод Параметр Тип Значение
PROCEDURE DELETE_TREE_NODE(параметры) itemname [idname] VARCHAR2 [FORMS4C.ITEM] Определяет имя элемента или его идентификатор
node FTREE.NODE Определяет вершину дерева, которую необходимо удалить

Следующий пример описывает процесс удаления вершины и всех ее детей.

DECLARE
 Itree item := find_item('tree_block.tree_item ');
 del_node Ftree.Node;
 i_value VARCHAR2(30);
BEGIN
 del_node := Ftree.Find_Tree_Node(Itree, i_value,
  Ftree.FIND_NEXT, Ftree.NODE_LABEL,
  Ftree.ROOT_NODE, Ftree.ROOT_NODE);
 IF NOT Ftree.ID_NULL(del_node) then 
  Ftree.Delete_Tree_Node(Itree, del_node); 
 END IF; 
END;
Листинг 3.2. Удаление элемента дерева
Функция FTREE.GET_TREE_NODE_PARENT

FTREE.GET_TREE_NODE_PARENT (item_name [item_id] VARCHAR2, node FTREE.NODE) - возвращает родителя указанной вершины дерева.

Метод Параметр Тип Значение
FUNCTION DELETE_TREE_NODE (параметры) RETURN NODE itemname [idname] VARCHAR2 [FORMS4C.ITEM] Определяет имя элемента или его идентификатор
node FTREE.NODE Вершина дерева, для которой отыскивается родитель

Следующий пример описывает процесс получения родителя указанного элемента.

DECLARE
 Itree item := find_item('tree_block.tree_item ');
 par_node FTREE.NODE;
BEGIN
 par_node := Ftree.Get_Tree_Node_Parent(Itree,
   :SYSTEM.TRIGGER_NODE);
 ...
END;
Листинг 3.3. Получение родителя элемента дерева. Триггер WHEN-TREE-NODE-SELECTED
Функция FTREE.GET_TREE_NODE_PROPERTY

FTREE.GET_TREE_NODE_PROPERTY (item_name [item_id] VARCHAR2, node NODE, property NUMBER) RETURN VARCHAR2 - возвращает значение свойства указанной вершины дерева.

Метод Параметр Тип Значение
FUNCTION GET_TREE_NODE_PROPERTY (параметры) RETURN VARCHAR2 itemname [idname] VARCHAR2 [FORMS4C.ITEM] Определяет имя элемента или его идентификатор
node FTREE.NODE Вершина дерева, для которой отыскивается родитель
property NUMBER Возвращает значение одного из перечисленных свойств: NODE_STATE, NODE_DEPTH, NODE_LABEL, NODE_ICON, NODE_VALUE

Следующий пример проверяет состояние указанной вершины, и если она не раскрыта, то есть NODE_STATE установлено в COLLAPSED_ NODE, то вершина автоматически раскрывается, то есть NODE_STATE устанавливается в EXPANDED_NODE.

DECLARE
 Itree item := find_item('tree_block.tree_item ');
BEGIN
 IF Ftree.Get_Tree_Node_Property(Itree,
   :SYSTEM.TRIGGER_NODE, Ftree.NODE_STATE)=Ftree.COLLAPSED_NODE
 THEN 
  ftree.set_tree_node_property(Itree, 
    :SYSTEM.TRIGGER_NODE, ftree. node_state, ftree.expanded_node); 
 END IF; 
END;
Листинг 3.4. Получение значения свойства элемента дерева. Триггер WHEN-TREE-NODE-SELECTED

Используйте функцию FTREE.GET_TREE_NODE_PROPERTY для получения значения вершины.

DECLARE
 Itree item := find_item('tree_block.tree_item ');
BEGIN
 Ftree.Get_Tree_Node_Property(Itree, :SYSTEM.TRIGGER_NODE, 
   Ftree.NODE_VALUE);
 ...
END;
Листинг 3.5. Получение значения элемента дерева. Триггер WHEN-TREE-NODE-SELECTED
Функция FTREE.GET_TREE_PROPERTY

FTREE.GET_TREE_PROPERTY (item_name [item_id] VARCHAR2, property NUMBER) RETURN VARCHAR2 - возвращает значение свойства указанного элемента дерева.

Метод Параметр Тип Значение
FUNCTION GET_TREE_PROPERTY (параметры) RETURN VARCHAR2 itemname [idname] VARCHAR2 [FORMS4C.ITEM] Определяет имя элемента или его идентификатор
property NUMBER Возвращает значение одного из перечисленных свойств: DATASOURCE, RECORD_GROUP, SET_TREE_PROPERTY, QUERY_TEXT, NODE_COUNT, SELECTION_COUNT, ALLOW_EMPTY_BRANCHES, ALLOW_MULTI-SELECT

Следующий пример описывает процесс получения количества вершин указанного дерева.

DECLARE
 Itree item := find_item('tree_block.tree_item ');
 node_cnt NUMBER;
BEGIN
 node_cnt := Ftree.Get_Tree_Property(Itree,
 Ftree.NODE_COUNT);
 Message('Количество вершин дерева: '||node_cnt);
END;
Листинг 3.6. Получение значения свойства дерева. Триггер WHEN-TREE-NODE-SELECTED
Функция FTREE.GET_TREE_SELECTION

GET_TREE_SELECTION (item_name [item_id] VARCHAR2, selection NUMBER) RETURN Ftree.NODE - возвращает выделенную вершину дерева.

Метод Параметр Тип Значение
FUNCTION GET_TREE_SELECTION (параметры) RETURN VARCHAR2 itemname [idname] VARCHAR2 [FORMS4C.ITEM] Определяет имя элемента или его идентификатор
selection NUMBER Индекс выделенной вершины дерева

Следующий пример описывает процесс получения выделенных элементов указанного дерева. Все элементы, помеченные как выделенные, будут удалены, причем удалять элементы нужно в обратном порядке, как показано в примере.

DECLARE
 Itree item := find_item('tree_block.tree_item ');
 Select_cnt NUMBER;
 del_node FTREE.NODE;
BEGIN
 Select_cnt:= Ftree.Get_Tree_Property(Itree,
 Ftree.SELECTION_COUNT);
 FOR i IN REVERSE 1..select_cnt LOOP
  del_node := Ftree.Get_Tree_Selection(Itree, i);
  Ftree.Delete_Tree_Node(Itree, del_node);
 END LOOP;
END;
Листинг 3.7. Получение выделенной вершины
Процедура FTREE.SET_TREE_NODE_PROPERTY

SET_TREE_NODE_PROPERTY (item_name [item_id] VARCHAR2 [FORMS4C.ITEM], node FTREE.NODE, property NUMBER, value NUMBER [VARCHAR2]) - устанавливает свойства элемента дерева.

Метод Параметр Тип Значение
PROCEDURE SET_TREE_NODE_PROPERTY (параметры) RETURN VARCHAR2 item_name VARCHAR2 [id_name] [FORMS4C.ITEM] Определяет имя элемента или его идентификатор
node FTREE.NODE Вершина дерева, для которой устанавливается свойство
property NUMBER Устанавли вает одно из перечисленных свойств равным value: NODE_STATE, NODE_LABEL, NODE_ICON, NODE_VALUE
value NUMBER [VARCHAR2] Значение, устанавливаемое для заданного свойства

Следующий пример описывает процесс поиска корневого узла и его развертывания.

DECLARE
 Itree item := find_item('tree_block.tree_item ');
 branch_node Ftree.NODE;
 i_value varchar2(30);
begin
 select_node := Ftree.Find_Tree_Node(Itree, i_value,
   Ftree.FIND_NEXT, Ftree.NODE_VALUE,
   Ftree.ROOT_NODE, Ftree.ROOT_NODE); 
 ftree.set_tree_node_property(Itree, select_node, 
   ftree.node_state, ftree.expanded_node); 
END;
Листинг 3.8. Установка значения свойства элемента дерева

С помощью процедуры SET_TREE_NODE_PROPERTY вы можете менять иконку узла в зависимости от какого-либо условия, как показано в листинге 3.8.

DECLARE
 Itree item := find_item('tree_block.tree_item ');
BEGIN
 IF Ftree.Get_Tree_Node_Property(Itree,
  :SYSTEM.TRIGGER_NODE, Ftree.NODE_STATE)=Ftree.COLLAPSED_NODE
 THEN Ftree.Set_Tree_Node_Property(Itree, :SYSTEM.TRIGGER_NODE, Ftree.NODE_ICON, 'Close'); 
 ELSIF 
  Ftree.Get_Tree_Node_Property(Itree, :SYSTEM.TRIGGER_NODE, 
        Ftree.NODE_STATE)= Ftree.EXPANDED_NODE
 THEN 
  Ftree.Set_Tree_Node_Property(Itree, :SYSTEM.TRIGGER_NODE, 
    Ftree.NODE_ICON, 'Open'); 
 END IF; 
END;
Листинг 3.9. Установка новой иконки для элемента дерева
< Лекция 2 || Лекция 3: 12 || Лекция 4 >
Константин Лукин
Константин Лукин

ошибка: FRM47337  Tree node label can not be null

при выполнении скрипта

DECLARE
 Itree ITEM;
 top_node Ftree.Node;
 new_node Ftree.Node;
 i_value VARCHAR2(30);
BEGIN
 Itree := Find_Item('tree_block.tree_item ');
 new_node := Ftree.Add_Tree_Node(Itree, Ftree.ROOT_NODE,
   Ftree.PARENT_OFFSET, Ftree.LAST_CHILD,
   Ftree.EXPANDED_NODE, i_value, NULL, i_value);
END;

Юлия Малыгина
Юлия Малыгина
приведена функция скрытия URL отчета и ее применение, но применения так и нет
Андрей Кошелев
Андрей Кошелев
Россия, Москва, Московская Финансово-Юридическая Академия
Артем Чуйко
Артем Чуйко
Россия, Самара