Swing實(shí)現(xiàn)日期選擇器DatePicker(帶時(shí)分秒選擇功能)

DateSelector.java


package Test;

import java.util.Date;

import java.util.Calendar;

import java.text.DateFormat;

import java.text.SimpleDateFormat;

import java.text.ParseException;

import java.awt.Color;

import java.awt.Font;

import java.awt.Point;

import java.awt.Dimension;

import java.awt.BorderLayout;

import java.awt.FlowLayout;

import java.awt.GridLayout;

import java.awt.Component;

import java.awt.Cursor;

import java.awt.Frame;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.MouseListener;

import java.awt.event.MouseAdapter;

import java.awt.event.MouseEvent; //import javax.swing.JFrame;

import javax.swing.JButton;

import javax.swing.JDialog;

import javax.swing.JPanel;

import javax.swing.JLabel;

import javax.swing.JSpinner;

import javax.swing.JSpinner.NumberEditor;

import javax.swing.SpinnerNumberModel;

import javax.swing.SwingUtilities;

import javax.swing.SwingConstants;

import javax.swing.event.ChangeListener;

import javax.swing.event.ChangeEvent;

import javax.swing.border.LineBorder;

public class DateSelector extends JButton {

private DateChooser dateChooser = null;

private String preLabel = "";

public DateSelector() {

this(getNowDate());

}

public DateSelector(SimpleDateFormat df, String dateString) {

this();

setText(df, dateString);

}

public DateSelector(Date date) {

this("", date);

}

public DateSelector(String preLabel, Date date) {

if (preLabel != null)

this.preLabel = preLabel;

setDate(date);

setBorder(null);

setCursor(new Cursor(Cursor.HAND_CURSOR));

super.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent e) {

if (dateChooser == null)

dateChooser = new DateChooser();

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時(shí)mm分ss秒");

}

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 {

return getDefaultDateFormat().parse(dateString);

} catch (ParseException e) {

return getNowDate();

}

}

// 覆蓋父類的方法使之無效

public void addActionListener(ActionListener listener) {

}

private class DateChooser extends JPanel implements ActionListener,

ChangeListener {

int startYear = 1980; // 默認(rèn)【最小】顯示年份

int lastYear = 2050; // 默認(rèn)【最大】顯示年份

int width = 200; // 界面寬度

int height = 200; // 界面高度

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.blue; // 控制條底色

Color controlTextColor = Color.white; // 控制條標(biāo)簽文字色

Color rbFontColor = Color.white; // RoundBox文字色

Color rbBorderColor = Color.red; // RoundBox邊框色

Color rbButtonColor = Color.pink; // RoundBox按鈕色

Color rbBtFontColor = Color.red; // RoundBox按鈕文字色

JDialog dialog;

JSpinner yearSpin;

JSpinner monthSpin;

JSpinner hourSpin;

JSpinner minuteSpin;

JSpinner secondSpin;

JButton[][] daysButton = new JButton[6][7];

DateChooser() {

setLayout(new BorderLayout());

setBorder(new LineBorder(backGroundColor, 2));

setBackground(backGroundColor);

/*上中下布局*/

JPanel topYearAndMonth = createYearAndMonthPanal();

add(topYearAndMonth, BorderLayout.NORTH);

JPanel centerWeekAndDay = createWeekAndDayPanal();

add(centerWeekAndDay, BorderLayout.CENTER);

JPanel southMinAndSec = createMinuteAndsecondPanal();

add(southMinAndSec, BorderLayout.SOUTH);

}

private JPanel createYearAndMonthPanal() {

Calendar c = getCalendar();

int currentYear = c.get(Calendar.YEAR);//年

int currentMonth = c.get(Calendar.MONTH) + 1;//月

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);

return result;

}

private JPanel createWeekAndDayPanal() {

String colname[] = { "日", "一", "二", "三", "四", "五", "六" };

JPanel result = new JPanel();

// 設(shè)置固定字體著拭,以免調(diào)用環(huán)境改變影響界面美觀

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;

}

private JPanel createMinuteAndsecondPanal() {

Calendar c = getCalendar();

int currentHour = c.get(Calendar.HOUR_OF_DAY);//時(shí)

int currentMin = c.get(Calendar.MINUTE);//分

int currentSec = c.get(Calendar.SECOND);//秒

JPanel result = new JPanel();

result.setLayout(new FlowLayout());

result.setBackground(controlLineColor);

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("時(shí)");

hourLabel.setForeground(controlTextColor);

result.add(hourLabel);

minuteSpin = new JSpinner(new SpinnerNumberModel(currentMin, 0, 59, 1));

minuteSpin.setPreferredSize(new Dimension(35, 20));

minuteSpin.setName("Minute");

minuteSpin.addChangeListener(this);

result.add(minuteSpin);

JLabel minuteLabel = new JLabel("分");

minuteLabel.setForeground(controlTextColor);

result.add(minuteLabel);

secondSpin = new JSpinner(new SpinnerNumberModel(currentSec, 0, 59,1));

secondSpin.setPreferredSize(new Dimension(35, 20));

secondSpin.setName("Second");

secondSpin.addChangeListener(this);

result.add(secondSpin);

JLabel secondLabel = new JLabel("秒");

secondLabel.setForeground(controlTextColor);

result.add(secondLabel);

return result;

}

