下面是我用SWT写的一个日历控件,主要是用于让用记选择日期,可以通过按钮 上一年、下一年、上一月 和 下一月 调整到要切换的月份,也可以通过改 年 和 月 的下拉框中的选择项来切换到指定年月,还可以直接在 年 和 月 的下拉框中输入要切换到的年月后按 回车键 切换到指定年月。运行后的效果如下图所示:
源代码如下:
- packagecom.hmw.tools;
- importjava.util.Calendar;
- importorg.eclipse.swt.SWT;
- importorg.eclipse.swt.custom.CLabel;
- importorg.eclipse.swt.events.KeyAdapter;
- importorg.eclipse.swt.events.KeyEvent;
- importorg.eclipse.swt.events.KeyListener;
- importorg.eclipse.swt.events.MouseAdapter;
- importorg.eclipse.swt.events.MouseEvent;
- importorg.eclipse.swt.events.MouseListener;
- importorg.eclipse.swt.events.SelectionAdapter;
- importorg.eclipse.swt.events.SelectionEvent;
- importorg.eclipse.swt.events.SelectionListener;
- importorg.eclipse.swt.graphics.Color;
- importorg.eclipse.swt.graphics.Rectangle;
- importorg.eclipse.swt.layout.GridData;
- importorg.eclipse.swt.layout.GridLayout;
- importorg.eclipse.swt.widgets.Button;
- importorg.eclipse.swt.widgets.Combo;
- importorg.eclipse.swt.widgets.Display;
- importorg.eclipse.swt.widgets.Shell;
- /**
- *日历弹出窗口
- *
- *@authorCarlHe
- *
- */
- publicclassCalendarWidget{
- /**显示对象*/
- privateDisplaydisplay=null;
- /**窗口对象*/
- privateShellshell=null;
- /**窗口的宽度*/
- privatestaticfinalintSHELLWIDTH=380;
- /**窗口的高度*/
- privatestaticfinalintSHELLHEIGHT=280;
- /**Clabel大小的宽度*/
- privatestaticfinalintGRIDDATAHINT=20;
- /**上一年*/
- privatestaticfinalStringTOOPTIPTEXT_PREVIOUSYEAR="上一年";
- /**下一年*/
- privatestaticfinalStringTOOPTIPTEXT_NEXTYEAR="下一年";
- /**上一月*/
- privatestaticfinalStringTOOPTIPTEXT_PREVIOUSMONTH="上一月";
- /**下一月*/
- privatestaticfinalStringTOOPTIPTEXT_NEXTMONTH="下一月";
- /**星期日——星期六*/
- privatestaticfinalString[]weekdays={"星期日","星期一","星期二","星期三",
- "星期四","星期五","星期六"};
- /**年下拉框显示到当前年的前后多少年*/
- privatestaticfinalinthalfYearItemCount=20;
- /**年份下拉框选项的数组*/
- privatestaticfinalString[]years=newString[halfYearItemCount*2+1];
- /**月份:1——12*/
- privatestaticfinalString[]months={"1","2","3","4","5","6","7","8","9","10","11","12",};
- /**选择的日期:yyyy-MM-dd*/
- privateStringselectedDate="";
- /**年的下拉框*/
- Combocbo_year;
- /**月的下拉框*/
- Combocbo_month;
- /**显示日的Clable数组*/
- privatefinalCLabel[]clbl_days=newCLabel[42];//6*7
- /**日历窗体的背景颜色*/
- privateColorCOLOR_SHELL_BACKGROUND=null;
- /**星期X标签的背景颜色*/
- privateColorCOLOR_CLBLWEEKDAY_BACKGROUND=null;
- /**白色(得到的为系统的颜色,不需要对其进行资源释放)*/
- privateColorCOLOR_SYSTEM_WHITE=null;
- /**蓝色(得到的为系统的颜色,不需要对其进行资源释放)*/
- privateColorCOLOR_SYSTEM_BLUE=null;
- publicCalendarWidget(Shellparent){
- RectangleparentRec=parent.getBounds();
- display=parent.getDisplay();
- COLOR_SHELL_BACKGROUND=newColor(display,219,235,250);
- COLOR_CLBLWEEKDAY_BACKGROUND=newColor(display,64,128,128);
- COLOR_SYSTEM_WHITE=display.getSystemColor(SWT.COLOR_WHITE);
- COLOR_SYSTEM_BLUE=display.getSystemColor(SWT.COLOR_BLUE);
- shell=newShell(parent,SWT.CLOSE|SWT.APPLICATION_MODAL);
- shell.setText("选择日期");
- //保证显示在父窗体的正中间
- shell.setBounds(parentRec.x+(parentRec.width-SHELLWIDTH)/2,
- parentRec.y+(parentRec.height-SHELLHEIGHT)/2,SHELLWIDTH,
- SHELLHEIGHT);
- GridLayoutgridLayout=newGridLayout();
- gridLayout.numColumns=7;
- gridLayout.makeColumnsEqualWidth=true;
- shell.setLayout(gridLayout);
- shell.setBackground(COLOR_SHELL_BACKGROUND);
- //上一年
- Buttonbtn_yearPrevious=newButton(shell,SWT.ARROW|SWT.UP);
- btn_yearPrevious.setLayoutData(newGridData(SWT.FILL,SWT.CENTER,true,false));
- btn_yearPrevious.setToolTipText(TOOPTIPTEXT_PREVIOUSYEAR);
- btn_yearPrevious.addSelectionListener(btnSelectionListener);
- //上一月
- Buttonbtn_monthPrevious=newButton(shell,SWT.ARROW|SWT.LEFT);
- btn_monthPrevious.setLayoutData(newGridData(SWT.FILL,SWT.CENTER,true,false));
- btn_monthPrevious.setToolTipText(TOOPTIPTEXT_PREVIOUSMONTH);
- btn_monthPrevious.addSelectionListener(btnSelectionListener);
- cbo_year=newCombo(shell,SWT.DROP_DOWN);
- cbo_year.setLayoutData(newGridData(SWT.FILL,SWT.CENTER,true,false));
- cbo_year.addSelectionListener(cboSelectionListener);
- cbo_year.addKeyListener(cboKeyListener);
- CLabelclabel=newCLabel(shell,SWT.CENTER|SWT.SHADOW_OUT);
- clabel.setBackground(COLOR_SYSTEM_WHITE);
- clabel.setLayoutData(newGridData(SWT.FILL,SWT.CENTER,true,false));
- clabel.setText("-");
- cbo_month=newCombo(shell,SWT.DROP_DOWN);
- cbo_month.setItems(months);
- cbo_month.select(Calendar.getInstance().get(Calendar.MONTH));
- cbo_month.setLayoutData(newGridData(SWT.FILL,SWT.CENTER,true,false));
- cbo_month.addSelectionListener(cboSelectionListener);
- cbo_month.addKeyListener(cboKeyListener);
- //下一月
- Buttonbtn_monthNext=newButton(shell,SWT.ARROW|SWT.RIGHT);
- btn_monthNext.setLayoutData(newGridData(SWT.FILL,SWT.CENTER,true,false));
- btn_monthNext.setToolTipText(TOOPTIPTEXT_NEXTMONTH);
- btn_monthNext.addSelectionListener(btnSelectionListener);
- //下一年
- Buttonbtn_yearNext=newButton(shell,SWT.ARROW|SWT.DOWN);
- btn_yearNext.setLayoutData(newGridData(SWT.FILL,SWT.CENTER,true,false));
- btn_yearNext.setToolTipText(TOOPTIPTEXT_NEXTYEAR);
- btn_yearNext.addSelectionListener(btnSelectionListener);
- GridDatagridData_1=null;
- //将星期日——星期六的标签显示出来
- for(inti=0;i<weekdays.length;i++){
- CLabelclbl_weekDay=newCLabel(shell,SWT.CENTER|SWT.SHADOW_OUT);
- clbl_weekDay.setForeground(COLOR_SYSTEM_WHITE);
- clbl_weekDay.setBackground(COLOR_CLBLWEEKDAY_BACKGROUND);
- gridData_1=newGridData(SWT.FILL,SWT.CENTER,true,false);
- gridData_1.widthHint=GRIDDATAHINT;
- gridData_1.heightHint=GRIDDATAHINT;
- clbl_weekDay.setLayoutData(gridData_1);
- clbl_weekDay.setText(weekdays[i]);
- }
- //将当月的所有日的标签显示出来
- for(inti=0;i<clbl_days.length;i++){
- clbl_days[i]=newCLabel(shell,SWT.FLAT|SWT.CENTER);
- clbl_days[i].setLayoutData(newGridData(GridData.FILL_HORIZONTAL
- |GridData.FILL_VERTICAL));
- clbl_days[i].setCursor(display.getSystemCursor(SWT.CURSOR_HAND));
- clbl_days[i].addMouseListener(clblMouseListener);
- }
- }
- /**
- *给年的下拉框设置设置选项
- *@parammiddleYear中间年份
- */
- privatevoidsetCboYearItems(intmiddleYear){
- intselectIndex=halfYearItemCount;
- //确保不出现负的年份
- if(middleYear<halfYearItemCount){
- selectIndex=middleYear;
- middleYear=halfYearItemCount;
- }
- intindex=0;
- for(inti=middleYear-halfYearItemCount;i<=middleYear+halfYearItemCount;i++){
- years[index++]=""+i;
- }
- cbo_year.setItems(years);
- cbo_year.select(selectIndex);
- }
- /**
- *得到指定年月的天数
- *
- *@paramyear
- *年
- *@parammonth
- *月(1-12)
- *@return指定年月的天数,如:year=2008,month=1就返回2008年1月的天数:31
- */
- privateintgetDayCountOfMonth(intyear,intmonth){
- Calendarcal=Calendar.getInstance();
- cal.set(year,month-1,1);//因为Calendar中的month是0-11,故month要减去1
- Calendarcal2=(Calendar)cal.clone();
- cal2.add(Calendar.MONTH,1);
- cal2.add(Calendar.DAY_OF_MONTH,-1);
- returncal2.get(Calendar.DAY_OF_MONTH);
- }
- /**
- *得到下拉框中的年和月
- */
- privateint[]getYearAndMonth(){
- Calendarnow=Calendar.getInstance();
- intyear=now.get(Calendar.YEAR);//年
- intmonth=now.get(Calendar.MONTH)+1;//月
- if("".equals(cbo_year.getText().trim()))
- cbo_year.setText(year+"");
- else{
- try{
- year=Integer.parseInt(cbo_year.getText().trim());
- }catch(NumberFormatExceptione){
- //年下拉框中的文本不是一个Int型数字,则设为当前年
- cbo_year.setText(year+"");
- }
- }
- if("".equals(cbo_month.getText().trim()))
- cbo_month.setText(month+"");
- else{
- try{
- month=Integer.parseInt(cbo_month.getText().trim());
- if(month<1){
- month=1;
- cbo_month.setText("1");
- }elseif(month>12){
- month=12;
- cbo_month.setText("12");
- }
- }catch(NumberFormatExceptione){
- //月下拉框中的文本不是一个Int型数字,则设为当前月
- cbo_month.setText(month+"");
- }
- }
- returnnewint[]{year,month};
- }
- /**
- *为所有的日标签设置相关属性
- *@paramreflushCboYearItems是否刷新年下拉框中的选项
- */
- privatevoiddisplayClblDays(booleanreflushCboYearItems){
- Calendarcalendar=Calendar.getInstance();
- intcurrentDate=calendar.get(Calendar.DATE);//日
- int[]yearAndMonth=getYearAndMonth();
- intyear=yearAndMonth[0];//年
- intmonth=yearAndMonth[1];//月
- calendar.set(year,month-1,1);//Calendar中的month为0-11,故在此处month要减去1
- intbeginIndex=calendar.get(Calendar.DAY_OF_WEEK)-1;//得到指定月份的第一天为星期几,Calendar对象返回的1-7对应星期日-星期六,故减去1
- intendIndex=beginIndex+getDayCountOfMonth(year,month)-1;
- if(reflushCboYearItems)
- setCboYearItems(year);
- intday=1;
- for(inti=0;i<clbl_days.length;i++){
- if(i>=beginIndex&&i<=endIndex){
- clbl_days[i].setText(day+"");
- clbl_days[i].setToolTipText(year+"-"+month+"-"+day);
- if(day==currentDate)
- clbl_days[i].setBackground(COLOR_SYSTEM_BLUE);
- else
- clbl_days[i].setBackground(COLOR_SYSTEM_WHITE);
- day++;
- }else{
- clbl_days[i].setText("");
- clbl_days[i].setToolTipText("");
- clbl_days[i].setBackground(COLOR_SYSTEM_WHITE);
- }
- }
- }
- publicStringopen(){
- displayClblDays(true);
- shell.open();
- while(!shell.isDisposed()){
- if(!display.readAndDispatch()){
- display.sleep();
- }
- }
- COLOR_SHELL_BACKGROUND.dispose();
- COLOR_CLBLWEEKDAY_BACKGROUND.dispose();
- returnselectedDate;
- }
- privateMouseListenerclblMouseListener=newMouseAdapter(){
- /*
- *(non-Javadoc)
- *
- *@seeorg.eclipse.swt.events.MouseAdapter#mouseDown(org.eclipse.swt.events.MouseEvent)
- */
- @Override
- publicvoidmouseDown(MouseEvente){
- selectedDate=((CLabel)e.widget).getToolTipText();
- if(!"".equals(selectedDate))
- shell.close();
- }
- };
- privateSelectionListenerbtnSelectionListener=newSelectionAdapter(){
- publicvoidwidgetSelected(SelectionEvente){
- Stringtooptip=((Button)e.widget).getToolTipText();
- int[]yearAndMonth=getYearAndMonth();
- intyear=yearAndMonth[0];
- intmonth=yearAndMonth[1];
- booleanreflushCboyearItems=true;
- //前一年
- if(TOOPTIPTEXT_PREVIOUSYEAR.equals(tooptip))
- cbo_year.setText((year-1)+"");
- //后一年
- elseif(TOOPTIPTEXT_NEXTYEAR.equals(tooptip))
- cbo_year.setText((year+1)+"");
- //前一月
- elseif(TOOPTIPTEXT_PREVIOUSMONTH.equals(tooptip)){
- if(month==1){
- setCboYearItems(year-1);
- cbo_month.select(11);
- }else{
- cbo_month.select(month-2);
- reflushCboyearItems=false;
- }
- //后一月
- }elseif(TOOPTIPTEXT_NEXTMONTH.equals(tooptip)){
- if(month==12){
- setCboYearItems(year+1);
- cbo_month.select(0);
- }else{
- cbo_month.select(month);
- reflushCboyearItems=false;
- }
- }
- displayClblDays(reflushCboyearItems);
- }
- };
- privateSelectionListenercboSelectionListener=newSelectionAdapter(){
- publicvoidwidgetSelected(SelectionEvente){
- booleanreflushCboyearItems=e.widget==cbo_year?true:false;
- displayClblDays(reflushCboyearItems);
- }
- };
- privateKeyListenercboKeyListener=newKeyAdapter(){
- /*(non-Javadoc)
- *@seeorg.eclipse.swt.events.KeyAdapter#keyPressed(org.eclipse.swt.events.KeyEvent)
- */
- @Override
- publicvoidkeyPressed(KeyEventevent){
- //小键盘的Enter或Enter,显示日历
- if(event.keyCode==16777296||event.keyCode==13){
- booleanreflushCboyearItems=event.widget==cbo_year?true:false;
- displayClblDays(reflushCboyearItems);
- }else{
- //只能输入数字
- if((event.keyCode<'0'||event.keyCode>'9')&&!(event.keyCode==SWT.BS||event.keyCode==SWT.ARROW_UP||event.keyCode==SWT.ARROW_DOWN))
- event.doit=false;
- }
- }
- };
- publicstaticvoidmain(Stringargs[]){
- try{
- Displaydisplay=Display.getDefault();
- Shellshell=newShell(display,SWT.SHELL_TRIM);
- shell.setSize(500,375);
- shell.open();
- shell.layout();
- CalendarWidgetca=newCalendarWidget(shell);
- System.out.println(ca.open());
- while(!shell.isDisposed()){
- if(!display.readAndDispatch())
- display.sleep();
- }
- }catch(Exceptione){
- e.printStackTrace();
- }
- }
- }