Tag Archives: java

如何调整Netbeans的字体

开发Rails应用有一阵子了,使用了朋友推荐的Netbeans作为主要的开发工具,功能很好,唯一让我别扭的地方便是无法设置一个好的字体。由于Netbeans是基于的Swing,所以字体的渲染要通过Java来实现。默认的配置下的monospaced字体是映射到宋体的,如果在字体中选择其他的字体,那么中文就无法显示了。那如何解决这个问题,可以按照以下几个步骤:

在Java2平台企业版中应用异步JavaScript技术和XML(AJAX)

作者Greg Murray, 2005年6月9日  翻译:ShiningRay@Nirvana Studio2005年9月9日 任何试过过Flickr、GMail、Google Suggest或者是Google Maps的人都会意识到一种新型的动态Web应用正在逐渐浮出水面。这些应用外观和表现都和传统的桌面应用程序很像,而他们不需要依赖于插件或者是特定于浏览器的功能。过去Web应用只是一系列HTML页面,他们任意一部份内容的更改都必须重新载入页面。像JavaScript编程语言和层叠样式表 (CSS)之类的技术已经成熟,可以有效地应用他们来创建高动态的Web应用,而且可以运行在所有的主流浏览器中。本文将会详细介绍你马上就可以使用的一些技术,让他们使你的Web应用像桌面应用更加丰富和更有交互性。 介绍异步JavaScript技术和XML(AJAX) 使用JavaScript技术,一个HTML页面可以异步地对服务器(一般是载入页面的服务器)发送请求并获取XML文档。然后JavaScript可以使用XML文档来更新或改动HTML页面的文档对象模型(DOM)。最近形成了一个术语AJAX(Asynchronous JavaScript Technology and XML)来描述这种交互模型。 AJAX其实不是很新的东西。这些技术对于Windows平台上专注于Internet Explorer的开发人员来说,已经存在好几年了。直到最近,这个技术才被作为Web远程技术或者远程脚本技术被大家了解。Web开发人员也有一段时间曾经使用过插件、Java applet和隐藏框架来模拟这种交互模型。最近发生的变化是,对XMLHttpRequest对象的支持已经成为所有平台上的主流浏览器都包括的特性了。JavaScript技术的XMLHttpRequest对象是。尽管在正式的JavaScript技术标准中并没有提到这种对象,然而今天主流的浏览器都对他提供了支持。而当代的浏览器如Firefox、Internet Explorer以及Safari在JavaScript技术和CSS的支持上有些细微的差别,但是这种差别是可以处理的。如果你要考虑支持较老的浏览器,AJAX也许就不能成为你的解决方法。 基于AJAX的客户端之所以独特的原因是客户端包含了用JavaScript嵌入的特定于页面的控制逻辑。应用JavaScript技术的页面基于事件进行交互,如文档载入、鼠标点击、焦点改变甚至是定时器。AJAX交互使得表现层逻辑更加清晰地与数据分离。一个HTML页面也可以根据需要每次读入适当的数据,而不是每次需要显示一个更改时都重新载入整个页面。AJAX要求一种不同的服务器架构来支持它这种交互模型。以前,服务器端Web应用关注于对每个导致服务器调用的客户端事件都生成HTML文档。然后客户端对每个回应都要重新读入并重新渲染完整的HTML页面。富Web应用(Rich Web Application)关注于,让一个客户端获取一个HTML文档让它表现为一个模板或者是一个容器,可以基于事件并使用从服务器端组件中获取的XML 数据来对文档注入内容。 一些AJAX交互的应用如: 实时表单数据检验:像用户ID、序列号、邮政编码或者是特殊的票据代码这类需要服务器端验证的数据也可以在用户提交表单之前进行验证。 自动补全:像电子邮件地址、姓名或城市名之类的表单数据都可以根据用户情况自动补全。 处理细节操作:根据一个客户端事件,一个HTML页面可以根据现存的一些数据再去获取更多详细的信息,如现在有一个产品列表,客户端可以控制查看单独的产品信息而无需刷新页面。 复杂的用户界面控件:像树型控件、菜单和进度条之类不要求页面刷新的控件也能实现。 页面内刷新数据:HTML页面可以从服务器上查询最新的数据如分数、股指、天气还有其它的特定于应用的数据。 服务器端通知:一个HTML页面可以通过对服务器进行定时查询来模拟一个服务器的事件通知推送,实现像通知客户端一个消息、刷新页面数据或将客户端重定向到另一个页面。 这个列表并未把所有的应用都列出来,但它已经显示了AJAX交互可以让Web应用比从前能做更多的事情。但尽管这些好处是值得关注的,这种方式也有一些缺点: 复杂度:服务器端开发人员必需理解,HTML客户端页面中的表现层逻辑以及生成HTML客户端页面所需的XML内容的服务器端逻辑。HTML页面开发人员必须了解JavaScript技术。如果开发新的框架和发展已有的框架来支持这种交互模型,那么AJAX应用的创建就会越来越简单。 XMLHttpRequest对象的标准化:XMLHttpRequest对象还不是JavaScript技术标准的一部分,这就意味着根据客户端的不同,应用的行为也有所会不同。 JavaScript技术的实现:AJAX交互极大地依赖于JavaScript技术,而由于客户端的原因JavaScript还有一些细微的差别。见QuirksMode.org来了解更多关于浏览器之间区别的内容。 调试:AJAX应用也难于调试,因为流程逻辑是同时嵌在客户端中和服务器上的。 代码可见:客户端的JavaScript可以很容易通过“查看源代码”被人看见。一个没有良好设计的AJAX应用很可能被黑客攻击或被他人剽窃。 当开发人员在使用AJAX交互模型上获得更多的经验后,AJAX技术的框架和模式就会慢慢浮现出来。现在就关注于完全通用的AJAX交互框架,还为时过早。本文和相关的解决方案将关注于在现有的Java 2平台企业版(J2EE)上如何对AJAX进行支持,像servlet,JavaServer Page(JSP)软件、JavaServer Face应用和Java标准标签库(JSTL)。 AJAX交互剖析 现在我们已经讨论了AJAX是什么以及一些高层次的问题。那现在让我们把所有的零件放在一起来展示一个具有AJAX的J2EE应用。 首先考虑一个例子。一个Web应用包括了一个静态HTML页面,或者是一个由JSP生成的HTML页面,这个JSP中还包括了一个HTML表单,它需要服务器端逻辑来对表单中的数据进行检验,而不用刷新页面。一个名为ValidateServlet服务器端组件(servlet)用来提供这种验证逻辑。图一描述了这种具有验证逻辑的AJAX交互的细节。 图1: 一个提供验证逻辑的AJAX交互 以下条目代表了图1中出来AJAX交互的过程: 发生一个客户端事件。 创建和配置一个XMLHttpRequest对象。 XMLHttpRequest对象进行一个调用。 ValidateServlet对请求进行处理。 ValidateServlet返回一个包含了结果的XML文档。 XMLHttpRequest对象调用callback()函数并处理结果。 更新 HTML DOM。 [...]

