HomeDigital EditionSys-Con RadioSearch Java Cd
Advanced Java AWT Book Reviews/Excerpts Client Server Corba Editorials Embedded Java Enterprise Java IDE's Industry Watch Integration Interviews Java Applet Java & Databases Java & Web Services Java Fundamentals Java Native Interface Java Servlets Java Beans J2ME Libraries .NET Object Orientation Observations/IMHO Product Reviews Scalability & Performance Security Server Side Source Code Straight Talking Swing Threads Using Java with others Wireless XML
 

"JCalendar"
Volume: 4 Issue: 3, p. 30

Download files assoicated with this article

	

Listing 1.
 
public interface CalendarRenderer 
{ 
  public Component getCalendarRendererComponent( 
    JComponent parent, Object value, 
    boolean isSelected, boolean hasFocus); 
  public Color getBackdrop(); 
} 
  

Listing 2.
 
public class DefaultCalendarRenderer extends JLabel 
  implements CalendarRenderer 
{ 
  private boolean isHeader = false; 

    private static final Border raised = 
    new ThinBorder(ThinBorder.RAISED); 
  private static final Border lowered = 
    new ThinBorder(ThinBorder.LOWERED); 

  public DefaultCalendarRenderer(boolean isHeader) 
  { 
    setOpaque(true); 
    setBorder(raised); 
    setVerticalAlignment(JLabel.TOP); 
    setHorizontalAlignment( 
      isHeader ? JLabel.CENTER : JLabel.LEFT); 
    setPreferredSize(new Dimension(19, 18)); 
    setMinimumSize(new Dimension(19, 18)); 
    this.isHeader = isHeader; 
  } 

   public Color getBackdrop() 
  { 
    return Color.lightGray; 
  } 

    public Component getCalendarRendererComponent( 
    JComponent parent, Object value, 
    boolean isSelected, boolean hasFocus) 
  { 
    setText(value.toString()); 
    if (isSelected) 
    { 
      setBorder(lowered); 
      setBackground( 
        hasFocus ? Color.blue : Color.lightGray); 
      setForeground( 
        hasFocus ? Color.white : Color.black); 
    } 
    else 
    { 
      setBorder(raised); 
      setBackground(isHeader ? 
        Color.gray : Color.lightGray); 
      setForeground(Color.black); 
    } 
    return this; 
  } 
} 
  

Listing 3.
 
public class SimpleCalendarRenderer extends JLabel 
  implements CalendarRenderer 
{ 
  private boolean hasFocus = false; 
  private boolean isSelected = false; 
  private boolean isHeader = false; 

  public SimpleCalendarRenderer(boolean isHeader) 
  { 
    setOpaque(true); 
    setBorder(null); 
    setVerticalAlignment(JLabel.TOP); 
    setHorizontalAlignment(JLabel.CENTER); 
    setPreferredSize(new Dimension(19, 18)); 
    setMinimumSize(new Dimension(19, 18)); 
    this.isHeader = isHeader; 
  } 

    public Color getBackdrop() 
  { 
    return Color.white; 
  } 

    public Component getCalendarRendererComponent( 
    JComponent parent, Object value, 
    boolean isSelected, boolean hasFocus) 
  { 
    this.hasFocus = hasFocus; 
    this.isSelected = isSelected; 
    setText(value.toString()); 
    if (isSelected) 
    { 
      setBackground(Color.blue); 
      setForeground(Color.white); 
    } 
    else 
    { 
      setBackground(Color.white); 
      setForeground(Color.black); 
    } 
    return this; 
  } 

    public void paintComponent(Graphics g) 
  { 
    super.paintComponent(g); 
    int w = getSize().width; 
    int h = getSize().height; 
    if (!isHeader && hasFocus & isSelected) 
      { 
g.setColor(Color.white); 
      BasicGraphicsUtils.drawDashedRect( 
        g, 0, 0, w, h); 
    } 
    if (isHeader) g.drawLine(0, h - 1, w, h - 1); 
  } 
} 
  

Listing 4.
 
