zoukankan      html  css  js  c++  java
  • JAVA可视化闹钟源码

    概述

    一些同学的Java课设有这样一个问题,比较感兴趣就做了一下

    功能介绍:

    1、可增加闹钟

    2、可删除闹钟

    3、时间到了响铃

    4、关闭闹钟不会丢失闹钟(因为闹钟存储在txt文件中,不会因程序关闭就终止)

    缺点

    1、没有使用多线程,闹钟响起时只能等待1分钟或者关闭程序

    2、界面设计不够美观,后期有时间会进行修改,重新设计

    3、没有闹钟修改的功能,虽然可以通过增删来达到修改的目的,但功能仍然属于空缺范围

      1 package Clock;
      2 
      3 import sun.audio.AudioPlayer;
      4 import sun.audio.AudioStream;
      5 
      6 import javax.swing.*;               //awt和swing是做界面用的类
      7 import java.awt.*;
      8 import java.awt.event.ActionEvent;
      9 import java.awt.event.ActionListener;
     10 import java.awt.event.WindowAdapter;
     11 import java.awt.event.WindowEvent;
     12 import java.io.*;                   //io流用于读写文件,包括增删闹钟、打开铃声等等
     13 import java.util.Calendar;          //用于获取当前时间的类
     14 import java.util.GregorianCalendar;//标准阳历
     15 import java.util.StringTokenizer;  //读取文件转换成计算机语言用的类
     16 /*
     17 1 计时器
     18 要求1:一个带有可视化界面的钟表。
     19 要求2:可以添加若干个闹钟。
     20 要求3:具备持久化功能,关闭程序不能丢失闹钟。
     21 要求4:闹钟是可编辑,可删除的。
     22 
     23 实现:先创建一个面板显示闹钟,面板内创建按钮增加闹钟,按钮查看闹钟,按钮删除闹钟
     24      线程间隔1s读取时间和闹钟比较
     25 
     26  */
     27 public class ClockTry extends JFrame implements Runnable {
     28     /* 成员变量 */
     29     private JPanel xx;      //总的面板
     30     private JComboBox ho;   //hour选择时间的下拉框
     31     private JComboBox mi;  //min选择分钟的下拉框
     32     private JButton tjnz;   //添加闹钟的按钮
     33     private JButton schour;    //删除闹钟的按钮
     34     private String filename = "D://homework//java//Gui//src//Clock//0.wav";     //所有的路径改这两个地方就可以了
     35     private String pathname = "D://homework//java//Gui//src//Clock//nz.txt"; // 绝对路径或相对路径都可以,写入文件时演示相对路径,读取以上路径的input.txt文件
     36 
     37     private int HOUR;       //定义HOUR用于接收按钮按下从下拉框中获取的数据
     38     private int MIN;        //同上
     39 
     40     int x = 100, y = 100, r = 100; // (x,y)为(0,0)点,表示原点
     41     int h, m, s; // 时,分,秒
     42     double rad = Math.PI / 180; //
     43 
     44     private String[][] str= new String[100][2];     //定义二维数组,用于存储以及对小时和分针的操作,暂定为100个闹钟于是定义为【100】【2】
     45     /**
     46     *读取文件,每次的增删都需要对数据进行读取,将数据写在面板上也需要读取数据
     47      */
     48     public void readFile() {
     49         try (FileReader reader = new FileReader(pathname);      //创建一个FilReader对象,将文件读出来,相当于请教一个当地人,当地人了解本地文化,但是语言不通听不懂
     50              BufferedReader br = new BufferedReader(reader) // 建立一个对象,它把文件内容转成计算机能读懂的语言,相当于请一个翻译,把当地人读取的东西转换成计算机能懂的东西
     51         ) {
     52             String line;
     53 
     54             int i =0;
     55             while ((line = br.readLine()) != null) {        //翻译理解的东西存到line里面
     56                 int j =0;
     57                 StringTokenizer st = new StringTokenizer(line, ":");        //重点:由于存储数据时都是时间,道理来说都是数字,无法区分小时部分和分钟部分
     58                 while (st.hasMoreTokens()){               //每读取一次读到的内容     //所以这里用分割符“:”来分割,相应的,后面的写入文件也应该已“:”分割进行写入
     59                     str[i][j]=st.nextToken();               //把读到的内容存储在数组里面便于后面的操做——增删
     60                     j++;                                    //包括上面的j=0,是将for循环拆分放进while循环中,要不然循环写起来也很麻烦
     61                 }
     62                 //System.out.print(str[i][0]+":"+str[i][1]);       写的时候用来在控制台打印查看效果
     63                 //System.out.println();
     64                 i++;
     65                 j = 0;
     66             }
     67         } catch (IOException e) {
     68             e.printStackTrace();                    //try……catch抛出异常
     69         }
     70     }
     71 
     72 
     73     /**
     74      * 写入TXT文件
     75      */
     76     public void writeFile() {
     77         HOUR = Integer.valueOf(ho.getSelectedIndex());                          //获取下拉框中的值,存储到HOUR中
     78         MIN = Integer.valueOf(mi.getSelectedIndex());
     79         String x = HOUR + ":" + MIN;
     80         try (FileWriter writer = new FileWriter(pathname,true);         //同上面的读取,本地人写入,注意:后面的append:true是表示不是重新写,而是在后面追加
     81              BufferedWriter out = new BufferedWriter(writer)                    //翻译一下再写入
     82         ) {
     83 
     84             out.write(HOUR + ":" + MIN + "
    ");                           //这里写入的时候把:写进去了!
     85             out.flush();                                                        // 把缓存区内容压入文件,计算机的存储过程,存在缓存区再写入文件
     86             JOptionPane.showMessageDialog(null,"闹钟添加成功!","添加闹钟提醒",JOptionPane.INFORMATION_MESSAGE); //提示框:添加闹钟成功
     87         } catch (IOException e) {
     88             e.printStackTrace();
     89 
     90         }
     91 
     92     }
     93 
     94 
     95     /**
     96      * 删除闹钟,实际上是先将要删除的数据找到移除数组,再将数组重新写入,所以要先读取文件,再重新写入
     97      */
     98     public void shanchuFile() {
     99         HOUR = Integer.valueOf(ho.getSelectedIndex());
    100         MIN = Integer.valueOf(mi.getSelectedIndex());
    101         try (FileWriter writer = new FileWriter(pathname);              //没有append:true,表示重新写!
    102              BufferedWriter out = new BufferedWriter(writer)
    103         ) {
    104             readFile();
    105             for (int i = 0; i < 100; i++) {
    106                 if (Integer.valueOf(str[i][0])==HOUR && Integer.valueOf(str[i][1])==MIN){
    107                     continue;
    108                 }
    109                 else{
    110                     out.write(str[i][0]+":"+str[i][1]+"
    "); // 
    即为换行
    111                 }
    112             }
    113 
    114             //out.write("1"+"1"+"
    "); // 
    即为换行
    115             out.flush(); // 把缓存区内容压入文件
    116         } catch (IOException e) {
    117             e.printStackTrace();
    118         }catch (NumberFormatException e){
    119             System.out.println("this isn't exist!");
    120             JOptionPane.showMessageDialog(null,"该闹钟已删除!","删除闹钟提醒",JOptionPane.INFORMATION_MESSAGE); //弹窗提示
    121         }
    122     }
    123 
    124     /* 初始化函数 */
    125     public void init() {
    126 
    127         Calendar now = new GregorianCalendar();     //获取当前时间
    128         /*
    129          * GregorianCalendar(标准阳历)
    130          * 是Calendar(日历)【国际环境下都能运行的程序】
    131          * 的子类
    132          */
    133         s = now.get(Calendar.SECOND) * 6; // 秒针转换成角度:1秒,秒针动一次,转动6°
    134         m = now.get(Calendar.MINUTE) * 6; // 分针转换为角度:1分,分针动一次,转动6°
    135         h = now.get(Calendar.HOUR) * 30 + now.get(Calendar.MINUTE) / 12 * 6; // 先把分化为小时,再乘以6°,因为分针转12°,时针才会转1°,一小时中间有5格,数学问题
    136         /*
    137          * Calendar.HOUR 显示范围:1-12(无论AM还是PM) Calendar.HOUR_OF_DAY 显示范围:1-24(包括PM
    138          */
    139 
    140         Thread t = new Thread(this);        //添加线程,线程目标是整个程序,this
    141         t.start();                                  //线程就绪
    142     }
    143 
    144     public void paint(Graphics g) {                 //awt中的方法,因为要时时显示闹钟,所以不得不使用绘画的方式,不断重绘
    145         super.paint(g);
    146         /*
    147          * paint(g)函数会重绘图像,要加上super.paint(g),表示在原来图像的基础上,再画图。
    148          * 如果不加super.paint(g),重绘时,会将原有的绘制清空,再根据paing(g)函数绘制。
    149          */
    150 
    151         g.setColor(Color.BLACK);                    //设置画笔颜色——黑色
    152         g.drawOval(x, y, r * 2, r * 2);// 画表
    153         /* drawOval(x,y,width,height)以矩形恰好框住椭圆,矩形左上角的顶点坐标为(x,y) */
    154 
    155         // 秒针
    156         int x1 = (int) (90 * Math.sin(rad * s));
    157         int y1 = (int) (90 * Math.cos(rad * s));
    158         g.drawLine(r+x, r+y, r+x + x1, r +y- y1);
    159         /* drawLine(a,b,c,d) (a,b)为起始坐标 (c,d)为终点坐标 */
    160 
    161         // 分针
    162         x1 = (int) (80 * Math.sin(rad * m));
    163         y1 = (int) (80 * Math.cos(rad * m));
    164         g.drawLine(r+x, r+y, r +x+ x1, r+y - y1);
    165 
    166         // 时针
    167         x1 = (int) (60 * Math.sin(rad * h));
    168         y1 = (int) (60 * Math.cos(rad * h));
    169         g.drawLine(r+x, r+y, r+x + x1, r +y- y1);
    170 
    171         // 画数字
    172         int d = 30;
    173         for (int i = 1; i <= 12; i++) {
    174             x1 = (int) ((r - 10) * Math.sin(rad * d));
    175             y1 = (int) ((r - 10) * Math.cos(rad * d));
    176             g.drawString(String.valueOf(i), r+x + x1, r+y - y1);    //字符型的数据才能画
    177             d += 30;
    178         }
    179 
    180         // 画刻度
    181         d = 0;
    182         for (int i = 1; i <= 60; i++) {
    183             x1 = (int) ((r - 2) * Math.sin(rad * d));
    184             y1 = (int) ((r - 2) * Math.cos(rad * d));
    185             g.drawString(".", r+x + x1, r +y- y1);      //画的是点,表示刻度
    186             d += 6;
    187         }
    188         // 显示时间
    189         Calendar now1 = new GregorianCalendar();
    190         int a, b, c;
    191         a = now1.get(Calendar.HOUR_OF_DAY);     //获取当前的小时
    192         b = now1.get(Calendar.MINUTE);          //获取当前的分钟
    193         c = now1.get(Calendar.SECOND);           //获取当前的秒钟
    194         g.drawString(a + ":" + b + ":" + c, 175, 330);      //将时间也画到面板上
    195         g.drawString("全部闹钟:",100,350);                  //全部闹钟
    196 
    197         try (FileReader reader = new FileReader(pathname);
    198              BufferedReader br = new BufferedReader(reader) // 建立一个对象,它把文件内容转成计算机能读懂的语言
    199         ) {
    200             String line;
    201 
    202             int i =0;
    203             while ((line = br.readLine()) != null) {
    204                 int j =0;
    205                 StringTokenizer st = new StringTokenizer(line, ":");
    206 while (st.hasMoreTokens()){
    207 str[i][j]=st.nextToken();
    208                     j++;
    209                 }
    210                 g.drawString(str[i][0]+":"+str[i][1]+"
    ",180+(i/10)*70,350+15*(i-(i/10)*10));  //貌似重新写了一下readfile的方法,其实是有区别的,这里是读取以后画出来
    211 //qbnz.setText(str[i][0]+":"+str[i][1]+"
    ");
    212 //System.out.print(str[i][0]+":"+str[i][1]);
    213 //System.out.println();
    214                 i++;
    215                 j = 0;
    216             }
    217         } catch (IOException z) {
    218             z.printStackTrace();
    219         }
    220     }
    221 
    222 
    223 // 实现Runnable,实现implement Runnable就务必实现run方法,使线程运行
    224 public void run() {
    225 while (true) {
    226 try {
    227                 Thread.sleep(1000);// 间隔一秒
    228             } catch (Exception ex) {
    229             }
    230             s += 6;                // 秒针每次走6°
    231 if (s >= 360) {
    232                 s = 0;            // 秒针归零
    233                 m += 6;
    234 if (m == 72 || m == 144 || m == 288) {
    235                 h += 6;                // 分针走72°,时针走6° 分针的12倍,时针走一次
    236                 }
    237 
    238 if (m >= 360) {
    239                 m = 0;                // 分针归零
    240                 h += 6;
    241                 }
    242 if (h >= 360) {
    243                 h = 0;                // 时针归零
    244                 }
    245             }
    246 
    247 
    248 this.repaint();     // 重新绘制
    249 //this.readFile();
    250 this.alert();       //将闹钟加入到线程当中
    251         }}
    252 
    253 public void alert(){
    254         Calendar now1 = new GregorianCalendar();
    255 int a, b;
    256         a = now1.get(Calendar.HOUR_OF_DAY);
    257         b = now1.get(Calendar.MINUTE);      //这里没有获取秒针是因为闹钟不看秒针。。。。。
    258 try (FileReader reader = new FileReader(pathname);
    259 BufferedReader br = new BufferedReader(reader) // 建立一个对象,它把文件内容转成计算机能读懂的语言
    260         ) {
    261 String line;
    262 String[][] str= new String[100][2];
    263 int i =0;
    264 while ((line = br.readLine()) != null) {
    265 int j =0;
    266                 StringTokenizer st = new StringTokenizer(line, ":");
    267 while (st.hasMoreTokens()){
    268 str[i][j]=st.nextToken();
    269                     j++;
    270                 }
    271 if (a==Integer.valueOf(str[i][0]) && b==Integer.valueOf(str[i][1])){        //读取后与获得的时间比较,如果闹钟存在,就响
    272 try{
    273                         InputStream in = new FileInputStream("D://homework//java//Gui//src//Clock//0.wav");//FIlename 是你加载的声音文件如(“game.wav”)
    274                         AudioStream as = new AudioStream(in);           //和读取文件类似的原理,经翻译之后才播放出来
    275                         AudioPlayer.player.start(as);       //用静态成员player.start播放音乐
    276                         } catch(FileNotFoundException e){
    277                         System.out.print("FileNotFoundException ");
    278                     } catch(IOException e){
    279                         System.out.print("有错误!");
    280                     }
    281                 }
    282                 i++;
    283                 j = 0;
    284             }
    285         } catch (IOException z) {
    286             z.printStackTrace();
    287         }
    288     }
    289 
    290 //初始化界面
    291 public  void  launchFrame(){
    292         xx = new JPanel();      //插入一个面板
    293 String[] hours = new String[24];        //长度为24的数组用于存储小时
    294 for (int i = 0; i < hours.length; i++) {
    295             hours[i]=i+"";              //循环对hour进行赋值
    296         }
    297         ho = new JComboBox(hours);      //将hour加入到下拉框中
    298         ho.setSize(50,40);  //设置大小好像没用
    299 String[] mins = new String[60];     //同理,这是分钟的地方
    300 for (int i = 0; i < mins.length; i++) {
    301             mins[i]=i+"";                   //分钟赋值
    302         }
    303         mi = new JComboBox(mins);           //分钟下拉框
    304         mi.setSize(50,40);
    305         tjnz = new JButton();               //添加闹钟的按钮,拼音首字母
    306         tjnz.setText("添加到闹钟");             //按钮上显示的文字
    307         tjnz.setSize(100,40);
    308         schour = new JButton();                 //删除闹钟的按钮
    309         schour.setText("从闹钟中删除");           //按钮上显示的文字
    310         schour.setSize(100,40);
    311 
    312 /**
    313          * 将按钮下拉框啥的加入到面板中
    314          */
    315         xx.add(ho);
    316         xx.add(mi);
    317         xx.add(tjnz);
    318         xx.add(schour);
    319 this.add(xx);       //将面板加入到this对象中,要不然面板就不显示
    320         tjnz.addActionListener(new ActionListener() {       //添加按钮的功能
    321                 @Override                                   //重写的标识,务必要会
    322 public void actionPerformed(ActionEvent e) {
    323 // TODO Auto-generated method stub
    324                     HOUR = Integer.valueOf(ho.getSelectedIndex());
    325                     MIN = Integer.valueOf(mi.getSelectedIndex());      //获取到时分后
    326                     writeFile();                                       //写入txt文件保存为闹钟
    327                     readFile();                                        //再读取,这样才能时时更新面板上的全部闹钟
    328         }});
    329 
    330         schour.addActionListener(new ActionListener() {
    331                 @Override
    332 public void actionPerformed(ActionEvent e) {
    333 // TODO Auto-generated method stub
    334                     HOUR = Integer.valueOf(ho.getSelectedIndex());
    335                     MIN = Integer.valueOf(mi.getSelectedIndex());
    336                     shanchuFile();                                      //这里是删除闹钟的按钮功能
    337                     readFile();
    338                 }});
    339 
    340 this.setTitle("小闹钟");                                     //设置窗口标题
    341 this.setVisible(true);                                      //设置窗口不隐身
    342 this.setSize(700,500);                        //设置窗口大小
    343 this.setLocation(500, 250);                           //设置窗口位置,相对于桌面左上角
    344 this.init();                                                //调用初始化函数进行初始化
    345 this.alert();
    346 //this.run();       //重复调用run()方法结果是秒针一次走12°
    347 this.addWindowListener(new WindowAdapter() {
    348             @Override
    349 public void windowClosing(WindowEvent e) {
    350                 System.exit(0);
    351             }
    352         });     //设置窗口叉号的功能,点击就关闭程序
    353     }
    354 
    355 
    356 
    357 public static void main(String[] args) {
    358         ClockTry c = new ClockTry();        //main方法,必有的成分,创建主类对象,
    359         c.launchFrame();                    //调用初始化面板的方法,简化了本该在main方法中写的代码
    360 
    361 }}

    运行效果

    2

    3

    此版本为第一次尝试,后续有时间会继续更新版本

  • 相关阅读:
    WebFrom 小程序【分页功能 】
    WebForm 【Repeater】展示数据
    WebForm 小项目【人员管理系统】分析
    WebFrom 【内置对象】— —跳转页面,页面传值
    WebForm 【复合控件】
    WebForm 【简单控件】【表单元素】
    WebForm 基础学习
    js对元素属性.内容的操作。定时器。元素的平级,父级,子集关系。
    常用事件【由浅入深】1
    document 对象
  • 原文地址:https://www.cnblogs.com/mxdon/p/11324600.html
Copyright © 2011-2022 走看看