【设计模式】学习笔记16:代理模式之虚拟代理(实现CD封面加载器)
本文出自 http://blog.csdn.net/shuangde800
走进代理模式
我们打算建立一个应用程序,用来展现你最喜欢的CD封面。你可以建立一个CD标题菜单,然后从豆瓣等网站的在线服务中取得CD封面的图。如果使用Swing,可以创建一个Icon接口从网络上加载图像。唯一的问题是,限于连接带宽和网络负载,下载可能需要一些时间,所以在等待图片加载的时候,应该显示一些东西。我们希望在等待图像时整个应用程序被挂起。一旦图像被加载完成,刚才显示的东西应该消失,图像显示出来。
![](/assets/blank.gif)
![](/assets/blank.gif)
比较远程代理和虚拟代理:
设计CD封面虚拟代理
![](/assets/blank.gif)
使用虚拟代理实现CD封面加载器
package com.zsd;import java.awt.Component;
import java.awt.Graphics;
import java.net.URL;import javax.swing.Icon;
import javax.swing.ImageIcon;//实现Icon接口
public class ImageProxy implements Icon {ImageIcon imageIcon;URL imageURL;Thread retrievalThread;boolean retrieving = false;// 将图片的URL传入构造器中public ImageProxy(URL url) {imageURL = url;}// 在图像加载完毕前,返回默认的宽和高// 图像加载完毕后,装给iamgeIcon处理public int getIconWidth() {if (imageIcon != null) {return imageIcon.getIconWidth();} else {return 800;}}public int getIconHeight() {if (imageIcon != null) {return imageIcon.getIconHeight();} else {return 600;}}// 当要在屏幕上绘制图像时,就调用此方法public void paintIcon(final Component c, Graphics g, int x, int y) {// 如果已经有了icon,就画出if (imageIcon != null) {imageIcon.paintIcon(c, g, x, y);} else {// 还没有icon时,就显示“加载中...”的消息g.drawString("CD封面加载中,请稍后...", x + 300, y + 190);if (!retrieving) {retrieving = true;// 在这个线程中加载真正的icon图像。注意,加载图像和ImageIcon是同步(synchronous)// 也就是说,只有在加载完之后,ImageIcon构造器才会返回。这样,我们的程序会耗在这里// 所以要把加载变成异步(asynchronous)的。retrievalThread = new Thread(new Runnable() {public void run() {try {imageIcon = new ImageIcon(imageURL, "CD Cover");c.repaint();} catch (Exception e) {e.printStackTrace();}}});retrievalThread.start();}}}}
package com.zsd;import java.awt.*;
import javax.swing.*;class ImageComponent extends JComponent {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);}
}
package com.zsd;import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;public class ImageProxyTestDrive {ImageComponent imageComponent;JFrame frame = new JFrame("CD封面加载器");JMenuBar menuBar; // 菜单栏JMenu menu; // 菜单Hashtable cds = new Hashtable();public static void main (String[] args) throws Exception {ImageProxyTestDrive testDrive = new ImageProxyTestDrive();}public ImageProxyTestDrive() throws Exception{// 构造菜单项用的, key=CD名, value=URLcds.put("三国志:英雄的黎明","http://img3.douban.com/lpic/s4131026.jpg");cds.put("东邪西毒","http://img3.douban.com/lpic/s10425517.jpg");cds.put("龙猫","http://img3.douban.com/lpic/s1668213.jpg");cds.put("Once<曾经>","http://img3.douban.com/lpic/s2821080.jpg");cds.put("太阳照常升起","http://img3.douban.com/lpic/s4714977.jpg");cds.put("蝙蝠侠:侠影之谜","http://img3.douban.com/lpic/s4591642.jpg");cds.put("天国王朝","http://img3.douban.com/lpic/s2595263.jpg");// 设置初始的CD封面URL initialURL = new URL((String)cds.get("Once<曾经>"));// 建立菜单栏menuBar = new JMenuBar();menu = new JMenu("最爱的CD");menuBar.add(menu);frame.setJMenuBar(menuBar);for(Enumeration e = cds.keys(); e.hasMoreElements();) {String name = (String)e.nextElement();JMenuItem menuItem = new JMenuItem(name);menu.add(menuItem); menuItem.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {imageComponent.setIcon(new ImageProxy(getCDUrl(event.getActionCommand())));frame.repaint();}});}// set up frame and menusIcon icon = new ImageProxy(initialURL);imageComponent = new ImageComponent(icon);frame.getContentPane().add(imageComponent);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setSize(800,600);frame.setVisible(true);}URL getCDUrl(String name) {try {return new URL((String)cds.get(name));} catch (MalformedURLException e) {e.printStackTrace();return null;}}
}
小结
现在再来回顾虚拟代理的定义,虚拟代理为什么取名为“虚拟”代理呢?以这个CD封面下载器为例,CD浏览器真正需要的是一个ImageIcon也就是封面图片并要让它显示出来,但是由于图片还在网上不存在本地,所以就用了一个代理ImageProxy来假装就是“ImageIcon”,对于CD浏览器来说,他把这个代理看作和一般的图片一样,让他显示出来。但是刚创建代理Imageproxy时,这个代理根本就没有图片!所以说他是“虚拟”的,挂了个马甲装自己就是图片!一直到下载完图片之后,才真正地把图片显示出来。
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
![](/assets/blank.gif)
【设计模式】学习笔记16:代理模式之虚拟代理(实现CD封面加载器)相关推荐
- 设计模式学习笔记-2 创建者模式-工厂方法模式
设计模式学习笔记-2 创建者模式-工厂方法模式 工厂模式介绍 工厂模式又称工厂方法模式,是一种创建型设计模式,其在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型. 这种设计模式使Java开 ...
- 设计模式学习笔记——状态(State)模式框架
设计模式学习笔记--状态(State)模式框架 @(设计模式)[设计模式, 状态模式, State] 设计模式学习笔记状态State模式框架 基本介绍 状态案例 类图 实现代码 State接口 Day ...
- 设计模式学习笔记——备忘录(Memento)模式
设计模式学习笔记--备忘录(Memento)模式 @(设计模式)[设计模式, 备忘录模式, memento] 设计模式学习笔记备忘录Memento模式 基本介绍 备忘录案例 类图 实现代码 Memen ...
- 设计模式学习笔记——解释器(Interpreter)模式
设计模式学习笔记--解释器(Interpreter)模式 @(设计模式)[设计模式, 解释器模式, Interpreter] 设计模式学习笔记解释器Interpreter模式 基本介绍 解释器案例 类 ...
- 设计模式学习笔记——命令(Command)模式
设计模式学习笔记--命令(Command)模式 @(设计模式)[设计模式, 命令模式, command] 设计模式学习笔记命令Command模式 基本介绍 命令案例 类图 实现代码 Command接口 ...
- 设计模式学习笔记——观察者(Observer)模式
设计模式学习笔记--观察者(Observer)模式 @(设计模式)[设计模式, 观察者模式, Observer] 设计模式学习笔记观察者Observer模式 基本介绍 观察者案例 类图 实现代码 Ob ...
- 设计模式学习笔记——外观(Facade)模式
设计模式学习笔记--外观(Facade)模式 @(设计模式)[设计模式, 外观模式, facade] 设计模式学习笔记外观Facade模式 基本介绍 外观案例 类图 实现代码 Database类 ma ...
- 设计模式学习笔记——访问者(Visitor)模式
设计模式学习笔记--访问者(Visitor)模式 @(设计模式)[设计模式, 访问者模式, visitor] 设计模式学习笔记访问者Visitor模式 基本介绍 访问者案例 类图 实现代码 Visit ...
- 设计模式学习笔记——装饰(Decorator)模式
设计模式学习笔记--装饰(Decorator)模式 @(设计模式)[设计模式, 装饰模式, decorator] 设计模式学习笔记装饰Decorator模式 基本介绍 装饰案例 类图 实现代码 Dis ...
最新文章
- Window编程主函数详解
- 10 个最值得 Python 新人练手的有趣项目 | 赠书
- Flex Builder 2 注册码
- 学校做计算机教室锐捷,锐捷云课堂:让学生爱上每一节课
- 第二十二章 李逵为什么不可爱
- 网易易盾李雨珂:服务性能+算法确定性优化,迎接5G时代内容安全爆发式流量增长...
- kali之metasploit基本使用
- python实例[判断操作系统类型]
- [3.3训练赛]One-Dimensional(矩阵快速幂),Freda的迷宫(无向图强连通分量+并查集),一道防AK好题
- C++输入一个整数后接着输入字符串
- mysql数据库输出数据语法错误_获取RDS-Mysql数据语法错误
- 找工作?最容易遇到的Java面试题
- Mendeley--免费的文献管理工具,给论文自动插入参考文献
- 一套图 搞懂“时间复杂度”
- 1.U3D和U3D安装介绍
- Event-triggered MPC Design for Distributed Systems With Network Communications
- Vue2.js:v-click-outside自定义指令和vue-click-outside监听鼠标点击元素外部区域事件
- Unreal Engine 4(虚幻UE4)GameplayAbilities 插件入门教程(三)技能标签(Ability Tags)...
- Java中Math函数的用法
- DOCTYPE 的作用是什么
热门文章
- 聚乙烯吡咯烷酮PVP纳米纤维膜|多孔PVP纳米纤维薄膜-孔径20um-齐岳在线
- CSM5150SG是国内第一颗做ESOP8封装大电流的40V耐压LDO
- Java和c++的区别!
- 三步搞定oracle 11G 导出的pmd文件,导入oracle 12C数据库中
- wget安装及问题解决
- php parse url,详解php parse_url()函数的定义与用法
- 解决网页背景图片高度无法达到100%平铺界面问题
- 大势所趋——区块链(Python代码实现)
- 如何提高笔试做题准确率和解题速度?
- 在家办公都要半个多月了,快要逼疯了,就再谈谈这个在家办公的问题?