java swing 日期時間控件


package yz;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class DateChooserJButton extends JButton {

private DateChooser dateChooser = null;
private String preLabel = "";
private String originalText = null;
private SimpleDateFormat sdf = null;

public DateChooserJButton() {
this(getNowDate());
}

public DateChooserJButton(String dateString) {
this();
setText(getDefaultDateFormat(), dateString);
//保存原始是日期時間
initOriginalText(dateString);
}

public DateChooserJButton(SimpleDateFormat df, String dateString) {
this();
setText(df, dateString);

//記憶當前的日期格式化器
this.sdf = df;

//記憶原始日期時間
Date originalDate = null;
try {
originalDate = df.parse(dateString);
} catch (ParseException ex) {
originalDate = getNowDate();
}
initOriginalText(originalDate);
}

public DateChooserJButton(Date date) {
this("", date);
//記憶原始日期時間
initOriginalText(date);
}

public DateChooserJButton(String preLabel, Date date) {
if (preLabel != null) {
this.preLabel = preLabel;
}
setDate(date);
//記憶原始是日期時間
initOriginalText(date);

setBorder(null);
setCursor(new Cursor(Cursor.HAND_CURSOR));
super.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
if (dateChooser == null) {
dateChooser = new DateChooser(sdf);
}
Point p = getLocationOnScreen();
p.y = p.y + 30;
dateChooser.showDateChooser(p);
}
});
}

private static Date getNowDate() {
return Calendar.getInstance().getTime();
}

private static SimpleDateFormat getDefaultDateFormat() {
return new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
}

/**
* 得到當前使用的日期格式化器
* @return 日期格式化器
*/
public SimpleDateFormat getCurrentSimpleDateFormat(){
if(this.sdf != null){
return sdf;
}else{
return getDefaultDateFormat();
}
}


//保存原始是日期時間
private void initOriginalText(String dateString) {
this.originalText = dateString;
}

//保存原始是日期時間
private void initOriginalText(Date date) {
this.originalText = preLabel + getDefaultDateFormat().format(date);
}

/**
* 得到當前記憶的原始日期時間
* @return 當前記憶的原始日期時間(未修改前的日期時間)
*/
public String getOriginalText() {
return originalText;
}

// 覆蓋父類的方法
@Override
public void setText(String s) {
Date date;
try {
date = getDefaultDateFormat().parse(s);
} catch (ParseException e) {
date = getNowDate();
}
setDate(date);
}

public void setText(SimpleDateFormat df, String s) {
Date date;
try {
date = df.parse(s);
} catch (ParseException e) {
date = getNowDate();
}
setDate(date);
}

public void setDate(Date date) {
super.setText(preLabel + getDefaultDateFormat().format(date));
}

public Date getDate() {
String dateString = getText().substring(preLabel.length());
try {
SimpleDateFormat currentSdf = getCurrentSimpleDateFormat();
return currentSdf.parse(dateString);
} catch (ParseException e) {
return getNowDate();
}
}

/**
* 覆蓋父類的方法使之無效
* @param listener 響應監聽器
*/
@Override
public void addActionListener(ActionListener listener) {
}

