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

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

使用Decorator模式實(shí)現(xiàn)日期選擇組件(3)

2019-11-18 12:18:11
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

  基本的selector接口
  日期選擇類的核心是Date_selector_panel.仔細(xì)分析后,首先做了一些如下變量聲明,不要被"常量初始化"語(yǔ)法擲出。(以為括號(hào)中的代碼是靜態(tài)的,和其他沒(méi)有任何聯(lián)系.)實(shí)例初始化聲名使用this的結(jié)構(gòu)避免了在構(gòu)造器中連接另一個(gè)構(gòu)造器。他們提供了保證在每個(gè)構(gòu)造器都能有效調(diào)用的初始化方法。同時(shí)在一個(gè)地方給出所有的初始化代碼也是非常方便的。散布在各個(gè)地方的沒(méi)有初始化的變量很輕易引起運(yùn)行錯(cuò)誤。當(dāng)移動(dòng)代碼到構(gòu)造器中也是非常困難的,因?yàn)橐苿?dòng)過(guò)程中你必須考慮你已經(jīng)改變的2個(gè)地方。比如說(shuō),在下面日歷聲明中代碼就是實(shí)例初始化:
    public class Date_selector_panel extends JPanel implements Date_selector
  {
   //這些字符串應(yīng)該應(yīng)該在資源包中,因此它們是國(guó)際化的。  
      PRivate String[] months =
    {  "Jan","Feb", "Mar","Apr", "May","June",
      "July","Aug","Sept","Oct","Nov","Dec"
    };
  
    private static final int DAYS_IN_WEEK = 7, // 一個(gè) 星期的天數(shù)
    MAX_WEEKS  = 6; // 在一月中最大的//星期數(shù)。
    // 用戶選擇的日期
  private Date selected = null;
  
    private Calendar calendar = Calendar.getInstance();
    {  calendar.set( Calendar.HOUR,  0 );
      calendar.set( Calendar.MINUTE, 0 );
      calendar.set( Calendar.SECOND, 0 );
    }
  
    //顯示在屏幕上的當(dāng)前日期
    private final Calendar today = Calendar.getInstance();
  
  下面便開(kāi)始處理點(diǎn)擊不同天的事件。我采用比較輕易實(shí)現(xiàn)的外觀即將天天都以一個(gè)標(biāo)簽是日期的按紐顯示在屏幕上,我定義了一個(gè)簡(jiǎn)單的監(jiān)聽(tīng)對(duì)象并加載到每個(gè)按紐中。由監(jiān)聽(tīng)對(duì)象獲取按紐標(biāo)簽值,由標(biāo)簽值可以得到日期與日歷的位置,然后它將從日歷中獲取日期對(duì)象并且將日期字符串發(fā)送給監(jiān)聽(tīng)器(通過(guò)調(diào)用fire_ActionEvent()的方式)。
  //一個(gè)監(jiān)聽(tīng)器適合所有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() );
        }
      }
    }
  }
  
  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) );
  }
  
  
  
  //在面板顯示前調(diào)用addNotify()。它實(shí)際上創(chuàng)建了基本的圖象對(duì)象,因此你可以調(diào)用super.addNotify()去調(diào)用面板。
  [code]//這里使用它是一個(gè)入口去發(fā)送初始化ActionEvent到支持標(biāo)題的任何實(shí)體。
  public void addNotify()
  {
    super.addNotify();
    int month = calendar.get(Calendar.MONTH);
    int year = calendar.get(Calendar.YEAR);
    fire_ActionEvent( CHANGE_ACTION, months[month] + " " + year );
  }[/code]
    然后我創(chuàng)建并初始化了代表天的按紐數(shù)組。有趣的是,日歷并不能用二維數(shù)組表示,于是,我把按紐放在GridLayout布局中,讓布局治理器來(lái)獲取他的狀態(tài)。在線形數(shù)組中在Grid中的第一個(gè)按鈕表示第一周的第一天;第八個(gè)按紐是第二周的第一天;等等。下面是代碼 :
  
  [code]--");
      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
    }
  }[/code]
  然后便是構(gòu)造器。主要工作都在這沒(méi)有參數(shù)的構(gòu)造器中。它創(chuàng)建了包含日歷的面板,建立了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();
  }
  
    全部代碼清單還含有少量的的方便組件,使用他們比用當(dāng)前日期能更好的初始化日歷。在這里我沒(méi)有談到。
  在Date_selector_panel中最值得說(shuō)的是update_calendar_display()方法,當(dāng)改變?nèi)諝v的時(shí)候該方法更新顯示的日歷。我使用java.util.Calendar()方法來(lái)判定星期日與月初的偏移量并在這些按鈕上設(shè)置空字符串的標(biāo)簽。最后我將用空字符串來(lái)填寫表示月末的按鈕標(biāo)簽。
  通過(guò)這種方式,你看到的每個(gè)按都在改變,即使它代表的是當(dāng)前月中的無(wú)效天。這里并不需要用代碼實(shí)現(xiàn) ,因?yàn)楫?dāng)你 將按鈕放入GridLayout中,布局便會(huì)自動(dòng)列出你放入的按鈕。
  [code]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
    // a

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 邳州市| 博罗县| 抚远县| 石柱| 佛冈县| 遂川县| 新田县| 金平| 汾阳市| 巧家县| 呼伦贝尔市| 孟村| 屯昌县| 金川县| 信宜市| 长沙县| 沂源县| 吉隆县| 隆回县| 冕宁县| 耒阳市| 峨眉山市| 牙克石市| 中方县| 平武县| 遵化市| 宜川县| 诸城市| 九江县| 潜江市| 得荣县| 天峨县| 牟定县| 巴南区| 龙山县| 大埔区| 藁城市| 龙口市| 龙口市| 扬州市| 页游|