logo资料库

java实现天气预报(解释+源代码).pdf

第1页 / 共8页
第2页 / 共8页
第3页 / 共8页
第4页 / 共8页
第5页 / 共8页
第6页 / 共8页
第7页 / 共8页
第8页 / 共8页
资料共8页,全文预览结束
实现 Java Yahoo 天气预报客户端 吴亚峰 刘 佳 李志昕 摘 要: 详细介绍了如何结合使用 JavaSE 中自带的 JAXP 以及 Yahoo 提供的天气预报 XML 信息服务来实现桌面版的 Yahoo 天气预报客户端。 通过实际案例的开发, 向读者介绍了如何 使用 Java 获取网络上的 XML 文档, 以及如何使用 JAXP 对 XML 文档进行解析。 关键词: XML; JAXP; Yahoo; 天气预报 1 Yahoo 天气预报 Yahoo 作为最大的中文门户网站之一 提供了种类繁多的 , 各种信息服务 , 非常值得注意的是 , Yahoo 其中也包括了非常 实用的天气 预 报 信 息 服 务 。 提供的天气预报信息不但可以通过 登 录 Yahoo 的网站 浏 览 , 也 可 以 获 取 特 定 格 式 的 文 档 自 XML 行解析 。 有了第二种天气预报服务 , 就可以自己开发天气预报 的 客 户 端 软 件 , Web 应用中 。 或 把 天 气 预 报 功 能 嵌 入 到 自己 的 桌 面 软 件 或 获 取 Yahoo 天 气 预 报 的 XML 文 档 非 常 简 单 , 只 要 使 用 如 下格式的 URL 即可 : http://xml.weather.yahoo.com/forecastrss?u=c&p=CHXX0008 其中查询参数 若摄氏度则为 表示温度单位 华氏 u , 度则为 是一个 数字 , 查询参数 “f”。 p 位长度的字符串 8 表示不同的城市 , 例如 表示地点 后跟城市 代码 。 , 前四位固定为 “c”, 城市代码 “CHXX”, 表示北京 , 后四位为 常见的城 。 , “0008” 市代码如表 所列 。 1 代码 CHXX0008 CHXX0116 CHXX0037 CHXX0138 北京 上海 广州 武汉 表 1 城市代码 城市 代码 城市 CHXX0044 CHXX0502 CHXX0131 CHXX0321 杭州 海口 唐山 扬州 输 入 了 上 述 的 URL 京地区天气预报信息的 后 , 就 可 以 获 得 Yahoo 提 供 的 当 天 北 XML 文档 , 其基本内容如下 : 48 2009. 11 Sun, 06 Jul 2008 3:00 pm CST 上 述 文 档 中 包 含 了 当 时 的 天 气 情 况 信 息 当 天 以 及 明 天 、 的天气预报信息 , 详细说明如下所列 : (1) yweather:wind 标 记 中 的 chill 属 性 表 示 当 前 的 风 冷 热 系数 , direction 属性表示当前的风向 , speed (2) yweather:atmosphere 标记中 的 humidity 表示当前的风速 。 属 性 表 示 当 前 的 湿 度 , visibility 当前的气压 。 属 性 表 示 当 前 的能 见 度 , pressure 属 性 表 示 (3) yweather:astronomy 标 记 中 的 出时间 , sunset 属性表示当天日落时间 sunrise 。 属 性 表 示 当 天 日 (4) pubDate 标记中的内容是天气预报的发布时间 。 (5) yweather:condition 标 记 中 的 code 属 性 表 示 当 前 的 天 气情况代码 , temp 属性表示当前温度 。 两 个 (6) yweather:forecast 标 记 中 包 含 的 分 别 是 今 天 与 明 天的天气预报信息 其中 , date 属性表示日期 , low 属性表示 最 低 温 度 , high 属 性 表 示 最 高 温 度 , code 属 性 表 示 天 气 情 况 代 码 。
2 案例功能 将 结 合 Yahoo 的简单使用 , 界面进行简单的介绍 API fox XML Processing) 能 2.1 程序界面 、 。 天 气 预 报 客 户 端 的 开 发 来 介 绍 JAXP (Java 下面首先对本软件的功 网络与通信 CHXX0116上海 CHXX0037广州 CHXX0138武汉 程序中主要包含两个窗体 , 第一个用于选择天气预报的城 市 如图 ( 1 所示 ), 所示 )。 2 第二个用来显示获取的天气预报信息 如图 ( CHXX0044杭州 图 1 城市选择窗口 CHXX0502海口 CHXX0131唐山 CHXX0321扬州 使用 XML 要修改源代码 文档的 好 处 是 , 只需要在 XML , 有了记录城市 信 息 的 未 来 需 要 添 加 新 的 城 市 时 不 需 中添加新的 元素即可 。 文 档 后 就 可 以 对 城 市 选 择 窗 体 cityItem 类 YahooWeatherFramePre 其代码框架如下 : , XML 进行开发了 图 2 天气预报信息显示窗口 2.2 软件实现的功能 程 序 启 动 后 首 先 显 示 的 是 如 图 (1) 用户可以在其中选择需要的城市 所 示 的 城 市 选 择 窗 1 并按下 , “ 程 序 通 过 网 络 连 接 确定 ” 按钮 。 的 服 务 Yahoo 按 下 确 定 按 钮 后 (2) 获取所需的天气预报 , XML 文档 。 口 , 器 , 获取 (3) 今明两天的天气预报信息显示在界面上 XML , 文档后 软件进行解析 , 息 3 城市选择窗体的开发 并将当前天气信 , 。 城 市 选 择 窗 体 的 主 要 功 能 就 是 让 用 户 选 择需 要 天 气 预 报 的城市 , 其核心就是供城市选择的下拉列表框 为了方便维护 。 以及程序的可扩展性考虑 , 下拉列表中的城市信息将从一个自 定义的 文档 XML CityList.xml 中加载 , 其基本内容如下 : CHXX0008北京 package wyf; import java.util.*; import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.xml.parsers.*; import org.w3c.dom.*; import java.io.*; import java.net.*; public class YahooWeatherFramePre extends JFrame{ Image image;//窗体图标 JLabel jl=new JLabel("请选择城市"); //城市选择下拉列表 JComboBox jcb=new JComboBox(); JButton jb=new JButton("确定"); //用来封装每个城市名称及代码的内部类 public static class CityItem{ String cname;//城市名称 String ccode;//城市代码 // CityItem 内部类构造器 public CityItem(String cname,String ccode) {this.cname=cname; this.ccode=ccode;} //重写 toString 方法 @Override public String toString(){return cname;} } // YahooWeatherFramePre 类构造器 public YahooWeatherFramePre() { //对标题和 logo 图片进行初始化 this.setTitle("Yahoo 天气预报客户端"); 2009. 2009. 11 49
image=new ImageIcon("img/ico.png").getImage(); this.setIconImage(image); //对界面中的控件进行摆放 this.setLayout(new FlowLayout(FlowLayout.LEFT,10,6)); jl.setPreferredSize(new Dimension(200,20)); this.add(jl); jcb.setPreferredSize(new Dimension(150,20)); this.add(jcb); jb.setPreferredSize(new Dimension(60,20)); this.add(jb); //对城市列表初始化 this.initCityList(); //为“确定”按钮添加监听器 jb.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e) { //获取当前选中的城市 CityItem currCI = (CityItem)jcb.getSelectedItem(); String selectedCityCode = currCI.ccode; //未来在此处添加创建天气预报信息显示 //窗口的代码…… YahooWeatherFramePre.this.dispose(); } } ); //设置窗体首次出现的大小和位置 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); int centerX=screenSize.width/2;//屏幕中央 x 坐标 int centerY=screenSize.height/2; //屏幕中央 y 坐标 int w=250;//本窗体宽度 int h=100;//本窗体高度 //设置窗体出现在屏幕中央 this.setBounds(centerX-w/2,centerY-h/2-100,w,h); this.setVisible(true); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setResizable(false);//设置窗体不可修改大小 } //从 CityList.xml 文件中加载城市列表 public void initCityList(){} //主方法 public static void main(String args[]) {new YahooWeatherFramePre();} } 上 述 代 码 中 图 片 , “ImageIcon (" img/ico.png") ” 图 片 文 件 存 放 到 因 此 要 将 ico.png 文 件 夹 放 置 在 class 包 所 在 目 录 下 , 加 载 了 窗 体 的 文 件 夹 下 img , 否 则 程 序 不 能 正 确 执 logo img 行 。 在 完 成 了 代 码 框 架的 开 发 后 就 可 以 开 发 加 载 城 市 列 表 文档 XML CityList.xml 的 initCityList 方法了 , 其代码如下 : public void initCityList() 50 2009. 11 { try { // 为解析 XML 文件创建 DOM 对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); //解析 XML 文件 Document doc = builder.parse(new File("CityList.xml")); // 规格化 doc.normalize(); //解析城市列表 NodeList cityItems = doc.getElementsByTagName("cityItem"); int cityCount=cityItems.getLength(); CityItem[] cia=new CityItem[cityCount]; for(int i=0;i
new Font("楷体 _GB2312",Font.PLAIN,18); //左侧显示详细天气情况的面板 JPanel jpz=new JPanel(); //右上侧显示今天天气预报的面板 JPanel jps=new JPanel(); //右下侧显示明天天气预报的面板 JPanel jpx=new JPanel(); JsplitPane jspy = new JSplitPane( JSplitPane.VERTICAL_SPLIT,jps,jpx); JSplitPane jspz = new JSplitPane( JSplitPane.HORIZONTAL_SPLIT,jpz,jspy); //当前天气情况的各个显示标签 JLabel jlTodayImg=new JLabel();//天气情况图片 JLabel jlTodayTitle=new JLabel();//天气总情况描述 JLabel jlTodayDegree=new JLabel();//当前气温 JLabel jlTodayChill=new JLabel();//当前风冷热系数 JLabel jlTodaySpeed=new JLabel();//当前风速 JLabel jlTodayDirection=new JLabel();//当前风向 JLabel jlTodayHumidity=new JLabel();//当前湿度 JLabel jlTodayPressure=new JLabel();//当前气压 JLabel jlTodayVisibility=new JLabel();//当前能见度 JLabel jlTodaySunrise=new JLabel();//日出时间 JLabel jlTodaySunset=new JLabel();//日落时间 JLabel jlTodayPublishTime=new JLabel();//发布时间 //今天天气预报情况的各个显示标签 JLabel jlTomorrowTime=new JLabel();//今天时间 //今天情况图片 JLabel jlTomorrowImg=new JLabel(); //今天最高温度 JLabel jlTomorrowHigh=new JLabel(); //今天最低温度 JLabel jlTomorrowLow=new JLabel(); //明天天气预报情况的各个显示标签 JLabel jlDATTime=new JLabel();//明天时间 JLabel jlDATImg=new JLabel();//明天情况图片 JLabel jlDATHigh=new JLabel();//明天最高温度 JLabel jlDATLow=new JLabel();//明天最低温度 public YahooWeatherFrame(String cityCode, Image image){ //对界面进行初始化 this.initWeatherFrame(image); //未来添加解析天气并填充到界面代码…… //设置窗体首次出现的大小和位置 Dimension screenSize= Toolkit.getDefaultToolkit().getScreenSize(); int centerX=screenSize.width/2;//屏幕中央 x 坐标 int centerY=screenSize.height/2;//屏幕中央 y 坐标 int w=620;//本窗体宽度 int h=358;//本窗体高度 //设置窗体出现在屏幕中央 this.setBounds(centerX-w/2,centerY-h/2-100,w,h); this.setVisible(true); 网络与通信 //设置窗体的默认关闭动作 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setResizable(false); } //对界面进行初始化的方法 public void initWeatherFrame(Image image){} } 在完成了 YahooWeatherFrame 类框架的开发后 , 方 法 了 就可以开 其 代 码 , 发对界面控件进 行 初 始 化 的 initWeatherFrame 如下 : public void initWeatherFrame(Image image) { //对标题和 logo 图片进行初始化 this.setTitle("Yahoo 天气预报客户端"); this.setIconImage(image); //设置三个面板的背景色 jpz.setBackground(new Color(231,231,231)); jps.setBackground(new Color(252,237,180)); jpx.setBackground(new Color(176,237,255)); //对总界面进行初始化 this.add(jspz,BorderLayout.CENTER); jspz.setDividerLocation(300); jspy.setDividerLocation(165); jspz.setDividerSize(0); jspy.setDividerSize(0); //对本日天气界面进行初始化 jpz.setLayout(null); jlTodayImg.setBounds(50,5,175,120); jpz.add(jlTodayImg);jlTodayTitle.setFont(font); jlTodayTitle.setBounds(5,130,260,20); jpz.add(jlTodayTitle);jlTodayDegree.setFont(font); jlTodayDegree.setBounds(5,150,260,20); jpz.add(jlTodayDegree);jlTodayChill.setFont(font); jlTodayChill.setBounds(150,150,150,20); jpz.add(jlTodayChill);jlTodaySpeed.setFont(font); jlTodaySpeed.setBounds(5,170,180,20); jpz.add(jlTodaySpeed);jlTodayDirection.setFont(font); jlTodayDirection.setBounds(190,170,170,20); jpz.add(jlTodayDirection); jlTodayHumidity.setFont(font); jlTodayHumidity.setBounds(5,190,170,20); jpz.add(jlTodayHumidity); jlTodayPressure.setFont(font); jlTodayPressure.setBounds(100,190,170,20); jpz.add(jlTodayPressure); jlTodayVisibility.setFont(font); jlTodayVisibility.setBounds(5,210,170,20); jpz.add(jlTodayVisibility); jlTodaySunrise.setFont(font); jlTodaySunrise.setBounds(5,230,150,20); jpz.add(jlTodaySunrise); 2009. 2009. 11 51
jlTodaySunset.setFont(font); jlTodaySunset.setBounds(5,250,150,20); jpz.add(jlTodaySunset); jlTodayPublishTime.setFont(font); jlTodayPublishTime.setBounds(5,270,290,20); jpz.add(jlTodayPublishTime); //对明日天气界面进行初始化 jps.setLayout(null); jlTomorrowTime.setFont(font); jlTomorrowTime.setBounds(5,5,300,20); jps.add(jlTomorrowTime); jlTomorrowImg.setBounds(55,20,175,120); jps.add(jlTomorrowImg); jlTomorrowHigh.setFont(font); jlTomorrowHigh.setBounds(5,140,175,20); jps.add(jlTomorrowHigh); jlTomorrowLow.setFont(font); jlTomorrowLow.setBounds(155,140,175,20); jps.add(jlTomorrowLow); //对后天天气界面进行初始化 jpx.setLayout(null); jlDATTime.setFont(font); jlDATTime.setBounds(5,5,300,20); jpx.add(jlDATTime); jlDATImg.setBounds(55,20,175,120); jpx.add(jlDATImg);jlDATHigh.setFont(font); jlDATHigh.setBounds(5,140,175,20); jpx.add(jlDATHigh);jlDATLow.setFont(font); jlDATLow.setBounds(155,140,175,20); jpx.add(jlDATLow); } 完成了上述代码的开发后将 译 , 并在 YahooWeatherFramePre YahooWeatherFrame 类代码框架中 未来在此处添 “ 加创建天气预报信息显示窗口的代码 ……” 处添加如下代码 : new YahooWeatherFrame(selectedCityCode, image); 添加完上述代码后 再次编译 , YahooWeatherFramePre 类并 运行 , 此时再点击 确定 “ ” 按钮就可以看到天 气 预 报 窗 体 了 , 不过此时程序还不能从网络中获取天气预报信息解析显示 5 信息解析类 。 完成了两个窗体类的开发后 , 就可以进行天气预报信息解 析类 YahooWeather 的开发了 , 其代码框架如下 : package wyf; import javax.xml.parsers.*; import org.w3c.dom.*; import java.io.*;import java.net.*; import javax.swing.*;import java.text.*; import java.util.*; public class YahooWeather { 52 2009. 11 //获取天气信息并解析填充的方法 public static void parseWeather (YahooWeatherFrame ywf, String cityCode) {} //将天气情况代码转换为文字信息的方法 public static String fromCodeToText(int code){} //将风向角度转化为文字信息的方法 public static String fromDegreeToDirectionStr(int degree){} } 从上述代码中可以看出 中提供了用于获取解析天气的 , YahooWeather 个静态方法 3 是一个工具类 其 , 首先应该开发将 。 风向角度转化为文字信息的 fromDegreeToDirectionStr 方 法 , 其 代码如下 : public static String fromDegreeToDirectionStr(int degree) if(degree>337 && degree<=360){return "北风";} else if(degree>=0 && degree<=22){return "北风";} else if(degree>22 && degree<=67){return "东北风";} else if(degree>67 && degree<=112){return "东风";} else if(degree>112 && degree<=157){return "东南风";} else if(degree>157 && degree<=202){return "南风";} else if(degree>202 && degree<=247){return "西南风";} else if(degree>247 && degree<=292){return "西风";} else if(degree>292 && degree<=337){return "西北风";} else {return "错误的方向值";} { } 开发完将风向角度转化为文字信息的 fromDegreeToDirection 就 可 以 开 发 将 天 气 情 况 代 码 转 换 为 文 字信 息 的 方 法 后 , Str public static String fromCodeToText(int code){ switch(code){ case 0: return "龙卷风";case 1: return "热带风暴"; case 2: return "飓风";case 3: return "雷暴雨"; case 4: return "雷雨";case 5: return "雨夹雪"; case 6: return "雨夹冰雹";case 7: return "雪夹冰雹"; case 8: return "冻毛毛雨";case 9: return "毛毛雨"; case 10: return "冻雨";case 11: return "阵雨"; case 12: return "阵雪";case 13: return "雪小雪"; case 14: return "小雪骤雨";case 15: return "风雪"; case 16: return "雪";case 17: return "冰雹"; case 18: return "雨夹雪";case 19: return "尘"; case 20: return "雾";case 21: return "霾"; case 22: return "黑烟";case 23: return "狂风"; case 24: return "风";case 25: return "冷"; case 26: return "多云"; case 27: return "夜间大部多云"; case 28: return "日间大部多云"; case 29: return "夜间部分多云"; case 30: return "日间部分多云"; 类进行编 fromCodeToText 方法了 , 其代码如下 :
case 31: return "夜间晴朗";case 32: return "日间晴朗"; case 33: return "夜间清晰";case 34: return "日间清晰"; case 35: return "雨夹雹";case 36: return "热"; case 37: return "局部雷阵雨";case 38: return "零星雷阵雨"; case 39: return "零星雷阵雨";case 40: return "零星暴雨"; case 41: return "大雪";case 42: return "零星暴雪"; case 43: return "大雪";case 44: return "部分多云"; case 45: return "雷阵雨";case 46: return "阵雪"; case 47: return "局部地区雷阵雨"; case 3200: default: return "没有此代码"; } return "不可用"; } 在两个用于信息转换的辅助方法都开发完成后 就可以开 , 发用于获取并解析显示天气 文档的 XML parseWeather 方法了 , 其代码如下 : public static void parseWeather (YahooWeatherFrame ywf,String cityCode){ try{ //为解析 XML 文件创建 DOM 对象 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder= factory.newDocumentBuilder(); //远程 URL 解析 URL url=new URL("http://xml.weather.yahoo."+ "com/forecastrss?u=c&p="+cityCode); Document doc=builder.parse(url.openStream()); doc.normalize(); //规格化 //解析天气预报发布时间 NodeList links = doc.getElementsByTagName("pubDate"); String dateStr = links.item(0).getFirstChild().getNodeValue(); SimpleDateFormat sdf=new SimpleDateFormat( "EEE, dd MMM yyyy K:mm aa zzz",Locale.US); Date date=sdf.parse(dateStr); Calendar cd=Calendar.getInstance(); cd.setTime(date); dateStr=(cd.get(Calendar.YEAR))+"年" +(cd.get(Calendar.MONTH)+1)+"月" +(cd.get(Calendar.DATE))+"日" +cd.get(Calendar.HOUR_OF_DAY)+"时" +((cd.get (Calendar.MINUTE) >9)?cd.get (Calendar. MINUTE)+"":"0"+cd.get(Calendar.MINUTE))+"分"; ywf.jlTodayPublishTime.setText("发布时间:"+dateStr); //解析风相关信息 links =doc.getElementsByTagName("yweather:wind"); NamedNodeMap nnm=links.item(0).getAttributes(); ywf.jlTodayChill.setText("风冷热系数:" +nnm.getNamedItem("chill").getNodeValue()); ywf.jlTodaySpeed.setText("风速:" 网络与通信 +nnm.getNamedItem("speed").getNodeValue() +"公里/小时"); String directionStr= nnm.getNamedItem("direction").getNodeValue(); int directionInt=Integer.parseInt(directionStr); ywf.jlTodayDirection.setText("风向:" +fromDegreeToDirectionStr(directionInt)); //解析大气相关信息 links =doc.getElementsByTagName( "yweather:atmosphere"); nnm=links.item(0).getAttributes(); ywf.jlTodayHumidity.setText("湿度:"+ nnm.getNamedItem("humidity").getNodeValue()+"%"); ywf.jlTodayPressure.setText("气压:"+ nnm.getNamedItem("pressure").getNodeValue()+"毫巴"); ywf.jlTodayVisibility.setText("能见度:"+ ((int)Double.parseDouble (nnm.getNamedItem ("visibility"). getNodeValue())*100)/10000.0+"公里"); //解析天文学有关信息 links =doc.getElementsByTagName("yweather: astronomy"); nnm=links.item(0).getAttributes(); ywf.jlTodaySunrise.setText("日出时间:" +nnm.getNamedItem ("sunrise").getNodeValue (). replaceAll("\\s","")); ywf.jlTodaySunset.setText("日落时间:+ nnm.getNamedItem("sunset").getNodeValue().replaceAll(" \\s","")); //解析当前天气相关信息 links =doc.getElementsByTagName("yweather:condition"); nnm=links.item(0).getAttributes(); int code= Integer.parseInt( nnm.getNamedItem("code").getNodeValue()); ywf.jlTodayTitle.setText("当前天气情况:" +fromCodeToText(code)); ImageIcon ii=new ImageIcon("img\\"+code+".png"); ywf.jlTodayImg.setIcon(ii); ywf.jlTodayDegree.setText("当前气温:"+ nnm.getNamedItem("temp").getNodeValue()+"℃") //解析天气预报信息 links =doc.getElementsByTagName("yweather:forecast"); //解析今天天气预报信息 nnm=links.item(0).getAttributes(); code =Integer.parseInt (nnm.getNamedItem ("code"). getNodeValue()); ii=new ImageIcon("img\\"+code+".png"); ywf.jlTomorrowImg.setIcon(ii); sdf=new SimpleDateFormat("dd MMM yyyy",Locale.US); date=sdf.parse( nnm.getNamedItem("date").getNodeValue()); cd=Calendar.getInstance(); cd.setTime(date); 2009. 2009. 11 53
dateStr=(cd.get(Calendar.YEAR))+"年" +(cd.get(Calendar.MONTH)+1)+"月" +(cd.get(Calendar.DATE))+"日"; ywf.jlTomorrowTime.setText("今天:"+dateStr+" " +fromCodeToText(code)); ywf.jlTomorrowHigh.setText("最高温度:"+ nnm.getNamedItem("high").getNodeValue()+"℃"); ywf.jlTomorrowLow.setText("最低温度:"+ nnm.getNamedItem("low").getNodeValue()+"℃"); //解析明天天气预报信息 nnm=links.item(1).getAttributes(); code=Integer.parseInt( nnm.getNamedItem("code").getNodeValue()); ii=new ImageIcon("img\\"+code+".png"); ywf.jlDATImg.setIcon(ii); sdf=new SimpleDateFormat("dd MMM yyyy",Locale.US); date =sdf.parse (nnm.getNamedItem ("date").getNodeValue ()); cd=Calendar.getInstance(); cd.setTime(date); dateStr=(cd.get(Calendar.YEAR))+"年" +(cd.get(Calendar.MONTH)+1)+"月" +(cd.get(Calendar.DATE))+"日"; ywf.jlDATTime.setText("明天:"+dateStr +" "+fromCodeToText(code)); ywf.jlDATHigh.setText("最高温度:"+ nnm.getNamedItem("high").getNodeValue()+"℃"); ywf.jlDATLow.setText("最低温度:"+ nnm.getNamedItem("low").getNodeValue()+"℃"); }catch(Exception e){e.printStackTrace();} } 此方法中使用 JAXP 中的 DOM 方式对从网络上获取 的 天 气信息 XML 文档进行解析 , 各个控件进行显示 。 并 将 解 析 的 结果 填 充 到 界 面 中 的 图 3 天气情况图片 6 程序的打包与发布 完成了所有代码的编写后 就可以将程序打包发布了 在 , , 本案 例 中 使 用 JavaSE 6.0 自 带 的 jar 工 具 将 应 用 程 序 打 包 成 可 执行 包发布 读者按如下步骤操作即可 , 在 进 行 打 包 之 前 首 先 要编 写 一 个 名 称 为 。 jar 首 先 , 的 清 单 文 件 , 用 来 对 应 用 程 序进 行 描 述 其 内 , MANIFEST.MF 容如下 : Mainfest-Version: 1.0 Main-Class: wyf.YahooWeatherFramePre Created-By: 1.6.0(Sun Microsystems Inc.) 请读者特别注意的是 , 这个文件的格式非常重要 每一行 , 要 顶 格 写 , 前 面 不 能 留 空 格 同 时 后面一定要留一个空格 , 。 “:” 大小写也不能出错 , 前 面 不 能 有 空 格 , 。 其次 在的目录 , , 将 MANIFEST.MF 文件保存到编译后 文件包所 class 在命令行窗口执行如下命令 执行结果如图 所示 。 4 , path=C:\Program Files\Java\jdk1.6.0\bin 要 特 别 注 意 的 是 , 在 显 示 天 气 情 况 时 为 了生 动 形 象 对每种不同的天气情况代码各提供一幅图片 用了图片 。 存 放 在 文 件 夹 中 , img 图 片 的 名 称 即 为 情 况 代 码 , 采 , 统一 所 3 , 如 图 另外要注意将 文件夹与 img class 文件包放在同一个目录 图 4 制作可执行 jar 包的过程 jar cvfm YWC.jar mainfest.mf wyf/* 请 读 者 注 意 笔 者 机 器 上 “C: , 读者需要根据自己机器的情况对路径进行相应 JavaSE 6.0 的 安 装 目 录 为 \Java\jdk1.6.0”, 修改 。 第三 , jar 包制作完毕后 , 可以通过运行如下命令启 Yahoo 天气预报客户端应用程序 。 path=C:\Program Files\Java\jdk1.6.0\bin java -jar YWC.jar 下转第 ( 页 ) 64 示 。 中 , 否则程序无法正确运行 完 成 了 YahooWeather 。 类 的 开 发 后 YahooWeatherFrame 到界面代码 ……” 类 代 码 框 架 中 处添加如下代码 将 其 进 行 编 译 并 在 , , 未 来 添 加 解 析 天 气并 填 充 “ : 类 并 程 , , YahooWeather.parseWeather(this,cityCode); 添加完上述代码后 再次编译 , YahooWeatherFrame 运行 YahooWeatherFramePre 类 。 此时如同图 图 2 所示 1、 序就能够从网络中获取对应城市的天气预报信息并显示在界面 上了 。 54 2009. 11
storage = cvCreateMemStorage(0); cvNamedWindow( "人脸检测", CV_WINDOW_AUTOSIZE ); //创建窗口 radius = cvRound ((r ->width + r ->height) *0.25*scale); cvCircle( img, center, radius, color[0], 3, 8, 0 ); //调用人脸检与标示事件 //如果图片存在则分析并显示结果,否则退出程序 if(src) detect_and_draw(src); cvReleaseImage(&src); cvReleaseMemStorage( &storage ); } else { AfxMessageBox(L"无法加载分类器,请确认后重试! "); } cvReleaseHaarClassifierCascade( &cascade ); } void CFaceDetectionView::detect_and_draw(IplImage *img) //人脸检与标示事件 { static CvScalar color[] = {0,0,255}; //用于设置标示图像中人脸的颜色 double scale = 1.3; IplImage* gray = cvCreateImage ( cvSize (img ->width, img->height), 8, 1 ); IplImage* small_img = cvCreateImage ( cvSize ( cvRound (img->width/scale),cvRound (img->height/scale)),8,1 ); int i; cvCvtColor( img, gray, CV_BGR2GRAY ); cvResize( gray, small_img, CV_INTER_LINEAR ); cvEqualizeHist( small_img, small_img ); cvClearMemStorage( storage ); if( cascade ) //检测人脸 { CvSeq* faces = cvHaarDetectObjects ( small_img, cascade, storage, 1.1, 2, 0, cvSize(30, 30) ); for( i = 0; i < (faces ? faces->total : 0); i++ ) { CvRect* r = (CvRect*)cvGetSeqElem( faces, i ); CvPoint center; int radius; center.x = cvRound((r->x + r->width*0.5)*scale); center.y = cvRound((r->y + r->height*0.5)*scale); } } cvShowImage( "人脸检测", img ); cvReleaseImage( &gray ); cvReleaseImage( &small_img ); } 需要注意的是 , 本程序运行时应将分类器文件置于程序目 录下 , 如 果 运 行 的 是 生 成 的 EXE 文 件 , 则 应 将 分 类 器 文 件 与 该 EXE 文件放在同一个目录下 。 图 3 3 运行结果 运 行 该 程 序 , 选 择 人 脸 检 测 菜 单 项 , 弹 出 文 件 打 开 对 话 框 , 选择要检测的图像文件 , 程序就会将检测到的人脸用圆圈 标示出来 , 由 于 光 照 、 如图 所示 。 3 本程序能顺利检测出大部分人脸 遮 挡 和 倾 斜 等 原 因 , 部 分 人 脸 不 能 正 确 检 测 但 另 , 。 外 , 也有一些非人脸部分由于具有人脸的某些特征 也被当成 , 了人脸 这些都是本程序需要改进的部分 。 , 收稿日期 ( : 2009-3-12) 3333333333333333333333333333333333333333333333 上接第 ( 页 ) 54 由于本应用程序使用了资源图片 因此在运行可执行 , 包时需要将 包与 jar img 文件夹 放 在 同 一 个 目 录 下 另 外 , 。 jar 如 果 读 者 机 器 上 的 JavaSE 安 装 完 全 正 确 的 话 , 也 可 以 通 过 鼠 标 文件启动此应用程序 。 YWC.jar 双击 7 结语 通 过 开 发 Yahoo 天 气 预 报 客 户 端 程 序 读 者 应 该 对 , 64 2009. 11 中 提 供 的 JavaSE 应该了解到使用 JAXP DOM 有 了 一 定 的 了 解 同 时 , 。 读 者 也 提供的天气预报信息服务来丰富自己软 Yahoo 件的功能也是十分方便的 另外 , 。 本案例虽然是桌面版的 获 取 天 气 信 息 并 解 析 的 YahooWeather 类 是 独 立 开 发 的 。 但 , 如 果 有 需 要 读 者 只 要 稍 加 修 改 就 可 以 将 其 与 应 用 程 序 结 合 Web Web 应用轻松拥有天气预报的功能 。 , 让自己的 使用 , ( 收稿日期 : 2009-2-8)
分享到:
收藏