public class CalendarMonth extends JPanel 
  implements MouseListener, MouseMotionListener, 
    KeyListener, FocusListener 
{ 
  public static final String ACTION_ENTER = “Enter”; 
  public static final String ACTION_CLICK = “Click”; 
  public static final String ACTION_NEXT = “Next”; 
  public static final String ACTION_PREV = “Prev”; 

    protected Vector listeners = new Vector(); 
  protected boolean hasFocus = false; 
  protected CellRendererPane renderPane = 
    new CellRendererPane(); 

    protected CalendarRenderer renderer; 
  protected ListSelectionModel selector; 
  protected CalendarGroup group; 

      private static final int daysInMonth[] = 
    {31,28,31,30,31,30,31,31,30,31,30,31}; 

      protected Calendar date = Calendar.getInstance(); 
  protected double xunit = 0, yunit = 0; 
  protected int first, days; 
  protected boolean active = true; 
  public CalendarMonth(Calendar date, 
    ListSelectionModel selector, 
    CalendarRenderer renderer, 
    CalendarGroup group) 
  { 
    this.group = group; 
    this.selector = selector; 
    this.renderer = renderer; 
    group.add(this); 
    setLayout(new BorderLayout()); 
    add(BorderLayout.CENTER, renderPane); 
    addMouseMotionListener(this); 
    addMouseListener(this); 
    addFocusListener(this); 
    addKeyListener(this); 
    setDate(date); 
  } 

  public void setDay(int day) 
  { 
    selector.setSelectionInterval(day, day); 
    date.set(Calendar.DAY_OF_MONTH, day); 
  } 

  public void setMonth(int month) 
  { 
    date.set(Calendar.MONTH, month); 
    setDate(date); 
  } 
  public void setYear(int year) 
  { 
    date.set(Calendar.YEAR, year); 
    setDate(date); 
  } 

  public void setDate(Calendar date) 
  { 
    this.date = date; 
    Calendar temp = (Calendar)date.clone(); 
    temp.set(Calendar.DAY_OF_MONTH, 1); 
    first = temp.get(Calendar.DAY_OF_WEEK) - 1; 
    int current = date.get(Calendar.DAY_OF_MONTH); 
    selector.setSelectionInterval(current, current); 
    days = daysInMonth[date.get(Calendar.MONTH)]; 
    if (isLeapYear(date.get(Calendar.YEAR)) && 
      date.get(Calendar.MONTH) == 1) days = 29; 
  } 

  public Calendar getDate() 
  { 
    return date; 
  } 

    public void nextMonth() 
  { 
    date.add(Calendar.MONTH, 1); 
    setDate(date); 
    fireActionEvent(ACTION_NEXT); 
  } 

  public void prevMonth() 
  { 
    date.add(Calendar.MONTH, -1); 
    setDate(date);  
    fireActionEvent(ACTION_PREV); 
  } 

  public void setFirstDay() 
  { 
    setDay(1); 
  } 

   public void setLastDay() 
  { 
    setDay(days); 
  } 

   public void setActive(boolean active) 
  { 
    this.active = active; 
  } 

  public void paintComponent(Graphics g) 
  { 
    xunit = getSize().width / 7; 
    yunit = getSize().height / 6; 
    g.setColor(renderer.getBackdrop()); 
    g.fillRect(0, 0, getSize().width, getSize().height); 

       int day = 1; 
    for (int y = 0; y < 6; y++) 
    { 
      for (int x = 0; x < 7; x ++) 
      { 
        if (isValidDay(x, y)) 
        { 
          drawCell(g, 
            (int)(x * xunit), (int)(y * yunit), 
            (int)xunit, (int)yunit, 
            “” + day, isSelected(day)); 
          day++; 
        } 
      } 
    } 
  } 

  protected boolean isSelected(int day) 
  { 
    if (!active) return false; 
    return selector.isSelectedIndex(day); 
  } 
  protected boolean isValidDay(int x, int y) 
  { 
    int day = (x + y * 7) - first; 
    return (y == 0 && x >= first) || (y > 0 && day < days); 
  } 

  protected void drawCell(Graphics g, int x, int y, 
    int w, int h, String text, boolean isSelected) 
  { 
    Component render = 
renderer.getCalendarRendererComponent( 
        this, text, isSelected, hasFocus); 
    renderPane.paintComponent(g, render, this, x, y, w, h); 
  } 

  protected boolean isLeapYear(int year) 
  { 
    return ((year % 4 == 0) && 
      ((year % 100 != 0) || (year % 400 == 0))); 
  } 

  public Dimension getPreferredSize() 
  { 
    Dimension dimension =  
((Component)renderer).getPreferredSize(); 
    int width = dimension.width * 7; 
    int height = dimension.height * 6; 
    return new Dimension(width, height); 
  } 

  public Dimension getMinimumSize() 
  { 
    Dimension dimension =  
((Component)renderer).getMinimumSize(); 
    int width = dimension.width * 7; 
    int height = dimension.height * 6; 
    return new Dimension(width, height); 
  } 

  public void mouseClicked(MouseEvent event) {} 
  public void mouseReleased(MouseEvent event) {} 
  public void mouseEntered(MouseEvent event) {} 
  public void mouseExited(MouseEvent event) {} 
  public void mousePressed(MouseEvent event) 
  { 
    if (!hasFocus()) 
    { 
      requestFocus(); 
      group.setActiveMonth(this); 
    } 
    int x = (int)(event.getX() / xunit); 
    int y = (int)(event.getY() / yunit); 
    if (!isValidDay(x, y)) return; 
    int day = x + y * 7 - first + 1; 
    if (event.isShiftDown() || event.isControlDown()) 
    { 
      selector.setLeadSelectionIndex(day); 
      repaint(); 
    } 
    else 
    { 
      setDay(day); 
      repaint(); 
    } 
    fireActionEvent(ACTION_CLICK); 
  } 

    public void mouseMoved(MouseEvent event) {} 
  public void mouseDragged(MouseEvent event) 
  { 
    int x = (int)(event.getX() / xunit); 
    int y = (int)(event.getY() / yunit); 
    if (!isValidDay(x, y)) return; 
    int day = x + y * 7 - first + 1; 
    selector.setLeadSelectionIndex(day); 
    repaint(); 
  } 

   public void keyTyped(KeyEvent event) {} 
  public void keyReleased(KeyEvent event) {} 
  public void keyPressed(KeyEvent event) 
  { 
    if (!active) return; 
    int key = event.getKeyCode(); 
    if (key == KeyEvent.VK_ENTER) 
    { 
      fireActionEvent(ACTION_ENTER); 
    } 
    if (key == KeyEvent.VK_HOME) 
    { 
      setFirstDay(); 
      repaint(); 
    } 
    if (key == KeyEvent.VK_END) 
    { 
      setLastDay(); 
      repaint(); 
    } 
    if (key == KeyEvent.VK_PAGE_DOWN) 
    { 
      group.prevMonth(true); 
    } 
    if (key == KeyEvent.VK_PAGE_UP) 
    { 
      group.nextMonth(true); 
    } 
    int anchor = selector.getAnchorSelectionIndex(); 
    int lead = selector.getLeadSelectionIndex(); 
    if (key == KeyEvent.VK_RIGHT) 
    { 
      if (event.isShiftDown() || event.isControlDown()) 
      { 
        if (lead < days) 
        { 
          selector.setLeadSelectionIndex(lead + 1); 
          repaint(); 
        } 
      } 
      else if (anchor < days) 
      { 
        setDay(anchor + 1); 
        repaint(); 
      } 
      else if (anchor == days) 
      { 
        if (group.isLastCalendarMonth(this)) 
        { 
          group.nextMonth(true); 
          setLastDay(); 
          repaint(); 
        } 
        else 
        { 
          CalendarMonth next = 
           group.nextCalendarMonth(); 
          next.setFirstDay(); 
          next.repaint(); 
          repaint(); 
        } 
      } 
    } 
    if (key == KeyEvent.VK_LEFT) 
    { 
      if (event.isShiftDown() || event.isControlDown()) 
      { 
        if (lead > 1) 
        { 
          selector.setLeadSelectionIndex(lead - 1); 
          repaint(); 
        } 
      } 
      else if (anchor > 1) 
      { 
        setDay(anchor - 1); 
        repaint(); 
      } 
      else if (anchor == 1) 
      { 
        if (group.isFirstCalendarMonth(this)) 
        { 
          group.prevMonth(true); 
          setFirstDay(); 
          repaint(); 
        } 
        else 
        { 
          CalendarMonth prev = 
            group.prevCalendarMonth(); 
          prev.setLastDay(); 
          prev.repaint(); 
          repaint(); 
        } 
      } 
    } 
    if (key == KeyEvent.VK_UP) 
    { 
      if (event.isShiftDown() || event.isControlDown()) 
      { 
        if (lead > 7) 
        { 
          selector.setLeadSelectionIndex(lead - 7); 
          repaint(); 
        } 
      } 
      else if (anchor > 7) 
      { 
        setDay(anchor - 7); 
        repaint(); 
      } 
    } 
    if (key == KeyEvent.VK_DOWN) 
    { 
      if (event.isShiftDown() || event.isControlDown()) 
      { 
        if (lead <= (days - 7)) 
        { 
          selector.setLeadSelectionIndex(lead + 7); 
          repaint(); 
        } 
      } 
      else if (anchor <= (days - 7)) 
      { 
        setDay(anchor + 7); 
        repaint(); 
      } 
    } 
  } 

  public void focusGained(FocusEvent event) 
  { 
    hasFocus = true; 
    repaint(); 
  } 

  public void focusLost(FocusEvent event) 
  { 
    hasFocus = false; 
    repaint(); 
  } 

  public boolean isFocusTraversable() 
  { 
    return active; 
  } 

    public void addActionListener(ActionListener listener) 
  { 
    listeners.addElement(listener); 
  } 

      public void removeActionListener(ActionListener listener) 
  { 
    listeners.removeElement(listener); 
  } 

  public void fireActionEvent(String command) 
  { 
    ActionListener listener; 
    Vector list = (Vector)listeners.clone(); 
    ActionEvent event = new ActionEvent(this, 
    ActionEvent.ACTION_PERFORMED, command); 
    for (int i = 0; i < list.size(); i++) 
    { 
      listener = ((ActionListener)list.elementAt(i)); 
      listener.actionPerformed(event); 
    } 
  } 
} 
  

