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

JSP
GET 方式提交的含有特殊字符的参数
java big5到gb2312的编码转换
java Lucene 中自定义排序的实现
hibernate中的增删改查实现代码
jsp 定制标签(Custom Tag)
jsp基础速成精华讲解
IE cache缓存 所带来的问题收藏
关于JSP的一点疑问小结
JSP 多条SQL语句同时执行的方法
jsp include文件时的一个乱码解决方法
在JSTL EL中处理java.util.Map,及嵌套List的情况
jsp 页面显示的一些用法
根据Hibernte的cfg文件生成sql文件
五种 JSP页面跳转方法详解
JSP 防范SQL注入攻击分析
JSP 连接MySQL配置与使用
java eclipse 启动参数
jsp 页面上图片分行输出小技巧
解决jsp开发中不支持EL问题
JSP 页面中使用FCKeditor控件(js用法)

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-03   浏览: 63 ::
收藏到网摘: 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查看她的个人信息