package com;/** * 日曆控制項 * @author lucifer.wang */import java.awt.BorderLayout;import java.awt.Color;import java.awt.Component;import java.awt.Dimension;import java.awt.FlowLayout;import java.awt.Toolkit;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.KeyEvent;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.util.Calendar;import java.util.Date;import javax.swing.AbstractAction;import javax.swing.InputMap;import javax.swing.JButton;import javax.swing.JComboBox;import javax.swing.JComponent;import javax.swing.JDialog;import javax.swing.JFrame;import javax.swing.JPanel;import javax.swing.JSpinner;import javax.swing.JTable;import javax.swing.KeyStroke;import javax.swing.ListSelectionModel;import javax.swing.SpinnerNumberModel;import javax.swing.SwingConstants;import javax.swing.UIManager;import javax.swing.event.ChangeEvent;import javax.swing.event.ChangeListener;import javax.swing.event.ListSelectionEvent;import javax.swing.event.ListSelectionListener;import javax.swing.table.DefaultTableCellRenderer;import javax.swing.table.DefaultTableModel;public class CalendarPanel extends JDialog {private JComboBox comboBoxMonth;private JSpinner spinnerYear;private JTable2 table;private JTableModel2 tableModel;private Calendar calendar;private String[] days = { "SUN", "MON", "TUR", "WED", "THU", "FRI", "SAT" };private String[] months = { "January", "February", "March", "April", "May","June", "July", "August", "September", "October", "November","December" };private int year = -1;private int month = -1;private int date = -1;private int oldYear = -1;private int oldMonth = -1;private int oldDate = -1;private boolean flag = true;private JButton okButton;private JButton cancelButton;public CalendarPanel(JFrame frame) {super(frame, true);this.setTitle("選擇日期");calendar = Calendar.getInstance();initComponent();setSize(400, 450);center(); setVisible(true);}public CalendarPanel(Calendar calendar) {super();this.calendar = calendar;initComponent();setSize(400, 450);center(); setVisible(true);}public CalendarPanel(Date date) {super();this.calendar = Calendar.getInstance();this.calendar.setTime(date);initComponent();setSize(400, 450);center(); setVisible(true);}public CalendarPanel(int year, int month, int date) {super();this.calendar = Calendar.getInstance();calendar.set(Calendar.YEAR, year);calendar.set(Calendar.MONTH, month - 1);calendar.set(Calendar.DATE, date);oldYear = calendar.get(Calendar.YEAR);oldMonth = calendar.get(Calendar.MONTH);oldDate = calendar.get(Calendar.DATE);initComponent();setSize(400, 450);center(); setVisible(true);}public void center() { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension frameSize = getSize(); if (frameSize.height > screenSize.height) { frameSize.height = screenSize.height; } if (frameSize.width > screenSize.width) { frameSize.width = screenSize.width; } super.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);}public Calendar getCalendar() {return calendar;}public String getCalendarByDate(String tag) {StringBuffer strRet = new StringBuffer();if (calendar != null) {oldYear = calendar.get(Calendar.YEAR);oldMonth = calendar.get(Calendar.MONTH);oldDate = calendar.get(Calendar.DATE);if (oldDate < 10)strRet.append("0" + oldDate);elsestrRet.append(oldDate);strRet.append(tag);if (oldMonth < 10)strRet.append("0" + oldMonth);elsestrRet.append(oldMonth);strRet.append(tag + oldYear);return strRet.toString();}return null;}public Date getCalendarByDate() {if (calendar != null)return calendar.getTime();return null;}private void initComponent() {oldYear = calendar.get(Calendar.YEAR);oldMonth = calendar.get(Calendar.MONTH);oldDate = calendar.get(Calendar.DATE);// this.setBorder(new TitledBorder("Date"));this.getContentPane().setLayout(new BorderLayout());setNorthPanel();setCenterPanel();setSouthPanel();eventListenter();setData();}private void setData() {year = calendar.get(Calendar.YEAR);month = calendar.get(Calendar.MONTH);date = calendar.get(Calendar.DATE);comboBoxMonth.setSelectedIndex(month);spinnerYear.setValue(new Integer(year));}private void eventListenter() {spinnerYear.addChangeListener(new ChangeListener() {public void stateChanged(ChangeEvent e) {year = Integer.parseInt(String.valueOf(spinnerYear.getValue()));refreshTable();}});comboBoxMonth.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {month = comboBoxMonth.getSelectedIndex();refreshTable();}});table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {public void valueChanged(ListSelectionEvent e) {if (table.getSelectedRow() > -1&& table.getSelectedColumn() > -1) {date = Integer.parseInt(String.valueOf(table.getValueAt(table.getSelectedRow(), table.getSelectedColumn())));calendar.set(Calendar.YEAR, year);calendar.set(Calendar.MONTH, month);calendar.set(Calendar.DATE, date);}}});AbstractAction right = (new AbstractAction() {/** * */private static final long serialVersionUID = -3429888240127305492L;public void actionPerformed(ActionEvent e) {if (table.getColumnCount() == table.getSelectedColumn() + 1) {table.changeSelection(table.getSelectedRow() + 1, 0, false,false);} else {table.changeSelection(table.getSelectedRow(), table.getSelectedColumn() + 1, false, false);}}});AbstractAction left = (new AbstractAction() {/** * */private static final long serialVersionUID = -2487040789339112435L;public void actionPerformed(ActionEvent e) {if (0 > table.getSelectedColumn() - 1) {table.changeSelection(table.getSelectedRow() - 1, table.getColumnCount() - 1, false, false);} else {table.changeSelection(table.getSelectedRow(), table.getSelectedColumn() - 1, false, false);}}});InputMap inputMap = table.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);KeyStroke keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0);table.getActionMap().put(inputMap.get(keyStroke), right);keyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0);table.getActionMap().put(inputMap.get(keyStroke), left);okButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {/* * calendar.set(Calendar.YEAR, Integer.parseInt(String * .valueOf(spinnerYear.getValue()))); * calendar.set(Calendar.MONTH, * comboBoxMonth.getSelectedIndex()); * calendar.set(Calendar.DATE, Integer.parseInt(String * .valueOf(table.getValueAt(table.getSelectedRow(), table * .getSelectedColumn())))); oldYear = * calendar.get(Calendar.YEAR); oldMonth = * calendar.get(Calendar.MONTH); oldDate = * calendar.get(Calendar.DATE); * JOptionPane.showMessageDialog(CalendarPanel.this, "OK, Select * Date is " + CalendarPanel.this.getCalendarByDate()); */setVisible(false);}});cancelButton.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {/* * calendar.set(Calendar.YEAR, oldYear); * calendar.set(Calendar.MONTH, oldMonth); * calendar.set(Calendar.DATE, oldDate); * JOptionPane.showMessageDialog(CalendarPanel.this, "Cancel, * Date is " + CalendarPanel.this.getCalendarByDate()); */calendar = null;setVisible(false);}});addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {calendar = null;super.windowClosing(e);}});}private void refreshTable() {for (int i = tableModel.getRowCount() - 1; i > 0; i--) {tableModel.removeRow(i);}calendar.set(Calendar.YEAR, year);calendar.set(Calendar.MONTH, month);int maxDate = calendar.getActualMaximum(Calendar.DATE);calendar.set(Calendar.DATE, 1);int startDay = calendar.get(Calendar.DAY_OF_WEEK);for (int i = 0; i < 6; i++) {tableModel.addRow(new Object[7]);}int selectRow = -1;int selectColumn = -1;for (int i = 0; i < maxDate; i++) {int m = (int) ((startDay - 1) / 7) + 1;int n = (startDay - 1) % 7;tableModel.setValueAt(String.valueOf(i + 1), m, n);startDay = startDay + 1;if (date != -1 && date == i + 1) {selectRow = m;selectColumn = n;}}table.changeSelection(selectRow, selectColumn, false, false);}private void setSouthPanel() {JPanel panel = new JPanel();panel.setLayout(new FlowLayout(FlowLayout.RIGHT));okButton = new JButton("OK");panel.add(okButton);cancelButton = new JButton("Cancel");panel.add(cancelButton);this.getContentPane().add(panel, BorderLayout.SOUTH);}private void setCenterPanel() {table = new JTable2();tableModel = new JTableModel2();tableModel.setColumnIdentifiers(days);tableModel.addRow(days);table.setModel(tableModel);for (int i = 0; i < 7; i++) {table.getColumnModel().getColumn(i).setCellRenderer(new DefaultTableCellRenderer2());}this.getContentPane().add(table, BorderLayout.CENTER);}private void setNorthPanel() {JPanel panel = new JPanel();panel.setLayout(new FlowLayout());comboBoxMonth = new JComboBox();for (int i = 0; i < months.length; i++) {comboBoxMonth.addItem(months[i]);}comboBoxMonth.setSelectedIndex(-1);panel.add(comboBoxMonth);RolloverSpinnerListModel numberModel = new RolloverSpinnerListModel(1980, 1980, 2099, 1);spinnerYear = new JSpinner(numberModel);JSpinner.NumberEditor numberEditor = new JSpinner.NumberEditor(spinnerYear, "####");spinnerYear.setEditor(numberEditor);panel.add(spinnerYear);this.getContentPane().add(panel, BorderLayout.NORTH);}public static void main(String[] args) {JFrame frame = new JFrame();CalendarPanel calendarPanel = new CalendarPanel(frame);// frame.getContentPane().add(calendarPanel, BorderLayout.CENTER);calendarPanel.setSize(400, 450);// calendarPanel.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);calendarPanel.setVisible(true);}protected void validateTree() {super.validateTree();if (flag) {table.requestFocus();flag = false;}}}class RolloverSpinnerListModel extends SpinnerNumberModel {/** * */private static final long serialVersionUID = 7366455425120197392L;public RolloverSpinnerListModel(int value, int minimum, int maximum,int stepSize) {super(value, minimum, maximum, stepSize);}public Object getNextValue() {Object returnValue = super.getNextValue();if (returnValue == null) {returnValue = super.getMinimum();}return returnValue;}public Object getPreviousValue() {Object returnValue = super.getPreviousValue();if (returnValue == null) {returnValue = super.getMaximum();}return returnValue;}}class JTable2 extends JTable {/** * */private static final long serialVersionUID = 2092799354481792367L;public JTable2() {this.getTableHeader().setReorderingAllowed(false);this.getTableHeader().setResizingAllowed(false);this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);this.setCellSelectionEnabled(true);this.setGridColor(Color.white);}public void changeSelection(int rowIndex, int columnIndex, boolean toggle,boolean extend) {if (this.getValueAt(rowIndex, columnIndex) == null) {return;}if (rowIndex == 0) {return;}super.changeSelection(rowIndex, columnIndex, toggle, extend);}public void repaint(int x, int y, int width, int height) {super.repaint(x, y, width, height);if (height > 0) {makeTableRowHeight();}}protected void validateTree() {super.validateTree();makeTableRowHeight();}private void makeTableRowHeight() {int rowHeight = (int) ((this.getHeight() / 7) * 0.6);if (rowHeight > 0) {this.setRowHeight(0, rowHeight);}rowHeight = (int) ((this.getHeight() - rowHeight) / 6);if (rowHeight > 0) {for (int i = 1; i < 8; i++) {this.setRowHeight(i, rowHeight);}}}}class JTableModel2 extends DefaultTableModel {/** * */private static final long serialVersionUID = 3655520869200784738L;public boolean isCellEditable(int row, int column) {return false;}}class DefaultTableCellRenderer2 extends DefaultTableCellRenderer {/** * */private static final long serialVersionUID = -8779549993366848535L;public Component getTableCellRendererComponent(JTable table, Object value,boolean isSelected, boolean hasFocus, int row, int column) {Component component = super.getTableCellRendererComponent(table, value,isSelected, hasFocus, row, column);this.setHorizontalAlignment(SwingConstants.CENTER);if (row == 0) {component.setBackground(UIManager.getColor("Table.focusCellForeground"));component.setForeground(UIManager.getColor("Table.focusCellBackground"));return component;} else {if (isSelected) {component.setBackground(UIManager.getColor("Table.focusCellForeground"));component.setForeground(UIManager.getColor("Table.focusCellBackground"));} else {component.setBackground(UIManager.getColor("Table.focusCellBackground"));component.setForeground(UIManager.getColor("Table.focusCellForeground"));}if (column == 0 || column == 6) {component.setForeground(Color.red);}}return component;}}