Listing 5.
 
public class ArrowButton extends BasicArrowButton 
{ 
  public ArrowButton(int direction) 
  { 
    super(direction); 
  } 

  public void paint(Graphics g) 
  { 
    Color origColor; 
    boolean isPressed, isEnabled; 
    int w, h, size; 

    w = getSize().width; 
    h = getSize().height; 
    origColor = g.getColor(); 
    isPressed = getModel().isPressed(); 
    isEnabled = isEnabled(); 

    g.setColor(getBackground()); 
    g.fillRect(1, 1, w-2, h-2); 

    /// Draw the proper Border 
    if (isPressed) 
    { 
g.setColor(UIManager.getColor(“controlShadow”)); 
      g.drawRect(0, 0, w-1, h-1); 
    } 
    else 
    { 
g.setColor(UIManager.getColor(“controlLtHighlight”)); 
      g.drawLine(0, 0, 0, h-1); 
      g.drawLine(1, 0, w-2, 0); 

g.setColor(UIManager.getColor(“controlShadow”)); 
      g.drawLine(0, h-1, w-1, h-1); 
      g.drawLine(w-1, h-1, w-1, 0); 
    } 

    // If there’s no room to draw arrow, bail 
    if(h < 5 || w < 5) 
    { 
      g.setColor(origColor); 
      return; 
    } 

    if (isPressed) 
    { 
      g.translate(1, 1); 
    } 

    // Draw the arrow 
    size = Math.min((h - 4) / 3, (w - 4) / 3); 
    size = Math.max(size, 2); 
    paintTriangle(g, (w - size) / 2, (h - size) / 2, 
      size, direction, isEnabled); 

    // Reset the Graphics back to it’s original settings 
    if (isPressed) 
    { 
      g.translate(-1, -1); 
    } 
    g.setColor(origColor); 
  } 
} 
  

