Афоризм
Да, я сулил златые горы,
но вот о шубе речь не шла.
Последние статьи

 • Активности Android
Многоэкранные Android приложения
 • Fragment dynamic
Динамическая загрузка фрагментов в Android
 • Fragment lifecycle
Жизненный цикл Fragment'ов в Android
 • Fragment example
Пример Fragment'ов в Android
 • Data Binding
Описание и пример Data Binding
 • Пример MVVM
Пример использования MVVM в Android
 • Компонент TreeTable
Описание компонента TreeTable для Swing
 • Пример TreeTable
Пример использования TreeTable
 • Хранилища Android
Внутренние и внешние хранилища данных
 • Пример SQLite
Пример использования SQLite в Android
 • WebSocket
Описание и пример реализации WebSocket
 • Визуальные компоненты
Улучшен компонент выбора даты из календаря
 • Анимация jQuery
Описание и примеры анимации элементов DOM
 • APK-файл Android
Создание apk-файла для android устройств, .dex файлы
 • платформа JaBricks
Платформа OSGi-приложения JaBricks
Поддержка проекта

Если Вам сайт понравился и помог, то будем признательны за Ваш «посильный» вклад в его поддержку и развитие
 • Yandex.Деньги
  410013796724260

 • Webmoney
  R335386147728
  Z369087728698
в помощь разработчикам Swing-приложений

Описание компонента JTreeTable

Интерфейсный компонент JTreeTable позволяет отображать многоуровневую структуру записей в табличном виде. Иерархия данных представлена в первой колонке таблицы. API (Application Programmer Interface) компонента JTreeTable позволяет добавлять, обновлять и удалять записи. Кроме этого, компонент позволяет вызывать callback-функцию при выделении записи в таблице с передачей в функцию выделенного объекта/записи набора данных.

Заметка :
1. Пример использования компонента представлен здесь.
2. Данный компонент используется используется в различных интерфейсных OSGi-бандлах; пример Справочник единиц измерения.
3. В качестве прототипа компонента использован пример представления файловой инфраструктуры TreeTables: Part 2.

На скриншоте представлен проект создания библиотеки gui-widgets (IDE Eclipse) для Swing. Библиотека включает различные интерфейсные компоненты; пакет визуального компонента JTreeTable (org.jabricks.widgets.treetable) отображен в развернутом виде.

В таблице приведен список классов пакета org.jabricks.widgets.treetable. Важные выделенные классы, которые следуют использовать при разработке интерфейса приложения и реализации бизнес-логики, описаны ниже.

AbstractCellEditor class AbstractCellEditor implements CellEditor
AbstractTreeTableModel abstract class AbstractTreeTableModel implements TreeTableModel
ITreeTableListener interface ITreeTableListener содержит один метод :
public void callBack (final Object object);
JTreeTable class JTreeTable extends JTable
ObjectModel модель описания данных в таблице
ObjectNode базовый класс описания записи в интерфейсе компонента (в таблице)
ObjectRecord базовый класс описания записи в хранилище
TreeTableModel interface TreeTableModel extends TreeModel
TreeTableModelAdapter class TreeTableModelAdapter extends AbstractTableModel

Интерфейс ITreeTableListener

ITreeTableListener включает единственный метод callBack, который должен быть переопределен в родительском классе, реализующим этот интерфейс. Данный метод вызывается каждый раз при выделении какой-либо записи в таблице. Таким образом, родительский класс получает информацию о выделенном объекте, которую может соответствующим образом сразу же обработать.

public interface ITreeTableListener {
    public void callBack (final Object object);
}

Пример callBack-функции

При выделении записи в таблице компонент вызывает callBack-функцию объекта, класс которого реулизует интерфейс ITreeTableListener.

public void callBack(Object obj) {
    if (obj != null) {
        // Определение выделенной записи
        ObjectNode node = (ObjectNode) obj;
        System.out.println ("id = " + 
                            node.getRecord().getId());
    }
}

Класс ObjectRecord

