Афоризм
В моей душе нет больше места. Ищу, кого-бы удалить.
Последние статьи

 • Активности 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-приложений

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

В статье рассмотрен пример (example-tree) создания дерева Tree для иерархического представления набора записей в виде объектов с использованием модуля base-gui. В примере демонстрируются возможности API Tree по добавлению и удалению записей, использования «собственных» иконок, а также callback функция, вызываемая после выделения одной из записей дерева и открывающая окно с сообщением об объекте.

На следующем скриншоте представлен интерфейс примера.

1. Описание примера

Описание главного класса примера ExampleTree будет представлено следующим образом :

  1. Описание внутреннего класса Good;
  2. Поля с данными и метод создания объектов Good;
  3. Формирование интерфейса;
  4. Методы добавления/удаления записей;
  5. Главный класс ExampleTree.

Внутренний класс Good

Внутрений класс Good (товар) расширяет свойства базового класса TreeRecord и используется для загрузки данных в дерево. TreeRecord включает поля 'id', 'pid', 'name' и методы управления полями Get/Set. Класс Good включает дополнительные 2 поля (quantity, cost), определяющие количество и стоимость товара.

class Good extends TreeRecord 
{
    private Float quantity;
    private Float cost    ;

    public Float getQuantity(){
        return quantity;
    }

    public void setQuantity(Float quantity) {
        this.quantity = quantity;
    }

    public Float getСost() {
        return cost;
    }

    public void setСost(Float cost) {
        this.cost = cost;
    }
}

Поля с данными, метод формирования объекта Good

Описание полей класса (см. листинг ниже) включает объект дерева tree, массив данных goods, загружаемый в дерево после инсталляции, массив данных goods_add, загружаемый в дерево при нажатии на кнопку «Добавить запись». Индексный параметр added_idx определяет добавляемую в дерево запись. Путь к файлу с изображением IMG_PATH используется для загрузки в визуализатор дерева изображения, отличного от используемого по умолчанию.

Поля массивов goods и goods_add имеют следующее назначение (отсчет от 0) :

  • 0 – id, идентификатор записи;
  • 1 – pid, идентификатор родительской записи;
  • 2 – name, наименование записи;
  • 3 – quantity, количество;
  • 4 – cost, стоимость.

Идентификаторы id и pid базового класса TreeRecord позволяют определить иерархическую структуру записей.

Для преобразования записей массива типа Object[] в объект Good используется метод createGood.

private ITree tree = null;

private Object[][] goods = 
                   {{ 0, 0, "Список товаров", null, null},
                    { 1, 0, "Продукты"      , null, null},
                    {11, 1, "Хлеб дарницкий",  0.4f, 40f},
                    {12, 1, "Батон нарезной",  0.3f, 32f},
                    {13, 1, "Сметана"       ,  0.3f, 48f},
                    { 2, 0, "Промтовары"    , null, null},
                    { 3, 2, "Для дома"      , null, null},
                    {31, 3, "Лампочки"      ,  35f, 140f},
                    {31, 3, "Батарейки"     ,  45f, 90f},
                    { 4, 2, "Для дачи"      , null, null},
                    {41, 4, "Замок"         , 600f, 600f},
                    {42, 4, "Грабли"        , 290f, 290f}};
private int        added_idx = 0; 
private Object[][] goods_add = 
                   {{ 5, 2, "Инструмент"    , null, null},
                    {50, 5, "Шуруповерт"    , 7800f, 7800f},
                    {51, 5, "Перфоратор"    , 9000f, 9000f}};

private final String IMG_PATH = "images/document.png";
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
private Good createGood(final Object[] object)
{
    Good good = new Good();
    good.setId      ((int   ) object[0]);
    good.setPid     ((int   ) object[1]);
    good.setName    ((String) object[2]);
    good.setQuantity((Float ) object[3]);
    good.setCost    ((Float ) object[4]);
    return good;
}

Формирование интерфейса

Метод createGUI формирует интерфейс примера. В методе сначала создается компонент дерева, в конструктор которого передается реализация родительского класса (this) для callback-вызова.

private void createGUI()
{
    tree = new Tree(this);

    File file = new File(IMG_PATH);
    if (file.exists()) {
        ImageIcon image = new ImageIcon(IMG_PATH);
        tree.setLeafIcon(image);
    }

    JButton btnAdd = new JButton("Добавить запись");
    btnAdd.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            addRecord();
        }
    });

    JButton btnDel = new JButton("Удалить запись");
    btnDel.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            deleteRecord();
        }
    });
    // Панель кнопок управления
    JPanel pnlButtons = new JPanel();
    pnlButtons.add(btnAdd);
    pnlButtons.add(btnDel);

    Container container = getContentPane();
    container.add(tree.asWidget(), BorderLayout.CENTER);
    container.add(pnlButtons     , BorderLayout.SOUTH);
}