Listing 6.
 
public class ThinBorder implements Border 
{ 
  public static final int RAISED  = 0; 
  public static final int LOWERED = 1; 
  public static final int thickness = 1; 

  protected int type = RAISED; 
  protected Color highlight; 
  protected Color shadow; 

  public ThinBorder() 
  { 
    this(LOWERED, null, null); 
  } 

  public ThinBorder(int type) 
  { 
    this(type, null, null); 
  } 
  public ThinBorder(int type, 
    Color highlight, Color shadow) 
  { 
    this.type = type; 
    this.highlight = highlight; 
    this.shadow = shadow; 
    } 

  public boolean isBorderOpaque() 
  { 
    return true; 
  } 

  public Insets getBorderInsets(Component component) 
  { 
    return new Insets(thickness, thickness, thickness, thickness); 
  } 

    public Color getHightlightColor(Component c) 
  { 
    if (highlight == null) 
      highlight = c.getBackground().brighter(); 
    return highlight; 
  } 

  public Color getShadowColor(Component c) 
  { 
    if (shadow == null) 
      shadow = c.getBackground().darker(); 
    return shadow; 
  } 

  public void paintBorder(Component c, Graphics g, 
    int x, int y, int w, int h) 
  { 
    Color hi = (type == RAISED ? 
      getHightlightColor(c) : getShadowColor(c)); 
    Color lo = (type == RAISED ? 
      getShadowColor(c) : getHightlightColor(c)); 

    for (int i = thickness - 1; i >= 0; i--) 
    { 
      g.setColor(hi); 
      g.drawLine(x + i, y + i, x + w - i - 1, y + i); 
      g.drawLine(x + i, y + i, x + i, x + h - i - 1); 

      g.setColor(lo); 
      g.drawLine(x + w - i - 1, y + i, x + w - i - 1, y + h - i - 1); 
      g.drawLine(x + i, y + h - i - 1, x + w - i - 1, y + h - i - 1); 
    } 
  } 
} 
  

