corner imagecorner image
IDEPlatformPluginsDocs & SupportCommunityPartners

通过 Web 服务传递二进制数据,第 6 部分:创建 Swing 客户端

下载样例

本练习的目的在于为您以前创建和部署的 Web 服务创建一个客户端,然后给该客户端添加一个 GUI 界面。该界面显示 Web 服务以二进制数据传递的图像。

本教程中的课程

本页上的内容适用 NetBeans IDE 6.5
  1. 概述
  2. 创建 EJB 模块
  3. 创建 Web 服务
  4. 测试 Web 服务
  5. 修改架构文件和 WSDL 文件以传递二进制数据
  6. => 创建 Swing 客户端

创建 Swing 客户端

在以下步骤中,会创建一个 Web 应用程序。在此应用程序内,将创建一个客户端,该客户端使用您在以前的教程中创建并修改的 Web 服务。然后向该 Web 应用程序添加一个 JFrame,并在其中使用 Swing 组件设计一个 GUI 界面。最后,将该 Swing 组件绑定到该 Web 服务客户端代码。

创建 Swing 客户端:

  1. 选择“文件”>“新建项目”(Ctrl-Shift-N)。此时将打开“新建项目 ”向导。选择 Java 类别中的“Java 应用程序”选项。单击“下一步”。此时将打开“新建 Java 应用程序”向导。在“项目名称”中键入 FlowerClient 并单击“完成”。IDE 创建一个新的 Java 应用程序项目。
  2. 右键单击 FlowerClient 项目节点,然后从上下文菜单选择“新建”>“Web 服务客户端”。此时将打开“新建 Web 服务客户端”向导。选择 WSDL URL 单选按钮,并将 WSDL 文件的 URL 粘贴到该字段。默认情况下,该 URL 为 http://localhost:8080/FlowerService/FlowerService?WSDL。单击“完成”。IDE 将下载该 WSDL 文件,添加与 Web 服务交互的客户端桩模块,并在“项目”窗口的 Java 应用程序项目中添加节点,如下所示。


    显示新 Web 服务客户端的“项目”视图

  3. 右键单击 "FlowerClient" 节点,然后选择“新建”>“JFrame 窗体”。将该窗体命名为 FlowerFrame。并且,将其置于 flowerclient 包中。
  4. 向该 FlowerFrame 添加一个 JPanel。对其进行扩展,以填充整个 FlowerFrame。将该面板命名为 gardenFlowersPanel
  5. 将以下 Swing 组件添加到 gardenFlowersPanel,从面板的顶部开始。(有关 Swing 组件的教程,请参见 在 NetBeans IDE 中设计 Swing GUI):
    • Label。变量名:titleLabel,文本:Garden Flowers,位置:顶部居中。您可能想要将文本设置为粗体和/或增大字号。
    • ButtonGroup。变量名:buttonGroup1
    • 将以下 4 个单选按钮添加到 titleLabel 下面的水平行中。在每个按钮的属性中,将其设置为 buttonGroup1 的成员。 buttonGroup1 中的单选按钮
      变量名 已选定 文本
      asterRadioButton true Aster
      honeysuckleRadioButton false Honeysuckle
      roseRadioButton false Rose
      sunflowerRadioButton false Sunflower
    • JScrollPane。变量名:mainScrollPane。位置:在单选按钮下,填充水平空间和大约三分之二的剩余垂直空间。
      • JPanel。变量名:mainPanel。布局:边框式。位置:填充 mainScrollPane
      • JButton。变量名:mainPictureButton。文本:Waiting for picture... 位置:在 mainPanel 中(根据面板的边框式布局,按钮将自动填充整个空间)。
    • JScrollPane。变量名:thumbnailScrollPane。位置:在单选按钮下,填充水平空间和所有剩余的垂直空间。
      • JPanel。变量名:thumbnailPanel。布局:网格式。位置:填充 thumbnailScrollPane。网格式布局表示以下 4 个按钮将会是同样大小,并完全填充 thumbnailPanelthumbnailPanel 中的按钮
        变量名 文本
        asterButton Waiting...
        honeysuckleButton Waiting...
        roseButton Waiting
        sunflowerButton Waiting...

    此时,FlowerFrame 将如下所示。
    已完成的 Flower 窗体,其中显示按钮文本,而不是图像

  6. 在源代码编辑器中,像这样初始化 FlowerFrame
    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);
        
    } 
  7. 当单击 JRadioButton 时,我们希望在主按钮中显示一个新图像。
    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("");
    }
  8. 当单击 JButton 时,我们选择相关的 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);
        }
    }
  9. Main 类中,将会调用 FlowerFrame 中的 setThumbnails 方法。
    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("");
        }
    }
  10. FlowerFrame 中修复导入(如果在代码中粘贴导入内容时未对其进行修复)。通过在编辑器中单击鼠标右键,然后从上下文菜单中选择“修复导入”,可以一次性修复所有导入内容。下面是完整的导入语句集:
    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;
  11. 按如下所示填充 Main.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();
        }
    
    }
  12. Main.java 中修复导入(如果在代码中粘贴导入内容时未对其进行修复)。通过在编辑器中单击鼠标右键,然后从上下文菜单中选择“修复导入”,可以一次性修复所有导入内容。您可以选择要导入的 List 类;请选择 java.util.List。下面是完整的导入语句集:
    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;
  13. 删除 FlowerFrame 类中的现有 main 方法。

现在该 Web 服务完整了,具有与 Web 服务交互的代码,该 Web 服务委托给了 EJB 模块,以公开其图像。右键单击客户端,然后选择“运行”。将启动 Swing 应用程序,并且之后会填充从 Web 服务接收到的图像。如果图像没有全部出现,请清理并生成 FlowerService 项目,然后再次运行。

后续步骤:

Logging and Optimizing the Service(登录和优化服务)

要发送意见和建议、获得支持以及随时了解 NetBeans IDE Java EE 开发功能的最新开发情况,请加入 邮件列表