410013796724260
• Webmoney
R335386147728
Z369087728698
в помощь разработчикам Swing-приложений
Пример использования дерева TreeВ статье рассмотрен пример (example-tree) создания дерева Tree для иерархического представления набора записей в виде объектов с использованием модуля base-gui. В примере демонстрируются возможности API Tree по добавлению и удалению записей, использования «собственных» иконок, а также callback функция, вызываемая после выделения одной из записей дерева и открывающая окно с сообщением об объекте. На следующем скриншоте представлен интерфейс примера. 1. Описание примераОписание главного класса примера 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) :
Идентификаторы 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) Методы управления записямиВ пример включены два методы добавления и удаления записей. Листинг метода добавления записиМетод добавления записи 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. |