CalenderNote

用Java实现日历记事本

1. 实验目的

掌握RandomAccessFile类的使用;掌握字符输入、输出流和缓冲输入、输出流的使用。

2. 实验要求

实验前,应事先熟悉相关知识点,拟出相应的实验操作步骤,明确实验目的和要求;实验过程中,服从实验指导教师安排,遵守实验室的各项规章制度,爱护实验仪器设备;实验操作完成后,认真书写实验报告,总结实验经验,分析实验过程中出现的问题。

3. 实验内容

编程实现日历记事本。具体要求如下:

(1)该日历可以通过在文本框中输入年份和月份设置日期,也可按年前后翻动,用鼠标左键单击“上年”和“下年”按钮,将当前日历的年份减一和加一。还可以在某年内按月前后翻动,用鼠标左键单击“上月”和“下月”按钮,将日历的月份减一和加一。

(2)左键单击日历上的日期,可以通过右侧的记事本(文本区)编辑有关日志,并将日志保存到一个文件,该文件的名字是由当前日期组成的字符序列。用户可以读取、删除某个日期的日志,也可以继续向某个日志添加新的内容。在保存、删除和读取日志时都会先弹出一个确认对话框,以确认保存、删除和读取操作。

(3)当某个日期有日志时,该日期以粗体16号字显示,表明这个日期有日志;当用户删除某个日期的日志后,该日期恢复原来的外观。

实现效果图(参考)如下:

提示:(1)组件调用public void setFont(Fontf)方法可以设置组件上的字体,Font类的构造方法为:public Font(Stringname,intstyle,intsize),其中name是字体的名字,style决定字体的样式(如Font.BOLD表示粗体)size决定字体的大小。(具体请参考JDK API)

(2)当左键单击日历上的日期时,如要获取该日期,可通过处理该组件上的鼠标事件来实现。

4. 实验步骤、实施过程、关键代码、实验结果及分析说明等

代码(半成品,没有添加监听事件):

package CalendarNote;

import java.awt.*;
import java.util.Calendar;
import java.io.*;
import javax.swing.*;

public class CalendarNotebook extends JFrame {

    JButton prevYearBtn, nextYearBtn, prevMonthBtn, nextMonthBtn, saveBtn, deleteBtn, readBtn;
    JTextField yearField, monthField, date;
    JTextArea textArea;
    JPanel northPanel, southPanel, leftPanel, rightPanel;
    String clickDay;
    Calendar ca = Calendar.getInstance();

