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.
In the following procedure, you create a web application. Within this application, you create a client that consumes the web service you created and modified in previous tutorials. You then add a JFrame 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.
To create the Swing client:
Choose File > New Project (Ctrl-Shift-N). The
New Project wizard appears. Select
Java Application from the Java category. Click
Next. The New Java Application wizard appears.
Type FlowerClient in Project Name and click Finish.
The IDE creates a new Java application project.
Right-click the FlowerClient project node
and choose New > Web Service Client from the context menu. The New Web Service Client wizard opens. Select the WSDL URL radio button and paste the URL of the WSDL file into that field. By default, the URL is http://localhost:8080/FlowerService/FlowerService?WSDL. 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, as shown below.
Right-click the FlowerClient node and select New > JFrame Form. Name the frame FlowerFrame.
Place it in the flowerclient package.
Add a JPanel to the FlowerFrame. Expand it to fill the entire FlowerFrame. Name the panel gardenFlowersPanel.
Add the following Swing components to the gardenFlowersPanel, starting from the top of the panel. (For a tutorial on Swing components, see Designing a Swing GUI in NetBeans IDE):
Label. variable name: titleLabel, text: Garden Flowers, position: Centered at the top. You may want to bold the text and/or give it a larger font size.
ButtonGroup. variable name: buttonGroup1.
Add the following 4 Radio Buttons in a horizontal row beneath the titleLabel. In the properties of each button, set it as a member of buttonGroup1.
Radio Buttons in buttonGroup1
Variable Name
Selected
Text
asterRadioButton
true
Aster
honeysuckleRadioButton
false
Honeysuckle
roseRadioButton
false
Rose
sunflowerRadioButton
false
Sunflower
JScrollPane. variable name: mainScrollPane. position: Below the radio buttons, filling the horizontal space and about two-thirds of the remaining vertical space.
JPanel. variable name: mainPanel. layout: Border. position: Filling the mainScrollPane.
JButton. variable name: mainPictureButton. text: Waiting for picture... position: In mainPanel (Due to Border layout of panel, button will automatically fill entire space.)
JScrollPane. variable name: thumbnailScrollPane. position: Below the radio buttons, filling the horizontal space and all the remaining vertical space.
JPanel. variable name: thumbnailPanel.
layout: Grid. position: Filling the thumbnailScrollPane.
The Grid layout means that the four following buttons will all be of equal size and completely fill the thumbnailPanel.
Buttons in the thumbnailPanel
Variable Name
Text
asterButton
Waiting...
honeysuckleButton
Waiting...
roseButton
Waiting
sunflowerButton
Waiting...
At this point, the FlowerFrame looks
as follows.
In the Source Editor, initialize the FlowerFrame like this:
public static final String[] FLOWERS = {"aster", "honeysuckle", "rose", "sunflower"};
private Map<String, Image> flowers;
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);
}
When a JRadioButton is clicked, we want to show
a new image in the main button.
private class RBListener implements ItemListener {
public void itemStateChanged(ItemEvent e) {
showFlower();
}
}
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("");
}
When a JButton is clicked, we select the related JRadioButton:
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);
}
}
In the Main class, the setThumbnails method will be called, which
is in the FlowerFrame.
Fix the imports in FlowerFrame, 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:
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();
}
}
Fix the imports in Main.java, 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 java.util.List. The complete set of import statements follows:
Remove the existing main method in the FlowerFrame class.
The web service 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.
To send comments and suggestions, get support, and keep informed on the latest
developments on the NetBeans IDE Java EE development features, join
the mailing list.