简单编程-测试反应能力

目的:当屏幕上出现不同的图像时,通过按键盘上的空格键来测试一个人的反应能力。

常规:允许参与者输入姓名和年龄。记录我和日期。

要求:启动时,点击屏幕右侧显示的绿色按钮,程序运行时使该变为红色,然后在屏幕中间显示4x4cm的红色正方形1秒。接下来显示一个4x4x4x4蓝色三角形,持续80毫秒。然后再次显示正方形1秒。每一次显示一个三角形,这个人点击键盘,程序就会记录下发生这种情况的次数。以不规则的方式交替显示正方形和三角形。例如:先显示正方形,再显示三角形,然后显示正方形两次,在正方形和三角形之间的20毫秒内不显示任何内容。记住,当人们看到三角形并按下键盘上的空格键时,要记下时间。运行此程序6分钟,然后显示最终计数。

本次小测使用GUI图形化界面实现,内部数据没有连接数据库,因此为一次性数据。每次测量数据无法保存。

首先在程序一开始,想采用面向面向过程的方法,但是由于学艺不精,有一些结构上的混乱。代码仅供参考,希望可以提出建议。

在程序一开始先大致判断需要用到的面板,按钮组件,在最上面定义好,后期有需要再添加别的组件。

JFrame jf=new JFrame("反应时间测试");
JLabel label = new JLabel("出现三角形图形时候摁下空格");
JLabel label1 = new JLabel();   //用来展示图片
ImageIcon icon0 = new ImageIcon("src\\picture\\红色正方形.png");//正方形图标组件
ImageIcon icon1 = new ImageIcon("src\\picture\\蓝色三角形2.png");//三角形图标组件
JButton jButton ;
JButton jButton1;
int jishu = 1;
int jishu1= 2;
int zhuangtai = 1;
ArrayList<Date> list = new ArrayList<>();

然后定义与方法名相同的Interface()方法,此方法自启动。

 public Interface(){
       this.init();
       this.addAction();
    }

定义init()方法,用来设置各个按钮的参数,以及面板的组装。其中各个按钮的位置需要自己一点一点的调试,达到自己满意的位置。
其中在最后一个按钮添加时候遇到点问题,一添加按钮,会把整个界面全部占满。后期找了很多参考代码没有解决,在一次运行时候,代码自己好了,不明白原理。就很神奇,我称之为神学<😂>。

  private void init(){
        // jf.setLayout(new BorderLayout());
        jf.setSize(600,500);   //设置窗体大小
        GUITools.center(jf);            //设置居中
        label1.setBounds(220, 120, 150,150);

        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //设置标签格式
        label.setFont(new Font("幼圆", Font.BOLD, 16));
        label.setBounds(200, 30, 250, 40);

        //设置图片格式
        Image book0 = icon0.getImage();
        book0 = book0.getScaledInstance(150,150,Image.SCALE_DEFAULT);
        icon0.setImage(book0);
        //label1.setIcon(icon0);


        Image book1 = icon1.getImage();
        book1 = book1.getScaledInstance(300,150,Image.SCALE_DEFAULT);
        icon1.setImage(book1);


        JPanel panel = new JPanel();
        // panel.setBorder(new TitledBorder(null, "\u4E66\u7C4D\u6DFB\u52A0", TitledBorder.LEADING, TitledBorder.TOP, null, Color.RED));
        panel.setBounds(500, 500, 200, 300);
        jf.getContentPane().add(panel);
        panel.setLayout(null);

        jButton = new JButton("开始");
        jButton.setFont(new Font("幼圆", Font.BOLD, 14));
        jButton.setBounds(480, 350, 77, 27);
        jButton.setBackground(Color.green);
        panel.add(jButton);


        jf.add(label);
        jf.add(label1);
        jf.add(panel);
        jf.setVisible(true);
    }

