基于java GUI实现的一个日历记事本小项目

最近刚学了gui部分的内容,练手和两个同学一起做了一个小日历,第一次做没啥经验,代码多多少少有点不规范的,各位见谅,下面浅浅讲一下思路。

代码已给出了每段比较详细的注释,整体分FirstFrame和MainFrame,first上有两个按钮,分别加监听触发退出和进入主页面

 

然后main中是整体精华所在,通过不断setText每个按钮上的文字,来达到切换时,日期自动切换的功能,然后,有年份选择和月份选择两个列表框,通过获取列表框中的内容,来设置当前应该显示的时间。

这个是mainframe的页面:

 然后本日历记事本还可以通过点击当天按钮,然后唤起一个文本框,可以输入想要记录的备忘事项,并且,当下次打开程序时,上次记录的事项可以通过文件可持续化保存,这也属于一个小功能。

整体项目分三个java文件,分别是TextBook:主要代码,TextFile:文件操作,封装在一个类中了,Start启动器

在文章底部有源码链接

下面是TextBook.java文件:

package com.tt.Textbook;

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;
import java.io.*;
import java.net.*;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

//初始页面
class FirstFrame extends JFrame
{
	public FirstFrame(){
		//container分为上下表格布局
		Container FirstContainer = this.getContentPane();
		FirstContainer.setLayout( new GridLayout(2,1) );
		
		//需要两个面板,分别是标题和退出框以及进入按钮
		Panel panel1 = new Panel( new BorderLayout() );
		Panel panel2 = new Panel( new GridLayout(1,3) );//下部分的1行3列表格布局
		Panel panel3 = new Panel( new GridLayout(2,1) );//下面中间的二层布局
		Panel panel4 = new Panel( new FlowLayout() );//下中之一
		Panel panel5 = new Panel( new FlowLayout() );//下中之二
		//导入标题图片
		ImageIcon Titleimg = new ImageIcon( "photo/title.png" );
		JLabel l1 = new JLabel();
		l1.setIcon( Titleimg );
		JLabel l2 = new JLabel();
		l2.setIcon( new ImageIcon("............") );
		JLabel l3 = new JLabel();
		l3.setIcon( new ImageIcon("............") );
		panel1.add( l1, BorderLayout.CENTER );
		//进入主页面按钮
		JButton b1 = new JButton("退出程序");
		JButton b2 = new JButton("进入主页面 ");
		panel2.add( l2 );

		panel4.add( b2 );
		panel5.add( b1 );
		
		panel3.add( panel4 );
		panel3.add( panel5 );
		
		panel2.add( panel3 );

		panel2.add( l3 );
		//container添加两个面板
		FirstContainer.add( panel1 );
		FirstContainer.add( panel2 );
		
		b1.addActionListener(new ActionListener() 
		{
			@Override
			public void actionPerformed( ActionEvent e ) {
				System.exit(0);
			}
		});
		
		b2.addActionListener(new ActionListener() //添加监听事件,点击后可以打开主Frame
		{
			@Override
			public void actionPerformed(ActionEvent e) 
			{
				new MainFrame();
				dispose();
			}
		});
		
		//一些初始化操作
		this.setVisible(true);
		this.setBounds(500,300,700,500);
		this.setTitle( "桌面记事本" );
		this.setDefaultCloseOperation( EXIT_ON_CLOSE );
		this.setResizable( false );
	}
}

//主要界面
class MainFrame extends JFrame 
{
	private String content;
	private JComboBox YearBox=new JComboBox();
	private JComboBox MonthBox=new JComboBox();
	//两个标签,在init中设置字体样式
	private  JLabel YearLabel=new JLabel("年份:");
	private  JLabel MonthLabel=new JLabel("月份:");
	//两个按钮,需要满足监听功能
	private	JButton b_ok=new JButton("确定");
	private	JButton b_today=new JButton("今天");

	//前后两个按钮
	private JButton upJButton=new JButton( new ImageIcon("photo/line_left.png"));
	private JButton downJButton=new JButton(new ImageIcon("photo/line_right.png"));
	
	//使用日期类,获取当前年份,月份,日期
	private Date date = new Date();//属于一个工具对象,对日期的操作。
	//日期类的get方法获取当前时间
	private int NowYear = date.getYear() + 1900;
	private int NowMonth = date.getMonth();
	private boolean todayFlag = false;//标志开始设置成false是因为有一个初始化
	
	private JButton[] b_week=new JButton[7];
	private	ItemButton[] b_day=new ItemButton[42];
	private String[] week= {"MON","TUE","WED","THU","FRI","SAT","SUN"};
	
	private int Month=0;
	private String Year=null;
	
	private static JLabel BeijingTime;
	private Calendar nowTime=Calendar.getInstance();
	
	private static String sday;
	
	public void init()							//初始化
	{
		Container containerMain=this.getContentPane();
		containerMain.setLayout(new BorderLayout());
		//首先进行页面布局,分为两个panel,操作panel和主日历panel
		JPanel PanelOpreater = new JPanel(new FlowLayout());
		JPanel PanelMain = new JPanel(new GridLayout(7,7,4,4));
		JPanel PanelNow = new JPanel(new FlowLayout());
		
		//可写可不写
		//container1.setLayout(new BorderLayout());
		
		//设置label字体样式
		YearLabel.setFont(new Font("Dialog",Font.BOLD,16));
		MonthLabel.setFont(new Font("Dialog",Font.BOLD,16));
		
		for(int i = NowYear - 20;i <= NowYear + 100;i++)//年份范围为前后二十年
		{
			YearBox.addItem(i+"");
		}
		YearBox.setSelectedIndex(20);//当前年份
		
		for(int i = 1; i <= 12; i++)//仅有12个月
		{
			MonthBox.addItem(i+"");
		}
		MonthBox.setSelectedIndex(NowMonth);
		
		//先把操作面板添加好按钮和标签
		PanelOpreater.add(YearLabel);
		PanelOpreater.add(YearBox);
		PanelOpreater.add(MonthLabel);
		PanelOpreater.add(MonthBox);
		PanelOpreater.add(b_ok);
		PanelOpreater.add(b_today);
		//获取当前类的监听事件,ok和today可以共用一个事件
		b_ok.addActionListener(new FindActionListener());
		b_today.addActionListener(new FindActionListener());
		
		//up和down按钮
		upJButton.addActionListener(new BesideActionListener());
		downJButton.addActionListener(new BesideActionListener());
		
		
		//对星期进行设置
		for( int i=0; i<7; i++ )
		{
			b_week[i] = new JButton( week[i] );
			if( i == 5 || i == 6 )
				b_week[i].setForeground( Color.red );
			PanelMain.add( b_week[i] );
		}
		
		//把day按钮加进去
		for(int i=0; i<42; i++)
		{
			b_day[i]=new ItemButton("");
			PanelMain.add(b_day[i]);
		}
		
		this.SetCalendar();
		
		JLabel time = new JLabel();
		time.setForeground(Color.black);
		time.setBounds(30, 0, 500, 130);
		time.setFont(new Font("微软雅黑", Font.BOLD, 30));

		final JLabel varTime = time;
		Timer timeAction = new Timer(100, new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				long timemillis = System.currentTimeMillis();
				// 转换日期显示格式
				SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				varTime.setText(df.format(new Date(timemillis)));
			}
		});
		timeAction.start();
		PanelNow.add(varTime);

        containerMain.add(PanelOpreater,BorderLayout.NORTH);
		containerMain.add(upJButton,BorderLayout.WEST);
		containerMain.add(PanelMain,BorderLayout.CENTER);
		containerMain.add(downJButton,BorderLayout.EAST);
		containerMain.add(PanelNow,BorderLayout.SOUTH);
	}
	
	public void SetCalendar()					//需要传入列表框中选中的年份,月份;然后重新设置表格内容
	{
		int SumDays=0;
		if(todayFlag)//是今天
		{
			Year=NowYear+"";
			Month=NowMonth;
		}
		else//不是今天,根据列表框中的选择
		{
			Year=YearBox.getSelectedItem().toString();//object类中,转成字符串
			Month=MonthBox.getSelectedIndex();//默认设置月份从0开始
		}
		int intYear=Integer.parseInt(Year)-1900;//将字符串转成int型
		Date FirstDay = new Date(intYear, Month, 1);
		GregorianCalendar cal = new GregorianCalendar();
		cal.setTime(FirstDay);
		int counter=1;//计数器,用来设置时间
		
		if(Month == 0||Month == 2||Month == 4||Month == 6||Month == 7||Month == 9||Month == 11)//
		{
			SumDays = 31;
		} else if(Month == 3||Month == 5||Month == 8||Month == 10) {
			SumDays = 30;
		} else {
			if( cal.isLeapYear(intYear) )    //判断闰年
			{
				SumDays = 29;
			} else {
				SumDays = 28;
			}
		}
		
		int FirstLocation=FirstDay.getDay();
		for(int i=((FirstLocation-1)+7)%7;i<((FirstLocation-1)+7)%7+SumDays;i++)
		{
			if(Month==NowMonth && intYear==NowYear-1900 && i==((FirstLocation-1)+7)%7+date.getDate()-1)
			{
				b_day[i].setForeground(Color.ORANGE);
				b_day[i].setText((counter++)+"");
			}
			else {
				b_day[i].setText((counter++) + "");
				b_day[i].setForeground(Color.black);
			}
			if(i%7==5 || i%7==6)
			{
				if(!(Month==NowMonth && intYear==NowYear-1900 && i==((FirstLocation-1)+7)%7+date.getDate()-1))
					b_day[i].setForeground(Color.red);
			}
		}
		//没有用的地方清空
		for(int i=0;i<((FirstLocation-1)+7)%7;i++)
			b_day[i].setText("");
		for(int i=((FirstLocation-1)+7)%7+SumDays;i<42;i++)
			b_day[i].setText("");
	}
	
	class ItemButton extends JButton			//按钮事件触发
	{
		public ItemButton(String name)
		{
			super();
			this.setText(name);
			this.setVisible(true);
			this.addActionListener(new ActionListener() {
				@Override
				public void actionPerformed(ActionEvent e) 
				{
					sday=e.getActionCommand();
					if( sday!="" )							//防止日期空白按钮被打开写文件
					try {
						new TextJFrame();
					} catch (IOException ioException) {
						ioException.printStackTrace();
					}
				}
			});
		}
	}

	class TextJFrame extends JFrame				//文本框frame,用来输入待办事项
	{
		public TextJFrame() throws IOException {
			this.setTitle("备忘事项");
			Container TextContainer=this.getContentPane();
			TextContainer.setLayout(new BorderLayout());

			String syear = (String) YearBox.getSelectedItem();
			String smonth = (String) MonthBox.getSelectedItem();
			String fname = null;											//用于判断的文件名字:是否存在
			if(smonth.length()<2)
			{
				if(sday.length()<2)
					fname = syear+"0"+smonth+"0"+sday;
				else
					fname = syear+"0"+smonth+sday;
			} else {
				if(sday.length()<2)
					fname = syear+smonth+"0"+sday;
				else
					fname = syear+smonth+sday;
			}
			File file = new File("src//"+fname);				//创建文档,可以根据前面传来的 key 修改文件名用于后期的读出

			if (!file.exists()) {										//原文件不存在, 需要新建文件
				file.createNewFile();
				content=null;
				System.out.println("文件已创建");
			} else {													//原文件存在, 可以直接打开 并 续写
				content = TextFile.read("src//"+fname);	    //已经获取文件内容
				System.out.println("文件已存在");
			}

			TextField textMain=new TextField(content);					//文本框所在
			textMain.addActionListener(new TextActionListener() );		//添加监听事件

			//使用一个返回按钮
			JButton ret=new JButton("返回按钮");
			ret.addActionListener(new ActionListener() {

				@Override
				public void actionPerformed(ActionEvent e) {
					dispose();
				}
			});
			TextContainer.add(textMain,BorderLayout.CENTER);
			TextContainer.add(ret,BorderLayout.SOUTH);
			//文本窗口的一些初始化工作

			this.setVisible(true);
			this.setBounds(500, 300, 700 ,500 );
			this.setResizable(false);
		}
	}

	class FindActionListener implements ActionListener
	{
			//监听ok和today的事件
			@Override
			public void actionPerformed(ActionEvent e) 
			{
				
				//点击通过判断todayflag,true就返回当天,列表框中的内容变化就变成false然后跳转,用到Date类中的函数
				//跳转时,要调用一个SetCalendar函数
				if(e.getSource()==b_ok)
				{
					todayFlag=false;
					SetCalendar();//跳转操作
				}
				if(e.getSource()==b_today)
				{
					todayFlag=true;//先设置成true然后通过SetCalendar方法跳转
					//刷新列表框中的初始值
					YearBox.setSelectedIndex(20);
					MonthBox.setSelectedIndex(NowMonth);
					SetCalendar();
				}
			}
	}

	class BesideActionListener implements ActionListener//侧翼双栏的控制
	{
		@Override
		public void actionPerformed(ActionEvent e) 
		{
			if(e.getSource()==upJButton)
			{
				int monthb=MonthBox.getSelectedIndex();
				int year = YearBox.getSelectedIndex();
				if( monthb - 1 != -1) {
					MonthBox.setSelectedIndex(monthb - 1);
					todayFlag = false;
					SetCalendar();
				}
				else {
					MonthBox.setSelectedIndex(11);
					YearBox.setSelectedIndex(year-1);
					todayFlag = false;
					SetCalendar();
				}
			}
			else 
				if(e.getSource()==downJButton)
			{
				int monthb=MonthBox.getSelectedIndex();
				int year = YearBox.getSelectedIndex();
				if( monthb + 1 != 12) {
					MonthBox.setSelectedIndex(monthb + 1);
					todayFlag = false;
					SetCalendar();
				}
				else {
					MonthBox.setSelectedIndex(0);
					YearBox.setSelectedIndex(year+1);
					todayFlag = false;
					SetCalendar();
				}
			}
		}
		
	}
	
	class TextActionListener implements ActionListener//内部监听类
	{

		@Override
		public void actionPerformed(ActionEvent e) 						//在这之前先判断同名文件是否存在,如果存在则读出,不存在则新建
		{																//新建文件存储在src文件夹内
			String syear=(String) YearBox.getSelectedItem();
			String smonth=(String) MonthBox.getSelectedItem();
			String fname=null;
			if(smonth.length()<2)
			{
				if(sday.length()<2)
					fname=syear+"0"+smonth+"0"+sday;
				else
					fname=syear+"0"+smonth+sday;
			} else {
				if(sday.length()<2)
					fname=syear+smonth+"0"+sday;
				else
					fname=syear+smonth+sday;
			}
			TextField field=(TextField)e.getSource();						//获得一些资源
			TextFile.write( "src//" + fname, field.getText() );	//将 field 中的内容写入 data.txt
			//				例子测试
			//				public static void main(String[] args) {
			//					String file = read("e:\\data\\data3.txt");			//读出文件
			//					System.out.println(file);							//输出到控制台
			//					write("e:\\data\\data5.txt",file);					//写入到 xx 文件
			//
			//					TextFile text = new TextFile("e:\\data\\data3.txt");		//读出/文件到 TextFile
			//					System.out.println(text);									//输出
			//					text.write("e:\\data\\data6.txt");							//将 TextFile 写入到 xx 路径的文件
			//				}
			//				System.out.println(	field.getText());
			//				field.setText("");
		}
	}
	
	public MainFrame()
	{
		this.init();

		//此处也可以把初始化封装在一个init方法里
		this.setTitle("日历");
		this.setVisible(true);
		this.setBounds(500, 300, 700 ,500 );
		this.setResizable(false);
		this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
		this.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				int result = JOptionPane.showConfirmDialog(null, "确认退出?", "确认", 							JOptionPane.OK_CANCEL_OPTION, JOptionPane.INFORMATION_MESSAGE);
				if(result == JOptionPane.OK_OPTION){
					System.exit(0);
				}
			}
		});
	}
}

 因为是第一次做的项目,所以肯定有很多地方不足的,非常欢迎大家指出问题,一起讨论

 点此查看完整项目源码

