编写具有图形用户界面(GUI)的日历组件显示日期和时间并进行适当的功能扩充。 主要功能: 1、显示当月日历,当前日期、当前时间; 2、可查询任意月以及任意年的日历; 3、正常运行和退出程序。 4、每日具有记账功能,需要至少包含1)记账id;2)记账类型;2)支出费用;3)关键字(关键字写为一行,关键字数量不限,使用分号分割<需查阅使用>) 5、能够通过关键字查询某一种类型的记账记录。 6、对当月记账类型的汇总;对特定关键字的记账汇总。

时间: 2024-03-13 12:47:20 浏览: 21
好的,下面是一个基于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,电影;音乐会 ``` 希望这个程序能够满足您的需求!

相关推荐

最新推荐

recommend-type

grpcio-1.63.0-cp38-cp38-linux_armv7l.whl

Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
recommend-type

SQLyog-13.1.3-0.x86Community.exe

SQLyog-13.1.3-0.x86Community
recommend-type

VB自动出题题库系统设计(源代码+系统).rar

计算机专业毕业设计VB精品论文资源
recommend-type

debugpy-1.0.0b2-cp35-cp35m-manylinux1_i686.whl

Python库是一组预先编写的代码模块,旨在帮助开发者实现特定的编程任务,无需从零开始编写代码。这些库可以包括各种功能,如数学运算、文件操作、数据分析和网络编程等。Python社区提供了大量的第三方库,如NumPy、Pandas和Requests,极大地丰富了Python的应用领域,从数据科学到Web开发。Python库的丰富性是Python成为最受欢迎的编程语言之一的关键原因之一。这些库不仅为初学者提供了快速入门的途径,而且为经验丰富的开发者提供了强大的工具,以高效率、高质量地完成复杂任务。例如,Matplotlib和Seaborn库在数据可视化领域内非常受欢迎,它们提供了广泛的工具和技术,可以创建高度定制化的图表和图形,帮助数据科学家和分析师在数据探索和结果展示中更有效地传达信息。
recommend-type

实战自学python如何成为大佬(目录):https://blog.csdn.net/weixin-67859959/artic

实战自学python如何成为大佬(目录):https://blog.csdn.net/weixin-67859959/artic
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

MATLAB柱状图在信号处理中的应用:可视化信号特征和频谱分析

![matlab画柱状图](https://img-blog.csdnimg.cn/3f32348f1c9c4481a6f5931993732f97.png) # 1. MATLAB柱状图概述** MATLAB柱状图是一种图形化工具,用于可视化数据中不同类别或组的分布情况。它通过绘制垂直条形来表示每个类别或组中的数据值。柱状图在信号处理中广泛用于可视化信号特征和进行频谱分析。 柱状图的优点在于其简单易懂,能够直观地展示数据分布。在信号处理中,柱状图可以帮助工程师识别信号中的模式、趋势和异常情况,从而为信号分析和处理提供有价值的见解。 # 2. 柱状图在信号处理中的应用 柱状图在信号处理
recommend-type

用Spring boot和vue写一个登录注册界面

好的,这是一个比较常见的技术问题,我可以为您提供一些参考资料和思路。首先,您可以使用Spring Boot作为后端框架来处理用户认证和注册的逻辑,比如使用Spring Security实现用户登录认证。同时,您还需要设计相应的数据模型和数据库表结构来存储用户信息。在前端方面,您可以使用Vue.js作为框架来构建登录注册页面,使用Axios来发起API请求并和后端进行交互。当然,在实现过程中,还需要考虑一些具体细节,比如数据校验、安全性和用户体验等方面。希望这些信息能够帮助到您。
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。