Listing 7.
 
public class CalendarTitle extends JLabel 
{ 
  public CalendarTitle(String text) 
  { 
    super(text); 
    setHorizontalAlignment(JLabel.CENTER); 
    setBorder(new ThinBorder(ThinBorder.RAISED)); 
  } 
} 
  

Listing 8.
 
public class CalendarHeader extends JPanel 
{ 
  protected CalendarRenderer renderer; 
  protected CellRendererPane renderPane = 
    new CellRendererPane(); 

  private static final String header[] = 
    {“S”, “M”, “T”, “W”, “T”, “F”, “S”}; 

  protected double xunit = 0, yunit = 0; 
  protected int first, days, current = 1; 

  public CalendarHeader(CalendarRenderer renderer) 
  { 
    this.renderer = renderer; 
    setLayout(new BorderLayout()); 
    add(BorderLayout.CENTER, renderPane); 
  } 

  public void paintComponent(Graphics g) 
  { 
    xunit = getSize().width / 7; 
    yunit = getSize().height; 
    for (int x = 0; x < 7; x ++) 
    { 
      drawCell(g, (int)(x * xunit), 0, 
        (int)xunit, (int)yunit, header[x], false); 
    } 
  } 

  private void drawCell(Graphics g, int x, int y, 
    int w, int h, String text, boolean selected) 
  { 
    Component render = renderer. 
      getCalendarRendererComponent( 
        this, text, selected, false); 
    renderPane.paintComponent(g, render, this, x, y, w, h); 
  } 

  public boolean isFocusTraversable() 
  { 
    return false; 
  } 

  public Dimension getPreferredSize() 
  { 
    Dimension dimension =  
((Component)renderer).getPreferredSize(); 
    int width = dimension.width * 7; 
    int height = dimension.height; 
    return new Dimension(width, height); 
  } 

