问题
I have followed an example program from the book "Head First Java", chapter 14 page 448-459
Here's a link to the book online though Google Books: Head First Java
I made sure that I had Japanese installed as a viewing language on my OS (Windows 7) and I of course have the Japanese IME in order to type in Japanese in the first place.
I even saved the text file with a unicode encoding.
I'm sure this has something to do with the code because it works properly with only English words.
Thank you!
The program consists of 3 classes.
package chap14;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import java.io.*;
public class QuizCardReader {
private JTextArea display;
private JTextArea answer;
private ArrayList cardList;
private QuizCard currentCard;
private Iterator cardIterator;
private JFrame frame;
private JButton nextButton;
private boolean isShowAnswer;
public static void main (String[] args) {
QuizCardReader qReader = new QuizCardReader();
qReader.go();
}
public void go() {
frame = new JFrame("Quiz Card Player");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel();
Font bigFont = new Font("sanserif", Font.BOLD, 24);
display = new JTextArea(9,20);
display.setFont(bigFont);
display.setLineWrap(true);
display.setWrapStyleWord(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);
nextButton.addActionListener(new NextCardListener());
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(500,600);
frame.setVisible(true);
}
public class NextCardListener implements ActionListener {
public void actionPerformed(ActionEvent ev) {
if (isShowAnswer) {
display.setText(currentCard.getAnswer());
nextButton.setText("Next Card");
isShowAnswer = false;
} else {
if (cardIterator.hasNext()) {
showNextCard();
} else {
display.setText("That was last card");
nextButton.disable();
}
}
}
}
public class OpenMenuListener implements ActionListener {
public void actionPerformed(ActionEvent ev) {
JFileChooser fileOpen = new JFileChooser();
fileOpen.showOpenDialog(frame);
loadFile(fileOpen.getSelectedFile());
}
}
private void loadFile(File file) {
cardList = new ArrayList();
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
String line = null;
while ((line = reader.readLine()) != null) {
makeCard(line);
}
reader.close();
} catch(Exception ex) {
System.out.println("couldn't read the card file");
ex.printStackTrace();
}
cardIterator = cardList.iterator();
showNextCard();
}
private void makeCard(String lineToParse) {
StringTokenizer parser = new StringTokenizer(lineToParse, "/");
if (parser.hasMoreTokens()) {
QuizCard card = new QuizCard(parser.nextToken(), parser.nextToken());
cardList.add(card);
}
}
private void showNextCard() {
currentCard = (QuizCard) cardIterator.next();
display.setText(currentCard.getQuestion());
nextButton.setText("Show Answer");
isShowAnswer = true;
}
}
Here is the second class.
package chap14;
import java.io.*;
public class QuizCard implements Serializable {
private String uniqueID;
private String category;
private String question;
private String answer;
private String hint;
public QuizCard(String q, String a) {
question = q;
answer = a;
}
public void setUniqueID(String id) {
uniqueID = id;
}
public String getUniqueID() {
return uniqueID;
}
public void setCategory(String c) {
category = c;
}
public String getCategory() {
return category;
}
public void setQuestion(String q) {
question = q;
}
public String getQuestion() {
return question;
}
public void setAnswer(String a) {
answer = a;
}
public String getAnswer() {
return answer;
}
public void setHint(String h) {
hint = h;
}
public String getHint() {
return hint;
}
}
And the third class
package chap14;
import java.util.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.*;
import java.io.*;
public class QuizCardBuilder {
private JTextArea question;
private JTextArea answer;
private ArrayList cardList;
private JFrame frame;
public static void main (String[] args) {
QuizCardBuilder builder = new QuizCardBuilder();
builder.go();
}
public void go() {
frame = new JFrame("Quiz Card Builder");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // title bar
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:");
mainPanel.add(qLabel);
mainPanel.add(qScroller);
mainPanel.add(aLabel);
mainPanel.add(aScroller);
mainPanel.add(nextButton);
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);
}
public class NextCardListener implements ActionListener {
public void actionPerformed(ActionEvent ev) {
QuizCard card = new QuizCard(question.getText(), answer.getText());
cardList.add(card);
clearCard();
}
}
public class SaveMenuListener implements ActionListener {
public void actionPerformed(ActionEvent ev) {
QuizCard card = new QuizCard(question.getText(), answer.getText());
cardList.add(card);
JFileChooser fileSave = new JFileChooser();
fileSave.showSaveDialog(frame);
saveFile(fileSave.getSelectedFile());
}
}
public class NewMenuListener implements ActionListener {
public void actionPerformed(ActionEvent ev) {
cardList.clear();
clearCard();
}
}
private void clearCard() {
question.setText("");
answer.setText("");
question.requestFocus();
}
private void saveFile(File file) {
try {
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
Iterator cardIterator = cardList.iterator();
while (cardIterator.hasNext()) {
QuizCard card = (QuizCard) cardIterator.next();
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();
}
}
}
The errors I get when I try to get the program to read Japanese from a text file:
couldn't read the card file
java.util.NoSuchElementException
at java.util.StringTokenizer.nextToken(Unknown Source)
at chap14.QuizCardReader.makeCard(QuizCardReader.java:122)
at chap14.QuizCardReader.loadFile(QuizCardReader.java:104)
at chap14.QuizCardReader.access$8(QuizCardReader.java:98)
at chap14.QuizCardReader$OpenMenuListener.actionPerformed(QuizCardReader.java:94)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.AbstractButton.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
回答1:
BufferedReader reader = new BufferedReader(new FileReader(file));
should be
BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream(file), StandardCharsets.UTF_8));
FileReader is an old utility class with no option to set the encoding. And that tripped you. The same holds for FileWriter that should use an OutputStreamWriter with a FileOutputStream and an encoding.
Whether this helps with the scanner, still is to see.
StringTokenizer parser = new StringTokenizer(lineToParse, "/");
if (parser.hasMoreTokens()) {
String q = parser.nextToken();
if (parser.hasMoreTokens()) {
String a = parser.nextToken();
QuizCard card = new QuizCard(q, a);
cardList.add(card);
}
}
or
String[] qa = lineToParse.split("/", 2);
if (qa.length == 2) {
QuizCard card = new QuizCard(qa[0], aq[1]);
cardList.add(card);
}
The latter would split "Kiom?/3 / 4" into {"Kiom", "3 / 4"} because of the split(-, 2).
回答2:
To make code less cluttered, one can use Stream-related functionality that is available starting from Java 1.8:
import java.util.*;
import java.io.*;
class GenjiMonogatariReader{
public static void main(String[] args){
try(BufferedReader br = new BufferedReader(
new InputStreamReader(
new FileInputStream("源氏物語.txt"), "UTF-8")))
{
br.lines()
.forEach(System.out::println);
} catch (Exception e) { e.printStackTrace(); }
}
}
The 源氏物語.txt file should be UTF-8 encoded in this particular example. Modify charset's name as needed.
Do keep in mind, though, that in order to view the text in console (I'm talking about the cmd.exe window), the system must support the Japanese language. If it doesn't, the output will most likely be garbled. Even changing the default Locale with Locale.setDefault(Locale.JAPANESE); won't help.
On the other hand, running the above code from inside an IDE such as NetBeans (in my case it's ver.8.1) gives completely satisfactory results.
来源:https://stackoverflow.com/questions/21118684/how-do-i-get-my-java-program-to-read-japanese-unicode-encoding-from-a-text-fil