国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

解決日期選擇問題,一勞永逸(使用Decorator模式實現日期選擇組件)(三)

2019-11-18 16:25:45
字體:
來源:轉載
供稿:網友
基本的selector接口
  
  日期選擇類的核心是Date_selector_panel.仔細分析后,首先做了一些如下變量聲明,不要被"常量初始化"語法擲出。(以為括號中的代碼是靜態的,和其他沒有任何聯系.)實例初始化聲名使用this的結構避免了在構造器中連接另一個構造器。他們提供了保證在每個構造器都能有效調用的初始化方法。同時在一個地方給出所有的初始化代碼也是非常方便的。散布在各個地方的沒有初始化的變量很容易引起運行錯誤。當移動代碼到構造器中也是非常困難的,因為移動過程中你必須考慮你已經改變的2個地方。比如說,在下面日歷聲明中代碼就是實例初始化:
   public class Date_selector_panel extends JPanel implements Date_selector
{
//這些字符串應該應該在資源包中,因此它們是國際化的。    
        PRivate String[] months =
    {   "Jan","Feb", "Mar","Apr", "May","June",
        "July","Aug","Sept","Oct","Nov","Dec"
    };

    private static final int DAYS_IN_WEEK = 7,  // 一個 星期的天數
   MAX_WEEKS    = 6;  // 在一月中最大的//星期數。
    // 用戶選擇的日期
private Date selected = null;

    private Calendar calendar = Calendar.getInstance();
    {   calendar.set( Calendar.HOUR,    0 );
        calendar.set( Calendar.MINUTE,  0 );
        calendar.set( Calendar.SECOND,  0 );
    }

    //顯示在屏幕上的當前日期
    private final Calendar today = Calendar.getInstance();

下面便開始處理點擊不同天的事件。我采用比較容易實現的外觀即將每天都以一個標簽是日期的按紐顯示在屏幕上,我定義了一個簡單的監聽對象并加載到每個按紐中。由監聽對象獲取按紐標簽值,由標簽值可以得到日期與日歷的位置,然后它將從日歷中獲取日期對象并且將日期字符串發送給監聽器(通過調用fire_ActionEvent()的方式)。
//一個監聽器適合所有calendar事件
private final Button_handler day_listener  = new Button_handler();

private class Button_handler implements ActionListener
{   public void actionPerformed(ActionEvent e)
    {
        if (e.getActionCommand().equals("D"))
        {   String text = ((JButton) e.getSource()).getText();

            if(text.length() > 0)  //  <=0 means click on blank square. Ignore.
            {   calendar.set
                (   calendar.get(Calendar.YEAR),    // Reset the calendar
                    calendar.get(Calendar.MONTH),   // to be the chosen
                    Integer.parseInt(text)          // date.
                );
                selected = calendar.getTime();
                fire_ActionEvent( SELECT_ACTION, selected.toString() );
            }
        }
    }
}

     java的AWTEventMulticaster 類實現了動作監聽。這種實現在我提供的文檔(一篇關于multicasters的文章列在 Resources <http://www.javaworld.com/javaworld/jw-07-2003/>.)中敘述的比較清楚。
private ActionListener subscribers = null;
public synchronized void addActionListener(ActionListener l)
{   subscribers = AWTEventMulticaster.add(subscribers, l);
}
public synchronized void removeActionListener(ActionListener l)
{   subscribers = AWTEventMulticaster.remove(subscribers, l);
}
private void fire_ActionEvent( int id, String command )
{   if (subscribers != null)
         subscribers.actionPerformed(new ActionEvent(this, id, command) );
}


//在面板顯示前調用addNotify()。它實際上創建了基本的圖象對象,因此你可以調用super.addNotify()去調用面板。
//這里使用它是一個入口去發送初始化ActionEvent到支持標題的任何實體。
public void addNotify()
{
    super.addNotify();
    int month = calendar.get(Calendar.MONTH);
    int year  = calendar.get(Calendar.YEAR);
    fire_ActionEvent( CHANGE_ACTION, months[month] + " " + year );
}

    然后我創建并初始化了代表天的按紐數組。有趣的是,日歷并不能用二維數組表示,于是,我把按紐放在GridLayout布局中,讓布局管理器來獲取他的狀態。在線形數組中在Grid中的第一個按鈕表示第一周的第一天;第八個按紐是第二周的第一天;等等。下面是代碼 :

--");
        days[i] = day;
        day.setBorder (BorderFactory.createEmptyBorder(1,2,1,2));
         day.setFocusPainted (false);   // Cannot get focus
        day.setActionCommand    ("D");
        day.addActionListener   (day_listener);// Our single listener
        day.setOpaque (false);                  
  // Transparent background
    }
}

然后便是構造器。主要工作都在這沒有參數的構造器中。它創建了包含日歷的面板,建立了gridlayout布局,并將按紐加入到布局中:

