实现日期选择 实现了核心的日期选择面板并将它做为一个可用Decorator 模式的接口(在i/o例子中所有的Decorate 对象都是inputStream 对象因此可同等对待所有的模式构造器参数都是InputStream 引 用你可以在不知道包装对象时用其他Decorator 来包装任何一个Decorator ) public interface Date_selector { public static final int CHANGE_ACTION = ; public static final int SELECT_ACTION = ; public void addActionListener(ActionListener l); public void removeActionListener(ActionListener l); public Date get_selected_date(); public Date get_current_date(); /** Must work just like {@link Calendar#roll(intboolean)} */ public void roll(int flag boolean up); /** Must work just like {@link Calendar#get(int)} */ public int get(int flag); } Date_selector接口定义了个静态值CHANGE_ACTION和SELECT_ACTION用于事件处理过程中(在下面将有更多例子)接口也提供了添加与移除当选择日期时已激发的ActionListener对象的方法最后它提供了模仿javautilCalendar()方法通过增量(年月)来推进日历并获取属性值(如当前月份和年份)的接口 我们返回动作监听向按纽增加监听一样在日期选择中增加监听 Date_selector selector = new Date_selector_panel(); selectoraddActionListener ( new ActionListener() { public void actionPerformed( ActionEvent e ) { // Do whatever youd do to process an event } } ); 监听策略采用的是观察者(Observer)模式 在两种情况下监听将被唤醒(actionPerformed()被调用)两者区别是通过发送 ActionEvent对象并传递给actionPerformed一个getID()消息下面表进行了详细说明 动作事件 CHANGE_ACTION当日历面板改变显示的月与年(典型的就是导航条要改变)的时候发送该事件调用eventgetActionCommandgetActionCommand()去获得发生改变后的当前月与年你也可以调用get_current_date()获取当前用户选择的日期 SELECT_ACTION:当用户点击日期时发送时间调用eventgetActionCommandgetActionCommand()去获得选择日期的字符串形式(这字符串和使用toString()得到相同的结构)你也可以调用get_selected_date()获取改变后当前用户选择的日期 下面代码演示了这两种事件类型它实现了当用户通过导航条改变月份Date_selector改变标签与用户点击面板改变日期的功能 Date_selector selector = new Date_selector_panel(); JLabel moth_display = new JLabel(); saddActionListener ( new ActionListener() { public void actionPerformed( ActionEvent e ) { if( egetID() == Date_selectorCHANGE_ACTION ) month_displaysetText( egetActionCommand() ); else Systemoutprintln( egetActionCommand() ); } } ); 所有实现了Date_selector接口还继承了 JPanel类(或至少说是一些 Container 的衍生物)代码要实现这个需求以便日期选择器不用派生也可以当作一个JPanel使用但是此时实现不了因为javaawtContainer不是一个接口对于一个方法如果要返回一个能看为日期选择器或容器它将必须实现这两个类这样是非法的而且接口(Date_selector)不能继承于一个类(Container) 这个缺陷正好是一个很好的例子:这说明了有时为何难于在已经存在而没有正确使用接口的代码上改型四人帮模式如果是我我重制它并将 Container写成一个接口实现 Container与Date_selector(很明显我无法改变java*包)这种类到接口重组是非常困难的因为所有的类代码不变而接口变化程序将会中断 引进c++风格的重载操作原因是通过重载操作new可以是重组变的容易些这种方式你可以新建(new)一个接口并且具有默认借口类的性质java的解决方法是生成一四人帮工厂它是比刚才那样假想的正确做法容易多了 |