BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

JRuby GUI API三剑客

| 作者 Werner Schuster 关注 6 他的粉丝 ,译者 Jason lai 关注 0 他的粉丝 发布于 2007年7月7日. 估计阅读时间: 7 分钟 | Google、Facebook、Pinterest、阿里、腾讯 等顶尖技术团队的上百个可供参考的架构实例!

Swing早在1998年被加入JRE 1.2版,因为人们已经发现它的前身AWT在面临重要的应用已经力不从心了。Swing广受诟病的问题之一(仅次于性能和外观问题)就是,哪怕构建一些小型应用都需要带来大量的编码工作。因此,又有了一系列基于XML的GUI定义语言应运而生。

现在,JRuby的横空出世又引发了一次全新的浪潮,涌现出许多使用(J)Ruby语言特性的类库,试图让Swing应用的开发变得不那么单调乏味。有了Block,我们就可以从编写冗余的Listener样板代码(Boilerplate Code)中解放出来,而Builder的概念则可以用于在Ruby代码中创建复杂的嵌套GUI。

最近刚问世的API叫做Profligacy,发起人是Zed Shaw。这套API的关注点在于让事件处理变得更加轻而易举,并免去AWT/Swing Listener所需要的所有样板代码。在另一方面,对组件的创建和装配也和普通JRuby代码的形式大同小异,比如说使用new来创建新的Swing小部件。下面让我们来看看Profligacy的范例代码到底是什么样子的:

@ui = Swing::Build.new JFrame, :texts, :label do |c,i|
c.texts = [JTextField.new(10), JTextField.new(10)]
c.texts.each_with_index { |t, n|
t.action_command = "text#{n}"
}
c.label = JLabel.new "Something will show up here."
i.texts = {:action => method(:text_action) }
end

@ui.layout = FlowLayout.new
@ui.build("Two Text Fields Demo").default_close_operation = JFrame::EXIT_ON_CLOSE

def text_action(type, event)
puts "EVENT: #{type} #{event.action_command}"
end

请点击上面的链接查看更多的示例代码。

由Bill Dortch创建的Cheri::Swing则是Cheri项目的一部分,该项目是一套创建Builder应用的框架。Builder可以让开发人员使用非常少量的Ruby代码创建出层次型的结构。

menu_bar {
menu('File') {
mnemonic :VK_F
menu_item('Exit') {
mnemonic :VK_X
on_click { @frame.dispose }
}
}
}

这段示例代码则向我们展示了如何使用Ruby的method_missing和Block来使得我们可以使用非常精炼的代码,创建出一个菜单栏,上面包含了拥有一个菜单项的菜单。这些方法的调用使用的全是Block(包含在花括号内的代码)来执行的。同时还把元编程(Metaprogramming)和method_missing组合起来,用于判断到底是该创建一个新的对象,还是在刚刚创建的对象上执行如mnemonic这样的方法。正如我们看见的on_click调用一样,Cheri::Swing也可以让我们轻而易举地处理事件。on_click也使用了一个Block,它在MenuItem被单击的时候会被执行,这样也就把所有冗余无味的Listener或者Action的构建代码隐藏得一干二净。

由Jean Lazarous创建的实验性项目Swiby,则以一个JRuby DSL的方式克隆了JavaFXScript(就是以前的F3)。尽管Swiby也是用了Builder的概念构造GUI,它还从JavaFX Script中借鉴了bind操作符。这种方式允许人们定义表达式,这些表达式在它们引用的变量被重新赋值之后就会被求值。它使用了一种很精炼的方式来完成事件处理。示例代码如下:

require 'swiby'

class HelloWorldModel
attr_accessor :saying
end
model = HelloWorldModel.new
model.saying = "Hello World"

Frame {
title "Hello World F3"
 width 200
content {
Label {
text bind(model,:saying)
}
}
visible true
}

这几套API到底哪一套更加合乎人们的口味呢?这还有待观察。Swing XML GUI定义类库现在已经俯拾皆是了,而且我们的视线中越来越多新的相似类库接踵而来。与它们的区别则是,JRuby的类库一般来说块头都非常小,目前在Profligacy的例子里只有200行代码,并且还不存在对第三方类库的依赖。这就使得这些类库非常容易理解和维护。此外,由于这些类库全都允许在Ruby中编写GUI定义,它们扩展起来同样也要容易得多。如果有哪些组件的特性或者组合还没有得到支持,我们也可能退回只处理Swing对象的步骤上去,而不必去请求类库的维护者添加一项新特性了。

那么,亲爱的读者,到底哪种编写Ruby GUI代码的方式您更喜欢呢?

查看英文原文:Three approaches to JRuby GUI APIs

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

代码太丑了 by lu wenhua

宁可多写点,效率差点,也不用这样的东西,太丑了。

Re: 代码太丑了 by Lai Jason

呵呵,看来楼上还没有体验到 DSL 的好处。运用 JRuby 你完全可以非常灵活地设计出完全符合你审美观的 GUI Builder DSL。

我倒觉得 Cheri::Swing 的 GUI DSL 是相当优雅的,感觉完全像在写一个配置文件!几乎缩略掉所有你能看出 Ruby 语法痕迹的代码。如果用过 Delphi 的朋友都会知道一般用可视化设计器设计界面的项目中都会有不少 .dfm 文件,内容其实就是一个结构化的文本文件,用来描述 form 上各个组件以及相应属性,如布局颜色等。其实这就是一个用于描述界面的外部 DSL。用 JRuby 完全有能力构造出和 .dfm 格式相类似的 DSL,而且花点力气甚至可以构造出一个支持组件拖放的可视化界面设计器!

我预感,随着各大阵营对动态语言的支持愈加火爆,它们会是未来富客户端可视化设计的一个方向的。

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

2 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT