2015年12月18日一、课程题目设计一个万年历系统,实现以下功能(1)可以查看当前的年份、月份和日期;(2)有时间栏,便于用户查看当前时间;(3)能够查找1至9999年的日期与星期的关系。
其它功能可自行开发。
二、题目分析与设计1.使用的开发环境为eclipseJdk环境:jdk1.82. (此为万年历界面图)使用了jTabbedPane 类对功能页面分页,布局策略基本用BorderLayout 和GridLayout 。
3.本项共有5个类,基本一个功能有一个类实现,主类CalendarMain只包含一个main函数:对创建框架和其属性设置。
AlarmDemo类则实现闹钟功能;NoteBook 类实现记事本功能;CalendarsView 类则实现基本日历功能,ChooseDay 类是一个弹窗,被CalendarsView 调用,CalendarsView 、AlarmDemo 也在该类被调用;.new CalendarsView();4.日历界面使用了jTable ,功能的实现逻辑则是1.首先定义两个全局变量---年和月,查看不同时间的日历,该变量也随之改变。
2.写了几个函数获取今年第一天是星期几,然后根据月份天数即可推算具体某月第一天是星期几。
3.知道一个月第一天是星期几,则该月日历既可以顺序列出。
闹钟的功能实现思路:1.获取界面设定的时间。
2.使用线程,每过一秒急救获取当前时间,并判断是否到达设定的时间3.到设定的时间,启动弹窗,播放闹铃4.闹铃科根据文件选择器自行选择记事本功能实现思路1.在项目文件夹先新建一个txt文件作为储存的数据库2.利用File 类和io 数据流将界面文本储存进txt文件,实现保存功能3.每当程序启动,读取txt文件内容并显示到界面上三、测试分析1.使用如下拓展包2.程序界面截图如下日历主界面闹钟界面记事本界面3.测试流程及功能介绍(1)点击上一月、下一月可查看不同月份日历,左下角显示当前时间。
点击蓝色的日期栏可以回到当前页(2)点击圈中按钮会出现弹框,可以调节年、月,查看指定年月日历(3)闹铃可以使用默认闹铃,也能自定义选择闹铃,不过闹铃格式只能为wav或au时间到了以后出现弹框,并响起闹铃(4)记事本输入文本,按保存即可。
(5)点击最小化按钮,可以选择普通缩小或者直接缩小到托盘.附录:源代码(注:在工程目录下新建文件夹source ,并添加了闹铃文件,txt,托盘图片,如图)AlarmDemo.javaimport java.applet.Applet;import java.applet.AudioClip;import java.awt.BorderLayout;import java.awt.Dimension;import java.awt.Font;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.File;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import javax.swing.*;import javax.swing.text.DefaultFormatterFactory;import javax.swing.text.NumberFormatter;public class AlarmDemo extends JPanel implements Runnable { private static final long serialVersionUID = -7066237267822356675L;Thread alarm;public AudioClip soumd1;Calendar c = Calendar.getInstance();JButton sure = new JButton("确定");JButton open = new JButton("可选择闹铃");JLabel jLabel = new JLabel("设置时间日-时-分", JLabel.CENTER);JLabel dayLabel = new JLabel("日", JLabel.CENTER);JLabel hourLabel = new JLabel("时", JLabel.CENTER);JLabel minuteLabel = new JLabel("分", JLabel.CENTER);JPanel jPanel1 = new JPanel();JPanel jPanel2 = new JPanel();JPanel jPanel3 = new JPanel();JPanel jPanel4 = new JPanel();JTextField music = new JTextField(System.getProperty("user.dir")+"\\source\\alarm.wav");int y = 0, m = 0, h = 0, mi = 0, d = 0;boolean fo = false;public AlarmDemo() {music.setEditable(false);// 设置标签格式dayLabel.setFont(new Font("Dialog", 1, 30));hourLabel.setFont(new Font("Dialog", 1, 30));minuteLabel.setFont(new Font("Dialog", 1, 30));jLabel.setFont(new Font("Dialog", 1, 30));//按钮设置sure.setContentAreaFilled(false);sure.setFocusPainted(false);open.setContentAreaFilled(false);open.setFocusPainted(false);JSpinner spinner1 = new JSpinner();JSpinner spinner2 = new JSpinner();JSpinner spinner3 = new JSpinner();spinner3.setModel(new SpinnerNumberModel(c.get(Calendar.DATE), 1, 31, 1));spinner1.setModel(new SpinnerNumberModel(c.get(Calendar.HOUR_OF_DAY),0, 23, 1));XXX——《Java语言》课程期末作业spinner2.setModel(new SpinnerNumberModel(c.get(Calendar.MINUTE), 0, 59,1));// 设置属性setSpinners(spinner1);setSpinners(spinner2);setSpinners(spinner3);jPanel4.add(jLabel);jPanel4.setPreferredSize(new Dimension(500, 100));jPanel1.setLayout(new GridLayout(1, 6));jPanel1.add(spinner3);jPanel1.add(dayLabel);jPanel1.add(spinner1);jPanel1.add(hourLabel);jPanel1.add(spinner2);jPanel1.add(minuteLabel);jPanel1.setPreferredSize(new Dimension(500, 100));jPanel2.setLayout(new BorderLayout());jPanel2.add(jPanel4, BorderLayout.NORTH);jPanel2.add(music, BorderLayout.CENTER);jPanel2.add(open, BorderLayout.EAST);jPanel3.setLayout(new GridLayout(1, 1));jPanel3.add(sure);setLayout(new BorderLayout());add(jPanel1, BorderLayout.NORTH);add(jPanel2, BorderLayout.CENTER);add(jPanel3, BorderLayout.SOUTH);XXX——《Java语言》课程期末作业open.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {JFileChooser fileChooser = new JFileChooser(); // 实例化文件选择器fileChooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); // 设置文件选择模式,此处为文件和目录均可fileChooser.setCurrentDirectory(new File(".")); // 设置文件选择器当前目录fileChooser.setFileFilter(new javax.swing.filechooser.FileFilter() {public boolean accept(File file) { // 可接受的文件类型String name = file.getName().toLowerCase();return name.endsWith(".wav")|| name.endsWith(".au")|| file.isDirectory();}public String getDescription() { // 文件描述return "音乐文件(*.wav,*.au)";}});if (fileChooser.showOpenDialog(AlarmDemo.this) == JFileChooser.APPROVE_OPTION) { // 弹出文件选择器,并判断是否点击了打开按钮String fileName = fileChooser.getSelectedFile().getAbsolutePath(); // 得到选择文件或目录的绝对路径music.setText(fileName);}}});sure.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent event) {if (sure.getText().equals("确定")) {try {d = (int) spinner3.getValue();h = (int) spinner1.getValue();mi = (int) spinner2.getValue();if (1 <= d && d <= 31 && 0 <= h && h <= 23 && 0 <= mi&& mi <= 59) {fo = true;jLabel.setText("设置闹钟成功");spinner1.setEnabled(false);spinner2.setEnabled(false);spinner3.setEnabled(false);start();} elseJOptionPane.showMessageDialog(null, "输入时间错误");} catch (Exception e) {JOptionPane.showMessageDialog(null, "请输入正确的时间");}} else {spinner1.setEnabled(true);spinner2.setEnabled(true);spinner3.setEnabled(true);fo = false;stop();soumd1.stop();sure.setText("确定");jLabel.setText("设置时间日-时-分");}}});}public void start() {if (alarm == null) {alarm = new Thread(this);alarm.start();}}public void stop()// 停止线程{alarm = null;}public void run() {while (true) {Date now = new Date();if (fo) {sure.setText("关闭");SimpleDateFormat ri = new SimpleDateFormat("dd"); // 封装为了获取日期SimpleDateFormat shi = new SimpleDateFormat("kk"); // 封装为了获取小时SimpleDateFormat fen = new SimpleDateFormat("mm"); // 封装为了获取分int riqi = Integer.parseInt(ri.format(now)); // 获取日期int shizhong = Integer.parseInt(shi.format(now)); // 获取小时int fenzhong = Integer.parseInt(fen.format(now)); // 获取分钟if (riqi == d && shizhong == h && fenzhong == mi) // 判断条件{try {soumd1 = Applet.newAudioClip(new File(music.getText()).toURL()); // 播放音乐soumd1.loop();fo = false;JOptionPane.showMessageDialog(null, "时间到了!!!(⊙v⊙)");} catch (Exception e) {e.printStackTrace();}}}try {Thread.sleep(1000);} catch (InterruptedException ie) {}}}public void setSpinners(JSpinner spinner) {// 设置属性JSpinner.NumberEditor editor = new JSpinner.NumberEditor(spinner, "0");spinner.setEditor(editor);JFormattedTextField textField = ((JSpinner.NumberEditor) spinner.getEditor()).getTextField();textField.setFont(new Font("Dialog", 1, 45));textField.setEditable(true);DefaultFormatterFactory factory = (DefaultFormatterFactory) textField.getFormatterFactory();NumberFormatter formatter = (NumberFormatter) factory.getDefaultFormatter();formatter.setAllowsInvalid(false);}}CalendarsView.javaimport java.awt.AWTException;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Dimension;import java.awt.Font;import java.awt.Frame;import java.awt.GridLayout;import java.awt.SystemTray;import java.awt.TrayIcon;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.io.File;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import javax.imageio.ImageIO;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTabbedPane;import javax.swing.JTable;import javax.swing.Timer;import javax.swing.table.DefaultTableModel;public class CalendarsView extends JFrame {private static final long serialVersionUID = 1L;static Calendar c = Calendar.getInstance();static int year = c.get(Calendar.YEAR);static int month = c.get(Calendar.MONTH) + 1;int monthday = 0;String[] weekdaystr = { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };Object[][] monthview = new String[6][7];JPanel dayPanel = new JPanel();JPanel panel1 = new JPanel();JPanel calPanel = new JPanel();JPanel alarmDemo = new AlarmDemo();JPanel noteBook = new NoteBook();JTabbedPane jTabbedPane = new JTabbedPane(JTabbedPane.TOP);JButton Prebutton = new JButton("上一月");JButton Nextbutton = new JButton("下一月");JButton PreYear = new JButton("上一年");JButton NextYear = new JButton("下一年");JButton Change = new JButton(c.get(Calendar.YEAR) + "年"+ (c.get(Calendar.MONTH) + 1) + "月");JLabel nowLabel = new JLabel(c.get(Calendar.YEAR) + "年"+ (c.get(Calendar.MONTH) + 1) + "月" + (c.get(Calendar.DATE)) + "日",JLabel.CENTER);JLabel timeLabel = new JLabel("---", JLabel.LEFT);DefaultTableModel model = new DefaultTableModel();JTable JTable;JScrollPane JScrollPane;TrayIcon trayIcon;//托盘图标SystemTray systemTray;//系统托盘public CalendarsView() {//托盘化systemTray = SystemTray.getSystemTray();//获得系统托盘的实例try {trayIcon = new TrayIcon(ImageIO.read(new File(System.getProperty("user.dir")+"\\source\\360.png")));}catch (IOException e1) {e1.printStackTrace();}this.addWindowListener(new WindowAdapter(){public void windowIconified(WindowEvent e){XXX——《Java语言》课程期末作业int n = JOptionPane.showConfirmDialog(null, "是否缩小到托盘?", "缩小", JOptionPane.YES_NO_OPTION);if (n == JOptionPane.YES_OPTION) {dispose();//窗口最小化时dispose该窗口try {systemTray.add(trayIcon);} catch (AWTException e1) {e1.printStackTrace();}//设置托盘的图标} else if (n == JOptionPane.NO_OPTION) {systemTray.remove(trayIcon);}}});trayIcon.addMouseListener(new MouseAdapter(){public void mouseClicked(MouseEvent e){if(e.getClickCount() == 2)//双击托盘窗口再现setExtendedState(Frame.NORMAL);setVisible(true);systemTray.remove(trayIcon);}});//时间栏Timer timer = new Timer(1000, new ActionListener() {public void actionPerformed(ActionEvent evt) {XXX——《Java语言》课程期末作业timeLabel.setText(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));}});timer.start();nowLabel.setFont(new java.awt.Font("Dialog", 1, 15));nowLabel.setForeground(Color.blue);dataOfDay();dayPanel.setLayout(new BorderLayout());dayPanel.add(nowLabel, BorderLayout.NORTH);dayPanel.add(JScrollPane, BorderLayout.CENTER);// 上方按钮panel1.setLayout(new GridLayout(1, 3));panel1.setBackground(Color.white);Prebutton.setContentAreaFilled(false);Prebutton.setFocusPainted(false);Change.setContentAreaFilled(false);Change.setFocusPainted(false);Nextbutton.setContentAreaFilled(false);Nextbutton.setFocusPainted(false);panel1.add(Prebutton);panel1.add(Change);panel1.add(Nextbutton);calPanel.setLayout(new BorderLayout());calPanel.add(panel1, BorderLayout.NORTH);calPanel.add(dayPanel, BorderLayout.CENTER);calPanel.add(timeLabel, BorderLayout.SOUTH);jTabbedPane.add(calPanel, "日历");jTabbedPane.add(alarmDemo,"闹钟");jTabbedPane.add(noteBook,"记事本");add(jTabbedPane, BorderLayout.NORTH);// 按钮监听器Prebutton.addActionListener(new PressButton());Nextbutton.addActionListener(new PressButton());Change.addMouseListener(new MouseListener() {public void mouseClicked(MouseEvent e) {if (e.getButton() == MouseEvent.BUTTON1)new ChooseDay(null, year, month).setVisible(true);dataOfDay();Change.setText(year + "年" + month + "月");}public void mousePressed(MouseEvent e) {}public void mouseReleased(MouseEvent e) {}public void mouseEntered(MouseEvent e) {}public void mouseExited(MouseEvent e) {}});nowLabel.addMouseListener(new MouseListener() {public void mouseClicked(MouseEvent e) {if (e.getButton() == MouseEvent.BUTTON1)year = c.get(Calendar.YEAR);month = c.get(Calendar.MONTH) + 1;dataOfDay();Change.setText(year + "年" + month + "月");}public void mousePressed(MouseEvent e) {}public void mouseReleased(MouseEvent e) {}public void mouseEntered(MouseEvent e) {}public void mouseExited(MouseEvent e) {}});}public void dataOfDay() {int n = 1;int k = getDays();for (int i = 0; i < 6; i++) {for (int j = 0; j < 7; j++) {if (i == 0 && j < k % 7 || n > getMonthDay(month)) {monthview[i][j] = "";} else {monthview[i][j] = String.valueOf(n);n++;}}}model.setRowCount(0);model.setDataVector(monthview, weekdaystr);JTable = new JTable(model);JTable.setGridColor(Color.gray);JTable.setBackground(Color.white);JTable.setColumnSelectionAllowed(true);// 将table中的列设置为可选择的JTable.setSelectionBackground(Color.pink);// 当选定某一天时背景颜色为粉JTable.setSelectionForeground(Color.BLUE);JTable.setFont(new Font("黑体", Font.BOLD, 24));// 日期数字字体格式JTable.setRowHeight(26);// 表格的高度JScrollPane js = new JScrollPane(JTable);// 设置大小Dimension dimension = new Dimension(500, 185);js.setPreferredSize(dimension);JScrollPane = js;}public boolean isLeapYear(int year1) // 判断是否是闰年{return ((year1 % 4 == 0 && year1 % 100 != 0) || (year1 % 400 == 0)); }public int firstDay() // 计算该年第一天是星期几{long n = year * 365;for (int i = 1; i < year; i++) {if (isLeapYear(i)) {n++;}}return (int) n % 7;}public int getMonthDay(int m) // 获取每个月的天数{switch (m) {case 1:case 3:case 5:case 7:case 8:case 10:case 12:return 31;case 4:case 6:case 9:case 11:return 30;case 2:if (isLeapYear(year))return 29;elsereturn 28;default:return 0;}}// 获取该月月第一天是星期几public int getDays() {monthday = 0;for (int i = 1; i < month; i++)monthday += getMonthDay(i);return (firstDay() + (monthday % 7)) % 7;}public class PressButton implements ActionListener { @Overridepublic void actionPerformed(ActionEvent e) {JButton button = (JButton) e.getSource();if (button == Prebutton) {month--;if (month <= 0) {year--;month += 12;}} else {month++;if (month > 12) {year++;month -= 12;}}dataOfDay();Change.setText(year + "年" + month + "月");}}}ChooseDay.javaimport java.awt.BorderLayout;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import javax.swing.JButton;import javax.swing.JDialog;import javax.swing.JFormattedTextField;import javax.swing.JPanel;import javax.swing.JSpinner;import javax.swing.SpinnerNumberModel;import javax.swing.text.DefaultFormatterFactory;import javax.swing.text.NumberFormatter;public class ChooseDay extends JDialog {private static final long serialVersionUID = -3230014153625851275L;private JButton sure = new JButton("完成");private JButton cancel = new JButton("取消");public ChooseDay(CalendarsView calendarsView, int year, int mouth) { super(calendarsView, "设置日期", true);JPanel panel1 = new JPanel();JPanel panel2 = new JPanel();JSpinner spinner1 = new JSpinner();JSpinner spinner2 = new JSpinner();spinner1.setModel(new SpinnerNumberModel(year, 0, 9999, 1));spinner2.setModel(new SpinnerNumberModel(mouth, 1, 12, 1));//设置属性setSpinners(spinner1);setSpinners(spinner2);panel1.add(spinner1);panel1.add(spinner2);sure.setContentAreaFilled(false);sure.setFocusPainted(false);cancel.setContentAreaFilled(false);cancel.setFocusPainted(false);panel2.setLayout(new GridLayout(1, 2));panel2.add(cancel);panel2.add(sure);add(panel1, BorderLayout.NORTH);add(panel2, BorderLayout.SOUTH);pack(); // 按组件天界大小setResizable(false); // 不可调节窗口大小setLocationRelativeTo(null); // 居中显示窗口sure.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent evt) {dispose();CalendarsView.year = (int) spinner1.getValue();CalendarsView.month = (int) spinner2.getValue();}});cancel.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent evt) {dispose(); // 关闭当前窗口}});}public void setSpinners(JSpinner spinner){//设置属性JSpinner.NumberEditor editor = new JSpinner.NumberEditor(spinner, "0");spinner.setEditor(editor);JFormattedTextField textField = ((JSpinner.NumberEditor) spinner.getEditor()).getTextField();textField.setFont(new java.awt.Font("Dialog", 1, 30));textField.setEditable(true);DefaultFormatterFactory factory = (DefaultFormatterFactory) textField.getFormatterFactory();NumberFormatter formatter = (NumberFormatter) factory.getDefaultFormatter();formatter.setAllowsInvalid(false);}}NoteBook .javaimport java.awt.BorderLayout;import java.awt.Color;import java.awt.Dimension;import java.awt.Font;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import javax.swing.JButton;import javax.swing.JOptionPane;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTextArea;public class NoteBook extends JPanel {private static final long serialVersionUID = 5692290911249557954L;JTextArea jTextArea = new JTextArea();JScrollPane JScrollPane = new JScrollPane(jTextArea);JButton jButton = new JButton("保存");JPanel jPanel1 = new JPanel();JPanel jPanel2 = new JPanel();public NoteBook() {open();jTextArea.setFont(new Font("宋体", 1, 15));jButton.setContentAreaFilled(false);jButton.setFocusPainted(false);JScrollPane.setVisible(true);jPanel1.setLayout(new BorderLayout());jPanel1.add(JScrollPane, BorderLayout.CENTER);jPanel1.setPreferredSize(new Dimension(500, 230));jPanel2.setLayout(new BorderLayout());jPanel2.add(jButton, BorderLayout.CENTER);this.setLayout(new BorderLayout());this.setBackground(Color.white);add(jPanel1, BorderLayout.NORTH);add(jPanel2, BorderLayout.SOUTH);jButton.addMouseListener(new MouseListener() {public void mouseClicked(MouseEvent e) {if (e.getButton() == MouseEvent.BUTTON1)save();}public void mousePressed(MouseEvent e) {}public void mouseReleased(MouseEvent e) {}public void mouseEntered(MouseEvent e) {}public void mouseExited(MouseEvent e) {}});}//打开的具体方法private void open() {try {File file = new File(System.getProperty("user.dir")+ "\\source\\note.txt");BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));byte[] b = new byte[in.available()];in.read(b, 0, b.length);jTextArea.append(new String(b, 0, b.length));in.close();}catch (IOException ex) {jTextArea.setText("Error opening ");}}// 保存具体private void save() {try {File file = new File(System.getProperty("user.dir")+ "\\source\\note.txt");BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));byte[] b = (jTextArea.getText()).getBytes();out.write(b, 0, b.length);out.close();JOptionPane.showMessageDialog(null, "保存成功");} catch (IOException ex) {jTextArea.setText("Error saving ");}}}CalendarMain.javaimport javax.swing.JFrame;public class CalendarMain {public static void main(String[] args) {CalendarsView frame = new CalendarsView();frame.setTitle("万年历");frame.setResizable(false);frame.pack();XXX——《Java语言》课程期末作业frame.setLocationRelativeTo(null);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}}。