| // |
| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you under the Apache License, Version 2.0 (the |
| // "License"); you may not use this file except in compliance |
| // with the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| // |
| |
| = Передача двоичных данных с помощью приложения веб-службы, часть 5: создание клиента Swing |
| :jbake-type: tutorial |
| :jbake-tags: tutorials |
| :jbake-status: published |
| :icons: font |
| :syntax: true |
| :source-highlighter: pygments |
| :toc: left |
| :toc-title: |
| :description: Передача двоичных данных с помощью приложения веб-службы, часть 5: создание клиента Swing - Apache NetBeans |
| :keywords: Apache NetBeans, Tutorials, Передача двоичных данных с помощью приложения веб-службы, часть 5: создание клиента Swing |
| |
| Целью этого упражнения является создание клиента для веб-службы, которая была создана и развернута ранее, с последующим добавлением графического интерфейса пользователя в этот клиент. Интерфейс служит для вывода на экран изображений, переданных веб-службой в качестве двоичных данных. |
| |
| Полную версию клиента можно загрузить из link:https://netbeans.org/projects/samples/downloads/download/Samples%252FWeb%2520Services%252FWeb%2520Service%2520Passing%2520Binary%2520Data%2520--%2520EE6%252FFlowerClient.zip[+каталога примеров NetBeans+]. |
| |
| *Уроки, представленные в этом учебном курсе* |
| |
| image::images/netbeans-stamp-74-73-72.png[title="Содержимое этой страницы применимо к IDE NetBeans 7.2, 7.3 и 7.4"] |
| |
| 1. link:./flower_overview.html[+Обзор+] |
| 2. link:./flower_ws.html[+Создание веб-службы+] |
| 3. link:./flower-code-ws.html[+Написание кода веб-службы и ее тестирование+] |
| 4. link:./flower_wsdl_schema.html[+Изменение схемы и файлов WSDL для передачи двоичных данных+] |
| 5. => Создание клиента Swing |
| |
| |
| 1. <<create-client-app,Создание приложения клиента>> |
| |
| 2. <<design-jframe,Проектирование JFrame>> |
| 3. |
| <<bind-jframe,Привязка компонентов JFrame>> |
| |
| 4. <<code-main-class,Написание кода главного класса>> |
| |
| |
| == Создание клиента приложения |
| |
| В этом разделе рассматривается создание веб-приложения. В рамках приложения выполняется создание клиента, потребляющего веб-службу, которая была создана и изменена в предыдущих учебных курсах. |
| |
| *Создание приложения* |
| |
| 1. Выберите 'Файл' > 'Создать проект' (Ctrl-Shift-N в Windows и Linux, ⌘-Shift-N в ОС Mac). Откроется мастер создания проекта. |
| 2. Выберите "Приложение Java" в категории "Java". Нажмите кнопку "Далее". Появится мастер создания приложения Java. Введите текст ``FlowerClient`` в поле "Имя проекта". Выберите папку проекта и нажмите кнопку "Готово". В среде IDE будет создан новый проект приложения на Java. |
| 3. Щелкните правой кнопкой мыши узел проекта ``FlowerClient`` и последовательно выберите в контекстном меню команды "Создать" > "Клиент веб-службы". Появится мастер создания клиента веб-службы. |
| 4. Выберите переключатель "URL-адрес WSDL" и вставьте в соответствующее поле URL-адрес файла WSDL. По умолчанию URL-адресом является ``http://localhost:8080/FlowerAlbumService/FlowerServiceService?wsdl`` . URL-адрес можно найти в браузере, выполнив тестирование веб-службы и заменив текст ``?Tester`` на ``?wsdl`` в конце URL-адреса. Примите все прочие значения по умолчанию, включая пустое имя пакета. |
| image::images/ws-client-wiz.png[] |
| 5. Нажмите кнопку "Завершить". В среде IDE выполняется загрузка файла WSDL, добавление заглушек клиента для взаимодействия с веб-службой, а также добавление узлов в проект приложения на Java в окне "Проекты". |
| image::images/client-generated-sources.png[title="Представление проекта, в котором отображается новый клиент веб-службы"] |
| |
| |
| [[design-jframe]] |
| == Разработка формы JFrame |
| |
| В этом разделе рассматривается добавление формы ``JFrame`` в веб-приложение и проектирование в рамках этого приложения графического интерфейса пользователя с использованием компонентов Swing. В заключение описывается привязка компонентов Swing к коду клиента веб-службы. |
| |
| При отсутствии необходимости самостоятельного проектирования формы JFrame можно загрузить готовый файл JFrame Java link:https://netbeans.org/projects/www/downloads/download/webservices%252FFlowerFrame.java[+здесь+]. |
| |
| 1. Щелкните правой кнопкой мыши узел ``FlowerClient`` и выберите пункт "Создать", а затем – "Форма JFrame". Присвойте фрейму имя ``FlowerFrame`` . Разместите его в пакете ``flowerclient`` . |
| 2. Фрейм ``FlowerFrame`` будет открыт в редакторе. Откройте палитру (если она еще не открыта). Растяните нижнюю границу фрейма приблизительно на одну треть. |
| image::images/opened-flowerform.png[] |
| 3. Перетащите панель JPanel из раздела "Контейнеры Swing" на палитре в фрейм ``FlowerFrame`` . Разверните панель, чтобы она заполнила все пространство фрейма ``FlowerFrame`` . |
| image::images/add-panel.png[] |
| 4. Щелкните правой кнопкой мыши панель в представлении "Проектирование". Выберите в контекстном меню пункт "Изменить имя переменной...". Присвойте панели имя ``gardenFlowersPanel`` . |
| 5. Перетащите метку JLabel из палитры в верхнюю область панели `` gardenFlowersPanel`` . Щелкните метку правой кнопкой мыши и измените имя переменной метки на ``titleLabel`` . Снова щелкните правой кнопкой мыши метку ``titleLabel`` и выберите пункт "Изменить текст". Измените текст на "Garden Flowers". Можно также изучить свойства ``titleLabel`` и увеличить шрифт. |
| 6. Перетащите группу кнопок в представление "Проектирование". Примите имя группы кнопок ``buttonGroup1`` , заданное по умолчанию. |
| 7. Перетащите четыре переключателя в горизонтальный ряд под меткой ``titleLabel`` . В свойствах каждого переключателя укажите, что он является компонентом группы кнопок ``buttonGroup1`` . Для других свойств переключателей действительны следующие свойства: |
| |=== |
| Переключатели в группе кнопок buttonGroup1 |
| |
| |Имя переменной |Выбрано |Текст |
| |
| |asterRadioButton |true |Aster |
| |
| |honeysuckleRadioButton |false |Honeysuckle |
| |
| |roseRadioButton |false |Rose |
| |
| |sunflowerRadioButton |false |Sunflower |
| |=== |
| 8. Перетащите панель с прокруткой в область под переключателями. Разверните панель, чтобы она заполнила всю область по горизонтали и приблизительно две трети свободной области по вертикали. Измените имя переменной панели с прокруткой на ``mainScrollPane`` . |
| 9. Перетащите панели на панель ``mainScrollPane`` . Измените имя переменной панели на ``mainPanel`` . |
| 10. В представление 'Конструирование' щелкните правой кнопкой мыши ``mainPanel`` и выберите 'Настроить макет' > 'Макет границ'. |
| 11. Перетащите кнопку на панель ``mainPanel`` . Поскольку панель ``mainPanel`` имеет границы, кнопка автоматически заполняет все пространство панели. Измените имя переменной кнопки на ``mainPictureButton`` , и введите для кнопки текст "Waiting for picture..." |
| 12. Перетащите еще одну панель с прокруткой в область под панелью ``mainScrollPane`` . Разверните новую панель с прокруткой, чтобы она заполнила все свободное пространство. Измените имя переменной новой панели с прокруткой на ``thumbnailScrollPane`` . |
| 13. Перетащите панель из палитры на панель ``thumbnailScrollPane`` . Измените имя переменной панели на ``thumbnailPanel`` . Установите в качестве формата панели ``thumbnailPanel`` формат сетки. |
| 14. Перетащите четыре кнопки на панель ``thumbnailPanel`` . Поскольку панель ``thumbnailPanel`` имеет формат сетки, кнопки автоматически становятся одинакового размера и полностью заполняют панель. Свойства кнопок Кнопки на панели thumbnailPanel |
| |=== |
| |
| |Имя переменной |Текст |
| |
| |asterButton |Ожидание... |
| |
| |honeysuckleButton |Ожидание... |
| |
| |roseButton |Ожидание |
| |
| |sunflowerButton |Ожидание |
| |=== |
| |
| Форма JFrame готова. На данный момент файл ``FlowerFrame`` выглядит следующим образом. |
| image::images/designed-form.png[title="Завершенный фрейм Flower, в которой отображается текст кнопок вместо изображений"] |
| |
| |
| == Привязка компонентов JFrame |
| |
| В этом разделе рассматривается инициализация компонентов в конструкторе и привязка компонентов к прослушивателям. Прослушиватели используются для вызова кода, который отвечает за отображение цветов. |
| |
| |
| === [[Инициализация компонентов]] |
| |
| [[В этом разделе описывается заполнение конструктора ``FlowerFrame`` |
| |
| ]] |
| |
| 1. Перейдите в представление "Исходный код" в редакторе. Найдите начало тела класса ``FlowerFrame`` и конструктор ``FlowerFrame`` . |
| image::images/ff-empty-constructor.png[] |
| 1. В верхней части тела класса фрейма ``FlowerFrame`` создайте над строкой конструктора массив строк с названиями всех цветов. |
| |
| [source,java] |
| ---- |
| |
| protected static final String[] FLOWERS = {"aster", "honeysuckle", "rose", "sunflower"}; |
| ---- |
| 1. Добавьте между массивом строк FLOWERS и конструктором строку, инициализирующую элемент ``link:http://download.oracle.com/javase/6/docs/api/java/util/Map.html[+java.util.Map+]`` с именем ``flowers`` . Карта ссылок принимает объект ``String`` и устанавливает его соответствие с объектом ``Image`` . |
| |
| [source,java] |
| ---- |
| |
| private Map<String, Image> flowers; |
| ---- |
| 1. Добавьте операторы импорта для ``java.util.Map`` и ``java.awt.Image`` . |
| 2. Добавьте код в конструктор ``FlowerFrame`` , чтобы связать определенный объект ``Image`` с определенным объектом ``String`` для определенного экземпляра карты ссылок ``flowers`` . |
| |
| [source,java] |
| ---- |
| |
| public FlowerFrame(Map<String, Image> flowers) { |
| |
| this.flowers = flowers; |
| for (String flower:FLOWERS) { |
| flowers.put(flower,null); |
| } |
| |
| initComponents(); |
| } |
| ---- |
| 3. Инициализируйте прослушиватели ``ItemListener`` для переключателей, а также прослушиватели ``ActionListener`` для четырех кнопок цветов и установите заголовок по умолчанию. |
| |
| [source,java] |
| ---- |
| |
| public FlowerFrame(Map<String, Image> flowers) { |
| |
| this.flowers = flowers; |
| for (String flower:FLOWERS) { |
| flowers.put(flower,null); |
| } |
| |
| initComponents(); |
| |
| setTitle("Garden Flowers [waiting for picture]"); |
| |
| ItemListener rbListener = new RBListener(); |
| asterRadioButton.addItemListener(rbListener); |
| honeysuckleRadioButton.addItemListener(rbListener); |
| roseRadioButton.addItemListener(rbListener); |
| sunflowerRadioButton.addItemListener(rbListener); |
| |
| ActionListener bListener = new ButtonListener(); |
| asterButton.addActionListener(bListener); |
| honeysuckleButton.addActionListener(bListener); |
| roseButton.addActionListener(bListener); |
| sunflowerButton.addActionListener(bListener); |
| } |
| ---- |
| 4. Добавьте операторы импорта для ``link:http://download.oracle.com/javase/6/docs/api/java/awt/event/ItemListener.html[+java.awt.event.ItemListener+]`` и ``link:http://download.oracle.com/javase/6/docs/api/java/awt/event/ActionListener.html[+java.awt.event.ActionListener+]`` . |
| |
| Конструктор готов. В коде выводятся сообщения об ошибках, поскольку код не содержит классы ``RBListener`` и ``ButtonListener`` . Эти два класса представляют собой реализации прослушивателей ``ItemListener`` и ``ActionListener`` , соответственно. Запись этих классов в код рассматривается в следующем разделе. |
| |
| |
| === [[Изображения с цветами]] |
| |
| [[В этом разделе рассматривается написание пользовательских прослушивателей для переключателей и кнопок цветов. Также рассматривается написание метода, который определяет цветок, выбираемый при нажатии кнопки, и получает объект ``Image`` цветка на карте ссылок ``flowers`` . В завершение описывается создание метода, который вызывается посредством класса ``Main`` и получает объект ``Image`` для каждого эскиза. |
| |
| ]] |
| |
| 1. Найдите метод ``public static void main(String args[])`` в теле класса ``FlowerFrame`` . Удалите этот метод и его документацию. (Вместо него в приложении будет использован класс ``Main`` .) |
| 1. Напишите вместо метода ``main`` пользовательский прослушиватель ``ItemListener`` для переключателей. Этот прослушиватель служит для отображения нового изображения цветка при выборе переключателя. |
| |
| [source,java] |
| ---- |
| |
| private class RBListener implements ItemListener { |
| public void itemStateChanged(ItemEvent e) { |
| showFlower(); |
| } |
| } |
| ---- |
| 1. Добавьте оператор импорта для ``link:http://download.oracle.com/javase/6/docs/api/java/awt/event/ItemEvent.html[+java.awt.event.ItemEvent+]`` . |
| 1. Запишите под пользовательским прослушивателем ``ItemListener`` пользовательский прослушиватель ``ActionListener`` для четырех кнопок цветов. При нажатии кнопки прослушиватель выбирает соответствующий переключатель: |
| |
| [source,java] |
| ---- |
| |
| private class ButtonListener implements ActionListener { |
| |
| public void actionPerformed(ActionEvent e) { |
| if (e.getSource() == asterButton) asterRadioButton.setSelected(true); |
| else if (e.getSource() == honeysuckleButton) honeysuckleRadioButton.setSelected(true); |
| else if (e.getSource() == roseButton) roseRadioButton.setSelected(true); |
| else if (e.getSource() == sunflowerButton) sunflowerRadioButton.setSelected(true); |
| } |
| } |
| ---- |
| 2. Добавьте оператор импорта для ``link:http://download.oracle.com/javase/6/docs/api/java/awt/event/ActionEvent.html[+java.awt.event.ActionEvent+]`` . |
| 3. Напишите под пользовательским прослушивателем ``ActionListener`` метод ``showFlower`` . Этот метод определяет выбранный переключатель и получает объект ``Image`` для соответствующего цветка из карты ссылок ``flowers`` . |
| |
| [source,java] |
| ---- |
| |
| void showFlower() { |
| Image img = null; |
| if (asterRadioButton.isSelected()) { |
| img = flowers.get("aster"); |
| if (img != null) { |
| mainPictureButton.setIcon(new ImageIcon(img)); |
| setTitle("Garden Flowers [Aster]"); |
| } |
| } else if (honeysuckleRadioButton.isSelected()) { |
| img = flowers.get("honeysuckle"); |
| if (img != null) { |
| mainPictureButton.setIcon(new ImageIcon(img)); |
| setTitle("Garden Flowers [Honeysuckle]"); |
| } |
| |
| } else if (roseRadioButton.isSelected()) { |
| img = flowers.get("rose"); |
| if (img != null) { |
| mainPictureButton.setIcon(new ImageIcon(img)); |
| setTitle("Garden Flowers [Rose]"); |
| } |
| } else if (sunflowerRadioButton.isSelected()) { |
| img = flowers.get("sunflower"); |
| if (img != null) { |
| mainPictureButton.setIcon(new ImageIcon(img)); |
| setTitle("Garden Flowers [Sunflower]"); |
| } |
| } |
| if (img == null) { |
| mainPictureButton.setIcon(null); |
| setTitle("Garden Flowers [waiting for picture]"); |
| } else mainPictureButton.setText(""); |
| } |
| ---- |
| 4. Добавьте оператор импорта для ``link:http://download.oracle.com/javase/6/docs/api/javax/swing/ImageIcon.html[+javax.swing.ImageIcon+]`` . |
| 5. Напишите метод ``setThumbnails`` . Этот метод получает изображение для каждого эскиза из карты ссылок ``flowers`` . Метод вызывается посредством класса ``Main`` . |
| |
| [source,java] |
| ---- |
| |
| void setThumbnails(Map<String, Image> thumbs) { |
| Image img = thumbs.get("aster"); |
| if (img != null) { |
| asterButton.setIcon(new ImageIcon(img)); |
| asterButton.setText(""); |
| } |
| img = thumbs.get("honeysuckle"); |
| if (img != null) { |
| honeysuckleButton.setIcon(new ImageIcon(img)); |
| honeysuckleButton.setText(""); |
| } |
| img = thumbs.get("rose"); |
| if (img != null) { |
| roseButton.setIcon(new ImageIcon(img)); |
| roseButton.setText(""); |
| } |
| img = thumbs.get("sunflower"); |
| if (img != null) { |
| sunflowerButton.setIcon(new ImageIcon(img)); |
| sunflowerButton.setText(""); |
| } |
| } |
| ---- |
| 6. Исправьте операторы импорта ``FlowerFrame`` , если они не были исправлены ранее при вставке в код. Можно исправить все ошибки одновременно, щелкнув правой кнопкой мыши в редакторе и выберите 'Исправить выражения импорта' в контекстном меню. Ниже представлен полный список операторов импорта: |
| |
| [source,java] |
| ---- |
| |
| import java.awt.Image;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.ItemEvent;import java.awt.event.ItemListener;import java.util.Map;import javax.swing.ImageIcon; |
| ---- |
| |
| Конструктор ``FlowerFrame`` готов. |
| |
| |
| == [[Создание кода класса Main]] |
| |
| [[В этом разделе описывается завершение кода класса ``Main`` для отображения ``FlowerFrame`` , подключения к веб-службе и вызова операций веб-службы. |
| |
| 1. Откройте класс ``Main.java`` в редакторе. |
| image::images/main-empty.png[] |
| 2. В теле класса инициализируйте переменную ``int`` перед методом ``main`` для числа загруженных изображений. |
| |
| [source,java] |
| ---- |
| |
| private static int downloadedPictures; |
| ---- |
| 3. Создайте в теле метода ``main`` хранилище ``HashMap`` для четырех изображений цветов и второе хранилище ``HashMap`` для четырех эскизов. |
| |
| [source,java] |
| ---- |
| |
| final Map<String,Image> flowers = new HashMap<String,Image>(4); |
| final Map<String,Image> thumbs = new HashMap<String,Image>(4); |
| ---- |
| 4. Добавьте операторы импорта ``java.awt.Image`` , ``java.util.Map`` и ``java.util.HashMap`` . |
| 5. Добавьте в тело метода ``main`` код для отображения ``FlowerFrame`` .*// Show the FlowerFrame.* |
| |
| [source,java] |
| ---- |
| |
| final FlowerFrame frame = new FlowerFrame(flowers); |
| frame.setVisible(true); |
| ---- |
| 6. Добавьте в тело метода ``main`` код для подключения клиента к веб-службе.*// The client connects to the service with this code.* |
| |
| [source,java] |
| ---- |
| |
| FlowerServiceService service = new FlowerServiceService(); |
| final FlowerService port = service.getFlowerServicePort(); |
| ---- |
| 7. Добавьте операторы импорта для ``org.flower.service.FlowerService`` и ``org.flower.service.FlowerServiceService`` . |
| 8. Добавьте в тело метода ``main`` код для создания массива четырех потоков ``Runnable`` и вызова операции ``getFlower`` веб-службы в каждом потоке.*// The web service getFlower operation |
| // is called 4 times, each in a separate thread. |
| // When the operation finishes the picture is shown in |
| // a specific button.* |
| |
| [source,java] |
| ---- |
| |
| Runnable[] tasks = new Runnable[4]; |
| |
| for (int i=0; i<4;i++) { |
| final int index = i; |
| tasks[i] = new Runnable() { |
| public void run() { |
| try { |
| |
| *// Call the getFlower operation |
| // on the web service:* |
| Image img = port.getFlower(FlowerFrame.FLOWERS[index]); |
| System.out.println("picture downloaded: "+FlowerFrame.FLOWERS[index]); |
| |
| *// Add strings to the hashmap:* |
| flowers.put(FlowerFrame.FLOWERS[index],img); |
| |
| *// Call the showFlower operation |
| // on the FlowerFrame:* |
| frame.showFlower(); |
| |
| } catch (IOException_Exception ex) { |
| ex.printStackTrace(); |
| } |
| downloadedPictures++; |
| } |
| }; |
| new Thread(tasks[i]).start(); |
| } |
| ---- |
| 9. Добавьте оператор импорта для ``org.flower.service.IOException_Exception`` . |
| 10. Добавьте в тело метода ``main`` код для вызова операции ``getThumbnails`` веб-службы в отдельном потоке.*// The web service getThumbnails operation is called |
| // in a separate thread, just after the previous four threads finish. |
| // When the images are downloaded, the thumbnails are shown at |
| // the bottom of the frame.* |
| |
| [source,java] |
| ---- |
| |
| Runnable thumbsTask = new Runnable() { |
| public void run() { |
| try { |
| while (downloadedPictures < 4) { |
| try {Thread.sleep(100);} catch (InterruptedException ex) {} |
| } |
| |
| *// Call the getThumbnails operation |
| // on the web service:* |
| List<Image> images = port.getThumbnails(); |
| System.out.println("thumbs downloaded"); |
| |
| if (images != null && images.size() == 4) { |
| for (int i=0;i<4;i++) { |
| thumbs.put(FlowerFrame.FLOWERS[i],images.get(i)); |
| } |
| frame.setThumbnails(thumbs); |
| } |
| } catch (IOException_Exception ex) { |
| ex.printStackTrace(); |
| } |
| } |
| }; |
| new Thread(thumbsTask).start(); |
| |
| ---- |
| 11. Исправьте операторы импорта в ``Main.java`` , если они не были исправлены при вставке в код. Можно исправить все ошибки одновременно, щелкнув правой кнопкой мыши в редакторе и выберите 'Исправить выражения импорта' в контекстном меню. Будет предоставлен список классов List для импорта; выберите ``java.util.List`` . Ниже представлен полный список операторов импорта: |
| |
| [source,java] |
| ---- |
| |
| import flower.album.FlowerService;import flower.album.FlowerService_Service;import flower.album.IOException_Exception;import java.awt.Image;import java.util.HashMap;import java.util.List;import java.util.Map; |
| ---- |
| |
| Класс ``Main`` готов. |
| |
| |
| [source,java] |
| ---- |
| |
| public class Main { |
| |
| private static int downloadedPictures; |
| |
| public static void main(String[] args) { |
| |
| final Map<String,Image> flowers = new HashMap<String,Image>(4); |
| final Map<String,Image> thumbs = new HashMap<String,Image>(4); |
| |
| *// Show the FlowerFrame.* |
| final FlowerFrame frame = new FlowerFrame(flowers); |
| frame.setVisible(true); |
| * // The client connects to the service with this code.* |
| FlowerService_Service service = new FlowerService_Service(); |
| final FlowerService port = service.getFlowerServicePort(); |
| |
| Runnable[] tasks = new Runnable[4]; |
| |
| *// The web service getFlower operation |
| // is called 4 times, each in a separate thread. |
| // When the operation finishes the picture is shown in |
| // a specific button.* |
| for (int i=0; i<4;i++) { |
| final int index = i; |
| tasks[i] = new Runnable() { |
| public void run() { |
| try { |
| |
| *// Call the getFlower operation |
| // on the web service:* |
| Image img = port.getFlower(FlowerFrame.FLOWERS[index]); |
| System.out.println("picture downloaded: "+FlowerFrame.FLOWERS[index]); |
| |
| *// Add strings to the hashmap:* |
| flowers.put(FlowerFrame.FLOWERS[index],img); |
| |
| *// Call the showFlower operation |
| // on the FlowerFrame:* |
| frame.showFlower(); |
| |
| } catch (IOException_Exception ex) { |
| ex.printStackTrace(); |
| } |
| downloadedPictures++; |
| } |
| }; |
| new Thread(tasks[i]).start(); |
| } |
| *// The web service getThumbnails operation is called |
| // in a separate thread, just after the previous four threads finish. |
| // When the images are downloaded, the thumbnails are shown at |
| // the bottom of the frame.* |
| Runnable thumbsTask = new Runnable() { |
| public void run() { |
| try { |
| while (downloadedPictures < 4) { |
| try {Thread.sleep(100);} catch (InterruptedException ex) {} |
| } |
| |
| *// Call the getThumbnails operation |
| // on the web service:* |
| List<Image> images = port.getThumbnails(); |
| System.out.println("thumbs downloaded"); |
| |
| if (images != null && images.size() == 4) { |
| for (int i=0;i<4;i++) { |
| thumbs.put(FlowerFrame.FLOWERS[i],images.get(i)); |
| } |
| frame.setThumbnails(thumbs); |
| } |
| } catch (IOException_Exception ex) { |
| ex.printStackTrace(); |
| } |
| } |
| }; |
| new Thread(thumbsTask).start(); |
| } |
| |
| } |
| ---- |
| |
| Приложение клиента готово. Код приложения взаимодействует с веб-службой, делегируемой в модуль EJB для вывода соответствующих изображений. Щелкните приложение правой кнопкой и выберите команду "Выполнить". Приложение Swing откроется, и через некоторое время диалоговое окно приложения заполнится изображениями, полученными из веб-службы. Если появляются не все изображения, необходимо очистить и построить проект FlowerService, а затем снова запустить его . Обратите внимание, что изображение в основном фрейме можно заменить, выбрав переключатель или нажав на эскиз. |
| |
| ]] |
| |
| link:/about/contact_form.html?to=3&subject=Feedback:%20Flower%20Swing%20Client%20EE6[+Отправить отзыв по этому учебному курсу+] |
| |
| Для отправки комментариев и предложений, получения поддержки и новостей о последних разработках, связанных с Java EE IDE NetBeans link:../../../community/lists/top.html[+присоединяйтесь к списку рассылки nbj2ee@netbeans.org+]. |
| |