分享
 
 
 

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

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

弹出对话框

对话框包装器有2个类组成:第一个是Popup_dialog,继承与JDialog实现小的如前所示的框架。

生成常规对话框的主要难点是所有的装饰(框架与标题栏)的消失问题,因此如果你需要生成自己的标题栏,下面提供了具体实现的大部分代码:

标题栏是包含一个显示标题的标签和一个按钮(关闭按钮,如导航箭头一样加载图象资源)。

代码如下:

public class Popup_dialog extends JDialog

{

private Color TITLE_BAR_COLOR = com.holub.ui.Colors.LIGHT_YELLOW;

private Color CLOSE_BOX_COLOR = com.holub.ui.Colors.DARK_RED;

private JLabel title = new JLabel("xxxxxxxxxxxxxx");

{ title.setHorizontalAlignment(SwingConstants.CENTER);

title.setOpaque( false );

title.setFont( title.getFont().deriveFont(Font.BOLD) );

}

private JPanel header = new JPanel();

{ header.setBackground( TITLE_BAR_COLOR );

header.setLayout( new BorderLayout() );

header.setBorder( BorderFactory.createEmptyBorder(2,2,2,2) );

header.add( title , BorderLayout.CENTER );

header.add( create_close_button() , BorderLayout.EAST );

}

private JPanel content_pane = new JPanel();

{ content_pane.setLayout( new BorderLayout() );

}

public Popup_dialog( Frame owner ){ super(owner); setModal(true); }

public Popup_dialog( Dialog owner){ super(owner); setModal(true); }

/* Code common to all constrUCtors. */

{

init_dragable();

setUndecorated( true );

JPanel contents = new JPanel();

contents.setBorder( BorderFactory.createLineBorder(Color.BLACK,1) );

contents.setLayout(new BorderLayout());

contents.add(header, BorderLayout.NORTH);

contents.add(content_pane, BorderLayout.CENTER);

contents.setBackground( Color.WHITE );

setContentPane( contents ); // , BorderLayout.CENTER );

setLocation(100,100);

}

private JButton create_close_button()

{

URL image = getClass().getClassLoader().getResource(

"images/8px.red.X.gif");

JButton b = (image!=null) ? new JButton( new ImageIcon(image) )

: new JButton( " X " )

;

Border outer = BorderFactory.createLineBorder(CLOSE_BOX_COLOR,1);

Border inner = BorderFactory.createEmptyBorder(2,2,2,2);

b.setBorder( BorderFactory.createCompoundBorder(outer,inner) );

b.setOpaque( false );

b.addActionListener

( new ActionListener()

{ public void actionPerformed(ActionEvent e)

{ Popup_dialog.this.setVisible(false);

Popup_dialog.this.dispose();

}

}

);

b.setFocusable( false );

return b;

}

/** Set the dialog title to the indicated text. */

public void setTitle( String text ){ title.setText( text ); }

/** Add your widgets to the window returned by this method, in

* a manner similar to a JFrame. Do not modify the Popup_dialog

* itself. The returned container is a {@link JPanel JPanel}

* with a preinstalled {@link BorderLayout}.

* By default, it's colored dialog-box gray.

* @return the content pane.

*/

public Container getContentPane(){ return content_pane; }

有点意思实现拖拉功能的代码。主要的思路是设置2个监听器。扑捉按纽的鼠标监听器与使用变量reference_position存储鼠标点击在标题标签中的上层窗口位置。

当鼠标移动时,鼠标移动监听器将被激活。问题是和拖动联系一起的事件一般和屏幕联系在一起而不是和上层窗口联系一起。拉句柄在当前鼠标位置移动对话框到原始的reference_position位置。就象从原始位置拖动窗体到现在鼠标位置一样。

下面是代码:

private Point reference_position = new Point(0,0);

private MouseMotionListener movement_handler;

private MouseListener click_handler;

private void init_dragable()

{

movement_handler =

new MouseMotionAdapter()

{ public void mouseDragged( MouseEvent e )

{ // The reference position is the (window-relative)

// cursor position when the click occurred. The

// current_mouse_position is mouse position

// now, and the deltas represent the distance

// moved.

Point current_mouse_position = e.getPoint();

Point current_window_location = getLocation();

int delta_x=current_mouse_position.x - reference_position.x;

int delta_y=current_mouse_position.y - reference_position.y;

// Move the window over by the computed delta. This move

// effectively shifts the window-relative, current mouse

// position back to the original reference position.

current_window_location.translate(delta_x, delta_y);

setLocation(current_window_location);

}

};

click_handler =

new MouseAdapter()

{ public void mousePressed( MouseEvent e )

{ reference_position = e.getPoint(); // Start of the drag

}

};

setDragable(true);

}

/** Turn dragability on or off.

*/

public void setDragable( boolean on )

{ if( on )

{ title.addMouseMotionListener ( movement_handler );

title.addMouseListener ( click_handler );

}

else

{ title.removeMouseMotionListener ( movement_handler );

title.removeMouseListener ( click_handler );

}

}

日期对话框

剩下的都是些微不足道的包装。Date_selector_dialog 修饰者把包装的Date_selector放在弹出框中。它从Titled_date_selector中复制了一些代码用来显示对话框标题栏(当前日期和月份)这里根本就没有考虑导航条问题。因为Date_selector已经包含了导航条等等。。

public class Date_selector_dialog extends Popup_dialog implements Date_selector

{

private Date_selector selector = new Date_selector_panel();

/** Creates a dialog box with the indicated parent that holds

* a standard {@link Date_selector_panel Date_selector_panel}

* (as created using the no-arg constructor).

*/

public Date_selector_dialog( Frame parent )

{ super(parent);

selector = new Navigable_date_selector( new Date_selector_panel() );

init();

}

/* Like {@link #Date_selector_dialog(Frame),

* but for a {@link Dialog} parent.

*/

public Date_selector_dialog( Dialog parent )

{ super(parent);

selector = new Navigable_date_selector( new Date_selector_panel() );

init();

}

/** Creates a dialog box with the indicated parent that holds

* the indicated Date_selector.

* Note that the current month and year display in the

* dialog-box title bar, so there's no need to display them in

* the selector too.

*/

public Date_selector_dialog( Frame parent, Date_selector to_wrap )

{ super(parent);

selector = to_wrap;

init();

}

/* Like {@link #Date_selector_dialog(Frame,Date_selector),

* but for a {@link Dialog} parent.

*/

public Date_selector_dialog( Dialog parent, Date_selector to_wrap )

{ super(parent);

selector = to_wrap;

init();

}

/** Code common to all constructors.

*/

private void init()

{ getContentPane().add( (Container)selector, BorderLayout.CENTER );

selector.addActionListener

( new ActionListener()

{ public void actionPerformed( ActionEvent event )

{ if( event.getID() == Date_selector.CHANGE_ACTION )

{ setTitle( event.getActionCommand() );

}

else

{ setVisible(false);

dispose();

}

}

}

);

((Container)selector).setVisible(true);

pack();

}

/** For use when you pop up a dialog using

* setVisible(true) rather than {@link #select}.

* @return the selected date or null if the dialog was closed

* without selecting anything.

*/

public Date get_selected_date()

{ return selector.get_selected_date();

}

/** Get the current date. The dialog stays in existence

* until the user closes it or selects a date, so this

* method can be used to see what month the user has

* scrolled to.

* @return the date currently displayed on the calendar.

*/

public Date get_current_date()

{ return selector.get_current_date();

}

/** Add an action listener for both.

* {@link Date_selector#CHANGE_ACTION} and

* {@link Date_selector#SELECT_ACTION} action events.

*/

public void addActionListener(ActionListener l)

{ selector.addActionListener(l);

}

/** Remove a previously added listener. */

public void removeActionListener(ActionListener l)

{ selector.removeActionListener(l);

}

/** Pops up the chooser and blocks until the user selects

* a date.

* @return the selected date or null if the dialog was closed

* without selecting anything.

*/

public Date select()

{

setVisible(true);

return selector.get_selected_date();

}

public void roll(int f, boolean up) { selector.roll(f,up); }

public int get(int f) { return selector.get(f); }

}

decorator 模式:

总的来说,尽管日历选择组件比实用,但是这篇文章的重点还是使用细化实现的Decorator 模式的使用。Decorator 模式适合代码独立化,易于管理,实现和调试。每个Decorator 在逻辑上都很重要且规范化。你要改变某物,只要知道要改变的地方;你要添加一个装饰,只要继承一个的简单接口。

这种细化也减少了类中耦合度(不受欢迎的相互之间的依赖性)。在单一接口中改变或增加某一特性时使用Decorator 模式更能显示它的灵活性。so ,使用Decorator 模式吧

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- 王朝網路 版權所有