Создание Ajax-проекта с использованием инструментария Google Web Toolkit, Apache Derby и Eclipse: Часть 1. Изящный пользовательский интерфейс

Используйте инструменты Google Web Toolkit для разработки Ajax-приложений на платформе Java

Инструментарий Google Web Toolkit (GWT) является серьезным шагом вперед в области создания динамических Java™Script-приложений, работающих в пользовательских Web-браузерах. Используя GWT, разработчики могут проектировать пользовательские интерфейсы (UI) и обработку событий, используя привычные технологии Java, пока GWT проделывает сложную работу адаптации кода для всех основных браузеров. В данной статье, первой из серии, вы сможете приобрести базовые навыки работы с GWT, включая создание приложения, поддерживающего технологию Asynchronous JavaScript + XML (Ajax), продолжая писать код на языке Java. Узнаете, как создать и запустить с помощью GWT небольшое приложение-пример - проект Web 2.0, называющийся Slicr, задача которого состоит в продаже пиццы через интернет.

Ноэл Рэппин, старший инженер-программист, Motorola, Inc.

Ноэл Рэппин (Noel Rappin) имеет степень доктор философии по графике, визуализации и используемости от Georgia Institute of Technology. Он работает старшим инженером-программистом в Motorola, Inc. Является соавтором книг "wxPython в действии" (Manning Publications, март 2006) и "Основные элементы Jython" (O'Reilly, март 2002).



30.01.2008

GWT делает создание функционально богатого Ajax-интерфейса едва ли не более легким, чем построение традиционного графического Java-интерфейса. Однако несмотря на его достоинства, GWT не сможет создать полноценное Web-приложение самостоятельно. Вам все еще необходимо иметь хранилище данных на сервере и определенную рабочую среду для конвертирования этих данных в объекты Java, чтобы GWT смог передать их клиенту с сервера. В данной серии статей мы будем использовать Apache Derby, основанную на Java базу данных, которую вы можете внедрить в виртуальную Java-машину (JVM), используемую серверным приложением.

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

Что такое Google Web Toolkit?

С помощью GWT вы можете разрабатывать Ajax-приложения на языке Java. Признаком Ajax-приложения является богатый интерактивный интерфейс, гораздо чаще ассоциируемый с традиционными приложениями. Рисунок 1 иллюстрирует пример GWT-интерфейса, схожего с десктопным почтовым приложением. Этот пример доступен на Web-сайте Google Web Toolkit.

Рисунок 1. Почтовый интерфейс с помощью GWT
Почтовый интерфейс с помощью GWT

Уникальной особенностью GWT является возможность создавать Ajax-приложения, работая с кодом на языке Java. Вы можете использовать свою привычную интегрированную среду разработки JAVA (IDE), и даже заниматься отладкой приложения в этой IDE. У вас есть возможность налаживать связь между клиентской и серверной частью с помощью объектов Java; более того, данный подход позволит уменьшить размер клиента по сравнению с Java-апплетом.

По своей сути, GWT является компилятором. Он конвертирует Java-код в код JavaScript, который будет вставлен в HTML-страницу и использован для запуска клиентской части проекта. Данный функционал освобождает вас от проблем с поддержкой JavaScript-кода в различных браузерах, позволяя вам сфокусироваться на интерфейсе и моделировании поведения программы.

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

  • Набор стандартных компонентов пользовательского интерфейса, которые имеют привлекательный внешний вид, возможность гибкой настройки, и адаптированы для работы во всех основных браузерах (включая Safari и Opera).
  • Полноценный механизм перехвата и обработки событий полностью на стороне клиента.
  • Рабочую среду для управления асинхронными вызовами между вашим Web-приложением и сервером.
  • Механизм создания полноценной истории работы с браузером, таким образом, ваш Ajax-проект не страдает от проблем с несоответствующим ожиданиям поведением кнопки Back.
  • Тестовое окружение, позволяющее использовать JUnit для создания модульных тестов, помогающих при отладке вашего приложения.

В этой серии статей будет рассмотрено большинство данных особенностей. Однако давайте начнем со скачивания и инсталляции GWT.

Приобретение GWT

На момент написания статьи, текущей версией GWT является 1.2. (Обратитесь к Ресурсам в конце статьи для получения ссылки на сайт с дистрибутивом.) GWT поддерживается операционными системами Microsoft® Windows® XP, Windows 2000, системами Linux®, использующими GTK+ версии 2.2.1 или более поздней, а также Mac OS X.

Распакуйте скачанный архив и расположите полученную папку в удобном вам месте. Некоторые компоненты дистрибутива незначительно изменяются в разных версиях, однако основными его элементами являются:

  • Три .jar файла. Один из них, gwt-user.jar, содержит пользовательские классы, которые вам понадобится подключить в настройках classpath вашего проекта. Файл gwt-dev-windows.jar или gwt-dev-linux.jar содержит основной код компилятора. Tретий файл, gwt-servlet.jar, используется при установке приложения.
  • Три консольных утилиты: applicationCreator, junitCreator и projectCreator. (В Windows данные файлы имеют суффикс .cmd). О них мы поговорим чуть позже.
  • Директория с примерами кода.

При использовании GWT, некоторые другие файлы располагаются в корневой директории GWT для управления временными файлами.

Создание проекта

После установки необходимого инструментария, нашей первоочередной задачей является создание проекта. Мы попробуем создать небольшой Web 2.0-проект, который будет назван Slicr, задачей которого будет продажа пиццы через интернет. Точные детали создания GWT-проекта зависят от используемой IDE. Для наших целей мы будем использовать Eclipse, в силу его свободного распространения и поддержки консольными утилитами GWT.

Начнем с использования данных утилит для создания проекта Eclipse:

  1. Создайте новую директорию с именем slicr в любом удобном вам месте на диске.
  2. Запустите консоль в этой директории.
  3. Напечатайте следующую команду (вам будет нужно конвертировать слэши и подчеркивания для соответствия выбранной операционной системе):

<GWT_HOME>/projectCreator -eclipse slicr

Эта команда создает необходимый для GWT-проекта минимум. В качестве результата мы получим поддиректорию src и два новых файла .project и .classpath.

Вы можете начать работу с текущей конфигурацией, однако GWT необходимы некоторые дополнительные параметры, которые можно настроить с помощью такой команды:


<GWT_HOME>/applicationCreator -eclipse slicr com.ibm.examples.client.Slicr

Аргумент -eclipse slicr является именем проекта Eclipse и должен соответствовать использованному в projectCreator. (Если это не так, у вас возникнут проблемы с запуском GWT-приложения из среды Eclipse.) Последний аргумент - полное имя главного класса вашего приложения. Мы назвали пакет нижнего уровня client, но, по сути, вы можете выбрать любое название.

Данная команда также создает несколько файлов. Файл .java является нашим основным классом. Также была создана директория public, на том же уровне, что и каталог client, содержащая файл Slicr.html. Директория уровнем выше содержит важный файл с названием Slicr.gwt.xml. GWT также создает файл Slicr.launch, используемый Eclipse как скрипт оболочки.


Импорт проекта в Eclipse

Теперь нам нужно импортировать созданный проект в Eclipse.

  1. Запустите Eclipse и выберите в меню File > Import.
  2. В появившемся окне, в разделе General, выберите Existing Projects into Workspace.
  3. Нажмите Next, затем нажмите Browse и выберите корневую директорию Slicr.
  4. Выбрав проект, убедитесь что опция Copy projects into workspace не включена; нам нет необходимости перемещать проект.

Данный процесс помещает ваш код в среду Eclipse. GWT создал три важных файла, первый из них расположен в пакете com.ibm.examples и называется slicr.gwt.xml. Это конфигурационный XML файл, и он должен выглядеть так, как описано в листинге 1.

Листинг 1. slicr.gwt.xml
<module>
    <inherits name='com.google.gwt.user.User'/>
    <entry-point class='com.ibm.examples.client.Slicr'/>
</module>

В данном XML-документе вы можете определить модули вашего GWT приложения. Модулем является базовая единица вашего GWT-кода, и она связана с HTML-страницами, используемыми вашим клиентом.

Вторым рассматриваемым файлом является Slicr.html, находящийся в директории public. Этот .html файл является главной страницей вашего Web-приложения. По умолчанию, он содержит множество комментариев, которые мы не будем рассматривать. Содержимое файла приведено в листинге 2.

Листинг 2. Slicr.html
<html>
    <head>
        <title>Wrapper HTML for Slicr</title>
        <meta name='gwt:module' 
            content='com.ibm.examples.Slicr'>
    </head>
    <body>
        <script language="javascript" 
            src="gwt.js"></script>
        <iframe id="__gwt_historyFrame" 
            style="width:0;height:0;border:0"></iframe>
        <h1>Slicr</h1>
        <p>
            This is an example of a host page for 
            the Slicr application. 
        </p>
        <table align=center>
            <tr>
                <td id="slot1"></td>
                <td id="slot2"></td>
            </tr>
        </table>
    </body>
</html>

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

  • Тэг meta: Атрибут name должен выглядеть, как описано выше, а атрибут content содержит полное логическое имя вашего модуля. (Оно состоит из имени пакета, содержащего XML-файл модуля, и имя XML-файла без расширений.) Данный тег ассоциирует вашу HTML-страницу с определенным модулем. Обращение к странице инициирует старт модуля. (А именно, инициализируются все точки входа в нем.)
  • Тэг script указывает на файл gwt.js, который является одним из файлов, создающихся при конвертировании Java-кода GWT в код JavaScript. В силу того, что он контролирует загрузку всего клиентского кода, наличие данного тега критично для запуска вашей программы.
  • Тэг iframe: Включение данного тега в точности, как написано, позволяет вашему Web-приложению запоминать историю работы и состояний. Это означает, что ваше GWT-приложение сможет работать с пользовательской кнопкой "Back".
  • Тэги td: В данном случае эти теги содержат идентификаторы JavaScript. Как вы узнаете позже, GWT использует эти идентификаторы как место для хранения необходимых данных.

Шаблонный Java-класс инициализации

GWT также создает шаблон Java-класса инициализации, показанный в листинге 3.

Листинг 3. Шаблонный Java-класс инициализации
public class Slicr implements EntryPoint {

  public void onModuleLoad() {
    final Button button = new Button("Click me");
    final Label label = new Label();
    button.addClickListener(new ClickListener() {
      public void onClick(Widget sender) {
        if (label.getText().equals(""))
          label.setText("Hello World!");
        else
          label.setText("");
      }
    });
    RootPanel.get("slot1").add(button);
    RootPanel.get("slot2").add(label);
  }
}

Рассмотрим пару особенностей данного класса подробнее. Он находится в пакете client, и это означает, что данный класс будет преобразован с помощью GWT в код JavaScript. Это накладывает некоторые ограничения на содержимое файла, однако, по своей сути, это обычный Java 1.4 код. Созданный класс наследует интерфейс EntryPoint, в котором определен метод onModuleLoad(). GWT автоматически вызывает данный метод при загрузке HTML страницы, ссылающейся на данный модуль.

Эта реализация EntryPoint достаточно проста, в ней определены объекты Button и Label в первых двух строках кода. В последних двух строках эти виджеты ассоциируются с определенными элементами HTML-страницы с помощью метода RootPanel.get(). Передаваемым в метод параметром является JavaScript ID элемента, определенный на HTML-странице.

Между этими действиями мы создаем обработчик событий, используя механизм, похожий на привязку к событию в Swing. В данном случае, ClickListener вызывается при нажатии кнопки и изменяет текст в виджете label.


Запуск вашей GWT программы

Теперь мы можем попробовать запустить созданную GWT программу-пример. Для этого есть два способа: Web-режим и режим хоста. Первый вариант подразумевает под собой полную развертку приложения в среде разработки, и будет использоваться после компиляции программы GWT в код Javascript.

Второй способ мы будем использовать в процессе разработки; это эмулятор, который позволяет выполнять одновременно код и сервера, и клиента, что значительно упрощает процесс запуска приложения во время разработки. (Режим хоста в данный момент не поддерживается Mac OS X.) Если вы используете IDE со встроенным дебаггером, вы можете запустить вашу GWT-программу данным способом с использованием дебаггера, что позволит вам устанавливать точки прерывания (breakpoints) и отслеживать значения переменных даже на стороне клиента, который будет преобразован в код JavaScript. Безусловно, это очень удобно и полезно. Во время работы вы будете часто использовать данный способ.

Вы можете запустить режим хоста любым из нескольких путей. applicationCreator, запущенный нами раньше, сгенерировал скрипт Slicr-shell, который вы можете вызвать для старта hosted mode. Вы уже видели в данной статье, как импортировать ваш GWT-проект в среду Eclipse. Из Eclipse вы можете выбрать опцию Debug или Run из закладки Run на панели инструментов. В появившемся окне, нажмите Java Application и вы увидите опцию Slicr. Она стала доступной благодаря файлу Slicr.launch, созданному GWT и импортированному в Eclipse вместе с проектом. Этот файл запуска описывает переменную classpath и стартовый класс для Eclipse. После первого запуска, эта опция станет доступна по умолчанию через нажатие соответствующей кнопки на панели управления. Рисунок 2 показывает, как выглядит это окно.

Рисунок 2. Вызов режима хоста
Вызов режима хоста

После запуска режима хоста, вы увидите два окна. (Учтите, что потребуется около минуты для инициализации данного режима, особенно при первом запуске.) Первое окно, показанное на рисунке 3, будет иметь заголовок Google Web Toolkit Development Shell / Port 8888. Оно содержит лог ошибок и сообщений от GWT. С помощью панели инструментов вы сможете открыть новое окно браузера режима хоста, а так же свернуть или развернуть окно и очистить консоль с логом.

Рисунок 3. Окно оболочки хост-режима
Окно оболочки хост-режима

Вторым окном, показанным на рисунке 4, является симулированный браузер. Как вы можете видеть, оно содержит статическую HTML страницу из файла slicr.html, вместе с виджетом-кнопкой, созданной в классе EntryPoint в Slicr.java. Нажатие на кнопку приведет к появлению текста в соответствующем месте. Если вы сделали что-то не так в процессе запуска, вы не увидите этого окна, вместо него в логе появится сообщение об ошибке. В таком случае, убедитесь, что все имена прописаны корректно. (В особенности, проверьте ваш .launch файл и убедитесь, что в нем указана корректная директория проекта.)

Рисунок 4. Окно имитации браузера хост-режима
Окно имитации браузера хост-режима

Создание простого клиента

В данной статье мы научимся размещать виджеты на экране и добавлять интерактивность в наш проект. В результате, у нас должно получиться простое, но функциональное приложение, показанное на рисунке 5.

Рисунок 5. Slicr
Slicr

Для того чтобы данные виджеты были созданы при загрузке страницы, мы должны поместить соответствующий код в метод onModuleLoad() нашего класса EntryPoint. Листинг 4 содержит определения экземпляров объектов данных и метод, вызывающий соответствующих помощников для создания каждой панели. Для работы данного кода необходимо иметь элемент на HTML-странице с ID slicr. Это позволит команде RootPanel.get() найти на ней нужный элемент. Наиболее просто это осуществляется заменой таблицы из предыдущего HTML листинга кодом >div id="slicr" /<.

Листинг 4. Обработчик события загрузки модуля
private DockPanel panel;
private List clearables;

public void onModuleLoad() {
    clearables = new ArrayList();
    initDockPanel();
    panel.add(buildActionPanel(), DockPanel.SOUTH);
    panel.add(buildPizzaTypePanel(), DockPanel.WEST);
    panel.add(buildToppingPanel(), DockPanel.EAST);
    RootPanel.get("slicr").add(panel);
}

Настройка виджетов

Объект DockPanel является в GWT эквивалентом панели Swing, использующей BorderLayout, однако в отличие от Swing, в котором используется несколько менеджеров прорисовки для одного класса Panel, в GWT имеется множество подклассов, каждый из которых имеет собственный алгоритм обрисовки дочерних виджетов. Среди других классов панелей есть SimplePanel, HTMLTable, FlowPanel, и StackPanel. Создать такую панель совсем не сложно: для этого используем set-методы, как показано в листинге 5.

Listing 5. Инициализация главной панели
private void initDockPanel() {
    panel = new DockPanel();
    panel.setBorderWidth(1);
    panel.setSpacing(5);
}

Создание нижней панели (кнопки)

Сначала мы создадим нижнюю (SOUTH) панель, чтобы она обслуживалась первой при распределении пространства в углу. Таким образом, данный виджет займет весь низ основной панели. Для этого нам понадобится HorizontalPanel, приблизительный аналог box в Swing. Работа с ним показана в листинге 6.

Listing 6. Нижняя (SOUTH) панель с кнопками
public HorizontalPanel buildActionPanel() {
    HorizontalPanel actions = new HorizontalPanel();
    actions.setSpacing(10);
    Button clear = new Button("Clear");
    clear.addClickListener(new ClearClickListener());
    Button newPizza = new Button("Another Pizza");
    Button submitOrder = new Button("Submit");
    actions.add(clear);
    actions.add(newPizza);
    actions.add(submitOrder);
    return actions;
}

Теперь мы используем содержащийся в GWT виджет Button для создания трех кнопок, которые добавим на панель. Заодно мы создадим ClickListener для кнопки Clear, который мы определим позднее. В GWT разделение перехватчиков событий реализовано не так, как в Swing: ClickListener работает с кликами мышью и только с ними. (Часто вы будете встречаться с перехватчиками, определенными как анонимный класс. Такой стиль достаточно неудобен для чтения кода и отладки, поэтому я создал именованный внутренний класс.)

Создание панели с типами пиццы (WEST)

Панель с типами пиццы достаточно проста, мы используем виджет RadioButton, как показано в листинге 7.

Листинг 7. Левая (WEST) панель с типами пиццы
public static final String[] PIZZA_TYPES = new String[] {
    "Thin Crust Medium", "Thin Crust Large", 
    "Thin Crust X-Large", "Thick Crust Medium", 
    "Thick Crust Large"
};

private VerticalPanel buildPizzaTypePanel() {
    VerticalPanel pizzaTypes = new VerticalPanel();
    HTML label = new HTML("<h2>Pizza</h2>");
    pizzaTypes.add(label);
    for (int i = 0; i < PIZZA_TYPES.length; i++) {
        RadioButton radio = new RadioButton("pizzaGroup", 
            PIZZA_TYPES[i]);
        clearables.add(radio);
        pizzaTypes.add(radio);
    }
    return pizzaTypes;
}

Позже вы сможете реализовать более изящный механизм работы с данными, а сейчас мы будем использовать VerticalPanel, которая является вертикальным аналогом HorizontalPanel. Мы также будем использовать виджет HTML, который является элементом, отображающим HTML. (По сути, это оболочка для HTML тэга <span>.) Конструктор RadioButton принимает два аргумента. Первым из них является строка для обозначения группы переключателей, а вторым - текстовая метка. Мы добавляем каждую кнопку на панель, а так же в соответствующий список, который будет использоваться в одном из перехватчиков.

Создание правой (EAST) панели

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

Листинг 8. Панель с наполнителями для пиццы
public static final String[] TOPPINGS = new String[] {
    "Anchovy", "Gardineria", "Garlic", 
    "Green Pepper", "Mushrooms", "Olives", 
    "Onions", "Pepperoni", "Pineapple", 
    "Sausage", "Spinach"
};

private VerticalPanel buildToppingPanel() {
    VerticalPanel toppings = new VerticalPanel();
    toppings.add(new HTML("<h2>Toppings</h2>"));
    Grid topGrid = new Grid(TOPPINGS.length + 1, 3);
    topGrid.setText(0, 0, "Topping");
    topGrid.setText(0, 1, "Left");
    topGrid.setText(0, 2, "Right");
    for (int i = 0; i < TOPPINGS.length; i++) {
        Button button = new Button(TOPPINGS[i]);
        CheckBox leftCheckBox = new CheckBox();
        CheckBox rightCheckBox = new CheckBox();
        clearables.add(leftCheckBox);
        clearables.add(rightCheckBox);
        button.addClickListener(new ToppingButtonListener(
                leftCheckBox, rightCheckBox));
        topGrid.setWidget(i + 1, 0, button);	
        topGrid.setWidget(i + 1, 1, leftCheckBox);
        topGrid.setWidget(i + 1, 2, rightCheckBox);
    }
    toppings.add(topGrid);
    return toppings;
}

Здесь мы снова используем VerticalPanel и виджет HTML. Мы размещаем все элементы в GWT-таблице Grid, таким образом, нам необходимо задать ее размер при создании. Каждая ячейка в ней может содержать текст либо другой GWT-виджет. Для каждого ряда, создадим кнопку и два чекбокса, и распределим их по соответствующим ячейкам. Добавим новый перехватчик для кнопки, и затем добавим чекбоксы в список clearable.

Перехватчики событий

После настройки виджетов, обратим внимание на два определенных нами перехватчика событий. Первый из них относится к кнопке Clear. При нажатии данной кнопки происходит просмотр списка clearable и сбрасываются значения всех его элементов, как показано в листинге 9.

Листинг 9. Обработчик нажатия на кнопку Clear
private class ClearClickListener implements ClickListener {
    public void onClick(Widget sender) {
    for (Iterator iter = clearables.iterator(); iter.hasNext();) {
            CheckBox cb = (CheckBox) iter.next();
            cb.setChecked(false);
        }
    }
}

Обратите внимание: В GWT, RadioButton является подклассом CheckBox. Таким образом, приведенный выше код не вызывает ошибки приведения классов.

Обработчик событий для кнопок, отвечающих за наполнители, чуть сложнее - если ни один из соответствующих чекбоксов не установлен, обработчик устанавливает их оба, в противном случае - сбрасывает, как показано в листинге 10.

Листинг 10. Обработчик событий для кнопок
private class ToppingButtonListener implements ClickListener {

    private CheckBox cb1;
    private CheckBox cb2;

    public ToppingButtonListener(CheckBox cb1, CheckBox cb2) {
        this.cb1 = cb1;
        this.cb2 = cb2;
    }

    public void onClick(Widget sender) {
        boolean unchecked = !cb1.isChecked() && !cb2.isChecked();
        cb1.setChecked(unchecked);
        cb2.setChecked(unchecked);
    }
}

В следующих статьях

Вы ознакомились с информацией, необходимой для создания простой версии клиентского приложения Slickr. В следующей статье мы научимся создавать слой данных на стороне сервера с использованием базы данных Derby и конвертировать эти данные в объекты Java для передачи GWT-клиенту. Далее, мы рассмотрим архитектуру удаленных процедур, связывающих клиентскую часть с серверной.

В силу того, что серверная часть приложения должна быть запущена отдельно, нам придется позаботиться о ее развертке, как для разработки, так и на рабочем окружении. Также, мы узнаем, как сделать интерфейс приложения более приятным и удобным для пользователя. Между тем, вам следует обратиться на сайт GWT для дополнительной информации.

Ресурсы

Научиться

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Open source, Information Management
ArticleID=284857
ArticleTitle=Создание Ajax-проекта с использованием инструментария Google Web Toolkit, Apache Derby и Eclipse: Часть 1. Изящный пользовательский интерфейс
publish-date=01302008