/**
* 內部類,主要是定義一個JPanel,然后把日歷相關的所有內容填入本JPanel,
* 然后再創建一個JDialog,把本內部類定義的JPanel放入JDialog的內容區
*/
private class DateChooser extends JPanel implements ActionListener, ChangeListener {

int startYear = 1980; // 默認【最小】顯示年份
int lastYear = 2050; // 默認【最大】顯示年份
int width = 390; // 界面寬度
int height = 210; // 界面高度
Color backGroundColor = Color.gray; // 底色
// 月歷表格配色----------------//
Color palletTableColor = Color.white; // 日歷表底色
Color todayBackColor = Color.orange; // 今天背景色
Color weekFontColor = Color.blue; // 星期文字色
Color dateFontColor = Color.black; // 日期文字色
Color weekendFontColor = Color.red; // 周末文字色
// 控制條配色------------------//
Color controlLineColor = Color.pink; // 控制條底色
Color controlTextColor = Color.white; // 控制條標簽文字色
Color rbFontColor = Color.white; // RoundBox文字色
Color rbBorderColor = Color.red; // RoundBox邊框色
Color rbButtonColor = Color.pink; // RoundBox按鈕色
Color rbBtFontColor = Color.red; // RoundBox按鈕文字色
/** 點擊DateChooserButton時彈出的對話框,日歷內容在這個對話框內 */
JDialog dialog;
JSpinner yearSpin;
JSpinner monthSpin;
JSpinner daySpin;
JSpinner hourSpin;
JSpinner minuteSpin;
JSpinner secondSpin;
SimpleDateFormat df;
JButton[][] daysButton = new JButton[6][7];

DateChooser(SimpleDateFormat df) {
this.df=df;
setLayout(new BorderLayout());
setBorder(new LineBorder(backGroundColor, 2));
setBackground(backGroundColor);

JPanel topYearAndMonth = createYearAndMonthPanal(df);
add(topYearAndMonth, BorderLayout.NORTH);
JPanel centerWeekAndDay = createWeekAndDayPanal();
add(centerWeekAndDay, BorderLayout.CENTER);
JPanel buttonBarPanel = createButtonBarPanel();
this.add(buttonBarPanel, java.awt.BorderLayout.SOUTH);
}

private JPanel createYearAndMonthPanal(SimpleDateFormat df) {
Calendar c = getCalendar();
int currentYear = c.get(Calendar.YEAR);
int currentMonth = c.get(Calendar.MONTH) + 1;
int currentHour = c.get(Calendar.HOUR_OF_DAY);
int currentMinute = c.get(Calendar.MINUTE);
int currentSecond = c.get(Calendar.SECOND);

JPanel result = new JPanel();
result.setLayout(new FlowLayout());
result.setBackground(controlLineColor);

yearSpin = new JSpinner(new SpinnerNumberModel(currentYear, startYear, lastYear, 1));
yearSpin.setPreferredSize(new Dimension(48, 20));
yearSpin.setName("Year");
yearSpin.setEditor(new JSpinner.NumberEditor(yearSpin, "####"));
yearSpin.addChangeListener(this);
result.add(yearSpin);

JLabel yearLabel = new JLabel("年");
yearLabel.setForeground(controlTextColor);
result.add(yearLabel);

monthSpin = new JSpinner(new SpinnerNumberModel(currentMonth, 1, 12, 1));
monthSpin.setPreferredSize(new Dimension(35, 20));
monthSpin.setName("Month");
monthSpin.addChangeListener(this);
result.add(monthSpin);

JLabel monthLabel = new JLabel("月");
monthLabel.setForeground(controlTextColor);
result.add(monthLabel);

//如果這里要能夠選擇,會要判斷很多東西,比如每個月分別由多少日,以及閏年問題.所以,就干脆把Enable設為false
daySpin = new JSpinner(new SpinnerNumberModel(currentMonth, 1, 31, 1));
daySpin.setPreferredSize(new Dimension(35, 20));
daySpin.setName("Day");
daySpin.addChangeListener(this);
daySpin.setEnabled(false);
daySpin.setToolTipText("請下下面的日歷面板中進行選擇哪一天!");
result.add(daySpin);

JLabel dayLabel = new JLabel("日");
dayLabel.setForeground(controlTextColor);
result.add(dayLabel);

hourSpin = new JSpinner(new SpinnerNumberModel(currentHour, 0, 23, 1));
hourSpin.setPreferredSize(new Dimension(35, 20));
hourSpin.setName("Hour");
hourSpin.addChangeListener(this);
result.add(hourSpin);

JLabel hourLabel = new JLabel("時");
hourLabel.setForeground(controlTextColor);
result.add(hourLabel);

minuteSpin = new JSpinner(new SpinnerNumberModel(currentMinute, 0, 59, 1));
minuteSpin.setPreferredSize(new Dimension(35, 20));
minuteSpin.setName("Minute");
minuteSpin.addChangeListener(this);
result.add(minuteSpin);

JLabel minuteLabel = new JLabel("分");
hourLabel.setForeground(controlTextColor);
if(!df.toPattern().contains("mm"))
{
minuteSpin.setVisible(false);
minuteLabel.setVisible(false);
}
result.add(minuteLabel);

secondSpin = new JSpinner(new SpinnerNumberModel(currentSecond, 0, 59, 1));
secondSpin.setPreferredSize(new Dimension(35, 20));
secondSpin.setName("Second");
secondSpin.addChangeListener(this);
result.add(secondSpin);

JLabel secondLabel = new JLabel("秒");
hourLabel.setForeground(controlTextColor);
if(!df.toPattern().contains("ss"))
{
secondSpin.setVisible(false);
secondLabel.setVisible(false);
}
result.add(secondLabel);

return result;
}

private JPanel createWeekAndDayPanal() {
String colname[] = {"日", "一", "二", "三", "四", "五", "六"};
JPanel result = new JPanel();
// 設置固定字體,以免調用環境改變影響界面美觀
result.setFont(new Font("宋體", Font.PLAIN, 12));
result.setLayout(new GridLayout(7, 7));
result.setBackground(Color.white);
JLabel cell;

for (int i = 0; i < 7; i++) {
cell = new JLabel(colname[i]);
cell.setHorizontalAlignment(JLabel.RIGHT);
if (i == 0 || i == 6) {
cell.setForeground(weekendFontColor);
} else {
cell.setForeground(weekFontColor);
}
result.add(cell);
}

int actionCommandId = 0;
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
JButton numberButton = new JButton();
numberButton.setBorder(null);
numberButton.setHorizontalAlignment(SwingConstants.RIGHT);
numberButton.setActionCommand(String.valueOf(actionCommandId));
numberButton.addActionListener(this);
numberButton.setBackground(palletTableColor);
numberButton.setForeground(dateFontColor);
if (j == 0 || j == 6) {
numberButton.setForeground(weekendFontColor);
} else {
numberButton.setForeground(dateFontColor);
}
daysButton[i][j] = numberButton;
result.add(numberButton);
actionCommandId++;
}
}

