<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> | |
<html> | |
<head><link rel="stylesheet" href="../../../print.css" type="text/css" media="print"> | |
<title>Creating the Swing Client, Web Service Passing Binary Data pt 6 - NetBeans IDE Tutorial</title> | |
<meta http-equiv="content-type" content="text/html; charset=UTF-8"> | |
<meta name="KEYWORDS" content="NETBEANS, TUTORIAL, GUIDE, USER, DOCUMENTATION, WEB SERVICE, SOAP, EJB, BINARY ATTACHMENT, JAX-WS"> | |
<meta name="description" | |
content="This learning trail shows how to create and | |
consume a web service that delegates to an EJB and sends binary data via SOAP. | |
This tutorial shows how to create a client for the web service that | |
displays the result in a GUI designed with Swing components."> | |
<link rel="stylesheet" href="../../../netbeans.css"></head> | |
<body> | |
<h1>Web Service Passing Binary Data, pt 5: Creating the Swing Client</h1> | |
<p>The goal of this exercise is to create a client for the web service you previously created and deployed, and then add a GUI interface to that client. The interface displays the images that the web service passes as binary data.</p> | |
<p>You can download a complete version of the client from the <a target="_blank" href="https://netbeans.org/projects/samples/downloads/download/Samples%252FWeb%2520Services%252FWeb%2520Service%2520Passing%2520Binary%2520Data%2520--%2520EE6%252FFlowerClient.zip">NetBeans Samples Catalog</a>.</p> | |
<p><b>Lessons In This Tutorial</b></p> | |
<img src="../../../images_www/articles/72/netbeans-stamp-74-73-72.png" class="stamp" alt="Content on this page applies to NetBeans IDE 7.2, 7.3 and 7.4" title="Content on this page applies to the NetBeans IDE 7.2, 7.3 and 7.4" > | |
<ol> | |
<li><a href="./flower_overview.html">Overview</a></li> | |
<li><a href="./flower_ws.html">Creating the Web Service</a></li> | |
<li><a href="./flower-code-ws.html">Coding and Testing the Web Service</a></li> | |
<li><a href="./flower_wsdl_schema.html">Modifying the Schema and WSDL Files to Pass Binary Data</a></li> | |
<li> => Creating the Swing Client</li> | |
</ol> | |
<p><b>Contents of This Lesson</b></p> | |
<ol> | |
<li> | |
<p><a href="#create-client-app">Creating the Client Application</a></p> | |
</li> | |
<li><a href="#design-jframe">Designing the JFrame</a></li> | |
<li><p><a href="#bind-jframe">Binding the JFrame Components</a></p> | |
<ul> | |
<li><a href="#initialize-components">Initializing the Components</a></li> | |
<li><a href="#show-flowers">Showing the Flowers</a></li> | |
</ul></li> | |
<li><a href="#code-main-class">Coding the Main Class</a></li> | |
</ol> | |
<h2><a name="create-client-app"></a> Creating the Client Application</h2> | |
<p>In this section, you create a web application. Within this application, you create a client that consumes the web service you created and modified in previous tutorials. </p> | |
<p><strong>To create the client application: </strong></p> | |
<ol> | |
<li>Choose File > New Project (Ctrl-Shift-N on Linux/Windows, ⌘-Shift-N on MacOS). The | |
New Project wizard appears. </li> | |
<li>Select | |
Java Application from the Java category. Click | |
Next. The New Java Application wizard appears. | |
Type <tt>FlowerClient</tt> in Project Name. Select a location for the project and click Finish. | |
The IDE creates a new Java application project.</li> | |
<li>Right-click the <tt>FlowerClient</tt> project node | |
and choose New > Web Service Client from the context menu. The New Web Service Client wizard opens. </li> | |
<li>Select the WSDL URL radio button and paste the URL of the WSDL file into that field. (By default, the URL is <tt>http://localhost:8080/FlowerAlbumService/FlowerServiceService?wsdl</tt>. Find the URL in the browser by testing the web service and replacing <tt>?Tester</tt> with <tt>?wsdl</tt> at the end of the URL.) Accept all other default values, including a blank package name. <br><img src="../../../images_www/articles/73/websvc/flower/ws-client-wiz.png" alt="Web Service Client wizard showing WSDL URL" height="440" width="588" class="margin-around"></li> | |
<li>Click Finish. The IDE downloads the WSDL file, adds client | |
stubs for interacting with the web service, | |
and adds nodes to the Projects window in the Java application project. | |
<br><img src="../../../images_www/articles/73/websvc/flower/client-generated-sources.png" alt="Projects view showing new web service client" height="474" width="360" class="margin-around" title="Projects view showing new web service client"></li></ol> | |
<h2 id="design-jframe">Designing the JFrame Form</h2> | |
<p>In this section, you add a <tt>JFrame</tt> to the web application and design a GUI interface within it, using Swing components. Finally, you bind the Swing components to the web service client code.</p> | |
<p class="tips">If you do not want to design the JFrame form yourself, you can download a predesigned JFrame Java file <a target="_blank" href="https://netbeans.org/projects/www/downloads/download/webservices%252FFlowerFrame.java">here</a>.</p> | |
<ol> | |
<li>Right-click the <tt>FlowerClient</tt> node and select New > JFrame Form. Name the frame <tt>FlowerFrame</tt>. | |
Place it in the <tt>flowerclient</tt> package.</li> | |
<li>The <tt>FlowerFrame</tt> opens in the editor. Open the Palette if it is not open. | |
Extend the bottom boundary of the frame by around one-third.<br><img src="../../../images_www/articles/73/websvc/flower/opened-flowerform.png" alt="Flower Form in editor, in design view, with Palette also open" height="437" width="600" class="margin-around"></li> | |
<li>Drag a JPanel from the Swing Containers section of the Palette to the <tt>FlowerFrame</tt>. Expand it to fill the entire <tt>FlowerFrame</tt>. <br> | |
<img src="../../../images_www/articles/73/websvc/flower/add-panel.png" alt="Adding and expanding a JPanel in the FlowerFrame" height="408" width="587" class="margin-around"></li> | |
<li>Right-click the Panel in the Design View. Select Change Variable Name... from the context menu. Name the panel <tt>gardenFlowersPanel</tt>.</li> | |
<li>Drag a JLabel from the Palette to the top of the<tt> gardenFlowersPanel</tt>. Right-click the label, and change the label's variable name to <tt>titleLabel</tt>. Right-click the <tt>titleLabel</tt> again and select Edit Text. Change the text to Garden Flowers. You may want to explore the <tt>titleLabel</tt>'s properties and give it a prominent font.</li> | |
<li>Drag a Button Group into the design view. Accept the button group's default variable name of <tt>buttonGroup1</tt>.</li> | |
<li>Drag four Radio Buttons into a horizontal row beneath the <tt>titleLabel</tt>. In the properties of each button, set it as a member of <tt>buttonGroup1</tt>. | |
The buttons' other properties are as follows: | |
<table> | |
<caption>Radio Buttons in buttonGroup1</caption> | |
<tbody> | |
<tr> | |
<th class="tblheader">Variable Name</th> | |
<th class="tblheader">Selected</th> | |
<th class="tblheader">Text</th> | |
</tr> | |
<tr> | |
<td class="tbltd1">asterRadioButton</td> | |
<td class="tbltd1">true</td> | |
<td class="tbltd1">Aster</td> | |
</tr> | |
<tr> | |
<td class="tbltd1">honeysuckleRadioButton</td> | |
<td class="tbltd1">false</td> | |
<td class="tbltd1">Honeysuckle</td> | |
</tr> | |
<tr> | |
<td class="tbltd1">roseRadioButton</td> | |
<td class="tbltd1">false</td> | |
<td class="tbltd1">Rose</td> | |
</tr> | |
<tr> | |
<td class="tbltd1">sunflowerRadioButton</td> | |
<td class="tbltd1">false</td> | |
<td class="tbltd1">Sunflower</td> | |
</tr> | |
</tbody> | |
</table> | |
</li> | |
<li>Drag a Scroll Pane to below the radio buttons. Expand it to fill all the horizontal space and about two-thirds of the free vertical space. Change the scroll pane's variable name to <tt>mainScrollPane</tt>.</li> | |
<li>Drag a Panel into the <tt>mainScrollPane</tt>. Change the Panel's variable name to <tt>mainPanel</tt>. </li> | |
<li>In the Design view, right-click the <tt>mainPanel</tt> and select Set Layout > Border Layout. </li> | |
<li>Drag a Button into the <tt>mainPanel</tt>. Because the <tt>mainPanel</tt> has border layout, the button automatically fills the entire panel. Change the button's variable name to <tt>mainPictureButton</tt> and change the button's text to "Waiting for picture..."</li> | |
<li>Drag another Scroll Pane to the space below the <tt>mainScrollPane</tt>. Expand the new scroll pane to fill up all remaining free space. Change the new scroll pane's variable name to <tt>thumbnailScrollPane</tt>.</li> | |
<li>Drag a Panel into the <tt>thumbnailScrollPane</tt>. Change the Panel's variable name to <tt>thumbnailPanel</tt>. Set the <tt>thumbnailPanel</tt>'s layout to Grid Layout.</li> | |
<li>Drag four Buttons into the <tt>thumbnailPanel</tt>. Because the <tt>thumbnailPanel</tt> has Grid Layout, the Buttons are automatically of equal size and completely fill the panel. The buttons' properties are as follows: | |
<table> | |
<title>Buttons in the thumbnailPanel</title> | |
<tbody> | |
<tr> | |
<th class="tblheader">Variable Name</th> | |
<th class="tblheader">Text</th> | |
</tr> | |
<tr> | |
<td class="tbltd1">asterButton</td> | |
<td class="tbltd1">Waiting...</td> | |
</tr> | |
<tr> | |
<td class="tbltd1">honeysuckleButton</td> | |
<td class="tbltd1">Waiting...</td> | |
</tr> | |
<tr> | |
<td class="tbltd1">roseButton</td> | |
<td class="tbltd1">Waiting</td> | |
</tr> | |
<tr> | |
<td class="tbltd1">sunflowerButton</td> | |
<td class="tbltd1">Waiting...</td> | |
</tr> | |
</tbody> | |
</table> | |
</li> | |
</ol> | |
<p>The JFrame Form is now completely designed. At this point, the <tt>FlowerFrame</tt> looks | |
as follows. | |
<br> | |
<img src="../../../images_www/articles/73/websvc/flower/designed-form.png" alt="Completed Flower Frame showing button texts instead of images" height="412" width="500" border="1" class="margin-around" title="Completed Flower Frame showing button texts instead of images"></p> | |
<a name="bind-jframe"></a> | |
<h2>Binding the JFrame Components</h2> | |
<p>In this section, you initialize the components in the constructor and bind the components to listeners. The listeners call code that shows the flower images.</p> | |
<div class="indent"> | |
<h3><a name="initialize-components">Initializing the Components</h3> | |
<p>In this section, you fill in the <tt>FlowerFrame</tt> constructor</p> | |
<ol> | |
<li>Change to the Source view of the editor. Locate the beginning of the <tt>FlowerFrame</tt> class body and the <tt>FlowerFrame</tt> constructor.<br> | |
<img src="../../../images_www/articles/73/websvc/flower/ff-empty-constructor.png" alt="Source view of editor showing empty FlowerForm constructor" height="197" width="492" class="margin-around" border="1"></li> | |
<li>At the top of the class body of <tt>FlowerFrame</tt>, before the constructor, create an array of strings of the names of every flower. | |
<pre class="examplecode">protected static final String[] FLOWERS = {"aster", "honeysuckle", "rose", "sunflower"};</pre> | |
</li> | |
<li>Between the FLOWERS string array and the constructor, add a line that initializes a <tt><a target="_blank" href="http://download.oracle.com/javase/6/docs/api/java/util/Map.html">java.util.Map</a></tt> named <tt>flowers</tt>. The map takes a <tt>String</tt> and maps it to an <tt>Image</tt>. | |
<pre class="examplecode">private Map<String, Image> flowers;</pre> </li> | |
<li>Add import statements for <tt>java.util.Map</tt> and <tt>java.awt.Image</tt>. </li> | |
<li>Add code to the <tt>FlowerFrame</tt> constructor to associate a specific <tt>Image</tt> with a specific <tt>String</tt> for a specific instance of the <tt>flowers</tt> map | |
<pre> | |
public FlowerFrame(Map<String, Image> flowers) { | |
this.flowers = flowers; | |
for (String flower:FLOWERS) { | |
flowers.put(flower,null); | |
} | |
initComponents(); | |
} </pre></li> | |
<li>Initialize <tt>ItemListener</tt>s for the radio buttons and <tt>ActionListener</tt>s for the four flower buttons, and set the default title. | |
<pre class="examplecode"> | |
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); | |
}</pre> | |
</li> | |
<li>Add import statements for <tt><a target="_blank" href="http://download.oracle.com/javase/6/docs/api/java/awt/event/ItemListener.html">java.awt.event.ItemListener</a></tt> and <tt><a target="_blank" href="http://download.oracle.com/javase/6/docs/api/java/awt/event/ActionListener.html">java.awt.event.ActionListener</a></tt>.</li> | |
</ol> | |
<p>The constructor is now complete. You have compile error warnings in the code because the code does not contain the classes <tt>RBListener</tt> and <tt>ButtonListener</tt>. These two classes are custom implementations of <tt>ItemListener</tt> and <tt>ActionListener</tt>, respectively. You write these two classes in the next section.</p> | |
<h3><a name="show-flowers">Showing the Flowers</h3> | |
<p>In this section, you write custom listeners for the radio buttons and the flower buttons. You also write a method that determines which flower is selected by the buttons and gets an <tt>Image</tt> of that flower from the <tt>flowers</tt> map. Lastly, you write a method that is called by the <tt>Main</tt> class and that gets an <tt>Image</tt> for each thumbnail.</p> | |
<ol> | |
<li>Find the <tt>public static void main(String args[])</tt> method in the <tt>FlowerFrame</tt> class body. Delete this method and its documentation. (The application uses the <tt>Main</tt> class instead.)</li> | |
<li>In place of the <tt>main</tt> method, write a custom <tt>ItemListener</tt> for the radio buttons. | |
This listener shows a new flower image when a radio button is chosen. | |
<pre class="examplecode">private class RBListener implements ItemListener { | |
public void itemStateChanged(ItemEvent e) { | |
showFlower(); | |
} | |
}</pre></li> | |
<li>Add an import statement for <tt><a target="_blank" href="http://download.oracle.com/javase/6/docs/api/java/awt/event/ItemEvent.html">java.awt.event.ItemEvent</a></tt>.</li> | |
<li>Below the custom <tt>ItemListener</tt>, write a custom <tt>ActionListener</tt> for the 4 flower buttons. When a button is clicked, the listener selects the related radio button: | |
<pre class="examplecode">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); | |
} | |
}</pre> | |
</li> | |
<li>Add an import statement for <tt><a target="_blank" href="http://download.oracle.com/javase/6/docs/api/java/awt/event/ActionEvent.html">java.awt.event.ActionEvent</a></tt>.</li> | |
<li>Below the custom <tt>ActionListener</tt>, write the <tt>showFlower</tt> method. This method determines which radio button is selected and gets an <tt>Image</tt> of the corresponding flower from the <tt>flowers</tt> map. | |
<pre class="examplecode"> | |
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(""); | |
}</pre> | |
</li> | |
<li>Add an import statement for <tt><a target="_blank" href="http://download.oracle.com/javase/6/docs/api/javax/swing/ImageIcon.html">javax.swing.ImageIcon</a></tt>.</li> | |
<li>Write the <tt>setThumbnails</tt> method. This method gets an image for each thumbnail from the <tt>flowers</tt> map. The <tt>Main</tt> class calls this method. | |
<pre class="examplecode">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(""); | |
} | |
}</pre></li> | |
<li>Fix the imports in <tt>FlowerFrame</tt>, if you did not fix them as you pasted in the code. You can fix them all at once by right-clicking in the editor and choosing Fix Imports from the context menu. The complete set of import statements follows: | |
<pre class="examplecode">import java.awt.Image;<br>import java.awt.event.ActionEvent;<br>import java.awt.event.ActionListener;<br>import java.awt.event.ItemEvent;<br>import java.awt.event.ItemListener;<br>import java.util.Map;<br>import javax.swing.ImageIcon;</pre> </li> </ol> | |
<p>The <tt>FlowerFrame</tt> is now complete.</p> | |
</div> | |
<h2><a name="code-main-class">Coding the Main Class</h2> | |
<p>In this section, you complete the <tt>Main</tt> class so that is shows the <tt>FlowerFrame</tt>, connects to the web service, and calls the web service operations.</p> | |
<ol> | |
<li>Open the <tt>Main.java</tt> class in the editor.<br> | |
<img src="../../../images_www/articles/73/websvc/flower/main-empty.png" alt="Empty Main class" height="303" width="425" class="margin-around" border="1"> </li> | |
<li>In the class body, before the <tt>main</tt> method, initialize an <tt>int</tt> variable for the number of downloaded pictures. | |
<pre class="examplecode"> private static int downloadedPictures;</pre></li> | |
</li> | |
<li>In the <tt>main</tt> method body, create a <tt>HashMap</tt> of four flowers and another <tt>HashMap</tt> of four thumbnails.<pre class="examplecode">final Map<String,Image> flowers = new HashMap<String,Image>(4); | |
final Map<String,Image> thumbs = new HashMap<String,Image>(4);</pre> | |
</li> | |
<li>Add import statements for <tt>java.awt.Image</tt>, <tt>java.util.Map</tt>, and <tt>java.util.HashMap</tt>.</li> | |
<li>In the <tt>main</tt> | |
method body, add code to show the <tt>FlowerFrame</tt>.<pre class="examplecode"><b>// Show the FlowerFrame.</b> | |
final FlowerFrame frame = new FlowerFrame(flowers); | |
frame.setVisible(true); </pre> | |
</li> | |
<li>In the <tt>main</tt> method body, add code to connect the client to the service.<pre class="examplecode"><b>// The client connects to the service with this code.</b> | |
FlowerServiceService service = new FlowerServiceService(); | |
final FlowerService port = service.getFlowerServicePort();</pre> | |
</li> | |
<li>Add import statements for <tt>org.flower.service.FlowerService</tt> and <tt>org.flower.service.FlowerServiceService</tt>.</li> | |
<li>In the <tt>main</tt> method body, add code that creates an array of four <tt>Runnable</tt> threads and calls the | |
web service's <tt>getFlower</tt> operation once in each thread.<pre class="examplecode"><b>// 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.</b> | |
Runnable[] tasks = new Runnable[4]; | |
for (int i=0; i<4;i++) { | |
final int index = i; | |
tasks[i] = new Runnable() { | |
public void run() { | |
try { | |
<b>// Call the getFlower operation | |
// on the web service:</b> | |
Image img = port.getFlower(FlowerFrame.FLOWERS[index]); | |
System.out.println("picture downloaded: "+FlowerFrame.FLOWERS[index]); | |
<b>// Add strings to the hashmap:</b> | |
flowers.put(FlowerFrame.FLOWERS[index],img); | |
<b>// Call the showFlower operation | |
// on the FlowerFrame:</b> | |
frame.showFlower(); | |
} catch (IOException_Exception ex) { | |
ex.printStackTrace(); | |
} | |
downloadedPictures++; | |
} | |
}; | |
new Thread(tasks[i]).start(); | |
}</pre> | |
</li> | |
<li>Add an import statement for <tt>org.flower.service.IOException_Exception</tt>. </li> | |
<li>In the <tt>main</tt> method body, add code that calls the web service's <tt>getThumbnails</tt> operation in a separate thread. | |
<pre class="examplecode"><b>// 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.</b> | |
Runnable thumbsTask = new Runnable() { | |
public void run() { | |
try { | |
while (downloadedPictures < 4) { | |
try {Thread.sleep(100);} catch (InterruptedException ex) {} | |
} | |
<b>// Call the getThumbnails operation | |
// on the web service:</b> | |
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(); | |
</pre> | |
</li> | |
<li>Fix the imports in <tt>Main.java</tt>, if you did not fix them as you pasted in the code. You can fix them all at once by right-clicking in the editor and choosing Fix Imports from the context menu. You are given a choice of List classes to import; select <tt>java.util.List</tt>. The complete set of import statements follows: | |
<pre class="examplecode">import flower.album.FlowerService;<br>import flower.album.FlowerService_Service;<br>import flower.album.IOException_Exception;<br>import java.awt.Image;<br>import java.util.HashMap;<br>import java.util.List;<br>import java.util.Map;</pre> | |
</li> | |
</ol> | |
<p>The <tt>Main</tt> class is now complete.</p> | |
<pre class="examplecode">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); | |
<b>// Show the FlowerFrame.</b> | |
final FlowerFrame frame = new FlowerFrame(flowers); | |
frame.setVisible(true); | |
<br><b> // The client connects to the service with this code.</b> | |
FlowerService_Service service = new FlowerService_Service(); | |
final FlowerService port = service.getFlowerServicePort(); | |
Runnable[] tasks = new Runnable[4]; | |
<b>// 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.</b> | |
for (int i=0; i<4;i++) { | |
final int index = i; | |
tasks[i] = new Runnable() { | |
public void run() { | |
try { | |
<b>// Call the getFlower operation | |
// on the web service:</b> | |
Image img = port.getFlower(FlowerFrame.FLOWERS[index]); | |
System.out.println("picture downloaded: "+FlowerFrame.FLOWERS[index]); | |
<b>// Add strings to the hashmap:</b> | |
flowers.put(FlowerFrame.FLOWERS[index],img); | |
<b>// Call the showFlower operation | |
// on the FlowerFrame:</b> | |
frame.showFlower(); | |
} catch (IOException_Exception ex) { | |
ex.printStackTrace(); | |
} | |
downloadedPictures++; | |
} | |
}; | |
new Thread(tasks[i]).start(); | |
} | |
<b>// 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.</b> | |
Runnable thumbsTask = new Runnable() { | |
public void run() { | |
try { | |
while (downloadedPictures < 4) { | |
try {Thread.sleep(100);} catch (InterruptedException ex) {} | |
} | |
<b>// Call the getThumbnails operation | |
// on the web service:</b> | |
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(); | |
} | |
}</pre> | |
<p>The client application is now complete, with code that interacts with | |
the web service that delegates to the EJB module to exposes its images. Right-click | |
the client and choose Run. The Swing application starts up and, after a moment, | |
is filled with the images received from the web service. | |
If the images do not all appear, clean and build the FlowerService project and run it again. | |
Note that you can change the image that appears in the main frame either by selecting a radio button or by clicking a thumbnail.<div class="feedback-box" ><a href="/about/contact_form.html?to=3&subject=Feedback:%20Flower%20Swing%20Client%20EE6">Send Feedback on This Tutorial</a></div> | |
<p>To send comments and suggestions, get support, and keep informed about the latest | |
developments on the NetBeans IDE Java EE development features, <a href="../../../community/lists/top.html">join | |
the nbj2ee@netbeans.org mailing list</a>.</p> | |
</body> | |
</html> |