使用 java.awt 元件建立視窗式萬年曆,包含月份、年份下拉選單、日期按鈕網格。透過 GregorianCalendar 計算每月天數與起始星期,動態更新按鈕標籤。程式碼雖使用舊版 AWT API,但邏輯清晰,適合初學者理解事件驅動與日期計算。
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class CalendarCreator extends Frame {
Button[] days = new Button[49];
Choice monthChoice = new Choice();
Choice yearChoice = new Choice();
Label lMonth = new Label("MONTH");
Label lYear = new Label("Year");
Label lText = new Label("YEAR UPTO:::");
Panel p1, p2;
GregorianCalendar gc = new GregorianCalendar();
int totDays;
TextField textField = new TextField(2);
public CalendarCreator() {
setTitle("Calendar");
setSize(400, 400);
setResizable(false);
setLocation(50, 50);
p1 = new Panel(new FlowLayout());
p2 = new Panel(new GridLayout(7, 7, 10, 10));
p1.setBackground(Color.red);
p2.setBackground(Color.cyan);
add(p1, BorderLayout.NORTH);
add(p2);
p1.add(lText); p1.add(textField);
p1.add(lMonth); p1.add(monthChoice);
String[] months = {"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"};
for (String m : months) monthChoice.add(m);
monthChoice.addItemListener(new MyListener(this));
textField.addActionListener(new MyAction(this));
p1.add(lYear); p1.add(yearChoice);
yearChoice.add("1990");
yearChoice.addItemListener(new MyListener(this));
for (int i = 0; i < 49; i++) days[i] = new Button("");
for (int c = 0; c < 49; c++) p2.add(days[c]);
setVisible(true);
}
void setYear(String newYear) {
int y = Integer.parseInt(newYear);
for (int i = 1991; i <= y; i++) yearChoice.add(String.valueOf(i));
}
void setButtons(int startDay, int totalDays) {
int idx = 7;
String[] week = {"SUN","MON","TUE","WED","THUR","FRI","SAT"};
for (int i = 0; i < 7; i++) days[i].setLabel(week[i]);
for (int i = 0; i < startDay; i++, idx++) days[idx].setLabel("");
for (int d = 1; d <= totalDays; d++, idx++) days[idx].setLabel(String.valueOf(d));
while (idx < 49) days[idx++].setLabel("");
}
void setVal(Date date, int day, int selMonth, int selYear) {
gc.setTime(date);
if (selMonth==0||selMonth==2||selMonth==4||selMonth==6||selMonth==7||selMonth==9||selMonth==11) totDays=31;
else if (selMonth==3||selMonth==5||selMonth==8||selMonth==10) totDays=30;
else if (gc.isLeapYear(selYear)) totDays=29;
else totDays=28;
setButtons(day, totDays);
}
public static void main(String[] args) { new CalendarCreator(); }
}
class MyListener implements ItemListener {
CalendarCreator cal;
MyListener(CalendarCreator c) { cal = c; }
public void itemStateChanged(ItemEvent e) {
int m = cal.monthChoice.getSelectedIndex();
int y = Integer.parseInt(cal.yearChoice.getSelectedItem()) - 1900;
Date d = new Date(y, m, 1);
cal.setVal(d, d.getDay(), m, y);
}
}
class MyAction implements ActionListener {
CalendarCreator cal;
MyAction(CalendarCreator c) { cal = c; }
public void actionPerformed(ActionEvent e) {
String s = cal.textField.getText();
cal.setYear(s);
((TextField)e.getSource()).removeActionListener(this);
}
}
改進建議:
JFrame, JComboBox, JButton) 取代 AWT,獲得更好的跨平台外觀。Date 建構子與 getDay() 已過時,建議改用 Calendar 或 java.time.YearMonth。