/*
* JTimeStamp.java
*
* Created on 2006��10��11��, ����1:13
*
* RealCix2.0
*/
package realcix20.guis.components;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.UIManager;
import javax.swing.border.AbstractBorder;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.plaf.basic.BasicComboBoxUI;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.plaf.basic.ComboPopup;
import javax.swing.plaf.metal.MetalComboBoxUI;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;
import javax.swing.text.PlainDocument;
import realcix20.utils.Resources;
import com.sun.java.swing.plaf.motif.MotifComboBoxUI;
import com.sun.java.swing.plaf.windows.WindowsComboBoxUI;
public class JTimeStamp extends JComboBox {
private static final long serialVersionUID = 6402443535775880347L;
public static final SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyy-MM-dd hh:mm:ss");
public static final SimpleDateFormat monthFormat = new SimpleDateFormat(
"yyyy-MM");
public static final SimpleDateFormat dayFormat = new SimpleDateFormat("d");
private JSpinner hourSpinner;
private JSpinner minuteSpinner;
private JSpinner secondSpinner;
private Calendar selectedCalendar;
public JTimeStamp() {
setEditable(true);
JTextField textField = ((JTextField) this.getEditor().getEditorComponent());
textField.setDocument(new JDateDocument(textField));
setSelectedItem(dateFormat.format(getSelectedCalendar().getTime()));
}
public Object getSelectedDate() {
try {
return this.getSelectedItem().toString();
} catch (Exception ex) {
return new java.sql.Date(new Date().getTime());
}
}
public void setSelectedItem(Object item) {
removeAllItems();
addItem(item);
super.setSelectedItem(item);
Date selectedDate;
try {
selectedDate = dateFormat.parse(this.getSelectedItem().toString());
} catch (Exception ex) {
selectedDate = new Date();
}
getSelectedCalendar().setTime(selectedDate);
getHourSpinner().setValue(getSelectedCalendar().getTime().getHours());
getMinuteSpinner().setValue(getSelectedCalendar().getTime().getMinutes());
getSecondSpinner().setValue(getSelectedCalendar().getTime().getSeconds());
}
public void updateUI() {
BasicComboBoxUI cui = (BasicComboBoxUI) UIManager.getUI(this);
if (cui instanceof MetalComboBoxUI) {
cui = new MetalDateComboBoxUI();
} else if (cui instanceof MotifComboBoxUI) {
cui = new MotifDateComboBoxUI();
} else if (cui instanceof WindowsComboBoxUI) {
cui = new WindowsDateComboBoxUI();
}else{
cui = new WindowsDateComboBoxUI();
}
setUI(cui);
}
class MetalDateComboBoxUI extends MetalComboBoxUI {
protected ComboPopup createPopup() {
this.arrowButton = new JButton();
return new DatePopup(comboBox);
}
}
class WindowsDateComboBoxUI extends WindowsComboBoxUI {
protected ComboPopup createPopup() {
return new DatePopup(comboBox);
}
}
class MotifDateComboBoxUI extends MotifComboBoxUI {
protected ComboPopup createPopup() {
return new DatePopup(comboBox);
}
}
public static class JDateDocument extends PlainDocument {
private JTextComponent textComponent;
private int newOffset;
public JDateDocument(JTextComponent tc) {
textComponent = tc;
String strCurrentDate = getCurrentDate();
try {
insertString(0, strCurrentDate, null);
} catch (Exception ex) {
// System.out.println(ex);
}
}
public void insertString(int offset, String s, AttributeSet attributeSet)
throws BadLocationException {
String toTest;
if (s.length() == 1) {
try {
Integer.parseInt(s);
} catch (Exception ex) {
Toolkit.getDefaultToolkit().beep();
return;
}
newOffset = offset;
if (offset == 4 || offset == 7) {
newOffset++;
textComponent.setCaretPosition(newOffset);
}
if (offset == 10)
return;
toTest = textComponent.getText();
toTest = toTest.substring(0, newOffset) + s
+ toTest.substring(newOffset + 1, 10);
if (!isLegalDate(toTest)) {
Toolkit.getDefaultToolkit().beep();
return;
}
super.remove(newOffset, 1);
super.insertString(newOffset, s, attributeSet);
}
else if (s.length() >= 10) {
//else if (s.length() == 10) {
if (!isLegalDate(s)) {
Toolkit.getDefaultToolkit().beep();
return;
}
super.remove(0, getLength());
super.insertString(0, s, attributeSet);
}
}
public void remove(int offset, int length) throws BadLocationException {
if (offset == 4 || offset == 7)
textComponent.setCaretPosition(offset - 1);
else
textComponent.setCaretPosition(offset);
}
public boolean isLegalDate(String strDate) {
int intY, intM, intD;
int iCaretPosition;
strDate = strDate.trim();
if (strDate == null || strDate.trim().equals("")
|| strDate.trim().length() <= 10)
{
return false;
}
for (int i = 0; i < strDate.trim().length(); i++)
if (((int) strDate.charAt(i)) > 255) {
return false;
}
try {
intY = Integer.parseInt(strDate.substring(0, 4));
intM = Integer.parseInt(strDate.substring(5, 7));
intD = Integer.parseInt(strDate.substring(8, 10));
} catch (Exception e) {
return false;
}
iCaretPosition = textComponent.getCaretPosition();
if (intY > 2999) {
textComponent.setText("2999" + strDate.substring(5));
textComponent.setCaretPosition(iCaretPosition + 1);
return false;
}
if (intY < 1000) {
textComponent.setText("1000" + strDate.substring(5));
textComponent.setCaretPosition(iCaretPosition + 1);
return false;
}
if (intM > 12) {
textComponent.setText(strDate.substring(0, 5) + "12"
+ strDate.substring(7));
textComponent.setCaretPosition(iCaretPosition + 1);
return false;
}
if (intM < 1) {
textComponent.setText(strDate.substring(0, 5) + "01"
+ strDate.substring(7));
textComponent.setCaretPosition(iCaretPosition + 1);
return false;
}
switch (intM) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if (intD > 31) {
textComponent.setText(strDate.substring(0, 8) + "31");
textComponent.setCaretPosition(iCaretPosition + 1);
}
if (intD < 1) {
textComponent.setText(strDate.substring(0, 8) + "01");
textComponent.setCaretPosition(iCaretPosition + 1);
}
return (intD <= 31 && intD > 0);
case 4:
case 6:
case 9:
case 11:
if (intD > 30) {
textComponent.setText(strDate.substring(0, 8) + "30");
textComponent.setCaretPosition(iCaretPosition + 1);
}
if (intD < 1) {
textComponent.setText(strDate.substring(0, 8) + "01");
textComponent.setCaretPosition(iCaretPosition + 1);
}
return (intD <= 30 && intD > 0);
case 2:
if ((intY % 4 == 0 && intY % 100 != 0) || intY % 400 == 0) {
if (intD > 29) {
textComponent.setText(strDate.substring(0, 8) + "29");
textComponent.setCaretPosition(iCaretPosition + 1);
}
if (intD < 1) {
textComponent.setText(strDate.substring(0, 8) + "01");
textComponent.setCaretPosition(iCaretPosition + 1);
}
return (intD <= 29 && intD > 0);
} else {
if (intD > 28) {
textComponent.setText(strDate.substring(0, 8) + "28");
textComponent.setCaretPosition(iCaretPosition + 1);
}
if (intD < 1) {
textComponent.setText(strDate.substring(0, 8) + "01");
textComponent.setCaretPosition(iCaretPosition + 1);
}
return (intD <= 28 && intD > 0);
}
default:
return false;
}
}
public static String getCurrentDate() {
return (dateFormat).format(new java.util.Date());
}
}
class DatePopup extends BasicComboPopup {
protected Calendar calendar;
protected JLabel monthLabel;
protected JPanel days = null;
protected Color selectedBackground;
protected Color selectedForeground;
protected Color background;
protected Color foreground;
ImageIcon todayIcon;
private JPanel header;
private DateFormatSymbols sy;
private JSpinner hourSpinner;
private JSpinner minuteSpinner;
private JSpinner secondSpinner;
private Calendar selectedCalendar;
//SpinnerModel is not use to support minutes
public DatePopup(JComboBox box) {
super(box);
JTimeStamp timeStamp = (JTimeStamp)box;
timeStamp.setSelectedCalendar(Calendar.getInstance());
if (timeStamp.getHourSpinner() == null) {
SpinnerModel model = new SpinnerNumberModel(getSelectedCalendar().getTime().getHours(), 0, 23, 1);
timeStamp.setHourSpinner(new JSpinner(model));
}
if (timeStamp.getMinuteSpinner() == null) {
SpinnerModel model = new SpinnerNumberModel(getSelectedCalendar().getTime().getHours(), 0, 59, 1);
timeStamp.setMinuteSpinner(new JSpinner(model));
}
if (timeStamp.getSecondSpinner() == null) {
SpinnerModel model = new SpinnerNumberModel(getSelectedCalendar().getTime().getHours(), 0, 59, 1);
timeStamp.setSecondSpinner(new JSpinner(model));
}
hourSpinner = timeStamp.getHourSpinner();
minuteSpinner = timeStamp.getMinuteSpinner();
secondSpinner = timeStamp.getSecondSpinner();
selectedCalendar = timeStamp.getSelectedCalendar();
//todayIcon=new ImageIcon(Application.instance().getServices().getImage("today"));
if (Resources.getLanguage().equals("EN")) {
sy = new DateFormatSymbols(Locale.US);
} else if (Resources.getLanguage().equals("ZH")) {
sy = new DateFormatSymbols(Locale.CHINA);
} else if (Resources.getLanguage().equals("DE")) {
sy = new DateFormatSymbols(Locale.GERMAN);
} else {
sy = new DateFormatSymbols(Locale.US);
}
calendar = selectedCalendar;
todayIcon=new ImageIcon();
background = UIManager.getColor("ComboBox.background");
foreground = UIManager.getColor("ComboBox.foreground");
selectedBackground = UIManager.getColor("ComboBox.selectionBackground");
selectedForeground = UIManager.getColor("ComboBox.selectionForeground");
initializePopup();
}
protected void initializePopup() {
header = new JPanel();
header.setLayout(new BoxLayout(header, BoxLayout.X_AXIS));
header.setBackground(new Color(0x33AE15));
header.setForeground(Color.white);
header.setPreferredSize(new Dimension(1, 25));
JLabel label;
label = createUpdateButton(Calendar.YEAR, -1);
label.setText("<<");
header.add(Box.createHorizontalStrut(12));
header.add(label);
header.add(Box.createHorizontalStrut(12));
label = createUpdateButton(Calendar.MONTH, -1);
label.setText("< ");
header.add(label);
monthLabel = new JLabel("", JLabel.CENTER);
monthLabel.setBackground(new Color(0, 0, 128));
monthLabel.setForeground(Color.white);
header.add(Box.createHorizontalGlue());
header.add(monthLabel);
header.add(Box.createHorizontalGlue());
label = createUpdateButton(Calendar.MONTH, 1);
label.setText(" >");
header.add(label);
label = createUpdateButton(Calendar.YEAR, 1);
label.setText(">>");
header.add(Box.createHorizontalStrut(12));
header.add(label);
header.add(Box.createHorizontalStrut(12));
JPanel pWeeks = new JPanel(new GridLayout(0, 7));
pWeeks.setBackground(background);
pWeeks.setOpaque(true);
String strWeeks[] = sy.getShortWeekdays();
for (int i = 1; i <= 7; i++) {
label = new JLabel();
label.setHorizontalAlignment(JLabel.CENTER);
label.setForeground(foreground);
label.setText(strWeeks[i]);
pWeeks.add(label);
}
days = new JPanel(new GridLayout(0, 7));
days.setBorder(new TopBottomLineBorder(Color.black));
days.setBackground(background);
days.setOpaque(true);
JPanel pCenter = new JPanel(new BorderLayout());
pCenter.setBackground(background);
pCenter.setOpaque(true);
pCenter.add(pWeeks, BorderLayout.NORTH);
pCenter.add(days, BorderLayout.CENTER);
JPanel pSouth = new JPanel(new FlowLayout());
pSouth.setBackground(background);
pSouth.setForeground(foreground);
pSouth.add(getHourSpinner());
label = new JLabel(" : ");
pSouth.add(label);
pSouth.add(getMinuteSpinner());
label = new JLabel(" : ");
pSouth.add(label);
pSouth.add(getSecondSpinner());
setForeground(foreground);
setBackground(background);
setBorder(BorderFactory.createLineBorder(Color.black));
setLayout(new BorderLayout());
removeAll();
add(BorderLayout.NORTH, header);
add(BorderLayout.CENTER, pCenter);
add(BorderLayout.SOUTH, pSouth);
}
//�·ݿؼ�.
public JPanel getMonthControl(){
initializePopup();
return header;
}
public void show() {
updatePopup();
super.show();
}
protected JLabel createUpdateButton(final int field, final int amount) {
final JLabel label = new JLabel();
final Border selectedBorder = new LineBorder(Color.black);
final Border unselectedBorder = new EmptyBorder(selectedBorder
.getBorderInsets(new JLabel()));
label.setBorder(unselectedBorder);
label.setBackground(new Color(0, 0, 128));
label.setForeground(Color.white);
label.setRequestFocusEnabled(false);
label.addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
calendar.add(field, amount);
updatePopup();
}
public void mouseEntered(MouseEvent e) {
label.setBorder(selectedBorder);
}
public void mouseExited(MouseEvent e) {
label.setBorder(unselectedBorder);
}
});
return label;
}
protected void updatePopup() {
monthLabel.setText(monthFormat.format(calendar.getTime()));
days.removeAll();
Calendar setupCalendar = (Calendar) calendar.clone();
setupCalendar.set(Calendar.DAY_OF_MONTH, 1);
int first = setupCalendar.get(Calendar.DAY_OF_WEEK);
setupCalendar.add(Calendar.DATE, -first);
int flag = 0;
for (int i = 0; i < 42; i++) {
setupCalendar.add(Calendar.DATE, 1);
String txt = dayFormat.format(setupCalendar.getTime());
JLabel label = new JDayLable(this, setupCalendar.getTime(), txt);
days.add(label);
if (txt.equals("1")) {
flag++;
}
if (flag != 1) {
label.setEnabled(false);
}
}
days.repaint();
pack();
}
class TopBottomLineBorder extends AbstractBorder {
private Color lineColor;
public TopBottomLineBorder(Color color) {
lineColor = color;
}
public void paintBorder(Component c, Graphics g, int x, int y,
int width, int height) {
g.setColor(lineColor);
g.drawLine(0, 0, c.getWidth(), 0);
g.drawLine(0, c.getHeight() - 1, c.getWidth(),
c.getHeight() - 1);
}
}
class JDayLable extends JLabel implements MouseListener {
Date date;
Image img;
DatePopup dp;
boolean isToday = false;
public JDayLable(DatePopup dp, Date date, String text) {
this.dp = dp;
setHorizontalAlignment(JLabel.CENTER);
setForeground(foreground);
setPreferredSize(new Dimension(40, 20));
setToolTipText(dateFormat.format(date));
addMouseListener(this);
this.date = date;
setText(text);
Date d = new Date();
isToday = (text.length() < 3)
&& dateFormat.format(date).equals(dateFormat.format(d));
if (calendar.getTime().equals(date)) {
setBorder(new LineBorder(selectedBackground, 1));
}
}
public void mousePressed(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
// System.err.println("mouseReleased");
if (isEnabled()) {
setOpaque(false);
setBackground(background);
setForeground(foreground);
}
calendar.setTime(date);
if (comboBox.isEditable() && comboBox.getEditor() != null) {
comboBox.configureEditor(comboBox.getEditor(), dateFormat
.format(calendar.getTime()));
}
int hour = Integer.parseInt(dp.getHourSpinner().getValue().toString());
int minute = Integer.parseInt(dp.getMinuteSpinner().getValue().toString());
int second = Integer.parseInt(dp.getSecondSpinner().getValue().toString());
calendar.set(Calendar.HOUR, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, second);
comboBox.setSelectedItem(dateFormat.format(calendar.getTime()));
comboBox.setPopupVisible(false);
}
public void mouseEntered(MouseEvent e) {
if (isEnabled()) {
setOpaque(true);
setBackground(selectedBackground);
setForeground(selectedForeground);
}
}
public void mouseExited(MouseEvent e) {
if (isEnabled()) {
setOpaque(false);
setBackground(background);
setForeground(foreground);
}
}
public void paint(Graphics g) {
super.paint(g);
if (isToday && todayIcon != null && isEnabled()) {
int x = (this.getWidth() - todayIcon.getIconWidth()) / 2;
int y = (this.getHeight() - todayIcon.getIconHeight()) / 2;
todayIcon.paintIcon(this, g, x, y);
}
}
}
public JSpinner getHourSpinner() {
return hourSpinner;
}
public JSpinner getMinuteSpinner() {
return minuteSpinner;
}
public JSpinner getSecondSpinner() {
return secondSpinner;
}
}
public JSpinner getHourSpinner() {
return hourSpinner;
}
public JSpinner getMinuteSpinner() {
return minuteSpinner;
}
public JSpinner getSecondSpinner() {
return secondSpinner;
}
public Calendar getSelectedCalendar() {
return selectedCalendar;
}
public void setHourSpinner(JSpinner hourSpinner) {
this.hourSpinner = hourSpinner;
}
public void setMinuteSpinner(JSpinner minuteSpinner) {
this.minuteSpinner = minuteSpinner;
}
public void setSecondSpinner(JSpinner secondSpinner) {
this.secondSpinner = secondSpinner;
}
public void setSelectedCalendar(Calendar selectedCalendar) {
this.selectedCalendar = selectedCalendar;
}
}