﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-weibogao-随笔分类-software development</title><link>http://www.blogjava.net/weibogao/category/10168.html</link><description>my second lifespace</description><language>zh-cn</language><lastBuildDate>Wed, 28 Nov 2007 20:04:32 GMT</lastBuildDate><pubDate>Wed, 28 Nov 2007 20:04:32 GMT</pubDate><ttl>60</ttl><item><title>Hibernate批量处理的性能优化问题</title><link>http://www.blogjava.net/weibogao/archive/2006/12/27/90245.html</link><dc:creator>weibogao</dc:creator><author>weibogao</author><pubDate>Wed, 27 Dec 2006 03:16:00 GMT</pubDate><guid>http://www.blogjava.net/weibogao/archive/2006/12/27/90245.html</guid><wfw:comment>http://www.blogjava.net/weibogao/comments/90245.html</wfw:comment><comments>http://www.blogjava.net/weibogao/archive/2006/12/27/90245.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weibogao/comments/commentRss/90245.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weibogao/services/trackbacks/90245.html</trackback:ping><description><![CDATA[
		<p>
				<br />Hibernate批量处理:</p>
		<p>Hibernate批量处理其实从性能上考虑，它是很不可取的，浪费了很大的内存。从它的机制上讲，Hibernate它是先把符合条件的数据查出来，放到内存当中，然后再进行操作。实际使用下来性能非常不理想,在笔者的实际<br />使用中采用下面的第三种优化方案的数据是:100000条数据插入数据库,主流台式机的配置,需要约30分钟,呵呵,晕倒.</p>
		<p>总结下来有三种来处理以解决性能问题：</p>
		<p>1：绕过Hibernate API ，直接通过 JDBC API 来做，这个方法性能上是比较好的。也是最快的.</p>
		<p>2：运用存储过程。</p>
		<p>3：还是用Hibernate API 来进行常规的批量处理，可以也有变，变就变在，我们可以在查找出一定的量的时候，及时的将这些数据做完操作就</p>
		<p>删掉，session.flush();session.evict(XX对象集); 这样也可以挽救一点性能损失。这个“一定的量”要就要根据实际情况做定量参考了。一般为30-60左右,但效果仍然不理想.</p>
		<p> </p>
		<p> </p>
		<p>1：绕过Hibernate API ，直接通过 JDBC API 来做，这个方法性能上是比较好的，也是最快的。(实例为 更新操作)</p>
		<p> </p>
		<p>Transaction tx=session.beginTransaction(); //注意用的是hibernate事务处理边界</p>
		<p>Connection conn=session.connection(); </p>
		<p>PreparedStatement stmt=conn.preparedStatement("update CUSTOMER as C set C.sarlary=c.sarlary+1 where c.sarlary&gt;1000");</p>
		<p>stmt.excuteUpdate();</p>
		<p>tx.commit(); //注意用的是hibernate事务处理边界 </p>
		<p>这小程序中，采用的是直接调用JDBC 的API 来访问数据库，效率很高。避免了Hibernate 先查询出来加载到内存，再进行操作引发的性能问题</p>
		<p>。 </p>
		<p>2：运用存储过程。但这种方式考虑到易植和程序部署的方便性,不建议使用.(实例为 更新操作)</p>
		<p>如果底层数据库（如Oracle）支持存储过程，也可以通过存储过程来执行批量更新。存储过程直接在数据库中运行，速度更加快。在Oracle数</p>
		<p>据库中可以定义一个名为batchUpdateCustomer()的存储过程，代码如下： </p>
		<p>
				<br />代码内容<br />create or replace procedure batchUpdateCustomer(p_age in number) as <br />begin <br />update CUSTOMERS set AGE=AGE+1 where AGE&gt;p_age; <br />end;  </p>
		<p>
				<br />以上存储过程有一个参数p_age，代表客户的年龄，应用程序可按照以下方式调用存储过程： </p>
		<p>代码内容<br />tx = session.beginTransaction(); <br />Connection con=session.connection(); <br />String procedure = "{call batchUpdateCustomer(?) }"; <br />CallableStatement cstmt = con.prepareCall(procedure); <br />cstmt.setInt(1,0); //把年龄参数设为0 <br />cstmt.executeUpdate(); <br />tx.commit();  </p>
		<p>
				<br />从上面程序看出，应用程序也必须绕过Hibernate API，直接通过JDBC API来调用存储过程。 </p>
		<p>3：还是用Hibernate API 来进行常规的批量处理，可以也有变，变就变在，我们可以在查找出一定的量的时候，及时的将这些数据做完操作就</p>
		<p>删掉，session.flush();session.evict(XX对象集); 这样也可以挽救一点性能损失。这个“一定的量”要就要根据实际情况做定量参考了。。</p>
		<p>(实例为 保存操作)</p>
		<p>业务逻辑为：我们要想数据库插入10 0000 条数据</p>
		<p>tx=session.beginTransaction();</p>
		<p>for(int i=0;i&lt;100000;i++)</p>
		<p>{</p>
		<p>Customer custom=new Customer();</p>
		<p>custom.setName("user"+i);</p>
		<p>session.save(custom);</p>
		<p>if(i%50==0) // 以每50个数据作为一个处理单元，也就是我上面说的“一定的量”，这个量是要酌情考虑的</p>
		<p>{</p>
		<p>session.flush(); </p>
		<p>session.clear();</p>
		<p>}</p>
		<p>}</p>
		<p>这样可以把系统维持在一个稳定的范围....<br /></p>
<img src ="http://www.blogjava.net/weibogao/aggbug/90245.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weibogao/" target="_blank">weibogao</a> 2006-12-27 11:16 <a href="http://www.blogjava.net/weibogao/archive/2006/12/27/90245.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>模式对话框的详细使用说明</title><link>http://www.blogjava.net/weibogao/archive/2006/09/20/70715.html</link><dc:creator>weibogao</dc:creator><author>weibogao</author><pubDate>Wed, 20 Sep 2006 02:27:00 GMT</pubDate><guid>http://www.blogjava.net/weibogao/archive/2006/09/20/70715.html</guid><wfw:comment>http://www.blogjava.net/weibogao/comments/70715.html</wfw:comment><comments>http://www.blogjava.net/weibogao/archive/2006/09/20/70715.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weibogao/comments/commentRss/70715.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weibogao/services/trackbacks/70715.html</trackback:ping><description><![CDATA[
		<p>javascript有许多内建的方法来产生对话框，如：window.alert(), window.confirm(),window.prompt().等。 然而IE提供更多的方法支持对话框。如： <br /><br />　　showModalDialog() (IE 4+ 支持) <br />　　showModelessDialog() (IE 5+ 支持) <br /><br /><br />window.showModalDialog()方法用来创建一个显示HTML内容的模态对话框，由于是对话框，因此它并没有一般用window.open()打开的窗口的所有属性。 <br />window.showModelessDialog()方法用来创建一个显示HTML内容的非模态对话框。 <br /><br />当我们用showModelessDialog()打开窗口时，不必用window.close()去关闭它，当以非模态方式［IE5］打开时， 打开对话框的窗口仍可以进行其他的操作，即对话框不总是最上面的焦点，当打开它的窗口ＵＲＬ改变时，它自动关闭。而模态［ＩＥ４］方式的对话框始终有焦点（焦点不可移走，直到它关闭）。模态对话框和打开它的窗口相联系，因此我们打开另外的窗口时，他们的链接关系依然保存，并且隐藏在活动窗口的下面。 <br /><br />使用方法如下： <br />vReturnvalue = window.showModalDialog(sURL [, vArguments] [, sFeatures]) <br />vReturnvalue = window.showModelessDialog(sURL [, vArguments] [, sFeatures]) <br />参数说明： <br />sURL <br />必选参数，类型：字符串。用来指定对话框要显示的文档的URL。 <br />vArguments <br />可选参数，类型：变体。用来向对话框传递参数。传递的参数类型不限，包括数组等。对话框通过window.dialogArguments来取得传递进来的参数。 <br />sFeatures <br />可选参数，类型：字符串。用来描述对话框的外观等信息，可以使用以下的一个或几个，用分号“;”隔开。 <br />  dialogHeight 对话框高度，不小于１００px，ＩＥ４中dialogHeight 和 dialogWidth 默认的单位是em，而ＩＥ５中是px，为方便其见，在定义modal方式的对话框时，用px做单位。 <br />　　dialogWidth: 对话框宽度。 <br />　　dialogLeft: 距离桌面左的距离。 <br />　　dialogTop: 离桌面上的距离。 <br />　　center: {yes | no | 1 | 0 }：窗口是否居中，默认yes，但仍可以指定高度和宽度。 <br />　　help: {yes | no | 1 | 0 }：是否显示帮助按钮，默认yes。 <br />　　resizable: {yes | no | 1 | 0 } ［ＩＥ５＋］：是否可被改变大小。默认no。 <br />　　status: {yes | no | 1 | 0 } ［IE5+］：是否显示状态栏。默认为yes[ Modeless]或no[Modal]。 <br />  scroll:{ yes | no | 1 | 0 | on | off }：指明对话框是否显示滚动条。默认为yes。 <br /><br />  还有几个属性是用在HTA中的，在一般的网页中一般不使用。 <br />  dialogHide:{ yes | no | 1 | 0 | on | off }：在打印或者打印预览时对话框是否隐藏。默认为no。 <br />  edge:{ sunken | raised }：指明对话框的边框样式。默认为raised。 <br />  unadorned:{ yes | no | 1 | 0 | on | off }：默认为no。 <br /><br />传入参数： <br />要想对话框传递参数，是通过vArguments来进行传递的。类型不限制，对于字符串类型，最大为4096个字符。也可以传递对象，例如： <br /><br />test1.htm <br />==================== <br />&lt;script&gt; <br />  var mxh1 = new Array("mxh","net_lover","孟子E章") <br />  var mxh2 = window.open("about:blank","window_mxh") <br />  // 向对话框传递数组 <br />  window.showModalDialog("test2.htm",mxh1) <br />  // 向对话框传递window对象 <br />  window.showModalDialog("test3.htm",mxh2) <br />&lt;/script&gt; <br /><br />test2.htm <br />==================== <br />&lt;script&gt; <br />  var a = window.dialogArguments <br />  alert("您传递的参数为：" + a) <br />&lt;/script&gt; <br /><br />test3.htm <br />==================== <br />&lt;script&gt; <br />  var a = window.dialogArguments <br />  alert("您传递的参数为window对象，名称：" + a.name) <br />&lt;/script&gt; <br /><br />可以通过window.returnvalue向打开对话框的窗口返回信息，当然也可以是对象。例如： <br /><br />test4.htm <br />=================== <br />&lt;script&gt; <br />  var a = window.showModalDialog("test5.htm") <br />  for(i=0;i&lt;a.length;i++) alert(a[i]) <br />&lt;/script&gt; <br /><br />test5.htm <br />=================== <br />&lt;script&gt; <br />function sendTo() <br />{ <br />  var a=new Array("a","b") <br />  window.returnvalue = a <br />  window.close() <br />} <br />&lt;/script&gt; <br />&lt;body&gt; <br />&lt;form&gt; <br />  &lt;input value="返回" type=button onclick="sendTo()"&gt; <br />&lt;/form&gt; <br /><br />常见问题： <br />1，如何在模态对话框中进行提交而不新开窗口？ <br />如果你 的 浏览器是IE5.5+,可以在对话框中使用带name属性的iframe，提交时可以制定target为该iframe的name。对于IE4+，你可以用高度为0的frame来作：例子， <br /><br />test6.htm <br />=================== <br />&lt;script&gt; <br />  window.showModalDialog("test7.htm") <br />&lt;/script&gt; <br /><br />test7.htm <br />=================== <br />if(window.location.search) alert(window.location.search) <br />&lt;frameset rows="0,*"&gt; <br />  &lt;frame src="about:blank"&gt; <br />  &lt;frame src="test8.htm"&gt; <br />&lt;/frameset&gt; <br /><br />test8.htm <br />=================== <br />&lt;form target="_self" method="get"&gt; <br />&lt;input name=txt value="test"&gt; <br />&lt;input type=submit&gt; <br />&lt;/form&gt; <br />&lt;script&gt; <br />if(window.location.search) alert(window.location.search) <br />&lt;/script&gt; <br />2,可以通过http://servername/virtualdirname/test.htm?name=mxh方式直接向对话框传递参数吗？ <br />答案是不能。但在frame里是可以的。 <br /><br />－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－ <br />另外： <br /><a href="http://www.csdn.net/" target="_blank">http://www.csdn.net/</a><br />本人整理 <br /><br />问： <br />1.模态窗口的打开 <br />2.模态窗口的关闭 <br />3.模态窗口的传递参数。 <br />4.其他。。。。 <br /><br />hgknight(江雨.net)答： <br />1.window.showModalDialog("DialogPage.aspx","newwin","dialogHeight: 200px; dialogWidth: 150px; dialogTop: 458px; dialogLeft: 166px; edge: Raised; center: Yes; help: Yes; resizable: Yes; status: Yes;"); <br /><br />2.window.close(); <br /><br />3.传值 <br />ParentPage.aspx: <br />window.showModalDialog("DialogPage.aspx?para1=aaa¶2=bbb"); <br /><br />DialogPage.aspx: <br />string str1=Request.QueryString["para1"].toString(); <br />string str2=Request.QueryString["para2"].toString(); <br /><br />返回值 <br />DialogPage.aspx: <br />window.returnvalue="aaa"; <br /><br />ParentPage.aspx: <br />var str=window.showModalDialog("DialogPage.aspx"); <br /><br />4. <br />aspx页面在showmodeldialog情况下为什么一提交就重新打开一个页面? <br />showmodaldialog打开的页面中在&lt;head&gt;&lt;/head&gt;之间加入一行：&lt;base target="_self"&gt; <br />－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－ <br />snowjin78(方圆) <br />以前，我也问过此类问题，现把收获贴如下（当然好多东西都是别人告诉我的）： <br />最好不要用Response.Write(  "  &lt;script....  &lt;/script  &gt;  ")这样的方法注册客户端脚本，而应该用Page.RegisterStartupScript或Page.RegisterClientScriptBlock方法来注册. <br />Page.RegisterClientScriptBlock：   <br />在  Page  对象的    &lt;form  runat=  server  &gt;  元素的开始标记后立即发出客户端脚本   <br />Page.RegisterStartupScript:   <br />该方法在  Page  对象的    &lt;form  runat=  server  &gt;  元素的结束标记之前发出该脚本 <br /><br />客户端代码有两个问题，第一是把window写成了Window，javascript是严格区分大小写的，用Window是肯定会出错的；第二个问题是设置对话框的宽度用dialogWidth，高度用dialogHeight，而不是height和width。！</p>
