| 网站首页 | JAVA文章 | AppServers | Web开发 | 应用开发 | 资源下载 | 论坛
    想学好编程,学好外语很重要  [enadd  2006年12月25日]        
设为首页 加入收藏 联系站长
您现在的位置: 编程笔记网 >> JAVA文章 >> JAVA基础 >> 文章正文
Java技巧: 推动JButtonGroup        【字体:
Java技巧: 推动JButtonGroup
作者:佚名    文章来源:不详    点击数:    更新时间:2006-4-16

摘要

Swing的 ButtonGroup 类允许单选按钮分组以保证单一选择;但是,这个实现引起了许多问题标记。你不能检索到组中当前选择的按钮的引用,并且类允许你选择或者取消选择通过引用访问的任何按钮,不是组中成员也可。本技巧描述了当提供便利的、使得JButtonGroup更加易于使用的方法时JButtonGroup 子类ButtonGroup如何提供更为可靠的实现。

Swing有许多有用的类,这些类可简化绘图用户界面(GUI)的开发。 但是,其中有一些类实现起来不那么容易,如ButtonGroup。本文解释了为什么ButtonGroup 难于设计并提供了一个代替的类,JButtonGroup,它继承了ButtonGroup并解决了ButtonGroup的某些问题。

注意: 你可从Resources处下载本文的源代码。

ButtonGroup 突破口

在开发Swing GUI 经常会出现这样的情况:你建立了一个表格来收集关于输入到数据库或者保存到文件中的数据项。这个表格可能包括文本框、单选按钮和其他窗口小部件。你使用ButtonGroup 类将所有需要单一选择的单选按钮分组。当表格设计准备好了的时候,你开始填写表格数据。你遇到一组单选按钮,你需要知道组中哪个按钮被选了这样你就能储存恰当的信息到数据库或者文件中。你现在卡住了。为什么? ButtonGroup 类不提供到组中当前所选按钮的引用。

ButtonGroup有一个getSelection()方法,它返回所选按钮的模型(作为ButtonModel 类型),但不是按钮本身。现在,如果你能够从模型中得到按钮引用那也好,但是你得不到。ButtonModel 接口和它的实现类不允许你从它的模型中检索按钮引用。那你怎么办?你仔细看看ButtonGroup 文档你会看到getActionCommand()方法。你想想如果你使用按钮旁边显示文本的String 来例示JRadioButton 的话,你调用按钮上的getActionCommand(),构造器中的文本就会返回。你可能会以为你仍然使用代码工作,因为虽然你没有按钮引用,至少你有了它的文本而且仍然知道所选的按钮。

好,太棒了!可奇怪的是,你的代码在运行过程出现NullPointerException。为什么?因为ButtonModel中的getActionCommand() 返回null。如果你赌(像我一样) getActionCommand()在按钮上的调用或者在模型上的调用也出现了同样的异常(许多其他的方法都是这样,如 isSelected()、isEnabled()、或者getMnemonic()),那你就错了。如果你确实没有调用按钮上的setActionCommand(),你没有在它的模型中设置作用指令的话, 获得器方法就会返回对于模型的null 。但是,调用按钮上的获得器方法,它确实会返回按钮文本。下面就是AbstractButton 中的 getActionCommand() ,继承于Swing 中的所有按钮类: public String getActionCommand() {
String ac = getModel().getActionCommand();
if(ac == null) {
ac = getText();
}
return ac;
}



设置和获得行为指令之间的矛盾是无法接受的。如果当行为指令为空时,AbstractButton 中的setText()设置模型的行为指令到按钮文本上,你就能避免这种矛盾。毕竟,除非setActionCommand()使用某些String参数(非空)来调用,否则按钮文本总是被按钮本身当作行为指令。为什么模型表现如此不同呢?

当你的代码需要到ButtonGroup 中的当前所选按钮的引用,你得遵循下列步骤,这些步骤中没有一个调用了getSelection():

?调用ButtonGroup 上的getElements(),它将返回一个Enumeration

?通过Enumeration迭代,以便得到每个按钮的引用

?调用每个按钮上的 isSelected(),判断出它是否被选

?返回引用到返回true 的按钮上

?或者,如果你需要行为指令,调用按钮上的getActionCommand()

如果这些步骤看起来过于繁杂的话,请往下读。我认为 ButtonGroup的实现根本上是错误的。它保存的是到所选按钮模型的引用,实际上它应该保存到所选按钮的引用。而且, getSelection()检索所选按钮的方法,你会认为相应的设置器方法就是setSelection(),可实际上它不是,而是setSelected()。现在,setSelected()有一个大问题。它的参数是ButtonModel和布尔值。如果你调用ButtonGroup 上的setSelected(),并传递按钮的非该组成员的模型和参数true , 那么该按钮被选,组中其他按钮则为非被选。换句话说, ButtonGroup 有权决定传递到它的方法处的按钮选择还是不选择,即使该按钮与该组毫无关系。这种行为是存在的,因为ButtonGroup 中的setSelected()不检查作为参数收到的 ButtonModel引用是否代表组中的按钮。而且由于该方法坚持单一选择,它实际上不选自己的按钮而选择与该组无关的按钮。

这种约定在ButtonGroup文档中表现得更为有趣:

我们无法为了清除按钮组而程序化地关闭按钮。为了表现出“非被选”,添加一个可见的单选按钮到组中,然后程序化地选择该按钮来关闭所有显示的单选按钮。例如:可安装带有卷标´´none´´的普通按钮来选择可见的单选按钮。

很好,但是这不现实:你可以使用任何按钮,放在你的应用程序中的任何位置,可见或不可见,设置也可以是无效的。是的,你甚至可以使用按钮组来选择一个组外的无效按钮,并且它仍然还可以取消对它所有按钮的选择。要得到组中所有按钮的引用,你得调用这个机械的getElements()。"elements" 能对ButtonGroup做些什么,大家都知道。getElements(),的命名可能就是受Enumeration类的方法 (hasMoreElements()和nextElement())所启发,但是getElements()无疑应该命名为 getButtons()。因为按钮组分组的是按钮,而不是元素。

[1] [2] [3] 下一页  

文章录入:enadd    责任编辑:enadd 
  • 上一篇文章:

  • 下一篇文章:
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
  • RESIN/TOMCAT和MYSQL的连接解…

  • 通过JDBC连接oracle数据库的…

  • Tomcat4的数据库连接池配置

  • 数据库连接池Java实现小结

  • Java数据库编程中查询结果的…

  • Java,Beans和关系数据库的镜…

  • 课程介绍(11): SL-351 Java数…

  • 课程介绍(12): SL-330 用Jav…

  • JavaBeans和关系数据库的镜像

  • Java访问数据库的速度瓶颈问…

  •   网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)
    | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 管理登录 |