分享
 
 
 

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

王朝other·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

标题

这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查看她的个人信息

进入讨论组讨论。

(出处:http://www.knowsky.com)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有