前言
《Head First Java》QuizCard示例代码
一、QuizCard
/**
* Title : QuizCard.java
* Description: This class contains the definition of the QuizCard.
*
* @author : Zhonghao Yan
* @version : 18/05/2022
*/
public class QuizCard {
private String question;
private String answer;
QuizCard(String question, String answer) {
this.question = question;
this.answer = answer;
}
// public void setQuestion(String question) { this.question = question; }
// public void setAnswer(String answer) { this.answer = answer; }
public String getQuestion() {
return question;
}
public String getAnswer() {
return answer;
}
}
二、QuizCardBuilder
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import java.io.*;
/**
* Title : QuizCardBuilder.java
* Description: This class contains the definition of the QuizCardBuilder
* which can design and store the card.
*
* @author : Zhonghao Yan
* @version : 18/05/2022
*/
public class QuizCardBuilder {
private JTextArea question;
private JTextArea answer;
private ArrayList<QuizCard> cardList;
public JFrame frame;
public static void main(String[] args) {
QuizCardBuilder builder = new QuizCardBuilder();
builder.go();
}
/**
* Run the builder to create and store quiz card
*/
public void go() {
frame = new JFrame("Quiz Card Builder");
JPanel mainPanel = new JPanel();
Font bigFont = new Font("sanserif", Font.BOLD, 24);
question = new JTextArea(6, 20);
question.setLineWrap(true); // 自动换行
question.setWrapStyleWord(true);
question.setFont(bigFont);
JScrollPane qScroller = new JScrollPane(question);
qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
qScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
answer = new JTextArea(6, 20);
answer.setLineWrap(true); // 自动换行
answer.setWrapStyleWord(true);
answer.setFont(bigFont);
JScrollPane aScroller = new JScrollPane(answer);
aScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
aScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
JButton nextBUtton = new JButton("Next Card");
cardList = new ArrayList<>();
JLabel qLabel = new JLabel("Question:");
JLabel aLabel = new JLabel("Answer:");
/*
创建菜单,把new与save项目驾到File下,然后指定frame使用这个菜单,菜单项目会触发ActionEvent
*/
mainPanel.add(qLabel);
mainPanel.add(qScroller);
mainPanel.add(aLabel);
mainPanel.add(aScroller);
nextBUtton.addActionListener(new NextCardListener());
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenuItem newMenuItem = new JMenuItem("New");
JMenuItem saveMenuItem = new JMenuItem("Save");
newMenuItem.addActionListener(new NewMenuListener());
saveMenuItem.addActionListener(new SaveMenuListener());
fileMenu.add(newMenuItem);
fileMenu.add(saveMenuItem);
menuBar.add(fileMenu);
frame.setJMenuBar(menuBar);
frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
frame.setSize(500, 600);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
/**
* Monitor the action when we create next quiz card
*/
public class NextCardListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
QuizCard card = new QuizCard(question.getText(), answer.getText());
cardList.add(card);
clearCard();
}
}
/**
* Monitor the action when we save the quiz card we have created
*/
public class SaveMenuListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
QuizCard card = new QuizCard(question.getText(), answer.getText());
cardList.add(card);
/*
showSaveDialog(Component parent)
显示保存文件的对话框
参数parent: 文件选取器对话框的父组件, 对话框将会尽量显示在靠近 parent 的中心; 如果传 null, 则显示在屏幕中心。
File getSelectedFile()
返回一个File对象,获取选择的文件
*/
JFileChooser fillSave = new JFileChooser();
fillSave.showSaveDialog(frame);
saveFile(fillSave.getSelectedFile());
}
}
/**
* Monitor the action when we create new file
*/
public class NewMenuListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
cardList.clear();
clearCard();
}
}
/**
* Clear the JTextArea to wait next input
*/
private void clearCard() {
question.setText("");
answer.setText("");
question.requestFocus();
}
/**
* Save the data of the quiz card
* @param file The object of File we choose in the dialog
*/
private void saveFile(File file) {
try {
/*
将BufferWriter链接到FileWriter
效率会更高,先在缓存区暂存一些内容,等缓存区满了后一并写入
如果需要强制缓存区立即写入,调用flush()方法即可
*/
BufferedWriter writer = new BufferedWriter(new FileWriter((file)));
for (QuizCard card : cardList) {
// 将ArrayList中的卡片逐个写到文件中,一行一张卡片
writer.write(card.getQuestion() + "/");
writer.write(card.getAnswer() + "\n");
}
writer.close();
} catch (IOException ex) {
System.out.println("couldn't write the cardList out");
ex.printStackTrace();
}
}
}
三、QuizCardPlayer
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import java.io.*;
/**
* Title : QuizCardPlayer.java
* Description: This class contains the definition of the QuizCardPlayer
* which can let users play the game.
*
* @author : Zhonghao Yan
* @version : 18/05/2022
*/
public class QuizCardPlayer {
private JTextArea display;
private JTextArea answer;
private ArrayList<QuizCard> cardList;
private QuizCard currentCard;
private int currentCardIndex;
private JFrame frame;
private JButton nextButton;
private boolean isShowAnswer;
public static void main(String[] args) {
QuizCardPlayer reader = new QuizCardPlayer();
reader.go();
}
private void go() {
frame = new JFrame("Quiz Card Player");
JPanel mainPanel = new JPanel();
Font bigFont = new Font("sanserif", Font.BOLD, 24);
display = new JTextArea(10, 20);
display.setFont(bigFont);
display.setLineWrap(true);
display.setEditable(false); // 禁止编辑
JScrollPane qScroller = new JScrollPane(display);
qScroller.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
qScroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
nextButton = new JButton("Show Question");
mainPanel.add(qScroller);
mainPanel.add(nextButton);
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenuItem loadMenuItem = new JMenuItem("Load card set");
loadMenuItem.addActionListener(new OpenMenuListener());
fileMenu.add(loadMenuItem);
menuBar.add(fileMenu);
frame.setJMenuBar(menuBar);
frame.getContentPane().add(BorderLayout.CENTER, mainPanel);
frame.setSize(640, 500);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
/**
* Monitor the action when we click the next button
*/
public class NextCardListener implements ActionListener {
public void actionPerformed(ActionEvent ev) {
if (isShowAnswer) {
// 显示答案
display.setText(currentCard.getAnswer());
nextButton.setText("Next Card");
isShowAnswer = false;
} else {
if (currentCardIndex < cardList.size()) {
showNextCard();
} else {
// 没有更多的卡片了
display.setText("That is the last card");
nextButton.setEnabled(false); // 禁用按钮
}
}
}
}
/**
* Monitor the action when we click menu
*/
public class OpenMenuListener implements ActionListener {
public void actionPerformed(ActionEvent ev) {
JFileChooser fileOpen = new JFileChooser();
fileOpen.showSaveDialog(frame);
loadFile(fileOpen.getSelectedFile());
}
}
/**
* Read the file, and split the String of line to make card
* @param file The object of File we choose in the dialog
*/
public void loadFile(File file) {
cardList = new ArrayList<>();
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = null;
while ((line = reader.readLine()) != null) {
// 读取一行数据,传给makeCard(),将字符串解析成卡片
makeCard(line);
}
reader.close();
} catch (Exception ex ) {
System.out.println("Couldn't read the card file");
ex.printStackTrace();
}
}
/**
* Split the String of the line to question and answer
* @param lineToParse One line of the file.
*/
private void makeCard(String lineToParse) {
String[] result = lineToParse.split("/");
QuizCard card = new QuizCard(result[0], result[1]);
cardList.add(card);
System.out.println("made a card");
}
public void showNextCard() {
currentCard = cardList.get(currentCardIndex);
currentCardIndex++;
display.setText(currentCard.getQuestion());
nextButton.setText("Show Answer");
isShowAnswer = true;
}
}