2015年12月18日
一、课程题目
一个万年历系统,实现以下功能
(1)可以查看当前的年份、月份和日期;
(2)有时间栏,便于用户查看当前时间;
(3)能够查找1至9999年的日期与星期的关系。
其它功能可自行开发。
二、题目分析与设计
1.使用的开发环境为 eclipse
Jdk环境: jdk1.8
2.
(此为万年历界面图)
使用了 jTabbedPane 类 对功能页面分页,布局策略基本用BorderLayout 和GridLayout 。
3. 本项共有5个类,基本一个功能有一个类实现,主类 CalendarMain 只包含一个main函数:对创建框架和其属性设置。
AlarmDemo类 则实现闹钟功能;NoteBook 类实现记事本功能;CalendarsView 类 则实现基本日历功能,ChooseDay 类 是一个弹窗,被CalendarsView 调用,CalendarsView 、AlarmDemo 也在该类被调用;
CalendarMain -----运行
.
new CalendarsView();
CalendarsView
总的框架界面设计布局,日历功能的实现,对其他功能的调用
new AlarmDemo(); new NoteBook();
AlarmDemo
继承Jpanel ,运用线程 和applet 实现闹钟功能,到规定时间播放闹铃
NoteBook
继承Jpanel ,运用io ,可以保存文本
newChooseDay(null, year, month).setVisible(true);
ChooseDay
继承 JDialog ,让用户选择看那一年月的日历
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.java
import 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));
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);
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();
} else
JOptionPane.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.java
import 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){
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) {
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;
else
return 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 {
@Override
public 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.java
import 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 .java
import 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.java
import javax.swing.JFrame;
public class CalendarMain {
public static void main(String[] args) {
CalendarsView frame = new CalendarsView();
frame.setTitle("万年历");
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}