return result;
}

/** 得到DateChooserButton的當前text,本方法是為按鈕事件匿名類准備的。 */
public String getTextOfDateChooserButton() {
return getText();
}

/** 恢復DateChooserButton的原始日期時間text,本方法是為按鈕事件匿名類准備的。 */
public void restoreTheOriginalDate() {
String originalText = getOriginalText();
setText(originalText);
}

private JPanel createButtonBarPanel() {
JPanel panel = new JPanel();
panel.setLayout(new java.awt.GridLayout(1, 2));

JButton ok = new JButton("確定");
ok.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
//記憶原始日期時間
initOriginalText(getTextOfDateChooserButton());
//隱藏日歷對話框
dialog.setVisible(false);
}
});
panel.add(ok);

JButton cancel = new JButton("取消");
cancel.addActionListener(new ActionListener() {

@Override
public void actionPerformed(ActionEvent e) {
//恢復原始的日期時間
restoreTheOriginalDate();
//隱藏日歷對話框
dialog.setVisible(false);
}
});

panel.add(cancel);
return panel;
}

private JDialog createDialog(Frame owner) {
JDialog result = new JDialog(owner, "日期時間選擇", true);
result.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
result.getContentPane().add(this, BorderLayout.CENTER);
result.pack();
result.setSize(width, height);
return result;
}

void showDateChooser(Point position) {
Frame owner = (Frame) SwingUtilities.getWindowAncestor(DateChooserJButton.this);
if (dialog == null || dialog.getOwner() != owner) {
dialog = createDialog(owner);
}
dialog.setLocation(getAppropriateLocation(owner, position));
flushWeekAndDay();
dialog.setVisible(true);
}

Point getAppropriateLocation(Frame owner, Point position) {
Point result = new Point(position);
Point p = owner.getLocation();
int offsetX = (position.x + width) - (p.x + owner.getWidth());
int offsetY = (position.y + height) - (p.y + owner.getHeight());

if (offsetX > 0) {
result.x -= offsetX;
}

if (offsetY > 0) {
result.y -= offsetY;
}

return result;
}

