zoukankan      html  css  js  c++  java
  • 201871010102-常龙龙《面向对象程序设计(java)》第十六周学习总结

    项目

    内容

    这个作业属于哪个课程

    https://www.cnblogs.com/nwnu-daizh/

    这个作业的要求在哪里

    https://www.cnblogs.com/nwnu-daizh/p/12031970.html

    作业学习目标

              

                (1) 掌握Java应用程序的打包操作;

                (2) 掌握线程概念;

                (3) 掌握线程创建的两种技术。

     

    第一部分:总结第十二章本周理论知识(25分)

    14.1 什么是线程

    1.程序、进程与线程

             ● 程序是一段静态的代码,它是应用程序执行的蓝本。

             ● 进程是程序的一次动态执行,它对应了从代码加载、执行至执行完毕的一个完整过程。

             ● 线程是进程执行过程中产生的多条执行线索。 线程是比进程执行更小的单位。

                    

    2.Java中实现多线程应用有两种途径:

      ● 创建Thread类的子类

      ● 在程序中实现Runnable接口

    14.1.1 用Thread类的子类创建线程

      只需从Thread类派生出一个子类,在类中一定要实现run()。

      例: class hand extends Thread {

          public void run() {…….}

                   }

                   class Lefthand extends Thread {

           public void run() {

            for(int i=0;i<=5;i++)

            { System.out.println("You are Students!");

            try{ sleep(500); }

            catch(InterruptedException e) {… }

          }

        }

                  class Righthand extends Thread {

           public void run() {

            for(int i=0;i<=5;i++) {

            System.out.println("I am a Teacher!");

            try{ sleep(300); }

            catch(InterruptedException e) {…. } }

          }

                   }

    然后用该类创建一个对象

          Lefthand left=new Lefthand();

          Righthand right=new Righthand();

    用start()方法启动线程

          left.start();

          right.start();

    在程序中实现多线程,关键性操作:

          -定义用户线程操作,即run()方法的实现。

          -在适当的时候启动线程。

    public class ThreadTest {

          static Lefthand left;

          static Righthand right;

          public static void main(String[] args) {

          left=new Lefthand();

          right=new Righthand();

          left.start();

          right.start();

        }

    }

    例:ThreadTest.java 执行结果:

            You are Students!

            I am a Teacher!

            I am a Teacher!

            You are Students!

            I am a Teacher!

            I am a Teacher!

            You are Students!

            I am a Teacher!

            You are Students!

            I am a Teacher!

            You are Students!

            You are Students!

    14.1.2 用Runnable()接口创建线程

      ●用Runnable()接口实现多线程时,也必须必须实现run()方法,也需用start()启动 线程。

      ●用Runnable()接口实现多线程时,常用Thread类的构造方法来创建线程对象。

    class BallRunnable implements Runnable {

      public void run() {

        try { for (int i = 1; i <= STEPS; i++) {

          ball.move(component.getBounds());

          component.repaint();

          Thread.sleep(DELAY);

            }

        }catch (InterruptedException e) { }

         }

    ●API:java.lang.Thread

    Thread(Runnable r)

    Runnable r = new BallRunnable(b, comp);

    Thread t = new Thread(r);

    创建一个新线程,它调用r的run(), r是一个实现了Runnable接口的类的实例。

    ● 例14-1 Bounce.java p625

    ● 例14-4 BounceThread.java p631

    14.2 中断线程

    ●当线程的run方法执行方法体中最后一条语句后,并经由执行return语句返回时,或者出现了在方法中没有捕获的异常时,线程将终止。

    ●在程序中常常调用interrupt()来终止线程,interrupt()不仅可中断正在运行的线程,而且也能中断处于blocked状态的线程,此时interrupt()会抛出一个InterruptedException异常。

    ●Java提供了几个用于测试线程是否被中断的方法。

    ●void interrupt() 向一个线程发送一个中断请求,同时把这个线程的“interrupted”状态置为true。 若该线程处于blocked状态,会抛出InterruptedException。

    ●static boolean interrupted() 检测当前线程是否已被中断,并重置状态“interrupted”值为false。

    ●boolean isInterrupted() 检测当前线程是否已被中断,不改变状态“interrupted”值 。

    14.3 线程状态

    线程一共有如下6种状态:

    ●New (新建)

    ●Runnable (可运行)

    ●Blocked (被阻塞)

    ●Waiting (等待)

    ●Timed waiting (计时等待)

    ●Terminated (被终止)

    14.3.1 新创建线程

    ●new(新建)

      线程对象刚刚创建,还没有启动,此时还处于不可运行状态。

    ●Thread thread=new Thread(“test”)

      此时线程thread处于新建状态,但已有了相应的内存空间以及其它资源。

    14.3.2 被终止的线程

    ●Terminated (被终止)

    线程被终止的原因有二:

      一是run()方法中最后一个语句执行完毕,因而自然死亡。

      二是因为一个没有捕获的异常终止了run方法,从而意外死亡。

    ●thread.stop() 可以调用线程的stop方法杀死一个线程,但是,stop方法已过时,不要在自己的代码中调用它。

    第二部分:实验部分

    实验1: 导入第13章示例程序,测试程序并进行代码注释。

    测试程序1

    ● elipse IDE中调试运行教材585页程序13-1,结合程序运行结果理解程序;

    ● 将所生成的JAR文件移到另外一个不同的目录中,再运行该归档文件,以便确认程序是从JAR文件中,而不是从当前目录中读取的资源。

    ● 掌握创建JAR文件的方法;

    代码如下:

    package resource;
    
    import java.awt.*;
    import java.io.*;
    import java.net.*;
    import java.util.*;
    import javax.swing.*;
    
    /**
     * @version 1.41 2015-06-12
     * @author Cay Horstmann
     */
    public class ResourceTest
    {
       public static void main(String[] args)
       {
          EventQueue.invokeLater(() -> {
             JFrame frame = new ResourceTestFrame();
             frame.setTitle("ResourceTest");
             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.setVisible(true);
          });
       }
    }
    
    /**
     * 一个加载图像和文本资源的框架。
     */
    class ResourceTestFrame extends JFrame
    {
       private static final int DEFAULT_WIDTH = 300;
       private static final int DEFAULT_HEIGHT = 300;
    
       public ResourceTestFrame()
       {
          setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
          
          //在找到ResourceTest类的地方查找about.gif文件
          URL aboutURL = getClass().getResource("about.gif");
          
          //将此图像设置为框架的图标
          Image img = new ImageIcon(aboutURL).getImage();
          setIconImage(img);
    
          JTextArea textArea = new JTextArea();
          
          //getResourceAsStream方法的作用是找到与类位于同一位置的资源,返回一个可以加载资源的URL或者输入流
          InputStream stream = getClass().getResourceAsStream("about.txt");
          
          //在读取文本时使用同一编码UTF-8
          try (Scanner in = new Scanner(stream, "UTF-8"))
          {
             while (in.hasNext())
                textArea.append(in.nextLine() + "
    ");
          }
          add(textArea);
       }
    }

    生成jar文件的过程:通过Eclipse中的功能 File->Export->Java->JAR File->选择需要生成jar文件的包->选择jar文件存储位置JAR file->next->next->main class->finish

      

    生成的文件归档后使用压缩包打开:

    双击运行结果如下:

    测试程序2:

    ● 在elipse IDE中调试运行ThreadTest,结合程序运行结果理解程序;

    ● 掌握线程概念;

    ● 掌握用Thread的扩展类实现线程的方法;

    ● 利用Runnable接口改造程序,掌握用Runnable接口创建线程的方法。

    代码如下:

    package ThreadTest;
    
    class Lefthand extends Thread { 
           public void run()
           {
               for(int i=0;i<=5;i++)
               {  System.out.println("You are Students!");
               //调用Thread的sleep方法不会创建一个新线程,
               //sleep是Thread的静态方法,用于暂停当前线程的活动
                   try{   
                       sleep(500);  
                   }
                   catch(InterruptedException e)
                   { 
                       System.out.println("Lefthand error.");
                   }    
               } 
          } 
        }
        class Righthand extends Thread {
            public void run()
            {
                 for(int i=0;i<=5;i++)
                 {   System.out.println("I am a Teacher!");
                     try{  
                         sleep(300);  
                     }
                     catch(InterruptedException e)
                     { 
                         System.out.println("Righthand error.");
                     }
                 }
            }
        }
        public class ThreadTest 
        {
             static Lefthand left;
             static Righthand right;
             public static void main(String[] args)
             {     left=new Lefthand();
                   right=new Righthand();
                   //同时启动两个线程
                   left.start();
                   right.start();
             }
        }

    运行结果如下:

    测试程序3:

    ● 在Elipse环境下调试教材625页程序14-1、14-2 14-3,结合程序运行结果理解程序;

    ● 在Elipse环境下调试教材631页程序14-4,结合程序运行结果理解程序;

    ● 对比两个程序,理解线程的概念和用途;

    ● 掌握线程创建的两种技术。

    代码一:

    Ball类:

    package bounce;
    
    import java.awt.geom.*;
    
    /**
     * 在长方形边缘上移动和反弹的球
     * @version 1.33 2007-05-17
     * @author Cay Horstmann
     */
    public class Ball
    {
       private static final int XSIZE = 15;
       private static final int YSIZE = 15;
       private double x = 0;
       private double y = 0;
       private double dx = 1;
       private double dy = 1;
    
       /**
        * 将球移动到下一个位置,如果碰到其中一个边,则反转方向
        */
       public void move(Rectangle2D bounds)
       {
          x += dx;
          y += dy;
          //宽度上的最小位置
          if (x < bounds.getMinX())
          {
             x = bounds.getMinX();
             dx = -dx;
          }
        //宽度上的最大位置
          if (x + XSIZE >= bounds.getMaxX())
          {
             x = bounds.getMaxX() - XSIZE;
             dx = -dx;
          }
          //高度上的最小位置
          if (y < bounds.getMinY())
          {
             y = bounds.getMinY();
             dy = -dy;
          }
        //宽度上的最大位置
          if (y + YSIZE >= bounds.getMaxY())
          {
             y = bounds.getMaxY() - YSIZE;
             dy = -dy;
          }
       }
    
       /**
        * 获取球在其当前位置的形状
        */
       public Ellipse2D getShape()
       {
          return new Ellipse2D.Double(x, y, XSIZE, YSIZE);
       }
    }

    BallComponent类:

    package bounce;
    
    import java.awt.*;
    import java.util.*;
    import javax.swing.*;
    
    /**
     * 画弹力球的部件.
     * @version 1.34 2012-01-26
     * @author Cay Horstmann
     */
    public class BallComponent extends JPanel
    {
       private static final int DEFAULT_WIDTH = 450;
       private static final int DEFAULT_HEIGHT = 350;
    
       private java.util.List<Ball> balls = new ArrayList<>();
    
       /**
        * 增加一个球到组件上。
        * @param b the ball to add
        */
       
       //创建add方法,在add方法中使用球类型集合的add方法向集合中添加球
       public void add(Ball b)
       {
          balls.add(b);
       }
    
       //paintComponent方法中有一个Graphics类型的参数,这个参数保留着用于绘制图像和文本的设置。
       //在Java中,所有的绘制都必须使用Graphics对象,其中包含了绘制图案,图像和文本的方法。
       public void paintComponent(Graphics g)
       {
          super.paintComponent(g); // 使用背景色绘制面板
          Graphics2D g2 = (Graphics2D) g;
          
          //获取每一个球的位置和形状并使用默认颜色进行填充
          for (Ball b : balls)
          {
             g2.fill(b.getShape());
          }
       }
       
       public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); }
    }

    Bounce类:

    package bounce;
    
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    /**
     * 显示动画弹跳球。
     * @version 1.34 2015-06-21
     * @author Cay Horstmann
     */
    public class Bounce
    {
       public static void main(String[] args)
       {
          EventQueue.invokeLater(() -> {
             JFrame frame = new BounceFrame();
             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.setVisible(true);
          });
       }
    }
    
    /**
     * 有球部件和按钮的框架。
     */
    class BounceFrame extends JFrame
    {
       private BallComponent comp;
       public static final int STEPS = 1000;
       public static final int DELAY = 3;
    
       /**
        * 构造包含用于显示弹跳球和启动和关闭按钮的框架 
        */
       public BounceFrame()
       {
          setTitle("Bounce");
          comp = new BallComponent();
          add(comp, BorderLayout.CENTER);
          JPanel buttonPanel = new JPanel();
          
          //使用addBuuton方法为按钮添加标题,监听器,并且将按钮添加至面板中
          addButton(buttonPanel, "Start", event -> addBall());
          addButton(buttonPanel, "Close", event -> System.exit(0));
          
          //将按钮面板添加至框架的南部
          add(buttonPanel, BorderLayout.SOUTH);
          pack();
       }
    
       /**
        *向容器添加按钮
        * @param c the container
        * @param 为按钮设置标题
        * @param 为按钮设置监听器
        */
       public void addButton(Container c, String title, ActionListener listener)
       {
          JButton button = new JButton(title);
          c.add(button);
          button.addActionListener(listener);
       }
    
       /**
        * 在面板中添加一个弹跳球,使其弹跳1000次。
        */
       public void addBall()
       {
          try
          {
             Ball ball = new Ball();
             comp.add(ball);
    
             for (int i = 1; i <= STEPS; i++)
             {
                //这样设置的话所有球的移动都处于一个线程当中
                ball.move(comp.getBounds());
                comp.paint(comp.getGraphics());
                Thread.sleep(DELAY);
             }
          }
          //中断异常
          catch (InterruptedException e)
          {
          }
       }
    }

    运行结果如下:

    代码二:

    Ball类:

    package bounce;
    
    import java.awt.geom.*;
    
    /**
     * 在长方形边缘上移动和反弹的球
     * @version 1.33 2007-05-17
     * @author Cay Horstmann
     */
    public class Ball
    {
       private static final int XSIZE = 15;
       private static final int YSIZE = 15;
       private double x = 0;
       private double y = 0;
       private double dx = 1;
       private double dy = 1;
    
       /**
        * 将球移动到下一个位置,如果碰到其中一个边,则反转方向
        */
       public void move(Rectangle2D bounds)
       {
          x += dx;
          y += dy;
          //宽度上的最小位置
          if (x < bounds.getMinX())
          {
             x = bounds.getMinX();
             dx = -dx;
          }
        //宽度上的最大位置
          if (x + XSIZE >= bounds.getMaxX())
          {
             x = bounds.getMaxX() - XSIZE;
             dx = -dx;
          }
          //高度上的最小位置
          if (y < bounds.getMinY())
          {
             y = bounds.getMinY();
             dy = -dy;
          }
        //宽度上的最大位置
          if (y + YSIZE >= bounds.getMaxY())
          {
             y = bounds.getMaxY() - YSIZE;
             dy = -dy;
          }
       }
    
       /**
        * 获取球在其当前位置的形状
        */
       public Ellipse2D getShape()
       {
          return new Ellipse2D.Double(x, y, XSIZE, YSIZE);
       }
    }

    BallComponent类:

    package bounce;
    
    import java.awt.*;
    import java.util.*;
    import javax.swing.*;
    
    /**
     * 画弹力球的部件.
     * @version 1.34 2012-01-26
     * @author Cay Horstmann
     */
    public class BallComponent extends JPanel
    {
       private static final int DEFAULT_WIDTH = 450;
       private static final int DEFAULT_HEIGHT = 350;
    
       private java.util.List<Ball> balls = new ArrayList<>();
    
       /**
        * 增加一个球到组件上。
        * @param b the ball to add
        */
       
       //创建add方法,在add方法中使用球类型集合的add方法向集合中添加球
       public void add(Ball b)
       {
          balls.add(b);
       }
    
       //paintComponent方法中有一个Graphics类型的参数,这个参数保留着用于绘制图像和文本的设置。
       //在Java中,所有的绘制都必须使用Graphics对象,其中包含了绘制图案,图像和文本的方法。
       public void paintComponent(Graphics g)
       {
          super.paintComponent(g); // 使用背景色绘制面板
          Graphics2D g2 = (Graphics2D) g;
          
          //获取每一个球的位置和形状并使用默认颜色进行填充
          for (Ball b : balls)
          {
             g2.fill(b.getShape());
          }
       }
       
       public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); }
    }

    BounceThread类:

    package bounceThread;
    
    import java.awt.*;
    import java.awt.event.*;
    
    import javax.swing.*;
    
    /**
     * 显示动画弹跳球。
     * @version 1.34 2015-06-21
     * @author Cay Horstmann
     */
    public class BounceThread
    {
       public static void main(String[] args)
       {
          EventQueue.invokeLater(() -> {
             JFrame frame = new BounceFrame();
             frame.setTitle("BounceThread");
             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.setVisible(true);
          });
       }
    }
    
    /**
     * 有面板和按钮的框架。
     */
    class BounceFrame extends JFrame
    {
       private BallComponent comp;
       public static final int STEPS = 1000;
       public static final int DELAY = 5;
    
    
       /**
        * 构造包含用于显示弹跳球和开始和关闭按钮的组件的框架
        */
       public BounceFrame()
       {
          comp = new BallComponent();
          add(comp, BorderLayout.CENTER);
          JPanel buttonPanel = new JPanel();
          addButton(buttonPanel, "Start", event -> addBall());
          addButton(buttonPanel, "Close", event -> System.exit(0));
          add(buttonPanel, BorderLayout.SOUTH);
          pack();
       }
    
       /**
        * 添加一个按钮到框架中.
        * @param c the container
        * @param 为按钮设置标题
        * @param 为按钮设置监听器
        */
       public void addButton(Container c, String title, ActionListener listener)
       {
          JButton button = new JButton(title);
          c.add(button);
          button.addActionListener(listener);
       }
    
       /**
        * 在画布上添加一个弹跳球并开始一条线使其弹跳
        */
       public void addBall()
       {
          Ball ball = new Ball();
          comp.add(ball);
          
          //将移动球的代码放置在一个独立的线程中,运行这段代码可以提高弹跳球的相应性能
          //实现一个BallRunnable类,然后,将动画代码放在run方法中,这样就即将动画代码放在了一个单独的线程中
          Runnable r = () -> { 
             try
             {  
                for (int i = 1; i <= STEPS; i++)
                {
                   ball.move(comp.getBounds());
                   //调用组件的repaint方法,重新绘制组件
                   comp.repaint();
                   Thread.sleep(DELAY);
                }
             }
             catch (InterruptedException e)
             {
             }
          };
          
          //将Runnable对象作为入口参数传入Thread的构造函数,再调用start方法就可以启动线程
          Thread t = new Thread(r);
          t.start();
       }
    }

    运行结果如下:

     可以同时运行一个以上线程的程序叫多线程程序。

    实验2:结对编程练习:采用GUI界面设计以下程序,并创建程序归档文件。

    ● 设计一个100以内整数小学生四则运算练习程序,由计算机随机产生10道加减乘除练习题,

    学生输入答案,由程序检查答案是否正确,每道题正确计10分,错误不计分,10道题测试结束后给出测试总分;

    ● 将程序中测试练习题及学生答题结果输出到文件,文件名为test.txt。

    1)   程序设计思路简述;

    GUI界面设计思路:

          我在框架北部加了一个title(JLabel),在中部加了一个problemPanel面板,problemPanel面板布局为10行一列的网格布局,每一行又是一个contentPanel面板,在contentPanel面板中添加了显示题号的orderLabel,显示题目的problemLabel,用于作答的answer,显示对错的judgeLabel组件。在框架南部加了一个用于放置按钮的buttonPanel面板,里面分别放置makeProblemButton,submitbutton,reset

    Button和checkButton。另外还有一个用于显示txt文本的框架,其中只放置了一个display(JTextArea),最后,我加了一个计时器来限制作答时间(额外补充的)。这样,就完成了整个小学生四则运算练习程序的GUI页面布局。

    动作事件设计思路:我为出题按钮设置了一个problemAction监听器,监听器中又有一个makeOperation方法,用于生成题目,makeOperation方法中使用随机数产生两个操作数(第二个操作数过滤掉0),然后再产生一个1-4的随机数用于设置题目的类型,将生成的题目设置为problemLabel的标题,再将每个题的结果存在result数组中。同时为提交按钮设置了一个judgeAction监听器,将answer中输入的内容与result所存的结果相比较,想同judgeLabel则显示√,否则显示×。并为重置按钮设置resetAction监听器,将answer中输入的内容全部清空,但是不能在提交之后清空。最后为check按钮设置checkAction监听器,将所有信息读入txt文件,并且创建新框架,在新框架中显示出最后的信息。在倒计时动作事件中,我使用time类中的schedule方法实现了倒计时的功能,并且在时间剩余10秒时,字体会放大以用于强调,当时间到0时,会弹出信息对话框,并且当用户提交时,计时也会停止。

    2)   符合编程规范的程序代码;

     ArithmeticExercisesFrame类:

    package demo;
    
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.FlowLayout;
    import java.awt.Font;
    import java.awt.GridLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.Random;
    import java.util.Timer;
    import java.util.TimerTask;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JTextArea;
    import javax.swing.JTextField;
    
    public class ArithmeticExercisesFrame extends JFrame {
    
        private JPanel[] contentPanel=new JPanel[10];
        private JLabel[] orderLabel=new JLabel[10];
        private JLabel[] problemLabel=new JLabel[10];
        private JTextField[] answer=new JTextField[10];
        private JLabel[] judge=new JLabel[10];
        private JPanel problemPanel;
        private JButton submitButton;
        private JButton resetButton;
        private JPanel buttonPanel;
        private JLabel title;
        private JButton makeproblemButton;
        private int operands1;
        private int operands2;
        private int[] result=new int[10];
        private JButton checkButton;
        //private static int i=1;
        private File file=new File("小学生四则运算答案结果");
        private JTextArea textarea=new JTextArea(10,20);
        private JPanel timeLimitPanel;
        private JLabel sumTime;
        private JLabel timeLabel;
        private JLabel timechange;
        private JLabel s;
        private Timer time;
        private JOptionPane message;
        
        public ArithmeticExercisesFrame()
        {
            setSize(400,630);
            //添加标题
            JPanel titlePanel=new JPanel();
            title = new JLabel("小学生四则运算练习程序");
            title.setFont(new Font("宋体",Font.ROMAN_BASELINE,25));
            titlePanel.add(title);
            add(titlePanel,BorderLayout.NORTH);                        
            problemPanel = new JPanel();
            problemPanel.setLayout(new GridLayout(11,1));
            time();
            createQuestionBoard();
            addQuestionBoard();
            makeButtonPanel();
            add(problemPanel,BorderLayout.CENTER);
            
        }
        
        public void time()
        {
            timeLimitPanel = new JPanel();
            sumTime = new JLabel("总时间:180s");
            timeLabel = new JLabel("    倒计时:");
            timechange = new JLabel("180");
            s = new JLabel("s");
            
            sumTime.setFont(new Font("宋体",Font.ROMAN_BASELINE,20));
            sumTime.setForeground(Color.green);
            timeLabel.setFont(new Font("宋体",Font.ROMAN_BASELINE,20));
            timeLabel.setForeground(Color.red);
            timechange.setFont(new Font("宋体",Font.ROMAN_BASELINE,20));
            timechange.setForeground(Color.red);
            s.setFont(new Font("宋体",Font.ROMAN_BASELINE,20));
            s.setForeground(Color.red);
            
            timeLimitPanel.add(sumTime);
            timeLimitPanel.add(timeLabel);
            timeLimitPanel.add(timechange);
            timeLimitPanel.add(s);
            problemPanel.add(timeLimitPanel);
            
        }
        public void createQuestionBoard()
        {
            //为每一行创建一个面板
            for(int i=0;i<10;i++)
            {
                    contentPanel[i]=new JPanel();
                    contentPanel[i].setLayout(new FlowLayout(FlowLayout.CENTER,15,0));
            }
            orderLabel = new JLabel[] {
                    new JLabel("第一题:"),
                    new JLabel("第二题:"),
                    new JLabel("第三题:"),
                    new JLabel("第四题:"),
                    new JLabel("第五题:"),
                    new JLabel("第六题:"),
                    new JLabel("第七题:"),
                    new JLabel("第八题:"),
                    new JLabel("第九题:"),
                    new JLabel("第十题:")
            };
            for(int i=0;i<10;i++)
            {
                    problemLabel[i]=new JLabel("请出题");
                    answer[i]=new JTextField(8);
                    judge[i]=new JLabel("待定");
                    judge[i].setFont(new Font("宋体",Font.ROMAN_BASELINE,30));
            }
        }
        
        public void addQuestionBoard()
        {
            for(int i=0;i<contentPanel.length;i++)
            {
                contentPanel[i].add(orderLabel[i]);
                contentPanel[i].add(problemLabel[i]);
                contentPanel[i].add(answer[i]);
                contentPanel[i].add(judge[i]);
                problemPanel.add(contentPanel[i]);
            }
        }
        
        public void makeButtonPanel() {
            buttonPanel = new JPanel();
            buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER,10,0));
            makeproblemButton = new JButton("出题");
            submitButton=new JButton("提交");
            resetButton=new JButton("重置");
            checkButton = new JButton("查看");
            buttonPanel.add(makeproblemButton);
            buttonPanel.add(submitButton);
            buttonPanel.add(resetButton);
            buttonPanel.add(checkButton);
            
            ActionListener problem=new problemAction();
            ActionListener countDown=new timeAction();
            makeproblemButton.addActionListener(problem);
            makeproblemButton.addActionListener(countDown);
            
            
            ActionListener judge=new judgeAction();
            submitButton.addActionListener(judge);
            
            ActionListener reset=new resetAction();
            resetButton.addActionListener(reset);
            
            ActionListener check=new checkAction();
            checkButton.addActionListener(check);
            
            add(buttonPanel,BorderLayout.SOUTH);        
        }
        
         //产生加减乘除运算的方法
        public void makeOperation()
        {       
            for(int i=0;i<10;i++)
            {
                Random rand=new Random();
                int temp;
                operands1 = rand.nextInt(100) +1;    
                operands2=rand.nextInt(100) +1;
                while(operands2==0)
                {
                    operands2=rand.nextInt(100) +1;
                }
                int index=rand.nextInt(4) +1;
                switch(index)
                {
                    case 1:problemLabel[i].setText(operands1+"+"+operands2);
                           result[i] = operands1+operands2;
                           break;
                    case 2:problemLabel[i].setText(operands1+"-"+operands2);
                           result[i]=operands1-operands2;
                           break;
                    case 3:problemLabel[i].setText(operands1+"*"+operands2);
                           result[i]=operands1*operands2;
                           break;
                    case 4:problemLabel[i].setText(operands1+"/"+operands2);
                           result[i]=operands1/operands2;
                           break;
                    default:System.out.println("error!");
                }
            }
        }
        //判断对错的方法
        public void judgeProblem()
        {
            int score=0;
            for(int i=0;i<10;i++)
            {
                //System.out.println(result[i]);
                int res=Integer.parseInt(answer[i].getText());
                //System.out.println(res);
                if(res==result[i])
                {
                    judge[i].setText("√");
                    judge[i].setForeground(Color.green);
                    score+=10;
                }
                else {
                    judge[i].setText("×");
                    judge[i].setForeground(Color.red);
                    score+=0;
                }
                textarea.append(orderLabel[i].getText()+" "+problemLabel[i].getText()+"    "+"你的答案:"+answer[i].getText()+"    正确答案:"+result[i]+"
    ");
            }
            textarea.append("你的总得分是:"+score+"
    ");
        }
        
        public void savefile() {
            try {
                FileWriter fw=new FileWriter(file);
                //System.out.println(textarea.getText());
                fw.write(textarea.getText());
                fw.close();
            }catch (FileNotFoundException e) {
                System.out.println("信息文件找不到");
                e.printStackTrace();
            } catch (IOException e) {
                System.out.println("信息文件读取错误");
                e.printStackTrace();
            }
        }
        
        //出题监听器
        class problemAction implements ActionListener{
            @Override
            public void actionPerformed(ActionEvent e) {
                makeOperation();
                for(int i=0;i<10;i++)
                {
                    judge[i].setVisible(false);
                    answer[i].setText(null);
                }
                
            }
            
        }
        //判断正误监听器
        class judgeAction implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                judgeProblem();
                savefile();
                for(int i=0;i<10;i++)
                {
                    judge[i].setVisible(true);
                }
                time.cancel();
            }
        }
        
        //查看结果监听器
        class checkAction implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                EventQueue.invokeLater(() -> {
                     var frame = new checkFrame();
                     frame.setTitle("小学生四则运算答案结果");
                     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                     frame.setVisible(true);
                  });
            }
        }
        
      //重置监听器
        class resetAction implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                for(int i=0;i<10;i++)
                {
                    if(!judge[i].isVisible())
                    {
                        answer[i].setText(null);
                    }
                }
            }
        }
        
        //倒计时监听器
        class timeAction implements ActionListener{
    
            private int i=180;
            @Override
            public void actionPerformed(ActionEvent e) {        
                    time = new Timer();
                    
                    time.schedule(new TimerTask() {
                        public void run() {
                            timechange.setText(""+(i--));
                            if(i<=10)
                            {
                                timechange.setFont(new Font("宋体",Font.ROMAN_BASELINE,30));
                            }
                            if(i<0)
                            {
                                time.cancel();
                                message.showMessageDialog(ArithmeticExercisesFrame.this,"同学,考试时间已结束,请立即停止作答!");
                                for(int i=0;i<10;i++)
                                {
                                    answer[i].setEditable(false);
                                }
                            }
                        }
                    }, 0, 20);        
                }            
            }
    }

    checkFrame类:

    package demo;
    
    import java.awt.BorderLayout;
    import java.awt.Font;
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    import javax.swing.JFrame;
    import javax.swing.JTextArea;
    
    public class checkFrame extends JFrame {
           private JTextArea display;
           private File file;
           //private static int i=1;
           public checkFrame()
               {
                   setSize(400,600);
                   
                   display = new JTextArea(10,20);
                   add(display,BorderLayout.CENTER);
                   loadfile();
               }
           public void loadfile() {
                   try {
                          file=new File("小学生四则运算答案结果");
                          FileInputStream fis = new FileInputStream(file);
                       BufferedReader in = new BufferedReader(new InputStreamReader(fis));
                       String temp = null;
                       display.append("              小学生四则运算答案结果"+"
    ");
                       while((temp=in.readLine())!=null)
                       {
                               display.append(temp+"
    ");
                       }
                       display.setFont(new Font("宋体",Font.ROMAN_BASELINE,15));
                       in.close();
                       
                   }catch (FileNotFoundException e) {
                       System.out.println("信息文件找不到");
                       e.printStackTrace();
                } catch (IOException e) {
                       System.out.println("信息文件读取错误");
                       e.printStackTrace();
                }
           }
    }

    ArithmeticExercisesFrameTest类:

    package demo;
    
    import java.awt.*;
    import javax.swing.*;
    
    /**
     * @version 1.35 2018-04-10
     * @author Cay Horstmann
     */
    public class ArithmeticExercisesFrameTest
    {
       public static void main(String[] args)
       {
          EventQueue.invokeLater(() -> {
             var frame = new ArithmeticExercisesFrame();
             frame.setTitle("小学生四则运算练习程序");
             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.setVisible(true);
          });
       }
    }

    3)   程序运行功能界面截图;

     4)   结对过程描述,提供两人在讨论、细化和编程时的结对照片(非摆拍)。

     

    5)程序归档文件

    实验总结:(15分)

           通过本章的第一个测试程序,我掌握了Java应用程序的打包操作,按我的理解是,如果将Java应用程序打包之后就可以直接发给其他人,而那个人就可以在安装了java虚拟机的计算机上直接运行此应用程序,大大加大了应用程序的可移植性。通过第三个测试程序,我掌握了线程创建的两种技术。在结对编程中,一些不懂的知识点我也通过上网查询慢慢掌握了,最终的编程效果我还是比较满意的,但是程序还是有可提高的余地,我会继续努力,将此程序不断完善,并在此过程中掌握更多的API以及编程技巧。

  • 相关阅读:
    springboot项目前端页面中文搜索时,数据库查询为空(mysql)
    Eclipse修改项目包名
    eclipse中maven父子项目层级显示设置
    springboot整合pagehelper实现分页
    eclipse设置文档注释
    永久修改mysql时区
    前端页面展示时间与数据库时间相差8小时(mysql)
    前端页面展示时间与数据库时间相差5小时(mysql)
    AxureRP 9安装、激活、汉化
    PowerDesigner 16.5安装、激活
  • 原文地址:https://www.cnblogs.com/xiaobeike/p/12034373.html
Copyright © 2011-2022 走看看