Базовый класс ObjectRecord включает поля id, pid, childRecords (идентификатор записи, идентификатор родительской записи, список дочерних записей) и методы Get/Set (не представлены в листинге) для управления значениями полей. Поля id и pid позволяют сформировать иерархическую структуру записей. Поле childRecords хранит список дочерних записей.

ObjectRecord следует использовать в качестве базового класса для формирования иерархического списка данных внешнего хранилища (файл, БД).

package org.jabricks.widgets.treetable;

import java.util.ArrayList;
import java.util.List;

public class ObjectRecord
{
    private Integer id ;
    private Integer pid;

    private List<ObjectRecord> childRecords;

    public ObjectRecord() 
    {
        childRecords = new ArrayList<ObjectRecord>();
    }
}

Класс ObjectNode

Базовый класс ObjectRecord, предназначенный для отображения записи в интерфейсе компонента, включает запись record типа Object, "ссылку" на родительский узел parent типа ObjectNode, список дочерних записей children и методы Get/Set (не представлены в листинге) для управления их значениями. Класс ObjectNode имеет два конструктора : один конструктор получает в качестве параметра только объект записи record, второй — родительский узел parent и объект записи record.

Особое значение в данном классе представляют статические закрытые (private) поля fieldName и fieldLeaf, которые определяют наименования полей, используемых для отображения значений и иконок в первой колонке таблицы (дерева). Это, так называемые, значимые поля, которые определяет разработчик при использовании компонента JTreeTable. Статический метод setSignificantFields позволяет определить наименования значимых полей. Методы toString и isLeaf позволяют извлечь значения данных полей из объекта записи. Подробные комментарии к полям и методам приведены в листинге. Исходный код методов toString и isLeaf не представлен (только многоточие).


import java.lang.reflect.Field;

public class ObjectNode 
{
    // Object записи
    private Object record;

    // Родительская запись представления в компоненте
    private ObjectNode parent;

    // Дочерние записи представления в компоненте
    private ObjectNode[] children;
    