接下来定义一个改变中间图形的方法,前期我写代码的时候发现,面板中的组件,从一开始创建好之后,就不能再进行添加,删除以及更改,但是组件的内容可以更换,因此定义中间JLabel类型的标签后期可以替换显示的照片来达到更换照片的目的。

 //改变中间图形
    private class label1_change extends Thread{
        int i;
        public void run(){
            while (true){
                Random ra = new Random();
                i = ra.nextInt(2);
                zhuangtai=i;    //把现在显示的照片传递出去
                if (i==1){
                    ++jishu1;
                    label1.setIcon(icon1);//蓝色三角形,持续80ms
                    try {
                        TimeUnit.MILLISECONDS.sleep(80);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }else {
                    label1.setIcon(icon0);//红色正方形,持续1s
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                //程序运行完,等待20ms
                try {
                    TimeUnit.MILLISECONDS.sleep(20);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

创建一个定时器用来纪录运行了多长时间,达到运行一定时长截至程序运行的目的。
我在寻找代码的过程中找到两种关于计时器的程序,一种是等待一定时间后,执行一段代码固定时间,多次执行;第二种是等待一定时间,程序只运行一次。
接下来是第一种。

定义一个addAction()方法,用来设置监听事件。其中包括对开始,结束的监听;对整个界面的键盘事件监听,按下回车纪录次数。

第一种方法虽然我最终没有使用,但是纪录下来,以后或许能够用到

//设置计时器
    private class MyThread extends Thread{
       /* @Override
        public void run() {
            //创建定时器截止程序运行
            TimerTask task = new TimerTask() {
                @Override
                public void run() {
                    //执行条件
                    jf.dispose();
                    new Interface();
                   *//* String format = new DecimalFormat("0.00%").format((double) (jishu) / (double) (jishu1));
                    //增强for循环,把操作成功的时间纪录遍历一遍
                    for (Date s :list){
                        System.out.println(s);
                    }
                    System.out.println("您的反应为:");*//*
                }
            };
            Timer timer = new Timer();
            //定义等待时间,
            long delay =5*1000;
            //定义每次执行时间10s
            long intecalperiod = 1;
            //安排任务在一段时间内执行
            timer.scheduleAtFixedRate(task,delay,intecalperiod);//等待delay时间后,执行intecalperiod时间的是task程序
        }
    }*/

接下来是第二种,也就是我使用的那一种

 //设置计时器
    private class MyThread extends Thread{
        @Override
        public void run() {
            Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    jf.dispose();
                    new Interface();
                    String format = new DecimalFormat("0.00%").format((double) (jishu) / (double) (jishu1));
                    //增强for循环,把操作成功的时间纪录遍历一遍
                    for (Date s :list){
                        System.out.println(s);
                    }
                    System.out.println("您的反应为:"+format);
                }
            },30*1000);//设置时间为30秒
        }
    }

最后,对按钮,空格添加监听事件

//设置监听事件
    private void addAction(){
        //设置开始按钮
        jButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                if (jButton.getBackground()==Color.green){
                    MyThread myThread = new MyThread(); //创建Mythread的实例化对象
                    myThread.start();//开启线程
                    jButton.setText("结束");
                    jButton.setBackground(Color.red);//设置为红色
                    new label1_change().start();       //运行更换图案的方法

                }else {
                    jButton.setText("开始");
                    jButton.setBackground(Color.green);
                    jf.dispose();
                    new Interface();
                    String format = new DecimalFormat("0.00%").format((double) (jishu) / (double) (jishu1));
                    //增强for循环,把操作成功的时间纪录遍历一遍
                    for (Date s :list){
                        System.out.println(s);
                    }
                    System.out.println("您的反应为:"+format);
                }
            }
        });
        //设置键盘监听
      jButton1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (jButton.getBackground() == Color.red && zhuangtai == 1) {
                    jishu++;
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh-mm-ss");
                    String time = null;

                    time = sdf.format(new Date());//纪录当下时间
                    list.add(time);//把当前纪录存进数组
                }

        }});

其中用到的GUITools类,我在使用定义这个中间方法的时候,有导入一个包

import java.awt.*;

如果没有这个包的话,建议直接设置图形的位置。调用setBounds()方法设置大小以及坐标。

public class GUITools {
	public static void center(Component c) {
		Toolkit kit = Toolkit.getDefaultToolkit();
		int x = (kit.getScreenSize().width - c.getWidth()) / 2;
		int y = (kit.getScreenSize().height - c.getHeight()) / 2;
		c.setLocation(x, y);
	}
}

然后定义一个主方法来调用这个函数,这个结构学会后,真的挺方便的,对于代码后期的运行以及维护有很大的便利,结构清晰,能够一眼看出以及找到需要修改的部门。目前本人能看的懂,自己写,有些四不像的感觉,正在向那个方向靠拢,见谅。

public class main {
    public static void main(String[] args) {
        new Interface();
    }
}

最后,这是运行结果。运行程序出现以下界面,因为没有点击开始运行,所以中间部分图形没有显示。
请添加图片描述
点击开始运行后,红方块和绿三角随机显示,只有三角的时候摁下空格才会被纪录到。
在这里插入图片描述
最后当运行到系统设置的时间之后,结束程序。并且返回运行的纪录。例如:运行过程中什么时刻点击过空格的纪录。以及反应速度(小于1大于0,数据越大,反应代表越快)。
在这里插入图片描述

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值