  public Dimension getMinimumSize() 
  { 
    Dimension dimension =  
((Component)renderer).getMinimumSize(); 
    int width = dimension.width * 7; 
    int height = dimension.height; 
    return new Dimension(width, height); 
  } 
} 
  

Listing 9.
 
public class CalendarView extends JPanel 
  implements ActionListener 
{ 
  protected BasicArrowButton westArrow, eastArrow; 
  protected CalendarTitle title; 
  protected CalendarMonth month; 
  protected CalendarGroup group; 

  public CalendarView(Calendar date, 
    boolean west, boolean east, 
    ListSelectionModel selector, 
    CalendarRenderer headRenderer, 
    CalendarRenderer cellRenderer, 
    CalendarGroup group) 
  { 
    this.group = group; 
    setLayout(new BorderLayout()); 
    setBorder(new ThinBorder(ThinBorder.LOWERED)); 

    JPanel nav = new JPanel(); 
    nav.setLayout(new BorderLayout()); 
    nav.add(BorderLayout.CENTER,  
      title = new CalendarTitle(formatLabel(date))); 
    if (west) 
    { 
      nav.add(BorderLayout.WEST, westArrow = 
        new ArrowButton(BasicArrowButton. WEST)); 
      westArrow.addActionListener(this); 
    } 
    if (east) 
    { 
      nav.add(BorderLayout.EAST, eastArrow = 
        new ArrowButton(BasicArrowButton. EAST)); 
      eastArrow.addActionListener(this); 
    } 

    JPanel header = new JPanel(); 
    header.setLayout(new BorderLayout()); 
    header.add(BorderLayout.NORTH, nav); 
    header.add(BorderLayout.SOUTH, 
      new CalendarHeader(headRenderer)); 

    add(BorderLayout.NORTH, header); 
    add(BorderLayout.CENTER, month = new CalendarMonth( 
      date, selector, cellRenderer, group)); 
    month.addActionListener(this); 
  } 

  private String formatLabel(Calendar calendar) 
  { 
    String year = “” + calendar.get(Calendar.YEAR); 
    switch (calendar.get(Calendar.MONTH)) 
    { 
      case 0: return “January” + year; 
      case 1: return “February” + year; 
      case 2: return “March” + year; 
      case 3: return “April” + year; 
      case 4: return “May” + year; 
      case 5: return “June” + year; 
      case 6: return “July” + year; 
      case 7: return “August” + year; 
      case 8: return “September” + year; 
      case 9: return “October” + year; 
      case 10: return “November” + year; 
      default: return “December” + year; 
    } 
  } 

  public BasicArrowButton getWestArrow() 
  { 
    return westArrow; 
  } 

  public BasicArrowButton getEastArrow() 
  { 
    return eastArrow; 
  } 
  

  public void nextMonth() 
  { 
    group.nextMonth(false); 
    Calendar date = month.getDate(); 
    title.setText(formatLabel(date)); 
    repaint(); 
  } 

  public void prevMonth() 
  { 
    group.prevMonth(false); 
    Calendar date = month.getDate(); 
    title.setText(formatLabel(date)); 
    repaint(); 
  } 

  public void actionPerformed(ActionEvent event) 
  { 
    Object source = event.getSource(); 
    if (source == month) 
    { 
      Calendar date = month.getDate(); 
      title.setText(formatLabel(date)); 
      title.repaint(); 
    } 
    if (source == westArrow) 
    { 
      group.prevMonth(true); 
    } 
    if (source == eastArrow) 
    { 
      group.nextMonth(true); 
    } 
  } 
} 
  

Listing 10.
 
public class CalendarGroup 
{ 
  protected Component parent; 
  protected Vector group; 
  protected int active; 

  public CalendarGroup() 
  { 
    this(null); 
  } 

  public CalendarGroup(Component parent) 
  { 
    this.parent = parent; 
    group = new Vector(); 
    active = 0; 
  } 

  public void setParent(Component parent)  { 
    this.parent = parent; 
  } 

