Xcode 4 中使用自定义字体,非 Outlet 方式

在 Xcode 3 的时代,如果要使用自定义字体,只要把字体安装到系统中,就能够在 Interface Builder  中字体列表中选择到,当然需要把字体文件加到项目中,并且在 Xxx-Info.plist 文件中列举出来。

而到了 Xcode 4 后,要用个自定义的字体反而更难了,字体安装到了系统中,它也不会出现在 Interface Builder 中的字体列表,必须用 setFont 为需要的控件应用自定义字体,这是一个浩大的工程,要么遍历控件,要么就得为控件与 IBOutletCollection 关联起来。

难道是 Apple 不希望看到应用中各色字体令人眼花缭乱的景象,所以制造点障碍。也不知道新的  Interface Builder 中的字体列表由哪得来的,是否能把自己的字体出现在该列表中呢?这个嘛,有点难。

既然不想使用 setFont 方法对 Xib 中的众多的控件一一设置字体,那就得另寻 Hack 方法了,幸好有了 FontReplacer 的方法。FontReplacer 是为 UIFont 做的一个 Category,它的实现原理是利用 method_exchangeImplementations 机制把 UIFont 的 fontWithName:size:fontWithName:size:traits: 换成自定义的方法,然后在自定义的方法中按照预设置的字体映射,当遇到某个系统字体 A 时,换成自定义的字体  Custom-A。

而你所要做的就是在 Interface Builder 中寻找字体,自己记住当选用了 系统字体 A,运行时会是 Custom-A 字体,系统字体 B 运行时会是 Custom-B,根据需要自己映射就行。一般方便起见,我们会选择一种字体(Family),然后用它的 Style 来与我们的自定义字体对应。这样只需要 Interface Builder 里像往常一样设置字体就行了,从而达到一劳永逸。 阅读全文 >>

JavaDoc 编程,书写自定义的 Taglet 支持 @unmi 等

javadoc 可为我们的 Java 项目生成 API 文档,别人的应该是看得多了,自己的可能不好意思晾出来看。那 Java 源代码里的 @author, @see, @param 等应该是司空见惯了吧。除此之外我们还可以自定义自己的 tag,并让它们的内容按照我们需要的格式生成到 javadoc 文档中,或作他用。还记得没有 Maven 的时代我们是怎样用 XDoclet 生映射文件的吗?现在的 Taglet 定制想要做的事情大抵如此。

执行一下 javadoc 命令看看,一堆的参数可以指定,又有学问在里头,且看:

-tag <name>:<locations>:<header>  Specify single argument custom tags
-taglet                           The fully qualified name of Taglet to register
-tagletpath                       The path to Taglets

-doclet <class>           Generate output via alternate doclet
-docletpath <path>        Specify where to find doclet class files

关于 doclet 部份这儿暂且不说,单讲 tag 部分的东西。

对于自定义 tag,简单的时候,用参数 -tag  都可以不写自己的 taglet 类,例如有这样一个代码: 阅读全文 >>

保持顺序的 Java Properties 类

Java 的 Properties 加载属性文件后是无法保证输出的顺序与文件中一致的,因为 Properties 是继承自 Hashtable 的, key/value 都是直接存在 Hashtable 中的,而 Hashtable 是不保证进出顺序的。

总有时候会有关心顺序一致的需求,恰如有 org.apache.commons.collections.OrderdMap(其实用 LinkedHashMap 就是保证顺序) 一样,我们也想要有个 OrderdProperties。网上查了下还真有:

http://livedocs.adobe.com/jrun/4/javadocs/jrunx/util/OrderedProperties.html

http://www.openrdf.org/doc/alibaba/2.0-rc4/apidocs/org/openrdf/repository/object/composition/helpers/OrderedProperties.html

不过没找到源码,其实自己写一个 OrderedProperties  也不难,并不需要重头写起,只要继承自 Properties,覆盖原来的 put/keys,keySet,stringPropertyNames 即可,其中用一个 LinkedHashSet 来保存它的所有 key。完整代码如下: 阅读全文 >>

Scala 特质(trait) 的 super 方法调用是动态绑定的

在 Java 或者 Scala 的类中,super.foo() 这样的方法调用是静态绑定的,也就是说当你在代码中写下 super.foo() 的时候就能明确是调用它的父类的 foo() 方法。然而,如果是在特质中写下了 super.foo() 时,它的调用是动态绑定的。调用的实现奖在每一次特质被混入到具体类的时候才被决定。

确切的讲,特质的 super 调用与混入的次序很重要,参照下面的例子说话:

直截的讲就是超靠近后面的特质越优先起作用。当你调用带混入的类的方法是,最右侧特质的方法首先被调用。如果那个方法调用了 super,它调用其左侧特质的方法。可以这么认为,Doubling 的 super 指向了  Incrementing,Incrementing 的 super 指向了 BasicIntQueue。

来看个完整的实例实际体验一把,如果要帮助理解,最好应该实际运行一下这个实例 阅读全文 >>

Scala 的 yield 例子 (for 循环和 yield 的例子)

我看了《Programming in Scala》一书,仍然对 Scala yield 关键字的理解不甚清楚。起初我以为 Scala yield 的与 Ruby 的 yield 是一样,Ruby 中 yield 是被传入代码块的占位符。Scala 中的 yield 关键字好像总是在 for 循环中用的. 下面一些例子可以帮助你更好的理解 yield 关键字。下面是摘自 《Programming in Scala》关于 yield 的解释:

For each iteration of your for loop, yield generates a value which will be remembered. It's like the for loop has a buffer you can't see, and for each iteration of your for loop, another item is added to that buffer. When your for loop finishes running, it will return this collection of all the yielded values. The type of the collection that is returned is the same type that you were iterating over, so a Map yields a Map, a List yields a List, and so on.
Also, note that the initial collection is not changed; the for/yield construct creates a new collection according to the algorithm you specify.

上面那段话的意义就是,for 循环中的 yield 会把当前的元素记下来,保存在集合中,循环结束后将返回该集合。Scala 中 for 循环是有返回值的。如果被循环的是 Map,返回的就是  Map,被循环的是 List,返回的就是 List,以此类推。 阅读全文 >>

应用 Castor 把 XML 转换成相应的 JavaBean(二)

紧接前一篇 应用 Castor 把 XML 转换成相应的 JavaBean(一),本例稍显复杂一些,也就是要使用到映射文件,更复杂的 JavaBean、XML 数据类型和结构,引入自定的 FieldHandler,还有存在 Namespace 的情形。

关于如何使用 Castor 来把 XML 映射成 JavaBean 请着重阅读这个链接 http://www.castor.org/reference/html/XML%20data%20binding.html 中的内容,里面有说明支持的类型,如何定义自己的类型 Handler 及配置 Handler 的属性,mapping.xml 文件怎么写及各部份的意义;还有 castor.properties 的配置,比其中的 suppressNamespaces 为 true 时可以忽略掉 Namespace,默认为 false.

直接看例子吧:

1. persons.xml,这里放了一个 Namespace,并定义了一个 Address 类型,还使得节点名与 Bean 的属性名不一致: 阅读全文 >>

Struts2 使用 xslt 结果类型如何把字符串直接作为 Document 内容

在上一篇: Struts2 使用 XSLTResult 输出页面内容详解 中说到了,如果在 Action 中送给 xstl 的是一个字符串,例如 String user = "<user><name>Unmi</name></user>",那么 xslt result 输出的将是:

<result>
&lt;user&gt;&lt;name&gt;Unmi&lt;/name&gt;&lt;/user&gt;
</result>

而不我们期望的

<user>
<name>Unmi</name>
</user>

那么怎么才能做到这一点呢?在 XSLTResult 有 adapterFactory 以及相应的 setter/getter 方法,但它们是 protected,所以也无法定制自己的 AdapterFactory 来判断是字符串就作为 Document 的内容。 阅读全文 >>

JDK 7 中的语法增强 -- (4) 创建泛型实例时的类型推断

Java 的泛型实例在声明时有点傻,比如像这样的语句 List<String> list = new ArrayList<String>(); 前明的 List<String> 已经提供了足够的信息让编译器知道 ArrayList 的参数类型,当然这是个简单的例子,如果复杂些,来点嵌套的话:

Map<String, List<Map<String, String>>> myMap = new HashMap<String, List<Map<String,String>>>();

那就够呛的,所以 Java 的这一语法要求也让 Scala 这样的语言所诟病,当然人家 Scala 是个趋近于动态性的语言,它认为上面的语句应该这么写:

val x = new HashMap[String, List[String, List[Map[String, String]]]() 或者是
val x: Map[String, List[String, List[Map[String, String]]] = new HashMap()

总之,只要一端的表态就行,其他事情交给编译器来推断。现在 JDK 也反省到了这一点,因为引入一个叫做菱形操作符(Diamond operator) 的东西,即两个尖括号 <>。让使得你像 Scala 一样只要在左边声明参数类型就行啦。这个操作符不免让我想起了在 perl 里有个 <=>  这样的操作符,好像叫做飞机,不是斗地主的飞机,它相当于 Java 里的 compareTo() 的功能。

于是泛型实例的声明就简单化成了 Map<String, List<Map<String, String>>> myMap = new HashMap<>(); 继续往下看: 阅读全文 >>

灵活控制 Hibernate 的日志或 SQL 输出,以便于诊断

我们在使用 Hibernate 时一般只会关注是否显示生成的 SQL 语句,不过有些时候还不够。默认时 Hibernate 执行的 SQL 语句是打印在控制台上的,它也可以配置为输出给 Log4J 或是 Log4Back,还能显示出更详细的参数和取值信息。这里简单讲来。

Hibernate 的配置文件 hibernate.cfg.xml 里提供有三个有关显示 SQL 的配置项,如果是与 Spring 联合,也可以配置到 Spring 的配置中。它们的取值是 boolean 值。

1) hibernate.show_sql - 是否显示所生成 SQL 语句,我们最常和它打交道
2) hibernate.format_sql - 是否格式化生成的 SQL 语句,增加可读性,不然全挤在一行
3) hibernate.use_sql_comments - 是否显示注释,用以指出什么操作产生的 SQL 语句,相比上面两条而言,这个配置会稍稍陌生些

 来看看加了上面三条配置后产生的效果,执行了 Hibernate 查询后,在控制台上产生如下输出: 阅读全文 >>

如何让 Map 中的值按放入顺序输出

笔者致: 当你打开这个页面的时候, 基本就无需再看后面的内容了, 因为直接用 LinkedHashMap 就能满足您的需求.  文中对这个问题的探索只是不知道别人早已过河了, 仍然在河里摸着石头. LinkedHashMap 是 JDK 1.4 加进来的, 之所以有 apache-commons ListOrderedMap 大约是因为它最早所处的是 JDK 1.4 之前的年代.


在使用 Java 的 Hashmap 时,输出 Map 中的值如何使之按放入的顺序输出来,像 List 那样保持顺序。这里的顺序不是说对集合中的数据进行的排序,要是的话用 TreeMap,像 TreeSet 一样就行。 我们看个例子:

阅读全文 >>