面向对象程序设计

面向对象程序设计:

1 背诵记录文件的读写

关键代码如下:

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectInputStream;

import java.io.ObjectOutputStream;

import java.util.Vector;

 

class RRecordGetter {

// 将传入的Vector写入filePath(背诵记录文件)文件中

public static boolean saveRRecords(

    String filePath, Vector<ReciteRecord> vect) {

    try {

        ObjectOutputStream outputStream =

        new ObjectOutputStream(

        new FileOutputStream(filePath));

        // 遍历vect,并写入记录文件

        for (ReciteRecord i : vect) {

        outputStream.writeUTF(i.word);

        outputStream.writeLong(i.startDate);

        outputStream.writeLong(i.lastDate);

        outputStream.writeInt(i.stage);

        outputStream.writeInt(i.strange);

        }

        outputStream.close();

    } catch (IOException e) {

        System.out.println(e.getMessage());

        return false;

    }

    return true;

}

 

// 读取记录文件,返回Vector

public static Vector<ReciteRecord> loadRRecords(

    String filePath, int n) {

        Vector<ReciteRecord> vect = new Vector<ReciteRecord>();

        try {

            ObjectInputStream inputStream =

            new ObjectInputStream(

            new FileInputStream(filePath));

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

            ReciteRecord temp = new ReciteRecord();

            temp.word = inputStream.readUTF();

            temp.startDate = inputStream.readLong();

            temp.lastDate = inputStream.readLong();

            temp.stage = inputStream.readInt();

            temp.strange = inputStream.readInt();

            vect.addElement(temp);

            }

            inputStream.close();

        } catch(Exception e) {

            System.out.println(e.getMessage());

        }

        return vect;

    }

}

2 词库文件的读取

 

// WordManager.java

package whypro.memorize;

 

import java.io.BufferedReader;

import java.io.FileReader;

import java.io.IOException;

import java.util.Random;

 

public class WordManager {

    protected String filePath;

    protected String fileName;

    protected int index;

 

    protected int indexBound;

 

    protected String word;

    protected String phonetic;

    protected String interp;

    protected String thesName;

 

    public WordManager(String filePath, String fileName) throws IOException {

        this.filePath = filePath;

        this.fileName = fileName;

        calcIndexBound();

    }

 

    public void getWordAndInterp() throws IOException {

        Random random = new Random(System.currentTimeMillis());

        this.index = Math.abs(random.nextInt() % indexBound);

 

        FileReader fr = new FileReader(filePath + '/' + fileName);

        BufferedReader br = new BufferedReader(fr);

        String line = br.readLine();    // 词库名称

        thesName = line;

        for (int i = 0; i < 4 * index; i++) {

            line = br.readLine();

        }

        while (!line.equals("")) {

            line = br.readLine();

        }

 

        this.word = br.readLine();

        this.phonetic = br.readLine();

        this.interp = br.readLine();

        br.close();

        fr.close();

    }

 

    public void calcIndexBound() throws IOException {

        FileReader fr = new FileReader(filePath + '/' + fileName);

        BufferedReader br = new BufferedReader(fr);

        String line = br.readLine();    // 词库名称

        int indexBound = 0;

        while (line != null) {

            if (line.equals("")) {

                indexBound++;

            }

            line = br.readLine();

        }

        this.indexBound = indexBound;

        br.close();

        fr.close();

    }

 

}

3 统计已背诵的单词:

 

// ReciteStat.java

package whypro.memorize;

 

import java.awt.BorderLayout;

import java.awt.Dimension;

import java.awt.Toolkit;

import java.text.DateFormat;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Vector;

 

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JScrollPane;

import javax.swing.JTable;

 

class ReciteStat extends JFrame {

 

    final JTable table;

    Vector<ReciteRecord> recordsVector;

