Calendar.java
上传用户:haobig99
上传日期:2022-06-15
资源大小:369k
文件大小:20k
源码类别:

J2ME

开发平台:

Java

  1. /*
  2.  * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
  3.  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4.  *
  5.  * This code is free software; you can redistribute it and/or modify it
  6.  * under the terms of the GNU General Public License version 2 only, as
  7.  * published by the Free Software Foundation.  Sun designates this
  8.  * particular file as subject to the "Classpath" exception as provided
  9.  * by Sun in the LICENSE file that accompanied this code.
  10.  *
  11.  * This code is distributed in the hope that it will be useful, but WITHOUT
  12.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14.  * version 2 for more details (a copy is included in the LICENSE file that
  15.  * accompanied this code).
  16.  *
  17.  * You should have received a copy of the GNU General Public License version
  18.  * 2 along with this work; if not, write to the Free Software Foundation,
  19.  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20.  *
  21.  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  22.  * CA 95054 USA or visit www.sun.com if you need additional information or
  23.  * have any questions.
  24.  */
  25. package com.sun.lwuit;
  26. import com.sun.lwuit.events.ActionEvent;
  27. import com.sun.lwuit.events.ActionListener;
  28. import com.sun.lwuit.events.DataChangedListener;
  29. import com.sun.lwuit.events.FocusListener;
  30. import com.sun.lwuit.plaf.Style;
  31. import com.sun.lwuit.layouts.BorderLayout;
  32. import com.sun.lwuit.layouts.BoxLayout;
  33. import com.sun.lwuit.layouts.FlowLayout;
  34. import com.sun.lwuit.layouts.GridLayout;
  35. import com.sun.lwuit.plaf.UIManager;
  36. import com.sun.lwuit.util.EventDispatcher;
  37. import java.util.Date;
  38. import java.util.Hashtable;
  39. import java.util.TimeZone;
  40. /**
  41.  * Date widget for selecting a date/time value. 
  42.  * <p>To localize strings for month names
  43.  * use the values "Calendar.Month" in the resource localization e.g. "Calendar.Jan", "Calendar.Feb" etc...
  44.  *
  45.  * @author Iddo Ari, Shai Almog
  46.  */
  47. public class Calendar extends Container {
  48.     private Label month;
  49.     private Label year;
  50.     private MonthView mv;
  51.     private static final String[] MONTHS = new String[]{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  52.     private static final String[] DAYS = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
  53.     private static final String[] LABELS = {"Su", "M", "Tu", "W", "Th", "F", "Sa"};
  54.     static final long MINUTE = 1000 * 60;
  55.     static final long HOUR = MINUTE * 60;
  56.     static final long DAY = HOUR * 24;
  57.     static final long WEEK = DAY * 7;
  58.     private EventDispatcher dispatcher = new EventDispatcher();
  59.     private EventDispatcher dataChangeListeners = new EventDispatcher();
  60.     private long[] dates = new long[42];
  61.     private Button incrementMonth;
  62.     private Button decrementMonth;
  63.     /**
  64.      * Creates a new instance of Calendar set to the given date based on time
  65.      * since epoch (the java.util.Date convention)
  66.      * 
  67.      * @param time time since epoch
  68.      */
  69.     public Calendar(long time) {
  70.         super(new BorderLayout());
  71.         setUIID("Calendar");
  72.         Container upper = new Container(new FlowLayout(Component.CENTER));
  73.         incrementMonth = createIncrementButton();
  74.         decrementMonth = createDecrementButton();
  75.         mv = new MonthView(time);
  76.         incrementMonth.addActionListener(mv);
  77.         decrementMonth.addActionListener(mv);
  78.         month = new Label(getLocalizedMonth(mv.getMonth()));
  79.         java.util.Calendar cal = java.util.Calendar.getInstance();
  80.         cal.setTime(new java.util.Date(time));
  81.         month.getStyle().setBgTransparency(0);
  82.         int y = cal.get(java.util.Calendar.YEAR);
  83.         year = new Label("" + y);
  84.         year.getStyle().setBgTransparency(0);
  85.         Container cnt = new Container(new BoxLayout(BoxLayout.X_AXIS));
  86.         cnt.setRTL(false);
  87.         cnt.addComponent(decrementMonth);
  88.         Container dateCnt = new Container(new BoxLayout(BoxLayout.X_AXIS));
  89.         dateCnt.setUIID("CalendarDate");
  90.         dateCnt.addComponent(month);
  91.         dateCnt.addComponent(year);
  92.         cnt.addComponent(dateCnt);
  93.         cnt.addComponent(incrementMonth);
  94.         upper.addComponent(cnt);
  95.         addComponent(BorderLayout.NORTH, upper);
  96.         addComponent(BorderLayout.CENTER, mv);
  97.     }
  98.     /**
  99.      * Constructs a calendar with the current date and time
  100.      */
  101.     public Calendar() {
  102.         this(System.currentTimeMillis());
  103.     }
  104.     
  105.     /**
  106.      * Returns the time for the current calendar.
  107.      * 
  108.      * @return the time for the current calendar.
  109.      */
  110.     public long getSelectedDay() {
  111.         return mv.getSelectedDay();
  112.     }
  113.     private String getLocalizedMonth(int i) {
  114.         Hashtable t = UIManager.getInstance().getResourceBundle();
  115.         String text = MONTHS[i];
  116.         if (t != null) {
  117.             Object o = t.get("Calendar." + text);
  118.             if (o != null) {
  119.                 text = (String) o;
  120.             }
  121.         }
  122.         return text;
  123.     }
  124.     void componentChanged() {
  125.         java.util.Calendar cal = java.util.Calendar.getInstance();
  126.         cal.set(java.util.Calendar.YEAR, mv.getYear());
  127.         cal.set(java.util.Calendar.MONTH, mv.getMonth());
  128.         cal.set(java.util.Calendar.DAY_OF_MONTH, mv.getDayOfMonth());
  129.         month.setText(getLocalizedMonth(mv.getMonth()));
  130.         year.setText("" + mv.getYear());
  131.         month.getParent().revalidate();
  132.     }
  133.     /**
  134.      * Return the date object matching the current selection
  135.      * 
  136.      * @return the date object matching the current selection
  137.      */
  138.     public Date getDate() {
  139.         return new Date(mv.getSelectedDay());
  140.     }
  141.     /**
  142.      * Sets the current date in the view
  143.      * 
  144.      * @param d new date
  145.      */
  146.     public void setDate(Date d) {
  147.         mv.setSelectedDay(d.getTime());
  148.         mv.setCurrentDay(mv.currentDay, true);
  149.         componentChanged();
  150.     }
  151.     /**
  152.      * @inheritDoc
  153.      */
  154.     public void paint(Graphics g) {
  155.         super.paint(g);
  156.     }
  157.     /**
  158.      * Sets the selected style of the month view component within the calendar
  159.      * 
  160.      * @param s style for the month view 
  161.      */
  162.     public void setMonthViewSelectedStyle(Style s) {
  163.         mv.setSelectedStyle(s);
  164.     }
  165.     /**
  166.      * Sets the un selected style of the month view component within the calendar
  167.      * 
  168.      * @param s style for the month view 
  169.      */
  170.     public void setMonthViewUnSelectedStyle(Style s) {
  171.         mv.setUnSelectedStyle(s);
  172.     }
  173.     /**
  174.      * Gets the selected style of the month view component within the calendar
  175.      * 
  176.      * @return the style of the month view
  177.      */
  178.     public Style getMonthViewSelectedStyle() {
  179.         return mv.getSelectedStyle();
  180.     }
  181.     /**
  182.      * Gets the un selected style of the month view component within the calendar
  183.      * 
  184.      * @return the style of the month view
  185.      */
  186.     public Style getMonthViewUnSelectedStyle() {
  187.         return mv.getUnselectedStyle();
  188.     }
  189.     /**
  190.      * Fires when a change is made to the month view of this component
  191.      * 
  192.      * @param l listener to add
  193.      */
  194.     public void addActionListener(ActionListener l) {
  195.         mv.addActionListener(l);
  196.     }
  197.     /**
  198.      * Fires when a change is made to the month view of this component
  199.      * 
  200.      * @param l listener to remove
  201.      */
  202.     public void removeActionListener(ActionListener l) {
  203.         mv.removeActionListener(l);
  204.     }
  205.     /**
  206.      * Allows tracking selection changes in the calendar in real time
  207.      * 
  208.      * @param l listener to add
  209.      */
  210.     public void addDataChangeListener(DataChangedListener l) {
  211.         mv.addDataChangeListener(l);
  212.     }
  213.     /**
  214.      * Allows tracking selection changes in the calendar in real time
  215.      * 
  216.      * @param l listener to remove
  217.      */
  218.     public void removeDataChangeListener(DataChangedListener l) {
  219.         mv.removeDataChangeListener(l);
  220.     }
  221.     /**
  222.      * This method creates the Day Button Component for the Month View
  223.      * 
  224.      * @return a Button that corresponds to the Days Components
  225.      */
  226.     protected Button createDay() {
  227.         Button day = new Button();
  228.         day.setAlignment(CENTER);
  229.         day.setUIID("CalendarDay");
  230.         day.setEndsWith3Points(false);
  231.         day.setTickerEnabled(false);
  232.         return day;
  233.     }
  234.     /**
  235.      * This method creates the Day title Component for the Month View
  236.      * 
  237.      * @param day the relevant day values are 0-6 where 0 is sunday.
  238.      * @return a Label that corresponds to the relevant Day
  239.      */
  240.     protected Label createDayTitle(int day) {
  241.         String value = UIManager.getInstance().localize(DAYS[day], LABELS[day]);
  242.         Label dayh = new Label(value, "CalendarTitle");
  243.         dayh.setEndsWith3Points(false);
  244.         dayh.setTickerEnabled(false);
  245.         return dayh;
  246.     }
  247.     /**
  248.      * This method creates the increment month button
  249.      * 
  250.      * @return the Button that increase the Calendar months 
  251.      */
  252.     protected Button createIncrementButton() {
  253.         Button btn = new Button(">>");
  254.         btn.setUIID("CalendarNavigation");
  255.         btn.setEndsWith3Points(false);
  256.         btn.setTickerEnabled(false);
  257.         return btn;
  258.     }
  259.     /**
  260.      * This method creates the decrement month button
  261.      * 
  262.      * @return the Button that decrease the Calendar months 
  263.      */
  264.     protected Button createDecrementButton() {
  265.         Button btn = new Button("<<");
  266.         btn.setUIID("CalendarNavigation");
  267.         btn.setEndsWith3Points(false);
  268.         btn.setTickerEnabled(false);
  269.         return btn;
  270.     }
  271.     class MonthView extends Container implements ActionListener{
  272.         private long currentDay;
  273.         private Button[] buttons = new Button[42];
  274.         private Style selectedStyle;
  275.         private Button selected;
  276.         private long selectedDay = -1;
  277.         
  278.         public MonthView(long time) {
  279.             super(new GridLayout(7, 7));
  280.             setUIID("MonthView");
  281.             selectedStyle = UIManager.getInstance().getComponentStyle("CalendarSelectedDay");
  282.             
  283.             for (int iter = 0; iter < DAYS.length; iter++) {
  284.                 addComponent(createDayTitle(iter));
  285.             }
  286.             for (int iter = 0; iter < buttons.length; iter++) {
  287.                 buttons[iter] = createDay();
  288.                 addComponent(buttons[iter]);
  289.                 if (iter <= 3) {
  290.                     buttons[iter].setNextFocusUp(decrementMonth);
  291.                 } else if (iter <= 7) {
  292.                     buttons[iter].setNextFocusUp(incrementMonth);
  293.                 }
  294.                 buttons[iter].addActionListener(this);
  295.             }
  296.             setCurrentDay(time);
  297.             
  298.         }
  299.         public void setCurrentDay(long day){
  300.             setCurrentDay(day, false);
  301.         }
  302.         
  303.         private void setCurrentDay(long day, boolean force) {
  304.             repaint();
  305.             java.util.Calendar cal = java.util.Calendar.getInstance();
  306.             cal.setTime(new Date(currentDay));
  307.             cal.set(java.util.Calendar.HOUR, 1);
  308.             cal.set(java.util.Calendar.HOUR_OF_DAY, 1);
  309.             cal.set(java.util.Calendar.MINUTE, 0);
  310.             cal.set(java.util.Calendar.SECOND, 0);
  311.             cal.set(java.util.Calendar.MILLISECOND, 0);
  312.             
  313.             int yearOld = cal.get(java.util.Calendar.YEAR);
  314.             int monthOld = cal.get(java.util.Calendar.MONTH);
  315.             int dayOld = cal.get(java.util.Calendar.DAY_OF_MONTH);
  316.             cal.setTime(new Date(day));
  317.             cal.set(java.util.Calendar.HOUR, 1);
  318.             cal.set(java.util.Calendar.HOUR_OF_DAY, 1);
  319.             cal.set(java.util.Calendar.MINUTE, 0);
  320.             cal.set(java.util.Calendar.SECOND, 0);
  321.             cal.set(java.util.Calendar.MILLISECOND, 0);
  322.             int yearNew = cal.get(java.util.Calendar.YEAR);
  323.             int monthNew = cal.get(java.util.Calendar.MONTH);
  324.             int dayNew = cal.get(java.util.Calendar.DAY_OF_MONTH);
  325.             if (yearNew != yearOld || monthNew != monthOld || dayNew != dayOld || force) {
  326.                 currentDay = cal.getTime().getTime();
  327.                 if(selectedDay == -1){
  328.                     selectedDay = currentDay;
  329.                 }
  330.                 int month = cal.get(java.util.Calendar.MONTH);
  331.                 cal.set(java.util.Calendar.DAY_OF_MONTH, 1);
  332.                 long startDate = cal.getTime().getTime();
  333.                 int dow = cal.get(java.util.Calendar.DAY_OF_WEEK);
  334.                 cal.setTime(new Date(cal.getTime().getTime() - DAY));
  335.                 cal.set(java.util.Calendar.HOUR, 1);
  336.                 cal.set(java.util.Calendar.HOUR_OF_DAY, 1);
  337.                 cal.set(java.util.Calendar.MINUTE, 0);
  338.                 cal.set(java.util.Calendar.SECOND, 0);
  339.                 cal.set(java.util.Calendar.MILLISECOND, 0);
  340.                 int lastDay = cal.get(java.util.Calendar.DAY_OF_MONTH);
  341.                 int i = 0;
  342.                 Style unselected = createDay().getUnselectedStyle();
  343.                 
  344.                 if(dow > java.util.Calendar.SUNDAY){
  345.                     //last day of previous month
  346.                     while (dow > java.util.Calendar.SUNDAY) {
  347.                         cal.setTime(new Date(cal.getTime().getTime() - DAY));
  348.                         dow = cal.get(java.util.Calendar.DAY_OF_WEEK);
  349.                     }
  350.                     int previousMonthSunday = cal.get(java.util.Calendar.DAY_OF_MONTH);
  351.                     for (; i <= lastDay - previousMonthSunday; i++) {
  352.                         buttons[i].setUnselectedStyle(new Style(unselected));
  353.                         buttons[i].setEnabled(false);
  354.                         buttons[i].setText("" + (previousMonthSunday + i));
  355.                     }
  356.                 }
  357.                 //last day of current month
  358.                 cal.set(java.util.Calendar.MONTH, (month + 1) % 12);
  359.                 cal.set(java.util.Calendar.DAY_OF_MONTH, 1);
  360.                 cal.setTime(new Date(cal.getTime().getTime() - DAY));
  361.                 lastDay = cal.get(java.util.Calendar.DAY_OF_MONTH);
  362.                 
  363.                 int j = i;
  364.                 for (; j < buttons.length && (j - i + 1) <= lastDay; j++) {
  365.                     buttons[j].setEnabled(true);
  366.                     buttons[j].setText("" + (j - i + 1));
  367.                     dates[j] = startDate;
  368.                     if(dates[j] == selectedDay){
  369.                         buttons[j].setUnselectedStyle(new Style(selectedStyle));
  370.                         selected = buttons[j];
  371.                     }else{
  372.                         buttons[j].setUnselectedStyle(new Style(unselected));
  373.                     }
  374.                     startDate += DAY;
  375.                 }
  376.                 int d = 1;
  377.                 for (; j < buttons.length; j++) {
  378.                     buttons[j].setUnselectedStyle(new Style(unselected));
  379.                     buttons[j].setEnabled(false);
  380.                     buttons[j].setText("" + d++);
  381.                 }
  382.             }
  383.         }
  384.         public int getDayOfMonth() {
  385.             java.util.Calendar cal = java.util.Calendar.getInstance();
  386.             cal.setTime(new Date(currentDay));
  387.             return cal.get(java.util.Calendar.DAY_OF_MONTH);
  388.         }
  389.         public int getMonth() {
  390.             java.util.Calendar cal = java.util.Calendar.getInstance();
  391.             cal.setTime(new Date(currentDay));
  392.             return cal.get(java.util.Calendar.MONTH);
  393.         }
  394.         public void incrementMonth() {
  395.             int month = getMonth();
  396.             month++;
  397.             int year = getYear();
  398.             if (month > java.util.Calendar.DECEMBER) {
  399.                 month = java.util.Calendar.JANUARY;
  400.                 year++;
  401.             }
  402.             setMonth(year, month);
  403.         }
  404.         private long getSelectedDay() {
  405.             return selectedDay;
  406.         }
  407.         
  408.         public void setSelectedDay(long selectedDay){
  409.             java.util.Calendar cal = java.util.Calendar.getInstance();
  410.             cal.setTime(new Date(selectedDay));
  411.             cal.set(java.util.Calendar.HOUR, 1);
  412.             cal.set(java.util.Calendar.HOUR_OF_DAY, 1);
  413.             cal.set(java.util.Calendar.MINUTE, 0);
  414.             cal.set(java.util.Calendar.SECOND, 0);
  415.             cal.set(java.util.Calendar.MILLISECOND, 0);
  416.             this.selectedDay = cal.getTime().getTime();
  417.         }
  418.         
  419.         private void setMonth(int year, int month) {
  420.             java.util.Calendar cal = java.util.Calendar.getInstance();
  421.             cal.setTimeZone(TimeZone.getDefault());
  422.             cal.set(java.util.Calendar.MONTH, month);
  423.             cal.set(java.util.Calendar.DAY_OF_MONTH, 1);
  424.             cal.set(java.util.Calendar.YEAR, year);
  425.             Date date = cal.getTime();
  426.             long d = date.getTime();
  427.             // if this is past the last day of the month (e.g. going from January 31st
  428.             // to Febuary) we need to decrement the day until the month is correct
  429.             while (cal.get(java.util.Calendar.MONTH) != month) {
  430.                 d -= DAY;
  431.                 cal.setTime(new Date(d));
  432.             }
  433.             setCurrentDay(d);
  434.         }
  435.         public void decrementMonth() {
  436.             int month = getMonth();
  437.             month--;
  438.             int year = getYear();
  439.             if (month < java.util.Calendar.JANUARY) {
  440.                 month = java.util.Calendar.DECEMBER;
  441.                 year--;
  442.             }
  443.             setMonth(year, month);
  444.         }
  445.         public int getYear() {
  446.             java.util.Calendar cal = java.util.Calendar.getInstance();
  447.             cal.setTime(new Date(currentDay));
  448.             return cal.get(java.util.Calendar.YEAR);
  449.         }
  450.         public void addActionListener(ActionListener l) {
  451.             dispatcher.addListener(l);
  452.         }
  453.         public void removeActionListener(ActionListener l) {
  454.             dispatcher.removeListener(l);
  455.         }
  456.         /**
  457.          * Allows tracking selection changes in the calendar in real time
  458.          * 
  459.          * @param l listener to add
  460.          */
  461.         public void addDataChangeListener(DataChangedListener l) {
  462.             dataChangeListeners.addListener(l);
  463.         }
  464.         /**
  465.          * Allows tracking selection changes in the calendar in real time
  466.          * 
  467.          * @param l listener to remove
  468.          */
  469.         public void removeDataChangeListener(DataChangedListener l) {
  470.             dataChangeListeners.removeListener(l);
  471.         }
  472.         protected void fireActionEvent() {
  473.             componentChanged();
  474.             super.fireActionEvent();
  475.             dispatcher.fireActionEvent(new ActionEvent(Calendar.this));
  476.         }
  477.         public void actionPerformed(ActionEvent evt) {
  478.             Object src = evt.getSource();
  479.             if (src == incrementMonth) {
  480.                 incrementMonth();
  481.                 dataChangeListeners.fireDataChangeEvent(-1, DataChangedListener.CHANGED);
  482.                 componentChanged();
  483.                 return;
  484.             }
  485.             if (src == decrementMonth) {
  486.                 decrementMonth();
  487.                 dataChangeListeners.fireDataChangeEvent(-1, DataChangedListener.CHANGED);
  488.                 componentChanged();
  489.                 return;
  490.             }
  491.             for (int iter = 0; iter < buttons.length; iter++) {
  492.                 if (src == buttons[iter]) { 
  493.                     selected.setUnselectedStyle(new Style(buttons[iter].getUnselectedStyle()));
  494.                     buttons[iter].setUnselectedStyle(new Style(selectedStyle));
  495.                     selectedDay = dates[iter];
  496.                     selected = buttons[iter];
  497.                     fireActionEvent();
  498.                     if (!getComponentForm().isSingleFocusMode()) {
  499.                         setHandlesInput(false);
  500.                     }
  501.                     return;
  502.                 }
  503.             }
  504.         }
  505.         
  506.     }
  507. }