署理模式-虚拟代理

代理模式-虚拟代理
[环境]: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: