前言:鄙人是大二在读学生,大二上学期Java课程设计选了一个秒表计时器的题目,在此把代码和心得分享出来(懒人可以直接看PPT)。鄙人资历尚浅,代码中会有许多不当之处,望各位大佬海涵,有更好的建议希望各位大佬留言评论区。
题目要求设计一个与手机秒表类似的计时器,以钟表图形的方式呈现。
- 当用户用鼠标单击界面的“开始”按钮或图标时,秒表开始计时,表及数字都自动发生变化;当用户再次点击按钮,秒表暂停计时,按钮字样变为“继续”;当用户用鼠标点击“继续”按钮,秒表继续计时。
- 界面上还有一个“复位”按钮,当未点击“开始”按钮,没有进入计时状态时,“复位”按钮为灰色不可选,当开始计时后,“复位”按钮变为可选状态,当用户点击复位按钮时,秒表计时清零。
//手动换行分开三个按钮(手动滑稽)
//手动换行分开三个按钮(手动滑稽)
//手动换行分开图片(手动滑稽)
//手动换行分开图片(手动滑稽),下面这张图是数据库存储后的结果,为了方便展示直接使用了数据库管理系统的可视化工具navicat
程序分析程序能够符合题目的所有要求,并且结合实际考虑,在题目要求之外添加了如下几个功能:
- 在未点击开始按钮时,暂停按钮也设置成灰色不可点击的状态
- 在未点击开始前,点击暂停或者复位按钮的话,会有d窗提醒,告诉使用者“程序未开始,此按钮不可选!”
- 在窗口右侧添加了多行文本域,可以展示在一次使用中的多次记录的次序和时长
- 使用了JDBC技术连接了java程序和mysql数据库,可以在点击复位按钮时自动把每次记录的次序,时长,记录的时间存入数据库中,便于数据的保存和查询。
程序的不足之处:
- 因为采用了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
好了~第一篇博客到此就结束了,大家对这个课程设计有什么问题可以在评论区留言~也欢迎各位大佬提出宝贵的修改意见~
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)