    public ReciteStat() {

        JPanel mainPanel = new JPanel();

        mainPanel.setLayout(new BorderLayout());

        // 从记录文件中读取单词背诵记录并存入Object[][] o中

        recordsVector = RRecordGetter.loadRRecords("./record/recite.rec", 100);

        Object[][] o = new Object[recordsVector.size()][5];

        int j = 0;

        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        String str = null;

 

        for (ReciteRecord i : recordsVector) {

            o [j][0] = i.word;

            str = format.format(new Date(i.startDate));

            o [j][1] = str;

            str = format.format(new Date(i.lastDate));

            o [j][2] = str;

            o [j][3] = i.stage;

            o [j][4] = i.strange;

            ++j;

        }

 

        String[] names = {"单词", "首次记忆时间", "上次记忆时间", "记忆阶段", "陌生度"};

        table = new JTable(o, names);

 

        mainPanel.add(new JScrollPane(table));

 

        this.add(mainPanel);

        //

        this.setTitle("背诵情况统计");

        this.setSize(600, 400);

        this.setResizable(false);

 

        // 使窗口居中

        Toolkit kit = Toolkit.getDefaultToolkit(); // 定义工具包

        Dimension screenSize = kit.getScreenSize(); // 获取屏幕的尺寸

        int screenWidth = screenSize.width / 2; // 获取屏幕的宽

        int screenHeight = screenSize.height / 2; // 获取屏幕的高

        int height = this.getHeight();

        int width = this.getWidth();

        // 使窗口居中

        setLocation(screenWidth - width / 2, screenHeight - height / 2);

        this.setVisible(true);

    }

}

4 访问自定义字体文件

 

由于软件需要显示音标,因此定义了MyFont类,用于使用自定义字体显示单词的音标。关键代码如下:

 

// MyFont.java

package whypro.memorize;

 

import java.awt.Font;

import java.awt.FontFormatException;

import java.io.BufferedInputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.IOException;

 

public class MyFont {

    public static Font getFont(String filePath, String fileName, int style, float size)

            throws FontFormatException, IOException {

        File file = new File(filePath + '/' + fileName);

        FileInputStream fi;

        BufferedInputStream fb;

        Font font = null;

        fi = new FileInputStream(file);

        fb = new BufferedInputStream(fi);

        // 创建自定义字体

        font = Font.createFont(Font.TRUETYPE_FONT, fb);

        font = font.deriveFont(style, size);

        return font;

    }

}

5. GridBagLayout布局方式

 

软件使用了Swing更强大的GridBagLayout布局方式,代码如下:

 

// WordTester.java

package whypro.memorize;

 

import java.awt.*;

import java.awt.event.*;

import java.io.IOException;

import java.util.Vector;

 

import javax.swing.*;

 

 

class WordTester extends JFrame implements KeyListener, ActionListener {

 

    private static final long serialVersionUID = 1L;

 

    WordManager randomWord;

 

    final private JPanel mainPanel;

    final private JLabel lblEnglish;

    final private JLabel lblPhonetic;

    final private JTextArea txtChinese;

    final private JLabel lblStatus;

 

    final private JMenuBar menuBar = new JMenuBar();

    final private JMenu fileMenu = new JMenu("文件 (F)");

    final private JMenuItem chooseThItem = new JMenuItem("选择词库 (T)");

    final private JMenuItem statItem = new JMenuItem("词汇统计 (S)");

    final private JMenuItem exitItem = new JMenuItem("退出 (X)");

    final private JMenu helpMenu = new JMenu("帮助 (H)");

    final private JMenuItem aboutItem = new JMenuItem("关于 (A)");

 

    String strEnglish;  // 单词

    String strPhonetic; // 音标

    String strChinese; // 释义

    String strTName;    // 词库名

    String strSpelling = "";

    int wordLength; // 单词长度

    int strange = 0;    // 陌生度

 

    // 标志位,忽略一次Type事件

    boolean isCorrect = false;

 

 

 

    String fontPath = "./font"; // 字体路径

    String fontName = "TOPhonetic.ttf";

    String thesPath = "./thesaurus/TOFEL.txt";  // 词库路径

    String thesName = "";  

 

    String recordPath = "./record/recite.rec";  // 背诵记录文件路径

 

    Vector<ReciteRecord> recordsVector = new Vector<ReciteRecord>();    // 背诵记录

 