计算机科学与技术本科专业 Java课程设计任务书 题目: 日历记事本 学生姓名: 学号: 班级: 题目类型:软件工程(R) 指导教师: 一. 题目简介 该设计要求设计一个带有日程提醒功能的日历。 通过该题目的设计,培养学生面向对象程序设计的思想,要求学生达到熟练掌握Java语言的基本知识和技能,基本掌握面向对象程序设计的基本思路和方法,能够利用所学的基本知识和技能,解决简单的面向对象程序设计问题。同时强调好的程序设计风格,提高解决实际问题的能力。 二. 主要任务 1、查阅文献资料,一般在5篇以上; 2、应用系统分析,建立该系统的功能模块框图以及界面的组织和设计; 3、分析系统中的各个实体及它们之间的关系包括属性和方法; 4、根据问题描述,设计系统的类层次; 5、完成类层次中各个类的描述(包括属性和方法); 6、完成类中各个成员函数的定义; 7、完成系统的应用模块; 8、完成系统的软件开发和测试工作; 9、撰写设计说明书; 10、做好答辩工作。 三. 主要内容、功能及技术指标 (一) 基本要求: 编写一个Applet小应用程序能够显示时间,当用户最小化Applet时,程序会 被挂起,当还原Applet时,程序又会恢复执行,同时Applet中应显示挂起和恢复的时间。 (二)系统要求: 1、要求利用面向对象的方法以及Java的编程思想来完成系统的设计; 2、要求在设计的过程中,建立清晰的类层次; 3、在系统设计中要分析和定义各个类,每个类中要有各自的属性和方法; 4、在系统的设计中,要求运用面向对象的机制(继承、派生及多态性)来实现系统功能。 5、该系统的要求: (1)显示信息:用户可以向前翻页查询前一个月的日期,也可以向后翻页查询下一个月的日期。 (2)定时提醒:用户可以针对某一天来添加,删除和编辑这一天的日程提醒信息,当系统时间和提醒时间相吻合时,给出具有提示信息的对话框; (3)查询信息:用户可以查询到某个月的所有提示信息。 四. 提交的成果 1. 设计说明书一份,内容包括: 1) 中文摘要100字;关键词3-5个; 2) 序言; 3) 基本要求实现(包括程序流程图;部分代码;) 4) 系统要求实现 系统分析与设计(包括设计系统的类层次,各个实体及它们之间的关系) 详细设计(包括各个类的详细设计,如数据成员及成员函数的设计); 系统测试(包含测试方案、测试用例、测试结果及软件可靠性分析); 软件使用说明书(核心界面说明); 5)设计总结、参考文献、致谢等。 五. 主要参考文献 [1]曲朝阳,杨杰明等.Java程序设计. 北京: 清华大学出版社,2008.10 [2]耿祥以,张跃平.Java大学生实用教程. 北京: 电子工业出版社,2012.6 [3]明日科技.Java经典编程.北京:清华大学出版社,2012.10 [4]李尊朝,苏军.Java语言程序设计.北京:中国铁道出版社,2004.2 [5]王博. 面向对象的建模、设计技术与方法. 北京希望电脑公司,1990. 六. 各阶段时间安排(共2周): 周次 日期 内容 地点 第1周 星期一 教师讲解设计要求,准备参考资料 教室 星期二 分析系统,方案设计 实验室 星期三~五 编程 实验室 第2周 星期一~三 编程、调试程序 实验室 星期四 写设计书 实验室 星期五 答辩 实验室
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值