  public void setActiveMonth(int index) 
  { 
    if (index > group.size()) 
      throw new IndexOutOfBoundsException( 
        “Out of range CalendarGroup index”); 
    active = index; 
    for (int i = 0; i < group.size(); i++) 
    { 
      getCalendarMonth(i).setActive(i == active); 
      if (i == active) 
        getCalendarMonth(i).requestFocus(); 
    } 
  } 

    public void setActiveMonth(CalendarMonth month) 
  { 
    for (int i = 0; i < group.size(); i++) 
    { 
      if (getCalendarMonth(i) == month) 
      { 
        setActiveMonth(i); 
        parent.repaint(); 
        break; 
      } 
    } 
  } 

  public void add(CalendarMonth month) 
  { 
    group.addElement(month); 
    active = group.size() - 1; 
  } 

  public CalendarMonth getActiveMonth() 
  { 
    return getCalendarMonth(active); 
  } 

    public CalendarMonth getCalendarMonth(int index) 
  { 
    return (CalendarMonth)group.elementAt(index); 
  } 

    public CalendarMonth nextCalendarMonth() 
  { 
    active++; 
    if (active >= group.size()) active = 0; 
    setActiveMonth(active); 
    return getCalendarMonth(active); 
  } 

  public CalendarMonth prevCalendarMonth() 
  { 
    active--; 
    if (active < 0) active = group.size() - 1; 
    setActiveMonth(active); 
    return getCalendarMonth(active); 
  } 

    public boolean isFirstCalendarMonth(CalendarMonth month) 
  { 
    return month == getCalendarMonth(0); 
  } 

    public boolean isLastCalendarMonth(CalendarMonth month) 
  { 
    return month == getCalendarMonth(group.size() - 1); 
  } 

  public void nextMonth(boolean repaint) 
  { 
    for (int i = 0; i < group.size(); i++) 
    { 
      getCalendarMonth(i).nextMonth(); 
      getCalendarMonth(i).invalidate(); 
      if (repaint && parent != null) 
        parent.repaint(); 
    } 
  } 

  public void prevMonth(boolean repaint) 
  { 
    for (int i = 0; i < group.size(); i++) 
    { 
      getCalendarMonth(i).prevMonth(); 
      getCalendarMonth(i).invalidate(); 
      if (repaint && parent != null) 
        parent.repaint(); 
    } 
  } 
} 
  

Listing 11.
 
public class JCalendarField extends JPanel 
  implements ActionListener, KeyListener 
{ 
  protected DateFormat formatter = 
DateFormat.getDateInstance(DateFormat.LONG); 

    protected BasicArrowButton calendarButton; 
  protected JCalendar calendar; 
  protected JPopupMenu popup; 
  protected JTextField field; 
  protected Calendar date; 

  public JCalendarField() 
  { 
    this(Calendar.getInstance()); 
  } 

  public JCalendarField(Calendar date) 
  { 
    setLayout(new BorderLayout()); 
    add(BorderLayout.CENTER, field = new JTextField()); 
    field.setEditable(false); 
    setBorder(field.getBorder()); 
    field.setBorder(null); 

    calendarButton = 
      new BasicArrowButton(BasicArrowButton.SOUTH); 
    calendarButton.addActionListener(this); 
    add(BorderLayout.EAST, calendarButton); 

    calendar = new JCalendar(date, 1, 1, 
      new DefaultListSelectionModel(), 
      new SimpleCalendarRenderer(true), 
      new SimpleCalendarRenderer(false)); 
    calendar.addActionListener(this); 
    popup = new JPopupMenu(); 
    popup.add(calendar); 
    setField(date); 

    CalendarMonth month = 
      calendar.group.getActiveMonth(); 
    field.addKeyListener(month); 
    field.addKeyListener(this); 
  } 

  public void actionPerformed(ActionEvent event) 
  { 
    if (event.getSource() == calendarButton) 
    { 
      field.requestFocus(); 
      getRootPane().setDefaultButton(null); 
      if (!popup.isVisible()) 
      { 
        Dimension dim = calendarButton.getSize(); 
        calendar.setDate(date); 
        popup.show(calendarButton, dim.width - 
          popup.getPreferredSize().width, 
          dim.height); 
      } 
      else 
      { 
        popup.setVisible(false); 
        field.requestFocus(); 
      } 
    } 
    if (event.getSource() == calendar) 
    { 
      setField(calendar.getDate()); 
      popup.setVisible(false); 
      field.requestFocus(); 
    } 
  } 

  protected void setField(Calendar date) 
  { 
    this.date = date; 
field.setText(formatter.format(date.getTime())); 
  } 

  public void setDate(Calendar date) 
  { 
    calendar.setDate(date); 
  } 

  public Calendar getDate() 
  { 
    return calendar.getDate(); 
  } 

  public void setCalendar(JCalendar calendar) 
  { 
    this.calendar = calendar; 
  } 

  public JCalendar getCalendar() 
  { 
    return calendar; 
  } 

  public void setDateFormat(DateFormat formatter) 
  { 
    this.formatter = formatter; 
  } 

  public void keyTyped(KeyEvent event) {} 
  public void keyReleased(KeyEvent event) {} 
  public void keyPressed(KeyEvent event) 
  { 
    if (event.getKeyCode() == KeyEvent.VK_ESCAPE) 
      popup.setVisible(false); 
  } 
} 
  

Listing 12.
 
public class JCalendarField extends JPanel 
  implements ActionListener 
{ 
  protected DateFormat formatter = 
DateFormat.getDateInstance(DateFormat.LONG); 
  protected BasicArrowButton calendarButton; 
  protected JCalendar calendar; 
  protected JPopupMenu popup; 
  protected JTextField field; 
  protected Calendar date; 

  public JCalendarField() 
  { 
    this(Calendar.getInstance()); 
  } 

  public JCalendarField(Calendar date) 
  { 
    setLayout(new BorderLayout()); 
    add(BorderLayout.CENTER, field = new JTextField()); 
    field.setEditable(false); 
    setBorder(field.getBorder()); 
    field.setBorder(null); 

    calendarButton = 
      new BasicArrowButton(BasicArrowButton.SOUTH); 
    calendarButton.addActionListener(this); 
    add(BorderLayout.EAST, calendarButton); 

    calendar = new JCalendar(date, 1, 1, 
      new DefaultListSelectionModel(), 
      new SimpleCalendarRenderer(true), 
      new SimpleCalendarRenderer(false), 
      new CalendarGroup()); 
    calendar.addActionListener(this); 
    popup = new JPopupMenu(); 
    popup.add(calendar); 
    setField(date); 
  } 

  public void actionPerformed(ActionEvent event) 
  { 
    if (event.getSource() == calendarButton) 
    { 
      field.requestFocus(); 
      getRootPane().setDefaultButton(null); 
      if (!popup.isVisible()) 
      { 
        Dimension dim = calendarButton.getSize(); 
        calendar.setDate(date); 
        popup.show(calendarButton, dim.width - 
          popup.getPreferredSize().width, 
          dim.height); 
      } 
      else 
      { 

        popup.setVisible(false); 
        field.requestFocus(); 
      } 
    } 
    if (event.getSource() == calendar) 
    { 
      setField(calendar.getDate()); 
      popup.setVisible(false); 
      field.requestFocus(); 
    } 
  } 

  protected void setField(Calendar date) 
  { 
    this.date = date; 
field.setText(formatter.format(date.getTime())); 
  } 

  public void setDate(Calendar date) 
  { 
    calendar.setDate(date); 
  } 

  public Calendar getDate() 
  { 
    return calendar.getDate(); 
  } 

  public void setCalendar(JCalendar calendar) 
  { 
    this.calendar = calendar; 
  } 

  public JCalendar getCalendar() 
  { 
    return calendar; 
  } 

  public void setDateFormat(DateFormat formatter) 
  { 
    this.formatter = formatter; 
  } 
 } 
}
 

 

All Rights Reserved
Copyright ©  2004 SYS-CON Media, Inc.
  E-mail: [email protected]

Java and Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. SYS-CON Publications, Inc. is independent of Sun Microsystems, Inc.