    /*
     * Наименование поля, которое используется для
     * отображения в первой колонке таблицы. 
     * Значение fieldName должно быть определено 
     * в наследниках класса.
     */
    private static String fieldName;
    /*
     * Наименование поля, используемое для 
     * представления иконки рядом с текстовым
     * значением в 1-ой колонке компонента.
     * Значение fieldLeaf должно быть определено в 
     * наследниках класса.
     */
    private static String fieldLeaf;
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    public ObjectNode(Object record)
    { 
        this(null, record);
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    public ObjectNode(ObjectNode parent, Object record)
    { 
        this.parent = parent;
        this.record = record;
        setChildren(new ObjectNode[0]);
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /**
     * Метод получения значения поля leaf - логическое 
     * значение представления иконки записи в компоненте
     * JTreeTable в виде листа или папки.
     */
    public boolean isLeaf() {...}
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /**
     * Метод получения значения поля для представления в 
     * 1-ой колонке таблицы (дерева).
     */
    public String toString() {...}
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    /**
     * Метод определения наименований значимых полей 
     * записей fieldLeaf и fieldName для отображения 
     * в 1-ой колонке таблицы/дерева.
     * @param fldName наименование текстового поля, для 
     *        отображения значения в 1-ой колонке таблицы
     * @param fldLeaf наименование текстового поля, 
     *        используемое для отображения иконки 
     *        в 1-ой колонке таблицы 
     */
    public static void setSignificantFields (String fldName, 
                                             String fldLeaf)
    {
        fieldName = fldName;  
        fieldLeaf = fldLeaf;
    }
}

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

Класс ObjectModel

Класс ObjectModel включает несколько полей, определяющих заголовки (column_titles) и наименования (column_names) колонок таблицы, а также типы значений по колонкам (column_types). Все эти поля имеют методы Get/Set. Конструкторы класса в качестве параметров получают значения полей. Кроме этого, один из конструкторов получает корневую запись иерархического набора данных root типа ObjectNode. Ниже представлен листинг класса в усеченном виде (не представлены методы Get/Set по полям).

Кроме значимых полей визуального компонента и методов Get/Set класс ObjectModel включает дополнительные методы, необходимые для реализации AbstractTreeTableModel. Эти методы представлены после листинга в таблице.

public class ObjectModel extends AbstractTreeTableModel
{
    // заголовки колонок
    private  String[]    column_titles = null;
    // наименования колонок    
    private  String[]    column_names  = null;
    // типы значений по колонкам    
    private  Class<?>[]  column_types  = null;
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    public ObjectModel()
    {
        super(null);
    }
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    public ObjectModel(String[] col_names,
                       String[] col_titles,
                       Class<?>[] col_types) 
    {
        super(null);
        this.column_titles = col_titles;
        this.column_names  = col_names;
        this.column_types  = col_types;
    }
    // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    public ObjectModel(ObjectNode root, 
                       String[] col_names, 
                       String[] col_titles,
                       Class<?>[] col_types) 
    {
        super(null);
        this.column_titles = col_titles;
        this.column_names  = col_names;
        this.column_types  = col_types;

        this.root = root;
	}
	// Get/Set
	. . .
	// Дополнительные методы
	. . .
}

Заметка :
1. Первая колонка массива column_types должна иметь тип значений TreeTableModel.class, либо использовать данный класс в качестве базового (extends).
2. Заголовки колонок можно менять динамически, т.е. в режиме run-time без перезагрузки формы/приложения.

В таблице представлены дополнительные методы класса ObjectModel и описание к ним. Особый комментарий здесь не требуется. Ниже под таблицей представлен пример использования ObjectModel.

МетодОписание
void
setRootNode(ObjectNode root)
/**
 * Метод загрузки в компонент корневой записи
 *
 * @param root корневая запись
 */
int getColumnCount() /**
 * Метод получения количества колонок в таблице
 */
String
  getColumnName(int col)
/**
 * Метод получения наименования колонки
 *
 * @param column порядковый номер колонки
 */
Class<?>
   getColumnClass(int col)
/**
 * Функция получения типа поля записи
 * @param col индекс в массиве типов значений таблицы
 *
 * @return Class тип поля записи
 */
boolean isLeaf(Object node) /**
 * Функция получения значения поля leaf.
 * Значение извлекается из объекта типа ObjectNode.
 *
 * @return логическое значение поля leaf
 */
Object getValueAt
    (Object node, int column)
/**
 * Функция получения значения поля записи
 *
 * @param node узел записи
 * @param column индекс в массиве наименований колонок таблицы : column_names[column]
 */
Object
  getChild(Object node, int i)
/**
 * Функция получения дочерней записи в компоненте.
 *
 * @param node узел записи в дереве.
 * @param i порядковый номер в массиве дочерних записей.
 * @return дочерняя запись; тип ObjectNode
 */
int getChildCount(Object node) /**
 * Функция получения количества дочерних записей узла node
 *
 * @param node узел записи в дереве
 * @return количество дочерних записей
 */
static void
   setSignificantFields
     (final String fieldName,
     final String fieldLeaf);
/**
 * Метод определения наименований значимых полей записей для отображения в компоненте JTreeTable.
 *
 * @param fldName наименование текстового поля, для отображения значения в 1-ой колонке таблицы
 * @param fldLeaf наименование текстового поля, используемое для отображения иконки
 * в 1-ой колонке таблицы
 */
static ObjectNode
   convertRecord2Node
    (ObjectRecord record)
/**
 * Метод преобразования объекта записи из хранилища типа ObjectRecord в интерфейсный объект записи
 * ObjectNode для отображения в компоненте JTreeTable.
 *
 * @param record - объект записи из хранилища
 * @return - объект записи для отображения в интерфейсе компонента
 */

Пример использования ObjectModel

В листинге представлен пример использования класса ObjectModel. Полное описание примера JTreeTable приведено здесь.

// Объект данных
TreeTableData data = new TreeTableData();

// Корневая запись
Record record = data.getRootRecord();

// Определение значимых полей
ObjectModel.setSignificantFields("name", "leaf");

// Интерфейсный корневой объект иерархической структуры данных
ObjectNode rootNode = ObjectModel.convertRecord2Node (record);

// Модель представления данных в таблице TreeTable  
modelData = new ObjectModel(column_names, titles_ru, column_types);
		
modelData.setRootNode(rootNode);
		
// Создание компонента
treeTable = new JTreeTable(modelData);
treeTable.drawTableHeaderRaised();
treeTable.setName("TreeTableName");

Класс JTreeTable

JTreeTable реализует визуальный компонент таблицы с использованием дерева JTree и включением его в первую колонку таблицы JTable. Таким образом, использование дерева в первой колонке таблицы позволяет отображать иерархическую структуру данных.

Класс JTreeTable расширяет базовый класс JTable. Конструктор класса принимает в качестве параметра модель данных TreeTableModel. Ниже представлен конструктор класса и цепочка наследований модели данных :

// Конструктор класса
public JTreeTable(TreeTableModel);

// Цепочка наследований
interface TreeTableModel extends TreeModel
class AbstractTreeTableModel implements TreeTableModel 
class ObjectModel extends AbstractTreeTableModel

Таким образом, конструктор класса в качестве параметра может получать модель описания данных типа ObjectModel, описанную выше.

В таблице представлены методы класса JTreeTable с комментариями.

МетодОписание
void setParentCallBack
    (ITreeTableListener parent)
/**
 * Метод определения родителя для вызова callback-функции
 * @param treeTableParent родитель
 */
static void setLookAndFeel
          (final int idx)
/**
 * Метод определения интерфейса компонента
 * @param idx индекс стиля интерфейса. Список возможных значений :
 *   "Metal", "Nimbus", "CDE/Motif", "Windows", "Windows Classic"
 */
void setAutoResizeColumn
          (final int mode)
/**
 * Метод определения автоматической подстройки ширины столбцов
 * @param mode :
 *  - JTable.AUTO_RESIZE_OFF | JTable.AUTO_RESIZE_ALL_COLUMNS
 */
void drawTableHeaderRaised /**
 * Метод представления 3d-заголовков таблицы
 */
void setColumnsWidth
        (final int[] width)
/**
 * Метод определения размеров колонок
 * @param width размеры колонок
 */
void setColumnTitles
       (String[] col_titles)
/**
 * Метод определения заголовков таблицы
 * @param col_titles заголовки колонок
 */
JTree getTree
/**
 * Метод получения компонента дерева
 */
void setRowHeight
      (final int rowHeight)
/**
 * Метод определения высоты строк таблицы
 * @param rowHeight высота строки
 */
void selectRow
      (final int row,
      final boolean expand)
/**
 * Метод открытия/скрытия записи в таблице
 * @param row строка в таблице (в первой колонке таблицы)
 * @param expand флаг открытия/скрытия (true/false)
 */
void selectRow
      (final int[] rows,
      final boolean expand)
/**
 * Метод открытия/скрытия записи в таблице
 * @param rows строка в таблице (в первой колонке таблицы)
 * @param expand флаг открытия/скрытия (true/false)
 */
void addNode
    (ObjectNode parent,     ObjectNode child,
    TreePath path,
    ObjectModel model,
    boolean select)
/**
 * Метод добавления новой записи
 * @param parent родительская запись
 * @param child новая дочерняя запись
 * @param path путь к родительской записи
 * @param model модель данных
 * @param select флаг выделения новой записи
 */
void updateNode
    (ObjectNode object,
    TreePath path,
    ObjectModel model,
    boolean select)
/**
 * Метод обновления записи
 * @param object текущая запись
 * @param path путь к родительской записи
 * @param model модель данных
 * @param select флаг выделения новой записи
 */
void deleteNode
    (ObjectNode object,
    TreePath path,
    ObjectModel model)
/**
 * Метод удаления записи
 * @param object текущая запись
 * @param path путь к родительской записи
 * @param model модель данных
 */

Пример использования JTreeTable

Использование компонента JTreeTable библиотеки gui-widgets для представления многоуровнего иерархического набора записей в таблице в обычном Swing-приложении рассмотрено здесь. В примере демонстрируются методы добавления, обновления и удаления записей, а также вызова callback-функции при выделении записи.

Компонент JTreeTable используется в различных интерфейсных OSGi-бандлах; пример Справочник единиц измерения.

  Рейтинг@Mail.ru