从Trails和Firebird开始

作者:Chris翻译:ShiningRay @ Nirvana Studio 0. 前言 在Trails的首页上有一段Trails的指导视频,它比本文说得更为详细。你可以看看它,另外根据Firebird设置一节中的内容,设置一下和Firebird相关的东西。 1. 什么是Trails? Trails是一个领域驱动开发框架,它使用了Hibernate、Spring和Tapestry。其中,Hibernate 被用作数据访问层,Tapestry用来给用户显示数据。而Spring 则是把Hibernate和Tapestry连接在一起。 Trails自带了几乎所以必需的jar文件——你只需要安装一下Firebird的数据库驱动,它可以在 http://firebirdsql.sf.net上下载。 1.1 Hibernate Hibernate是一个O/RM工具。O/RM的意思是:对象关系映射。O/RM可以让你把 java 对象映射到后台数据库中。Hibernate使用了XDoclet来指明映射信息所需的信息,以便在数据库中存储复杂的对象。而XDoclet使用了javadoc注释来告诉Hibernate如何映射对象。例如: [code lang="java"]/** * @hibernate.class table="PERSON" */ public class Person { } [/code] 这段代码会告诉Hibernate要将一个指定的对象(在这里是Person)映射到PERSON表。 Hibernate 的主页是:www.hibernate.org. 1.2 Tapestry Tapestry 是(简而言之)一个Web框架。更确切地说,Taspetry是一个基于组件的Web框架,它将表示和逻辑清晰地分离开来了。 在Tapestry中,一个页面和一个.html文件相关,这个文件负责这个页面的外观,和一个Java类,它负责对.html文件提供数据,还有一个. page或者是一个.jwc文件(这由你是要作为一个真正的页面还是一个单独的组件),这两个负责把前两个层次连接起来。 组件是通过ognl语言来访问的,形式如: <a href=”#” jwcid=”@PageLink” page=”myPage”>Goto MyPage</a> jwcid 指明了使用的组件——这里是一个PageLink,它是一个HTML表现中的<a></a>标签的一个组件。page属性指明了你要链接的页面的名称。 Tapestry 的主页在jakarta.apache.org/tapestry 2. 安装Trails。 首先从trails.dev.java.net下载Trails. 当前的版本是0.5.1。先把下载的文件解压缩(在https://trails.dev.java.net上有一个很棒的演示,教你如何利用Trails来写应用程序)。 解压缩trails,并进入新建的文件夹。更改build.properties文件以匹配你的tomcat路径, [...]

