`
yanghuidang
  • 浏览: 915007 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

SWT做的一个日历控件

 
阅读更多

下面是我用SWT写的一个日历控件,主要是用于让用记选择日期,可以通过按钮 上一年、下一年、上一月 和 下一月 调整到要切换的月份,也可以通过改 年 和 月 的下拉框中的选择项来切换到指定年月,还可以直接在 年 和 月 的下拉框中输入要切换到的年月后按 回车键 切换到指定年月。运行后的效果如下图所示:

源代码如下:

  1. packagecom.hmw.tools;
  2. importjava.util.Calendar;
  3. importorg.eclipse.swt.SWT;
  4. importorg.eclipse.swt.custom.CLabel;
  5. importorg.eclipse.swt.events.KeyAdapter;
  6. importorg.eclipse.swt.events.KeyEvent;
  7. importorg.eclipse.swt.events.KeyListener;
  8. importorg.eclipse.swt.events.MouseAdapter;
  9. importorg.eclipse.swt.events.MouseEvent;
  10. importorg.eclipse.swt.events.MouseListener;
  11. importorg.eclipse.swt.events.SelectionAdapter;
  12. importorg.eclipse.swt.events.SelectionEvent;
  13. importorg.eclipse.swt.events.SelectionListener;
  14. importorg.eclipse.swt.graphics.Color;
  15. importorg.eclipse.swt.graphics.Rectangle;
  16. importorg.eclipse.swt.layout.GridData;
  17. importorg.eclipse.swt.layout.GridLayout;
  18. importorg.eclipse.swt.widgets.Button;
  19. importorg.eclipse.swt.widgets.Combo;
  20. importorg.eclipse.swt.widgets.Display;
  21. importorg.eclipse.swt.widgets.Shell;
  22. /**
  23. *日历弹出窗口
  24. *
  25. *@authorCarlHe
  26. *
  27. */
  28. publicclassCalendarWidget{
  29. /**显示对象*/
  30. privateDisplaydisplay=null;
  31. /**窗口对象*/
  32. privateShellshell=null;
  33. /**窗口的宽度*/
  34. privatestaticfinalintSHELLWIDTH=380;
  35. /**窗口的高度*/
  36. privatestaticfinalintSHELLHEIGHT=280;
  37. /**Clabel大小的宽度*/
  38. privatestaticfinalintGRIDDATAHINT=20;
  39. /**上一年*/
  40. privatestaticfinalStringTOOPTIPTEXT_PREVIOUSYEAR="上一年";
  41. /**下一年*/
  42. privatestaticfinalStringTOOPTIPTEXT_NEXTYEAR="下一年";
  43. /**上一月*/
  44. privatestaticfinalStringTOOPTIPTEXT_PREVIOUSMONTH="上一月";
  45. /**下一月*/
  46. privatestaticfinalStringTOOPTIPTEXT_NEXTMONTH="下一月";
  47. /**星期日——星期六*/
  48. privatestaticfinalString[]weekdays={"星期日","星期一","星期二","星期三",
  49. "星期四","星期五","星期六"};
  50. /**年下拉框显示到当前年的前后多少年*/
  51. privatestaticfinalinthalfYearItemCount=20;
  52. /**年份下拉框选项的数组*/
  53. privatestaticfinalString[]years=newString[halfYearItemCount*2+1];
  54. /**月份:1——12*/
  55. privatestaticfinalString[]months={"1","2","3","4","5","6","7","8","9","10","11","12",};
  56. /**选择的日期:yyyy-MM-dd*/
  57. privateStringselectedDate="";
  58. /**年的下拉框*/
  59. Combocbo_year;
  60. /**月的下拉框*/
  61. Combocbo_month;
  62. /**显示日的Clable数组*/
  63. privatefinalCLabel[]clbl_days=newCLabel[42];//6*7
  64. /**日历窗体的背景颜色*/
  65. privateColorCOLOR_SHELL_BACKGROUND=null;
  66. /**星期X标签的背景颜色*/
  67. privateColorCOLOR_CLBLWEEKDAY_BACKGROUND=null;
  68. /**白色(得到的为系统的颜色,不需要对其进行资源释放)*/
  69. privateColorCOLOR_SYSTEM_WHITE=null;
  70. /**蓝色(得到的为系统的颜色,不需要对其进行资源释放)*/
  71. privateColorCOLOR_SYSTEM_BLUE=null;
  72. publicCalendarWidget(Shellparent){
  73. RectangleparentRec=parent.getBounds();
  74. display=parent.getDisplay();
  75. COLOR_SHELL_BACKGROUND=newColor(display,219,235,250);
  76. COLOR_CLBLWEEKDAY_BACKGROUND=newColor(display,64,128,128);
  77. COLOR_SYSTEM_WHITE=display.getSystemColor(SWT.COLOR_WHITE);
  78. COLOR_SYSTEM_BLUE=display.getSystemColor(SWT.COLOR_BLUE);
  79. shell=newShell(parent,SWT.CLOSE|SWT.APPLICATION_MODAL);
  80. shell.setText("选择日期");
  81. //保证显示在父窗体的正中间
  82. shell.setBounds(parentRec.x+(parentRec.width-SHELLWIDTH)/2,
  83. parentRec.y+(parentRec.height-SHELLHEIGHT)/2,SHELLWIDTH,
  84. SHELLHEIGHT);
  85. GridLayoutgridLayout=newGridLayout();
  86. gridLayout.numColumns=7;
  87. gridLayout.makeColumnsEqualWidth=true;
  88. shell.setLayout(gridLayout);
  89. shell.setBackground(COLOR_SHELL_BACKGROUND);
  90. //上一年
  91. Buttonbtn_yearPrevious=newButton(shell,SWT.ARROW|SWT.UP);
  92. btn_yearPrevious.setLayoutData(newGridData(SWT.FILL,SWT.CENTER,true,false));
  93. btn_yearPrevious.setToolTipText(TOOPTIPTEXT_PREVIOUSYEAR);
  94. btn_yearPrevious.addSelectionListener(btnSelectionListener);
  95. //上一月
  96. Buttonbtn_monthPrevious=newButton(shell,SWT.ARROW|SWT.LEFT);
  97. btn_monthPrevious.setLayoutData(newGridData(SWT.FILL,SWT.CENTER,true,false));
  98. btn_monthPrevious.setToolTipText(TOOPTIPTEXT_PREVIOUSMONTH);
  99. btn_monthPrevious.addSelectionListener(btnSelectionListener);
  100. cbo_year=newCombo(shell,SWT.DROP_DOWN);
  101. cbo_year.setLayoutData(newGridData(SWT.FILL,SWT.CENTER,true,false));
  102. cbo_year.addSelectionListener(cboSelectionListener);
  103. cbo_year.addKeyListener(cboKeyListener);
  104. CLabelclabel=newCLabel(shell,SWT.CENTER|SWT.SHADOW_OUT);
  105. clabel.setBackground(COLOR_SYSTEM_WHITE);
  106. clabel.setLayoutData(newGridData(SWT.FILL,SWT.CENTER,true,false));
  107. clabel.setText("-");
  108. cbo_month=newCombo(shell,SWT.DROP_DOWN);
  109. cbo_month.setItems(months);
  110. cbo_month.select(Calendar.getInstance().get(Calendar.MONTH));
  111. cbo_month.setLayoutData(newGridData(SWT.FILL,SWT.CENTER,true,false));
  112. cbo_month.addSelectionListener(cboSelectionListener);
  113. cbo_month.addKeyListener(cboKeyListener);
  114. //下一月
  115. Buttonbtn_monthNext=newButton(shell,SWT.ARROW|SWT.RIGHT);
  116. btn_monthNext.setLayoutData(newGridData(SWT.FILL,SWT.CENTER,true,false));
  117. btn_monthNext.setToolTipText(TOOPTIPTEXT_NEXTMONTH);
  118. btn_monthNext.addSelectionListener(btnSelectionListener);
  119. //下一年
  120. Buttonbtn_yearNext=newButton(shell,SWT.ARROW|SWT.DOWN);
  121. btn_yearNext.setLayoutData(newGridData(SWT.FILL,SWT.CENTER,true,false));
  122. btn_yearNext.setToolTipText(TOOPTIPTEXT_NEXTYEAR);
  123. btn_yearNext.addSelectionListener(btnSelectionListener);
  124. GridDatagridData_1=null;
  125. //将星期日——星期六的标签显示出来
  126. for(inti=0;i<weekdays.length;i++){
  127. CLabelclbl_weekDay=newCLabel(shell,SWT.CENTER|SWT.SHADOW_OUT);
  128. clbl_weekDay.setForeground(COLOR_SYSTEM_WHITE);
  129. clbl_weekDay.setBackground(COLOR_CLBLWEEKDAY_BACKGROUND);
  130. gridData_1=newGridData(SWT.FILL,SWT.CENTER,true,false);
  131. gridData_1.widthHint=GRIDDATAHINT;
  132. gridData_1.heightHint=GRIDDATAHINT;
  133. clbl_weekDay.setLayoutData(gridData_1);
  134. clbl_weekDay.setText(weekdays[i]);
  135. }
  136. //将当月的所有日的标签显示出来
  137. for(inti=0;i<clbl_days.length;i++){
  138. clbl_days[i]=newCLabel(shell,SWT.FLAT|SWT.CENTER);
  139. clbl_days[i].setLayoutData(newGridData(GridData.FILL_HORIZONTAL
  140. |GridData.FILL_VERTICAL));
  141. clbl_days[i].setCursor(display.getSystemCursor(SWT.CURSOR_HAND));
  142. clbl_days[i].addMouseListener(clblMouseListener);
  143. }
  144. }
  145. /**
  146. *给年的下拉框设置设置选项
  147. *@parammiddleYear中间年份
  148. */
  149. privatevoidsetCboYearItems(intmiddleYear){
  150. intselectIndex=halfYearItemCount;
  151. //确保不出现负的年份
  152. if(middleYear<halfYearItemCount){
  153. selectIndex=middleYear;
  154. middleYear=halfYearItemCount;
  155. }
  156. intindex=0;
  157. for(inti=middleYear-halfYearItemCount;i<=middleYear+halfYearItemCount;i++){
  158. years[index++]=""+i;
  159. }
  160. cbo_year.setItems(years);
  161. cbo_year.select(selectIndex);
  162. }
  163. /**
  164. *得到指定年月的天数
  165. *
  166. *@paramyear
  167. *年
  168. *@parammonth
  169. *月(1-12)
  170. *@return指定年月的天数,如:year=2008,month=1就返回2008年1月的天数:31
  171. */
  172. privateintgetDayCountOfMonth(intyear,intmonth){
  173. Calendarcal=Calendar.getInstance();
  174. cal.set(year,month-1,1);//因为Calendar中的month是0-11,故month要减去1
  175. Calendarcal2=(Calendar)cal.clone();
  176. cal2.add(Calendar.MONTH,1);
  177. cal2.add(Calendar.DAY_OF_MONTH,-1);
  178. returncal2.get(Calendar.DAY_OF_MONTH);
  179. }
  180. /**
  181. *得到下拉框中的年和月
  182. */
  183. privateint[]getYearAndMonth(){
  184. Calendarnow=Calendar.getInstance();
  185. intyear=now.get(Calendar.YEAR);//年
  186. intmonth=now.get(Calendar.MONTH)+1;//月
  187. if("".equals(cbo_year.getText().trim()))
  188. cbo_year.setText(year+"");
  189. else{
  190. try{
  191. year=Integer.parseInt(cbo_year.getText().trim());
  192. }catch(NumberFormatExceptione){
  193. //年下拉框中的文本不是一个Int型数字,则设为当前年
  194. cbo_year.setText(year+"");
  195. }
  196. }
  197. if("".equals(cbo_month.getText().trim()))
  198. cbo_month.setText(month+"");
  199. else{
  200. try{
  201. month=Integer.parseInt(cbo_month.getText().trim());
  202. if(month<1){
  203. month=1;
  204. cbo_month.setText("1");
  205. }elseif(month>12){
  206. month=12;
  207. cbo_month.setText("12");
  208. }
  209. }catch(NumberFormatExceptione){
  210. //月下拉框中的文本不是一个Int型数字,则设为当前月
  211. cbo_month.setText(month+"");
  212. }
  213. }
  214. returnnewint[]{year,month};
  215. }
  216. /**
  217. *为所有的日标签设置相关属性
  218. *@paramreflushCboYearItems是否刷新年下拉框中的选项
  219. */
  220. privatevoiddisplayClblDays(booleanreflushCboYearItems){
  221. Calendarcalendar=Calendar.getInstance();
  222. intcurrentDate=calendar.get(Calendar.DATE);//日
  223. int[]yearAndMonth=getYearAndMonth();
  224. intyear=yearAndMonth[0];//年
  225. intmonth=yearAndMonth[1];//月
  226. calendar.set(year,month-1,1);//Calendar中的month为0-11,故在此处month要减去1
  227. intbeginIndex=calendar.get(Calendar.DAY_OF_WEEK)-1;//得到指定月份的第一天为星期几,Calendar对象返回的1-7对应星期日-星期六,故减去1
  228. intendIndex=beginIndex+getDayCountOfMonth(year,month)-1;
  229. if(reflushCboYearItems)
  230. setCboYearItems(year);
  231. intday=1;
  232. for(inti=0;i<clbl_days.length;i++){
  233. if(i>=beginIndex&&i<=endIndex){
  234. clbl_days[i].setText(day+"");
  235. clbl_days[i].setToolTipText(year+"-"+month+"-"+day);
  236. if(day==currentDate)
  237. clbl_days[i].setBackground(COLOR_SYSTEM_BLUE);
  238. else
  239. clbl_days[i].setBackground(COLOR_SYSTEM_WHITE);
  240. day++;
  241. }else{
  242. clbl_days[i].setText("");
  243. clbl_days[i].setToolTipText("");
  244. clbl_days[i].setBackground(COLOR_SYSTEM_WHITE);
  245. }
  246. }
  247. }
  248. publicStringopen(){
  249. displayClblDays(true);
  250. shell.open();
  251. while(!shell.isDisposed()){
  252. if(!display.readAndDispatch()){
  253. display.sleep();
  254. }
  255. }
  256. COLOR_SHELL_BACKGROUND.dispose();
  257. COLOR_CLBLWEEKDAY_BACKGROUND.dispose();
  258. returnselectedDate;
  259. }
  260. privateMouseListenerclblMouseListener=newMouseAdapter(){
  261. /*
  262. *(non-Javadoc)
  263. *
  264. *@seeorg.eclipse.swt.events.MouseAdapter#mouseDown(org.eclipse.swt.events.MouseEvent)
  265. */
  266. @Override
  267. publicvoidmouseDown(MouseEvente){
  268. selectedDate=((CLabel)e.widget).getToolTipText();
  269. if(!"".equals(selectedDate))
  270. shell.close();
  271. }
  272. };
  273. privateSelectionListenerbtnSelectionListener=newSelectionAdapter(){
  274. publicvoidwidgetSelected(SelectionEvente){
  275. Stringtooptip=((Button)e.widget).getToolTipText();
  276. int[]yearAndMonth=getYearAndMonth();
  277. intyear=yearAndMonth[0];
  278. intmonth=yearAndMonth[1];
  279. booleanreflushCboyearItems=true;
  280. //前一年
  281. if(TOOPTIPTEXT_PREVIOUSYEAR.equals(tooptip))
  282. cbo_year.setText((year-1)+"");
  283. //后一年
  284. elseif(TOOPTIPTEXT_NEXTYEAR.equals(tooptip))
  285. cbo_year.setText((year+1)+"");
  286. //前一月
  287. elseif(TOOPTIPTEXT_PREVIOUSMONTH.equals(tooptip)){
  288. if(month==1){
  289. setCboYearItems(year-1);
  290. cbo_month.select(11);
  291. }else{
  292. cbo_month.select(month-2);
  293. reflushCboyearItems=false;
  294. }
  295. //后一月
  296. }elseif(TOOPTIPTEXT_NEXTMONTH.equals(tooptip)){
  297. if(month==12){
  298. setCboYearItems(year+1);
  299. cbo_month.select(0);
  300. }else{
  301. cbo_month.select(month);
  302. reflushCboyearItems=false;
  303. }
  304. }
  305. displayClblDays(reflushCboyearItems);
  306. }
  307. };
  308. privateSelectionListenercboSelectionListener=newSelectionAdapter(){
  309. publicvoidwidgetSelected(SelectionEvente){
  310. booleanreflushCboyearItems=e.widget==cbo_year?true:false;
  311. displayClblDays(reflushCboyearItems);
  312. }
  313. };
  314. privateKeyListenercboKeyListener=newKeyAdapter(){
  315. /*(non-Javadoc)
  316. *@seeorg.eclipse.swt.events.KeyAdapter#keyPressed(org.eclipse.swt.events.KeyEvent)
  317. */
  318. @Override
  319. publicvoidkeyPressed(KeyEventevent){
  320. //小键盘的Enter或Enter,显示日历
  321. if(event.keyCode==16777296||event.keyCode==13){
  322. booleanreflushCboyearItems=event.widget==cbo_year?true:false;
  323. displayClblDays(reflushCboyearItems);
  324. }else{
  325. //只能输入数字
  326. if((event.keyCode<'0'||event.keyCode>'9')&&!(event.keyCode==SWT.BS||event.keyCode==SWT.ARROW_UP||event.keyCode==SWT.ARROW_DOWN))
  327. event.doit=false;
  328. }
  329. }
  330. };
  331. publicstaticvoidmain(Stringargs[]){
  332. try{
  333. Displaydisplay=Display.getDefault();
  334. Shellshell=newShell(display,SWT.SHELL_TRIM);
  335. shell.setSize(500,375);
  336. shell.open();
  337. shell.layout();
  338. CalendarWidgetca=newCalendarWidget(shell);
  339. System.out.println(ca.open());
  340. while(!shell.isDisposed()){
  341. if(!display.readAndDispatch())
  342. display.sleep();
  343. }
  344. }catch(Exceptione){
  345. e.printStackTrace();
  346. }
  347. }
  348. }

分享到:
评论

相关推荐

    SWT/JFace 自定义日历控件(可绑定注册到其他控件)

    因此自己写一个日历控件用着方便,功能大致如下: 1、日历控件可自定义设置常见的几种日期格式; 2、可以绑定注册到其他控件如:文本框、按钮、标签上使用; 3、可以绑定注册控件后给指定其他控件赋值。 使用者可以...

    SWT 实现日历空间

    用 SWT 来显示 日历控件 源码 很实用

    SWT日历控件

    在使用SWT 的控件CalendarCombo时,点击None之后再选择其他时间,会出现空指针异常,且会导致程序崩溃,改包下的几个类通过改写CalendarCombo解决了这个小bug ,使用方法与CalendarCombo类似,MyCalendarCombo mc=...

    DatePicker

    Java swing日历控件,界面精美,使用方便,能用于个人作品 首先,声明一点,这个控件是我从一套据说价值九百多美元的swing类包中提取出来, 并加以修改的,所以: 一, 你不能把该控件用于任何商业产品中。 二,...

    JAVA上百实例源码以及开源项目源代码

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

    JAVA上百实例源码以及开源项目

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

    java源码包---java 源码 大量 实例

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

    java源码包2

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

    java源码包3

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

    java源码包4

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

    成百上千个Java 源码DEMO 3(1-4是独立压缩包)

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

Global site tag (gtag.js) - Google Analytics