package com.iailab.netsdk.common; 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.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; 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.JLabel; import javax.swing.JPanel; import javax.swing.JSpinner; import javax.swing.SpinnerNumberModel; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.border.LineBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; /** * 时间选择器, 年月日-时分秒 */ public class DateChooserJButton extends JButton { private static final long serialVersionUID = 1L; int startYear = 1980; // 默认【最小】显示年份 int lastYear = 2050; // 默认【最大】显示年份 private DateChooser dateChooser = null; private String preLabel = ""; private String originalText = null; private SimpleDateFormat sdf = null; private JSpinner yearSpin; private JSpinner monthSpin; private JSpinner daySpin; private JSpinner hourSpin; private JSpinner minuteSpin; private JSpinner secondSpin; public DateChooserJButton() { this(getNowDate()); try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { e.printStackTrace(); } } 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(); } dateChooser.showDateChooser(); } }); } public DateChooserJButton(int startYear, int lastYear) { this(); this.startYear = startYear; this.lastYear = lastYear; } 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); initOriginalText(date); } public void setText(SimpleDateFormat df, String s) { Date date; try { date = df.parse(s); } catch (ParseException e) { date = getNowDate(); } setDate(date); initOriginalText(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 MouseListener, ChangeListener { private static final long serialVersionUID = 1L; JLabel yearLabel; JLabel monthLabel; JLabel dayLabel; JLabel hourLabel; JLabel minuteLabel; JLabel secondLabel; int width = 485; // 界面宽度 int height = 230; // 界面高度 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; // 控制条标签文字色 /** 点击DateChooserButton时弹出的对话框,日历内容在这个对话框内 */ JDialog dialog; JLabel[][] daysLabels = new JLabel[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 buttonBarPanel = createButtonBarPanel(); this.add(buttonBarPanel, BorderLayout.SOUTH); } private JPanel createYearAndMonthPanal() { Calendar c = getCalendar(); int currentYear = c.get(Calendar.YEAR); int currentMonth = c.get(Calendar.MONTH) + 1; int currentDay = c.get(Calendar.DAY_OF_MONTH); 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); yearLabel = new JLabel(Res.string().getYear()); 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); monthLabel = new JLabel(Res.string().getMonth()); monthLabel.setForeground(controlTextColor); result.add(monthLabel); //如果这里要能够选择,会要判断很多东西,比如每个月分别由多少日,以及闰年问题.所以,就干脆把Enable设为false daySpin = new JSpinner(new SpinnerNumberModel(currentDay, 1, 31, 1)); daySpin.setPreferredSize(new Dimension(35, 20)); daySpin.setName("Day"); daySpin.addChangeListener(this); daySpin.setEnabled(false); result.add(daySpin); dayLabel = new JLabel(Res.string().getDay()); 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); hourLabel = new JLabel(Res.string().getHour()); 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); minuteLabel = new JLabel(Res.string().getMinute()); minuteLabel.setForeground(controlTextColor); 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); secondLabel = new JLabel(Res.string().getSecond()); secondLabel.setForeground(controlTextColor); result.add(secondLabel); return result; } private JPanel createWeekAndDayPanal() { Res.string().getWeek(); 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(Res.string().getWeek()[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++) { JLabel numberLabel = new JLabel(); numberLabel.setBorder(null); numberLabel.setHorizontalAlignment(SwingConstants.RIGHT); // numberLabel.setActionCommand(String.valueOf(actionCommandId)); numberLabel.addMouseListener(this); numberLabel.setBackground(palletTableColor); numberLabel.setForeground(dateFontColor); if (j == 0 || j == 6) { numberLabel.setForeground(weekendFontColor); } else { numberLabel.setForeground(dateFontColor); } daysLabels[i][j] = numberLabel; result.add(numberLabel); // 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 GridLayout(1, 2)); JButton ok = new JButton(Res.string().getConfirm()); ok.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //记忆原始日期时间 initOriginalText(getTextOfDateChooserButton()); //隐藏日历对话框 dialog.setVisible(false); } }); panel.add(ok); JButton cancel = new JButton(Res.string().getCancel()); cancel.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { //恢复原始的日期时间 restoreTheOriginalDate(); //隐藏日历对话框 dialog.setVisible(false); } }); panel.add(cancel); return panel; } private JDialog createDialog() { JDialog result = new JDialog(); result.setTitle(Res.string().getDateChooser()); result.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); result.getContentPane().add(this, BorderLayout.CENTER); result.pack(); result.setSize(width, height); result.setModal(true); result.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { //恢复原始的日期时间 restoreTheOriginalDate(); //隐藏日历对话框 dialog.setVisible(false); } }); return result; } void showDateChooser() { if (dialog == null) { dialog = createDialog(); } dialog.setLocationRelativeTo(null); flushWeekAndDay(); dialog.setVisible(true); } 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) { daysLabels[i][j].setForeground(dateFontColor); } else { daysLabels[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); } daysLabels[i][j].setText(s); dayNo++; } } // 打开日历时,根据按钮的时间,设置日历的时间 String[] date1 = getText().split(" ")[0].split("-"); String[] date2 = getText().split(" ")[1].split(":"); yearSpin.setValue(new Integer(date1[0])); monthSpin.setValue(new Integer(date1[1])); daySpin.setValue(new Integer(date1[2])); hourSpin.setValue(new Integer(date2[0])); minuteSpin.setValue(new Integer(date2[1])); secondSpin.setValue(new Integer(date2[2])); // 重置日历天的数字颜色 for(int i = 0; i < 6; i++) { for(int j = 0; j < 7; j++) { if(!daysLabels[i][j].getText().equals("")) { daysLabels[i][j].setForeground(Color.BLACK); } } } // 重置日历星期六、星期日的数字颜色 for(int i = 0; i < 6; i++) { if(!daysLabels[i][0].getText().equals("")) { daysLabels[i][0].setForeground(weekendFontColor); } if(!daysLabels[i][6].getText().equals("")) { daysLabels[i][6].setForeground(weekendFontColor); } } // 设置当天的数字颜色 for(int i = 0; i < 6; i++) { for(int j = 0; j < 7; j++) { if(daysLabels[i][j].getText().equals(date1[2])) { daysLabels[i][j].setForeground(todayBackColor); } } } 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 mouseClicked(MouseEvent e) { JLabel source = (JLabel) 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)); } @Override public void mouseEntered(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseExited(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mousePressed(MouseEvent arg0) { // TODO Auto-generated method stub } @Override public void mouseReleased(MouseEvent arg0) { // TODO Auto-generated method stub } } }