为什么继承是有害的?

通过把具体的基类转变成接口来改进你的代码 作者:Allen Holub  翻译:ShiningRay @ Nirvana Studio 摘要 大多数优秀的设计师避免出现继承(extends描述的关系),就像躲避瘟疫似的。你的代码80%应该完全以接口的方式来书写,而不是继承具体的基类。其实,Gang of Four 这本关于设计模式的书(以下简称GoF)很大程度上关于如何把类继承转变成接口实现。本文将叙述为什么设计师们会有这种古怪的信条。(2,300 words;2003 年 8月 1日) 译注:本文其实已经有人翻译,当时没有具体了解就开始翻译了,如果另一位译者看到这篇文章,希望不要理解为我抄袭的。 extends关键字是很有害的;也许不仅仅是在Charles Mason的级别上,还坏到了只要可能都应该避免的程度。GoF中详细讨论了把类继承(extends)如何转变成接口实现(implements)。 优秀的设计师的大部分代码都是根据接口写的,而不是根据具体的基类。本文将会讲述为什么设计师们会有这种古怪的癖好,同时也将介绍一些基于接口的编程基础。 接口 VS 类 我曾经参加了一个Java用户小组会议,那次刚好是James Gosling(Java的发明者)作特邀演讲人。在那次难忘的Q&A对话(提问)上,一个人问他:“如果你可以重新将Java搞一遍,你会做哪些修改?”“我会去掉类,”他回答道。在笑声渐渐消失之后,他解释了真正的问题不是类的本质,而是类继承(extends关系)。接口实现(implements关系)却是完美的。只要有可能,你们就应该避免类继承。 弹性的丧失 为什么你应该避免类继承?第一个问题是明确的使用具体类的名称会把你框在特定的实现中,让以后的更改会十分困难。 当代,敏捷开发方法学的核心是设计和开发同步。你在完全详细描述程序之前,就开始编写代码了。这种技术完全违背了传统的理念——设计应该在编程之前完成——但是很多成功的项目已经证实了,用这个方法,你可以比传统流水线作业更快速地开发高质量的代码(同时付出很有效)。然而,在并行开发的核心是,弹性的概念。你必须以这种方式来写你的代码,以便你可以尽可能以无痛的方式加入新发现的需求到现有的代码中。 你只要实现确实需要的特性,而不是实现那些可能需要的特性,但要用一种可以适应变化的方法。如果你没有这种弹性,并行开发明显是不行的。 接口编程正是这个弹性接口的核心。要了解为什么,先让我们看看如果你不使用接口会发生什么。考虑以下代码: f() { LinkedList list = new LinkedList(); //… g( list ); } g( LinkedList list ) { list.add( … ); g2( list ) } 现在假设一个紧急的新需求,需要进行更快速的查找,已经暴露出来了,这样LinkedList就达不到要求了,你就要把它换成HashSet。在现有的代码中,因为你必须同时修改f()还有g()(它用一个LinkedList作为参数),因此更改不是局限在一处的,还有一切传列表给g()的地方。 [...]

jMemorize 介绍

jMemorize是一个 Java 应用程序,可以使用著名的Leither系统来管理你的抽认卡,让记忆事情不仅有效而且有趣。它可以管理你的整个学习过程和特点分类、统计和一个优雅的外观。 Leitner 原理 Wikipedia的文章这样定义Flashcard (抽认卡): 一个抽认卡是一小块纸片,在学校里用来作辅助教学(主要是英语国家)。抽认卡可以用来记录词汇、历史事件时间、公式等等。使用抽认卡的目的主要是帮助[[记忆]]。你在每个卡片上写下一个问题(同时在背面记下答案),用它们来测试自己,并根据你的测试、学习结果把它们进行排序、分组。 这种策略使得学习更有选择性,也是就:在一组的卡片越难,你就越要花时间复习这一组。于是,你就能节省很多学习时间。 这个方法是由德国心理学家 Sebastian Leitner 在 19世纪70年代提出的。 Pimsleur 语言课也是基于类似的想法。 这个基本思路是根据它们对你的难易程度把卡片划分成不同的级别。这是通过你尝试回答一些重复问题来完成的。每次你了解的一个卡片的正确回答,它就会放到下一个较高的卡片级别中。如果某个卡片你没有回答出来,它就会被放回到开始的级别。 这个系统是和时间表结合在一起的。已经学习过的卡片,会在一个特定的失效期过后,重新被确认为要学习。级别越高,失效时间就越长。例如一个卡片第一 次成功检测过之后,会被安排在一天之后再次学习,当这个卡片连续三次都回答正确了之后,系统会在一周内都认为学过了。只要这个卡片被认为是学过了,它就不 会在当前学习阶段出现。 总之,这个系统将管理你的个人学习过程并让你关注于学习本身,同时它会自动决定哪个事物现在要再学习,尽可能让这些事情从你的时间中抽出来。 特性 新建、编辑、删除和重置卡片。 通过建立卡片分类来安排卡片。 你当前的学习情况的可视化演示。 可方便地自定义你的学习会话设置。这包括以下功能: 选择要学习的分类。 选择只学习新的卡片、过期卡片和所有卡片。 选择卡片/时间的限制。 选择你是否想以普通模式(顺序)学习还是随机模式。 选择预设的时间表或自己创建自定义时间表。 可以搜索你的卡片 还有很多很多 许可证 本软件由 Riad Djemili ( riad.de) 开发以 GPL license.发布。这表示 jMemorize 是自由软件,不仅可以自由分发二进制代码,同时还提供完整的源代码。

Python 不是 Java

作者:Phillip J. Eby. 翻译:ShiningRay @ NirvanaStudio 原文地址:http://dirtsimple.org/2004/12/python-is-not-java.html 我最近正在看一个基于wxPython的GUI应用程序,大概45.5KLOC的样子,但我没有计算它用到的库的大小(如Twisted)。代码是由那些对Python相对生疏的Java的开发者写的,所以程序有很严重的性能问题(如三十秒的启动时间)。我在检查代码的时候发现他们写了很多对Java有意义但是对Python却很恐怖的东西。并不是因为“Python比Java慢”,而是因为在Python中有更方便的方法去完成同样的目标,甚至在Java中不可能的事情。 所以,可悲的事就是这些可怜人事倍功半,产生了很多很多不需要写的代码,从而比相应合乎Python习惯的写法慢得多得多。我们来看一些例子: 在Java中一个静态的方法(static)不能翻译成一个Python的类方法(classmethod)。哦,当然,多多少少他最终产生类似的效果,但类方法的目的实际上是做了一些通常在Java中不可能的事(如继承一个非默认的构造函数)。Java静态方法的习惯翻译通常是一个模块级函数,而不是一个类方法或静态方法(staticmethod)。(同时静态封闭(final)字段应该翻译成模块级常量。) 这并不是一个性能上的问题,但是一个Python程序员要用像这些类似Java习惯的代码的话,可能就会被在该输入Foo.someFunction时却要输入Foo.Foo.someMethod这种情况给惹毛了。但是请注意:调用一个类方法将会比调用一个静态方法和函数要多一部分额外的内存。 啊,那些Foo.Bar.Baz也不是省油的。在Java中,这些点分割的名称是由编译器去查找的,所以运行时根本无所谓你有多少点。在Python中,每次运行时都要查找,所以每个点都要计算在内。(Python中一定要记住这点,“平铺比嵌套好”,尽管比起性能,他和“可读性”和“简单就是美”更靠近。) 要用switch语句?Python翻译将是一个哈希表,不是一堆if-then语句。用一堆if-then在Java中也不是switch语句,如果有字符串参与了呢?他其实是一个哈希表。CPython字典实现用了性能最佳—在我们宇宙中目前所知道的—的哈希表的实现之一。你自己所写的代码也不会比这个再好了,除非你是Guido、Tim Peters和Raymond Hettinger的“私生子”——还是遗传增强了的。 XML不是答案。它也不是一个问题。要在正则表达式上解释Jamie Zawinski,“一些人,当遇到一个问题的时候,就想‘我知道,我要用XML’那这个时候,他们就有两个问题了。” 和Java比,这是一个不同的情况。因为比起Java代码,XML是轻巧而且有弹性的。但比起Python的代码来,XML就是一个船锚,一个绊脚石。在Python中,XML是用来做交换,而不是你的核心功能,因为你不需要这么做。在Java中,XML可能是你的大救星因为他让你实现了特定领域的语言并“不通过编码”提高了你的应用程序的适应性。在Java中,避免编码是一个很大的优势,因为编码意味着重新编译。但在Python中,更常见的是,写代码比写XML更方便简单。同时Python处理代码要远远比处理XML快。(不仅仅是这个,你必须书XML处理代码,同时Python自身就已经为你准备好了。) 如果你是一个Java程序员,对于你是否要在你的Python核心应用中使用XML作为一部分,不要相信你的本能。如果你不是因为信息交互的原因去实现一个已经存在的XML标准或是建立某种导入、导出格式或者建立某种XML编辑器或处理工具,那么就不要这么做。一次也别。甚至连想都不要想。现在,扔掉那个XML模式把你的手解放吧!如果你的应用程序或者平台要被Python开发者使用,他们只会感谢你不要在他们的工作量中添加使用XML的负担。 (这里唯一的例外是如果你的受众的的确确,确确实实需要XML,出于某种奇怪的理由。像,他们拒绝学习Python并只对你使用了XML而付钱给你,或者你打算给他们一个编辑XML的GUI,同时这个写XML的GUI呢是另一个人写的,同时你得到免费使用的权利。还有一些很少见的架构上的原因需要用到XML。相信我,他们不会出现在你的程序中。如果有疑问,对一个资深的Python开发员解释你的用例。或者,如果你脸皮厚的话,试试向一个Lisp程序解释你的程序为什么要用XML!) Getter和setter是坏蛋。坏蛋,魔鬼!Python对象不是Java Bean。不要写什么getter和setter,然后还把它们包装在“属性”里面。它直到你能证明你需要比一个简单访问复杂一点的功能时才有意义,否则,不要写getter和setter。它们是CPU时间的浪费,更要紧的是,它们还是程序员宝贵时间的极大浪费。不仅仅对于写代码和测试的人,对于那些要阅读和理解它们的人也是。 在Java中,你必须使用getter和setter因为公共字段不允许你以后改变想法再去使用getter和setter。在Python中,这样做很傻,因为你可以以一个普通特性开始并可以在任何时间改变你的想法,而不用影响到这个类的任何客户。所以不要写getter和setter。 代码重复在Java中常常是一个不得不要的魔鬼,你必须经常一遍一遍写同一个方法而只有一点点的变化(通常是因为静态类型约束)。在Python中这样做是没有必要的也是不值得的(除了极少数一些特定的场合需要内联一些要求性能的函数)。如果你发现自己一遍一遍在写同样的代码而且变化很少,你就需要去学一下闭包。他们并不是真的很可怕。 这就是你要做的。你写了一个包含了函数的函数。这里内部的函数就是你要一遍遍写的函数的模版,但是在里面加入了针对不同情况的函数要使用变量。外部的函数需要刚刚提高的那种变量作为参数,并且将内部的函数作为结果返回。然后,每次你要写另一种略微不同的函数的时候,你只要调用这个外部的函数,并且把返回值赋给你要让“重复”函数出现的名字。现在,如果你需要改变这个工作方式,你只要改变一个地方:这个模版。 在我所看过的应用程序/平台中,只有一个很微不足道的程序使用了这个技术之后可以去掉数百行重复代码。事实上,自从开发者使用了特别的样板文件来为这平台开发插件,这会节省很多很多第三方开发人员的代码,同时也使那些程序员要学习的东西简化了。 这只是Java->Python思维方式转变的冰山一角而已,现在我可以让他转变成正确的而不用钻研这个程序的细节。本质上,如果你曾经用过一段时间Java,而且对Python比较陌生,不要太相信自己的本能。你的本能已经为Java调节,而不是Python。向后退一步,最重要的,不要写这么多代码了。 要这样做,让自己觉得更加需要Python。假装好像Python是可以做任何你想做的魔棒,却让你无须动一个手指。问一下,“Python是怎样解决我的问题的?”还有“Python语言的哪个特点和我的问题最相似?”你绝对会惊讶于你需要的东西其实已经有了某种固定形式。事实上,这种现象实在是太普遍了,甚至在很有经验的Python程序员中也会出现,以至于Python社区中给这种现象起了个名字。我们称之为“GUIDO的时间机器”,因为有时候看上去得到我们所需要的东西好像只有他知道的一种方法,但当我们自己知道了就不一样了。 所以,如果你不能感到你在使用Python时至少比用Java要多出10倍的生产力,!(同时如果你还怀念你的Java IDE,考虑一下这种可能性:因为你写的Python程序比他所需要的要复杂得多) 附录:(翻译自此篇文章的评论) 确实,哈希表==字典。举个最简单的例子,从Python 标准库中检出“pickle”和“copy”模块,这两个模块会从字典中查找类型并调用相应的函数。另一个有些诡异的例子是范型函数,我已经在最近的Blog中写了一下。 关于闭包的例子,我这里给出一个很笨的例子。假设你要写很多这样的函数: def addOne(x): return x+1def addTwo(x): return x+2 然后你可以这样写: def makeAdder(addend):… def add_it(x): return x+addend… return add_it 并且这样使用: addOne = makeAdder(1)addTwo = [...]