最近在做项目时在日期选择控件上花了不少时间,所以在此总结一下,引用的地方均注明了原文出处。
一、SWING版
运行效果图:
代码:
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.swing.border. * ;
import javax.swing. event . * ;
import javax.swing. * ;
import java.awt. * ;
import java.awt. event . * ;
/* *
* 日期的选择控件,可以作为普通的组件使用,在构造函数中,必须传入一个该组件的所有者对象。
* 并且该对象只能是一个Frame对象或者一个JFrame对象。
* 使用方法如下:
* JFrame frame2 = new JFrame();
* frame2.getContentPane().setLayout(null);
* DateChooser date = new DateChooser(frame2);
* frame2.getContentPane().add(date);
* frame2.setSize(500, 400);
* frame2.setVisible(true);
*组件的外观象一个combox,单击下拉按钮就可以对日期进行选择。
* Title: 日期选择控件
* Copyright: Copyright (c) 2006
* Company: Xaccp
* Date:2006年6月17日
* @author Tellixu(许天岭)
* @version 1.0
*/
public class DateChooser extends JPanel
{
private int width = 200 ; // 日期控件的宽度
private int height = 220 ; // 日期控件的高度
private GridBagLayout gridBagLayout1 = new GridBagLayout();
private JTextField dateField = new JTextField();
private DateChooserButton btnChoose = new DateChooserButton( " ▼ " ); // ▼是指:▼下拉箭头的unicode码
private String parten;
private Container owner;
private int length = 120 ;
public DateChooser(Container owner, int length) {
this .owner = owner;
this .parten = " yyyy-MM-dd " ;
this .length = length;
try {
init();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
/* *
* 根据一个所有者和一个日期的显示格式构造一个DateChooser对象。
*/
public DateChooser(Container owner, String partten, int length) {
this .owner = owner;
this .parten = partten;
this .length = length;
try {
init();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
/* *
* 根据一个所有者和一个日期的显示格式构造一个DateChooser对象。
*/
public DateChooser(Container owner, String partten) {
this .owner = owner;
this .parten = partten;
try {
init();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
/* *
* 以缺省的partten构建DateChooser对象
* 日期选择框的所有者必须是Frame或者是JFrame对象。
*/
public DateChooser(Container owner) {
this .owner = owner;
this .parten = " yyyy-MM-dd " ;
try {
init();
}
catch (Exception ex) {
ex.printStackTrace();
}
}
/* *
* 系统初始化
* @throws Exception
*/
private void init() throws Exception {
dateField.setToolTipText( " 单击右边的按钮即可选择日期 " );
btnChoose.setToolTipText( " 单击即可选择日期 " );
this .setLayout(gridBagLayout1);
dateField.setEditable( false );
btnChoose.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
DateChooser. this .btnChoose_actionPerformed(e);
}
});
Date date = new Date();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(parten);
this .setText(simpleDateFormat.format(date));
this .add(dateField, new GridBagConstraints( 0 , 0 , 1 , 1 , 0.0 , 0.0
, GridBagConstraints.CENTER,
GridBagConstraints.NONE,
new Insets( 0 , 0 , 0 , 0 ), this .length, 0 ));
this .add(btnChoose, new GridBagConstraints( 1 , 0 , 1 , 1 , 0.0 , 0.0
, GridBagConstraints.CENTER, GridBagConstraints.NONE,
new Insets( 0 , 0 , 0 , 0 ), 0 , 0 ));
}
public void setToolTipText(String text) {
dateField.setToolTipText(text);
btnChoose.setToolTipText(text);
}
/* *
* 下拉按钮的事件处理
* @param e ActionEvent
*/
public void btnChoose_actionPerformed(ActionEvent e) {
java.awt.Rectangle r = dateField.getBounds();
Point pOnScreen = dateField.getLocationOnScreen();
Point result = new Point(pOnScreen.x, pOnScreen.y + r.height);
Point powner = owner.getLocation();
int offsetX = (pOnScreen.x + width) - (powner.x + owner.getWidth());
int offsetY = (pOnScreen.y + r.height + height) -
(powner.y + owner.getHeight());
if (offsetX > 0 ) {
result.x -= offsetX;
}
if (offsetY > 0 ) {
result.y -= height + r.height;
}
javax.swing.JDialog dateFrame = new javax.swing.JDialog();
dateFrame.setModal( false );
dateFrame.setUndecorated( true );
dateFrame.setLocation(result);
dateFrame.setSize(width, height);
dateFrame.addWindowListener( new WindowAdapter() {
// 在任意的非日期选择区单击,则日期选择组件将变为非活动状态,自动释放资源。
public void windowDeactivated(WindowEvent e) {
javax.swing.JDialog f = (javax.swing.JDialog) e.getSource();
f.dispose();
}
});
DatePanel datePanel = new DatePanel(dateFrame, parten);
dateFrame.getContentPane().setLayout( new BorderLayout());
dateFrame.getContentPane().add(datePanel);
dateFrame.setVisible( true );
}
/* *
* 得到日期控件中的值
* @return String
*/
public String getText() {
return this .dateField.getText();
}
/* *
* 设置文本域的值
* @param text String
*/
public void setText(String text) {
this .dateField.setText(text);
}
/* *
* 该方法非常有用,是外部直接访问的TextField对象。
* @return JTextField
*/
public JTextField getDateField() {
return dateField;
}
/* *
* 内部类,日期选择控件的主体,封装了所有日期选择的内容,主要是一个Panel
*/
class DatePanel
extends JPanel implements MouseListener,
ChangeListener {
int startYear = 1970 ; // 默认【最小】显示年份
int lastYear = 2050 ; // 默认【最大】显示年份
Color backGroundColor = Color.gray; // 底色
// 月历表格配色---------------- //
Color palletTableColor = Color.white; // 日历表底色
Color weekFontColor = Color.blue; // 星期文字色
Color dateFontColor = Color.black; // 日期文字色
Color weekendFontColor = Color.red; // 周末文字色
Color moveButtonColor = Color.BLUE; // 鼠标移动的日历底色
Color todayBtnColor = Color.pink; // 今天的日历底色
// 控制条配色------------------ //
Color controlLineColor = Color.pink; // 控制条底色
Color controlTextColor = Color.white; // 控制条标签文字色
JSpinner yearSpin;
JSpinner monthSpin;
JSpinner hourSpin;
JButton[][] daysButton = new JButton[ 6 ][ 7 ];
javax.swing.JDialog f;
JPanel dayPanel = new JPanel(); // 日期panel
JPanel yearPanel = new JPanel();
Calendar calendar = Calendar.getInstance();
String pattern;
/* *
* 日期选择控件放在了非模态对话框中
*/
public DatePanel(javax.swing.JDialog target, String pattern) {
super();
this .f = target;
this .pattern = pattern;
setLayout( new BorderLayout());
setBorder( new LineBorder(backGroundColor, 2 ));
setBackground(backGroundColor);
initButton(); // 初始化放置日期的按钮。
createYearAndMonthPanal(); //
this .flushWeekAndDayPanal(calendar); // 之前必须先保证放置日期的按钮已经初始化。
this .setLayout( new BorderLayout());
this .add(yearPanel, BorderLayout.NORTH);
this .add(dayPanel, BorderLayout.CENTER);
}
/* *
* 日期选择控件的按钮初始化
*/
private void initButton() {
int actionCommandId = 1 ;
for ( int i = 0 ; i < 6 ; i ++ ) {
for ( int j = 0 ; j < 7 ; j ++ ) {
JButton numberButton = new JButton();
numberButton.setBorder(BorderFactory.createEmptyBorder());
numberButton.setHorizontalAlignment(SwingConstants.CENTER);
numberButton.setActionCommand(String.valueOf(
actionCommandId));
numberButton.addMouseListener( this );
numberButton.setBackground(palletTableColor);
numberButton.setForeground(dateFontColor);
numberButton.setText(String.valueOf(actionCommandId));
numberButton.setPreferredSize( new Dimension( 25 , 25 ));
daysButton[i][j] = numberButton;
actionCommandId ++ ;
}
}
}
private Date getNowDate() {
return Calendar.getInstance().getTime();
}
private Calendar getNowCalendar() {
Calendar result = Calendar.getInstance();
return result;
}
private Date getSelectDate() {
return calendar.getTime();
}
/* *
* 创建年月日的面板
*/
private void createYearAndMonthPanal() {
Calendar c = getNowCalendar();
int currentYear = c. get (Calendar.YEAR);
int currentMonth = c. get (Calendar.MONTH) + 1 ;
int currentHour = c. get (Calendar.HOUR_OF_DAY);
yearSpin = new JSpinner( new javax.swing.SpinnerNumberModel(
currentYear,
startYear, lastYear, 1 ));
monthSpin = new JSpinner( new javax.swing.SpinnerNumberModel(
currentMonth, 1 , 12 ,
1 ));
hourSpin = new JSpinner( new javax.swing.SpinnerNumberModel(
currentHour, 0 , 23 ,
1 ));
yearPanel.setLayout( new java.awt.FlowLayout());
yearPanel.setBackground(controlLineColor);
yearSpin.setPreferredSize( new Dimension( 48 , 20 ));
yearSpin.setName( " Year " );
yearSpin.setEditor( new JSpinner.NumberEditor(yearSpin, " #### " ));
yearSpin.addChangeListener( this );
yearPanel.add(yearSpin);
JLabel yearLabel = new JLabel( " 年 " );
yearLabel.setForeground(controlTextColor);
yearPanel.add(yearLabel);
monthSpin.setPreferredSize( new Dimension( 35 , 20 ));
monthSpin.setName( " Month " );
monthSpin.addChangeListener( this );
yearPanel.add(monthSpin);
JLabel monthLabel = new JLabel( " 月 " );
monthLabel.setForeground(controlTextColor);
yearPanel.add(monthLabel);
hourSpin.setPreferredSize( new Dimension( 35 , 20 ));
hourSpin.setName( " Hour " );
hourSpin.addChangeListener( this );
yearPanel.add(hourSpin);
JLabel hourLabel = new JLabel( " 时 " );
hourLabel.setForeground(controlTextColor);
yearPanel.add(hourLabel);
}
/* *
* 根据日期刷新显示面板
*/
private void flushWeekAndDayPanal(Calendar c) {
// c.set
c. set (Calendar.DAY_OF_MONTH, 1 );
c.setFirstDayOfWeek( 0 );
int firstdayofWeek = c. get (Calendar.DAY_OF_WEEK);
int lastdayofWeek = c.getActualMaximum(Calendar.DAY_OF_MONTH);
String colname[] = {
" 日 " , " 一 " , " 二 " , " 三 " , " 四 " , " 五 " , " 六 " };
int today = getNowCalendar(). get (Calendar.DAY_OF_MONTH);
// 设置固定字体,以免调用环境改变影响界面美观
dayPanel.setFont( new java.awt.Font( " 宋体 " , java.awt.Font.PLAIN, 12 ));
dayPanel.setLayout( new GridBagLayout());
dayPanel.setBackground(Color.white);
JLabel cell;
for ( int i = 0 ; i < 7 ; i ++ ) {
cell = new JLabel(colname[i]);
cell.setHorizontalAlignment(JLabel.CENTER);
cell.setPreferredSize( new Dimension( 25 , 25 ));
if (i == 0 || i == 6 ) {
cell.setForeground(weekendFontColor);
}
else {
cell.setForeground(weekFontColor);
}
dayPanel.add(cell, new GridBagConstraints(i, 0 , 1 , 1 , 0.0 , 0.0
, GridBagConstraints.CENTER,
GridBagConstraints.NONE,
new Insets( 0 , 0 , 0 , 0 ), 0 , 0 )
);
}
int actionCommandId = 1 ;
for ( int i = 0 ; i < 6 ; i ++ ) {
for ( int j = 0 ; j < 7 ; j ++ ) {
JButton numberButton = daysButton[i][j];
actionCommandId = Integer.parseInt(numberButton.
getActionCommand());
if (actionCommandId == today) {
numberButton.setBackground(todayBtnColor);
}
if ( (actionCommandId + firstdayofWeek - 2 ) % 7 == 6 ||
(actionCommandId + firstdayofWeek - 2 ) % 7 == 0 ) {
numberButton.setForeground(weekendFontColor);
}
else {
numberButton.setForeground(dateFontColor);
}
if (actionCommandId <= lastdayofWeek) {
int y = 0 ;
if ( (firstdayofWeek - 1 ) <=
(j + firstdayofWeek - 1 ) % 7 ) {
y = i + 1 ;
}
else {
y = i + 2 ;
}
dayPanel.add(numberButton,
new GridBagConstraints( (j +
firstdayofWeek -
1 ) %
7 , y, 1 , 1 , 0.0 , 0.0
, GridBagConstraints.CENTER,
GridBagConstraints.NONE,
new Insets( 0 , 0 , 0 , 0 ), 0 , 0 )
);
}
}
}
}
private int getSelectedYear() {
return ( (Integer) yearSpin.getValue()).intValue();
}
private int getSelectedMonth() {
return ( (Integer) monthSpin.getValue()).intValue();
}
private int getSelectedHour() {
return ( (Integer) hourSpin.getValue()).intValue();
}
/* *
* 年月小时的事件处理
* @param e ChangeEvent
*/
public void stateChanged(ChangeEvent e) {
JSpinner source = (JSpinner) e.getSource();
if (source.getName().equals( " Hour " )) {
calendar. set (Calendar.HOUR_OF_DAY, getSelectedHour());
return ;
}
if (source.getName().equals( " Year " )) {
calendar. set (Calendar.YEAR, getSelectedYear());
dayPanel.removeAll();
this .flushWeekAndDayPanal(calendar);
dayPanel.revalidate();
dayPanel.updateUI();
return ;
}
if (source.getName().equals( " Month " )) {
calendar. set (Calendar.MONTH, getSelectedMonth() - 1 );
dayPanel.removeAll();
this .flushWeekAndDayPanal(calendar);
dayPanel.revalidate();
dayPanel.updateUI();
return ;
}
}
/* *
* 日期按钮的鼠标事件处理
* @param e MouseEvent
*/
public void mouseClicked(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 1 ) {
JButton source = (JButton) e.getSource();
String value = source.getText();
int day = Integer.parseInt(value);
calendar. set (Calendar.DAY_OF_MONTH, day);
Date selectDate = this .getSelectDate();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(
pattern);
DateChooser. this .setText(simpleDateFormat.format(selectDate));
int year = calendar. get (Calendar.YEAR);
int month = calendar. get (Calendar.MONTH) + 1 ;
// System.out.println(year + "年" + month + "月" + day + "日");
f.dispose();
}
}
public void mousePressed(MouseEvent e) {
// 空实现接口中的方法,不能删除
}
public void mouseReleased(MouseEvent e) {
// 空实现接口中的方法,不能删除
}
/* *
* 鼠标移动到日历中的事件
* @param e MouseEvent
*/
public void mouseEntered(MouseEvent e) {
JButton jbutton = (JButton) e.getSource();
jbutton.setBackground(moveButtonColor);
}
/* *
* 鼠标移出日历中的事件
* @param e MouseEvent
*/
public void mouseExited(MouseEvent e) {
JButton jbutton = (JButton) e.getSource();
int comm = Integer.parseInt(jbutton.getActionCommand());
int today = getNowCalendar(). get (Calendar.DAY_OF_MONTH);
if (comm == today) {
jbutton.setBackground(todayBtnColor);
}
else {
jbutton.setBackground(palletTableColor);
}
}
}
/* *
* 内部类,改变按钮的边框不可编辑区,使外观更加协调。
*/
class DateChooserButton
extends JButton {
public DateChooserButton(String text) {
super(text);
}
public Insets getInsets() {
return new Insets( 4 , 2 , 0 , 2 );
}
}
}
二、SWT版
原文出处: http://www.blogjava.net/Hexise/archive/2006/12/29/90676.html
目前有几种方式提供SWT的时间控件:
1.eclipse 3.3自带的org.eclipse.swt.widgets.DateTime控件.
eclipse 3.3版本增加了对日期选择控件的支持,下面是官方提供的示例代码:
import org.eclipse.swt. * ;
import org.eclipse.swt.events. * ;
import org.eclipse.swt.layout. * ;
import org.eclipse.swt.widgets. * ;
public class Snippet251 {
public static void main(String[] args) {
Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout( new FillLayout());
Button open = new Button(shell, SWT.PUSH);
open.setText( " Open Dialog " );
open.addSelectionListener( new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
final Shell dialog = new Shell(shell, SWT.DIALOG_TRIM);
dialog.setLayout( new GridLayout( 3 , false ));
final DateTime calendar = new DateTime(dialog, SWT.CALENDAR
| SWT.BORDER);
final DateTime date = new DateTime(dialog, SWT.DATE | SWT.SHORT);
final DateTime time = new DateTime(dialog, SWT.TIME | SWT.SHORT);
new Label(dialog, SWT.NONE);
new Label(dialog, SWT.NONE);
Button ok = new Button(dialog, SWT.PUSH);
ok.setText( " OK " );
ok.setLayoutData( new GridData(SWT.FILL, SWT.CENTER, false ,
false ));
ok.addSelectionListener( new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
System.out
.println( " Calendar date selected (MM/DD/YYYY) = "
+ (calendar.getMonth() + 1 )
+ " / "
+ calendar.getDay()
+ " / "
+ calendar.getYear());
System.out.println( " Date selected (MM/YYYY) = "
+ (date.getMonth() + 1 ) + " / " + date.getYear());
System.out.println( " Time selected (HH:MM) = "
+ time.getHours() + " : " + time.getMinutes());
dialog.close();
}
} );
dialog.setDefaultButton(ok);
dialog.pack();
dialog.open();
}
} );
shell.pack();
shell.open();
while ( ! shell.isDisposed()) {
if ( ! display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
2.第三方提供的免费日期选择控件,例如DatePicker, 它是一个下拉列表框, 提供了日期选择的功能.它在sourceforge上的主页是
http://sourceforge.net/projects/swt-datepicker/
3.也可以自己实现日期选择控件,下面是一个实现的例子:(以下代码做了部分修改)
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class CalendarDialog extends Dialog implements MouseListener ... {
private Display display = null;
private Date nowDate = null; // current date
private String selectedDate = ""; // selected date
private Shell shell = null;
private GridLayout gridLayout = null;
private GridData gridData = null;
private CLabel sunday = null;
private CLabel monday = null;
private CLabel tuesday = null;
private CLabel wednesday = null;
private CLabel thursday = null;
private CLabel friday = null;
private CLabel saturday = null;
private Button yearUp = null;
private Button yearNext = null;
private Button monthUp = null;
private Button monthNext = null;
private CLabel nowLabel = null;
private CLabel nowTimeLabel = null;
private CLabel[] days = new CLabel[42];
private boolean hasChanged = false;
public CalendarDialog(Shell parent, int style) ...{
super(parent, style);
}
public CalendarDialog(Shell parent) ...{
this(parent, 0);
}
private int getLastDayOfMonth(int year, int month) ...{
if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8
|| month == 10 || month == 12) ...{
return 31;
}
if (month == 4 || month == 6 || month == 9 || month == 11) ...{
return 30;
}
if (month == 2) ...{
if (isLeapYear(year)) ...{
return 29;
} else ...{
return 28;
}
}
return 0;
}
public boolean isLeapYear(int year) ...{
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
private void moveTo(int type, int value) ...{
Calendar now = Calendar.getInstance(); // get current Calendar object
now.setTime(nowDate); // set current date
now.add(type, value); // add to spec time.
nowDate = new Date(now.getTimeInMillis()); // result
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM");// format
// date
nowLabel.setText(formatter.format(nowDate)); // set to label
nowTimeLabel.setText(new SimpleDateFormat("HH:mm").format(nowDate));
setDayForDisplay(now);
}
private void setDayForDisplay(Calendar now) ...{
int currentDay = now.get(Calendar.DATE);
now.add(Calendar.DAY_OF_MONTH, -(now.get(Calendar.DATE) - 1)); //
int startIndex = now.get(Calendar.DAY_OF_WEEK) - 1; //
int year = now.get(Calendar.YEAR); //
int month = now.get(Calendar.MONTH) + 1; //
int lastDay = this.getLastDayOfMonth(year, month); //
int endIndex = startIndex + lastDay - 1; //
int startday = 1;
for (int i = 0; i < 42; i++) ...{
Color temp = days[i].getBackground();
if (temp.equals(display.getSystemColor(SWT.COLOR_BLUE))) ...{
days[i].setBackground(display.getSystemColor(SWT.COLOR_WHITE));
}
}
for (int i = 0; i < 42; i++) ...{
if (i >= startIndex && i <= endIndex) ...{
days[i].setText("" + startday);
if (startday == currentDay) ...{
days[i].setBackground(display
.getSystemColor(SWT.COLOR_BLUE)); //
}
startday++;
} else ...{
days[i].setText("");
}
}
}
public void previousYear() ...{
moveTo(Calendar.YEAR, -1);
}
public void nextYear() ...{
moveTo(Calendar.YEAR, 1);
}
public void nextMonth() ...{
moveTo(Calendar.MONTH, 1);
}
public void previousMonth() ...{
moveTo(Calendar.MONTH, -1);
}
public void previousHour()...{
moveTo(Calendar.HOUR, -1);
}
public void nextHour() ...{
moveTo(Calendar.HOUR, 1);
}
public void previousMin()...{
moveTo(Calendar.MINUTE, -1);
}
public void nextMin() ...{
moveTo(Calendar.MINUTE, 1);
}
public void mouseDoubleClick(MouseEvent e) ...{
}
public void mouseDown(MouseEvent e) ...{
CLabel day = (CLabel) e.getSource();
if (!day.getText().equals("")) ...{
if(day.getText().length()==1)...{
this.selectedDate = nowLabel.getText() + "-0" + day.getText() + " " + nowTimeLabel.getText();
}else...{
this.selectedDate = nowLabel.getText() + "-" + day.getText() + " " + nowTimeLabel.getText();
}
this.shell.close();
}
hasChanged = true;
}
public void mouseUp(MouseEvent e) ...{
}
public void open(int x, int y) ...{
Shell parent = getParent();
display = Display.getDefault();
shell = new Shell(parent);
shell.setBounds(x, y, 230, 230);
hasChanged = false;
gridLayout = new GridLayout();
gridLayout.numColumns = 7;
shell.setLayout(gridLayout);
gridData = new GridData(GridData.FILL_HORIZONTAL);
yearUp = new Button(shell, SWT.PUSH | SWT.FLAT);
yearUp.setText("<");
yearUp.setLayoutData(gridData);
yearUp.addSelectionListener(new SelectionAdapter() ...{
public void widgetSelected(SelectionEvent e) ...{
previousYear();
}
});
gridData = new GridData(GridData.FILL_HORIZONTAL);
monthUp = new Button(shell, SWT.PUSH | SWT.FLAT);
monthUp.setText("<<");
monthUp.setLayoutData(gridData);
monthUp.addSelectionListener(new SelectionAdapter() ...{
public void widgetSelected(SelectionEvent e) ...{
previousMonth();
}
});
nowLabel = new CLabel(shell, SWT.CENTER | SWT.SHADOW_OUT);
gridData = new GridData(GridData.FILL_HORIZONTAL);
gridData.horizontalSpan = 3;
nowLabel.setLayoutData(gridData);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM");
nowLabel.setText(formatter.format(new Date()));
gridData = new GridData(GridData.FILL_HORIZONTAL);
monthNext = new Button(shell, SWT.PUSH | SWT.FLAT);
monthNext.setText(">>");
monthNext.setLayoutData(gridData);
monthNext.addSelectionListener(new SelectionAdapter() ...{
public void widgetSelected(SelectionEvent e) ...{
nextMonth();
}
});
gridData = new GridData(GridData.FILL_HORIZONTAL);
yearNext = new Button(shell, SWT.PUSH | SWT.FLAT);
yearNext.setText(">");
yearNext.setLayoutData(gridData);
yearNext.addSelectionListener(new SelectionAdapter() ...{
public void widgetSelected(SelectionEvent e) ...{
nextYear();
}
});
gridData = new GridData(GridData.FILL_HORIZONTAL);
Button hourUp = new Button(shell, SWT.PUSH | SWT.FLAT);
hourUp.setText("<");
hourUp.setLayoutData(gridData);
hourUp.addSelectionListener(new SelectionAdapter() ...{
public void widgetSelected(SelectionEvent e) ...{
previousHour();
}
});
gridData = new GridData(GridData.FILL_HORIZONTAL);
Button minUp = new Button(shell, SWT.PUSH | SWT.FLAT);
minUp.setText("<<");
minUp.setLayoutData(gridData);
minUp.addSelectionListener(new SelectionAdapter() ...{
public void widgetSelected(SelectionEvent e) ...{
previousMin();
}
});
nowTimeLabel = new CLabel(shell, SWT.CENTER | SWT.SHADOW_OUT);
gridData = new GridData(GridData.FILL_HORIZONTAL);
gridData.horizontalSpan = 3;
nowTimeLabel.setLayoutData(gridData);
SimpleDateFormat formatterTime = new SimpleDateFormat("HH:mm");
nowTimeLabel.setText(formatterTime.format(new Date()));
gridData = new GridData(GridData.FILL_HORIZONTAL);
Button minNext = new Button(shell, SWT.PUSH | SWT.FLAT);
minNext.setText(">>");
minNext.setLayoutData(gridData);
minNext.addSelectionListener(new SelectionAdapter() ...{
public void widgetSelected(SelectionEvent e) ...{
nextMin();
}
});
gridData = new GridData(GridData.FILL_HORIZONTAL);
Button hourNext = new Button(shell, SWT.PUSH | SWT.FLAT);
hourNext.setText(">");
hourNext.setLayoutData(gridData);
hourNext.addSelectionListener(new SelectionAdapter() ...{
public void widgetSelected(SelectionEvent e) ...{
nextHour();
}
});
sunday = new CLabel(shell, SWT.CENTER | SWT.SHADOW_OUT);
gridData = new GridData(GridData.FILL_HORIZONTAL
| GridData.FILL_VERTICAL);
gridData.widthHint = 20;
gridData.heightHint = 20;
sunday.setLayoutData(gridData);
sunday.setText("Sun");
monday = new CLabel(shell, SWT.CENTER | SWT.SHADOW_OUT);
gridData = new GridData(GridData.FILL_HORIZONTAL
| GridData.FILL_VERTICAL);
gridData.widthHint = 20;
gridData.heightHint = 20;
monday.setLayoutData(gridData);
monday.setText("Mon");
tuesday = new CLabel(shell, SWT.CENTER | SWT.SHADOW_OUT);
gridData = new GridData(GridData.FILL_HORIZONTAL
| GridData.FILL_VERTICAL);
gridData.widthHint = 20;
gridData.heightHint = 20;
tuesday.setLayoutData(gridData);
tuesday.setText("Tue");
wednesday = new CLabel(shell, SWT.CENTER | SWT.SHADOW_OUT);
gridData = new GridData(GridData.FILL_HORIZONTAL
| GridData.FILL_VERTICAL);
gridData.widthHint = 20;
gridData.heightHint = 20;
wednesday.setLayoutData(gridData);
wednesday.setText("Wed");
thursday = new CLabel(shell, SWT.CENTER | SWT.SHADOW_OUT);
gridData = new GridData(GridData.FILL_HORIZONTAL
| GridData.FILL_VERTICAL);
gridData.widthHint = 20;
gridData.heightHint = 20;
thursday.setLayoutData(gridData);
thursday.setText("Thu");
friday = new CLabel(shell, SWT.CENTER | SWT.SHADOW_OUT);
gridData = new GridData(GridData.FILL_HORIZONTAL
| GridData.FILL_VERTICAL);
gridData.widthHint = 20;
gridData.heightHint = 20;
friday.setLayoutData(gridData);
friday.setText("Fri");
saturday = new CLabel(shell, SWT.CENTER | SWT.SHADOW_OUT);
gridData = new GridData(GridData.FILL_HORIZONTAL
| GridData.FILL_VERTICAL);
gridData.widthHint = 20;
gridData.heightHint = 20;
saturday.setLayoutData(gridData);
saturday.setText("Sat");
for (int i = 0; i < 42; i++) ...{
days[i] = new CLabel(shell, SWT.FLAT | SWT.CENTER);
gridData = new GridData(GridData.FILL_HORIZONTAL
| GridData.FILL_VERTICAL);
days[i].setLayoutData(gridData);
days[i].setBackground(display.getSystemColor(SWT.COLOR_WHITE));
days[i].addMouseListener(this);
}
Calendar now = Calendar.getInstance(); //
nowDate = new Date(now.getTimeInMillis());
setDayForDisplay(now);
shell.open();
Display display = parent.getDisplay();
while (!shell.isDisposed()) ...{
if (!display.readAndDispatch()) ...{
display.sleep();
}
}
}
public boolean isChanged() ...{
return hasChanged;
}
public String getDateText() ...{
return selectedDate.toString();
}
}
三、为java万年历加上农历
原文出处: http://www.blogjava.net/soddabao/archive/2007/01/04/91729.html
前几天在blog中,对网友的java
万年历作 修改,看到有的网友说能不能加上农历,后来在网上看到有人写过几个阳历转阴历的算法,我比较了一个发现,这个算法还算不错,只要有的计算机编程基础的人看 明白应该是没有问题的,其实这个就和我们以前在c中,判断一天是周几的算法差不多,都是和某一个特定的时间作比较,算出差多少天,再根据月大月小瑞月这些 规则,算出是农历的那年那月那日.
package clock;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class Lunar {
private int year;
private int month;
private int day;
private boolean leap;
final static String chineseNumber[] = {"一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"};
static SimpleDateFormat chineseDateFormat = new SimpleDateFormat("yyyy年MM月dd日");
final static long[] lunarInfo = new long[]
{0x04bd8, 0x04ae0, 0x0a570, 0x054d5, 0x0d260, 0x0d950, 0x16554, 0x056a0, 0x09ad0, 0x055d2,
0x04ae0, 0x0a5b6, 0x0a4d0, 0x0d250, 0x1d255, 0x0b540, 0x0d6a0, 0x0ada2, 0x095b0, 0x14977,
0x04970, 0x0a4b0, 0x0b4b5, 0x06a50, 0x06d40, 0x1ab54, 0x02b60, 0x09570, 0x052f2, 0x04970,
0x06566, 0x0d4a0, 0x0ea50, 0x06e95, 0x05ad0, 0x02b60, 0x186e3, 0x092e0, 0x1c8d7, 0x0c950,
0x0d4a0, 0x1d8a6, 0x0b550, 0x056a0, 0x1a5b4, 0x025d0, 0x092d0, 0x0d2b2, 0x0a950, 0x0b557,
0x06ca0, 0x0b550, 0x15355, 0x04da0, 0x0a5d0, 0x14573, 0x052d0, 0x0a9a8, 0x0e950, 0x06aa0,
0x0aea6, 0x0ab50, 0x04b60, 0x0aae4, 0x0a570, 0x05260, 0x0f263, 0x0d950, 0x05b57, 0x056a0,
0x096d0, 0x04dd5, 0x04ad0, 0x0a4d0, 0x0d4d4, 0x0d250, 0x0d558, 0x0b540, 0x0b5a0, 0x195a6,
0x095b0, 0x049b0, 0x0a974, 0x0a4b0, 0x0b27a, 0x06a50, 0x06d40, 0x0af46, 0x0ab60, 0x09570,
0x04af5, 0x04970, 0x064b0, 0x074a3, 0x0ea50, 0x06b58, 0x055c0, 0x0ab60, 0x096d5, 0x092e0,
0x0c960, 0x0d954, 0x0d4a0, 0x0da50, 0x07552, 0x056a0, 0x0abb7, 0x025d0, 0x092d0, 0x0cab5,
0x0a950, 0x0b4a0, 0x0baa4, 0x0ad50, 0x055d9, 0x04ba0, 0x0a5b0, 0x15176, 0x052b0, 0x0a930,
0x07954, 0x06aa0, 0x0ad50, 0x05b52, 0x04b60, 0x0a6e6, 0x0a4e0, 0x0d260, 0x0ea65, 0x0d530,
0x05aa0, 0x076a3, 0x096d0, 0x04bd7, 0x04ad0, 0x0a4d0, 0x1d0b6, 0x0d250, 0x0d520, 0x0dd45,
0x0b5a0, 0x056d0, 0x055b2, 0x049b0, 0x0a577, 0x0a4b0, 0x0aa50, 0x1b255, 0x06d20, 0x0ada0};
//====== 传回农历 y年的总天数
final private static int yearDays(int y) {
int i, sum = 348;
for (i = 0x8000; i > 0x8; i >>= 1) {
if ((lunarInfo[y - 1900] & i) != 0) sum += 1;
}
return (sum + leapDays(y));
}
//====== 传回农历 y年闰月的天数
final private static int leapDays(int y) {
if (leapMonth(y) != 0) {
if ((lunarInfo[y - 1900] & 0x10000) != 0)
return 30;
else
return 29;
} else
return 0;
}
//====== 传回农历 y年闰哪个月 1-12 , 没闰传回 0
final private static int leapMonth(int y) {
return (int) (lunarInfo[y - 1900] & 0xf);
}
//====== 传回农历 y年m月的总天数
final private static int monthDays(int y, int m) {
if ((lunarInfo[y - 1900] & (0x10000 >> m)) == 0)
return 29;
else
return 30;
}
//====== 传回农历 y年的生肖
final public String animalsYear() {
final String[] Animals = new String[]{"鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪"};
return Animals[(year - 4) % 12];
}
//====== 传入 月日的offset 传回干支, 0=甲子
final private static String cyclicalm(int num) {
final String[] Gan = new String[]{"甲", "乙", "丙", "丁", "戊", "己", "庚", "辛", "壬", "癸"};
final String[] Zhi = new String[]{"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"};
return (Gan[num % 10] + Zhi[num % 12]);
}
//====== 传入 offset 传回干支, 0=甲子
final public String cyclical() {
int num = year - 1900 + 36;
return (cyclicalm(num));
}
/** *//**
* 传出y年m月d日对应的农历.
* yearCyl3:农历年与1864的相差数 ?
* monCyl4:从1900年1月31日以来,闰月数
* dayCyl5:与1900年1月31日相差的天数,再加40 ?
* @param cal
* @return
*/
public Lunar(Calendar cal) {
@SuppressWarnings("unused") int yearCyl, monCyl, dayCyl;
int leapMonth = 0;
Date baseDate = null;
try {
baseDate = chineseDateFormat.parse("1900年1月31日");
} catch (ParseException e) {
e.printStackTrace(); //To change body of catch statement use Options | File Templates.
}
//求出和1900年1月31日相差的天数
int offset = (int) ((cal.getTime().getTime() - baseDate.getTime()) / 86400000L);
dayCyl = offset + 40;
monCyl = 14;
//用offset减去每农历年的天数
// 计算当天是农历第几天
//i最终结果是农历的年份
//offset是当年的第几天
int iYear, daysOfYear = 0;
for (iYear = 1900; iYear < 2050 && offset > 0; iYear++) {
daysOfYear = yearDays(iYear);
offset -= daysOfYear;
monCyl += 12;
}
if (offset < 0) {
offset += daysOfYear;
iYear--;
monCyl -= 12;
}
//农历年份
year = iYear;
yearCyl = iYear - 1864;
leapMonth = leapMonth(iYear); //闰哪个月,1-12
leap = false;
//用当年的天数offset,逐个减去每月(农历)的天数,求出当天是本月的第几天
int iMonth, daysOfMonth = 0;
for (iMonth = 1; iMonth < 13 && offset > 0; iMonth++) {
//闰月
if (leapMonth > 0 && iMonth == (leapMonth + 1) && !leap) {
--iMonth;
leap = true;
daysOfMonth = leapDays(year);
} else
daysOfMonth = monthDays(year, iMonth);
offset -= daysOfMonth;
//解除闰月
if (leap && iMonth == (leapMonth + 1)) leap = false;
if (!leap) monCyl++;
}
//offset为0时,并且刚才计算的月份是闰月,要校正
if (offset == 0 && leapMonth > 0 && iMonth == leapMonth + 1) {
if (leap) {
leap = false;
} else {
leap = true;
--iMonth;
--monCyl;
}
}
//offset小于0时,也要校正
if (offset < 0) {
offset += daysOfMonth;
--iMonth;
--monCyl;
}
month = iMonth;
day = offset + 1;
}
public static String getChinaDayString(int day) {
String chineseTen[] = {"初", "十", "廿", "卅"};
int n = day % 10 == 0 ? 9 : day % 10 - 1;
if (day > 30)
return "";
if (day == 10)
return "初十";
else
return chineseTen[day / 10] + chineseNumber[n];
}
public String toString() {
return year + "年" + (leap ? "闰" : "") + chineseNumber[month - 1] + "月" + getChinaDayString(day);
}
public static void main(String[] args) throws ParseException {
Calendar today = Calendar.getInstance();
today.setTime(chineseDateFormat.parse("2003年1月1日"));
Lunar lunar = new Lunar(today);
System.out.println("北京时间:" + chineseDateFormat.format(today.getTime()) + " 农历" + lunar);
}
}
在以前程序的label[i].setText(count +"");下设置label的浮动提示
try {
now.setTime(chineseDateFormat.parse(year_log+"年"+(month_log+1)+"月"+count+"日"));
} catch (ParseException e) {
e.printStackTrace();
}
label[i].setToolTipText( " 农历 " + new Lunar(now));
就能出现这种效果: