![]() |
|
Spaces home Java DreamsProfileFriendsBlogMore ![]() | ![]() |
|
December 22 Tapestry之Cache组件
November 29 提高eclipse在windows下的性能在windows中,假如程序处理一定的状态下,会把memory放到paging里面。这样就降低了性能,但提高了memory的利用率。 打开windows注册表, 找到 HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\DisablePagingExecutive 值, 然后把这个值1。 这样应用程序就会一直使用物理内存了。 详细请看:http://technet2.microsoft.com/WindowsServer/en/library/3d3b3c16-c901-46de-8485-166a819af3ad1033.mspx?mfr=true November 24 让GWT的FlexTable支持双击(double click)Each event has a set of browser events that fires it. For example take a look at the source of the HTMLTable Class in the gwt-user jar. It public HTMLTable() { Basically, it is "sinking" only the ONCLICK event, and will ignore all http://code.google.com/webtoolkit/documentation/com.google.gwt.user.c... So, for example, if you wanted the table to respond to ONDBLCLICK use (let's say FlexTable), so you would make the class: public class HappyTable extends FlexTable {
} What this code is doing, is telling the table to react to click, double click, and key press events. In the same code you would create an public void onBrowserEvent(Event event) { } } Because I was doing a variety of things with the table I created my own listener interface, and listener collection which included double keys): public interface HappyTableListener extends TableListener{ public void onCellDblClicked(SourcesTableEvents sender, int
} public class MyTableListenerCollection extends Vector { public void fireCellClicked(SourcesTableEvents sender, int row, public void fireCellDblClicked(SourcesTableEvents sender, int public void fireUpKey(SourcesTableEvents sender) { November 15 Dojo TreeV3使用详解Dojo TreeV3使用详解
作者:邓胤(deng.yin@gmail.com)
工作中使用了TreeV3这个dojo的组件,感觉基本上已经是把dojo的treeV3使用到了极点(自定义树的外观,树节点的拖拉,把其他Drag Source拖拉到树中),公司也要求我作个treeV3演说。所以特意把这篇文章写下来。 首先先对treeV3做一个简单的介绍。TreeV3.js, TreeNodeV3.js, .TreeBasicControllerV3.js, TreeContextMenuV3.js,TreeDndControllerV3.js,TreeEditor.js, 主要的就是这些js一起协作。有兴趣的可以看看源码, 其实dojo的代码看起来还算是瞒简单的。下面我就用几个例子来说明怎样扩展或自定义TreeV3。本篇文章是增对有一定dojo知识的读者,如果你现在还不了解dojo,请看 http://dojotoolkit.org/. 1. 为叶子节点增加图标。 IconTree.html
<div dojoType="TreeV3" listeners="controller">
我们在每个TreeNode上加上childIconSrc属性。请看icontree.js怎样让这个属性生效的。<div dojoType="TreeNodeV3" title="Item 1" widgetId="1"> <div dojoType="TreeNodeV3" childIconSrc="images/page.gif" title="Item 1.1" widgetId="Item 1.1"></div> <div dojoType="TreeNodeV3" childIconSrc="images/page.gif" title="Item 1.2" widgetId="Item 1.2"></div> </div> <div dojoType="TreeNodeV3" title="Item 2" widgetId="Item 2"> <div dojoType="TreeNodeV3" childIconSrc="images/page.gif" title="Item 2.1" widgetId="Item 2.1"></div> </div> <div dojoType="TreeNodeV3" title="Empty Folder" isFolder="true" widgetId="Item 3"></div> <div dojoType="TreeNodeV3" childIconSrc="images/page.gif" title="Item 4" widgetId="Item 4"></div> </div> icontree.js dojo.lang.extend(dojo.widget.TreeNodeV3, { childIconsrc: "", childIcon: null, iconNode:null, titleNode:null, postCreate: function(args) { //build icon if (args["childIconsrc"]) { this.childIconsrc = args["childIconsrc"]; } this.childIcon = document.createElement("img"); if (this.childIconsrc != "") { this.childIcon.src = this.childIconsrc; this.childIcon.setAttribute("width", "16"); this.childIcon.setAttribute("height", "16"); } this.iconNode = this.tree.labelNodeTemplate.cloneNode(true); this.titleNode = this.tree.labelNodeTemplate.cloneNode(true); if (!this.isFolder){ //clear treenode, if it is not folder node this.labelNode.innerHTML=""; } this.titleNode.innerHTML=this.title; this.iconNode.appendChild(this.childIcon); // add icon first, then add title this.labelNode.appendChild(this.iconNode); this.labelNode.appendChild(this.titleNode); } }); 我们扩展了TreeNodeV3这个组件的postCreate方法(dojo组件都有这个方法,他相当于构造方法吧,我们可以在这里做必要的初始化),这里做的事应该比较清楚,我们通过childIconsrc这个属性创建了iconNode, 然后清空TreeNodeV3的labelNode。再增加iconNode和titleNode 2. 拖动物体到tree中 dragother.html <div dojoType="TreeV3" DndMode="between;onto" DndAcceptTypes="firstTree;feed" widgetId="firstTree" listeners="basicController;dndcontroller;selector;disableWrap" toggle="fade" showGrid="false" showRootGrid="true"> <div dojoType="TreeNodeV3" title="Item 1" widgetId="1"> <div dojoType="TreeNodeV3" title="Item 1.1" widgetId="Item 1.1"></div> <div dojoType="TreeNodeV3" title="Item 1.2" widgetId="Item 1.2"></div> </div> <div dojoType="TreeNodeV3" title="Item 2" widgetId="Item 2"> <div dojoType="TreeNodeV3" title="Item 2.1" widgetId="Item 2.1"></div> </div> <div dojoType="TreeNodeV3" title="Empty Folder" isFolder="true" widgetId="Item 3"></div> <div dojoType="TreeNodeV3" title="Item 4" widgetId="Item 4"></div> </div> <br/> <span id="feed_0">Drag me0 to tree.</span><br/> <span id="feed_1">Drag me1 to tree.</span><br/> <span id="feed_2">Drag me2 to tree.</span><br/> <span>You can't drag me.</span> 注意黑体的DndAcceptTypes属性。说明这个树接受dragSource type为firstTree或者feed的(也就是自己,还有就是下面的span, 我们需要把span变成可以拖动的物体 dragSource)。再看dragother.js。 dojo.addOnLoad(function(){ var num = 0; while(dojo.byId("feed_" + num) != null){ var dropSource = new dojo.dnd.HtmlDragSource(dojo.byId("feed_" + num), "feed"); num++; } }); dojo.dnd.TreeDropTargetV3.prototype.oldGetDropHandler = dojo.dnd.TreeDropTargetV3.prototype.getDropHandler; dojo.lang.extend(dojo.dnd.TreeDropTargetV3, { getDropHandler: function(e, source, targetParent, targetIndex) { if (source.type == "feed"){ var sourceNode = source.domNode; if (dojo.widget.byId(sourceNode.id) != null){ alert("this widget has already been here."); return function(){ return false; } } var node = createTreeNode(sourceNode.id, sourceNode.innerHTML); targetParent.addChild(node, targetIndex); return function(){ return true; } } return this.oldGetDropHandler(e, source, targetParent, targetIndex); } }); function createTreeNode(widgetId, title) { return dojo.widget.createWidget("TreeNodeV3", { widgetId: widgetId, title: title, isFolder: false, tree: 'firstTree' }); } 第一段是让那些span成为dragsource。第二段我们hack了dojo.dnd.TreeDropTargetV3的 getDropHandler方法(具体可以看看TreeDndControllerV3.js)。当我们接收到dragSources时我们获取那些 span中的一些信息,然后create 一个treeNode,在把这个treeNode加到树中。 3. ................................................... 4. ................................................... 5. ................................................... 还有一些hack treeV3的东西实在不愿写。 dojo的treeV3真的是蛮强大的(仔细看看那几个**Controller和TreeV3 TreeNodeV3的源码), 而且dojo的widget源码还是蛮容易理解的。有兴趣的朋友可以看看dojo的源码。还有就是dojo包里面tests目录下面的例子。大多数应用的话看看里面的例子也就行了。 例 子的源码可以在http://deng.yin.googlepages.com/TreeV3Sample.zip下载。本例子中没有包括 dojo0.4源码,用户可以到http://download.dojotoolkit.org/release-0.4.0/dojo-0.4.0- ajax.zip下载源码, 然后解压到例子中的dojo目录。 格式不好的话可以看http://docs.google.com/View?docid=ajgd3tgv958v_3gz374h HttpURLConnection 访问页面时发生403问题。工作中发现一个问题。当我用HttpURLConnection去连接读取一个网站时,老是会发生这个403错误。这个引起了IOException,但是我用firefox访问这个网站时就没问题。 google后知道了答案。原来如果用java代码HttpURLConnection去连的话 http header 中的User-Agent就为空,解决方法就是在连接之前先设置这个属性。 URL myUrl = new URL(searchURL); 那台Server上要这么做, 可能是要组织一些网络机器人的访问(不过感觉不是很有用,用上面的方法就能破了)。 其实实现感觉也很简单, 加上一个Filter,判断如果request.getHeader("User-agent")为空的话,然后再response一个403 status就行。 November 07 晕,inputstream for get image from internet.需要网站的favicon保存到数据库中。思路很简单连接internet,然后得到图片的bytes保存到数据库的blob字段就行。但是我却在取到图片的bytes上面浪费了许多时间。 开始的代码如下 boolean fetched = false; URL url = null; try { url = new URL("http://" + channel.getSite().getHost() + "/favicon.ico"); HttpURLConnection httpURL = (HttpURLConnection) url.openConnection(); //httpURL.setConnectTimeout(60*1000); httpURL.connect(); if (httpURL.getResponseCode()==200){ InputStream is = httpURL.getInputStream(); int length = is.available(); byte[] bytes = new byte[length]; is.read(bytes, 0, length); Blob blob = Hibernate.createBlob(bytes); ((Image)image).setLocalSmallImage(blob); logger.debug("Image URL:[" + url + "] has been fetched."); logger.debug("read image size:" + length); fetched = true; } } catch (Exception e) { //ignored } if (!fetched) logger.debug("Fail to fetch Image URL:[" + url + "] "); 在本地上设置断点调试发现一切正常。 但是发不到服务器上却发现数据更本没有保存到进去,或者只保存进去一部分。奇怪!然后log了bytes的长度(logger.debug("read image size:" + length);)。发现这时候的长度为0。上面的代码肯定是有问题。 因为网络延时之类的这里的available根本就不准确。其实这里我们应该像读取一个文件,然后在把他写入另一个文件的操作是一样的。需要先用过inputstream read出bytes, 然后再通过outputstream把bytes输出。 但是这里我们不需要写到文件之类的datasource中。我们需要的只是bytes。我们可以方便的使用ByteArrayOutputStream来存储我们的bytes。 public static byte[] getAllBytes(InputStream in) throws Exception { int chunkSize = 4096; byte[] b = new byte[chunkSize]; int borb = -1; ByteArrayOutputStream fos = new ByteArrayOutputStream(); while ((borb = in.read(b)) != -1) { fos.write(b, 0, borb); } return fos.toByteArray(); } 升级到Edgy后, Vmware server不能启动。I can't start vmware server after I upgrade Ubuntu to lastest version "Edgy". do as this article(http://dengyin2000.spaces.live.com/blog/cns!AF4AB52B167D7EE7!237.entry), it still can't work. Finally I google an solution for this problem, please see http://www.debian-administration.org/users/emeitner/weblog/6 change command "vmware" to "LD_PRELOAD=/usr/lib/libdbus-1.so.3:$LD_PRELOAD vmware" October 25 小试GWT当gwt发布的时候我就初略的看了gwt的文档。当时没有在注意这个东西。当自己经过ajax, javascript洗礼后,蓦然想试试gwt这个东西。原卷了javascript的开发效率(虽然FF 有firebug, IE下面有VS)。我也不确定gwt是否会提高开发效率(我也没有用gwt做过项目),但是就评google的技术,而且可以用java去写页面代码。 我觉得有必要试试。 发了些时间看了gwt的Getting started guide 和 Develop guide 这个写得还是非常简单明了的。gwt会把你写的这些client java代码编译成html和js。应该大部分都是js吧。 在实践Reomte produce call 遇到的一个问题, 我把 MyService.java MyServiceImpl.java, MyServiceAsync.java都放在了com.dengyin.client包中,然后程序运行的时候老是会出现"com.google.gwt.user.server包找不到的错误", 但是程序运行是正常的。但是classpath中确实有MyServiceImpl这个类,后来在gwt develop forum 找到答案。 问题原因应该是gwt在真正运行前会先独立的编译com.dengyin.client包下的所有的类。但在编译的时候是不会把com.google.gwt.user.server中的类include进来。但是MyServiceImpl继承了RemoteServiceServlet,RemoteServiceServlet是在com.google.gwt.user.server包里面的,所以会发生这个问题。其实想想也就知道gwt为什么强制用户要有client这个包的原因了, 所有在client包里面的类都不应该跟Server端的有关系,在这个包里面的所有类应该仅仅是跟界面有关系。解决办法是把MyServiceImpl移到com.dengyin.server包里面。 October 20 巧妙使用javascript让你的页面程序处于index frame中。假如我们有这个一个页面, index.html <frameset framespacing="0" border="false" cols="180,*" frameborder="1"> <frame name="left" scrolling="auto" marginwidth="0" marginheight="0" src="Toc.html"> <frame name="main" scrolling="auto" src="Content.html"> </frameset> <noframes> <body> <p>This page uses frames, but your browser doesn't support them.</p> </body> </noframes> Toc.html是目录页面, Content.html是内容页面。 场景1:假如一个用户登入后, 进入index.html,然后用户过了很长一段时间没有操作session timeout了。这时候用户再去点页面的操作的话,这时候Content.html会转到登入页面, 但是因为在一个frame里面, 所以登入页面会在index.html中。我们希望他不出现在index.html中, 清在登入页面加上下面这段javascript <script type="text/javascript"> if (window.top != self){ window.top.location = self.location; } </script> 场景2:我们希望右边的内容页面不能独立的出现(即一定要出现在index.html中),我们也需要在每个在“main” frame的页面加上下面这段javascript if (window.top == self){ // ensure sub page would contain in index page window.location="index.html"; } October 10 使用Maven和WTP开发WEB项目。首先下载、安装Maven WTP。 Maven: http://maven.apache.org/download.html WTP: www.eclipse.org/webtools/ 建议使用1.03 或 1.5.1 首先你用Maven创建一个WEB项目,其实就是在你的pom.xml指定<packaging>war</packaging>就行了。然后自己在 src/main目录下面建立webapp web.xml等web项目需要的文件。 ok。 不知道的话请参阅Maven文档。 假设你的web项目已经用maven搭建好了。然后运行mvn clean install -Dtest , maven会自动从网上download依赖的包, 编译源码然后把声称的war放到你的资源库中。其中-Dtest是在打包之前跳过单元测试。 再运行mvn eclipse:eclipse -Dwtpversion=1.0 -DdownloadSources=true,maven会使用他的eclipse插件(如果没有的话,maven会自动download install这个插件)为你把这个项目转成eclipse的wtp项目。-Dwtpversion=1.0这里是指定wtp的版本,当前好像支持R7和1.0,但是因为1.5版本的wtp配置文件没有更改,所以-Dwtpversion=1.0一样适合1.5的版本。 配置wtp,添加你刚才那个项目到wtp Server中。 启动Server。这里有个好处就是他不会把dependency lib的scope为test 或 provided的lib考到webapp下。 当你更改了pom.xml后, 你还需要再运行下mvn eclipse:eclipse -Dwtpversion=1.0来更新你的wtp的配置文件。 我在使用wtp中发现一个非常严重的性能问题。 当你publish的文件非常多的时候,你保存一个文件时的性能非常低,有时候会需要6-10秒。wtp把你项目中需要deploy的文件都保存一个像这样的一个file:///home/denny/workspace/.metadata/.plugins/org.eclipse.wst.server.core/publish/publish1.xml文件中。假如你保存的那个文件位于publish.xml中比较靠头,那还是非常快的。 如果比较靠后就非常慢了。应为wtp需要更新你保存文件对应的stamp属性。假如非常考后的话,他需要先装在publish.xml文件, 然后找到你保存的文件再更新他的stamp属性。。 October 09 How can I move text cursor in a text input field?Thanks the following codes. while in Firefox, you just need to invoke textElement.focus() method. October 04 国庆购机柯达C603国庆在国美买了柯达C603, 总体感觉还不错。。 1399 + 512SD卡 + 手提袋 + 充电器和两只充电电池 * 610万像素 * 3倍光学变焦 * 4倍数码变焦 * 2.4寸显示屏(11.2万像素) * 17种场景拍摄模式 * 内置28M内存 September 19 安装VMWare Server, 模拟Windows Xp虽说以前通过linux4ie安装了IE, 但这个确实不好用, 一旦有javascript错误,看不到javascript错误弹出窗口,对调式来说的话根本就没有, 所以其实跟没有一样,所以调式IE的话,我还是希望切换到windows xp中用VS调式javascript。今天狠下心装了VMWare Server, 再在上面装了一个Window XP。 虽说慢一点(鼠标有点晃),其实的跟真正的Windows没有区别。 安装VMWare Server http://forum.ubuntu.org.cn/viewtopic.php?t=22441 http://thinkbase.net/w/main/Wiki?2006-08-26+%E5%9C%A8+Ubuntu+6.06+%E4%B8%8A%E5%AE%89%E8%A3%85+VMware-server+1.0.1 今天发现一个问题, 我更新内核后发现VMWare需要重新设置。 我们只学要再运行下 这个应该内核的C库吧。 sudo apt-get install linux-headers-`uname -r` build-essential xinetd 然后再重新配置下 sudo /usr/bin/vmware-config.pl Show 下我在Ubuntu下的Windows XP September 17 File permission (chmod)
user@host:/home/user$ touch file1 file2 file3 file4 Add owner execute bit: user@host:/home/user$ chmod u+x file1 Add other write & execute bit: user@host:/home/user$ chmod o+wx file2 Remove group read bit: user@host:/home/user$ chmod g-r file3 Add read, write and execute to everyone: user@host:/home/user$ chmod ugo+rwx file4 Details in: https://help.ubuntu.com/community/FilePermissions September 12 Hack dojo codes with dojo's utildojo.lang.extend(dojo.widget.PopupMenu2, { onOpen: function(e){ this.openEvent = e; var x = e.pageX, y = e.pageY; var win = dojo.html.getElementWindow(e.target); var iframe = win._frameElement || win.frameElement; if(iframe){ var cood = dojo.html.abs(iframe, true); x += cood.x - dojo.withGlobal(win, dojo.html.getScroll).left; //override the onOpen to reslove the problem the context popup menu open under the selected TreeNode. if (!(e.type == "contextmenu" && dojo.render.html.ie)) y += cood.y - dojo.withGlobal(win, dojo.html.getScroll).top; } this.open(x, y, null, [x, y]); e.preventDefault(); e.stopPropagation(); } }); 这样我们就是复写了dojo.widget.PopupMenu2类的onOpen方法。如果我们想调用覆盖以前的方法。 //backup the old function dojo.widget.TreeBasicControllerV3.prototype.oldOnKey =dojo.widget.TreeBasicControllerV3.prototype.onKey; dojo.lang.extend(dojo.widget.TreeBasicControllerV3, { onClick: function(e) { if (e.target.tagName == "INPUT") return ; // default click handler just sets the focus var treeWidget = this.getWidgetByNode(e.currentTarget); if (!treeWidget || !treeWidget.isTree) { return; } var nodeWidget = this.getWidgetByNode(e.target); if (!nodeWidget || !nodeWidget.isTreeNode) { return; } this._focusLabel(treeWidget, nodeWidget); }, onKey: function (e){ if (e.target.tagName == "INPUT") return ; this.oldOnKey(e); } }); dojo.lang.extend这个方式是多么的方便。我们可以用这个方法方便的扩展或修改以有的代码。 看看dojo的dojo.lang.common 里面包括了对象间的一些操作。如dojo.lang.inherits, dojo.lang.mixin etc September 06 Ubuntu 常用技巧快速设置指南 http://wiki.ubuntu.org.cn/%E5%BF%AB%E9%80%9F%E8%AE%BE%E7%BD%AE%E6%8C%87%E5%8D%97/DapperDrake 挂载硬盘 /etc/fstab /dev/hda1 /windows/C ntfs auto,user,ro,nls=utf8,umask =000 0 0 /dev/hda5 /windows/D vfat auto,user,rw,utf8,umask=000 0 0 /dev/hda6 /windows/E vfat auto,user,rw,utf8,umask=000 0 0 http://forum.ubuntu.org.cn/about19112.html 环境变量的设置 /home/denny/.bashrc export JAVA_HOME=/usr/lib/jvm/java-1.5.0-sun-1.5.0.06 export CLASSPATH=$CLASSPATH:$JAVA _HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar:. export MAVEN_HOME=/usr/local/maven-2.0.4 export PATH=$PATH:$MAVEN_HOME/bin:$JAVA_HOME/jre/bin:$JAVA_HOME/bin:. adsl拨号设置 第一次使用 sudo pppoeconf 设置好了之后以后只要使用下面两个命令拨号或断线。 sudo pon dsl-provider sudo poff 设置xserver 主要有显示器分辨率等等 sudo dpkg-reconfigure xserver-x 安装MPlayer http://wiki.ubuntu.org.cn/%E5%AE%89%E8%A3%85MPlayer javascript中的继承。本来打算写篇关于javascript继承的文章, 但是觉得这篇文章已经写得够好了。 http://forum.javaeye.com/viewtopic.php?t=19748 |
|
|