Перейти к содержанию

Работа с библиотекой ExtGWT: различия между версиями

Материал из Викиучебника — открытых книг для открытого мира
Содержимое удалено Содержимое добавлено
Нет описания правки
Строка 26: Строка 26:
{{Info|<b>Произношение слова "ExtGWT"</b>: Хотя это не официальное, но наиболее часто используемое среди англоязычных разработчиков: "и-экс-ти джи-дабл-ю-ти", что совпадает с произношением по отдельности слов ExtJS и GWT
{{Info|<b>Произношение слова "ExtGWT"</b>: Хотя это не официальное, но наиболее часто используемое среди англоязычных разработчиков: "и-экс-ти джи-дабл-ю-ти", что совпадает с произношением по отдельности слов ExtJS и GWT


<b>Лицензирование</b>: ExtGWT имеет двойную лицензию и доступна как вариант с открытым исходным кодом под GPLv3, так и под коммерческой, которую выбирают разработчики, кому по тем или иным причинам не подходит GPL}}
<b>Лицензирование</b>: ExtGWT имеет [http://www.extjs.com/products/license.php двойную лицензию] и доступна как вариант с открытым исходным кодом под GPLv3, так и под коммерческой, которую выбирают разработчики, кому по тем или иным причинам не подходит GPL}}


== Глава 2. Подготовка среды разработки ==
== Глава 2. Подготовка среды разработки ==

Версия от 14:35, 12 мая 2009

Глава 1. Обзор библиотек ExtGWT и GWT

Библиотеки ExtGWT и GWT представляют собой мощнейшее решение для разработки web-приложений, которые выглядят и обладают всеми функциями традиционных десктопных приложений. Разработчики, знающие язык программирования Java, могут использовать свой ранее накопленный опыт и существующие наработки для создания современного программного обеспечения. Стоит отметить, что ваше приложение не будет привязано к определенному контейнеру сервлетов, и вы можете создавать и запускать его даже дома на локальном компьютере. Мы также рассмотрим использование популярной среды разработки Eclipse, однако вы не будете ограничены каким-то одним программным продуктом и сможете работать с тем набором средств разработки, к которому уже привыкли.

В этой главе вы кратко познакомитесь с основными возможностями ExtGWT. Мы также поверхностно рассмотрим особенности библиотеки GWT, основные приемы ее использования и сборки приложений.

Немного об ExtGWT

Библиотека ExtGWT (также имевшая ранее название GXT) - это основанное на фреймворке Google Web Toolkit решение, предназначенное для построения высококлассных пользовательских интерфейсов web-приложений, разрабатываемое компанией ExtJS, которой принадлежит одноименная JavaScript библиотека.

Так как ExtGWT является надстройкой над мощной системой от Google, вместо изобретения очередного велосипеда она просто расширяет базовые возможности этой платформы, привнося в нее дополнительные компоненты, различные варианты их размещения, возможность работы с моделями данных и кэширующей их подсистемой. Библиотека начала свою жизнь под именем "MyGWT", а в дальнейшем ее главный разработчик присоединился к компании ExtJS и значительно расширил ее возможности, практически переписав некоторые ее части с нуля. На сегодняший момент существует уже вторая версия - ExtGWT 2.0, которая полностью покрывает потребности в компонентах типового RIA приложения.

Краткий перечень возможностей ExtGWT:

  • Компоненты для отображения и редактирования данных в их различных представлениях: Grid, List, DataView, Tree, Table
  • Панели, табы и методы автоматического расположения визуальных компонентов
  • Расширенные возможности по работе с окнами, диалогами, сообщениями и информационными панелями
  • Поддержка работы с формами ввода данных как с простым, так и с форматированным текстом, полей для ввода чисел, паролей, выпадающих списков, календарей, а также других элементов
  • Кнопки, всплывающие подсказки, панели инструментов, панели статуса и меню
  • Локальные кэширующие хранилища объектов данных, их автоматические загрузчики и модели данных, позволяющие легко взаимодействовать с компонентами библиотеки
  • Возможность создания интерактивных портальных и имитирующих десктоп web-приложений, написанных с использованием фреймворка MVC
  • Большой выбор графических эффектов, таких как изменяемые размеры и drag-n-drop для компонентов и их контейнеров
Информация

Произношение слова "ExtGWT": Хотя это не официальное, но наиболее часто используемое среди англоязычных разработчиков: "и-экс-ти джи-дабл-ю-ти", что совпадает с произношением по отдельности слов ExtJS и GWT

Лицензирование: ExtGWT имеет двойную лицензию и доступна как вариант с открытым исходным кодом под GPLv3, так и под коммерческой, которую выбирают разработчики, кому по тем или иным причинам не подходит GPL

Глава 2. Подготовка среды разработки

Глава 3. Виджеты и все, что с ними связано

Любая библиотека, которая помогает создавать «богатые web-приложения» (или по-английски Rich Internet Applications — RIA), прежде всего должна содержать широкий выбор интерфейсных элементов (или виджетов). Рассматриваемая нами библиотека ExtGWT содержит более 10 различных пакетов, содержащих более 210 классов, предназначенных для работы с виджетами. Каждый из таких элементов имеет кучу настраиваемых параметров и позволяет изменять свой внешний вид и дизайн, используя механизм тем оформления. Ниже мы рассмотрим приложение Explorer, которое содержит все доступные элементы библиотеки и служит хорошим подспорьем для изучения ее работы.

Пакет .widget

Базовый пакет com.extjs.gxt.ui.client.widget содержит наиболее часто используемые классы компонентов, контейнеров и виджетов общего назначения. Обычно именно с одного из виджетов, находящихся в этом пакете, вы начнете создавать новое приложение.

Component

Все виджеты библиотеки ExtGWT используют класс Component как родительский класс, либо наследуя его напрямую, либо наследуя его дочерний класс BoxComponent, в том случае, если элементу управления требуются функции изменения размера и позиционирования. Все дочерние классы, образованные от Component, автоматически управляются ядром библиотеки на протяжении всего цикла работы web-приложения (в том числе поддержка операций подсоединения и отсоединения виджета от DOM-модели браузера). Им также обеспечивается автоматическая поддержка скрытия и повторного отображения (hide/show) и отключения и включения (disable/enable) элементов управления. Класс Component позволяет своим дочерним классам использовать ленивое отображение в любом контейнере библиотеки ExtGWT. Это дает возможность таким контейнерам производить отображение видимых дочерних элементов (а следовательно выполнять дорогостоящие операции по работе с DOM-моделью в браузере пользователя и выделению памяти) только один раз при позиционировании самого контейнера.

Сам же класс Component является наследником класса Widget библиотеки GWT, что позволяет использовать все виджеты библиотеки ExtGWT в обычных GWT-приложениях. Все компоненты, подключаемые к панели GWT (класс Panel) будут отображены сразу же после операции добавления.

Container

Контейнеры — это виджеты, которые содержат другие компоненты. Они берут на себя всю заботу о жизненном цикле своих дочерних элементов, их создании, подключении и отключении от DOM-модели. Контейнеры также выполняют необходимые действия по правильному позиционированию и изменению размеров своих компонентов. К стандартным виджетам, которые являются контейнерами, можно отнести компоненты ButtonBar, HtmlContainer, Menu, Portal, Table, TabPanel, ToolBar и Tree.

LayoutContainer

Если вы уже имели опыт создания обычных приложений с графическим интерфейсом в средах Visual Studio, Delphi и тому подобных, то наверное помните их визуальные редакторы, позволяющие расположить несколько кнопочек, элементов ввода, редакторов текста в точно в заданных координатах оконного интерфейса. Разработчику было явно видно, что первая кнопка расположена в 8 пикселях от второй, а ширина всего диалогового окна жестко задана в 200 пикселей и не менялась пользователем, так как иначе могла «поехать» вся остальная разметка элементов.

Почему теперь такой подход считается неправильным? Да потому, что во-первых с тех пор кардинально изменилось число устройств, на которых могут работать приложения, а их технические характеристики выросли не только вверх, но и вниз. Одно и тоже приложение должно хорошо себя представлять как на 20" мониторе, установленном на рабочем столе, так и на маленьком экране нетбука с диагональю 7". Кроме того, обратите внимание на различную величину параметра DPI (число точек на дюйм) для различных устройств: число пикселей, которые помещаются в реальный физический размер экрана может отличаться в несколько раз, таким образом делая реальный отображаемый размер элементов или слишком маленьким, или наоборот слишком большим.


Мне сначала было сложно подобрать адекватный перевод технического термина layout, который используется как в документации Google Web Toolkit, так и библиотеки виджетов ExtGWT. Совершенно очевидно, что слово произошло фразы lay out, которая дословно переводится «выкладывать». Давайте в дальнейшем определимся, что наиболее подходящим русскоязычным аналогом мы будем считать термин раскладка.

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

Далее применительно к библиотеке ExtGWT мы рассмотрим компонент LayoutContainer, который является базовым контейнером, имеющим функции автоматической раскладки своих дочерних элементов. Его основной особенностью является возможность подключения различных вариантов раскладки элементов, позволяющую реализовать практически любой дизайн интерфейса приложения. По умолчанию в LayoutContainer используется тип раскладки FlowLayout, который подразумевает стандартное для HTML разметки расположение элементов (первый виджет прикрепляется к верхнему левому углу области, далее они выстраиваются сверху вниз). В связи с тем, что в ExtGWT реализовано много вариантов раскладки элементов, мы вернемся к их подробному рассмотрению в Главе 4, а на данном этапе просто сфокусируемся на основных функциях компонента LayoutContainer.

Далее предлагаю открыть редактор кода Eclipse и реализовать небольшой пример создания контейнера, добавления к нему нового виджета и подключения к основному объекту приложения RootPanel:

    // создание нового объекта LayoutContainer
    LayoutContainer container = new LayoutContainer();

    // создание и добавление в контейнер кнопки
    container.add(new Button("Нажми меня"));

    // жесткая установка ширины и высоты контейнера в 300 пикселей
    container.setSize(300,300);

    // задание отображения рамки
    container.setBorders(true);

    // подключение элемента-контейнера к DOM-модели приложения
    RootPanel.get().add(container);

    // "выкладка" контейнера - отображение всех дочерних элементов и выстраивание по заданному алгоритму
    container.layout();


По умолчанию компонент LayoutContainer не имеет никакого визуального изображения, поэтому бывает достаточно сложно определить его границы на экране. Для отладки вы можете попробовать использовать метод setBorders(true), который отобразит внешние границы контейнера. Помимо всего прочего, это даст возможность найти проблемы при отображении дочерних компонентов при той или иной раскладке.

Обратите внимание, что в нашем случае (когда компонент LayoutContainer помещается напрямую в DOM-модель, а не в другой существующий контейнер с заданным типом раскладки), необходимо явно задать ему размеры и вызвать метод layout(), который произведет операцию размещения и отображения его дочерних элементов. Это мы и сделали в последней строке примера.

HorizontalPanel и VerticalPanel

Компоненты HorizontalPanel и VerticalPanel реализуют свою функциональность путем использования стандартного в HTML разметке тега table. Эти контейнеры предназначены для упрощения раскладки элементов в совсем тривиальных случаях:

  • HorizontalPanel: размещает дочерние элементы в один единственный ряд слева направо, используя раскладку TableRowLayout
  • VerticalPanel: размещает дочерние элементы в одну единственную колонку сверху вниз, используя раскладку TableLayout

В следующем примере мы добавим два компонента Label (представляющего собой текстовый элемент) к горизонтальной панели, указав применительно ко второму дополнительные параметры, также называемые данные раскладки (layout data). Так как мы используем раскладку типа TableLayout, то дополнительные параметры должны содержаться в соответствующем ему объекте TableData. В нашем случае мы укажем необходимость выровнять текст во второй ячейке по правому краю.

    // создание объекта - горизонтальной панели
    HorizontalPanel hp = new HorizontalPanel();

    // установка ширины в пикселях
    hp.setWidth(300);

    // установка ширины встроенной таблицы
    hp.setTableWidth("100%");

    // добавление к панели компонента Label
    hp.add(new Label("Выровнено по центру"));

    // создание объекта TableData (содержащего дополнительные параметры раскладки)
    TableData td = new TableData();

    // задание выравнивания текста по правому краю
    td.setHorizontalAlign(HorizontalAlignment.RIGHT);

    // добавление к панели компонента Label с дополнительными параметрами по раскладке
    hp.add(new Label("Выровнено по правому краю"), td);

    // подключение элемента-контейнера к DOM-модели приложения
    RootPanel.get().add(hp);

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

ContentPanel

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

Класс ContentPanel является классом-наследником контейнера LayoutContainer, но вдобавок ко всем его методам и свойствам имеет дополнительные элементы оформления: отдельный заголовок, функции сворачивания/разворачивания содержимого, возможность отображения рамки и подключения специальных панелей соответственно вверху и внизу элемента. Также как и для LayoutContainer, компоненту ContentPanel должны быть явно заданы размеры, в том случае, если панель не помещается в другой контейнер с определенной раскладкой.

Давайте засучим рукава и напишем код, который создаст новую панель и выведет в область окна браузера:

    // Создание объекта - панели
    ContentPanel cp = new ContentPanel();

    // Установка заголовка
    cp.setHeading("Заголовок");
    
    // Явное задание размера панели
    cp.setSize(250, 140);
    
    // Смещение панели на 10 пикселей к низу и вправо относительно
    // родительского контейнера
    cp.setPosition(10, 10);

    // Активация функции сворачивания
    cp.setCollapsible(true);

    // Придание панели закругленных углов
    cp.setFrame(true);

    // Установка белого фона для тела панели
    cp.setBodyStyle("backgroundColor: white;");

    // Добавление к заголовку панели дополнительных кнопок
    cp.getHeader().addTool(new ToolButton("x-tool-gear"));
    cp.getHeader().addTool(new ToolButton("x-tool-close"));

    // Добавление произвольной HTML разметки в тело панели
    cp.addText("Текст <b>жирный</b>");

    // Кнопка OK в нижней области панели
    cp.addButton(new Button("OK"));

    // Установка иконки с папкой в верхнем левом углу панели
    cp.setIconStyle("tree-folder-open");

    // Подключение панели к корневому элементу
    RootPanel.get().add(cp);

В панель можно динамически добавлять компоненты после ее первоначальной отрисовки. Измененный пример:

    cp.addText("Текст <b>жирный</b>");

    // Кнопка OK в нижней области панели
    Button btn = new Button("OK");
    cp.addButton(btn);
    btn.addSelectionListener(new SelectionListener<ButtonEvent>() {

        @Override
        public void componentSelected(ButtonEvent be) {
            cp.add(new Text("Текст"));
            cp.layout();
        }
           
    });

В этом случае мы создали объект Button (кнопка), а затем воспользовались анонимным классом, реализующим интерфейс SelectionListener, в котором переопределили метод componentSelected, который вызывается при нажатии этой кнопки. Таким образом мы создали обработчик события типа ButtonEvent, выполняющий добавление нового компонента с надписью "Текст" и производящий перекомпоновку содержимого панели.

В классическом случае мы бы могли создать новый класс (называющийся например, BtnSelectionListener), а уже он него создать объект-обработчик события и привязать его к кнопке. Однако, так как в нашем случае логика обработки события тривиальна и нет необходимости привязывать обработчик в нескольким визуальным компонентам, использование анонимного класса сделало наш код компактным и более читаемым. Следует отметить, что среда разработки Eclipse всячески способствует быстрому написанию кода, в большинстве случаев "угадывая" нужные нам типы событий и подставляя целые шаблоны кода, что дает разработчику возможность сконцентрироваться на бизнес-логике приложения, не отвлекаясь на написание и отладку интерфейсного кода.

Для обновления содержимого панели после изменения нам необходимо обычно вызывать ее метод layout(). Библиотека ExtGWT будет делать это самостоятельно автоматически при установке метода панели setLayoutOnChange(true). Обратите внимание, что в нашем последнем примере компонент Text - это похожий на родной GWT-виджет Label (может содержать простой текст и не поддерживает HTML разметку).

Глава 5. Работа с данными

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

В этой главе описано, как библиотека ExtGWT оперирует данными, позволяя различным компонентам приложения получать к ним доступ. Используя объекты типа ModelData и BeanModel, а также локальную систему их хранения и загрузки, вы сможете получить максимум от потенциала таких мощных компонентов как Grid, Table, Tree и ListView.

Модели данных, хранилища и их загрузчики

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

Модели