    public WordTester() {

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel mainPanel = new JPanel();

        mainPanel.setLayout(new GridBagLayout());

        GridBagConstraints c = new GridBagConstraints();

 

        // 初始化菜单栏

 

        fileMenu.setMnemonic('F');

        menuBar.add(fileMenu); 

        chooseThItem.setMnemonic('T');

        fileMenu.add(chooseThItem);

        chooseThItem.setMnemonic('T');

        fileMenu.add(statItem);

        exitItem.setMnemonic('S');

        fileMenu.add(exitItem);

        helpMenu.setMnemonic('H');

        menuBar.add(helpMenu);

        aboutItem.setMnemonic('A');

        helpMenu.add(aboutItem);

 

        chooseThItem.addActionListener(this);

        statItem.addActionListener(this);

        exitItem.addActionListener(this);

        aboutItem.addActionListener(this);

        this.setJMenuBar(menuBar);

 

 

        lblEnglish = new JLabel(strEnglish);

        lblEnglish.setBackground(Color.WHITE);

        // lblEnglish.setFont(new Font("Bradley Hand ITC", Font.BOLD, 50));

        lblEnglish.setFont(new Font("Arial", Font.BOLD, 50));

        c.fill = GridBagConstraints.HORIZONTAL;

        c.gridx = 0;

        c.gridy = 1;

        c.weightx = 1;

        mainPanel.add(lblEnglish, c);

 

        lblPhonetic = new JLabel(strPhonetic);

        lblPhonetic.setBackground(Color.WHITE);

 

        // 获取音标字体

        try {

            lblPhonetic.setFont(MyFont.getFont(

                    fontPath, fontName, Font.PLAIN, 20));

        } catch (FontFormatException e) {

            JOptionPane.showMessageDialog(this, e.getMessage());

            System.exit(0);

        } catch (IOException e) {

            JOptionPane.showMessageDialog(this, e.getMessage());

            System.exit(0);

        }

        c.fill = GridBagConstraints.HORIZONTAL;

        c.gridx = 0;

        c.gridy = 2;

        c.weightx = 1;

        c.weighty = 0.1;

        mainPanel.add(lblPhonetic, c);

 

        txtChinese = new JTextArea(strChinese);

        txtChinese.setLineWrap(true);

        txtChinese.setFont(new Font("华文仿宋", Font.PLAIN, 28));

        //txtChinese.setBackground(Color.black);

        //txtChinese.setForeground(Color.white);

 

        txtChinese.setEditable(false);

        c.fill = GridBagConstraints.BOTH;

        c.gridx = 0;

        c.gridy = 3;

        c.weightx = 1;

        c.weighty = 2;

        mainPanel.add(txtChinese, c);

 

        lblStatus = new JLabel(strTName);

        // lblEnglish.setFont(new Font("Bradley Hand ITC", Font.BOLD, 50));

        lblStatus.setFont(new Font("宋体", Font.PLAIN, 12));

        c.fill = GridBagConstraints.HORIZONTAL;

        c.gridx = 0;

        c.gridy = 4;

        c.weighty = 0.2;

        mainPanel.add(lblStatus, c);

 

 

        txtChinese.setFocusable(false);

        this.addKeyListener(this);

        lblEnglish.addKeyListener(this);

        lblPhonetic.addKeyListener(this);

        txtChinese.addKeyListener(this);

 

        // 软件运行时将背诵记录从文件载入内存

        recordsVector = RRecordGetter.loadRRecords(recordPath, 100);

        newRandomWord();

 

 

        this.add(mainPanel);

        //

        this.setTitle("whyNotMemorize");

        this.setSize(400, 400);

        this.setResizable(false);

 

        // 使窗口居中

        Toolkit kit = Toolkit.getDefaultToolkit(); // 定义工具包

        Dimension screenSize = kit.getScreenSize(); // 获取屏幕的尺寸

        int screenWidth = screenSize.width / 2; // 获取屏幕的宽

        int screenHeight = screenSize.height / 2; // 获取屏幕的高

        int height = this.getHeight();

        int width = this.getWidth();

        setLocation(screenWidth - width / 2, screenHeight - height / 2);

 

        this.setVisible(true);

    }

 

    @Override

    public void keyPressed(KeyEvent e) {}

 

    @Override

    public void keyReleased(KeyEvent e) {}

 