private Calendar getCalendar() {
Calendar result = Calendar.getInstance();
result.setTime(getDate());
return result;
}

private int getSelectedYear() {
return ((Integer) yearSpin.getValue()).intValue();
}

private int getSelectedMonth() {
return ((Integer) monthSpin.getValue()).intValue();
}

private int getSelectedHour() {
return ((Integer) hourSpin.getValue()).intValue();
}

private int getSelectedMinite() {
return ((Integer) minuteSpin.getValue()).intValue();
}

private int getSelectedSecond() {
return ((Integer) secondSpin.getValue()).intValue();
}

private void dayColorUpdate(boolean isOldDay) {
Calendar c = getCalendar();
int day = c.get(Calendar.DAY_OF_MONTH);
c.set(Calendar.DAY_OF_MONTH, 1);
int actionCommandId = day - 2 + c.get(Calendar.DAY_OF_WEEK);
int i = actionCommandId / 7;
int j = actionCommandId % 7;
if (isOldDay) {
daysButton[i][j].setForeground(dateFontColor);
} else {
daysButton[i][j].setForeground(todayBackColor);
}
}

private void flushWeekAndDay() {
Calendar c = getCalendar();
c.set(Calendar.DAY_OF_MONTH, 1);
int maxDayNo = c.getActualMaximum(Calendar.DAY_OF_MONTH);
int dayNo = 2 - c.get(Calendar.DAY_OF_WEEK);
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
String s = "";
if (dayNo >= 1 && dayNo <= maxDayNo) {
s = String.valueOf(dayNo);
}
daysButton[i][j].setText(s);
dayNo++;
}
}
dayColorUpdate(false);
}

/**
* 選擇日期時的響應事件
*/
@Override
public void stateChanged(ChangeEvent e) {
JSpinner source = (JSpinner) e.getSource();
Calendar c = getCalendar();
if (source.getName().equals("Hour")) {
c.set(Calendar.HOUR_OF_DAY, getSelectedHour());
setDate(c.getTime());
return;
}
if (source.getName().equals("Minute")) {
c.set(Calendar.MINUTE, getSelectedMinite());
setDate(c.getTime());
return;
}
if (source.getName().equals("Second")) {
c.set(Calendar.SECOND, getSelectedSecond());
setDate(c.getTime());
return;
}

dayColorUpdate(true);

if (source.getName().equals("Year")) {
c.set(Calendar.YEAR, getSelectedYear());
} else if (source.getName().equals("Month")) {
c.set(Calendar.MONTH, getSelectedMonth() - 1);
}
setDate(c.getTime());
flushWeekAndDay();
}

/**
* 選擇日期時的響應事件
*/
@Override
public void actionPerformed(ActionEvent e) {
JButton source = (JButton) e.getSource();
if (source.getText().length() == 0) {
return;
}
dayColorUpdate(true);
source.setForeground(todayBackColor);
int newDay = Integer.parseInt(source.getText());
Calendar c = getCalendar();
c.set(Calendar.DAY_OF_MONTH, newDay);
setDate(c.getTime());
//把daySpin中的值也變了
daySpin.setValue(Integer.valueOf(newDay));
}
}

/**
* 測試方法
*/
public static void main(String[] args) {
JFrame mainFrame = new JFrame("測試");
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setSize(300, 300);
mainFrame.setLayout(new java.awt.BorderLayout());
//根據格式設置內容yyyy/MM/dd HH
mainFrame.add(new DateChooserJButton(new SimpleDateFormat("yyyy/MM/dd HH"),"2012/12/12 22"), java.awt.BorderLayout.CENTER);

Toolkit kit = Toolkit.getDefaultToolkit();
Dimension screenSize = kit.getScreenSize();
int width = (int) screenSize.getWidth();
int height = (int) screenSize.getHeight();
int w = mainFrame.getWidth();
int h = mainFrame.getHeight();
mainFrame.setLocation((width - w) / 2, (height - h) / 2);

mainFrame.setVisible(true);
}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM