实训内容:模仿“百词斩”手机App,设计并用Java语言实现一个“百词斩”图形界面程序(根据自己的能力,可以适当地增加或删除部分功能)。
参考程序界面:
设计思路:
(1)事先将一定数量的英语单词存入一个文本文件中(一个单词的信息占一行,单词和中文解释之间用空格分隔)。附件words.txt是四级单词表。
(2)从文件中取出所有单词的信息,存入总单词表中(ArrayList类型)。
(3)从总单词表中,随机取出N单词(为了测试方便,N值可以取小一点,比如N=10)存入测试的单词表中(ArrayList类型)。每次从总单词表中取出一个单词后,从总单词表中删除已取出的单词。
(4)从测试的单词表中,随机取一个单词。将英语单词和中文解释分开。如: ability n.能力;能耐,本领
将“ability”作为要测试的单词,“n.能力;能耐,本领”作为答案。
随机产生选项的序号(0、1、2、3),在该选项的后面放入正确答案。
(5)从总单词表中随机取出3个不同的单词。分离出三个单词的中文解释部分,并作为其它三个错误选项(四个选项不能有重复,如果有重复,再取一个单词)。
(6)在四个单选按钮中添加动作监听。如果答对了,更新答对单词的数量,并从测试的单词表中,删除答对的单词。如果答错了,显示正确答案。不管是答对还是答错,一旦选了,就不能更改(不能再选)。
(7)所有的单词都答对了,即测试单词表是空的,“继续”按钮变成不可用。
最低要求:
答对的单词,以后不会出现。
基本扩展:
(1)一次答对的单词,以后不会再出现。
(2)答错一次,要把这个单词加到测试的单词表中。例如,某个单词答错3次,在测试单词表中,这个单词应该出现4次。也就是说,一个单词答错一次,以后出现的几率会增加一倍。
(3)一个单词答错后,单词表中会有多个备份。以后再答对一次,只能删除一个备份。某个单词所有的备份都删除了,说明这个单词已经掌握了,这时才能计入答对的单词数量。
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class Bczh extends JFrame implements ActionListener {
// 所有的单词
ArrayList<String> totalWords = new ArrayList<String>();
// 用来测试的单词
ArrayList<String> testWords = new ArrayList<String>();
JPanel JPanel_center=new JPanel();
JPanel JPanel_north=new JPanel();
JPanel JPanel_south=new JPanel();
JLabel scoreLabel = new JLabel(); // 答对单词数
JLabel wordLabel = new JLabel(); // 正在测试的单词
JLabel blankLabel = new JLabel(); //设置空的标签
ButtonGroup group = new ButtonGroup();// 单选按钮组
JRadioButton rb1 = new JRadioButton();// 选项一单选按钮
JRadioButton rb2 = new JRadioButton();// 选项二单选按钮
JRadioButton rb3 = new JRadioButton();// 选项三单选按钮
JRadioButton rb4 = new JRadioButton();// 选项四单选按钮
JLabel answerLabel = new JLabel(); // 显示正确答案标签
JButton continueButton = new JButton("继续");
JButton endButton = new JButton("结束");
// 英语单词和正确答案
String Englishword;
String answer;
String item[] = new String[4];//存储四个选项存储
int right=0;//答对单词的个数
int whole=0;//测试总单词的个数(对的错的都算)
int totalNum=10;// 测试的单词总数(错的不算)
int okNum = 0; // 答对的单词数
int m=0;//记录答案位置
String wrong="";//记录答错的单词
Bczh() throws IOException {
this.setTitle("百词斩");
this.setSize(500, 600);
this.setLayout(new BorderLayout());
JPanel_south.setLayout(new GridLayout(1,2,3,3));
JPanel_center.setLayout(null);
JPanel_north.setLayout(new GridLayout(1,2));
// 设置答对的单词数
Font font = new Font("粗体",Font.BOLD,24);
scoreLabel.setText("答对的题数为: "+okNum+"/"+totalNum);
scoreLabel.setForeground(Color.red);// 设置颜色
scoreLabel.setFont(font); // 设置字体
JPanel_north.add(blankLabel);
JPanel_north.add(scoreLabel);//将标签对齐在右边
//设置按钮字体
continueButton.setFont(font);
endButton.setFont(font);
// 设置正在测试的英语单词的字体
wordLabel.setFont(font);
rb1.setFont(font);// 设置选项一的字体字号
rb2.setFont(font);// 设置选项二的字体字号
rb3.setFont(font);// 设置选项三的字体字号
rb4.setFont(font);// 设置选项四的字体字号
wordLabel.setBounds(40, 80, 200, 30);
rb1.setBounds(30, 120, 400, 80);
rb2.setBounds(30, 170, 400, 80);
rb3.setBounds(30, 220, 400, 80);
rb4.setBounds(30, 270, 400, 80);
// 添加动作命令标识
rb1.setActionCommand("1");
rb2.setActionCommand("2");
rb3.setActionCommand("3");
rb4.setActionCommand("4");
// 将各个单选按钮加入到按钮组,确保多选一(一个按钮组内只能选一项)
group.add(rb1);
group.add(rb2);
group.add(rb3);
group.add(rb4);
// 四个选项按钮添加监听
rb1.addActionListener(this);
rb2.addActionListener(this);
rb3.addActionListener(this);
rb4.addActionListener(this);
// 设置答案标签
answerLabel.setBounds(50, 350, 350, 50);
answerLabel.setFont(font);
answerLabel.setForeground(Color.red);// 设置答案的文字颜色
// 设置继续按钮
continueButton.setFont(font);
continueButton.setBounds(100, 450, 120, 30);
continueButton.setActionCommand("continue");// 添加动作命令标识
continueButton.addActionListener(this);// 添加监听
// 设置结束按钮
endButton.setFont(font);
endButton.setBounds(250, 450, 120, 30);
endButton.setActionCommand("end");
endButton.addActionListener(this); // 添加监听
// 将个组件添加到窗口中
this.add(JPanel_center,BorderLayout.CENTER);
this.add(JPanel_south,BorderLayout.SOUTH);
this.add(JPanel_north,BorderLayout.NORTH);
JPanel_center.add(wordLabel);
JPanel_center.add(rb1);
JPanel_center.add(rb2);
JPanel_center.add(rb3);
JPanel_center.add(rb4);
JPanel_center.add(answerLabel);
JPanel_south.add(continueButton);
JPanel_south.add(endButton);
//设置界面参数
this.setResizable(false);
this.setVisible(true); // 设置窗口可见
this.setLocationRelativeTo(null);// 设置窗口位置
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//对标签进行加文本操作
add();
addtestWords();
add1();
}
//将文件中的全部单词内容放入Arraylist列表中
void add() throws IOException{
BufferedReader br=new BufferedReader(new FileReader("C:\\Users\\岚铃\\Desktop\\words.txt"));
String[] content=new String[600];
String str;
int all=0;
while((str=br.readLine())!=null){
content[all]=str;
totalWords.add(content[all]);
all++;
}
}
//从totalWords列表中取出totalNum数量放入testWords中
void addtestWords(){
for(int i=0;i<totalNum;i++){
this.testWords.add(this.totalWords.get(casual(totalWords.size())));
}
}
//给选项以及wordLabel添加文本
void add1(){
split(0);
wordLabel.setText(Englishword);
m=casual(4);
item[m]=answer;
//给剩下的三个选项赋值,并保证选项内容不相等
for(int i=0;i<4;i++){
if(i!=m){
item[i]=totalWords.get(casual(totalWords.size()-1)+1);
item[i]=item[i].substring(item[i].indexOf(" ")+1);
}}
for(int j=0;j< item.length;j++){
for(int n=j+1;n<item.length;n++){
if((n!=m)&&item[j].equals(item[n])){
item[n]=totalWords.get(casual(totalWords.size()-1)+1);
item[n]=item[n].substring(item[n].indexOf(" ")+1);
}
if((n==m)&&item[j].equals(item[n])){
item[j]=totalWords.get(casual(totalWords.size()-1)+1);
item[j]=item[j].substring(item[j].indexOf(" ")+1);
}
}
}
rb1.setText(item[0]);
rb2.setText(item[1]);
rb3.setText(item[2]);
rb4.setText(item[3]);
}
//获取(0,m])范围内的随机数
int casual(int m){
int x=(int)(Math.random()*m);
return x;
}
//设置按钮的可选状态
void notselected(){
rb1.setEnabled(false);
rb2.setEnabled(false);
rb3.setEnabled(false);
rb4.setEnabled(false);
}
//从testWords中取出一个元素,并分离出单词和答案
void split(int i){
String[] temp=new String[2];
temp=testWords.get(i).split(" ");
Englishword=temp[0];
answer=temp[1];
}
@Override
public void actionPerformed(ActionEvent e) {
String click=e.getActionCommand();
int wrongsum=0;
int rightsum=0;
//判断答案在第几个item里
for(int i=0;i<4;i++){
if(item[i].equals(answer))
m=i;
}
//对命令标识进行识别
if(click.equals(""+(m+1))){
answerLabel.setText("√");
//如果选中全部选项设为不可选
notselected();
right++;
okNum++;
scoreLabel.setText("答对的题数为: "+okNum+"/"+totalNum);
//每次读取第0个数据,如果正确就删掉
testWords.remove(0);
}
if(click.matches("[1234]{1}")&&(!click.equals(""+(m+1)))){
answerLabel.setText("x "+answer);
notselected();
//每次读取第0个数据,如果错误就在加入testwords并设置范围,并使下一个不会出现刚错的单词
testWords.add(casual(testWords.size()-2)+2,testWords.get(0));
testWords.remove(0);
}
if(click.equals("continue")){
//解除按钮不可选状态
rb1.setEnabled(true);
rb2.setEnabled(true);
rb3.setEnabled(true);
rb4.setEnabled(true);
whole++;
//清空答案文本
answerLabel.setText("");
//更改标签文本
add1();
//对按钮进行取消聚焦操作
group.clearSelection();
}
if(totalNum==okNum)
continueButton.setEnabled(false);
if(click.equals("end")){
whole++;
//设置新的窗口,并关闭当前窗口
new iscontinueWindow(whole,right);
this.dispose();
}
}
public static void main(String[] args) throws IOException {
Bczh win = new Bczh();
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.ArrayList;
public class iscontinueWindow extends JFrame implements ActionListener {
JLabel summary=new JLabel();//设置上次总结
JLabel great=new JLabel();//设置评价标签
JLabel accuracy=new JLabel();//设置正确率标签
JButton goon=new JButton();
JButton end=new JButton();
JPanel JP_center=new JPanel();
JPanel JP_south=new JPanel();
iscontinueWindow(int whole,int right){
//设置窗口参数,与上个窗口大小位置相同
this.setTitle("百词斩");
this.setSize(500, 600);
this.setLayout(new BorderLayout());
this.setResizable(false);//窗口大小设为不可更改
this.setVisible(true); // 设置窗口可见
this.setLocationRelativeTo(null);// 设置窗口位置
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置文本
summary.setText("答对的题数为: "+right+"/"+whole);
int tmp=(int)(((double)right/whole)*100);//统计正确率
accuracy.setText(""+tmp+"%");
goon.setText("再来一次");
end.setText("结束");
if(tmp>=50)
great.setText("YOU ARE GREAT!(太棒了吧!)");
else
great.setText("TRY AGAIN!(再接再厉!)");
//设置字体的大小和颜色和文本
Font f=new Font("粗体",Font.BOLD,25);
summary.setFont(f);
accuracy.setFont(f);
great.setForeground(Color.MAGENTA);
great.setFont(f);
goon.setFont(f);
end.setFont(f);
//设置组件
JP_center.setLayout(new GridLayout(6,1));
JP_south.setLayout(new GridLayout(1,2,5,5));
JP_center.add(summary);
JP_center.add(accuracy);
JP_center.add(great);
JP_south.add(goon);
JP_south.add(end);
this.add(JP_center,BorderLayout.CENTER);
this.add(JP_south,BorderLayout.SOUTH);
//设置监听事件
goon.addActionListener(this);
end.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
String click=e.getActionCommand();
if(click.equals("再来一次")){
try {
new Bczh();
} catch (IOException ex) {
throw new RuntimeException(ex);
}
this.dispose();//关闭当前窗口
}
if(click.equals("结束")){
this.dispose();//关闭当前窗口
}
}
}
运行结果