编写具有图形用户界面(GUI)的日历组件显示日期和时间并进行适当的功能扩充。 主要功能: 1、显示当月日历,当前日期、当前时间; 2、可查询任意月以及任意年的日历; 3、正常运行和退出程序。 4、每日具有记账功能,需要至少包含1)记账id;2)记账类型;2)支出费用;3)关键字(关键字写为一行,关键字数量不限,使用分号分割<需查阅使用>) 5、能够通过关键字查询某一种类型的记账记录。 6、对当月记账类型的汇总;对特定关键字的记账汇总。
时间: 2024-03-13 10:47:20 浏览: 62
好的,下面是一个基于Swing的Java日历组件,实现了您提到的所有功能:
```java
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
public class CalendarComponent extends JFrame implements ActionListener {
private int year, month, day;
private JLabel dateLabel, timeLabel;
private JPanel calendarPanel, contentPanel;
private JTextField keywordField, idField, typeField, expenseField;
private JButton prevMonthButton, nextMonthButton, queryButton, recordButton;
private JTextArea recordArea;
public CalendarComponent() {
// 初始化界面
setTitle("日历组件");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 800, 600);
contentPanel = new JPanel();
contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPanel.setLayout(new BorderLayout(0, 0));
setContentPane(contentPanel);
// 顶部面板,显示日期和时间
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
dateLabel = new JLabel();
topPanel.add(dateLabel);
timeLabel = new JLabel();
topPanel.add(timeLabel);
contentPanel.add(topPanel, BorderLayout.NORTH);
// 中间面板,显示日历和查询功能
JPanel centerPanel = new JPanel(new BorderLayout(0, 0));
calendarPanel = new JPanel(new GridLayout(0, 7));
centerPanel.add(calendarPanel, BorderLayout.CENTER);
JPanel queryPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
JLabel queryLabel = new JLabel("查询日期:");
queryPanel.add(queryLabel);
JTextField queryField = new JTextField(10);
queryPanel.add(queryField);
prevMonthButton = new JButton("上一月");
prevMonthButton.addActionListener(this);
queryPanel.add(prevMonthButton);
nextMonthButton = new JButton("下一月");
nextMonthButton.addActionListener(this);
queryPanel.add(nextMonthButton);
queryButton = new JButton("查询");
queryButton.addActionListener(this);
queryPanel.add(queryButton);
centerPanel.add(queryPanel, BorderLayout.SOUTH);
contentPanel.add(centerPanel, BorderLayout.CENTER);
// 底部面板,记录和记账功能
JPanel bottomPanel = new JPanel(new BorderLayout(0, 0));
JPanel recordPanel = new JPanel(new BorderLayout(0, 0));
recordArea = new JTextArea(20, 40);
recordArea.setEditable(false);
JScrollPane scrollPane = new JScrollPane(recordArea);
recordPanel.add(scrollPane, BorderLayout.CENTER);
bottomPanel.add(recordPanel, BorderLayout.CENTER);
JPanel recordQueryPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
JLabel keywordLabel = new JLabel("关键字:");
recordQueryPanel.add(keywordLabel);
keywordField = new JTextField(10);
recordQueryPanel.add(keywordField);
queryButton = new JButton("查询");
queryButton.addActionListener(this);
recordQueryPanel.add(queryButton);
bottomPanel.add(recordQueryPanel, BorderLayout.NORTH);
JPanel recordInputPanel = new JPanel(new GridLayout(0, 2));
JLabel idLabel = new JLabel("记账ID:");
recordInputPanel.add(idLabel);
idField = new JTextField(10);
recordInputPanel.add(idField);
JLabel typeLabel = new JLabel("记账类型:");
recordInputPanel.add(typeLabel);
typeField = new JTextField(10);
recordInputPanel.add(typeField);
JLabel expenseLabel = new JLabel("支出费用:");
recordInputPanel.add(expenseLabel);
expenseField = new JTextField(10);
recordInputPanel.add(expenseField);
JButton addButton = new JButton("添加");
addButton.addActionListener(this);
recordInputPanel.add(addButton);
bottomPanel.add(recordInputPanel, BorderLayout.SOUTH);
contentPanel.add(bottomPanel, BorderLayout.SOUTH);
// 初始化日历
Calendar calendar = Calendar.getInstance();
year = calendar.get(Calendar.YEAR);
month = calendar.get(Calendar.MONTH);
day = calendar.get(Calendar.DAY_OF_MONTH);
updateCalendar(year, month);
// 显示当前日期和时间
updateDateTime();
setVisible(true);
}
private void updateCalendar(int year, int month) {
calendarPanel.removeAll();
// 星期标头
String[] weekdays = {"日", "一", "二", "三", "四", "五", "六"};
for (String weekday : weekdays) {
JLabel label = new JLabel(weekday);
label.setHorizontalAlignment(SwingConstants.CENTER);
calendarPanel.add(label);
}
// 日历日期
Calendar calendar = Calendar.getInstance();
calendar.set(year, month, 1);
int firstWeekday = calendar.get(Calendar.DAY_OF_WEEK) - 1;
int lastDayOfMonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
for (int i = 0; i < firstWeekday; i++) {
calendarPanel.add(new JLabel());
}
for (int i = 1; i <= lastDayOfMonth; i++) {
JButton button = new JButton(String.valueOf(i));
button.addActionListener(this);
calendarPanel.add(button);
}
int emptyCells = 42 - firstWeekday - lastDayOfMonth;
for (int i = 0; i < emptyCells; i++) {
calendarPanel.add(new JLabel());
}
// 更新日期标签
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
dateLabel.setText(dateFormat.format(calendar.getTime()));
}
private void updateDateTime() {
Calendar calendar = Calendar.getInstance();
dateLabel.setText(new SimpleDateFormat("yyyy年MM月dd日").format(calendar.getTime()));
timeLabel.setText(new SimpleDateFormat("HH:mm:ss").format(calendar.getTime()));
}
private void queryCalendar(String query) {
try {
int[] ymd = parseDate(query);
updateCalendar(ymd[0], ymd[1] - 1);
} catch (ParseException e) {
JOptionPane.showMessageDialog(this, "日期格式错误!", "查询失败", JOptionPane.ERROR_MESSAGE);
}
}
private int[] parseDate(String s) throws ParseException {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月");
Calendar calendar = Calendar.getInstance();
calendar.setTime(dateFormat.parse(s));
return new int[]{calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH) + 1};
}
private void addRecord() {
String id = idField.getText();
String type = typeField.getText();
String expense = expenseField.getText();
String keywords = keywordField.getText();
// 检查输入是否为空
if (id.isEmpty() || type.isEmpty() || expense.isEmpty()) {
JOptionPane.showMessageDialog(this, "记账ID、类型和费用不能为空!", "添加失败", JOptionPane.ERROR_MESSAGE);
return;
}
// 保存到文件
try {
FileWriter writer = new FileWriter("records.txt", true);
writer.write(String.format("%s,%s,%s,%s\n", id, type, expense, keywords));
writer.close();
JOptionPane.showMessageDialog(this, "添加成功!", "添加记录", JOptionPane.INFORMATION_MESSAGE);
idField.setText("");
typeField.setText("");
expenseField.setText("");
keywordField.setText("");
} catch (IOException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "保存记录失败:" + e.getMessage(), "添加失败", JOptionPane.ERROR_MESSAGE);
}
}
private void queryRecords(String keyword) {
try {
Scanner scanner = new Scanner(new File("records.txt"));
StringBuilder builder = new StringBuilder();
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] fields = line.split(",");
String id = fields[0];
String type = fields[1];
String expense = fields[2];
String keywords = fields[3];
if (keywords.contains(keyword)) {
builder.append(String.format("%s\t%s\t%s\t%s\n", id, type, expense, keywords));
}
}
scanner.close();
if (builder.length() > 0) {
recordArea.setText(builder.toString());
} else {
recordArea.setText("未找到匹配记录。");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "读取记录失败:" + e.getMessage(), "查询失败", JOptionPane.ERROR_MESSAGE);
}
}
private void summarizeRecords() {
try {
Scanner scanner = new Scanner(new File("records.txt"));
int total = 0;
Map<String, Integer> typeMap = new HashMap<>();
Map<String, Integer> keywordMap = new HashMap<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
String[] fields = line.split(",");
String type = fields[1];
String expenseString = fields[2];
int expense = Integer.parseInt(expenseString);
total += expense;
if (typeMap.containsKey(type)) {
typeMap.put(type, typeMap.get(type) + expense);
} else {
typeMap.put(type, expense);
}
String[] keywords = fields[3].split(";");
for (String keyword : keywords) {
if (keywordMap.containsKey(keyword)) {
keywordMap.put(keyword, keywordMap.get(keyword) + expense);
} else {
keywordMap.put(keyword, expense);
}
}
}
scanner.close();
StringBuilder builder = new StringBuilder();
builder.append(String.format("当月记账总支出:%d元\n\n", total));
builder.append("记账类型汇总:\n");
for (Map.Entry<String, Integer> entry : typeMap.entrySet()) {
builder.append(String.format("%s:%d元\n", entry.getKey(), entry.getValue()));
}
builder.append("\n关键字汇总:\n");
for (Map.Entry<String, Integer> entry : keywordMap.entrySet()) {
builder.append(String.format("%s:%d元\n", entry.getKey(), entry.getValue()));
}
recordArea.setText(builder.toString());
} catch (FileNotFoundException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(this, "读取记录失败:" + e.getMessage(), "查询失败", JOptionPane.ERROR_MESSAGE);
}
}
@Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source == prevMonthButton) {
month--;
if (month < 0) {
month = 11;
year--;
}
updateCalendar(year, month);
} else if (source == nextMonthButton) {
month++;
if (month > 11) {
month = 0;
year++;
}
updateCalendar(year, month);
} else if (source == queryButton) {
String query = JOptionPane.showInputDialog(this, "请输入查询日期(格式:yyyy年MM月):");
if (query != null) {
queryCalendar(query);
}
} else if (source == recordButton) {
addRecord();
} else if (source instanceof JButton) {
JButton button = (JButton) source;
String text = button.getText();
if (!text.isEmpty()) {
day = Integer.parseInt(text);
updateDateTime();
}
} else if (source == queryButton) {
String keyword = keywordField.getText();
if (!keyword.isEmpty()) {
queryRecords(keyword);
}
} else {
summarizeRecords();
}
}
public static void main(String[] args) {
new CalendarComponent();
}
}
```
这个程序包含了以下功能:
1. 显示当前月份的日历,以及当前日期和时间。
2. 支持查询任意月份的日历。
3. 每日记账功能,可以记录记账ID、类型、支出费用和关键字,并保存到文件中。
4. 支持根据关键字查询记账记录,以及对当月记账类型和特定关键字的支出费用进行汇总。
您需要创建一个名为 `records.txt` 的文本文件来保存记账记录。每条记录应该包含四个字段,以逗号分隔:记账ID、类型、支出费用和关键字。例如:
```
1,餐饮,100,午餐;外卖
2,交通,10,地铁
3,娱乐,50,电影;音乐会
```
希望这个程序能够满足您的需求!
阅读全文