目标效果:
界面没有优化,而且体验一般,先以实现功能为主
代码:
package Ten;
/**
* 在电视节目中经常看见主持人提出的问题,并要求考试者在限定时间内回答问题。
* 这里由程序提出问题,用户回答问题。问题保存在test.txt中,test.txt的格式如下。
* 每个问题提供A、B、C、D四个选择(单项选择)。
* 两个问题之间是用减号(-)尾加前一问题的答案分隔(例如:----D----)。
* 使用GUI界面,增加一个辅助限制答题时间的计时器线程,该线程限制用户必须在10秒内回答问题,一旦超过10秒,将进入下一题。
* @author Vivinia
*
* 2017年12月22日
*/
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
import javax.swing.Timer;
public class Exam extends JFrame implements ActionListener,ItemListener{
File fTest; //文件
FileReader frInput; //文件读取流
BufferedReader brInput; //缓冲字符流
Timer time; //计数器
JTextArea taShowQuestion; //文本区,显示题目
JRadioButton rbA,rbB,rbC,rbD; //选项
JLabel lbShowTime,lbShowScore; //时间标签,分数标签
JButton btReStart; //再来一次按钮
Box boxOne,boxTwo,boxBase,boxLable;
int MAX=10; //最大时间
int maxTime=MAX,score=0;
String correctAnswer; //正确答案
Exam(String title) {
super(title);
init(); //控件初始化
bindClick(); //控件绑定状态改变事件
}
//控件初始化
public void init() {
//基本控件实例化
time=new Timer(1000,this);
taShowQuestion=new JTextArea(3,20); //3行20列
lbShowScore = new JLabel("分数:"+score);
lbShowTime = new JLabel("剩余时间:");
rbA=new JRadioButton("A");
rbB=new JRadioButton("B");
rbC=new JRadioButton("C");
rbD=new JRadioButton("D");
btReStart=new JButton("再做一遍");
btReStart.setEnabled(false); //设置不可点击
//上方标签盒
boxLable=Box.createVerticalBox();
boxLable.add(lbShowTime);
boxLable.add(lbShowScore);
boxOne=Box.createHorizontalBox();
boxOne.add(boxLable);
boxOne.add(taShowQuestion);
//下方按钮盒
boxTwo=Box.createHorizontalBox();
boxTwo.add(rbA);
boxTwo.add(rbB);
boxTwo.add(rbC);
boxTwo.add(rbD);
boxTwo.add(btReStart);
//底层盒
boxBase=Box.createVerticalBox();
boxBase.add(boxOne);
boxBase.add(boxTwo);
add(boxBase);
//窗口基本设置
setSize(400,200);
setVisible(true); //设置可见
validate(); //生效
setLayout(new FlowLayout()); //组件按照加入的先后顺序按照设置的对齐方式从左向右排列,一行排满到下一行开始继续排列
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); //右上角关闭状态
}
//控件绑定状态改变事件
private void bindClick() {
rbA.addItemListener(this);
rbB.addItemListener(this);
rbC.addItemListener(this);
rbD.addItemListener(this);
btReStart.addActionListener(this);
}
//打开文件,参数为文件路径和文件名字
public void openTestFile(File f){
btReStart.setEnabled(false);
fTest=f;
try {
frInput=new FileReader(fTest); //创建文件读取流对象,和指定文件关联,如果文件不存在抛出异常
brInput=new BufferedReader(frInput); //包装字符流,将字符流放入缓存,等缓存满了或者flush时,再读入内存,提高读效率
readOneQuestion(); //读取一个问题
} catch (FileNotFoundException e1) {
taShowQuestion.setText("file");
e1.printStackTrace();
} catch (Exception e) {
taShowQuestion.setText("没有选题"+e.toString());
}
}
//读取一个问题
public void readOneQuestion() {
taShowQuestion.setText(null); //将文本区显示为空
try {
String s=null; //读取的字符串
while((s=brInput.readLine())!=null) { //从缓冲区中读入
if(!s.startsWith("-")) //字符串s不是以“-”开头,表示为题目
taShowQuestion.append("\n"+s); //文本区追加读取的字符串
else { //字符串以“-”开头,表示为答案
s=s.replace("-",""); //用空格代替“-”,方便答案比较
correctAnswer = s; //更新正确答案
break;
}
}
time.start(); //启动计时器
if(s==null) { //如果字符串空了,代表读取完毕
brInput.close(); //缓冲区关闭
btReStart.setEnabled(true); //“再做一遍”按钮可以点击
taShowQuestion.setText("题目完毕");
time.stop();
}
} catch (Exception e) {
e.printStackTrace();
}
}
//发生选择事件(单选按钮)
@Override
public void itemStateChanged(ItemEvent e) { //触发该方法可以是人为选中单选按钮,也可以是回答正确后按钮状态自动清空
JRadioButton rb=(JRadioButton) e.getSource();
String str=rb.getText();
boolean bOne=rb.isSelected(); //是否人为选中
boolean bTwo=str.compareToIgnoreCase(correctAnswer)==0; //比较忽略大小写,相等则返回0
if(bOne&&bTwo) { //如果是用户选中的并且答案正确
score++;
lbShowScore.setText("分数:"+score);
maxTime=MAX; //重新设置分数
readOneQuestion(); //更新题目
}
rb.setSelected(false); //清空选择情况
}
//页面发生变化(计时器和Button按钮)
@Override
public void actionPerformed(ActionEvent e) {
if(e.getSource()==time){ //如果计时器为发生动作的控件
lbShowTime.setText("剩:"+maxTime+"秒");
maxTime--;
if(maxTime<=0){ //时间结束
maxTime = MAX; //重新设置倒计时时间
readOneQuestion(); //更新题目
}
}
else if(e.getSource()==btReStart) //如果按钮为发生动作的控件
openTestFile(fTest); //重新读取文件
}
}
class Answer{
public static void main(String[] args) {
Exam em=new Exam("限时回答问题");
em.openTestFile(new File("C:\\","test.txt")); //打开文件,参数为文件路径和文件名字
}
}
test.txt文件为以下内容:
1. 北京奥运什么时间开幕的?
A.2008-08-08 B.2008-08-01
C.2008-10-01 D.2008-07-08
----------A----------
2. 下列哪种动物属于猫科动物?
A.猎狗 B.大象
C.棕熊 D.狮子
----------D----------
3. 下列哪个品牌的手机用的是ios系统?
A.华为 B.小米
C.格力 D.苹果
----------D----------