public Date_selector_panel()
{
    JPanel calendar_display = new JPanel();
    calendar_display.setOpaque(false);
    calendar_display.setBorder( BorderFactory.createEmptyBorder(5,3,0,1) );
    calendar_display.setLayout(new GridLayout(MAX_WEEKS /*rows*/, DAYS_IN_WEEK /*columns*/ ));

    for( int i = 0; i <  days.length; ++i )
        calendar_display.add(days[i]);

    setOpaque( false );
    setLayout( new BorderLayout() );
    add(calendar_display, BorderLayout.CENTER);
    update_calendar_display();
}

   全部代碼清單還含有少量的的方便組件,使用他們比用當前日期能更好的初始化日歷。在這里我沒有談到。
在Date_selector_panel中最值得說的是update_calendar_display()方法,當改變日歷的時候該方法更新顯示的日歷。我使用java.util.Calendar()方法來判斷星期日與月初的偏移量并在這些按鈕上設置空字符串的標簽。最后我將用空字符串來填寫表示月末的按鈕標簽。
通過這種方式,你看到的每個按都在改變,即使它代表的是當前月中的無效天。這里并不需要用代碼實現 ,因為當你 將按鈕放入GridLayout中,布局便會自動列出你放入的按鈕。
private void update_calendar_display()
{
    setVisible(false);  // Improves paint speed and redUCes flicker.

    clear_highlight();

    // The buttons that comprise the calendar are in a single
    // dimensioned array that was added to a 6x7 grid layout in
    // order. Because of the linear structure, it's easy to
    // lay out the calendar just by changing the labels on
    // the buttons. Here's the algorithm used below:
    //
    //  1) Find out the offset to the first day of the month.
    //  2) Clear everything up to that offset.
    //  3) Add the days of the month.
    //  4) Clear everything else.

    int month = calendar.get(Calendar.MONTH);
    int year  = calendar.get(Calendar.YEAR);

    fire_ActionEvent( CHANGE_ACTION, months[month] + " " + year );

    calendar.set( year, month, 1 ); // First day of the current month.

    int first_day_offset = calendar.get(Calendar.DAY_OF_WEEK);      /* 1 */

    assert Calendar.SUNDAY == 0;
    assert first_day_offset < days.length;

    int i = 0;
    while( i < first_day_offset-1 )                              /* 2 */
        days[i++].setText("");

    int day_of_month = 1;
    for(; i < days.length; ++i )                                 /* 3 */
    {
        if( calendar.get(Calendar.MONTH)==today.get(Calendar.MONTH)
        &&  calendar.get(Calendar.YEAR )==today.get(Calendar.YEAR )
        &&  calendar.get(Calendar.DATE )==today.get(Calendar.DATE ) )
        {   highlight( days[i] );
        }

        days[i].setText( String.valueOf(day_of_month) );

        calendar.roll( Calendar.DATE, /*up=*/ true );   // Forward one day.

        day_of_month = calendar.get(Calendar.DATE);
        if( day_of_month == 1 )
            break;
    }

    // Note that we break out of the previous loop with i positioned
    // at the last day we added, thus the following ++ *must* be a
    // preincrement because we want to start clearing at the cell
    // after that.

    while( ++i < days.length )                                 /* 4 */
        days[i].setText("");

    setVisible(true);
}

private JButton highlighted = null;
private void clear_highlight()
{
    if( highlighted != null )
    {   highlighted.setBackground( Color.WHITE );
        highlighted.setForeground( Color.BLACK );
        highlighted.setOpaque(false);
        highlighted = null;
    }
}

private void highlight( JButton cell )
{
    highlighted = cell;
    cell.setBackground( com.holub.ui.Colors.DARK_RED );
    cell.setForeground( Color.WHITE );
    cell.setOpaque( true );
}

    類的其他部分定義了獲取calendar值的幾種方法。都是些非常簡單的,在這里就沒有列出來。

ealy ,java 愛好者,Matrix jsp翻譯小組成員,可以點擊http://www.matrix.org.cn/user_view.asp?username=ealy查看她的個人信息 
進入討論組討論。

(出處:http://m.survivalescaperooms.com)



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 涪陵区| 房产| 广昌县| 壤塘县| 通化市| 江城| 收藏| 崇文区| 衡阳县| 望江县| 梁山县| 福鼎市| 英吉沙县| 如皋市| 石渠县| 苍南县| 娄烦县| 华亭县| 孟连| 奉贤区| 耒阳市| 来安县| 洞口县| 宁城县| 姜堰市| 大连市| 东兰县| 民乐县| 蓝田县| 乐清市| 忻城县| 礼泉县| 安岳县| 清水河县| 长阳| 吉隆县| 高要市| 麟游县| 许昌县| 牙克石市| 乌什县|