秒表计时器——Java基础练手项目(Java课程设计)

秒表计时器——Java基础练手项目(Java课程设计),第1张

秒表计时器——Java基础练手项目(Java课程设计)

前言:鄙人是大二在读学生,大二上学期Java课程设计选了一个秒表计时器的题目,在此把代码和心得分享出来(懒人可以直接看PPT)。鄙人资历尚浅,代码中会有许多不当之处,望各位大佬海涵,有更好的建议希望各位大佬留言评论区。

题目要求

设计一个与手机秒表类似的计时器,以钟表图形的方式呈现。

  1. 当用户用鼠标单击界面的“开始”按钮或图标时,秒表开始计时,表及数字都自动发生变化;当用户再次点击按钮,秒表暂停计时,按钮字样变为“继续”;当用户用鼠标点击“继续”按钮,秒表继续计时。
  2. 界面上还有一个“复位”按钮,当未点击“开始”按钮,没有进入计时状态时,“复位”按钮为灰色不可选,当开始计时后,“复位”按钮变为可选状态,当用户点击复位按钮时,秒表计时清零。
设计思路

  •   首先利用java中的swing创建窗口,及其相关的组件,构造出大概的图像,如下图
  • 然后利用java中的计时器类(Timer),让指针随着时间转动(本来有视频演示的,但是奈何视频鄙人还不会插入……)
  • 接着声明一些变量(例如haveStart,isStop,number)来帮助判断秒表的状态(如下图)

  • 结合静态变量,给三个按钮添加事件监听(jp_*为第*个按钮)

    //手动换行分开三个按钮(手动滑稽)

    //手动换行分开三个按钮(手动滑稽)

  • 使用jdbc技术连接java程序和mysql数据库(这个题目里面是没有要求的,但是想着完美一点就加上去了,下面3张图为代码演示和结果演示)

    //手动换行分开图片(手动滑稽)

    //手动换行分开图片(手动滑稽),下面这张图是数据库存储后的结果,为了方便展示直接使用了数据库管理系统的可视化工具navicat

    程序分析

    程序能够符合题目的所有要求,并且结合实际考虑,在题目要求之外添加了如下几个功能:

    1. 在未点击开始按钮时,暂停按钮也设置成灰色不可点击的状态
    2. 在未点击开始前,点击暂停或者复位按钮的话,会有d窗提醒,告诉使用者“程序未开始,此按钮不可选!”
    3. 在窗口右侧添加了多行文本域,可以展示在一次使用中的多次记录的次序和时长
    4. 使用了JDBC技术连接了java程序和mysql数据库,可以在点击复位按钮时自动把每次记录的次序,时长,记录的时间存入数据库中,便于数据的保存和查询。

    程序的不足之处:

    1. 因为采用了Java Swing中的组件来构造钟表,所以钟表图形简陋,窗口上的单行文本域和多行文本域也显得有些呆滞
    心得与体会 在这个课程设计中遇到的难题及其解决方案:

    1. 导包错误

    这个课程设计中使用到了java中的计时器类(Timer),但是由于之前没有接触过这个类,所以是通过一些视频,及百度才知道了这个类,使用这个类是需要导包的,但是不止一个包含有这个类,当时我下意识的导了java.swing这个包,因为这个课程设计很多都用到了swing,导致程序报错(见下图),但是明明我和百度和视频上的几乎一模一样,在漫长的折磨下,我才想到可能是导错包了。

    解决方案:在java的API文档和百度搜索上比较详细的了解了这个类在不同包下的使用之后,挑选了一个比较合适的包导入,并且修改java语句,尝试完成自己让指针转动的需求

    2.版本不匹配问题  

    我在电脑上配置的mysql的版本是5.7.36,然后用到的jdbc的jar是最新的8.0.27版本的,所以在起初看视频学习jdbc技术时,敲着一模一样的代码,但是我这里会报错(见下图),这就让人十分苦恼,难以继续学习下去    

     

    解决方案:在官网上找到对应版本的jdbc的jar文件(即5.7.36版本的jdbc的jar文件),然后把这个文件配置到运行环境中

    几个有用的网址:

    1. Overview - Java 11中文版 - API参考文档

    Java中文在线帮助文档

    2.https://mvnrepository.com/artifact/mysql/mysqlconnector-java

    可以很容易获取Jdbc中任意版本的jar包

    3. 百度一下,你就知道

    可以解答我们目前为止在编程上遇到的90%的问题

    源码
    package Miaobiao;
    
    import javax.swing.*;
    import java.awt.event.*;
    import java.sql.*;
    import java.text.SimpleDateFormat;
    import java.awt.*;
    import java.util.*;
    import java.util.Date;
    import java.util.Timer;
    
    
    public class MiaoBiao {
          //获得记录的时间
          SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss ");
          Date date = new Date(System.currentTimeMillis());
          String s;
        // 创造各个组件
        final static double pai = 3.14159;
        Jframe jf = new Jframe("秒表窗口");
        JPanel jp_one = new JPanel();
        JPanel jp_two = new JPanel();
        JPanel jp_three = new JPanel();
        static int location_x = 0;
        static int location_y = 110;
        static MyCanvas myCanvas = new MyCanvas();
    
        JButton jb_one = new JButton("开始");
        JButton jb_two = new JButton("暂停");
        JButton jb_three = new JButton("复位");
        // 未开始时点击复位d出的对话框
        JDialog jd = new JDialog(jf, true);
        Jtextarea jta = new Jtextarea("程序未开始,此按钮不可选!");
    
        static JTextField tf = new JTextField(10);
        Jtextarea ta = new Jtextarea(30, 10);
        // 设置一个变量来观察秒表是否暂停
        static boolean isStop = true;
        // 设置一个变量记录时间
        static private int t = 0;
        // 设置一个变量是否开始
        static boolean haveStart = false;
        // 设置一个变量记录秒表运行次数
        static int number = 0;
        
    
        private static class MyTimer extends TimerTask {
    
            @Override
            public void run() {
                if (isStop) {
    
                } else {
                	//更新指针终点的x,y坐标,并且更新单行文本域的内容
                    t++;
                    location_x = (int) (Math.cos((pai / 2 - t * pai / 30)) * 110);
                    location_y = (int) (Math.sin((pai / 2 - t * pai / 30)) * 110);
                    tf.setText("" + t + "秒");
                    myCanvas.repaint();
                   
                }
                // TODO Auto-generated method stub
    
            }
    
        }
      
        // 组装函数
        public void init() {
            // 设置d窗内容
            jd.setBounds(300, 300, 300, 200);
            jd.setTitle("错误!");
            jd.add(jta);
            // jd.setTe
            // 给复位按钮设置成灰色
            jb_two.setBackground(Color.gray);
            jb_three.setBackground(Color.gray);
            // 给按钮添加事件监听
            jb_one.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    if (jb_two.getActionCommand().equals("暂停")) {
                        isStop = false;
                        haveStart = true;
                        jb_two.setBackground(new Color(236, 242, 248));
                        jb_three.setBackground(new Color(236, 242, 248));
                    }
                }
            });
            jb_two.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    // 判断这个按钮当前的状态
                    if (!haveStart && e.getActionCommand().equals("暂停")) {
                        jd.setVisible(true);
                    } else if (haveStart && e.getActionCommand().equals("暂停")) {
                        isStop = true;
                        jb_two.setText("继续");
                    } else {
                        isStop = false;
                        jb_two.setText("暂停");
                    }
    
                }
            });
            jb_three.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    if (haveStart) {
                        // 更新成员变量的属性值
                  
                        isStop = true;
                        haveStart = false;
                        location_x = 0;
                        location_y = 110;
                        jb_two.setText("暂停");
                        // 在右边的文本域中更新内容
                        ta.append("第" + (++number )+ "次:" + t + "秒" + "n");
                        //写入数据库
      	           
                        t = 0;
                        tf.setText("");
                        // 给两个按钮回复颜色
                        jb_three.setBackground(Color.gray);
                        jb_two.setBackground(Color.gray);
                        myCanvas.repaint();
    
                    } else {
                        jd.setVisible(true);
                    }
                }
            });
            // 给三个面板添加组件
            myCanvas.setSize(new Dimension(360, 360));
            //myCanvas.setBackground(Color.blue);
            jp_one.add(myCanvas);
            jp_one.add(tf);
            jp_two.add(jb_one);
            jp_two.add(jb_two);
            jp_two.add(jb_three);
            jp_three.add(ta);
    
            // 给窗口添加三个面板
            jf.add(jp_one, BorderLayout.CENTER);
            jf.add(jp_two, BorderLayout.SOUTH);
            jf.add(jp_three, BorderLayout.EAST);
    
            // 设置窗口位置,大小,可见性,添加窗口关闭监听
            jf.setBounds(200, 200, 500, 500);
            jf.setVisible(true);
            //jf.addWindowListener(new MyListener());
            jf.setDefaultCloseOperation(1);
    
            Timer timer = new Timer();
            timer.schedule(new MyTimer(), 0, 1000);
    
        }
    
        public static void main(String[] args) {
            new MiaoBiao().init();
        }
    
     
    
        // 创建画布
        private static class MyCanvas extends Canvas {
            @Override
            public void paint(Graphics g) {
                // 绘制钟表图
                g.drawOval(60, 40, 250, 250);
                g.setFont((new Font("Times", Font.BOLD, 30)));
                g.drawString("12", 170, 65);
                g.drawString("3", 290, 175);
                g.drawString("6", 178, 288);
                g.drawString("9", 62, 175);
                g.drawString("1", 235, 80);
                g.drawString("2", 275, 120);
                g.drawString("4", 275, 235);
                g.drawString("5", 235, 275);
                g.drawString("7", 126, 275);
                g.drawString("8", 80, 235);
                g.drawString("10", 75, 120);
                g.drawString("11", 115, 80);
                // 绘制指针,利用计时器更新 a b 的值使指针不停的转动
                int a = 185 + location_x;
                int b = 165 - location_y;
                g.drawLine(185, 165, a, b);
    
            }
    
        }
    }
    

    注:为了让代码能够成功运行,有关数据库部分的代码被注释了。(注释掉的部分:第67-83行,第133-140行)

    另附本人的实验报告文档与分享会的PPT:

    链接:https://pan.baidu.com/s/17FUTWmdxrha2Lpy8aARPyQ 
    提取码:zlry

    好了~第一篇博客到此就结束了,大家对这个课程设计有什么问题可以在评论区留言~也欢迎各位大佬提出宝贵的修改意见~

    欢迎分享,转载请注明来源:内存溢出

    原文地址: https://outofmemory.cn/zaji/5706733.html

  • (0)
    打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
    上一篇 2022-12-18
    下一篇 2022-12-17

    发表评论

    登录后才能评论

    评论列表(0条)

    保存