当前位置: 首页 > 图文教程 > 网络编程 > JSP > 解决日期选择问题,一劳永逸(使用Decorator模式实现日期选择组件)(四)

JSP
Java 创建cookie和删除cookie
jsp 从web.xml读取连接数据库的参数
jsp 不支持EL表达式,解决办法
jsp 获取客户端的浏览器和操作系统信息
struts2 session 解读
struts2 spring整合fieldError问题
jsp 生成验证码代码
搭建java WEB开发环境和应用
JSP 自定义标签
Java 区分文本中的中英文字符函数
通用JSP页面 jsp入门级文章
jsp struts1 标签实例详解
一个jdbc 测试程序代码
SSH整合中 hibernate托管给Spring得到SessionFactory
jsp SmartUpload 实现上传功能代码
jsp Unsupported encoding: gb2312 错误原因
java Struts2 在拦截器里的跳转问题
jsp 对request.getSession(false)的理解(附程序员常疏忽的一个漏洞)
Java 项目生成静态页面的代码
jdk与jre的区别 很形象,很清晰,通俗易懂

JSP 中的 解决日期选择问题,一劳永逸(使用Decorator模式实现日期选择组件)(四)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-03   浏览: 62 ::
收藏到网摘: n/a

标题

这Date_selector_panel是重要部分。现在我们来看看他的装饰。Titled_date_selector类只做一件事情:给未装饰的日历增加个标题。这是对实现了Date_selector的JPanel面板的包装。它只显示现有的Date_selector和显示日期的标签。下面的实现是微不足道。和用户界面无相关值得说的只有那其中10行动作监听代码。监听器获取日期改变通知(通过用户导航或者方法调用)便做相应的标签日期更新。其他代码只是简单地创建面板和将Date_selector与JLable标题包装进面板中。
这表明这部分代码易写、易管理比较简单。如果它被混合在Date_selector_panel中,将会在 没有明显的优点的情况下增加了代码的复杂度。(代码有组织地放在某处比全混合在一个地方更加清晰。)如果我想要标题更加美观,只需要修改这一个类即可以实现根本就不需要动其他部分。

public class Titled_date_selector extends JPanel implements Date_selector
{   private       Date_selector selector;
    private final JLabel title = new JLabel("XXXX");

    /** Wrap an existing Date_selector to add a title bar showing
     *  the displayed month and year. The title changes as the
     *  user navigates.
     */

    public Titled_date_selector( Date_selector selector )
    {   this.selector = selector;

        title.setHorizontalAlignment(SwingConstants.CENTER);
        title.setOpaque     ( true                                      );
        title.setBackground ( com.holub.ui.Colors.LIGHT_YELLOW          );
        title.setFont       ( title.getFont().deriveFont( Font.BOLD )   );

        selector.addActionListener
        (   new ActionListener()
            {   public void actionPerformed( ActionEvent e )
                {   if( e.getID() == Date_selector_panel.CHANGE_ACTION )
                        title.setText( e.getActionCommand() );
                    else
                        my_subscribers.actionPerformed(e);
                }
            }
        );

        setOpaque(false);
        setLayout( new BorderLayout() );
        add( title,  BorderLayout.NORTH );
        add( (JPanel)selector, BorderLayout.CENTER );
    }

    /** This constructor lets you specify the background color of the
     *  title strip that holds the month name and year (the default
     *  is light yellow).
     *
     *  @param label_background_color the color of the title bar, or
     *      null to make it transparent.
     */
    public Titled_date_selector( Date_selector selector, Color label_background_color )
    {   this(selector);
        if( label_background_color == null )
            title.setOpaque( false );
        else
            title.setBackground( label_background_color );
    }

    private ActionListener my_subscribers = null;
    public synchronized void addActionListener(ActionListener l)
    {   my_subscribers = AWTEventMulticaster.add(my_subscribers, l);
    }
    public synchronized void removeActionListener(ActionListener l)
    {   my_subscribers = AWTEventMulticaster.remove(my_subscribers, l);
    }

    public Date get_selected_date()     { return selector.get_selected_date();  }
    public Date get_current_date()      { return selector.get_current_date();   }
    public void roll(int f, boolean up) {        selector.roll(f,up);           }
    public int  get(int f)              { return selector.get(f);               }
}


NAVIGATION/导航
下面展示的就是导航栏的实现代码,虽然有点长,但同样非常地简单。代码由定义了4个图象文件的代码开始。(我计划以后放弃箭头采用代码实现,但是现在仍然在用图象文件。)用下面的代码,把图象作为资源获取过来。
ClassLoader loader = getClass().getClassLoader();
loader.getResource( "IMAGE_FILE_NAME" );
classloader在找类的地方找图象资源;比如,程序在文件系统中运行,它将要在classpath中查找文件路径。因为没有用到绝对路径,代码是更加容易的打包成jar文件,并且文件也不再需要建立在文件系统中。导航栏是一个四个用图象做标签的按纽,按纽的动作监听通过Date_selector的roll()来包装日历对象,并且月份的改变也激发标题栏的改变。有一点非常重要就是导航条不知道也不影响标题。标题包装器是一个监听,所以它能自动的更新标题。导航条根本就不知道标题包装器的存在。

public class Navigable_date_selector extends JPanel implements Date_selector
{   private       Date_selector selector;

    // Names of image files used for the navigator bar
    private static final String
        NEXT_YEAR       = "images/10px.red.arrow.right.double.gif",
        NEXT_MONTH      = "images/10px.red.arrow.right.gif",
        PREVIOUS_YEAR   = "images/10px.red.arrow.left.double.gif",
        PREVIOUS_MONTH  = "images/10px.red.arrow.left.gif";

    // These constants are used to identify the button and
    // as the button caption in the event that the appropriate
    // image file can't be located

    private static final String FORWARD_MONTH   = ">"    ,
                                FORWARD_YEAR    = ">>"    ,
                                BACK_MONTH      = "<"    ,
                                BACK_YEAR       = "<<"    ;


    private JPanel navigation = new JPanel();

    public Navigable_date_selector( Date_selector selector )
    {   this.selector = selector;
        setBorder( null  );
        setOpaque( false );
        setLayout( new BorderLayout() );
        add( (JPanel)selector, BorderLayout.CENTER );

        navigation.setLayout(new FlowLayout());
        navigation.setBorder( null );
        navigation.setBackground( com.holub.ui.Colors.LIGHT_YELLOW );
        navigation.add( make_navigation_button(BACK_YEAR    ) );
        navigation.add( make_navigation_button(BACK_MONTH   ) );
        navigation.add( make_navigation_button(FORWARD_MONTH) );
        navigation.add( make_navigation_button(FORWARD_YEAR ) );

        add(navigation, BorderLayout.SOUTH);
    }

    // ...
    // I left out a few constructors and utility methods that go here
    // ...

    private final Navigation_handler navigation_listener
                                        = new Navigation_handler();

    /** Handle clicks from the navigation bar buttons */

    private class Navigation_handler implements ActionListener
    {   public void actionPerformed(ActionEvent e)
        {   String direction = e.getActionCommand();

            if     (direction==FORWARD_YEAR )selector.roll(Calendar.YEAR,true);
            else if(direction==BACK_YEAR    )selector.roll(Calendar.YEAR,false);
            else if(direction==FORWARD_MONTH)
            {
                selector.roll(Calendar.MONTH,true);
                if( selector.get(Calendar.MONTH) == Calendar.JANUARY )
                    selector.roll(Calendar.YEAR,true);
            }
            else if (direction==BACK_MONTH  )
            {
                selector.roll(Calendar.MONTH,false);
                if( selector.get(Calendar.MONTH) == Calendar.DECEMBER )
                    selector.roll(Calendar.YEAR,false);
            }
            else
            {   assert false:  "Unexpected direction";
            }
        }
    }

    private JButton make_navigation_button(String caption)
    {
        ClassLoader loader = getClass().getClassLoader();
        URL image =
            (caption==FORWARD_YEAR  )? loader.getResource(NEXT_YEAR):
            (caption==BACK_YEAR     )? loader.getResource(PREVIOUS_YEAR):
            (caption==FORWARD_MONTH )? loader.getResource(NEXT_MONTH):
                                       loader.getResource(PREVIOUS_MONTH) ;

        JButton b = (image!=null) ? new JButton( new ImageIcon(image) )
                                  : new JButton(caption)
                                  ;
        b.setBorder(new EmptyBorder(0,4,0,4));
        b.setFocusPainted(false);
        b.setActionCommand(caption);
        b.addActionListener( navigation_listener );
        b.setOpaque( false );
        return b;
    }

    public synchronized void addActionListener(ActionListener l)
    {   selector.addActionListener(l);
    }
    public synchronized void removeActionListener(ActionListener l)
    {   selector.removeActionListener(l);
    }
    public Date get_selected_date()     { return selector.get_selected_date();  }
    public Date get_current_date()      { return selector.get_current_date();   }
    public void roll(int f, boolean up) {        selector.roll(f,up);           }
    public int  get(int f)              { return selector.get(f);               }
}


ealy ,java 爱好者,Matrix jsp翻译小组成员,可以点击http://www.matrix.org.cn/user_view.asp?username=ealy查看她的个人信息