Если имеется файл (IMG_PATH), то вызывается метод дерева setLeafIcon, который загружает изображение в визуализатор дерева для его представления в «листьях» записей.

К кнопкам интерфейса подключаются обработчики событий, связанных с добавлением и удалением записей.

При размещении компонента дерева в интерфейсе используется метод asWidget.

Объект Tree включает метод (API)
• public JComponent asWidget() ,
который «оборачивает» дерево JTree в скроллинг JScrollPane. Для получения объекта дерева JTree необходимо использовать метод getTree().

Методы управления записями

В пример включены два методы добавления и удаления записей.

Листинг метода добавления записи

Метод добавления записи addRecord выполняет две проверки : индексный указатель added_idx не должен выходить за пределы своего массива и первую (нулевую) запись можно добавить только в определенную позицию.

Запись добавляется в дерево методом addNodeObject, который в качестве параметров получает объект и текстовое значение.

private void addRecord()
{
    if (added_idx > (goods_add.length - 1))
        return;
    Good good = (Good)tree.getSelectedNodeObject();
    if (added_idx == 0) {
        if (good.getId() != 2) {
            String title = "Ошибка"; 
            String msg = "Выделите запись 'Промтовары' и "
                       + "нажмите кнопку 'Добавить'";
            JOptionPane.showMessageDialog(ExampleTree.this,
                          msg, title,
                          JOptionPane.INFORMATION_MESSAGE);
        } else {
            good = createGood(goods_add[added_idx]);
            tree.addNodeObject(good, good.getName());
            added_idx++;
        }
    } else {
        good = createGood(goods_add[added_idx]);
        tree.addNodeObject(good, good.getName());
        added_idx++;					
    }
}

Листинг метода удаления записи

Метод удаления записи выполняет проверку наличия дочерних узлов. Запись удаляется, если метод getChildCount вернет значение 0, т.е. скажет об отсутствии «детей». Можно удалить запись из дерева вместе с дочерними; необходимо об этом помнить и синхронизировать удаляемые записи с хранилищем (базой данных).

private void deleteRecord()
{
    // Выделенная запись
    TreeNode node = tree.getSelectedNode();
    if ((node != null) && (node.getChildCount() == 0))
        tree.deleteNodeObject(node);
}

Главный класс ExampleTree

Листинг класса ExampleTree (см. код ниже), не включает поля и методы, описанные выше. Полный исходный код примера можно скачать в конце страницы.

В конструкторе класса создается интерфейс и в дерево загружается набор записей в виде объектов Good. Интерес представляет метод обратного вызова (callback) onClickNode, который вызывается компонентом tree при выделении какой либо записи. Чтобы данная функция «сработала» необходимо в классе (ExampleTree) реализовать интерфейс ITreeListener.

Функция обратного вызова onClickNode передает выделенный объект типа TreeRecord, который приводится к типу Good. А далее по сценарию : формирование текста и отображение сообщения в диалоговом окне JOptionPane окна JFrame.

public class ExampleTree extends JFrame 
                         implements ITreeListener
{
    public ExampleTree() {
        super("Tree example");
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        createGUI();
        List<TreeRecord> list;
        list = new ArrayList<TreeRecord>();
        for (int i = 0; i < goods.length; i++) {
            Good good = createGood(goods[i]);
            list.add(good);
        }
        tree.loadData(list);

        setSize(520, 360);
        setVisible(true);
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    @Override
    public void onClickNode(TreeRecord record)
    {
        // Выделенный объект
        Good good = (Good)record;
        String title = "Выделенная запись"; 
        String msg = "id=" + good.getId()
                   + ", pid=" + good.getPid()
                   + ", name=" + good.getName();
        JOptionPane.showMessageDialog(ExampleTree.this, 
            "Вы выбрали запись : \n" + msg,
            title, JOptionPane.INFORMATION_MESSAGE);
    }
    //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    public static void main(String[] args) {
        new ExampleTree();
    }
}

Старт примера

Архив примера включает командный файл run-example-tree.bat для старта example-tree.jar в Windows из командной строки. Запускаемый example-tree.jar (runable) может быть стартован не только из командной строки, но и обычным способом (двойным нажатием клавишей мыши), поскольку модуль lib/base-gui-1.0.0.jar включен в classpath манифеста META-INF/MANIFEST.MF.

Скачать пример

Архивный файл base-gui-example.zip включает данный пример (example-tree) и другие примеры использования модуля base-gui.

  Рейтинг@Mail.ru