    @Override

    public void keyTyped(KeyEvent e) {

 

        // 当拼写正确时,忽略一次键盘事件,并产生新词

        if (isCorrect) {

            isCorrect = false;

            newRandomWord();

            return;

        }

 

        char ch = e.getKeyChar();

        // 单词长度限制

        if (strSpelling.length() < strEnglish.length()) {

            // 字母限制

            if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z' || ch == '-'

                || ch == '(' || ch == ')') {

                lblEnglish.setForeground(Color.BLACK);

                strSpelling += ch;

                lblEnglish.setText(strSpelling);

            }

        }

 

        // 退格键

        if (strSpelling.length() > 0) {

            if (ch == '\b') {

                strSpelling = strSpelling

                .substring(0, strSpelling.length() - 1);

                if (strSpelling.length() > 0) {

                    lblEnglish.setText(strSpelling);

                } else {

                    lblEnglish.setText(" ");

                }

            }

        }

 

        // 回车键

        if (ch == '\n' || ch == ' ') {

 

            if (strSpelling.equals(strEnglish)) {

                // 当拼写正确时,以蓝色字体显示,并设置isCorrect标志

                strSpelling = "";

                lblEnglish.setForeground(Color.blue);

                lblEnglish.setText(strEnglish);

                isCorrect = true;

 

                // 生成该单词背诵数据,并写入文件

                ReciteRecord record = new ReciteRecord(

                        strEnglish,

                        System.currentTimeMillis(), System.currentTimeMillis(),

                        0, strange);

                recordsVector.addElement(record);

                RRecordGetter.saveRRecords(recordPath, recordsVector);

 

            } else {

                // 当拼写不正确时,以红色字体显示

                strSpelling = "";

                lblEnglish.setForeground(Color.red);

                lblEnglish.setText(strEnglish);

                // 陌生度

                strange++;

            }

        }

 

        // Tab键

        if (ch == '`') {

            newRandomWord();

        }

    }

 

    public void newRandomWord() {

        strSpelling = "";

        strange = 0;

        // Random random = new Random(System.currentTimeMillis());

        // int index = Math.abs(random.nextInt() % 3000);

        try {

            randomWord = new WordManager(thesPath, thesName);

        } catch (IOException e) {

            JOptionPane.showMessageDialog(this, e.getMessage());

            System.exit(0);

        }

        getTestWord();

    }

 

    public void setEventToLable(String strWord) {

        lblEnglish.setText(strWord);

    }

 

    // 从词库文件中随机抽取一个单词

    public void getTestWord() {

        try {

            randomWord.getWordAndInterp();

        } catch (IOException e) {

            JOptionPane.showMessageDialog(this, e.getMessage());

            System.exit(0);

        }

 

        strEnglish = randomWord.word;

        strPhonetic = randomWord.phonetic;

        strChinese = randomWord.interp;

        strTName = randomWord.thesName;

 

        wordLength = strEnglish.length();

 

        lblEnglish.setText(" ");

        lblPhonetic.setText(strPhonetic);

        txtChinese.setText(strChinese);

        lblStatus.setText(strTName);

    }

 

    public void chooseThesaurus() {

        JFileChooser chooser = new JFileChooser();

        chooser.setCurrentDirectory(new java.io.File("./thesaurus"));

        chooser.setDialogTitle("选择词库");

        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);

        chooser.setAcceptAllFileFilterUsed(false);

        if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {

            thesPath = chooser.getSelectedFile().getPath();

            // thesName = chooser.getSelectedFile().getName();

            newRandomWord();

 

 

        } else {

            return;

        }

    }

 

    @Override

    public void actionPerformed(ActionEvent e) {

        if (e.getSource() == chooseThItem) {

            chooseThesaurus();

        }

        else if (e.getSource() == statItem) {

            new ReciteStat();

        }

        else if (e.getSource() == exitItem){

            System.exit(0);

        }

        else if (e.getSource() == aboutItem) {

            JOptionPane.showMessageDialog(this,"欢迎大家\n ");

        }

 

    }

}

posted @ 2015-06-14 19:48  张文周臣  阅读(484)  评论(5编辑  收藏  举报