dongyukun
2024-11-05 e8ad669f7c97d45cd23630dc101180a130d6c17e
提交 | 用户 | 时间
ce910c 1 package com.netsdk.common;
H 2
3 import java.awt.BorderLayout;
4 import java.awt.Color;
5 import java.awt.Cursor;
6 import java.awt.Dimension;
7 import java.awt.FlowLayout;
8 import java.awt.Font;
9 import java.awt.GridLayout;
10 import java.awt.event.ActionEvent;
11 import java.awt.event.ActionListener;
12 import java.awt.event.MouseEvent;
13 import java.awt.event.MouseListener;
14 import java.awt.event.WindowAdapter;
15 import java.awt.event.WindowEvent;
16 import java.text.ParseException;
17 import java.text.SimpleDateFormat;
18 import java.util.Calendar;
19 import java.util.Date;
20
21 import javax.swing.JButton;
22 import javax.swing.JDialog;
23 import javax.swing.JLabel;
24 import javax.swing.JPanel;
25 import javax.swing.JSpinner;
26 import javax.swing.SpinnerNumberModel;
27 import javax.swing.SwingConstants;
28 import javax.swing.UIManager;
29 import javax.swing.border.LineBorder;
30 import javax.swing.event.ChangeEvent;
31 import javax.swing.event.ChangeListener;
32
33 /**
34  * 时间选择器, 年月日-时分秒
35  */
36 public class DateChooserJButton extends JButton {
37     private static final long serialVersionUID = 1L;
38     
39     int startYear = 1980; // 默认【最小】显示年份
40     int lastYear = 2050; // 默认【最大】显示年份
41     
42     private DateChooser dateChooser = null;
43     private String preLabel = "";
44     private String originalText = null;
45     private SimpleDateFormat sdf = null;
46     
47     private JSpinner yearSpin;
48     private JSpinner monthSpin;
49     private JSpinner daySpin;
50     private JSpinner hourSpin;
51     private JSpinner minuteSpin;
52     private JSpinner secondSpin;
53     
54     public DateChooserJButton() {
55         this(getNowDate());   
56         
57         try {
58             UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
59         } catch (Exception e) {
60             e.printStackTrace();
61         } 
62     }
63
64     public DateChooserJButton(String dateString) {
65         this();     
66         
67         setText(getDefaultDateFormat(), dateString);
68         //保存原始是日期时间
69         initOriginalText(dateString);
70     }
71
72     public DateChooserJButton(SimpleDateFormat df, String dateString) {
73         this();
74         setText(df, dateString);
75
76         //记忆当前的日期格式化器
77         this.sdf = df;
78
79         //记忆原始日期时间
80         Date originalDate = null;
81         try {
82             originalDate = df.parse(dateString);
83         } catch (ParseException ex) {
84             originalDate = getNowDate();
85         }
86         initOriginalText(originalDate);
87     }
88
89     public DateChooserJButton(Date date) {
90         this("", date);
91         //记忆原始日期时间
92         initOriginalText(date);
93     }
94
95     public DateChooserJButton(String preLabel, Date date) {
96         if (preLabel != null) {
97             this.preLabel = preLabel;
98         }
99         setDate(date);
100         //记忆原始是日期时间
101         initOriginalText(date);
102
103         setBorder(null);
104         setCursor(new Cursor(Cursor.HAND_CURSOR));
105         super.addActionListener(new ActionListener() {
106
107             @Override
108             public void actionPerformed(ActionEvent e) {
109                 if (dateChooser == null) {
110                     dateChooser = new DateChooser();
111                 }
112
113                 dateChooser.showDateChooser();          
114             }
115         });
116     }
117     
118     public DateChooserJButton(int startYear, int lastYear) {
119         this();
120         this.startYear = startYear;
121         this.lastYear = lastYear;
122     }
123
124     private static Date getNowDate() {
125         return Calendar.getInstance().getTime();
126     }
127
128     private static SimpleDateFormat getDefaultDateFormat() {
129         return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
130     }
131
132     /**
133      * 得到当前使用的日期格式化器
134      * @return 日期格式化器
135      */
136     public SimpleDateFormat getCurrentSimpleDateFormat(){
137         if(this.sdf != null){
138             return sdf;
139         }else{
140             return getDefaultDateFormat();
141         }
142     }
143
144
145     //保存原始是日期时间
146     private void initOriginalText(String dateString) {
147         this.originalText = dateString;
148     }
149
150     //保存原始是日期时间
151     private void initOriginalText(Date date) {
152         this.originalText = preLabel + getDefaultDateFormat().format(date);
153     }
154
155     /** 
156      * 得到当前记忆的原始日期时间
157      * @return 当前记忆的原始日期时间(未修改前的日期时间)
158      */
159     public String getOriginalText() {
160         return originalText;
161     }
162
163     // 覆盖父类的方法
164     @Override
165     public void setText(String s) {
166         Date date;
167         try {
168             date = getDefaultDateFormat().parse(s);
169         } catch (ParseException e) {
170             date = getNowDate();
171         }
172         setDate(date);
173         initOriginalText(date);
174     }
175
176     public void setText(SimpleDateFormat df, String s) {
177         Date date;
178         try {
179             date = df.parse(s);
180         } catch (ParseException e) {
181             date = getNowDate();
182         }
183         setDate(date);
184         initOriginalText(date);
185     }
186
187     public void setDate(Date date) {
188         super.setText(preLabel + getDefaultDateFormat().format(date));
189     }
190
191     public Date getDate() {
192         String dateString = getText().substring(preLabel.length());
193         try {
194             SimpleDateFormat currentSdf = getCurrentSimpleDateFormat();
195             return currentSdf.parse(dateString);
196         } catch (ParseException e) {
197             return getNowDate();
198         }
199     }
200
201     /**  
202      * 覆盖父类的方法使之无效
203      * @param listener 响应监听器
204      */
205     @Override
206     public void addActionListener(ActionListener listener) {
207     }
208
209     /**
210      * 内部类,主要是定义一个JPanel,然后把日历相关的所有内容填入本JPanel,
211      * 然后再创建一个JDialog,把本内部类定义的JPanel放入JDialog的内容区
212      */
213     private class DateChooser extends JPanel implements MouseListener, ChangeListener {
214         private static final long serialVersionUID = 1L;
215         
216         JLabel yearLabel;
217         JLabel monthLabel;
218         JLabel dayLabel;
219         JLabel hourLabel;
220         JLabel minuteLabel;
221         JLabel secondLabel;
222         
223         int width = 485; // 界面宽度
224         int height = 230; // 界面高度
225         Color backGroundColor = Color.gray; // 底色
226         // 月历表格配色----------------//
227         Color palletTableColor = Color.white; // 日历表底色
228         Color todayBackColor = Color.orange; // 今天背景色
229         Color weekFontColor = Color.blue; // 星期文字色
230         Color dateFontColor = Color.black; // 日期文字色
231         Color weekendFontColor = Color.red; // 周末文字色
232         // 控制条配色------------------//
233         Color controlLineColor = Color.pink; // 控制条底色
234         Color controlTextColor = Color.white; // 控制条标签文字色
235         
236         /** 点击DateChooserButton时弹出的对话框,日历内容在这个对话框内 */
237         JDialog dialog;
238         JLabel[][] daysLabels = new JLabel[6][7];
239
240         DateChooser() {
241             setLayout(new BorderLayout());
242             setBorder(new LineBorder(backGroundColor, 2));
243             setBackground(backGroundColor);
244
245             JPanel topYearAndMonth = createYearAndMonthPanal();
246             add(topYearAndMonth, BorderLayout.NORTH);
247             JPanel centerWeekAndDay = createWeekAndDayPanal();
248             add(centerWeekAndDay, BorderLayout.CENTER);
249             JPanel buttonBarPanel = createButtonBarPanel();
250             this.add(buttonBarPanel, BorderLayout.SOUTH);
251         }
252
253         private JPanel createYearAndMonthPanal() {
254             Calendar c = getCalendar();
255             int currentYear = c.get(Calendar.YEAR);
256             int currentMonth = c.get(Calendar.MONTH) + 1;
257             int currentDay = c.get(Calendar.DAY_OF_MONTH);
258             int currentHour = c.get(Calendar.HOUR_OF_DAY);
259             int currentMinute = c.get(Calendar.MINUTE);
260             int currentSecond = c.get(Calendar.SECOND);
261
262             JPanel result = new JPanel();
263             result.setLayout(new FlowLayout());
264             result.setBackground(controlLineColor);
265
266             yearSpin = new JSpinner(new SpinnerNumberModel(currentYear, startYear, lastYear, 1));
267             yearSpin.setPreferredSize(new Dimension(48, 20));
268             yearSpin.setName("Year");
269             yearSpin.setEditor(new JSpinner.NumberEditor(yearSpin, "####"));
270             yearSpin.addChangeListener(this);
271             result.add(yearSpin);
272
273             yearLabel = new JLabel(Res.string().getYear());
274             yearLabel.setForeground(controlTextColor);
275             result.add(yearLabel);
276
277             monthSpin = new JSpinner(new SpinnerNumberModel(currentMonth, 1, 12, 1));
278             monthSpin.setPreferredSize(new Dimension(35, 20));
279             monthSpin.setName("Month");
280             monthSpin.addChangeListener(this);
281             result.add(monthSpin);
282
283             monthLabel = new JLabel(Res.string().getMonth());
284             monthLabel.setForeground(controlTextColor);
285             result.add(monthLabel);
286
287             //如果这里要能够选择,会要判断很多东西,比如每个月分别由多少日,以及闰年问题.所以,就干脆把Enable设为false
288             daySpin = new JSpinner(new SpinnerNumberModel(currentDay, 1, 31, 1));
289             daySpin.setPreferredSize(new Dimension(35, 20));
290             daySpin.setName("Day");
291             daySpin.addChangeListener(this);
292             daySpin.setEnabled(false);
293             result.add(daySpin);
294
295             dayLabel = new JLabel(Res.string().getDay());
296             dayLabel.setForeground(controlTextColor);
297             result.add(dayLabel);
298
299             hourSpin = new JSpinner(new SpinnerNumberModel(currentHour, 0, 23, 1));
300             hourSpin.setPreferredSize(new Dimension(35, 20));
301             hourSpin.setName("Hour");
302             hourSpin.addChangeListener(this);
303             result.add(hourSpin);
304
305             hourLabel = new JLabel(Res.string().getHour());
306             hourLabel.setForeground(controlTextColor);
307             result.add(hourLabel);
308
309             minuteSpin = new JSpinner(new SpinnerNumberModel(currentMinute, 0, 59, 1));
310             minuteSpin.setPreferredSize(new Dimension(35, 20));
311             minuteSpin.setName("Minute");
312             minuteSpin.addChangeListener(this);
313             result.add(minuteSpin);
314
315             minuteLabel = new JLabel(Res.string().getMinute());
316             minuteLabel.setForeground(controlTextColor);
317             result.add(minuteLabel);
318
319             secondSpin = new JSpinner(new SpinnerNumberModel(currentSecond, 0, 59, 1));
320             secondSpin.setPreferredSize(new Dimension(35, 20));
321             secondSpin.setName("Second");
322             secondSpin.addChangeListener(this);
323             result.add(secondSpin);
324
325             secondLabel = new JLabel(Res.string().getSecond());
326             secondLabel.setForeground(controlTextColor);
327             result.add(secondLabel);
328
329             return result;
330         }
331
332         private JPanel createWeekAndDayPanal() {
333             Res.string().getWeek();
334             JPanel result = new JPanel();
335             // 设置固定字体,以免调用环境改变影响界面美观
336             result.setFont(new Font("宋体", Font.PLAIN, 12));
337             result.setLayout(new GridLayout(7, 7));
338             result.setBackground(Color.white);
339             JLabel cell;
340
341             for (int i = 0; i < 7; i++) {
342                 cell = new JLabel(Res.string().getWeek()[i]);
343                 cell.setHorizontalAlignment(JLabel.RIGHT);
344                 if (i == 0 || i == 6) {
345                     cell.setForeground(weekendFontColor);
346                 } else {
347                     cell.setForeground(weekFontColor);
348                 }
349                 result.add(cell);
350             }
351
352 //            int actionCommandId = 0;
353             for (int i = 0; i < 6; i++) {
354                 for (int j = 0; j < 7; j++) {
355                     JLabel numberLabel = new JLabel();
356                     numberLabel.setBorder(null);
357                     numberLabel.setHorizontalAlignment(SwingConstants.RIGHT);
358 //                    numberLabel.setActionCommand(String.valueOf(actionCommandId));
359                     numberLabel.addMouseListener(this);
360                     numberLabel.setBackground(palletTableColor);
361                     numberLabel.setForeground(dateFontColor);
362                     if (j == 0 || j == 6) {
363                         numberLabel.setForeground(weekendFontColor);
364                     } else {
365                         numberLabel.setForeground(dateFontColor);
366                     }
367                     daysLabels[i][j] = numberLabel;
368                     result.add(numberLabel);
369 //                    actionCommandId++;
370                 }
371             }
372
373             return result;
374         }
375
376         /** 得到DateChooserButton的当前text,本方法是为按钮事件匿名类准备的。 */
377         public String getTextOfDateChooserButton() {
378             return getText();
379         }
380
381         /** 恢复DateChooserButton的原始日期时间text,本方法是为按钮事件匿名类准备的。 */
382         public void restoreTheOriginalDate() {
383             String originalText = getOriginalText();
384             setText(originalText);
385         }
386
387         private JPanel createButtonBarPanel() {
388             JPanel panel = new JPanel();
389             panel.setLayout(new GridLayout(1, 2));
390
391             JButton ok = new JButton(Res.string().getConfirm());
392             ok.addActionListener(new ActionListener() {
393
394                 @Override
395                 public void actionPerformed(ActionEvent e) {
396                     //记忆原始日期时间
397                     initOriginalText(getTextOfDateChooserButton());
398                     //隐藏日历对话框
399                     dialog.setVisible(false);
400                 }
401             });
402             panel.add(ok);
403
404             JButton cancel = new JButton(Res.string().getCancel());
405             cancel.addActionListener(new ActionListener() {
406
407                 @Override
408                 public void actionPerformed(ActionEvent e) {
409                     //恢复原始的日期时间
410                     restoreTheOriginalDate();     
411                     //隐藏日历对话框
412                     dialog.setVisible(false);
413                 }
414             });
415
416             panel.add(cancel);
417             return panel;
418         }
419
420         private JDialog createDialog() {
421             JDialog result = new JDialog();
422             result.setTitle(Res.string().getDateChooser());
423             result.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
424             result.getContentPane().add(this, BorderLayout.CENTER);
425             result.pack();
426             result.setSize(width, height);
427             result.setModal(true);  
428             
429             result.addWindowListener(new WindowAdapter() {
430                 public void windowClosing(WindowEvent e) {
431                      //恢复原始的日期时间
432                     restoreTheOriginalDate();     
433                     //隐藏日历对话框
434                     dialog.setVisible(false);
435                 }
436             });
437             
438             return result;
439         }
440
441         void showDateChooser() {
442             if (dialog == null) {
443                 dialog = createDialog();
444             }
445             dialog.setLocationRelativeTo(null);
446             flushWeekAndDay();
447             dialog.setVisible(true);
448         }
449
450         private Calendar getCalendar() {
451             Calendar result = Calendar.getInstance();
452             result.setTime(getDate());
453             return result;
454         }
455
456         private int getSelectedYear() {
457             return ((Integer) yearSpin.getValue()).intValue();
458         }
459
460         private int getSelectedMonth() {
461             return ((Integer) monthSpin.getValue()).intValue();
462         }
463
464         private int getSelectedHour() {
465             return ((Integer) hourSpin.getValue()).intValue();
466         }
467
468         private int getSelectedMinite() {
469             return ((Integer) minuteSpin.getValue()).intValue();
470         }
471
472         private int getSelectedSecond() {
473             return ((Integer) secondSpin.getValue()).intValue();
474         }
475
476         private void dayColorUpdate(boolean isOldDay) {
477             Calendar c = getCalendar();
478             int day = c.get(Calendar.DAY_OF_MONTH);
479             c.set(Calendar.DAY_OF_MONTH, 1);
480             int actionCommandId = day - 2 + c.get(Calendar.DAY_OF_WEEK);
481             int i = actionCommandId / 7;
482             int j = actionCommandId % 7;
483             if (isOldDay) {
484                 daysLabels[i][j].setForeground(dateFontColor);
485             } else {
486                 daysLabels[i][j].setForeground(todayBackColor);
487             }
488         }
489
490         private void flushWeekAndDay() {     
491             Calendar c = getCalendar();
492             c.set(Calendar.DAY_OF_MONTH, 1);
493             int maxDayNo = c.getActualMaximum(Calendar.DAY_OF_MONTH);
494             int dayNo = 2 - c.get(Calendar.DAY_OF_WEEK);
495             for (int i = 0; i < 6; i++) {
496                 for (int j = 0; j < 7; j++) {
497                     String s = "";
498                     if (dayNo >= 1 && dayNo <= maxDayNo) {
499                         s = String.valueOf(dayNo);
500                     }
501                     daysLabels[i][j].setText(s);
502                     dayNo++;
503                 }
504             }
505
506             // 打开日历时,根据按钮的时间,设置日历的时间
507             String[] date1 = getText().split(" ")[0].split("-");
508             String[] date2 = getText().split(" ")[1].split(":");
509
510             yearSpin.setValue(new Integer(date1[0]));
511             monthSpin.setValue(new Integer(date1[1]));
512             daySpin.setValue(new Integer(date1[2]));
513             hourSpin.setValue(new Integer(date2[0]));
514             minuteSpin.setValue(new Integer(date2[1]));
515             secondSpin.setValue(new Integer(date2[2]));
516
517             // 重置日历天的数字颜色
518             for(int i = 0; i < 6; i++) {
519                 for(int j = 0; j < 7; j++) {
520                     if(!daysLabels[i][j].getText().equals("")) {
521                         daysLabels[i][j].setForeground(Color.BLACK);
522                     }
523                 }
524             }
525             
526             // 重置日历星期六、星期日的数字颜色
527             for(int i = 0; i < 6; i++) {
528                 if(!daysLabels[i][0].getText().equals("")) {
529                     daysLabels[i][0].setForeground(weekendFontColor);
530                 }
531                 if(!daysLabels[i][6].getText().equals("")) {
532                     daysLabels[i][6].setForeground(weekendFontColor);
533                 }
534             }
535             
536             // 设置当天的数字颜色
537             for(int i = 0; i < 6; i++) {
538                 for(int j = 0; j < 7; j++) {
539                     if(daysLabels[i][j].getText().equals(date1[2])) {
540                         daysLabels[i][j].setForeground(todayBackColor);
541                     }
542                 }
543             }
544
545             dayColorUpdate(false);
546         }
547
548         /**
549          * 选择日期时的响应事件
550          */
551         @Override
552         public void stateChanged(ChangeEvent e) {
553             JSpinner source = (JSpinner) e.getSource();
554             Calendar c = getCalendar();
555             if (source.getName().equals("Hour")) {
556                 c.set(Calendar.HOUR_OF_DAY, getSelectedHour());
557                 setDate(c.getTime());
558                 return;
559             }
560             if (source.getName().equals("Minute")) {
561                 c.set(Calendar.MINUTE, getSelectedMinite());
562                 setDate(c.getTime());
563                 return;
564             }
565             if (source.getName().equals("Second")) {
566                 c.set(Calendar.SECOND, getSelectedSecond());
567                 setDate(c.getTime());
568                 return;
569             }
570
571             dayColorUpdate(true);
572
573             if (source.getName().equals("Year")) {
574                 c.set(Calendar.YEAR, getSelectedYear());
575             } else if (source.getName().equals("Month")) {
576                 c.set(Calendar.MONTH, getSelectedMonth() - 1);
577             }
578             setDate(c.getTime());
579             flushWeekAndDay();
580         }
581
582         /**
583          * 选择日期时的响应事件
584          */
585         @Override
586         public void mouseClicked(MouseEvent e) {
587             JLabel source = (JLabel) e.getSource();
588             if (source.getText().length() == 0) {
589                 return;
590             }
591             dayColorUpdate(true);
592             source.setForeground(todayBackColor);
593             int newDay = Integer.parseInt(source.getText());
594             Calendar c = getCalendar();
595             c.set(Calendar.DAY_OF_MONTH, newDay);
596             setDate(c.getTime());
597             //把daySpin中的值也变了
598             daySpin.setValue(Integer.valueOf(newDay));
599         }
600
601         @Override
602         public void mouseEntered(MouseEvent arg0) {
603             // TODO Auto-generated method stub
604             
605         }
606
607         @Override
608         public void mouseExited(MouseEvent arg0) {
609             // TODO Auto-generated method stub
610             
611         }
612
613         @Override
614         public void mousePressed(MouseEvent arg0) {
615             // TODO Auto-generated method stub
616             
617         }
618
619         @Override
620         public void mouseReleased(MouseEvent arg0) {
621             // TODO Auto-generated method stub
622             
623         }
624     }
625 }