    public CalendarNotebook() {
        //基本设置
        setVisible(true);
        //setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocation(400, 200); // 设置窗口位置
        setSize(700, 500);
        setLayout(new BorderLayout(10, 15)); // 东西南北中布局:水平间距(horizontal)10,垂直间距(vertical)15。
        setResizable(false); // 窗口大小不可变


        JPanel centerPanel = new JPanel(); // 创建一个中心面板
        centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.X_AXIS)); // 设置中心面板的布局为盒子布局,横向排列
        northPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 15, 10)); // 创建一个北部面板,使用流式布局,居中对齐,水平间距为15,垂直间距为10
        southPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10)); // 创建一个南部面板,使用流式布局,居中对齐,水平间距为10,垂直间距为10
        leftPanel = new JPanel(new GridLayout(7, 7)); // 创建一个左部面板,使用表格布局,7行7列
        rightPanel = new JPanel(); // 创建一个右部面板
        rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.Y_AXIS)); // 设置右部面板的布局为盒子布局,纵向排列
        Font font = new Font("黑体", Font.BOLD, 16); // 创建一个字体对象

        yearField = new JTextField(6); // 创建一个文本框,设置初始宽度为6个字符
        yearField.setPreferredSize(new Dimension(76, 26)); // 设置文本框的首选大小为宽度76,高度26
        yearField.setText(String.valueOf(ca.get(Calendar.YEAR))); // 设置文本框的文本为当前年份(2023),ca.get(Calendar.YEAR):2023(java.lang.Integer)
        yearField.setEditable(false); // 设置文本框不可编辑
        yearField.setBackground(Color.white); // 设置文本框的背景颜色为白色

        prevYearBtn = new JButton("上年"); // 创建一个“上年”按钮
        prevYearBtn.setFont(font); // 设置“上年”按钮的字体为指定的字体
        nextYearBtn = new JButton("下年"); // 创建一个“下年”按钮
        nextYearBtn.setFont(font); // 设置“下年”按钮的字体为指定的字体

        monthField = new JTextField(6); // 创建一个文本框,设置初始宽度为6个字符
        monthField.setText(String.valueOf(ca.get(Calendar.MONTH) + 1)); // 设置文本框的文本为当前月份(加1是因为Calendar.MONTH返回的是0-11,需要加1转换为1-12)
        monthField.setPreferredSize(new Dimension(76, 26)); // 设置文本框的首选大小为宽度76,高度26
        monthField.setEditable(false); // 设置文本框不可编辑
        monthField.setBackground(Color.white); // 设置文本框的背景颜色为白色


        nextMonthBtn = new JButton("下月"); // 创建一个“下月”按钮
        nextMonthBtn.setFont(font); // 设置“下月”按钮的字体为指定的字体
        prevMonthBtn = new JButton("上月"); // 创建一个“上月”按钮
        prevMonthBtn.setFont(font); // 设置“上月”按钮的字体为指定的字体

        northPanel.add(prevYearBtn);
        northPanel.add(yearField);
        northPanel.add(nextYearBtn);
        northPanel.add(prevMonthBtn);
        northPanel.add(monthField);
        northPanel.add(nextMonthBtn);

        // 添加左边的日历面板
        int today = ca.get(Calendar.DAY_OF_MONTH); // 获取当前日期的天数
        clickDay = String.valueOf(today); // 将当前日期的天数转换为字符串
        week(); // 调用week方法
        Day(); // 调用Day方法
        centerPanel.add(leftPanel); // 将左部面板添加到中心面板


        // 创建一个用于间隔的空面板
        JPanel splitPanel = new JPanel(); // 创建一个面板作为间隔
        splitPanel.setPreferredSize(new Dimension(10, 10)); // 设置间隔面板的首选大小为宽度10,高度10
        centerPanel.add(splitPanel); // 将间隔面板添加到中心面板
        date = new JTextField(10); // 创建一个文本框用于显示日期
        date.setFont(font); // 设置文本框的字体
        date.setHorizontalAlignment(JTextField.CENTER); // 设置文本在文本框中的水平对齐方式为居中
        date.setPreferredSize(new Dimension(10, 10));// 设置文本框的首选大小为宽度10,高度10
        date.setEditable(false); // 设置文本框不可编辑
        date.setText("日历:" + ca.get(Calendar.YEAR) + "年" + (ca.get(Calendar.MONTH) + 1) + "月" + today + "日"); // 设置文本框的文本为当前日期
        textArea = new JTextArea(15, 20); // 创建一个文本域,并设置行数和列数
        textArea.setFont(new Font("黑体", Font.PLAIN, 16)); // 设置文本域的字体
        textArea.setLineWrap(true); // 激活自动换行功能
        textArea.setWrapStyleWord(true); // 激活断行不断字功能
        JScrollPane scrollPane = new JScrollPane(textArea); // 创建一个滚动窗格,并将文本域放入其中
        rightPanel.add(date); // 将日期文本框添加到右部面板
        rightPanel.add(scrollPane); // 将滚动窗格添加到右部面板
        centerPanel.add(rightPanel); // 将右部面板添加到中心面板

        saveBtn = new JButton("保存日志");
        saveBtn.setFont(font);
        deleteBtn = new JButton("删除日志");
        deleteBtn.setFont(font);
        readBtn = new JButton("读取日志");
        readBtn.setFont(font);
        

        southPanel.add(saveBtn);
        southPanel.add(deleteBtn);
        southPanel.add(readBtn);

        add(northPanel, BorderLayout.NORTH); // 将northPanel添加到布局的北部
        add(centerPanel, BorderLayout.CENTER); // 将centerPanel添加到布局的中间
        add(southPanel, BorderLayout.SOUTH); // 将southPanel添加到布局的南部


    }

    public void week() {
        JButton lab1 = new JButton("一");
        JButton lab2 = new JButton("二");
        JButton lab3 = new JButton("三");
        JButton lab4 = new JButton("四");
        JButton lab5 = new JButton("五");
        JButton lab6 = new JButton("六");
        JButton lab7 = new JButton("日");
        Font font = new Font("黑体", Font.BOLD, 16);
        lab1.setFont(font);
        lab2.setFont(font);
        lab3.setFont(font);
        lab4.setFont(font);
        lab5.setFont(font);
        lab6.setFont(font);
        lab7.setFont(font);
        leftPanel.add(lab7);
        leftPanel.add(lab1);
        leftPanel.add(lab2);
        leftPanel.add(lab3);
        leftPanel.add(lab4);
        leftPanel.add(lab5);
        leftPanel.add(lab6);

    }


    public void Day() {
        int temp = 1; // 初始化临时变量temp为1
        // 获取当前月份的最大天数
        int Month_max = ca.getActualMaximum(Calendar.DATE); //  getActualMaximum():表示根据传入的字段参数获取该字段意义下的最大值
        ca.set(Calendar.DATE, 1);// 将日期设置为第一天
        int Week = ca.get(Calendar.DAY_OF_WEEK);// 获取当前月份第一天是星期几
        Font font = new Font("TimesRoman", Font.PLAIN, 16);// 创建字体对象
        for (int i = 1; i <= 42; i++) {// 遍历42次,即遍历整个日历表格的所有格子
            JButton b = new JButton();// 创建一个按钮
            b.setBackground(Color.white);// 设置按钮的背景色为白色
            b.setFont(font);// 设置按钮的字体
            if (i >= Week && i < Week + Month_max) {// 如果i在本月的日期范围内
                b.setText(Integer.toString(temp));// 设置按钮的文本为当前日期
                if (hasLog(yearField.getText(), monthField.getText(), b.getText())) {// 如果该日期有日志记录
                    b.setFont(new Font("TimesRoman", Font.BOLD, 16));// 设置按钮的字体为粗体
                } else {
                    b.setFont(font);
                }
                temp++;// 递增临时变量temp
            }
            leftPanel.add(b);// 继续下一次循环
        }
    }

    private boolean hasLog(String year, String month, String day) {
        File file = new File("F:\\日志\\" + year + "-" + month + "-" + day + ".txt"); // 构造日志文件路径
        return file.exists();// 判断日志文件是否存在
    }

    //刷新日历
    public void refreshCalendar() {
        leftPanel.removeAll();// 移除左部面板中的所有组件
        week();// 调用week()方法,重新生成星期行
        Day();// 调用Day()方法,重新生成日期格子
        leftPanel.revalidate();// 重新验证左部面板的布局
        leftPanel.repaint();// 重绘左部面板
    }
    
    public static void main(String[] args) {
        // 使用SwingUtilities的invokeLater方法,确保在事件分发线程(Event Dispatch Thread)中执行
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                // 创建一个CalendarNotebook对象
                new CalendarNotebook();
            }
        });
    }
}

5.涉及知识点

setLocationRelativeTo()方法:设置相对定位

BorderLayout(东西南北中布局)布局管理器

Java BoxLayout(盒子布局)布局管理器

Java FlowLayout(流式布局)布局管理器

Java中dimension类详解

getActualMaximum():表示根据传入的字段参数获取该字段意义下的最大值

calendar.getinstance()获取的时间作用及相关细节解析

6.免费领取源代码(成品含监听事件) 点赞关注收藏+私聊

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值