— Нет, но я ведь могу ошибаться.
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. |
