定义 虚拟代理作为创建开销大的对象的代表。虚拟代理经常直到我们真正需要一个对象的时候才创建它。当对象在创建前和创建中时,由虚拟代理来扮演对象的替身。对象创建后,代理就会将请求直接委托给对象。
场景 可以显示CD封面的Swing应用
场景介绍 建立一个应用程序,用来展现你最喜欢的CD封面。应用程序提供一个下拉菜单,然后从相应网站取得对应的CD封面。已知,限于连接带宽和网络负载,下载可能需要一些时间,所以在等待图像加载的时候,应该给出一些友好的提示。要求在等待图像时整个应用程序不要被挂起。一旦图像加载完成,Swing组件上显示相应的图像。
 
解决方案 ImageProxy代理用于隐藏创建开销大的对象(因为我们需要通过网络获取图像数据)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 import  java.net.*;import  java.awt.*;import  javax.swing.*;class  ImageProxy  implements  Icon   {    volatile  ImageIcon imageIcon;     final  URL imageURL;     Thread retrievalThread;     boolean  retrieving = false ;     public  ImageProxy (URL url)   { imageURL = url; }     public  int  getIconWidth ()   {         if  (imageIcon != null ) {             return  imageIcon.getIconWidth();         } else  {             return  800 ;         }     }     public  int  getIconHeight ()   {         if  (imageIcon != null ) {             return  imageIcon.getIconHeight();         } else  {             return  600 ;         }     }     synchronized  void  setImageIcon (ImageIcon imageIcon)   {         this .imageIcon = imageIcon;     }     public  void  paintIcon (final  Component c, Graphics  g, int  x, int  y)   {         if  (imageIcon != null ) {             imageIcon.paintIcon(c, g, x, y);         } else  {             g.drawString("Loading album cover, please wait..." , x+300 , y+190 );             if  (!retrieving) {                 retrieving = true ;                 retrievalThread = new  Thread(new  Runnable() {                     public  void  run ()   {                         try  {                             setImageIcon(new  ImageIcon(imageURL, "Album Cover" ));                             c.repaint();                         } catch  (Exception e) {                             e.printStackTrace();                         }                     }                 });                 retrievalThread.start();             }         }     } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import  java.awt.*;import  javax.swing.*;class  ImageComponent  extends  JComponent   {    private  static  final  long  serialVersionUID = 1L ;     private  Icon icon;     public  ImageComponent (Icon icon)   {         this .icon = icon;     }     public  void  setIcon (Icon icon)   {         this .icon = icon;     }     public  void  paintComponent (Graphics g)   {         super .paintComponent(g);         int  w = icon.getIconWidth();         int  h = icon.getIconHeight();         int  x = (800  - w)/2 ;         int  y = (600  - h)/2 ;         icon.paintIcon(this , g, x, y);     } }