<img src ="http://www.blogjava.net/weibogao/aggbug/70715.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weibogao/" target="_blank">weibogao</a> 2006-09-20 10:27 <a href="http://www.blogjava.net/weibogao/archive/2006/09/20/70715.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>web页面打印的相关脚本</title><link>http://www.blogjava.net/weibogao/archive/2006/07/13/57929.html</link><dc:creator>weibogao</dc:creator><author>weibogao</author><pubDate>Thu, 13 Jul 2006 03:25:00 GMT</pubDate><guid>http://www.blogjava.net/weibogao/archive/2006/07/13/57929.html</guid><wfw:comment>http://www.blogjava.net/weibogao/comments/57929.html</wfw:comment><comments>http://www.blogjava.net/weibogao/archive/2006/07/13/57929.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weibogao/comments/commentRss/57929.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weibogao/services/trackbacks/57929.html</trackback:ping><description><![CDATA[
		<p style="LINE-HEIGHT: 150%">
				<font class="f14" id="zoom" style="FONT-SIZE: 14px">1、控制"纵打"、 横打”和“页面的边距。 <br />（1）&lt;script defer&gt; <br />function SetPrintSettings() { <br />　// -- advanced features <br />　factory.printing.SetMarginMeasure(2) // measure margins in inches <br />　factory.SetPageRange(false, 1, 3) // need pages from 1 to 3 <br />　factory.printing.printer = "HP DeskJet 870C" <br />　factory.printing.copies = 2 <br />　factory.printing.collate = true <br />　factory.printing.paperSize = "A4" <br />　factory.printing.paperSource = "Manual feed" <br /><br />　// -- basic features <br />　factory.printing.header = "This is MeadCo" <br />　factory.printing.footer = "Advanced Printing by ScriptX" <br />　factory.printing.portrait = false <br />　factory.printing.leftMargin = 1.0 <br />　factory.printing.topMargin = 1.0 <br />　factory.printing.rightMargin = 1.0 <br />　factory.printing.bottomMargin = 1.0 <br />} <br />&lt;/script&gt; <br /><br />（2） <br />&lt;script language="javascript"&gt; <br />　　function printsetup(){ <br />　　// 打印页面设置 <br />　　wb.execwb(8,1); <br />　　} <br />　　function printpreview(){ <br />　　// 打印页面预览 <br />　　　　 <br />　　wb.execwb(7,1); <br />　　　　　 <br />　　　　 <br />　　} <br /><br />　　function printit() <br />　　{ <br />　　if (confirm('确定打印吗？')) { <br />　　wb.execwb(6,6) <br />　　} <br />　　} <br />　　&lt;/script&gt; <br />&lt;/head&gt; <br />&lt;body&gt; <br />&lt;OBJECT classid="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2" <br /><br />height=0 id=wb name=wb width=0&gt;&lt;/OBJECT&gt; <br />&lt;input type=button name=button_print value="打印" <br /><br />onclick="javascript:printit()"&gt; <br />&lt;input type=button　name=button_setup value="打印页面设置" <br /><br />onclick="javascript:printsetup();"&gt; <br />&lt;input type=button　name=button_show value="打印预览" <br /><br />onclick="javascript:printpreview();"&gt; <br />&lt;input type=button name=button_fh value="关闭" <br /><br />onclick="javascript:window.close();"&gt; <br /><br />------------------------------------------------ <br />关于这个组件还有其他的用法，列举如下： <br />WebBrowser.ExecWB(1,1) 打开 <br />Web.ExecWB(2,1) 关闭现在所有的IE窗口，并打开一个新窗口 <br />Web.ExecWB(4,1) 保存网页 <br />Web.ExecWB(6,1) 打印 <br />Web.ExecWB(7,1) 打印预览 <br />Web.ExecWB(8,1) 打印页面设置 <br />Web.ExecWB(10,1) 查看页面属性 <br />Web.ExecWB(15,1) 好像是撤销，有待确认 <br />Web.ExecWB(17,1) 全选 <br />Web.ExecWB(22,1) 刷新 <br />Web.ExecWB(45,1) 关闭窗体无提示 <br /><br />2、分页打印 <br />&lt;HTML&gt; <br />&lt;HEAD&gt; <br />&lt;STYLE&gt;　　 <br />　　P {page-break-after: always} <br />&lt;/STYLE&gt; <br />&lt;/HEAD&gt; <br />&lt;BODY&gt; <br />&lt;%while not rs.eof%&gt; <br />&lt;P&gt;&lt;%=rs(0)%&gt;&lt;/P&gt; <br />&lt;%rs.movenext%&gt; <br />&lt;%wend%&gt; <br />&lt;/BODY&gt; <br />&lt;/HTML&gt; <br /><br />3、ASP页面打印时如何去掉页面底部的路径和顶端的页码编号 <br />（1）ie的文件-〉页面设置-〉讲里面的页眉和页脚里面的东西都去掉，打印就不出来了。 <br />（2）&lt;HTML&gt; <br />&lt;HEAD&gt; <br />&lt;TITLE&gt; New Document &lt;/TITLE&gt; <br />&lt;META NAME="Generator" CONTENT="EditPlus"&gt; <br />&lt;META NAME="Author" CONTENT="YC"&gt; <br />&lt;script language="VBScript"&gt; <br />dim hkey_root,hkey_path,hkey_key <br />hkey_root="HKEY_CURRENT_USER" <br />hkey_path="\Software\Microsoft\Internet Explorer\PageSetup" <br />'//设置网页打印的页眉页脚为空 <br />function pagesetup_null() <br />　　on error resume next <br />　　Set RegWsh = CreateObject("WScript.Shell") <br />　　hkey_key="\header"　　 <br />　　RegWsh.RegWrite hkey_root+hkey_path+hkey_key,"" <br />　　hkey_key="\footer" <br />　　RegWsh.RegWrite hkey_root+hkey_path+hkey_key,"" <br />end function <br />'//设置网页打印的页眉页脚为默认值 <br />function pagesetup_default() <br />　　on error resume next <br />　　Set RegWsh = CreateObject("WScript.Shell") <br />　　hkey_key="\header"　　 <br />　　RegWsh.RegWrite hkey_root+hkey_path+hkey_key,"&amp;w&amp;b页码，&amp;p/&amp;P" <br />　　hkey_key="\footer" <br />　　RegWsh.RegWrite hkey_root+hkey_path+hkey_key,"&amp;u&amp;b&amp;d" <br />end function <br />&lt;/script&gt; <br />&lt;/HEAD&gt; <br /><br />&lt;BODY&gt; <br />&lt;br/&gt; <br />&lt;br/&gt; <br />&lt;br/&gt; <br />&lt;br/&gt; <br />&lt;br/&gt; <br />&lt;br/&gt;&lt;p align=center&gt; <br />&lt;input type="button" value="清空页码" onclick=pagesetup_null()&gt; &lt;input type="button" value="恢复页吗" onclick=pagesetup_default()&gt;&lt;br/&gt; <br /><br />&lt;/p&gt; <br />&lt;/BODY&gt; <br />&lt;/HTML&gt; <br />4、浮动帧打印 <br />&lt;SCRIPT LANGUAGE=javascript&gt; <br />function button1_onclick() { <br />　　var odoc=window.iframe1.document; <br />　　var r=odoc.body.createTextRange(); <br />　　var stxt=r.htmlText; <br />　　alert(stxt) <br />　　var pwin=window.open("","print"); <br />　　pwin.document.write(stxt); <br />　　pwin.print(); <br />} <br />&lt;/SCRIPT&gt; <br />4、用FileSystem组件实现WEB应用中的本地特定打印 <br />&lt;script Language=VBScript&gt; <br />function print_onclick //打印函数 <br />dim label <br />label=document.printinfo.label.value //获得HTML页面的数据 <br />set objfs=CreateObject("Scripting.FileSystemObject") //创建FileSystem组件对象的实例 <br />set objprinter=objfs.CreateTextFile ("LPT1:",true) //建立与打印机的连接 <br />objprinter.Writeline("__________________________________") //输出打印的内容 <br />objprinter.Writeline("| |") <br />objprinter.Writeline("| 您打印的数据是："&amp;label&amp; " |”) <br />objprinter.Writeline("| |") <br />objprinter.Writeline("|_________________________________|") <br />objprinter.close //断开与打印机的连接 <br />set objprinter=nothing <br />set objfs=nothing // 关闭FileSystem组件对象 <br />end function <br />&lt;/script&gt; <br />服务器端脚本： <br />&lt;%……… <br />set conn=server.CreateObject ("adodb.connection") <br />conn.Open "DSN=name;UID=XXXX;PWD=XXXX;" <br />set rs=server.CreateObject("adodb.recordset") <br />rs.Open(“select ……”),conn,1,1 <br />……….%&gt; //与数据库进行交互 <br />HTML页面编码： <br />&lt;HTML&gt; <br />……… <br />&lt;FORM ID=printinfo NAME="printinfo" &gt; <br />&lt;INPUT type="button" value="打印&gt;&gt;" id=print name=print &gt; //调用打印函数 <br />&lt;INPUT type=hidden id=text1 name=label value=&lt;%=………%&gt;&gt; //保存服务器端传来的数据 <br />……… <br />&lt;/HTML&gt;</font>
		</p>
<img src ="http://www.blogjava.net/weibogao/aggbug/57929.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weibogao/" target="_blank">weibogao</a> 2006-07-13 11:25 <a href="http://www.blogjava.net/weibogao/archive/2006/07/13/57929.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jfreechart使用总结</title><link>http://www.blogjava.net/weibogao/archive/2006/07/11/57622.html</link><dc:creator>weibogao</dc:creator><author>weibogao</author><pubDate>Tue, 11 Jul 2006 03:31:00 GMT</pubDate><guid>http://www.blogjava.net/weibogao/archive/2006/07/11/57622.html</guid><wfw:comment>http://www.blogjava.net/weibogao/comments/57622.html</wfw:comment><comments>http://www.blogjava.net/weibogao/archive/2006/07/11/57622.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weibogao/comments/commentRss/57622.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weibogao/services/trackbacks/57622.html</trackback:ping><description><![CDATA[
		<p>
				<br />
				<br />这里分三部分来介绍 jFreeChart 。第一部分介绍jFreeChart产生<br />图形的流程及相关的重要的类；第二部分介绍四种常用的报表图（饼图、柱状图、折线图、时间序列图）；第三部分<br />介绍在图形中增加Item Lable 。 <br />jFreeChart 的版本是jfreechart-1.0.0-pre2(1)<br /><br /></p>
		<p>[b]一、jFreeChart产生图形的流程[/b]<br />   创建一个数据源（dataset）来包含将要在图形中显示的数据,创建一个 JFreeChart 对象来代表要显示的图形<br />   把图形输出<br />   重要的类和接口：<br />   org.jfree.data.general.Dataset  所有数据源类都要实现的接口<br />   org.jfree.chart.ChartFactory    由它来产生 JFreeChart 对象<br />   org.jfree.chart.JFreeChart    所有对图形的调整都是通过它噢！！<br />   org.jfree.chart.plot.Plot    通过JFreeChart 对象获得它，然后再通过它对图形外部部分（例：坐标轴）调整<br />                                注意：它有很多子类，一般都下嗍造型到它的子类！<br />   org.jfree.chart.renderer.AbstractRenderer     通过JFreeChart 对象获得它，然后再通过它对图形内部部分<br />                                                （例：折线的类型）调整。同样，针对不同类型的报表图，它有<br />                                                着不同的子类实现！在下面我们简称它为 Renderer<br />   下面我们结合不同类型的图形来具体分析这个流程。<br />   <br />[b]二、饼图[/b]<br />   饼图的dataset 一般是用PieDataset 接口，具体实现类是 DefaultPieDataset<br />   1、创建一个数据源（dataset）：<br />    private static PieDataset createDataset()<br />    {<br />        DefaultPieDataset defaultpiedataset = new DefaultPieDataset(); //注意是DefaultPieDataset！！<br />        defaultpiedataset.setValue("One", new Double(43.200000000000003D));<br />        defaultpiedataset.setValue("Two", new Double(10D));<br />        defaultpiedataset.setValue("Three", new Double(27.5D));<br />        defaultpiedataset.setValue("Four", new Double(17.5D));<br />        return defaultpiedataset;<br />    } <br />   2、由ChartFactory  产生 JFreeChart 对象<br />    private static JFreeChart createChart(PieDataset piedataset)<br />    {<br />        JFreeChart jfreechart = ChartFactory.createPieChart("Pie Chart Demo 1",  //图形标题名称<br />                                                              piedataset,   // dataset<br />                                                              true,      // legend?<br />                                                              true,     // tooltips?<br />                                                              false);  //URLs?<br />        PiePlot pieplot = (PiePlot)jfreechart.getPlot();  //通过JFreeChart 对象获得 plot：PiePlot！！<br />        pieplot.setNoDataMessage("No data available");    // 没有数据的时候显示的内容<br />        return jfreechart;<br />    } <br />    一些重要的方法：<br />    pieplot.setExplodePercent(0,0.3D) //把Lable 为"One" 的那一块”挖“出来30%    <br />   3、输出略  <br />   <br />[b]三、柱状图[/b]<br />   柱状图的dataset 一般是用CatagoryDataset接口(具体实现类是DefaultCategoryDataset),也会用 IntervalXYDataset <br />   接口<br />   1、创建一个数据源（dataset）：<br />    private static CategoryDataset createDataset()<br />    {<br />        String series1 = "First";<br />        String series2 = "Second";<br />        String series3 = "Third";<br />        String category1 = "Category 1";<br />        String category2 = "Category 2";<br />        String category3 = "Category 3";<br />        String category4 = "Category 4";<br />        String category5 = "Category 5";<br />        DefaultCategoryDataset defaultcategorydataset = new DefaultCategoryDataset();<br />        defaultcategorydataset.addValue(1.0D, series1, category1);<br />        defaultcategorydataset.addValue(4D, series1, category2);<br />        defaultcategorydataset.addValue(3D, series1, category3);<br />        defaultcategorydataset.addValue(5D, series1, category4);<br />        defaultcategorydataset.addValue(5D, series1, category5);<br />        <br />        defaultcategorydataset.addValue(5D, series2, category1);<br />        defaultcategorydataset.addValue(7D, series2, category2);<br />        defaultcategorydataset.addValue(6D, series2, category3);<br />        defaultcategorydataset.addValue(8D, series2, category4);<br />        defaultcategorydataset.addValue(4D, series2, category5);<br />        <br />        defaultcategorydataset.addValue(4D, series3, category1);<br />        defaultcategorydataset.addValue(3D, series3, category2);<br />        defaultcategorydataset.addValue(2D, series3, category3);<br />        defaultcategorydataset.addValue(3D, series3, category4);<br />        defaultcategorydataset.addValue(6D, series3, category5);<br />        return defaultcategorydataset;<br />    }<br />   2、由ChartFactory  产生 JFreeChart 对象    <br />    private static JFreeChart createChart(CategoryDataset categorydataset)<br />    {<br />        JFreeChart jfreechart = ChartFactory.createBarChart("Bar Chart Demo", //图形标题名称<br />                                                            "Category",//domain 轴 Lable <br />                                                                         这里先简单理解为横坐标Lable好了<br />                                                            "Value", //range 轴 Lable<br />                                                                       这里也先简单理解为纵坐标Lable好了<br />                                                            categorydataset, //  dataset<br />                                                            PlotOrientation.VERTICAL, //垂直显示<br />                                                            true, // legend?<br />                                                            true,  // tooltips?<br />                                                            false); //URLs?<br />        jfreechart.setBackgroundPaint(Color.white);   //设定背景色为白色<br />        CategoryPlot categoryplot = jfreechart.getCategoryPlot(); //获得 plot：CategoryPlot！！<br />        categoryplot.setBackgroundPaint(Color.lightGray); //设定图表数据显示部分背景色<br />        categoryplot.setDomainGridlinePaint(Color.white); //横坐标网格线白色<br />        categoryplot.setDomainGridlinesVisible(true); //可见<br />        categoryplot.setRangeGridlinePaint(Color.white); //纵坐标网格线白色<br />        //下面两行使纵坐标的最小单位格为整数<br />        NumberAxis numberaxis = (NumberAxis)categoryplot.getRangeAxis();<br />        numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());<br />        BarRenderer barrenderer = (BarRenderer)categoryplot.getRenderer(); //获得renderer 注意这里是下嗍造型<br />                                                                             到BarRenderer！！<br />        barrenderer.setDrawBarOutline(false); // Bar的外轮廓线不画<br />        GradientPaint gradientpaint = new GradientPaint(0.0F, 0.0F, Color.blue, <br />        0.0F, 0.0F, new Color(0, 0, 64));   //设定特定颜色<br />        GradientPaint gradientpaint1 = new GradientPaint(0.0F, 0.0F, Color.green, <br />        0.0F, 0.0F, new Color(0, 64, 0));<br />        GradientPaint gradientpaint2 = new GradientPaint(0.0F, 0.0F, Color.red,<br />        0.0F, 0.0F, new Color(64, 0, 0));<br />        barrenderer.setSeriesPaint(0, gradientpaint); //给series1 Bar设定上面定义的颜色<br />        barrenderer.setSeriesPaint(1, gradientpaint1); //给series2 Bar 设定上面定义的颜色<br />        barrenderer.setSeriesPaint(2, gradientpaint2); //给series3 Bar 设定上面定义的颜色<br />        CategoryAxis categoryaxis = categoryplot.getDomainAxis();  //横轴上的 Lable 45度倾斜<br />        categoryaxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);        <br />        return jfreechart;<br />    }  <br />    一些重要的方法：（增加一块标记）<br />        IntervalMarker intervalmarker = new IntervalMarker(4.5D, 7.5D);<br />        intervalmarker.setLabel("Target Range");<br />        intervalmarker.setLabelFont(new Font("SansSerif", 2, 11));<br />        intervalmarker.setLabelAnchor(RectangleAnchor.LEFT);<br />        intervalmarker.setLabelTextAnchor(TextAnchor.CENTER_LEFT);<br />        intervalmarker.setPaint(new Color(222, 222, 255, 128));<br />        categoryplot.addRangeMarker(intervalmarker, Layer.BACKGROUND);    <br />        <br />[b]四、折线图[/b]<br />   折线图的dataset 两种CatagoryDataset接口(具体实现类是DefaultCategoryDataset),XYDataset 接口 <br />   1、CatagoryDataset接口：         <br />   A、创建一个数据源（dataset）： <br />    private static CategoryDataset createDataset()<br />    {<br />        String series1 = "First";<br />        String series2 = "Second";<br />        String series3 = "Third";<br />        String type1 = "Type 1";<br />        String type2 = "Type 2";<br />        String type3 = "Type 3";<br />        String type4 = "Type 4";<br />        String type5 = "Type 5";<br />        String type6 = "Type 6";<br />        String type7 = "Type 7";<br />        String type8 = "Type 8";<br />        DefaultCategoryDataset defaultcategorydataset = new DefaultCategoryDataset();<br />        defaultcategorydataset.addValue(1.0D, series1, type1);<br />        defaultcategorydataset.addValue(4D, series1, type2);<br />        defaultcategorydataset.addValue(3D, series1, type3);<br />        defaultcategorydataset.addValue(5D, series1, type4);<br />        defaultcategorydataset.addValue(5D, series1, type5);<br />        defaultcategorydataset.addValue(7D, series1, type6);<br />        defaultcategorydataset.addValue(7D, series1, type7);<br />        defaultcategorydataset.addValue(8D, series1, type8);<br />        <br />        defaultcategorydataset.addValue(5D, series2, type1);<br />        defaultcategorydataset.addValue(7D, series2, type2);<br />        defaultcategorydataset.addValue(6D, series2, type3);<br />        defaultcategorydataset.addValue(8D, series2, type4);<br />        defaultcategorydataset.addValue(4D, series2, type5);<br />        defaultcategorydataset.addValue(4D, series2, type6);<br />        defaultcategorydataset.addValue(2D, series2, type7);<br />        defaultcategorydataset.addValue(1.0D, series2, type8);<br />        <br />        defaultcategorydataset.addValue(4D, series3, type1);<br />        defaultcategorydataset.addValue(3D, series3, type2);<br />        defaultcategorydataset.addValue(2D, series3, type3);<br />        defaultcategorydataset.addValue(3D, series3, type4);<br />        defaultcategorydataset.addValue(6D, series3, type5);<br />        defaultcategorydataset.addValue(3D, series3, type6);<br />        defaultcategorydataset.addValue(4D, series3, type7);<br />        defaultcategorydataset.addValue(3D, series3, type8);<br />        return defaultcategorydataset;<br />    } <br />   B、由ChartFactory  产生 JFreeChart 对象     (与上面重复的部分就不再注释）<br />    private static JFreeChart createChart(CategoryDataset categorydataset)<br />    {<br />        JFreeChart jfreechart = ChartFactory.createLineChart("Line Chart Demo 1", <br />                                                             "Type", <br />                                                             "Value", <br />                                                             categorydataset, <br />                                                             PlotOrientation.VERTICAL, <br />                                                             true, <br />                                                             true, <br />                                                             false);<br />        jfreechart.setBackgroundPaint(Color.white);<br />        CategoryPlot categoryplot = (CategoryPlot)jfreechart.getPlot();<br />        categoryplot.setBackgroundPaint(Color.lightGray);<br />        categoryplot.setRangeGridlinePaint(Color.white);<br />        NumberAxis numberaxis = (NumberAxis)categoryplot.getRangeAxis();<br />        numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());<br />        numberaxis.setAutoRangeIncludesZero(true);<br />        //获得renderer 注意这里是下嗍造型到lineandshaperenderer！！<br />        LineAndShapeRenderer lineandshaperenderer = (LineAndShapeRenderer)categoryplot.getRenderer();<br />        lineandshaperenderer.setShapesVisible(true); //series 点（即数据点）可见<br />        lineandshaperenderer.setSeriesStroke(0, new BasicStroke(2.0F, 1, 1, 1.0F, new float[] {<br />            10F, 6F<br />        }, 0.0F)); //定义series为"First"的（即series1）点之间的连线 ，这里是虚线，默认是直线<br />        lineandshaperenderer.setSeriesStroke(1, new BasicStroke(2.0F, 1, 1, 1.0F, new float[] {<br />            6F, 6F<br />        }, 0.0F)); //定义series为"Second"的（即series2）点之间的连线<br />        lineandshaperenderer.setSeriesStroke(2, new BasicStroke(2.0F, 1, 1, 1.0F, new float[] {<br />            2.0F, 6F<br />        }, 0.0F)); //定义series为"Third"的（即series3）点之间的连线<br />        return jfreechart;<br />    } <br />        一些重要的方法：<br />        lineandshaperenderer.setLineVisible(true)  //series 点（即数据点）间有连线可见<br />   2、XYDataset 接口：<br />   A、创建一个数据源（dataset）：<br />    private static XYDataset createDataset()<br />    {<br />        XYSeries xyseries = new XYSeries("First"); //先产生XYSeries 对象<br />        xyseries.add(1.0D, 1.0D);<br />        xyseries.add(2D, 4D);<br />        xyseries.add(3D, 3D);<br />        xyseries.add(4D, 5D);<br />        xyseries.add(5D, 5D);<br />        xyseries.add(6D, 7D);<br />        xyseries.add(7D, 7D);<br />        xyseries.add(8D, 8D);<br />        <br />        XYSeries xyseries1 = new XYSeries("Second");<br />        xyseries1.add(1.0D, 5D);<br />        xyseries1.add(2D, 7D);<br />        xyseries1.add(3D, 6D);<br />        xyseries1.add(4D, 8D);<br />        xyseries1.add(5D, 4D);<br />        xyseries1.add(6D, 4D);<br />        xyseries1.add(7D, 2D);<br />        xyseries1.add(8D, 1.0D);<br />        <br />        XYSeries xyseries2 = new XYSeries("Third");<br />        xyseries2.add(3D, 4D);<br />        xyseries2.add(4D, 3D);<br />        xyseries2.add(5D, 2D);<br />        xyseries2.add(6D, 3D);<br />        xyseries2.add(7D, 6D);<br />        xyseries2.add(8D, 3D);<br />        xyseries2.add(9D, 4D);<br />        xyseries2.add(10D, 3D);<br />        <br />        XYSeriesCollection xyseriescollection = new XYSeriesCollection(); //再用XYSeriesCollection添加入XYSeries 对象<br />        xyseriescollection.addSeries(xyseries);<br />        xyseriescollection.addSeries(xyseries1);<br />        xyseriescollection.addSeries(xyseries2);<br />        return xyseriescollection;<br />    }<br />   B、由ChartFactory  产生 JFreeChart 对象 <br />    private static JFreeChart createChart(XYDataset xydataset)<br />    {<br />        JFreeChart jfreechart = ChartFactory.createXYLineChart("Line Chart Demo 2", <br />                                                               "X", <br />                                                               "Y", <br />                                                               xydataset, <br />                                                               PlotOrientation.VERTICAL, <br />                                                               true, <br />                                                               true, <br />                                                               false);<br />        jfreechart.setBackgroundPaint(Color.white);<br />        XYPlot xyplot = (XYPlot)jfreechart.getPlot(); //获得 plot：XYPlot！！<br />        xyplot.setBackgroundPaint(Color.lightGray); //设定图表数据显示部分背景色<br />        xyplot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D)); //设定坐标轴与图表数据显示部分距离<br />        xyplot.setDomainGridlinePaint(Color.white); //网格线颜色<br />        xyplot.setRangeGridlinePaint(Color.white);<br />        //获得 renderer 注意这里是XYLineAndShapeRenderer ！！<br />        XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer)xyplot.getRenderer();<br />        xylineandshaperenderer.setShapesVisible(true); //数据点可见<br />        xylineandshaperenderer.setShapesFilled(true); //数据点被填充即不是空心点<br />        NumberAxis numberaxis = (NumberAxis)xyplot.getRangeAxis();<br />        numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());<br />        return jfreechart;<br />    }                      <br />   一些重要的方法：<br />        XYLineAndShapeRenderer xylineandshaperenderer = new XYLineAndShapeRenderer();<br />        xylineandshaperenderer.setSeriesLinesVisible(0, false); //第一个XYSeries数据点间连线不可见<br />        xylineandshaperenderer.setSeriesShapesVisible(1, false); //第二个XYSeries数据点不可见<br />        xyplot.setRenderer(xylineandshaperenderer);   <br />        <br />[b]五、时间序列图[/b]<br />    时间序列图和折线图很相似，不同的是它在 domain轴的数据是时间而不是数字。 时间序列图的dataset 是<br />    XYDataset 接口，具体实现类是TimeSeriesCollection ，和上面类似，有TimeSeries 对象，它被添加入<br />    TimeSeriesCollection 。                                                                               <br />  1、创建一个数据源（dataset）：<br />    private static XYDataset createDataset()<br />    {<br />        TimeSeries timeseries = new TimeSeries("L&amp;G European Index Trust",Month.class);<br />        timeseries.add(new Month(2, 2001), 181.8D);//这里用的是Month.class，同样还有Day.class Year.class 等等<br />        timeseries.add(new Month(3, 2001), 167.3D);<br />        timeseries.add(new Month(4, 2001), 153.8D);<br />        timeseries.add(new Month(5, 2001), 167.6D);<br />        timeseries.add(new Month(6, 2001), 158.8D);<br />        timeseries.add(new Month(7, 2001), 148.3D);<br />        timeseries.add(new Month(8, 2001), 153.9D);<br />        timeseries.add(new Month(9, 2001), 142.7D);<br />        timeseries.add(new Month(10, 2001), 123.2D);<br />        timeseries.add(new Month(11, 2001), 131.8D);<br />        timeseries.add(new Month(12, 2001), 139.6D);<br />        timeseries.add(new Month(1, 2002), 142.9D);<br />        timeseries.add(new Month(2, 2002), 138.7D);<br />        timeseries.add(new Month(3, 2002), 137.3D);<br />        timeseries.add(new Month(4, 2002), 143.9D);<br />        timeseries.add(new Month(5, 2002), 139.8D);<br />        timeseries.add(new Month(6, 2002), 137D);<br />        timeseries.add(new Month(7, 2002), 132.8D);<br />        <br />        TimeSeries timeseries1 = new TimeSeries("L&amp;G UK Index Trust",Month.class);<br />        timeseries1.add(new Month(2, 2001), 129.6D);<br />        timeseries1.add(new Month(3, 2001), 123.2D);<br />        timeseries1.add(new Month(4, 2001), 117.2D);<br />        timeseries1.add(new Month(5, 2001), 124.1D);<br />        timeseries1.add(new Month(6, 2001), 122.6D);<br />        timeseries1.add(new Month(7, 2001), 119.2D);<br />        timeseries1.add(new Month(8, 2001), 116.5D);<br />        timeseries1.add(new Month(9, 2001), 112.7D);<br />        timeseries1.add(new Month(10, 2001), 101.5D);<br />        timeseries1.add(new Month(11, 2001), 106.1D);<br />        timeseries1.add(new Month(12, 2001), 110.3D);<br />        timeseries1.add(new Month(1, 2002), 111.7D);<br />        timeseries1.add(new Month(2, 2002), 111D);<br />        timeseries1.add(new Month(3, 2002), 109.6D);<br />        timeseries1.add(new Month(4, 2002), 113.2D);<br />        timeseries1.add(new Month(5, 2002), 111.6D);<br />        timeseries1.add(new Month(6, 2002), 108.8D);<br />        timeseries1.add(new Month(7, 2002), 101.6D);<br />        TimeSeriesCollection timeseriescollection = new TimeSeriesCollection();<br />        timeseriescollection.addSeries(timeseries);<br />        timeseriescollection.addSeries(timeseries1);<br />        timeseriescollection.setDomainIsPointsInTime(true); //domain轴上的刻度点代表的是时间点而不是时间段<br />        return timeseriescollection;<br />    }<br />   2、由ChartFactory  产生 JFreeChart 对象 <br />    private static JFreeChart createChart(XYDataset xydataset)<br />    {<br />        JFreeChart jfreechart = ChartFactory.createTimeSeriesChart("Legal &amp; General Unit Trust Prices", <br />                                                                   "Date", <br />                                                                   "Price Per Unit", <br />                                                                   xydataset, <br />                                                                   true, <br />                                                                   true, <br />                                                                   false);<br />        jfreechart.setBackgroundPaint(Color.white);<br />        XYPlot xyplot = (XYPlot)jfreechart.getPlot(); //获得 plot : XYPlot!!<br />        xyplot.setBackgroundPaint(Color.lightGray);<br />        xyplot.setDomainGridlinePaint(Color.white);<br />        xyplot.setRangeGridlinePaint(Color.white);<br />        xyplot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));<br />        xyplot.setDomainCrosshairVisible(true);<br />        xyplot.setRangeCrosshairVisible(true);<br />        org.jfree.chart.renderer.xy.XYItemRenderer xyitemrenderer = xyplot.getRenderer();<br />        if(xyitemrenderer instanceof XYLineAndShapeRenderer)<br />        {<br />            XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer)xyitemrenderer;<br />            xylineandshaperenderer.setDefaultShapesVisible(true); //数据点可见<br />            xylineandshaperenderer.setDefaultShapesFilled(true);  //数据点是实心点<br />        }<br />        DateAxis dateaxis = (DateAxis)xyplot.getDomainAxis(); //对domain 轴上日期显示格式定义<br />        dateaxis.setDateFormatOverride(new SimpleDateFormat("MMM-yyyy"));<br />        return jfreechart;<br />    }  <br />       一些重要的方法：<br />     A、增加标记线： <br />        xyplot.addRangeMarker(new ValueMarker(550D)); //数值轴<br />        Quarter quarter = new Quarter(2, 2002);<br />        xyplot.addDomainMarker(new ValueMarker(quarter.getMiddleMillisecond()));  //时间轴<br />     B、数据点的调整<br />        XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer)xyplot.getRenderer();<br />        xylineandshaperenderer.setDefaultShapesVisible(true);  //数据点可见<br />        xylineandshaperenderer.setSeriesFillPaint(0, Color.red);  //数据点填充为红色<br />        xylineandshaperenderer.setSeriesFillPaint(1, Color.white);  //数据点填充为白色<br />        xylineandshaperenderer.setUseFillPaint(true);    //应用<br />     C、平均值曲线 <br />       这个曲线有什么用呢？很简单的例子，这里有一个以半年每天为单位的数据绘制的曲线，我们想看看以月为单位数据<br />       的变化，这时就可以用到它了。 <br />        TimeSeries timeseries = createEURTimeSeries();  //就是以半年每天为单位的数据<br />        TimeSeries timeseries1 = MovingAverage.createMovingAverage(timeseries, <br />                                                                   "30 day moving average", <br />                                                                   30, //30天为一个周期<br />                                                                   30); //最开始的30天跳过<br />        TimeSeriesCollection timeseriescollection = new TimeSeriesCollection();<br />        timeseriescollection.addSeries(timeseries);<br />        timeseriescollection.addSeries(timeseries1);<br />        return timeseriescollection; <br />     <br />[b]六、总结一下[/b]<br />                           dataset                          plot                    renderer                       <br />  饼图           PieDataset（DefaultPieDataset）           PiePlot                    ------<br />  柱状图    CatagoryDataset（DefaultCategoryDataset）    CategoryPlot                BarRenderer<br />  折线图    CatagoryDataset（DefaultCategoryDataset）    CategoryPlot              LineAndShapeRenderer<br />                  XYDataset（XYSeriesCollection）           XYPlot                XYLineAndShapeRenderer<br />  时间序列图     XYDataset （TimeSeriesCollection）         XYPlot                XYLineAndShapeRenderer<br />  这里只是一些常用的方法，具体还是看API ,主要的类总结如下：<br />JFreeChart:生成图表的中间存放类。</p>
		<div>CategoryDataSet:图表的数据，主要包含行数据（String[] 类型），列数据(String[] 类型）和主数据                    (double[][]类型）。一般来说简单的图表主数据都是double[1][]类型的。</div>
		<div>ChartFactory: 工厂类，提供多种方法生成多达30多种图表，用得比较多的是BarChart(柱状图),LineChart             （折线图），PieChart（饼状图）。工厂方法看起来比较统一：creatXXXChart(图表标题，              行标题，列标题，主数据（CategoryDataSet）)</div>
		<div>ChartUtities: 公用类，提供各种持久保存图表数据的方法，比如saveChartAsJPEG(File，                             JFreeChart,width,height)</div>
		<div>其他还有一些渲染类，主要是用来美化图表界面，调整和优化显示风格等。</div>
		<div>总的来说还不错，比jasperReport要简单，上手很快，图表效果也还不错，用来做普通数据图表足够了</div>
		<p>
				<br />
				<br />[b]七、Item Lable[/b] <br />   这里以柱状图为例说明，具体来说就是在每个柱状上显示它的数据，具体有下面内容：<br />   A、使 Item Lable 可见<br />   B、调整 Item Lable 的颜色、字体等<br />   C、调整 Item Lable 的位置<br />   D、定制 Item Lable 的内容<br />   1、分配一个 Lable Generator 给 renderer<br />      BarRenderer barrenderer = (BarRenderer)categoryplot.getRenderer();<br />      GategoryLableGenerator generator =new StandardGategoryLableGenerator(<br />           "{2}", new DecimalFormat("0.00")    //调整显示的数字和字符格式<br />      );<br />      barrenderer.setLableGenerator(generator);<br />   2、使 Item Lable 可见<br />      barrenderer.setItemLableVisible(true);<br />   3、调整 Item Lable 的颜色、字体等<br />      barrenderer.setItemLablePaint(Color.red);<br />      barrenderer.setItemLableFont(new Font("SansSerif",Font.PLAIN,10));<br />   4、调整 Item Lable 的位置<br />      这里涉及到一个新的对象 ItemLablePosition , ItemLablePosition的构造函数有两个或四个参数<br />      public ItemLabelPosition(ItemLabelAnchor itemLabelAnchor,<br />                         org.jfree.ui.TextAnchor textAnchor,<br />                         org.jfree.ui.TextAnchor rotationAnchor,<br />                         double angle)<br />      itemLabelAnchor - Item Lable 的位置 （最重要的！！）<br />      textAnchor - Item Lable里包含的正文相对于Item Lable 的位置<br />      rotationAnchor - Item Lable里包含的正文旋转的位置<br />      angle - 旋转的角度<br />      ItemLabelPosition itemlabelposition = new ItemLabelPosition(ItemLabelAnchor.INSIDE12, <br />                                                      TextAnchor.CENTER_RIGHT, <br />                                                      TextAnchor.CENTER_RIGHT, <br />                                                      -1.57D);<br />      barrenderer.setPositiveItemLabelPosition(itemlabelposition); <br />   这样就可以每个柱状上显示它的数据了，当然可以定制 Item Lable 的内容，比如 Item Lable text 超过100的才<br />   显示，这样就需要定制自己的类，它要实现GategoryLableGenerator 接口，实现generateItemLable()方法。</p>
<img src ="http://www.blogjava.net/weibogao/aggbug/57622.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weibogao/" target="_blank">weibogao</a> 2006-07-11 11:31 <a href="http://www.blogjava.net/weibogao/archive/2006/07/11/57622.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>jsp标签小结</title><link>http://www.blogjava.net/weibogao/archive/2006/07/06/56954.html</link><dc:creator>weibogao</dc:creator><author>weibogao</author><pubDate>Thu, 06 Jul 2006 07:05:00 GMT</pubDate><guid>http://www.blogjava.net/weibogao/archive/2006/07/06/56954.html</guid><wfw:comment>http://www.blogjava.net/weibogao/comments/56954.html</wfw:comment><comments>http://www.blogjava.net/weibogao/archive/2006/07/06/56954.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weibogao/comments/commentRss/56954.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weibogao/services/trackbacks/56954.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: JSP自定义标签试验原文：兔八哥笔记3:JSP自定义标签试验  一、概述       JSP中有一块重要的技术：自定义标签（Custom Tag），最近这几天在学习Struts的时候发现Struts中使用了很多自定义标签，如html、bean等。所以我就做了个简单的试验，学习一下这种技术。       首先介绍一下这种技术吧！1．优点：取代了JSP中的Java程序，并且可以重复使用，方便不熟悉...&nbsp;&nbsp;<a href='http://www.blogjava.net/weibogao/archive/2006/07/06/56954.html'>阅读全文</a><img src ="http://www.blogjava.net/weibogao/aggbug/56954.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weibogao/" target="_blank">weibogao</a> 2006-07-06 15:05 <a href="http://www.blogjava.net/weibogao/archive/2006/07/06/56954.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate中的投影查询</title><link>http://www.blogjava.net/weibogao/archive/2006/07/05/56749.html</link><dc:creator>weibogao</dc:creator><author>weibogao</author><pubDate>Wed, 05 Jul 2006 06:44:00 GMT</pubDate><guid>http://www.blogjava.net/weibogao/archive/2006/07/05/56749.html</guid><wfw:comment>http://www.blogjava.net/weibogao/comments/56749.html</wfw:comment><comments>http://www.blogjava.net/weibogao/archive/2006/07/05/56749.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weibogao/comments/commentRss/56749.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weibogao/services/trackbacks/56749.html</trackback:ping><description><![CDATA[投影(Projections)、聚合（aggregation）和分组（grouping） 
<div></div><p><tt class="literal">org.hibernate.criterion.Projections</tt>是 <tt class="literal">Projection</tt> 的实例工厂。我们通过调用 <tt class="literal">setProjection()</tt>应用投影到一个查询。 </p><pre class="programlisting">List results = session.createCriteria(Cat.class)
    .setProjection( Projections.rowCount() )
    .add( Restrictions.eq("color", Color.BLACK) )
    .list();</pre><pre class="programlisting">List results = session.createCriteria(Cat.class)
    .setProjection( Projections.projectionList()
        .add( Projections.rowCount() )
        .add( Projections.avg("weight") )
        .add( Projections.max("weight") )
        .add( Projections.groupProperty("color") )
    )
    .list();</pre><p>在一个条件查询中没有必要显式的使用 "group by" 。某些投影类型就是被定义为<span class="emphasis"><em> 分组投影</em></span>，他们也出现在SQL的<tt class="literal">group by</tt>子句中。 </p><p>你可以选择把一个别名指派给一个投影，这样可以使投影值被约束或排序所引用。下面是两种不同的实现方式： </p><pre class="programlisting">List results = session.createCriteria(Cat.class)
    .setProjection( Projections.alias( Projections.groupProperty("color"), "colr" ) )
    .addOrder( Order.asc("colr") )
    .list();</pre><pre class="programlisting">List results = session.createCriteria(Cat.class)
    .setProjection( Projections.groupProperty("color").as("colr") )
    .addOrder( Order.asc("colr") )
    .list();</pre><p><tt class="literal">alias()</tt>和<tt class="literal">as()</tt>方法简便的将一个投影实例包装到另外一个 别名的<tt class="literal">Projection</tt>实例中。简而言之，当你添加一个投影到一个投影列表中时 你可以为它指定一个别名： </p><pre class="programlisting">List results = session.createCriteria(Cat.class)
    .setProjection( Projections.projectionList()
        .add( Projections.rowCount(), "catCountByColor" )
        .add( Projections.avg("weight"), "avgWeight" )
        .add( Projections.max("weight"), "maxWeight" )
        .add( Projections.groupProperty("color"), "color" )
    )
    .addOrder( Order.desc("catCountByColor") )
    .addOrder( Order.desc("avgWeight") )
    .list();</pre><pre class="programlisting">List results = session.createCriteria(Domestic.class, "cat")
    .createAlias("kittens", "kit")
    .setProjection( Projections.projectionList()
        .add( Projections.property("cat.name"), "catName" )
        .add( Projections.property("kit.name"), "kitName" )
    )
    .addOrder( Order.asc("catName") )
    .addOrder( Order.asc("kitName") )
    .list();</pre><p>你也可以使用<tt class="literal">Property.forName()</tt>来表示投影： </p><pre class="programlisting">List results = session.createCriteria(Cat.class)
    .setProjection( Property.forName("name") )
    .add( Property.forName("color").eq(Color.BLACK) )
    .list();</pre><pre class="programlisting">List results = session.createCriteria(Cat.class)
    .setProjection( Projections.projectionList()
        .add( Projections.rowCount().as("catCountByColor") )
        .add( Property.forName("weight").avg().as("avgWeight") )
        .add( Property.forName("weight").max().as("maxWeight") )
        .add( Property.forName("color").group().as("color" )
    )
    .addOrder( Order.desc("catCountByColor") )
    .addOrder( Order.desc("avgWeight") )
    .list();</pre><img src ="http://www.blogjava.net/weibogao/aggbug/56749.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weibogao/" target="_blank">weibogao</a> 2006-07-05 14:44 <a href="http://www.blogjava.net/weibogao/archive/2006/07/05/56749.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate中多对多的两种保存方式</title><link>http://www.blogjava.net/weibogao/archive/2006/07/05/56740.html</link><dc:creator>weibogao</dc:creator><author>weibogao</author><pubDate>Wed, 05 Jul 2006 06:31:00 GMT</pubDate><guid>http://www.blogjava.net/weibogao/archive/2006/07/05/56740.html</guid><wfw:comment>http://www.blogjava.net/weibogao/comments/56740.html</wfw:comment><comments>http://www.blogjava.net/weibogao/archive/2006/07/05/56740.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weibogao/comments/commentRss/56740.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weibogao/services/trackbacks/56740.html</trackback:ping><description><![CDATA[1.使用关联表实现多对多的关联，在实体一端的映射文件中定义：<br />&lt;set name="unitTypes" lazy="true" table="IPMS_UNITTYPE" cascade="all"&gt;<br />   &lt;key column="UNITID"/&gt;<br />   &lt;many-to-many class="com.toone.ipms.common.dict.vo.CommDict" column="DICTID"/&gt;<br />&lt;/set&gt;<br />因为配置中cascade="all"，所以可以不使用中间表关联类来实现，而且不需要分别进行save操作<br />其中两个column都是关联表中的字段，key为本端外键，而另一个则是另一端外键 <br />2.另一种方式为生成关联表的映射文件和PO，写出关联类的基本管理类的增删改操作，实现保存时两个类的关联<img src ="http://www.blogjava.net/weibogao/aggbug/56740.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weibogao/" target="_blank">weibogao</a> 2006-07-05 14:31 <a href="http://www.blogjava.net/weibogao/archive/2006/07/05/56740.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>DisplayTag应用(转载)</title><link>http://www.blogjava.net/weibogao/archive/2006/07/03/56309.html</link><dc:creator>weibogao</dc:creator><author>weibogao</author><pubDate>Mon, 03 Jul 2006 05:23:00 GMT</pubDate><guid>http://www.blogjava.net/weibogao/archive/2006/07/03/56309.html</guid><wfw:comment>http://www.blogjava.net/weibogao/comments/56309.html</wfw:comment><comments>http://www.blogjava.net/weibogao/archive/2006/07/03/56309.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weibogao/comments/commentRss/56309.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weibogao/services/trackbacks/56309.html</trackback:ping><description><![CDATA[
		<div class="posttitle">
				<a class="singleposttitle" id="viewpost1_TitleUrl" href="/RongHao/archive/2005/12/08/22990.html">DisplayTag应用</a>
		</div>
		<p>  DisplayTag是一个非常好用的表格显示标签，适合MVC模式，其主页在<a href="http://displaytag.sourceforge.net/">http://displaytag.sourceforge.net/</a>  <br /><strong>一、最简单的情况，未使用&lt;display:column/&gt;标签<br /></strong>  &lt;%request.setAttribute( "test", new ReportList(6) );%&gt;<br />  &lt;display:table name="test" /&gt;<br />  标签遍历List里的每一个对象，并将对象里的所有属性显示出来。一般用于开发的时候检查对象数据的完整性。<br />  <br /><strong>二、使用&lt;display:column/&gt;标签的情况</strong><br />&lt;display:table name="test"&gt;<br />  &lt;display:column property="id" title="ID" /&gt;<br />  &lt;display:column property="name" /&gt;<br />  &lt;display:column property="email" /&gt;<br />  &lt;display:column property="status" /&gt;<br />  &lt;display:column property="description" title="Comments"/&gt;<br />&lt;/display:table&gt;<br />   property对应List里对象的属性（用getXXX()方法取得），title则对应表格表头里的列名。定义列有两种方式：<br />   A、&lt;display:column property="email" /&gt; <br />      使用&lt;display:column/&gt;标签里的property属性来定义<br />   B、&lt;display:column title="email"&gt;email@it.com&lt;/display:column&gt; <br />      在&lt;display:column/&gt;标签体里增加内容，可以是常量，也可以用其他标签等等<br />   两种方式比较，用property属性来定义更加快速和利于排序。<br />   <br /><strong>三、表格显示样式的定义<br /></strong>  A、在&lt;display:table/&gt;和&lt;display:column/&gt;标签里指定标准的html属性，烦琐<br />  B、修改样式表<br />&lt;display:table name="test" class="mars"&gt;<br />  &lt;display:column property="id" title="ID" class="idcol"/&gt;<br />  &lt;display:column property="name" /&gt;<br />  &lt;display:column property="email" /&gt;<br />  &lt;display:column property="status" class="tableCellError" /&gt;<br />  &lt;display:column property="description" title="Comments"/&gt;<br />&lt;/display:table&gt;<br />   通过class属性来指定所要应用的样式。可以在其默认样式表里（./css/screen.css）直接修改<br />   <br /><strong>四、标签取得数据的数据源<br /></strong>  有四种范围<br />   pageScope <br />   requestScope (默认)  &lt;display:table name="test2" &gt;<br />   sessionScope  &lt;display:table name="sessionScope.holder.list" &gt; 注意，这里要指定范围，非默认<br />   applicationScope <br />   <br /><strong>五、通过增加id属性创建隐含的对象<br /></strong>&lt;display:table name="test" id="testit"&gt;<br />    &lt;display:column property="id" title="ID" /&gt;<br />    &lt;display:column property="name" /&gt;<br />    &lt;display:column title="static value"&gt;static&lt;/display:column&gt;<br />    &lt;display:column title="row number (testit_rowNum)"&gt;&lt;%=pageContext.getAttribute("testit_rowNum")%&gt;&lt;/display:column&gt;<br />    &lt;display:column title="((ListObject)testit).getMoney()"&gt;&lt;%=((ListObject)pageContext.getAttribute("testit")).getMoney()%&gt;&lt;/display:column&gt;<br />&lt;/display:table&gt;<br />   注意到在&lt;display:table/&gt;里增加了id属性，这时就在page context里创建了一个隐含对象，指向List里的当前对象，<br />   可以通过(ListObject)pageContext.getAttribute("id")来捕获这个对象。同时还创建了一个id_rowNum对象，同样，可<br />   通过pageContext.getAttribute("testit_rowNum")来捕获，它仅仅代表当前行的行数。<br />   有了这两个隐含对象，就可以通过其他标签来访问，例如Jstl:<br />  &lt;display:table id="row" name="mylist"&gt;<br />    &lt;display:column title="row number" &gt;<br />      &lt;c:out value="${row_rowNum}"/&gt;<br />    &lt;/display:column&gt;<br />    &lt;display:column title="name" &gt;<br />      &lt;c:out value="${row.first_name}"/&gt;<br />      &lt;c:out value="${row.last_name}"/&gt;<br />    &lt;/display:column&gt;<br />  &lt;/display:table&gt;<br />  <br /><strong>六、显示部分数据</strong><br />   显示开始五条数据：通过设定length属性<br />&lt;display:table name="test" length="5"&gt;<br />  &lt;display:column property="id" title="ID" /&gt;<br />  &lt;display:column property="email" /&gt;<br />  &lt;display:column property="status" /&gt;<br />&lt;/display:table&gt;<br />   显示第三到第八条数据：通过设定offset和length属性<br />&lt;display:table name="test" offset="3" length="5"&gt;<br />  &lt;display:column property="id" title="ID" /&gt;<br />  &lt;display:column property="email" /&gt;<br />  &lt;display:column property="status" /&gt;<br />&lt;/display:table&gt;  </p>
		<p>
				<strong>七、对email和url地址的直接连接</strong>
				<br /> &lt;display:table name="test" &gt;<br />  &lt;display:column property="id" title="ID" /&gt;<br />  &lt;display:column property="email" autolink="true" /&gt;<br />  &lt;display:column property="url" autolink="true" /&gt;<br /> &lt;/display:table&gt;<br /> 如果要显示的对象里包含email和url地址，则可以在display:column里直接设定autolink="true"来直接连接<br /> <br /><strong>八、使用装饰模式转换数据显示（写自己的 decorator ）</strong><br />  A、对整个表格应用decorator<br />  &lt;display:table name="test" decorator="org.displaytag.sample.Wrapper" &gt;<br />      &lt;display:column property="id" title="ID" /&gt;<br />      &lt;display:column property="email" /&gt;<br />      &lt;display:column property="status" /&gt;<br />      &lt;display:column property="date" /&gt;<br />      &lt;display:column property="money" /&gt;<br />  &lt;/display:table&gt;<br />    org.displaytag.sample.Wrapper即自己写的decorator，它要继承TableDecorator类，看看它的一个方法：<br />        public String getMoney()<br />    {<br />        return this.moneyFormat.format(((ListObject) this.getCurrentRowObject()).getMoney());<br />    }<br />    很明显，它通过父类的getCurrentRowObject()方法获得当前对象，然后对其getMoney()方法进行‘油漆’<br />  B、对单独的column应用decorator<br />  &lt;display:table name="test"&gt;<br />     &lt;display:column property="id" title="ID" /&gt;<br />     &lt;display:column property="email" /&gt;<br />     &lt;display:column property="status" /&gt;<br />     &lt;display:column property="date" decorator="org.displaytag.sample.LongDateWrapper" /&gt;<br />  &lt;/display:table&gt;<br />    org.displaytag.sample.LongDateWrapper要实现ColumnDecorator接口，它的方法：<br />        public final String decorate(Object columnValue)<br />    {<br />        Date date = (Date) columnValue;<br />        return this.dateFormat.format(date);<br />    }<br />    显然，它获得不了当前对象（因为它实现的是接口），仅仅是获得该对象的columnValue，然后‘油漆’<br />    <br /><strong>九、创建动态连接<br /></strong>   有两种方法创建动态连接：<br />   A、在&lt;display:column/&gt;里通过增加href、paramId、paramName、paramScope、paramProperty属性<br />      href             基本的URL 地址<br />      paramId          加在URL 地址后的参数名称<br />      paramName        数据bean的名称，一般为null（即使用当前List里的对象）<br />      paramScope       数据bean的范围，一般为null<br />      paramProperty    数据bean的属性名称，用来填充URL 地址后的参数值<br />&lt;display:table name="sessionScope.details"&gt;<br />  &lt;display:column property="id" title="ID" href="details.jsp" paramId="id" /&gt;<br />  &lt;display:column property="email" href="details.jsp" paramId="action" paramName="testparam" paramScope="request" /&gt;<br />  &lt;display:column property="status" href="details.jsp" paramId="id" paramProperty="id" /&gt;<br />&lt;/display:table&gt;  <br />    这种方法简便直接，但缺点是无法产生类似details.jsp?id=xx&amp;action=xx的复合URL<br />   B、应用decorator 创建动态连接：<br />&lt;display:table name="sessionScope.details" decorator="org.displaytag.sample.Wrapper" &gt;<br />  &lt;display:column property="link1" title="ID" /&gt;<br />  &lt;display:column property="email" /&gt;<br />  &lt;display:column property="link2" title="Actions" /&gt;<br />&lt;/display:table&gt;<br />   org.displaytag.sample.Wrapper里的方法：<br /> public String getLink1()<br /> {<br />  ListObject lObject= (ListObject)getCurrentRowObject();<br />  int lIndex= getListIndex();<br />  return "&lt;a href=\"details.jsp?index=" + lIndex + "\"&gt;" + lObject.getId() + "&lt;/a&gt;";<br /> }</p>
		<p>
				<br /> public String getLink2()<br /> {<br />  ListObject lObject= (ListObject)getCurrentRowObject();<br />  int lId= lObject.getId();</p>
		<p>  return "&lt;a href=\"details.jsp?id=" + lId<br />   + "&amp;action=view\"&gt;View&lt;/a&gt; | "<br />   + "&lt;a href=\"details.jsp?id=" + lId<br />   + "&amp;action=edit\"&gt;Edit&lt;/a&gt; | "<br />   + "&lt;a href=\"details.jsp?id=" + lId<br />   + "&amp;action=delete\"&gt;Delete&lt;/a&gt;";<br /> }</p>
		<p>
				<strong>十、分页<br /></strong>   实现分页非常的简单，增加一个pagesize属性指定一次想显示的行数即可<br />&lt;display:table name="sessionScope.test" pagesize="10"&gt;<br /> &lt;display:column property="id" title="ID" /&gt;<br /> &lt;display:column property="name" /&gt;<br /> &lt;display:column property="email" /&gt;<br /> &lt;display:column property="status" /&gt;<br />&lt;/display:table&gt;</p>
		<p>
				<strong>十一、排序<br /></strong>   排序实现也是很简单，在需要排序的column里增加sortable="true"属性，headerClass="sortable"仅仅是<br />   指定显示的样式。column里的属性对象要实现Comparable接口，如果没有的话可以应用decorator<br />   defaultsort="1"              默认第一个column排序<br />   defaultorder="descending"    默认递减排序<br />&lt;display:table name="sessionScope.stest" defaultsort="1" defaultorder="descending"&gt;<br />  &lt;display:column property="id" title="ID" sortable="true" headerClass="sortable" /&gt;<br />  &lt;display:column property="name" sortable="true" headerClass="sortable"/&gt;<br />  &lt;display:column property="email" /&gt;<br />  &lt;display:column property="status" sortable="true" headerClass="sortable"/&gt;<br />&lt;/display:table&gt;<br />  注意的是，当同时存在分页时排序仅仅针对的是当前页面，而不是整个List都进行排序<br />  <br /><strong>十二、column 分组<br /></strong>   分组只是需要在column里增加group属性<br />&lt;display:table name="test" class="simple"&gt;<br />  &lt;display:column property="city" title="CITY" group="1"/&gt;<br />  &lt;display:column property="project" title="PROJECT" group="2"/&gt;<br />  &lt;display:column property="amount" title="HOURS"/&gt;<br />  &lt;display:column property="task" title="TASK"/&gt;<br />&lt;/display:table&gt;</p>
		<p>
				<strong>十三、导出数据到其他格式（页面溢出filter??）</strong>
				<br />   在&lt;display:table/&gt;里设定export="true"<br />   在&lt;display:column/&gt;里设定media="csv excel xml pdf" 决定该字段在导出到其他格式时被包不包含，不设定则都包含<br />   &lt;display:setProperty name="export.csv" value="false" /&gt;<br />   决定该种格式能不能在页面中导出<br />&lt;display:table name="test" export="true" id="currentRowObject"&gt;<br />  &lt;display:column property="id" title="ID"/&gt;<br />  &lt;display:column property="email" /&gt;<br />  &lt;display:column property="status" /&gt;<br />  &lt;display:column property="longDescription" media="csv excel xml pdf" title="Not On HTML"/&gt;<br />  &lt;display:column media="csv excel" title="URL" property="url"/&gt;<br />  &lt;display:setProperty name="export.pdf" value="true" /&gt;<br />  &lt;display:setProperty name="export.csv" value="false" /&gt;<br />&lt;/display:table&gt;</p>
		<p>
				<strong>十四、配置属性，覆盖默认<br /></strong>  两种方法：<br />  A、在程序classpath下新建displaytag.properties文件<br />  B、对于单个表格，应用&lt;display:setProperty&gt;标签<br />  具体可配置的属性：<a href="http://displaytag.sourceforge.net/configuration.html">http://displaytag.sourceforge.net/configuration.html</a><br />  <br /><strong>十五、一个完整的例子</strong><br />&lt;display:table name="test" export="true" sort="list" pagesize="8"&gt;<br />  &lt;display:column property="city" title="CITY" group="1" sortable="true"    headerClass="sortable"/&gt;<br />  &lt;display:column property="project" title="PROJECT" group="2" sortable="true" headerClass="sortable"/&gt;<br />  &lt;display:column property="amount" title="HOURS"/&gt;<br />  &lt;display:column property="task" title="TASK"/&gt;<br />&lt;/display:table&gt; <br />   sort="list" 对整个list进行排序<br />   导出数据到其他格式时，group无效</p>
<img src ="http://www.blogjava.net/weibogao/aggbug/56309.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weibogao/" target="_blank">weibogao</a> 2006-07-03 13:23 <a href="http://www.blogjava.net/weibogao/archive/2006/07/03/56309.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于ClassName.class.getResourceAsStream的路径问题</title><link>http://www.blogjava.net/weibogao/archive/2006/06/20/54010.html</link><dc:creator>weibogao</dc:creator><author>weibogao</author><pubDate>Tue, 20 Jun 2006 08:20:00 GMT</pubDate><guid>http://www.blogjava.net/weibogao/archive/2006/06/20/54010.html</guid><wfw:comment>http://www.blogjava.net/weibogao/comments/54010.html</wfw:comment><comments>http://www.blogjava.net/weibogao/archive/2006/06/20/54010.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weibogao/comments/commentRss/54010.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weibogao/services/trackbacks/54010.html</trackback:ping><description><![CDATA[
		<h2>
				<a id="viewpost1_TitleUrl" href="http://blog.dream4ever.org/zhangye/articles/104285.drl">关于ClassName.class.getResourceAsStream的路径问题</a>
		</h2>
		<p>对ClassName.class.getResourceAsStream的路径问题比较模糊，现在把研究的结果写一下：</p>
		<p>ClassName是这个Class的名称，这里假设为MyClass，处于MyPackage.MyChildPackage包中，如果你将source.props文件放在Classes文件夹中的时候，可以这样写ClassName.class.getResourceAsStream(/source.props)</p>
		<p>如果你想把props文件放在包中的时候，假设放到MyPackage.MyChildPackage中的res文件夹，可以这样写ClassName.class.getResourceAsStream(/MyPackage/MyChildPackage/res/source.props)，/代表的是包的.</p>
<img src ="http://www.blogjava.net/weibogao/aggbug/54010.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weibogao/" target="_blank">weibogao</a> 2006-06-20 16:20 <a href="http://www.blogjava.net/weibogao/archive/2006/06/20/54010.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>hibernate中很少用的one-to-one配置注意事项（一对一的本质是一对多的特例）</title><link>http://www.blogjava.net/weibogao/archive/2006/06/19/53800.html</link><dc:creator>weibogao</dc:creator><author>weibogao</author><pubDate>Mon, 19 Jun 2006 07:43:00 GMT</pubDate><guid>http://www.blogjava.net/weibogao/archive/2006/06/19/53800.html</guid><wfw:comment>http://www.blogjava.net/weibogao/comments/53800.html</wfw:comment><comments>http://www.blogjava.net/weibogao/archive/2006/06/19/53800.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weibogao/comments/commentRss/53800.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weibogao/services/trackbacks/53800.html</trackback:ping><description><![CDATA[
		<table class="fixedTable blogpost" cellspacing="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="ellipse">
										<span class="bvTitle" id="subjcns!B3ECA62141FF5FE0!192">
												<strong>hibernate:one-to-one注意事项</strong>
										</span>
								</td>
						</tr>
						<tr>
								<td class="bvh8">
										<strong>
										</strong>
								</td>
						</tr>
						<tr>
								<td id="msgcns!B3ECA62141FF5FE0!192">
										<div>
												<strong>one-to-one</strong>在hibernate中可以用来作为两张表之间的主键关联，这也是hibernate中主键关联的一种用法，这样在一张表中的ID，在生成另外一张表的同时回自动插入到相应的ID字段中去，相应的XML文件设置比较简单，举例如下：<br /><br />    &lt;!-- 建立一对一的到Address的映射，<font color="#ff0000">这个是写在User的XML配置文件中的</font> --&gt;<br />    &lt;!-- <font color="#ff0000">相应的User bean（PO）中也要添加属性 <strong>com.xx.Address </strong> <strong>address</strong></font>--&gt;<br />    <strong><font color="#008000">&lt;one-to-one name="address" cascade="all" class="com.xx.Address"/&gt;<br /></font></strong>   <br />   &lt;!-- cascade的属性设置不再重复了，可以查看hibernate文档 --&gt;<br /><br />    &lt;!-- 建立一对一的到User的映射，<font color="#ff0000">这个是写在Address的XML配置文件中的</font> --&gt;<br />    &lt;!-- <font color="#ff0000">相应的Address bean（PO）中也要添加属性 </font><font color="#ff0000"><strong>com.xx.</strong>User user</font>--&gt; --&gt;<br />    <strong><font color="#008000">&lt;one-to-one name="user" class="com.xx.User" constrained="true"/&gt;<br /></font></strong><br />      为了在Address中使用User中的主键ID值，我们需要设置Address中的主键生成规则，如下所示，采用foreign关键字<br /><br />   <strong><font color="#008000">&lt;id column="ID" name="id" type="long" unsaved-value="0"&gt; <br />      &lt;generator class="foreign"&gt;<br />        &lt;param name="property"&gt;user&lt;/param&gt;  <br />      &lt;/generator&gt;<br />   &lt;/id&gt;<br /></font></strong><br /><br />      <font color="#000000"><strong><em>这里需要注意的是property的属性值必须与上面到User的映射所填写的name属性值一致</em></strong></font>，这样就完成了one-to-one的映射关系。<br /><br />上面的过程都很简单，下面我来说说这里需要注意的地方：<br /><br />  1.   <strong>在设置属性ID的时候必须注意字段的长度，如笔者这样使用oracle的sequence来生成ID，其长度有14位之长，则应选择hibernate类型long，对应的实体中应选择Long，这样不会出现溢出的情况。</strong><br /><br /><br />  2.   在测试的时候必须要注意这两张表之间因为已经存在了一对一的关系，所以我们不能只写<br />         <font color="#008000">user.setAddress(address);<br /></font>         而忽略了<br />         <font color="#008000">address.setUser(user);<br /></font>         这样在做插入的时候会报出attempted to assign id from null one-to-one property: address的错误，这一点初学者会经常犯，笔者也是其中之一。<br /><br /><br /> 3.   如果不写cascade="all"或者写成cascade="none"的话，即使你写了<br />         <font color="#008000">user.setAddress(address);<br />         address.setUser(user);<br /></font>       也不会发生任何事情，只有user会被存储。</div>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/weibogao/aggbug/53800.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weibogao/" target="_blank">weibogao</a> 2006-06-19 15:43 <a href="http://www.blogjava.net/weibogao/archive/2006/06/19/53800.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计模式之食堂版</title><link>http://www.blogjava.net/weibogao/archive/2006/05/29/48728.html</link><dc:creator>weibogao</dc:creator><author>weibogao</author><pubDate>Mon, 29 May 2006 05:09:00 GMT</pubDate><guid>http://www.blogjava.net/weibogao/archive/2006/05/29/48728.html</guid><wfw:comment>http://www.blogjava.net/weibogao/comments/48728.html</wfw:comment><comments>http://www.blogjava.net/weibogao/archive/2006/05/29/48728.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weibogao/comments/commentRss/48728.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weibogao/services/trackbacks/48728.html</trackback:ping><description><![CDATA[
		<div class="tbox">转贴: <br /><br />设计模式是美国一位建筑大师（同时也是信息工程师，画家，机械工程师…的）克里斯蒂安.亚历山大首先提出来的，很快被软件界的技术员们所接受推广，成为软件工程里至高无上的法则之一（有兴趣的人可以找他的《建筑的永恒之道》一书看看，相信会受益非浅）。简单地说就是在面对对象的基础上，包括面对对象，把要设计的整体的各个部分模式化，层次化，细粒度化，高度复用化，可控化，人性化。其中至高无上的原则是建立在需求的基础之上，也就是说，无论做什么，人的需求要放在第一位考虑，从这个角度考虑整个系统是否足够合理。这门学问是非常有趣的，尤其在flash中，可以应用到很多很好玩的实例中去。下面我按照一些通用的设计模式，举例说明，有错误的地方，敬请高手指正：<br /><br />1．抽象工厂模式（Abstract Factory）：<br /><br />食堂里吃的东西很多，而我只想吃一样，那么食堂这个概念对我来说就是个抽象工厂，每个窗口可以看成它的一个具体实现，我要做的就是，去食堂，找到那个窗口，从窗口里买我要吃的东西。<br /><br />举例：flash前台与asp后台的交互，访问某个动态页面，从数据库里取出需要的数据，通常的做法是在后台就把数据集解析成xml字符串，再送给swf。每个业务逻辑模块，所取出的数据结构，也就是xml的结构是不一样的，我们要针对各个具体的业务逻辑，对相应的xml字符串解析，转换成可供显示的数组。也要把flash里文本输入的内容转换成 xml字符串，提交给后台也面<br /><br />AbstractFactory.as<br />//抽象工厂的接口<br />Interface AbstractFactory{<br />//生成xml解析工厂的具体实现<br />function createXmlParseFactory();<br />}<br /><br />XMLParserGetFactory.as<br />//生成解析读入的xml的对象的工厂<br />class XMLParserGetFactory implements AbstractFactory.{<br />var xmlParser;<br />function XMLParserGetFactory(str:String){<br />//生成解析器的具体实现，在后面会提到<br />}<br />function createXmlParser(){<br />return xmlParser;<br />}<br />}<br />XMLParserPostFactory.as<br />//生成解析输出的xml的对象的工厂<br />class XMLParserPostFactory implements AbstractFactory.{<br />var xmlParser;<br />function XMLParserPostFactory(str:String){<br />//生成解析器的具体实现<br />}<br />function createXmlParser(){<br />return xmlParser;<br />}<br />}<br /><br />这样，我们读入某个xml字符串时，在onLoad里面加入<br />//生成对留言板的留言列表解析的工厂<br />var xmlParser=new XMLParserGetFactory(“xmlParseGuestbookList”)<br />xmlParser= XMLParserGetFactory. createXmlParser()<br /><br />备注：抽象工厂模式是软件工程里最常用的设计模式之一，实现过程在于，需要某个类的实例时，通过某个工厂创建，而不是直接创建，坦白地说，它加大了开发工作量，但是对程序的层次性变得分明和降低耦合度有极大帮助。<br /><br /><br />2．生成器模式（builder）：<br /><br />还是那个说法，我要吃东西就去相应的食堂窗口，但我不能吃食堂窗口，窗口里的东西也许不少，我要跟师傅说，要这个，这个，还有这个。<br /><br />举例：我已经建立了 xml解析器的工厂，现在要返回解析器本身，就让工厂创建，返回给我。<br /><br />XMLParserGetFactory.as<br />//生成解析读入的xml的对象的工厂<br />class XMLParserGetFactory implements AbstractFactory.{<br />var xmlParser;<br />function XMLParserGetFactory(str:String){<br />//如果要求留言板列表解析器，就生成一个<br />if(str==” xmlParseGuestbookList”){<br />xmlParser=new xmlParserGuestbookList();<br />}<br />}<br />function createXmlParser(){<br />//返回所要求的解析器<br />return xmlParser;<br />}<br />}<br /><br />AbstractXmlParser.as<br />//抽象xml解析器<br />Interface AbstractXmlParser{<br />function ParseXml();<br />}<br />xmlParserGuestBookList.as<br />//留言板列表解析器<br />Class xmlParserGuestBookList implements AbstractXmlParser{<br />//把xml字符串里的内容解析到一堆数组里<br />function ParseXml(xml:XML,arrayID:Array,arrayTitle:Array){<br />//具体循环操作<br />}<br />}<br /><br />使用的时候：<br />var xmlParser=new XMLParserGetFactory(“xmlParseGuestbookList”)<br />xmlParser= XMLParserGetFactory. createXmlParser(xml,arrayID,arrayTitle);<br /><br />3．工厂方法模式（Factory Method）<br />我到了食堂窗口，如果师傅跟那儿抽烟，我还是吃不着东西。我说：师傅，打饭！师傅才会完成打饭这一动作。这是工厂方法模式，抽象工厂的实现通常用工厂方法模式来完成。<br /><br />举例：还是上一条，我本来想用一句话带一个参数就实现具体xml解析器的实现，无奈构造函数没有返回值，所以必须用<br />xmlParser= XMLParserGetFactory. createXmlParser(xml,arrayID,arrayTitle);<br />实现。<br /><br />备注：抽象工厂模式，生成器模式和工厂方法模式需要灵活应用。<br /><br /><br />4．单件模式（singleton）<br /><br />我前面一个人买了一条巨大的鸡腿，我说我也要一条，师傅说，就这一条<br /><br />举例：单件模式的应用是相当广泛的，它确保每个实例在全局范围内只被创建一次，我们flash里的mc大多数是单件。内核里的核心组件也只是单件，比如我的消息映射列表（见后）。<br />按照单件模式的严格定义，应该让类负责保存它的唯一实例。但是我在Flash里还想不到怎么实现这一点，或者实现它的意义所在，但另外一点我们可以做到，就是在全局范围内只提供该对象的唯一访问点。这可以由层次关系做到，把对该对象的访问具体实现全部封装在下层，只给上层提供唯一的访问点（原因是，上层不知道这个单件的具体信息，比如路径）。<br />看我内核文件的一部分：<br />Core.as<br />//内核<br />class Core {<br />var strucGlobalParam:ConfigVariables;<br />//站点信息<br />var xmlConfig:XML;<br />//站点信息的xml化对象<br />var ArrayStructureInitial:Array;<br />//用来提供给loadObject对象的数组<br />var ArrayForBtn:Array;<br />//用来初始化导航条组件的数组<br />var objInitial:loadObject;<br />//读取影片的对象<br />var objMessageMap:MessageMap;<br />//消息映射组件<br />……<br />}<br />这是我的内核类也就是全站最核心类的数据结构。里面的数据只有通过下层的BasicMovie，OriginalFunctionObject等类（见后）直接访问。<br /><br />备注，核心思想是，确保只有一个。<br /><br /><br />5．原型模式（protoType）<br /><br />到小炒窗口，看前面的哥们炒的青椒炒肉不错的样子。“师傅，我也要这样的。”<br /><br />举例：这对flash的用户来说再熟悉不过了，我们经常用duplicateMovieClip()和<br />attachMovie()这两个函数。按照一个原型复制相应的实例，各自执行自己的动作。在我的blog列表，导航条的生成。。几乎用得到多项数据的地方就要用原型模式。<br /><br />6.责任链模式，7.中介者模式，8.观察者模式：<br /><br />食堂里厨房最远的窗口没熬白菜了，要告诉厨房，快送过来。<br />责任链模式：一个窗口一个窗口地传话，一直传到食堂，食堂一看不妙，赶快做好送过去。<br />中介者模式：专门派一个人负责传话，任何窗口没菜了，就要这个人赶快去厨房催。<br />观察者模式：厨房那边派一个盯着，看哪个窗口没菜了就开始大声嚷嚷。<br /><br />举例：之所以要把这三个设计模式放在一块儿，是因为我在我的站里面结合这三者建立了一个好玩的东西，可以说是我的网站的核心所在。它解决了我的flash里面各个mc的通信问题。<br />比如，影片A放完了，要通知影片B开始播放，直接的做法是在A的最后一帧，写从A到B的相对路径或B的绝对路径，让B play()。这样做A和B的耦合性是相当高的，也就是说，相互依赖程度太高。运用设计模式的解决方案如下：<br /><br />MessageMap.as<br />//消息映射类<br />class MessageMap extends Object {<br />var Message:String;<br />var MessageWatcher:Function;<br />var Target;<br />var MessageList:Array;<br />var Num_Msg:Number;<br />function MessageMap() {<br />Num_Msg = 0;<br />MessageList = new Array();<br />Message = "HANG_UP";<br />MessageWatcher = function (prop, oldVar, newVar, Param) {<br />for (var i = 0; i<num_msg+1; i++)="" {<br="">if (newVar == MessageList[i][0]) {<br />MessageList[i][1].apply(MessageList[i][3], MessageList[i][2]);<br />if (!MessageList[i][4]) {<br />MessageList.splice(i, 1);<br />Num_Msg--;<br />i-=1;<br />}<br />}<br />}<br /><br />};<br />this.watch("Message", MessageWatcher, "test");<br />}<br />function SendMessage(Msg:String, mc:MovieClip) {<br />Message = Msg;<br />}<br />function UpdateMessageMap(Msg:String, objFunction:Function, ArrayParam:Array, objRefer,IsMultiUsed:Boolean) {<br />MessageList[Num_Msg] = new Array();<br />MessageList[Num_Msg][0] = new String();<br />MessageList[Num_Msg][0] = Msg;<br />MessageList[Num_Msg][1] = new Function();<br />MessageList[Num_Msg][1] = objFunction;<br />MessageList[Num_Msg][2] = new Array();<br />MessageList[Num_Msg][2] = ArrayParam;<br />MessageList[Num_Msg][3] = objRefer;<br />MessageList[Num_Msg][4] = IsMultiUsed;<br />Num_Msg++;<br />}<br />function DeleteMessageMap(objRefer) {<br />for (var i = 0; i<num_msg; i++)="" {<br="">if (MessageList[i][2] == objRefer) {<br />MessageList.splice(i, 1);<br />Num_Msg--;<br />}<br />}<br />}<br />}<br /><br />class SubTemplateMovie extends BaseMovie {<br />var MovieRemoveFunction:Function;<br />function SubTemplateMovie() {<br />this.stop();<br />MovieStartFunction = function () {<br />Lock();<br />this.play();<br />};<br />MovieEndFunction = function () {<br />Lock();<br />this.play();<br />};<br /><br />MovieRemoveFunction = function () {<br />this.stop();<br />SendMsg("SUB_TEMPLATE_REMOVED", this);<br />_parent.unloadMovie();<br />};<br />MovieMainFunction = function () {<br />stop();<br />SendMsg("SUB_TEMPLATE_OPEN", this);<br />};<br />UpdateMessage("LOADING_BAR_OVER", MovieStartFunction, null, this, false);<br />UpdateMessage("BACK_TO_INDEX", MovieEndFunction, null, this, false);<br />}<br />}<br /><br />大概机制就是，影片提前提交一个数据结构，声明，如果有影片提交这条消息，就执行这条函数。原理在于，发送消息，实际上是把消息映射的一个变量赋值，由于消息映射继承自object类，可以用watch方法对该变量进行监视，一旦改变，在已经提交上来的消息映射列表里检查，如果有，执行对应函数。实际上这也造成了一定程度的耦合性，但是我们已经成功地把耦合性控制在了下级类，上级子类完全不用理会这一套消息机制的实现过程。<br /><br />这个机制可以让我们对oop的真正目的有更深的看法。举例说明，影片A播放完了，就声明自己播放完了，至于我播完了你要干什么，不是我的事，我不控制你。所谓的降低耦合度是个相对概念，别忘了在计算机最底层，耦合度还是一样，cpu总是不断的直接或间接寻址，但我们需要做的是，改变系统的拓扑结构，把耦合度控制在某一个范围之内。<br /><br />整个消息映射类相当于一个中介者，内部生成一个观察器，一旦触发消息，以责任链的方式执行。<br /><br /><br />9.桥接模式（Bridge）<br /><br />菜太淡，不合有些人的胃口，所以要求食堂的师傅，专门开一个窗口，专门在做好的菜里多加些辣椒。<br /><br />我在自己的站里运用了桥接模式：所有的影片都继承自我定义的BasicMovie 类（BasicMovie继承自MovieClip类），但是在四个下级栏目的影片里，需要定义相同的方法和事件来响应消息，BasicMovie没有这些函数，不符合要求，这时候，在四个影片里都写一遍是愚蠢的，我又写了一个SubTemplateMovie类继承自BaseMovie，里面加进一些通用的方法，然后四个下级模板影片都继承它，这样大大简化了后期开发。<br /><br />BasicMovie.as<br />//基类影片<br />/所有影片的原始类，一切影片的父类都继承此类而来<br />class BaseMovie extends MovieClip {<br />var isLocked:Boolean;<br />//初始类开始影片函数<br />var MovieStartFunction:Function;<br />//初始类影片主功能函数<br />var MovieMainFunction:Function;<br />//初始类结束影片函数<br />var MovieEndFunction:Function;<br />var GlobalParam<br />//初始类构造函数<br />function BaseMovie() {<br />}<br />//<br /><br />//发送消息<br />function SendMsg(Msg:String, Mc:MovieClip) {<br />_root.objCore.objMessageMap.SendMessage(Msg, Mc);<br />}<br />//添加消息映射<br />function UpdateMessage(Msg:String, MsgMapFunction:Function, ArrayParam, obj, IsMultiUsed) {<br />_root.objCore.objMessageMap.UpdateMessageMap(Msg, MsgMapFunction, ArrayParam, obj, IsMultiUsed);<br />}<br />//删除消息映射<br />function DeleteMessage(obj) {<br />_root.objCore.objMessageMap.DeleteMessageMap(obj);<br />}<br />function GetGlobalParam() {<br />GlobalParam=_root.objCore.strucGlobalParam;<br />}<br />}<br /><br />SubTemplateMovie.as<br />//下级模板影片类<br />class SubTemplateMovie extends BaseMovie {<br />var MovieRemoveFunction:Function;<br />function SubTemplateMovie() {<br />this.stop();<br />MovieStartFunction = function () {<br />Lock();<br />this.play();<br />};<br />MovieEndFunction = function () {<br />Lock();<br />this.play();<br />};<br /><br />MovieRemoveFunction = function () {<br />this.stop();<br />SendMsg("SUB_TEMPLATE_REMOVED", this);<br />_parent.unloadMovie();<br />};<br />MovieMainFunction = function () {<br />stop();<br />SendMsg("SUB_TEMPLATE_OPEN", this);<br />};<br />UpdateMessage("LOADING_BAR_OVER", MovieStartFunction, null, this, false);<br />UpdateMessage("BACK_TO_INDEX", MovieEndFunction, null, this, false);<br />}<br />}<br />注（关于消息映射机制看 责任链模式）<br /><br /><br />10.适配器模式（Adapter）<br /><br />我要一碗汤，但是只有纸饭盒，还没勺，所以食堂的师傅给了我一次性的汤碗和勺，这叫适配器。<br /><br />适配器解决的是某一个类的对外接口不合用的问题，可能是参数或者返回值类型不符等问题造成的，这时候我们需要在工作对象和这个类之间加一层间接的层次。<br />这个模式我在底层的数据交换层用过。我说过，flash和asp.net之间交换数据全以xml为载体。返回xml在底层只有三层，数据库操作，数据操作，数据显示，由数据操作层返回给数据显示层一个xml字符串就可以了。然后我就遇到一个小问题，在另一方面，我需要提交数据到数据库，也是提交一个xml字符串，但是我需要数据库里对应的表的数据集的xml表现形式的xsd验证！（一口气说完，差点没憋死）。就是说我至少需要取出这个表里的一条记录，问题在于，我封装的类从来只返回xml，没有返回xsd的。解决办法就是适配器，新建一个项目，加了一层专用于获得xml验证格式，这样就完成了不同接口之间的转换。<br /><br />备注：适配器和桥接很象，都是在已有类不符合要求的时候，加入一层间接的元素以达到目的。不同的是适配器是解决不兼容接口之间的转换，桥接一般不涉及这个问题，只是完成一个一对多的转换。<br /><br /><br />11.外观模式（Facade）<br /><br />每天都要去食堂，每个人去不同的窗口吃不同的菜，很累，今天全寝室推举猴子去打饭：<br />你吃这个，三两饭，我吃那个，五两饭，所有人都只跟猴子一个人交涉，食堂所有的师傅也只见猴子一个人。<br /><br />举例：这个模式在程序的上下层的通信之间可以应用得十分广泛。Asp的每个模块要去不同的数据，访问数据库的不同表，就要跟不同的下层数据访问组件打交道。就是说，每个mc模块必须知道，我要去哪个具体的数据访问组件取数据。每个模块要维持自己的一个，至少是字符串。<br />如果运用外观模式。我们可以让所有的需要数据交互的mc访问同一个aspx页面，比如getStrXml.aspx。只要传送一个标示符，就可以通知这个唯一的取数据的叶面，访问哪个下层组件获取数据。下层组件不知道哪个mc要求数据，mc也不知道数据的具体来源，这样，上下层之间互相都显得不透明。这就降低了耦合度。<br /><br /><br />12.代理模式（Proxy）<br /><br />可能我们不是每个人每天都想吃饭，所以我们要求猴子每天中午必须在寝室，如果我们要吃，他就去，如果我们都不吃，他爱干嘛干嘛。<br /><br />举例：这恐怕是每个人在flash里都会无意中用到的模式。比如，一个网站，它的下级栏目不用在整个网站初始化的时候一开始就读进来，但是我们要确保，在浏览者想看并且点击导航条上的某个按钮时，能够正确地读进相应的影片文件，前提是，我们必须在内部保留一个索引，可以称作代理。通常是一个空mc<br /><br /><br />13.策略模式：（strategy）<br /><br />我每天先在食堂找座位，再打饭，再打菜，再买杯酸奶。这已经模式化。要是食堂有服务员，我也会要他这么做。<br /><br />举例，策略模式是把一系列的算法封装起来，形成一个类。这个模式几乎是随时随地都可以整合到别的模式里去的，我的那一堆xml解析器实际上就是策略模式的应用，这个模式还应用到我网站的下层，因为flash提交给aspx页面的数据也是xml字符串，下层模块也需要相应的解析算法。同样的，我把对xml的解析封装进了一个类。<br /><br />//Cs文件里的解析函数<br /><br />Class DataModel.BlogMsgs{<br />…<br />Public DataSet parseXML(string strXml){<br />DataSet ds=new DataSet(); <br />//。。把xml装载到DataSet 里<br />Return ds<br />}<br />…<br />}<br /><br /><br />14.享元模式（Flyweight）<br /><br />东西不够吃？给你摆20面镜子~<br />师傅，东西还是只有一份。。。<br /><br />关于这个模式十分抱歉，我暂时还没想到在flash显示层里面的实现。需要举例说明的是，浏览器的机制是，在有大量文字的英文文档里，相同的字母共享一个Flyweight，在内存里其实只占一份空间，然后在文档不同的地方显示，这样对于大量细粒度的效果来说，可以节省很多资源。在下层，我们可以做到的就是，对某个全局对象只在某处真正保存，任何对象想要这个全局对象，只引用它而不复制它。<br /><br />在显示层里有哪位想到了该怎么做请一定赐教。<br /><br /><br />15.访问者模式（Visitor）<br /><br />只要愿意，我随时都可以跑到哪个窗口打要吃的东西，前提是，我必须跑这一趟。<br /><br />举例：我说过，我的所有mc都继承自BasicMovie这个类，但不是我的所有mc都要从后来获取数据库数据。获取数据库数据所要访问的信息，比如ip，路径，文件保存在配置文件里，初始化的时候读入内核，并且只有内核那里有一份。在BasicMovie里加入对这些全局变量的引用是不合适的，因为只有少数mc要用到，而且由于某些原因我无法再使用桥接模式（我已经有了SubTemplateMovie，不能多继承），所以我用了访问者模式。<br /><br />BasicMovie.as<br /><br />//获取全局变量<br />function GetGlobalParam() {<br />GlobalParam=_root.objCore.strucGlobalParam;<br />}<br /><br />如果上级mc不执行这个函数，是不能获取全局变量的，如果要用，就执行。<br />也就是说，需要的时候，我去访问它。<br /><br />备注：声明一个visit操作，使得访问者可以正确访问需要的类。<br /><br /><br />16.状态模式（state）<br /><br />我今天想吃面，师傅问我：要什么料？西红柿鸡蛋，排骨还是牛肉？<br /><br />举例：状态模式是指将对象当前的某些状态局部化，当对象改变状态时，看起来好像改变了类。例子还是我的滚动条。如果要滚动的是文本框，就要引用一个TextField的Scroll,maxscroll属性，如果是mc，引用的是_y,_height属性，我用一个参数将二者区分，由一个if语句控制，让滚动条可以自由区别状态。<br />另外一个解决方案是定义ScrollBar的不同子类，这两者本质区别不大，在状态比较多时，可能要维持一个庞大的if算法，这样就用生成子类的方法比较好。<br /><br />ScrollBar.as<br />//滚动条组件<br />function BindTo(mc,type:String,intMcHeight:Number,yinitial:Number){<br />ScrollType=type;<br />if(type=="TXT"){<br />scrollTxt=mc;<br />}<br />if(type=="MC"){<br />initialY=yinitial;<br />McHeight=intMcHeight;<br />scrollMc=mc;<br />} <br />}<br />function Scroll() {<br />if(ScrollType=="TXT")<br />this.onEnterFrame = function() {<br />scrollTxt.scroll = scrollTxt.maxscroll*mcBlock._y/(BgLength-BlockLength*3/2)<br />};<br />if(ScrollType=="MC"){<br />this.onEnterFrame=function(){<br />if(scrollMc._height&gt;McHeight){<br />scrollMc._y=initialY-(scrollMc._height-McHeight)*mcBlock._y/(BgLength-BlockLength*3/2)}<br />}<br />}<br />}<br /><br />备注：这也是常见模式，在flash的逻辑控制里尤其随处可见<br /><br /><br />17.装饰模式（Decorator）<br /><br />在食堂吃饭，没筷子怎么行？我是从来不带饭盆的。师傅很人性化，每个窗口都放着一大把筷子，随用随拿。<br /><br />这个模式如果用好，有的地方可以很省力。比如，我网站里的滚动条：<br /><br />ScrollBar.as<br />//滚动条组件<br />class ScrollBar extends BaseMovie {<br />var BgLength:Number;<br />var BlockLength:Number;<br />var mcBlock:MovieClip<br />var Width:Number;<br />var ScrollType;<br />var scrollTxt:TextField;<br />var scrollMc:MovieClip;<br />var McHeight:Number<br />var initialY:Number<br />function ScrollBar() {<br />}<br />function InitialScrollBar(BgLength, BlockLength) {<br />this.BlockLength = BlockLength;<br />this.BgLength = BgLength;<br />}<br />function BindTo(mc,type:String,intMcHeight:Number,yinitial:Number){<br />ScrollType=type;<br />if(type=="TXT"){<br />scrollTxt=mc;<br />}<br />if(type=="MC"){<br />initialY=yinitial;<br />McHeight=intMcHeight;<br />scrollMc=mc;<br />} <br />}<br />function Scroll() {<br />if(ScrollType=="TXT")<br />this.onEnterFrame = function() {<br />scrollTxt.scroll = scrollTxt.maxscroll*mcBlock._y/(BgLength-BlockLength*3/2)<br />};<br />if(ScrollType=="MC"){<br />this.onEnterFrame=function(){<br />if(scrollMc._height&gt;McHeight){<br />scrollMc._y=initialY-(scrollMc._height-McHeight)*mcBlock._y/(BgLength-BlockLength*3/2)}<br />}<br />}<br />}<br />function ScrollMc() {<br /><br />}<br />function StopScroll() {<br />this.onEnterFrame=null;<br />}<br />function Reset(){<br />mcBlock._y=0;<br />}<br />}<br /><br />核心函数是BindTo（），把这个滚动条的实例绑定到某个动态文本框或者某个mc上，就可以实现滚动。<br /><br />备注：装饰模式的思想是，在不影响其他对象的情况下，以动态，透明的方式给单个对象添加职责。<br /><br /><br />18.组合模式（composite）<br /><br />我中午吃六两饭，猪肉炖粉条，辣子鸡，鱼丸，咸鸭蛋，外加两杯酸奶（猪！）<br />这些东西都是对象，他们共同组成了我的午饭。<br /><br />举例：应该说在Flash里组合模式是无处不在的，因为只要还有mc的嵌套，就有组合模式存在。几个mc装在一个mc里，这个装载用的mc称作容器。<br />但是就这么说，恐怕没人会重视这个模式，因为不管理不理解他我们都在用。他的确有很多种实现方式，我的方式之一是这样的。<br /><br />//blog.as<br />我的Blog<br />class Blog extends BaseMovie {<br />//blog第一界面，包括日记列表，日历，最近留言<br />var mcBlogList: mcBlogList;<br />//blog第二界面，包括日记全文，回复，对该日记的留言。<br />var mcBlogDairy:MovieClip;<br />var currentState:String;<br />var currentDairyID:Number;<br />function blog(){<br />} <br />}<br /><br />mcBlogList.as<br />//blog第一界面<br />class mcBlogList extends BaseMovie {<br />//最近留言<br />var recentMsgs:blogMsgsSC;<br />//日记列表<br />var blogList:BlogList;<br />//日历<br />var calendar:CalenderForBlog;<br /><br />｝<br />mcblogDairy.as<br />//blog第二界面<br />class mcBlogDairy extends BaseMovie {<br />//日记全文显示<br />var BlogDairy:BlogDairy;<br />//留言板<br />var GuestBook:BlogInputMsg;<br />//留言列表显示<br />var BlogMsgs:BlogMsgs;<br />}<br /><br />然后里面每个组件都还包含另外的组件，比如滚动条，动态文本框什么的，我想说的是，我写在as里的mc嵌套模式并不一定就符合fla文件里的具体物理嵌套模式，有很多装饰性的mc不需要包含进来，也有很多具体原因，需要改写路径。比如在BlogDairy下，滚动条的实际路径是BlogDairy.mc1.ScrollBar，不做成BlogDairy.ScrollBar可能是因为我需要mc1的动画，也可能是别的具体原因。但是我们可以在mc1的时间轴上加一句<br />_parent. ScrollBar =This.ScrollBar<br />把路径指向改写，达到我们要使用的模式，ScrollBar就是BlogDairy的直接成员。另外我没有语句初始化mc，我习惯在库里设置mc的linkage。<br /><br />备注：虽然组合模式是每个人必不可少要用的，但正因为如此，我们可以想出他更多更好更灵活的实现方式<br /><br /><br />19.备忘录模式（memento）<br /><br />～师傅，晚上的鸡腿没中午的新鲜啊。<br />～胡说！这就是中午的。<br /><br />举例：开个玩笑，上面两句话不是备忘录模式的本意，实际上我一时想不出在食堂里备忘录是什么样子。备忘录的意思是，在不破坏对象封装型的前提下，保存对象的当前状态，当需要时，恢复这个状态或提取这个状态。<br /><br />备忘录被广泛地运用到逻辑关系里，它似乎是目前我提到的唯一跟时间有关的模式，在控制论里可以涉及到因果系统。备忘录的应用非常广泛，最常见的是浏览器或网站的后退功能，返回到上一个界面，但是在我的站里没有用到，因为我的站是树状拓扑结构，每个栏目都只能唯一地从主界面进入或退回到主界面，那些网状拓扑结构的站点，每个栏目都可以通向其他的任何栏目，很可能就需要这么一个功能，其实现方法往往是维持一个堆栈型的数组。<br /><br />另外一个我想实现的东西是网站内部自动记录，由于某些原因我暂时没有把它加到网站里。很简单，就是监视浏览者的每一步操作，在哪个栏目，停了多久，做了些什么之类，如果离开了，下次访问网站时让他选择是否直接进入上次浏览的界面（比如他上次在看我写的小说而没看完）。这个可以通过sharedObject实现，差不多也就是flash内部的cookie。<br /><br />备注：备忘录的实现要求还是很高的，在提取对象状态的时候不要破坏对象的封装性。理想的备忘录作为一个对象需要两个借口，一个给管理者，它不知道备忘录里封装了什么状态，只负责地把状态移交给需要的对象，一个留给原发者，原发者只能了解并操作备忘录里封装的状态，不能做别的操作。<br /><br /><br />小结： <br /><br />小结：我会随时补充这篇文章。但是我要举的一些例子暂时已经说完了。其实设计模式远远不止这几种，经典的有２３种，我已知的有４１种，而这里只有１９种，还有命令模式，解释器模式，迭代器模式，模板方法模式我没写到。我的站还用了一些我没有提到的，自己都还没细想过的设计模式。但是一一列举其实是意义不大的，有兴趣的同志们要做的就是接触一下这些设计模式的细节和思想，然后统统忘掉，就和张无忌学太极拳，先学后忘是一样的。招式要看，要学，但是要领会其中的深意，灵活地，创造地，相互结合，融会贯通地使用招式，不能拘泥于招式，更不能为了用招而用招。设计模式作为UML的重要组成部分，能够极大程度地促进我们的开发效率，使我们养成好的书写习惯，做出更人性，更和谐，更清晰，复用性和可控性更高的作品。<br />不要说你不是程序员，就可以跟着感觉走，随心所欲，当然我们无权干涉。我也说了，as本来就是想怎么写就怎么写，但接不接触，学不学习先进的思维模式，这也是你的自由。更不要说你是搞艺术的，头脑偏重感性，不适合接触这些，我之所以要顺带拿食堂举例，是想说明，我要说的其实是就Christian Alexander先生的，建筑的永恒之道，无论是建筑本身，还是任何软件工程，或者Flash 的as，甚至Flash 的矢量绘图，美工，平面设计，一直到世界这一整体，无不是遵循一个结构化的，由模式构成的永恒之道，有着惊人的高度相通和相似性。参悟了这一点，不仅对做Flash，对整个生活都会有新的看法。区别仅仅在于，从哪里开始入手思考，在这里，可以从Flash开始。</num_msg;></num_msg+1;></div>
<img src ="http://www.blogjava.net/weibogao/aggbug/48728.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weibogao/" target="_blank">weibogao</a> 2006-05-29 13:09 <a href="http://www.blogjava.net/weibogao/archive/2006/05/29/48728.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Java2 RMI 入门</title><link>http://www.blogjava.net/weibogao/archive/2006/05/26/48384.html</link><dc:creator>weibogao</dc:creator><author>weibogao</author><pubDate>Fri, 26 May 2006 09:16:00 GMT</pubDate><guid>http://www.blogjava.net/weibogao/archive/2006/05/26/48384.html</guid><wfw:comment>http://www.blogjava.net/weibogao/comments/48384.html</wfw:comment><comments>http://www.blogjava.net/weibogao/archive/2006/05/26/48384.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weibogao/comments/commentRss/48384.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weibogao/services/trackbacks/48384.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" width="100%" border="0">
				<tbody>
						<tr>
								<td class="down" align="middle" height="40">
										<strong>
												<font style="FONT-SIZE: 14px">Java2 RMI 入门</font>
										</strong>
								</td>
						</tr>
						<tr>
								<td align="middle" height="22">日 期：2004-12-30 14:36:22  出 处：原创  作 者：admin  阅 读：<font color="#990000">128</font>次</td>
						</tr>
						<tr>
								<td> </td>
						</tr>
						<tr>
								<td>
										<table cellspacing="0" cellpadding="0" width="95%" align="center" border="0">
												<tbody>
														<tr>
																<td class="thin" style="FONT-SIZE: 14px">RMI从Java1.1开始，RMI使得运行于不同JVM(包括不同主机)上的Java应用程序可以彼此通话。 <br />即：一个JVM中的Java应用程序可以调用另一JVM上的对象（远程对象）所定义的方法。 <br />Java RMI有着重要的意义。RMI在Java网络编程和高级编程中都有重要的应用，如EJB, Jini等。 <br />Java2对RMI做了很多增强和改进，如安全性，动态代码下载等。 <br />本文给出了一个最简单的例子，以说明其中的一些基本原理。本文的特点是注重了实际开发和真正的运行 <br />环境相结合，模拟了RMI真正的开发和运行过程。 <br /><br />1. 实现远程接口，生成远程对象，存根（Stub）和框架(Skeleton) <br /><br />实现远程接口,远程接口告诉JVM：实现了该接口的对象可以远程调用及有哪些方法可以调用。 <br />本例子中定义了sayHello（）。由于远程调用会涉及到网络通讯，因此这些方法都要抛出RemoteException. <br />远程接口和远程对象可以由A开发，并把远程接口(Hello)d打包分给Client端开发者B。 <br /><br />建立f:\server目录，把Hello.java和HelloImpl.java拷贝到该目录中。 <br /><br />// Hello.java <br />package jdeveloper.rmi; <br /><br />import java.rmi.Remote; <br />import java.rmi.RemoteException; <br /><br />public interface Hello extends Remote { <br />String sayHello() throws RemoteException; <br />} <br /><br />生成远程对象. <br />// HelloImpl.java <br />package jdeveloper.rmi; <br /><br />import java.rmi.Naming; <br />import java.rmi.RemoteException; <br />import java.rmi.RMISecurityManager; <br />import java.rmi.server.UnicastRemoteObject; <br /><br />public class HelloImpl extends UnicastRemoteObject <br />implements Hello { <br /><br />public HelloImpl() throws RemoteException { <br />super(); <br />} <br /><br />public String sayHello() { <br />return "Hello World!"; <br />} <br /><br />public static void main(String args[]) { <br /><br />// Create and install a security manager <br />if (System.getSecurityManager() == null) { <br />System.setSecurityManager(new RMISecurityManager()); <br />} <br />try { <br />Hello obj = new HelloImpl(); <br />// Bind this object instance to the name "HelloServer" <br />Naming.rebind("HelloServer", obj); <br />System.out.println("HelloServer bound in registry"); <br />} catch (Exception e) { <br />System.out.println("HelloImpl err: " + e.getMessage()); <br />e.printStackTrace(); <br />} <br />} <br />} <br />存根（Stub）和框架(Skeleton) <br />f: <br />cd \server <br />javac -d . Hello.java <br />javac -d . HelloImpl.java <br />rmic -d . jdeveloper.rmi.HelloImpl <br /><br />jar cvf hello.jar jdeveloper\rmi\Hello.class 把hello.jar分发给Client端的开发者B。 <br /><br />存根（Stub）的存放！ <br />存根（Stub）是动态下载的。Client通过存根（Stub）和远程对象的框架(Skeleton)通讯，对Client来 <br />讲就象操作本地对象一样。在大多数情况下，可下载的代码放到http服务器的某个目录中。本例子放到http://hjc/rmi下。 <br />hjc:机器名，rmi:http的一个目录。如果只是单机测试则可以放到某个目录下 如f:\serverclasses. <br />本文将对以上两种方法都给出运行的步骤（policy文件和bat文件）。 <br /><br />2. 实现Client端程序 <br />// HelloClient.java <br />package jdeveloper.rmi; <br />import java.rmi.RMISecurityManager; <br />import java.rmi.Naming; <br />import java.rmi.RemoteException; <br />import java.rmi.NotBoundException; <br /><br />public class HelloClient { <br />public static void main(String args[]) throws Exception{ <br />System.setSecurityManager(new RMISecurityManager()); <br />Hello RemoteObj = (Hello)Naming.lookup("//"+ args[0] +"/HelloServer"); <br />System.out.println(RemoteObj.sayHello()); <br />} <br />} <br /><br />建立f:\client目录，把HelloClient.java拷贝到该目录中。 <br />建立f:\clientclasses目录，把hello.jar拷贝到该目录中。 <br />f: <br />cd \client <br />javac -classpath %CLASSPATH%;f:\clientclasses\hello.jar -d . HelloClient.java <br /><br />3. 运行程序 <br />启动DOS窗口 <br />set classpath= <br />start rmiregistry <br /><br />A.以单机方式运行 <br />建立f:\serverclasses\jdeveloper\rmi目录 <br />f: <br />cd f:\serverclasses <br />copy f:\server\hello.jar . <br />copy f:\server\jdeveloper\rmi\HelloImpl_Stub.class f:\serverclasses\jdeveloper\rmi\ <br />jar xvf hello.jar <br /><br />启动新的DOS窗口 <br />把 starthelloserver.bat 和 rmiserver.policy 放到f:\server\ <br />运行 starthelloserver <br /><br />starthelloserver.bat <br />SET CP=f:\server;f:\serverclasses\hello.jar <br />echo using classpath: %CP% <br />java -classpath %CP% -Djava.rmi.server.codebase=file:/f:\serverclasses/ <br />-Djava.rmi.server.hostname=hjc -Djava.security.policy=rmiserver.policy jdeveloper.rmi.HelloImpl <br /><br />rmiserver.policy <br />grant { <br />permission java.net.SocketPermission "*:1024-65535", <br />"connect"; <br />}; <br /><br />启动新的DOS窗口 <br />把 starthelloclient.bat 和 rmiclient.policy 放到f:\client\ <br />运行 starthelloclient <br /><br />starthelloclient.bat <br />@echo off <br />set CP=f:\client;f:\clientclasses\hello.jar <br />echo using classpath %CP% <br />@echo on <br />java -classpath %CP% -Djava.rmi.server.codebase=file:/f:\serverclasses/ <br />-Djava.security.policy=rmiclient.policy jdeveloper.rmi.HelloClient %1 <br />rmiclient.policy <br />grant { <br />permission java.net.SocketPermission "*:1024-65535", <br />"connect"; <br />permission java.io.FilePermission <br />"f:\\serverclasses\\-", "read"; <br />}; <br /><br />B.以网络方式运行 <br />建立 apache_path\htdocs\rmi\jdeveloper\rmi目录 <br />cd apache_path\htdocs\rmi <br />copy f:\server\hello.jar . <br />copy f:\server\jdeveloper\rmi\HelloImpl_Stub.class apache_path\htdocs\rmi\jdeveloper\rmi <br />jar xvf hello.jar <br />把 starthellohttpserver.bat 和 rmihttpserver.policy 放到f:\server\ <br /><br />启动新的DOS窗口 <br />运行 starthellohttpserver <br />starthellohttpserver.bat <br />SET CP=f:\server;f:\serverclasses\hello.jar <br />echo using classpath: %CP% <br />java -classpath %CP% -Djava.rmi.server.codebase=http://hjc/rmi/ <br />-Djava.security.policy=rmihttpserver.policy jdeveloper.rmi.HelloImpl <br />rmihttpserver.policy <br />grant { <br />permission java.net.SocketPermission "*:1099", "accept, connect, listen, resolve"; <br />permission java.net.SocketPermission "*:80", "accept, connect, listen, resolve"; <br />}; <br /><br />启动新的DOS窗口 <br />把 starthellohttpclient.bat 和 rmihttpclient.policy 放到f:\client\ <br />运行 starthellohttpclient <br />starthellohttpclient.bat <br />@echo off <br />set CP=f:\client;f:\clientclasses\hello.jar <br />echo using classpath %CP% <br />@echo on <br />java -classpath %CP% -Djava.rmi.server.codebase=http://hjc/rmi/ <br />-Djava.security.policy=rmihttpclient.policy jdeveloper.rmi.HelloClient %1 <br /><br />rmihttpclient.policy <br />grant { <br />permission java.net.SocketPermission "*:80", "connect"; <br />permission java.net.SocketPermission "*:1024-65535", "connect"; <br />}; <br /></td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
						<tr>
								<td>
										<table cellspacing="0" cellpadding="0" width="95%" align="center" border="0">
												<tbody>
														<tr>
																<td> </td>
														</tr>
												</tbody>
										</table>
								</td>
						</tr>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/weibogao/aggbug/48384.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weibogao/" target="_blank">weibogao</a> 2006-05-26 17:16 <a href="http://www.blogjava.net/weibogao/archive/2006/05/26/48384.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>设计模式的有趣解释－追MM </title><link>http://www.blogjava.net/weibogao/archive/2006/05/26/48374.html</link><dc:creator>weibogao</dc:creator><author>weibogao</author><pubDate>Fri, 26 May 2006 08:58:00 GMT</pubDate><guid>http://www.blogjava.net/weibogao/archive/2006/05/26/48374.html</guid><wfw:comment>http://www.blogjava.net/weibogao/comments/48374.html</wfw:comment><comments>http://www.blogjava.net/weibogao/archive/2006/05/26/48374.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weibogao/comments/commentRss/48374.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weibogao/services/trackbacks/48374.html</trackback:ping><description><![CDATA[
		<h2>
				<a id="viewpost1_TitleUrl" href="http://blog.yesky.com/blog/blueguy/archive/2005/01/14/65072.html">
						<font color="#223355">设计模式的有趣解释－追MM</font>
				</a>
		</h2>
		<div class="postbody">
				<span id="ArticleContent1_ArticleContent1_lblContent">
						<font size="4">
								<font color="#cc3333">//转自</font>
								<a id="ArticleContent1_ArticleContent1_AuthorBlogLink" href="http://blog.csdn.net/laurecn/" target="_blank">
										<font color="#cc3333">ht