starbhhc 发表于 2013-2-4 20:11:33

代理模式-虚拟代理

[环境]:StarUML5.0 + JDK6

虚拟代理:




package pattern.proxy.virtual;

import java.awt.Graphics;
import java.awt.Component;
import java.awt.Insets;
import java.awt.Container;
import javax.swing.JPanel;
import javax.swing.JOptionPane;
import javax.swing.ImageIcon;
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.Icon;
/**
* 虚拟代理
*
* 使用代理加载图片
*
* @version 2009-6-29
* @author Winty(wintys@gmail.com) http://wintys.blogjava.net
*/
public class VirtualProxyTest extends JFrame{
    private final int WIDTH = 500;
    private final int HEIGHT = 500;
   

    public VirtualProxyTest(){
      super("虚拟代理");
      
      setContentPane(new MyPanel());
      setSize(WIDTH , HEIGHT);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setVisible(true);
    }

    public static void main(String[] args){
      VirtualProxyTest test = new VirtualProxyTest();
    }
}

class MyPanel extends JPanel{
    private IconProxy iconProxy;

    public MyPanel(){
      iconProxy = new IconProxy("sample.jpg" , 200 , 20);
    }

    @Override
    public void paintComponent(Graphics g){
      super.paintComponent(g);
      
      iconProxy.paintIcon(this , g , 0 , 0);
    }
}

class IconProxy implements Icon{
    private Icon icon;
    private String fileName;//Icon的文件名
    private boolean done;//Icon是否加载完成
    private final int STR_X;
    private final int STR_Y;
   
    /**
   * @param fileName 图片文件
   * @param str_x 字符串输出的x位置
   * @param str_y 字符串输出的y位置
   */
    public IconProxy(String fileName , int str_x , int str_y){
      icon = null;
      this.fileName = fileName;
      done = false;
      STR_X = str_x;
      STR_Y = str_y;
      
    }

    @Override
    public int getIconHeight(){
      return icon.getIconHeight();
    }

    @Override
    public int getIconWidth(){
      return icon.getIconWidth();
    }

    @Override
    public void paintIcon(final Component c, Graphics g, int x, int y){
      //因为JFrame的标题栏和边框占据了空间,
      //而paintIcon是从容器的(0,0)坐标开始绘制,所以要计算边框所占的空间。
      Insets inset = new Insets(0,0,0,0);
      if(c instanceof Container)
            inset = ((Container)c).getInsets();

      if(!done){//未加载完成
            g.drawString("Loading icon...",
                              inset.right + STR_X ,
                              inset.top + STR_Y);
      
            synchronized(this){
                SwingUtilities.invokeLater(
                  new Runnable(){
                        public void run(){
                            //延时
                            try{
                              Thread.sleep(5*1000);
                            }catch(InterruptedException e){
                              JOptionPane.showMessageDialog(c , e.getMessage());
                            }
                           
                            icon = new ImageIcon(fileName);
                            done = true;
                            c.repaint();
                        }
                  }
                );
            }//end of synchronized
      }
      else{//加载完成
            
            g.drawString("Loaded successfully.",
                              inset.right + STR_X ,
                              inset.top + STR_Y);
            //空出长度为STR_Y的空间给String
            icon.paintIcon(c , g , x + inset.right , y + inset.top + STR_Y + 5);
      }
    }
}

运行结果:
Loading icon...


Loaded successfully:
页: [1]
查看完整版本: 代理模式-虚拟代理