private JDialog createDialog(Frame owner) {

JDialog result = new JDialog(owner, "日期時(shí)間選擇", 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(DateSelector.this);

if (dialog == null || dialog.getOwner() != owner)

dialog = createDialog(owner);

dialog.setLocation(getAppropriateLocation(owner, position));

flushWeekAndDay();

dialog.show();

}

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 getSelectedMinute() {

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);

}

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;

}

else if(source.getName().equals("Minute")){

c.set(Calendar.MINUTE, getSelectedMinute());

setDate(c.getTime());

return;

}

else 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

// (source.getName().equals("Month"))

c.set(Calendar.MONTH, getSelectedMonth() - 1);

setDate(c.getTime());

flushWeekAndDay();

}

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());

}

}

}


==========================================================================


Test.java

package Test;

import java.awt.BorderLayout;

import java.awt.EventQueue;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.border.EmptyBorder;

import javax.swing.JButton;

public class Test extends JFrame {

private JPanel contentPane;

public static void main(String[] args) {

Test frame = new Test();

frame.setVisible(true);

}

public Test() {

setBounds(100, 100, 350, 200);

contentPane = new JPanel();

contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));

contentPane.setLayout(new BorderLayout(0, 0));

setContentPane(contentPane);

JButton button = new DateSelector();

contentPane.add(button, BorderLayout.CENTER);

}

}


============================? ? ? ? ?我是分割線? ?==============================


點(diǎn)擊Test.java類誉碴,點(diǎn)擊Run as 運(yùn)行程序后,效果如下圖所示:


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子炎辨,更是在濱河造成了極大的恐慌,老刑警劉巖娩井,帶你破解...
    沈念sama閱讀 206,602評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呜投,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡炫隶,警方通過查閱死者的電腦和手機(jī)淋叶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來伪阶,“玉大人煞檩,你說我怎么就攤上這事≌ぬ” “怎么了斟湃?”我有些...
    開封第一講書人閱讀 152,878評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)檐薯。 經(jīng)常有香客問我凝赛,道長(zhǎng),這世上最難降的妖魔是什么坛缕? 我笑而不...
    開封第一講書人閱讀 55,306評(píng)論 1 279
  • 正文 為了忘掉前任墓猎,我火速辦了婚禮,結(jié)果婚禮上赚楚,老公的妹妹穿的比我還像新娘毙沾。我一直安慰自己,他們只是感情好宠页,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評(píng)論 5 373
  • 文/花漫 我一把揭開白布搀军。 她就那樣靜靜地躺著膨俐,像睡著了一般。 火紅的嫁衣襯著肌膚如雪罩句。 梳的紋絲不亂的頭發(fā)上焚刺,一...
    開封第一講書人閱讀 49,071評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音门烂,去河邊找鬼乳愉。 笑死,一個(gè)胖子當(dāng)著我的面吹牛屯远,可吹牛的內(nèi)容都是我干的蔓姚。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼慨丐,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼坡脐!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起房揭,我...
    開封第一講書人閱讀 37,006評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤备闲,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后捅暴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恬砂,經(jīng)...
    沈念sama閱讀 43,512評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評(píng)論 2 325
  • 正文 我和宋清朗相戀三年蓬痒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了泻骤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,094評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡梧奢,死狀恐怖狱掂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情亲轨,我是刑警寧澤趋惨,帶...
    沈念sama閱讀 33,732評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站瓶埋,受9級(jí)特大地震影響希柿,放射性物質(zhì)發(fā)生泄漏诊沪。R本人自食惡果不足惜养筒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望端姚。 院中可真熱鬧晕粪,春花似錦、人聲如沸渐裸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至尚氛,卻和暖如春诀诊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背阅嘶。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評(píng)論 1 262
  • 我被黑心中介騙來泰國打工属瓣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人讯柔。 一個(gè)月前我還...
    沈念sama閱讀 45,536評(píng)論 2 354
  • 正文 我出身青樓抡蛙,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親魂迄。 傳聞我的和親對(duì)象是個(gè)殘疾皇子粗截,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容