FileDocCategorySizeDatePackage
Cal.javaAPI DocExample7386Sat Nov 25 12:54:46 GMT 2000None

Cal

public class Cal extends JPanel
Bean to display a month calendar in a JPanel. Only works for the Western calendar.
author
Ian F. Darwin, ian@darwinsys.com
version
$Id: Cal.java,v 1.4 2000/11/25 17:54:47 ian Exp $

Fields Summary
protected int
yy
The currently-interesting year (not modulo 1900!)
protected int
mm
Currently-interesting month and day
protected int
dd
protected JButton[]
labs
The buttons to be displayed
protected int
leadGap
The number of day squares to leave blank at the start of this month
Calendar
calendar
A Calendar object used throughout
protected final int
thisYear
Today's year
protected final int
thisMonth
Today's month
private JButton
b0
One of the buttons. We just keep its reference for getBackground().
private JComboBox
monthChoice
The month choice
private JComboBox
yearChoice
The year choice
String[]
months
public static final int[]
dom
private int
activeDay
Constructors Summary
Cal()
Construct a Cal, starting with today.


	      	 
	 
		super();
		setYYMMDD(calendar.get(Calendar.YEAR),
			calendar.get(Calendar.MONTH),
			calendar.get(Calendar.DAY_OF_MONTH));
		buildGUI();
		recompute();
	
Cal(int year, int month, int today)
Construct a Cal, given the leading days and the total days

exception
IllegalArgumentException If year out of range

		super();
		setYYMMDD(year, month, today);
		buildGUI();
		recompute();
	
Methods Summary
private voidbuildGUI()
Build the GUI. Assumes that setYYMMDD has been called.


	          
	   
		getAccessibleContext().setAccessibleDescription(
			"Calendar not accessible yet. Sorry!");
		setBorder(BorderFactory.createEtchedBorder());

		setLayout(new BorderLayout());

		JPanel tp = new JPanel();
		tp.add(monthChoice = new JComboBox());
		for (int i=0; i<months.length; i++)
			monthChoice.addItem(months[i]);
		monthChoice.setSelectedItem(months[mm]);
		monthChoice.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				int i = monthChoice.getSelectedIndex();
				if (i>=0) {
					mm = i;
					// System.out.println("Month=" + mm);
					recompute();
				}
			}
		});
		monthChoice.getAccessibleContext().setAccessibleName("Months");
		monthChoice.getAccessibleContext().setAccessibleDescription("Choose a month of the year");

		tp.add(yearChoice = new JComboBox());
		yearChoice.setEditable(true);
		for (int i=yy-5; i<yy+5; i++)
			yearChoice.addItem(Integer.toString(i));
		yearChoice.setSelectedItem(Integer.toString(yy));
		yearChoice.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent ae) {
				int i = yearChoice.getSelectedIndex();
				if (i>=0) {
					yy = Integer.parseInt(yearChoice.getSelectedItem().toString());
					// System.out.println("Year=" + yy);
					recompute();
				}
			}
		});
		add(BorderLayout.CENTER, tp);

		JPanel bp = new JPanel();
		bp.setLayout(new GridLayout(7,7));
		labs = new JButton[6][7];	// first row is days

		bp.add(b0 = new JButton("S"));
		bp.add(new JButton("M"));
		bp.add(new JButton("T"));
		bp.add(new JButton("W"));
		bp.add(new JButton("R"));
		bp.add(new JButton("F"));
		bp.add(new JButton("S"));

		ActionListener dateSetter = new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String num = e.getActionCommand();
				if (!num.equals("")) {
					// set the current day highlighted
					setDayActive(Integer.parseInt(num));
					// When this becomes a Bean, you can
					// fire some kind of DateChanged event here.
					// Also, build a similar daySetter for day-of-week btns.
				}
			}
		};

		// Construct all the buttons, and add them.
		for (int i=0; i<6; i++)
			for (int j=0; j<7; j++) {
				bp.add(labs[i][j] = new JButton(""));
				labs[i][j].addActionListener(dateSetter);
			}

		add(BorderLayout.SOUTH, bp);
	
private voidclearDayActive()
Unset any previously highlighted day

		JButton b;

		// First un-shade the previously-selected square, if any
		if (activeDay > 0) {
			b = labs[(leadGap+activeDay-1)/7][(leadGap+activeDay-1)%7];
			b.setBackground(b0.getBackground());
			b.repaint();
			activeDay = -1;
		}
	
public booleanisLeap(int year)
isLeap() returns true if the given year is a Leap Year. "a year is a leap year if it is divisible by 4 but not by 100, except that years divisible by 400 *are* leap years." -- Kernighan & Ritchie, _The C Programming Language_, p 37.

		if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
			return true;
		return false;
	
public static voidmain(java.lang.String[] av)
For testing, a main program

		JFrame f = new JFrame("Cal");
		Container c = f.getContentPane();
		c.setLayout(new FlowLayout());

		// for this test driver, hardcode 1995/02/10.
		c.add(new Cal(1995, 2-1, 10));

		// and beside it, the current month.
		c.add(new Cal());

		f.pack();
		f.setVisible(true);
	
protected voidrecompute()
Compute which days to put where, in the Cal panel


	           
	   
		// System.out.println("Cal::recompute: " + yy + ":" + mm + ":" + dd);
		if (mm < 0 || mm > 11)
			throw new IllegalArgumentException("Month " + mm + " bad, must be 0-11");
		clearDayActive();
		calendar = new GregorianCalendar(yy, mm, dd);

		// Compute how much to leave before the first.
		// getDay() returns 0 for Sunday, which is just right.
		leadGap = new GregorianCalendar(yy, mm, 1).get(Calendar.DAY_OF_WEEK)-1;
		// System.out.println("leadGap = " + leadGap);

		int daysInMonth = dom[mm];
		if (isLeap(calendar.get(Calendar.YEAR)) && mm > 1)
			++daysInMonth;

		// Blank out the labels before 1st day of month
		for (int i = 0; i < leadGap; i++) {
			labs[0][i].setText("");
		}

		// Fill in numbers for the day of month.
		for (int i = 1; i <= daysInMonth; i++) {
			JButton b = labs[(leadGap+i-1)/7][(leadGap+i-1)%7];
			b.setText(Integer.toString(i));
		}

		// 7 days/week * up to 6 rows
		for (int i = leadGap+1+daysInMonth; i < 6*7; i++) {
			labs[(i)/7][(i)%7].setText("");
		}

		// Shade current day, only if current month
		if (thisYear == yy && mm == thisMonth)
			setDayActive(dd);		// shade the box for today

		// Say we need to be drawn on the screen
		repaint();
	
public voidsetDate(int yy, int mm, int dd)
Set the year, month, and day

		// System.out.println("Cal::setDate");
		this.yy = yy;
		this.mm = mm;		// starts at 0, like Date
		this.dd = dd;
		recompute();
	
public voidsetDayActive(int newDay)
Set just the day, on the current month


	         
	    

		clearDayActive();

		// Set the new one
		if (newDay <= 0)
			dd = new GregorianCalendar().get(Calendar.DAY_OF_MONTH);
		else
			dd = newDay;
		// Now shade the correct square
		Component square = labs[(leadGap+newDay-1)/7][(leadGap+newDay-1)%7];
		square.setBackground(Color.red);
		square.repaint();
		activeDay = newDay;
	
private voidsetYYMMDD(int year, int month, int today)

		yy = year;
		mm = month;
		dd = today;